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)  *  rx.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Abstract: Hardware miniport for Drawbridge specific hardware 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_rx_intr_producer(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 long bellbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	u8 intstat = rx_readb(dev, MUnit.OISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^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
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	 *	been enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	 *	Check to see if this is our interrupt.  If it isn't just return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	if (likely(intstat & ~(dev->OIMR))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		bellbits = rx_readl(dev, OutboundDoorbellReg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		if (unlikely(bellbits & DoorBellPrintfReady)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 			aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		else if (unlikely(bellbits & DoorBellAdapterNormCmdReady)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
^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) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		else if (likely(bellbits & DoorBellAdapterNormRespReady)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		else if (unlikely(bellbits & DoorBellAdapterNormCmdNotFull)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		else if (unlikely(bellbits & DoorBellAdapterNormRespNotFull)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static irqreturn_t aac_rx_intr_message(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	int isAif, isFastResponse, isSpecial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	struct aac_dev *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	u32 Index = rx_readl(dev, MUnit.OutboundQueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (unlikely(Index == 0xFFFFFFFFL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		Index = rx_readl(dev, MUnit.OutboundQueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	if (likely(Index != 0xFFFFFFFFL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			isAif = isFastResponse = isSpecial = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			if (Index & 0x00000002L) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 				isAif = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 				if (Index == 0xFFFFFFFEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 					isSpecial = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				Index &= ~0x00000002L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				if (Index & 0x00000001L)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 					isFastResponse = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 				Index >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			if (!isSpecial) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 				if (unlikely(aac_intr_normal(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 						Index, isAif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 						isFastResponse, NULL))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 					rx_writel(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 						MUnit.OutboundQueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 						Index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 					rx_writel(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 						MUnit.ODR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 						DoorBellAdapterNormRespReady);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			Index = rx_readl(dev, MUnit.OutboundQueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		} while (Index != 0xFFFFFFFFL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  *	aac_rx_disable_interrupt	-	Disable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  *	@dev: Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static void aac_rx_disable_interrupt(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  *	aac_rx_enable_interrupt_producer	-	Enable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  *	@dev: Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void aac_rx_enable_interrupt_producer(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
^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)  *	aac_rx_enable_interrupt_message	-	Enable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  *	@dev: Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static void aac_rx_enable_interrupt_message(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  *	rx_sync_cmd	-	send a command and wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *	@dev: Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  *	@command: Command to execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  *	@p1: first parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  *	@p2: second parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *	@p3: third parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  *	@p4: forth parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  *	@p5: fifth parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  *	@p6: sixth parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  *	@status: adapter status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  *	@r1: first return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  *	@r2: second return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  *	@r3: third return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  *	@r4: forth return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  *	This routine will send a synchronous command to the adapter and wait 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  *	for its	completion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int rx_sync_cmd(struct aac_dev *dev, u32 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	unsigned long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	int ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	 *	Write the command into Mailbox 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	writel(command, &dev->IndexRegs->Mailbox[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	 *	Write the parameters into Mailboxes 1 - 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	writel(p1, &dev->IndexRegs->Mailbox[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	writel(p2, &dev->IndexRegs->Mailbox[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	writel(p3, &dev->IndexRegs->Mailbox[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	writel(p4, &dev->IndexRegs->Mailbox[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	 *	Clear the synch command doorbell to start on a clean slate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	 *	Disable doorbell interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	 *	Force the completion of the mask register write before issuing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	 *	the interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	rx_readb (dev, MUnit.OIMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	 *	Signal that there is a new synch command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	rx_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	 *	Wait up to 30 seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	while (time_before(jiffies, start+30*HZ)) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		udelay(5);	/* Delay 5 microseconds to let Mon960 get info. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		 *	Mon960 will set doorbell0 bit when it has completed the command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		if (rx_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			 *	Clear the doorbell.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			ok = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		 *	Yield the processor in case we are slow 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if (unlikely(ok != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		 *	Restore interrupt mask even though we timed out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		aac_adapter_enable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	 *	Pull the synch status from Mailbox 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		*status = readl(&dev->IndexRegs->Mailbox[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		*r1 = readl(&dev->IndexRegs->Mailbox[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (r2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		*r2 = readl(&dev->IndexRegs->Mailbox[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	if (r3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		*r3 = readl(&dev->IndexRegs->Mailbox[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		*r4 = readl(&dev->IndexRegs->Mailbox[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	 *	Clear the synch command doorbell.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	 *	Restore interrupt mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	aac_adapter_enable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^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)  *	aac_rx_interrupt_adapter	-	interrupt adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  *	@dev: Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  *	Send an interrupt to the i960 and breakpoint it.
^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) static void aac_rx_interrupt_adapter(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  *	aac_rx_notify_adapter		-	send an event to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  *	@dev: Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  *	@event: Event to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  *	Notify the i960 that something it probably cares about has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  *	happened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	case AdapNormCmdQue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	case HostNormRespNotFull:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	case AdapNormRespQue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	case HostNormCmdNotFull:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	case HostShutdown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	case FastIo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	case AdapPrintfDone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)  *	aac_rx_start_adapter		-	activate adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  *	@dev:	Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  *	Start up processing on an i960 based AAC adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static void aac_rx_start_adapter(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	union aac_init *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	init = dev->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	init->r7.host_elapsed_seconds = cpu_to_le32(ktime_get_real_seconds());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	// We can only use a 32 bit address here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	  0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  *	aac_rx_check_health
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)  *	@dev: device to check if healthy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)  *	Will attempt to determine if the specified adapter is alive and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  *	capable of handling requests, returning 0 if alive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static int aac_rx_check_health(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	u32 status = rx_readl(dev, MUnit.OMRx[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	 *	Check to see if the board failed any self tests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (unlikely(status & SELF_TEST_FAILED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	 *	Check to see if the board panic'd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (unlikely(status & KERNEL_PANIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		char * buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		struct POSTSTATUS {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			__le32 Post_Command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			__le32 Post_Address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		} * post;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		dma_addr_t paddr, baddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		if (likely((status & 0xFF000000L) == 0xBC000000L))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			return (status >> 16) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		buffer = dma_alloc_coherent(&dev->pdev->dev, 512, &baddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 					    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		ret = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		if (unlikely(buffer == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		post = dma_alloc_coherent(&dev->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 					  sizeof(struct POSTSTATUS), &paddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 					  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		if (unlikely(post == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 			dma_free_coherent(&dev->pdev->dev, 512, buffer, baddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		memset(buffer, 0, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		post->Post_Address = cpu_to_le32(baddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		rx_writel(dev, MUnit.IMRx[0], paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		  NULL, NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		dma_free_coherent(&dev->pdev->dev, sizeof(struct POSTSTATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 				  post, paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		if (likely((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X')))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			ret = (hex_to_bin(buffer[2]) << 4) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 				hex_to_bin(buffer[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		dma_free_coherent(&dev->pdev->dev, 512, buffer, baddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	 *	Wait for the adapter to be up and running.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	if (unlikely(!(status & KERNEL_UP_AND_RUNNING)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		return -3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	 *	Everything is OK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  *	aac_rx_deliver_producer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  *	@fib: fib to issue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  *	Will send a fib, returning 0 if successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int aac_rx_deliver_producer(struct fib * fib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	struct aac_dev *dev = fib->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	u32 Index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	unsigned long nointr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib_va, 1, fib, &nointr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	atomic_inc(&q->numpending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	*(q->headers.producer) = cpu_to_le32(Index + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	if (!(nointr & aac_config.irq_mod))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		aac_adapter_notify(dev, AdapNormCmdQueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)  *	aac_rx_deliver_message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)  *	@fib: fib to issue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  *	Will send a fib, returning 0 if successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static int aac_rx_deliver_message(struct fib * fib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	struct aac_dev *dev = fib->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	u32 Index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	volatile void __iomem *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	unsigned long count = 10000000L; /* 50 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	atomic_inc(&q->numpending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		Index = rx_readl(dev, MUnit.InboundQueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		if (unlikely(Index == 0xFFFFFFFFL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			Index = rx_readl(dev, MUnit.InboundQueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		if (likely(Index != 0xFFFFFFFFL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		if (--count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 			atomic_dec(&q->numpending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	device = dev->base + Index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	addr = fib->hw_fib_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	writel((u32)(addr & 0xffffffff), device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	device += sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	writel((u32)(addr >> 32), device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	device += sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	writel(le16_to_cpu(fib->hw_fib_va->header.Size), device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	rx_writel(dev, MUnit.InboundQueue, Index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)  *	aac_rx_ioremap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)  *	@dev: adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)  *	@size: mapping resize request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static int aac_rx_ioremap(struct aac_dev * dev, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	if (!size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		iounmap(dev->regs.rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	dev->base = dev->regs.rx = ioremap(dev->base_start, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	if (dev->base == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	dev->IndexRegs = &dev->regs.rx->IndexRegs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static int aac_rx_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	u32 var = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	if (!(dev->supplement_adapter_info.supported_options2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	  AAC_OPTION_MU_RESET) || (bled >= 0) || (bled == -2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		if (bled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 				dev->name, dev->id, bled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 			  0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			if (!bled && (var != 0x00000001) && (var != 0x3803000F))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 				bled = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		if (bled && (bled != -ETIMEDOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 			bled = aac_adapter_sync_cmd(dev, IOP_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			  0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		if (bled && (bled != -ETIMEDOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	if (bled && (var == 0x3803000F)) { /* USE_OTHER_METHOD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		rx_writel(dev, MUnit.reserved2, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		msleep(5000); /* Delay 5 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		var = 0x00000001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	if (bled && (var != 0x00000001))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	ssleep(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	if (startup_timeout < 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		startup_timeout = 300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)  *	aac_rx_select_comm	-	Select communications method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)  *	@dev: Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)  *	@comm: communications method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) int aac_rx_select_comm(struct aac_dev *dev, int comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	switch (comm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	case AAC_COMM_PRODUCER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_producer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		dev->a_ops.adapter_intr = aac_rx_intr_producer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	case AAC_COMM_MESSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		dev->a_ops.adapter_intr = aac_rx_intr_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		dev->a_ops.adapter_deliver = aac_rx_deliver_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)  *	aac_rx_init	-	initialize an i960 based AAC card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)  *	@dev: device to configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)  *	Allocate and set up resources for the i960 based AAC variants. The 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)  *	device_interface in the commregion will be allocated and linked 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)  *	to the comm region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) int _aac_rx_init(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	unsigned long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	unsigned long status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	int restart = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	int instance = dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	const char * name = dev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	if (aac_adapter_ioremap(dev, dev->base_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		printk(KERN_WARNING "%s: unable to map adapter.\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	/* Failure to reset here is an option ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	if (((status & 0x0c) != 0x0c) || dev->init_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		dev->init_reset = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		if (!aac_rx_restart_adapter(dev, 0, IOP_HWSOFT_RESET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			/* Make sure the Hardware FIFO is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			while ((++restart < 512) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			       (rx_readl(dev, MUnit.OutboundQueue) != 0xFFFFFFFFL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	 *	Check to see if the board panic'd while booting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	status = rx_readl(dev, MUnit.OMRx[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	if (status & KERNEL_PANIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		if (aac_rx_restart_adapter(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 			aac_rx_check_health(dev), IOP_HWSOFT_RESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 			goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		++restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	 *	Check to see if the board failed any self tests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	status = rx_readl(dev, MUnit.OMRx[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	if (status & SELF_TEST_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	 *	Check to see if the monitor panic'd while booting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	if (status & MONITOR_PANIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		if ((restart &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		  time_after(jiffies, start+HZ*startup_timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 			printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 					dev->name, instance, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		if (!restart &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		  ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		  time_after(jiffies, start + HZ *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		  ((startup_timeout > 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		    ? (startup_timeout - 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		    : (startup_timeout / 2))))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 			if (likely(!aac_rx_restart_adapter(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 				aac_rx_check_health(dev), IOP_HWSOFT_RESET)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 				start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 			++restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	if (restart && aac_commit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		aac_commit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	 *	Fill in the common function dispatch table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	dev->a_ops.adapter_notify = aac_rx_notify_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	dev->a_ops.adapter_check_health = aac_rx_check_health;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	dev->a_ops.adapter_restart = aac_rx_restart_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	dev->a_ops.adapter_start = aac_rx_start_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	 *	First clear out all interrupts.  Then enable the one's that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	 *	can handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	aac_adapter_comm(dev, AAC_COMM_PRODUCER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	aac_adapter_disable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	rx_writel(dev, MUnit.ODR, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	aac_adapter_enable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	if (aac_init_adapter(dev) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	aac_adapter_comm(dev, dev->comm_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	dev->sync_mode = 0;	/* sync. mode not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 			IRQF_SHARED, "aacraid", dev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		if (dev->msi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 			pci_disable_msi(dev->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 			name, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	dev->dbg_base = dev->base_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	dev->dbg_base_mapped = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	dev->dbg_size = dev->base_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	aac_adapter_enable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	 *	Tell the adapter that all is configured, and it can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	 * start accepting requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	aac_rx_start_adapter(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) error_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int aac_rx_init(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	 *	Fill in the function dispatch table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	dev->a_ops.adapter_ioremap = aac_rx_ioremap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	dev->a_ops.adapter_comm = aac_rx_select_comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	return _aac_rx_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }