Linux Audio

Check our new training course

Embedded Linux training

Mar 31-Apr 8, 2025
Register
Loading...
v3.1
  1/*
  2 *	Adaptec AAC series RAID controller driver
  3 *	(c) Copyright 2001 Red Hat Inc.
  4 *
  5 * based on the old aacraid driver that is..
  6 * Adaptec aacraid device driver for Linux.
  7 *
  8 * Copyright (c) 2000-2010 Adaptec, Inc.
  9 *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
 
 10 *
 11 * This program is free software; you can redistribute it and/or modify
 12 * it under the terms of the GNU General Public License as published by
 13 * the Free Software Foundation; either version 2, or (at your option)
 14 * any later version.
 15 *
 16 * This program is distributed in the hope that it will be useful,
 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 19 * GNU General Public License for more details.
 20 *
 21 * You should have received a copy of the GNU General Public License
 22 * along with this program; see the file COPYING.  If not, write to
 23 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 24 *
 25 * Module Name:
 26 *  src.c
 27 *
 28 * Abstract: Hardware Device Interface for PMC SRC based controllers
 29 *
 30 */
 31
 32#include <linux/kernel.h>
 33#include <linux/init.h>
 34#include <linux/types.h>
 35#include <linux/pci.h>
 36#include <linux/spinlock.h>
 37#include <linux/slab.h>
 38#include <linux/blkdev.h>
 39#include <linux/delay.h>
 40#include <linux/version.h>
 41#include <linux/completion.h>
 42#include <linux/time.h>
 43#include <linux/interrupt.h>
 44#include <scsi/scsi_host.h>
 45
 46#include "aacraid.h"
 47
 
 
 48static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
 49{
 50	struct aac_dev *dev = dev_id;
 
 51	unsigned long bellbits, bellbits_shifted;
 52	int our_interrupt = 0;
 53	int isFastResponse;
 54	u32 index, handle;
 55
 56	bellbits = src_readl(dev, MUnit.ODR_R);
 57	if (bellbits & PmDoorBellResponseSent) {
 58		bellbits = PmDoorBellResponseSent;
 59		/* handle async. status */
 60		our_interrupt = 1;
 61		index = dev->host_rrq_idx;
 62		if (dev->host_rrq[index] == 0) {
 63			u32 old_index = index;
 64			/* adjust index */
 65			do {
 66				index++;
 67				if (index == dev->scsi_host_ptr->can_queue +
 68							AAC_NUM_MGT_FIB)
 69					index = 0;
 70				if (dev->host_rrq[index] != 0)
 71					break;
 72			} while (index != old_index);
 73			dev->host_rrq_idx = index;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 74		}
 
 
 
 
 
 
 
 
 75		for (;;) {
 76			isFastResponse = 0;
 77			/* remove toggle bit (31) */
 78			handle = (dev->host_rrq[index] & 0x7fffffff);
 79			/* check fast response bit (30) */
 
 80			if (handle & 0x40000000)
 81				isFastResponse = 1;
 82			handle &= 0x0000ffff;
 83			if (handle == 0)
 84				break;
 85
 86			aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
 87
 
 88			dev->host_rrq[index++] = 0;
 89			if (index == dev->scsi_host_ptr->can_queue +
 90						AAC_NUM_MGT_FIB)
 91				index = 0;
 92			dev->host_rrq_idx = index;
 93		}
 94	} else {
 95		bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
 96		if (bellbits_shifted & DoorBellAifPending) {
 97			our_interrupt = 1;
 98			/* handle AIF */
 99			aac_intr_normal(dev, 0, 2, 0, NULL);
100		}
 
101	}
102
103	if (our_interrupt) {
104		src_writel(dev, MUnit.ODR_C, bellbits);
105		return IRQ_HANDLED;
106	}
107	return IRQ_NONE;
108}
109
110/**
111 *	aac_src_disable_interrupt	-	Disable interrupts
112 *	@dev: Adapter
113 */
114
115static void aac_src_disable_interrupt(struct aac_dev *dev)
116{
117	src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
118}
119
120/**
121 *	aac_src_enable_interrupt_message	-	Enable interrupts
122 *	@dev: Adapter
123 */
124
125static void aac_src_enable_interrupt_message(struct aac_dev *dev)
126{
127	src_writel(dev, MUnit.OIMR, dev->OIMR = 0xfffffff8);
128}
129
130/**
131 *	src_sync_cmd	-	send a command and wait
132 *	@dev: Adapter
133 *	@command: Command to execute
134 *	@p1: first parameter
135 *	@ret: adapter status
136 *
137 *	This routine will send a synchronous command to the adapter and wait
138 *	for its	completion.
139 */
140
141static int src_sync_cmd(struct aac_dev *dev, u32 command,
142	u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
143	u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
144{
145	unsigned long start;
 
146	int ok;
147
148	/*
149	 *	Write the command into Mailbox 0
150	 */
151	writel(command, &dev->IndexRegs->Mailbox[0]);
152	/*
153	 *	Write the parameters into Mailboxes 1 - 6
154	 */
155	writel(p1, &dev->IndexRegs->Mailbox[1]);
156	writel(p2, &dev->IndexRegs->Mailbox[2]);
157	writel(p3, &dev->IndexRegs->Mailbox[3]);
158	writel(p4, &dev->IndexRegs->Mailbox[4]);
159
160	/*
161	 *	Clear the synch command doorbell to start on a clean slate.
162	 */
163	src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
 
 
 
164
165	/*
166	 *	Disable doorbell interrupts
167	 */
168	src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
169
170	/*
171	 *	Force the completion of the mask register write before issuing
172	 *	the interrupt.
173	 */
174	src_readl(dev, MUnit.OIMR);
175
176	/*
177	 *	Signal that there is a new synch command
178	 */
179	src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT);
180
181	ok = 0;
182	start = jiffies;
183
184	/*
185	 *	Wait up to 30 seconds
186	 */
187	while (time_before(jiffies, start+30*HZ)) {
188		/* Delay 5 microseconds to let Mon960 get info. */
189		udelay(5);
190
191		/* Mon960 will set doorbell0 bit
192		 * when it has completed the command
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193		 */
194		if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
195			/* Clear the doorbell */
196			src_writel(dev,
197				MUnit.ODR_C,
198				OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
199			ok = 1;
200			break;
201		}
202
203		 /* Yield the processor in case we are slow */
204		msleep(1);
205	}
206	if (unlikely(ok != 1)) {
207		 /* Restore interrupt mask even though we timed out */
208		aac_adapter_enable_int(dev);
209		return -ETIMEDOUT;
210	}
211
212	 /* Pull the synch status from Mailbox 0 */
213	if (status)
214		*status = readl(&dev->IndexRegs->Mailbox[0]);
215	if (r1)
216		*r1 = readl(&dev->IndexRegs->Mailbox[1]);
217	if (r2)
218		*r2 = readl(&dev->IndexRegs->Mailbox[2]);
219	if (r3)
220		*r3 = readl(&dev->IndexRegs->Mailbox[3]);
221	if (r4)
222		*r4 = readl(&dev->IndexRegs->Mailbox[4]);
223
224	 /* Clear the synch command doorbell */
225	src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
226
227	 /* Restore interrupt mask */
 
 
228	aac_adapter_enable_int(dev);
229	return 0;
230
231}
232
233/**
234 *	aac_src_interrupt_adapter	-	interrupt adapter
235 *	@dev: Adapter
236 *
237 *	Send an interrupt to the i960 and breakpoint it.
238 */
239
240static void aac_src_interrupt_adapter(struct aac_dev *dev)
241{
242	src_sync_cmd(dev, BREAKPOINT_REQUEST,
243		0, 0, 0, 0, 0, 0,
244		NULL, NULL, NULL, NULL, NULL);
245}
246
247/**
248 *	aac_src_notify_adapter		-	send an event to the adapter
249 *	@dev: Adapter
250 *	@event: Event to send
251 *
252 *	Notify the i960 that something it probably cares about has
253 *	happened.
254 */
255
256static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
257{
258	switch (event) {
259
260	case AdapNormCmdQue:
261		src_writel(dev, MUnit.ODR_C,
262			INBOUNDDOORBELL_1 << SRC_ODR_SHIFT);
263		break;
264	case HostNormRespNotFull:
265		src_writel(dev, MUnit.ODR_C,
266			INBOUNDDOORBELL_4 << SRC_ODR_SHIFT);
267		break;
268	case AdapNormRespQue:
269		src_writel(dev, MUnit.ODR_C,
270			INBOUNDDOORBELL_2 << SRC_ODR_SHIFT);
271		break;
272	case HostNormCmdNotFull:
273		src_writel(dev, MUnit.ODR_C,
274			INBOUNDDOORBELL_3 << SRC_ODR_SHIFT);
275		break;
276	case FastIo:
277		src_writel(dev, MUnit.ODR_C,
278			INBOUNDDOORBELL_6 << SRC_ODR_SHIFT);
279		break;
280	case AdapPrintfDone:
281		src_writel(dev, MUnit.ODR_C,
282			INBOUNDDOORBELL_5 << SRC_ODR_SHIFT);
283		break;
284	default:
285		BUG();
286		break;
287	}
288}
289
290/**
291 *	aac_src_start_adapter		-	activate adapter
292 *	@dev:	Adapter
293 *
294 *	Start up processing on an i960 based AAC adapter
295 */
296
297static void aac_src_start_adapter(struct aac_dev *dev)
298{
299	struct aac_init *init;
 
 
 
 
 
 
 
 
 
300
301	init = dev->init;
302	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
304	/* We can only use a 32 bit address here */
305	src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
306	  0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
307}
308
309/**
310 *	aac_src_check_health
311 *	@dev: device to check if healthy
312 *
313 *	Will attempt to determine if the specified adapter is alive and
314 *	capable of handling requests, returning 0 if alive.
315 */
316static int aac_src_check_health(struct aac_dev *dev)
317{
318	u32 status = src_readl(dev, MUnit.OMR);
319
320	/*
 
 
 
 
 
 
321	 *	Check to see if the board failed any self tests.
322	 */
323	if (unlikely(status & SELF_TEST_FAILED))
324		return -1;
325
326	/*
327	 *	Check to see if the board panic'd.
328	 */
329	if (unlikely(status & KERNEL_PANIC))
330		return (status >> 16) & 0xFF;
 
331	/*
332	 *	Wait for the adapter to be up and running.
333	 */
334	if (unlikely(!(status & KERNEL_UP_AND_RUNNING)))
335		return -3;
336	/*
337	 *	Everything is OK
338	 */
339	return 0;
 
 
 
 
 
 
 
 
 
 
 
340}
341
342/**
343 *	aac_src_deliver_message
344 *	@fib: fib to issue
345 *
346 *	Will send a fib, returning 0 if successful.
347 */
348static int aac_src_deliver_message(struct fib *fib)
349{
350	struct aac_dev *dev = fib->dev;
351	struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
352	unsigned long qflags;
353	u32 fibsize;
354	u64 address;
355	struct aac_fib_xporthdr *pFibX;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
357	spin_lock_irqsave(q->lock, qflags);
358	q->numpending++;
359	spin_unlock_irqrestore(q->lock, qflags);
360
361	/* Calculate the amount to the fibsize bits */
362	fibsize = (sizeof(struct aac_fib_xporthdr) +
363		fib->hw_fib_va->header.Size + 127) / 128 - 1;
364	if (fibsize > (ALIGN32 - 1))
365		fibsize = ALIGN32 - 1;
366
367    /* Fill XPORT header */
368	pFibX = (struct aac_fib_xporthdr *)
369		((unsigned char *)fib->hw_fib_va -
370		sizeof(struct aac_fib_xporthdr));
371	pFibX->Handle = fib->hw_fib_va->header.SenderData + 1;
372	pFibX->HostAddress = fib->hw_fib_pa;
373	pFibX->Size = fib->hw_fib_va->header.Size;
374	address = fib->hw_fib_pa - (u64)sizeof(struct aac_fib_xporthdr);
375
376	src_writel(dev, MUnit.IQ_H, (u32)(address >> 32));
377	src_writel(dev, MUnit.IQ_L, (u32)(address & 0xffffffff) + fibsize);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378	return 0;
379}
380
381/**
382 *	aac_src_ioremap
383 *	@size: mapping resize request
384 *
385 */
386static int aac_src_ioremap(struct aac_dev *dev, u32 size)
387{
388	if (!size) {
 
 
389		iounmap(dev->regs.src.bar0);
390		dev->regs.src.bar0 = NULL;
391		iounmap(dev->base);
392		dev->base = NULL;
393		return 0;
394	}
395	dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2),
396		AAC_MIN_SRC_BAR1_SIZE);
397	dev->base = NULL;
398	if (dev->regs.src.bar1 == NULL)
399		return -1;
400	dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base,
401				size);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402	if (dev->base == NULL) {
403		iounmap(dev->regs.src.bar1);
404		dev->regs.src.bar1 = NULL;
405		return -1;
406	}
407	dev->IndexRegs = &((struct src_registers __iomem *)
408		dev->base)->IndexRegs;
409	return 0;
410}
411
412static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413{
414	u32 var, reset_mask;
 
 
415
416	if (bled >= 0) {
417		if (bled)
418			printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
419				dev->name, dev->id, bled);
420		bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
421			0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
422			if (bled || (var != 0x00000001))
423				bled = -EINVAL;
424		if (dev->supplement_adapter_info.SupportedOptions2 &
425			AAC_OPTION_DOORBELL_RESET) {
426			src_writel(dev, MUnit.IDR, reset_mask);
427			msleep(5000); /* Delay 5 seconds */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428		}
429	}
430
431	if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
432		return -ENODEV;
 
 
 
433
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434	if (startup_timeout < 300)
435		startup_timeout = 300;
436
437	return 0;
 
 
 
 
 
 
438}
439
440/**
441 *	aac_src_select_comm	-	Select communications method
442 *	@dev: Adapter
443 *	@comm: communications method
444 */
445int aac_src_select_comm(struct aac_dev *dev, int comm)
446{
447	switch (comm) {
448	case AAC_COMM_MESSAGE:
449		dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
450		dev->a_ops.adapter_intr = aac_src_intr_message;
451		dev->a_ops.adapter_deliver = aac_src_deliver_message;
452		break;
453	default:
454		return 1;
455	}
456	return 0;
457}
458
459/**
460 *  aac_src_init	-	initialize an Cardinal Frey Bar card
461 *  @dev: device to configure
462 *
463 */
464
465int aac_src_init(struct aac_dev *dev)
466{
467	unsigned long start;
468	unsigned long status;
469	int restart = 0;
470	int instance = dev->id;
471	const char *name = dev->name;
472
473	dev->a_ops.adapter_ioremap = aac_src_ioremap;
474	dev->a_ops.adapter_comm = aac_src_select_comm;
475
476	dev->base_size = AAC_MIN_SRC_BAR0_SIZE;
477	if (aac_adapter_ioremap(dev, dev->base_size)) {
478		printk(KERN_WARNING "%s: unable to map adapter.\n", name);
479		goto error_iounmap;
480	}
481
482	/* Failure to reset here is an option ... */
483	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
484	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
485	if ((aac_reset_devices || reset_devices) &&
486		!aac_src_restart_adapter(dev, 0))
487		++restart;
 
 
 
 
488	/*
489	 *	Check to see if the board panic'd while booting.
490	 */
491	status = src_readl(dev, MUnit.OMR);
492	if (status & KERNEL_PANIC) {
493		if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
 
494			goto error_iounmap;
495		++restart;
496	}
497	/*
498	 *	Check to see if the board failed any self tests.
499	 */
500	status = src_readl(dev, MUnit.OMR);
501	if (status & SELF_TEST_FAILED) {
502		printk(KERN_ERR "%s%d: adapter self-test failed.\n",
503			dev->name, instance);
504		goto error_iounmap;
505	}
506	/*
507	 *	Check to see if the monitor panic'd while booting.
508	 */
509	if (status & MONITOR_PANIC) {
510		printk(KERN_ERR "%s%d: adapter monitor panic.\n",
511			dev->name, instance);
512		goto error_iounmap;
513	}
514	start = jiffies;
515	/*
516	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
517	 */
518	while (!((status = src_readl(dev, MUnit.OMR)) &
519		KERNEL_UP_AND_RUNNING)) {
520		if ((restart &&
521		  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
522		  time_after(jiffies, start+HZ*startup_timeout)) {
523			printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
524					dev->name, instance, status);
525			goto error_iounmap;
526		}
527		if (!restart &&
528		  ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
529		  time_after(jiffies, start + HZ *
530		  ((startup_timeout > 60)
531		    ? (startup_timeout - 60)
532		    : (startup_timeout / 2))))) {
533			if (likely(!aac_src_restart_adapter(dev,
534			    aac_src_check_health(dev))))
535				start = jiffies;
536			++restart;
537		}
538		msleep(1);
539	}
540	if (restart && aac_commit)
541		aac_commit = 1;
542	/*
543	 *	Fill in the common function dispatch table.
544	 */
545	dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
546	dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
 
547	dev->a_ops.adapter_notify = aac_src_notify_adapter;
548	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
549	dev->a_ops.adapter_check_health = aac_src_check_health;
550	dev->a_ops.adapter_restart = aac_src_restart_adapter;
 
551
552	/*
553	 *	First clear out all interrupts.  Then enable the one's that we
554	 *	can handle.
555	 */
556	aac_adapter_comm(dev, AAC_COMM_MESSAGE);
557	aac_adapter_disable_int(dev);
558	src_writel(dev, MUnit.ODR_C, 0xffffffff);
559	aac_adapter_enable_int(dev);
560
561	if (aac_init_adapter(dev) == NULL)
562		goto error_iounmap;
563	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
564		goto error_iounmap;
565
566	dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
 
 
 
567
568	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
569			IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
570
571		if (dev->msi)
572			pci_disable_msi(dev->pdev);
573
574		printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
575			name, instance);
576		goto error_iounmap;
577	}
578	dev->dbg_base = pci_resource_start(dev->pdev, 2);
579	dev->dbg_base_mapped = dev->regs.src.bar1;
580	dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
 
581
582	aac_adapter_enable_int(dev);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
583	/*
584	 *	Tell the adapter that all is configured, and it can
585	 * start accepting requests
586	 */
587	aac_src_start_adapter(dev);
 
 
 
 
 
 
 
588
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589	return 0;
590
591error_iounmap:
592
593	return -1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
594}
v4.17
   1/*
   2 *	Adaptec AAC series RAID controller driver
   3 *	(c) Copyright 2001 Red Hat Inc.
   4 *
   5 * based on the old aacraid driver that is..
   6 * Adaptec aacraid device driver for Linux.
   7 *
   8 * Copyright (c) 2000-2010 Adaptec, Inc.
   9 *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
  10 *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License as published by
  14 * the Free Software Foundation; either version 2, or (at your option)
  15 * any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; see the file COPYING.  If not, write to
  24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  25 *
  26 * Module Name:
  27 *  src.c
  28 *
  29 * Abstract: Hardware Device Interface for PMC SRC based controllers
  30 *
  31 */
  32
  33#include <linux/kernel.h>
  34#include <linux/init.h>
  35#include <linux/types.h>
  36#include <linux/pci.h>
  37#include <linux/spinlock.h>
  38#include <linux/slab.h>
  39#include <linux/blkdev.h>
  40#include <linux/delay.h>
 
  41#include <linux/completion.h>
  42#include <linux/time.h>
  43#include <linux/interrupt.h>
  44#include <scsi/scsi_host.h>
  45
  46#include "aacraid.h"
  47
  48static int aac_src_get_sync_status(struct aac_dev *dev);
  49
  50static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
  51{
  52	struct aac_msix_ctx *ctx;
  53	struct aac_dev *dev;
  54	unsigned long bellbits, bellbits_shifted;
  55	int vector_no;
  56	int isFastResponse, mode;
  57	u32 index, handle;
  58
  59	ctx = (struct aac_msix_ctx *)dev_id;
  60	dev = ctx->dev;
  61	vector_no = ctx->vector_no;
  62
  63	if (dev->msi_enabled) {
  64		mode = AAC_INT_MODE_MSI;
  65		if (vector_no == 0) {
  66			bellbits = src_readl(dev, MUnit.ODR_MSI);
  67			if (bellbits & 0x40000)
  68				mode |= AAC_INT_MODE_AIF;
  69			if (bellbits & 0x1000)
  70				mode |= AAC_INT_MODE_SYNC;
  71		}
  72	} else {
  73		mode = AAC_INT_MODE_INTX;
  74		bellbits = src_readl(dev, MUnit.ODR_R);
  75		if (bellbits & PmDoorBellResponseSent) {
  76			bellbits = PmDoorBellResponseSent;
  77			src_writel(dev, MUnit.ODR_C, bellbits);
  78			src_readl(dev, MUnit.ODR_C);
  79		} else {
  80			bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
  81			src_writel(dev, MUnit.ODR_C, bellbits);
  82			src_readl(dev, MUnit.ODR_C);
  83
  84			if (bellbits_shifted & DoorBellAifPending)
  85				mode |= AAC_INT_MODE_AIF;
  86			else if (bellbits_shifted & OUTBOUNDDOORBELL_0)
  87				mode |= AAC_INT_MODE_SYNC;
  88		}
  89	}
  90
  91	if (mode & AAC_INT_MODE_SYNC) {
  92		unsigned long sflags;
  93		struct list_head *entry;
  94		int send_it = 0;
  95		extern int aac_sync_mode;
  96
  97		if (!aac_sync_mode && !dev->msi_enabled) {
  98			src_writel(dev, MUnit.ODR_C, bellbits);
  99			src_readl(dev, MUnit.ODR_C);
 100		}
 101
 102		if (dev->sync_fib) {
 103			if (dev->sync_fib->callback)
 104				dev->sync_fib->callback(dev->sync_fib->callback_data,
 105					dev->sync_fib);
 106			spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
 107			if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
 108				dev->management_fib_count--;
 109				up(&dev->sync_fib->event_wait);
 110			}
 111			spin_unlock_irqrestore(&dev->sync_fib->event_lock,
 112						sflags);
 113			spin_lock_irqsave(&dev->sync_lock, sflags);
 114			if (!list_empty(&dev->sync_fib_list)) {
 115				entry = dev->sync_fib_list.next;
 116				dev->sync_fib = list_entry(entry,
 117							   struct fib,
 118							   fiblink);
 119				list_del(entry);
 120				send_it = 1;
 121			} else {
 122				dev->sync_fib = NULL;
 123			}
 124			spin_unlock_irqrestore(&dev->sync_lock, sflags);
 125			if (send_it) {
 126				aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
 127					(u32)dev->sync_fib->hw_fib_pa,
 128					0, 0, 0, 0, 0,
 129					NULL, NULL, NULL, NULL, NULL);
 130			}
 131		}
 132		if (!dev->msi_enabled)
 133			mode = 0;
 134
 135	}
 136
 137	if (mode & AAC_INT_MODE_AIF) {
 138		/* handle AIF */
 139		if (dev->sa_firmware) {
 140			u32 events = src_readl(dev, MUnit.SCR0);
 141
 142			aac_intr_normal(dev, events, 1, 0, NULL);
 143			writel(events, &dev->IndexRegs->Mailbox[0]);
 144			src_writel(dev, MUnit.IDR, 1 << 23);
 145		} else {
 146			if (dev->aif_thread && dev->fsa_dev)
 147				aac_intr_normal(dev, 0, 2, 0, NULL);
 148		}
 149		if (dev->msi_enabled)
 150			aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT);
 151		mode = 0;
 152	}
 153
 154	if (mode) {
 155		index = dev->host_rrq_idx[vector_no];
 156
 157		for (;;) {
 158			isFastResponse = 0;
 159			/* remove toggle bit (31) */
 160			handle = le32_to_cpu((dev->host_rrq[index])
 161				& 0x7fffffff);
 162			/* check fast response bits (30, 1) */
 163			if (handle & 0x40000000)
 164				isFastResponse = 1;
 165			handle &= 0x0000ffff;
 166			if (handle == 0)
 167				break;
 168			handle >>= 2;
 169			if (dev->msi_enabled && dev->max_msix > 1)
 170				atomic_dec(&dev->rrq_outstanding[vector_no]);
 171			aac_intr_normal(dev, handle, 0, isFastResponse, NULL);
 172			dev->host_rrq[index++] = 0;
 173			if (index == (vector_no + 1) * dev->vector_cap)
 174				index = vector_no * dev->vector_cap;
 175			dev->host_rrq_idx[vector_no] = index;
 
 
 
 
 
 
 
 
 176		}
 177		mode = 0;
 178	}
 179
 180	return IRQ_HANDLED;
 
 
 
 
 181}
 182
 183/**
 184 *	aac_src_disable_interrupt	-	Disable interrupts
 185 *	@dev: Adapter
 186 */
 187
 188static void aac_src_disable_interrupt(struct aac_dev *dev)
 189{
 190	src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
 191}
 192
 193/**
 194 *	aac_src_enable_interrupt_message	-	Enable interrupts
 195 *	@dev: Adapter
 196 */
 197
 198static void aac_src_enable_interrupt_message(struct aac_dev *dev)
 199{
 200	aac_src_access_devreg(dev, AAC_ENABLE_INTERRUPT);
 201}
 202
 203/**
 204 *	src_sync_cmd	-	send a command and wait
 205 *	@dev: Adapter
 206 *	@command: Command to execute
 207 *	@p1: first parameter
 208 *	@ret: adapter status
 209 *
 210 *	This routine will send a synchronous command to the adapter and wait
 211 *	for its	completion.
 212 */
 213
 214static int src_sync_cmd(struct aac_dev *dev, u32 command,
 215	u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
 216	u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
 217{
 218	unsigned long start;
 219	unsigned long delay;
 220	int ok;
 221
 222	/*
 223	 *	Write the command into Mailbox 0
 224	 */
 225	writel(command, &dev->IndexRegs->Mailbox[0]);
 226	/*
 227	 *	Write the parameters into Mailboxes 1 - 6
 228	 */
 229	writel(p1, &dev->IndexRegs->Mailbox[1]);
 230	writel(p2, &dev->IndexRegs->Mailbox[2]);
 231	writel(p3, &dev->IndexRegs->Mailbox[3]);
 232	writel(p4, &dev->IndexRegs->Mailbox[4]);
 233
 234	/*
 235	 *	Clear the synch command doorbell to start on a clean slate.
 236	 */
 237	if (!dev->msi_enabled)
 238		src_writel(dev,
 239			   MUnit.ODR_C,
 240			   OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
 241
 242	/*
 243	 *	Disable doorbell interrupts
 244	 */
 245	src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
 246
 247	/*
 248	 *	Force the completion of the mask register write before issuing
 249	 *	the interrupt.
 250	 */
 251	src_readl(dev, MUnit.OIMR);
 252
 253	/*
 254	 *	Signal that there is a new synch command
 255	 */
 256	src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT);
 257
 258	if ((!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) &&
 259		!dev->in_soft_reset) {
 260		ok = 0;
 261		start = jiffies;
 262
 263		if (command == IOP_RESET_ALWAYS) {
 264			/* Wait up to 10 sec */
 265			delay = 10*HZ;
 266		} else {
 267			/* Wait up to 5 minutes */
 268			delay = 300*HZ;
 269		}
 270		while (time_before(jiffies, start+delay)) {
 271			udelay(5);	/* Delay 5 microseconds to let Mon960 get info. */
 272			/*
 273			 *	Mon960 will set doorbell0 bit when it has completed the command.
 274			 */
 275			if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) {
 276				/*
 277				 *	Clear the doorbell.
 278				 */
 279				if (dev->msi_enabled)
 280					aac_src_access_devreg(dev,
 281						AAC_CLEAR_SYNC_BIT);
 282				else
 283					src_writel(dev,
 284						MUnit.ODR_C,
 285						OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
 286				ok = 1;
 287				break;
 288			}
 289			/*
 290			 *	Yield the processor in case we are slow
 291			 */
 292			msleep(1);
 293		}
 294		if (unlikely(ok != 1)) {
 295			/*
 296			 *	Restore interrupt mask even though we timed out
 297			 */
 298			aac_adapter_enable_int(dev);
 299			return -ETIMEDOUT;
 300		}
 301		/*
 302		 *	Pull the synch status from Mailbox 0.
 303		 */
 304		if (status)
 305			*status = readl(&dev->IndexRegs->Mailbox[0]);
 306		if (r1)
 307			*r1 = readl(&dev->IndexRegs->Mailbox[1]);
 308		if (r2)
 309			*r2 = readl(&dev->IndexRegs->Mailbox[2]);
 310		if (r3)
 311			*r3 = readl(&dev->IndexRegs->Mailbox[3]);
 312		if (r4)
 313			*r4 = readl(&dev->IndexRegs->Mailbox[4]);
 314		if (command == GET_COMM_PREFERRED_SETTINGS)
 315			dev->max_msix =
 316				readl(&dev->IndexRegs->Mailbox[5]) & 0xFFFF;
 317		/*
 318		 *	Clear the synch command doorbell.
 319		 */
 320		if (!dev->msi_enabled)
 
 321			src_writel(dev,
 322				MUnit.ODR_C,
 323				OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
 
 
 
 
 
 
 324	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 325
 326	/*
 327	 *	Restore interrupt mask
 328	 */
 329	aac_adapter_enable_int(dev);
 330	return 0;
 
 331}
 332
 333/**
 334 *	aac_src_interrupt_adapter	-	interrupt adapter
 335 *	@dev: Adapter
 336 *
 337 *	Send an interrupt to the i960 and breakpoint it.
 338 */
 339
 340static void aac_src_interrupt_adapter(struct aac_dev *dev)
 341{
 342	src_sync_cmd(dev, BREAKPOINT_REQUEST,
 343		0, 0, 0, 0, 0, 0,
 344		NULL, NULL, NULL, NULL, NULL);
 345}
 346
 347/**
 348 *	aac_src_notify_adapter		-	send an event to the adapter
 349 *	@dev: Adapter
 350 *	@event: Event to send
 351 *
 352 *	Notify the i960 that something it probably cares about has
 353 *	happened.
 354 */
 355
 356static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
 357{
 358	switch (event) {
 359
 360	case AdapNormCmdQue:
 361		src_writel(dev, MUnit.ODR_C,
 362			INBOUNDDOORBELL_1 << SRC_ODR_SHIFT);
 363		break;
 364	case HostNormRespNotFull:
 365		src_writel(dev, MUnit.ODR_C,
 366			INBOUNDDOORBELL_4 << SRC_ODR_SHIFT);
 367		break;
 368	case AdapNormRespQue:
 369		src_writel(dev, MUnit.ODR_C,
 370			INBOUNDDOORBELL_2 << SRC_ODR_SHIFT);
 371		break;
 372	case HostNormCmdNotFull:
 373		src_writel(dev, MUnit.ODR_C,
 374			INBOUNDDOORBELL_3 << SRC_ODR_SHIFT);
 375		break;
 376	case FastIo:
 377		src_writel(dev, MUnit.ODR_C,
 378			INBOUNDDOORBELL_6 << SRC_ODR_SHIFT);
 379		break;
 380	case AdapPrintfDone:
 381		src_writel(dev, MUnit.ODR_C,
 382			INBOUNDDOORBELL_5 << SRC_ODR_SHIFT);
 383		break;
 384	default:
 385		BUG();
 386		break;
 387	}
 388}
 389
 390/**
 391 *	aac_src_start_adapter		-	activate adapter
 392 *	@dev:	Adapter
 393 *
 394 *	Start up processing on an i960 based AAC adapter
 395 */
 396
 397static void aac_src_start_adapter(struct aac_dev *dev)
 398{
 399	union aac_init *init;
 400	int i;
 401
 402	 /* reset host_rrq_idx first */
 403	for (i = 0; i < dev->max_msix; i++) {
 404		dev->host_rrq_idx[i] = i * dev->vector_cap;
 405		atomic_set(&dev->rrq_outstanding[i], 0);
 406	}
 407	atomic_set(&dev->msix_counter, 0);
 408	dev->fibs_pushed_no = 0;
 409
 410	init = dev->init;
 411	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
 412		init->r8.host_elapsed_seconds = cpu_to_le32(get_seconds());
 413		src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
 414			lower_32_bits(dev->init_pa),
 415			upper_32_bits(dev->init_pa),
 416			sizeof(struct _r8) +
 417			(AAC_MAX_HRRQ - 1) * sizeof(struct _rrq),
 418			0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 419	} else {
 420		init->r7.host_elapsed_seconds = cpu_to_le32(get_seconds());
 421		// We can only use a 32 bit address here
 422		src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
 423			(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
 424			NULL, NULL, NULL, NULL, NULL);
 425	}
 426
 
 
 
 427}
 428
 429/**
 430 *	aac_src_check_health
 431 *	@dev: device to check if healthy
 432 *
 433 *	Will attempt to determine if the specified adapter is alive and
 434 *	capable of handling requests, returning 0 if alive.
 435 */
 436static int aac_src_check_health(struct aac_dev *dev)
 437{
 438	u32 status = src_readl(dev, MUnit.OMR);
 439
 440	/*
 441	 *	Check to see if the board panic'd.
 442	 */
 443	if (unlikely(status & KERNEL_PANIC))
 444		goto err_blink;
 445
 446	/*
 447	 *	Check to see if the board failed any self tests.
 448	 */
 449	if (unlikely(status & SELF_TEST_FAILED))
 450		goto err_out;
 451
 452	/*
 453	 *	Check to see if the board failed any self tests.
 454	 */
 455	if (unlikely(status & MONITOR_PANIC))
 456		goto err_out;
 457
 458	/*
 459	 *	Wait for the adapter to be up and running.
 460	 */
 461	if (unlikely(!(status & KERNEL_UP_AND_RUNNING)))
 462		return -3;
 463	/*
 464	 *	Everything is OK
 465	 */
 466	return 0;
 467
 468err_out:
 469	return -1;
 470
 471err_blink:
 472	return (status >> 16) & 0xFF;
 473}
 474
 475static inline u32 aac_get_vector(struct aac_dev *dev)
 476{
 477	return atomic_inc_return(&dev->msix_counter)%dev->max_msix;
 478}
 479
 480/**
 481 *	aac_src_deliver_message
 482 *	@fib: fib to issue
 483 *
 484 *	Will send a fib, returning 0 if successful.
 485 */
 486static int aac_src_deliver_message(struct fib *fib)
 487{
 488	struct aac_dev *dev = fib->dev;
 489	struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
 
 490	u32 fibsize;
 491	dma_addr_t address;
 492	struct aac_fib_xporthdr *pFibX;
 493	int native_hba;
 494#if !defined(writeq)
 495	unsigned long flags;
 496#endif
 497
 498	u16 vector_no;
 499
 500	atomic_inc(&q->numpending);
 501
 502	native_hba = (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) ? 1 : 0;
 503
 504
 505	if (dev->msi_enabled && dev->max_msix > 1 &&
 506		(native_hba || fib->hw_fib_va->header.Command != AifRequest)) {
 507
 508		if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE3)
 509			&& dev->sa_firmware)
 510			vector_no = aac_get_vector(dev);
 511		else
 512			vector_no = fib->vector_no;
 513
 514		if (native_hba) {
 515			if (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF) {
 516				struct aac_hba_tm_req *tm_req;
 517
 518				tm_req = (struct aac_hba_tm_req *)
 519						fib->hw_fib_va;
 520				if (tm_req->iu_type ==
 521					HBA_IU_TYPE_SCSI_TM_REQ) {
 522					((struct aac_hba_tm_req *)
 523						fib->hw_fib_va)->reply_qid
 524							= vector_no;
 525					((struct aac_hba_tm_req *)
 526						fib->hw_fib_va)->request_id
 527							+= (vector_no << 16);
 528				} else {
 529					((struct aac_hba_reset_req *)
 530						fib->hw_fib_va)->reply_qid
 531							= vector_no;
 532					((struct aac_hba_reset_req *)
 533						fib->hw_fib_va)->request_id
 534							+= (vector_no << 16);
 535				}
 536			} else {
 537				((struct aac_hba_cmd_req *)
 538					fib->hw_fib_va)->reply_qid
 539						= vector_no;
 540				((struct aac_hba_cmd_req *)
 541					fib->hw_fib_va)->request_id
 542						+= (vector_no << 16);
 543			}
 544		} else {
 545			fib->hw_fib_va->header.Handle += (vector_no << 16);
 546		}
 547	} else {
 548		vector_no = 0;
 549	}
 550
 551	atomic_inc(&dev->rrq_outstanding[vector_no]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 552
 553	if (native_hba) {
 554		address = fib->hw_fib_pa;
 555		fibsize = (fib->hbacmd_size + 127) / 128 - 1;
 556		if (fibsize > 31)
 557			fibsize = 31;
 558		address |= fibsize;
 559#if defined(writeq)
 560		src_writeq(dev, MUnit.IQN_L, (u64)address);
 561#else
 562		spin_lock_irqsave(&fib->dev->iq_lock, flags);
 563		src_writel(dev, MUnit.IQN_H,
 564			upper_32_bits(address) & 0xffffffff);
 565		src_writel(dev, MUnit.IQN_L, address & 0xffffffff);
 566		spin_unlock_irqrestore(&fib->dev->iq_lock, flags);
 567#endif
 568	} else {
 569		if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
 570			dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
 571			/* Calculate the amount to the fibsize bits */
 572			fibsize = (le16_to_cpu(fib->hw_fib_va->header.Size)
 573				+ 127) / 128 - 1;
 574			/* New FIB header, 32-bit */
 575			address = fib->hw_fib_pa;
 576			fib->hw_fib_va->header.StructType = FIB_MAGIC2;
 577			fib->hw_fib_va->header.SenderFibAddress =
 578				cpu_to_le32((u32)address);
 579			fib->hw_fib_va->header.u.TimeStamp = 0;
 580			WARN_ON(upper_32_bits(address) != 0L);
 581		} else {
 582			/* Calculate the amount to the fibsize bits */
 583			fibsize = (sizeof(struct aac_fib_xporthdr) +
 584				le16_to_cpu(fib->hw_fib_va->header.Size)
 585				+ 127) / 128 - 1;
 586			/* Fill XPORT header */
 587			pFibX = (struct aac_fib_xporthdr *)
 588				((unsigned char *)fib->hw_fib_va -
 589				sizeof(struct aac_fib_xporthdr));
 590			pFibX->Handle = fib->hw_fib_va->header.Handle;
 591			pFibX->HostAddress =
 592				cpu_to_le64((u64)fib->hw_fib_pa);
 593			pFibX->Size = cpu_to_le32(
 594				le16_to_cpu(fib->hw_fib_va->header.Size));
 595			address = fib->hw_fib_pa -
 596				(u64)sizeof(struct aac_fib_xporthdr);
 597		}
 598		if (fibsize > 31)
 599			fibsize = 31;
 600		address |= fibsize;
 601
 602#if defined(writeq)
 603		src_writeq(dev, MUnit.IQ_L, (u64)address);
 604#else
 605		spin_lock_irqsave(&fib->dev->iq_lock, flags);
 606		src_writel(dev, MUnit.IQ_H,
 607			upper_32_bits(address) & 0xffffffff);
 608		src_writel(dev, MUnit.IQ_L, address & 0xffffffff);
 609		spin_unlock_irqrestore(&fib->dev->iq_lock, flags);
 610#endif
 611	}
 612	return 0;
 613}
 614
 615/**
 616 *	aac_src_ioremap
 617 *	@size: mapping resize request
 618 *
 619 */
 620static int aac_src_ioremap(struct aac_dev *dev, u32 size)
 621{
 622	if (!size) {
 623		iounmap(dev->regs.src.bar1);
 624		dev->regs.src.bar1 = NULL;
 625		iounmap(dev->regs.src.bar0);
 626		dev->base = dev->regs.src.bar0 = NULL;
 
 
 627		return 0;
 628	}
 629	dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2),
 630		AAC_MIN_SRC_BAR1_SIZE);
 631	dev->base = NULL;
 632	if (dev->regs.src.bar1 == NULL)
 633		return -1;
 634	dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size);
 635	if (dev->base == NULL) {
 636		iounmap(dev->regs.src.bar1);
 637		dev->regs.src.bar1 = NULL;
 638		return -1;
 639	}
 640	dev->IndexRegs = &((struct src_registers __iomem *)
 641		dev->base)->u.tupelo.IndexRegs;
 642	return 0;
 643}
 644
 645/**
 646 *  aac_srcv_ioremap
 647 *	@size: mapping resize request
 648 *
 649 */
 650static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
 651{
 652	if (!size) {
 653		iounmap(dev->regs.src.bar0);
 654		dev->base = dev->regs.src.bar0 = NULL;
 655		return 0;
 656	}
 657
 658	dev->regs.src.bar1 =
 659	ioremap(pci_resource_start(dev->pdev, 2), AAC_MIN_SRCV_BAR1_SIZE);
 660	dev->base = NULL;
 661	if (dev->regs.src.bar1 == NULL)
 662		return -1;
 663	dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size);
 664	if (dev->base == NULL) {
 665		iounmap(dev->regs.src.bar1);
 666		dev->regs.src.bar1 = NULL;
 667		return -1;
 668	}
 669	dev->IndexRegs = &((struct src_registers __iomem *)
 670		dev->base)->u.denali.IndexRegs;
 671	return 0;
 672}
 673
 674void aac_set_intx_mode(struct aac_dev *dev)
 675{
 676	if (dev->msi_enabled) {
 677		aac_src_access_devreg(dev, AAC_ENABLE_INTX);
 678		dev->msi_enabled = 0;
 679		msleep(5000); /* Delay 5 seconds */
 680	}
 681}
 682
 683static void aac_clear_omr(struct aac_dev *dev)
 684{
 685	u32 omr_value = 0;
 686
 687	omr_value = src_readl(dev, MUnit.OMR);
 688
 689	/*
 690	 * Check for PCI Errors or Kernel Panic
 691	 */
 692	if ((omr_value == INVALID_OMR) || (omr_value & KERNEL_PANIC))
 693		omr_value = 0;
 694
 695	/*
 696	 * Preserve MSIX Value if any
 697	 */
 698	src_writel(dev, MUnit.OMR, omr_value & AAC_INT_MODE_MSIX);
 699	src_readl(dev, MUnit.OMR);
 700}
 701
 702static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev)
 703{
 704	__le32 supported_options3;
 705
 706	if (!aac_fib_dump)
 707		return;
 708
 709	supported_options3  = dev->supplement_adapter_info.supported_options3;
 710	if (!(supported_options3 & AAC_OPTION_SUPPORTED3_IOP_RESET_FIB_DUMP))
 711		return;
 712
 713	aac_adapter_sync_cmd(dev, IOP_RESET_FW_FIB_DUMP,
 714			0, 0, 0,  0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 715}
 716
 717static bool aac_is_ctrl_up_and_running(struct aac_dev *dev)
 718{
 719	bool ctrl_up = true;
 720	unsigned long status, start;
 721	bool is_up = false;
 722
 723	start = jiffies;
 724	do {
 725		schedule();
 726		status = src_readl(dev, MUnit.OMR);
 727
 728		if (status == 0xffffffff)
 729			status = 0;
 730
 731		if (status & KERNEL_BOOTING) {
 732			start = jiffies;
 733			continue;
 734		}
 735
 736		if (time_after(jiffies, start+HZ*SOFT_RESET_TIME)) {
 737			ctrl_up = false;
 738			break;
 739		}
 740
 741		is_up = status & KERNEL_UP_AND_RUNNING;
 742
 743	} while (!is_up);
 744
 745	return ctrl_up;
 746}
 747
 748static void aac_notify_fw_of_iop_reset(struct aac_dev *dev)
 749{
 750	aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, 0, 0, 0, 0, 0, 0, NULL,
 751						NULL, NULL, NULL, NULL);
 752}
 753
 754static void aac_send_iop_reset(struct aac_dev *dev)
 755{
 756	aac_dump_fw_fib_iop_reset(dev);
 757
 758	aac_notify_fw_of_iop_reset(dev);
 759
 760	aac_set_intx_mode(dev);
 761
 762	aac_clear_omr(dev);
 763
 764	src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK);
 765
 766	msleep(5000);
 767}
 768
 769static void aac_send_hardware_soft_reset(struct aac_dev *dev)
 770{
 771	u_int32_t val;
 772
 773	aac_clear_omr(dev);
 774	val = readl(((char *)(dev->base) + IBW_SWR_OFFSET));
 775	val |= 0x01;
 776	writel(val, ((char *)(dev->base) + IBW_SWR_OFFSET));
 777	msleep_interruptible(20000);
 778}
 779
 780static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type)
 781{
 782	bool is_ctrl_up;
 783	int ret = 0;
 784
 785	if (bled < 0)
 786		goto invalid_out;
 787
 788	if (bled)
 789		dev_err(&dev->pdev->dev, "adapter kernel panic'd %x.\n", bled);
 790
 791	/*
 792	 * When there is a BlinkLED, IOP_RESET has not effect
 793	 */
 794	if (bled >= 2 && dev->sa_firmware && reset_type & HW_IOP_RESET)
 795		reset_type &= ~HW_IOP_RESET;
 796
 797	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
 798
 799	dev_err(&dev->pdev->dev, "Controller reset type is %d\n", reset_type);
 800
 801	if (reset_type & HW_IOP_RESET) {
 802		dev_info(&dev->pdev->dev, "Issuing IOP reset\n");
 803		aac_send_iop_reset(dev);
 804
 805		/*
 806		 * Creates a delay or wait till up and running comes thru
 807		 */
 808		is_ctrl_up = aac_is_ctrl_up_and_running(dev);
 809		if (!is_ctrl_up)
 810			dev_err(&dev->pdev->dev, "IOP reset failed\n");
 811		else {
 812			dev_info(&dev->pdev->dev, "IOP reset succeeded\n");
 813			goto set_startup;
 814		}
 815	}
 816
 817	if (!dev->sa_firmware) {
 818		dev_err(&dev->pdev->dev, "ARC Reset attempt failed\n");
 819		ret = -ENODEV;
 820		goto out;
 821	}
 822
 823	if (reset_type & HW_SOFT_RESET) {
 824		dev_info(&dev->pdev->dev, "Issuing SOFT reset\n");
 825		aac_send_hardware_soft_reset(dev);
 826		dev->msi_enabled = 0;
 827
 828		is_ctrl_up = aac_is_ctrl_up_and_running(dev);
 829		if (!is_ctrl_up) {
 830			dev_err(&dev->pdev->dev, "SOFT reset failed\n");
 831			ret = -ENODEV;
 832			goto out;
 833		} else
 834			dev_info(&dev->pdev->dev, "SOFT reset succeeded\n");
 835	}
 836
 837set_startup:
 838	if (startup_timeout < 300)
 839		startup_timeout = 300;
 840
 841out:
 842	return ret;
 843
 844invalid_out:
 845	if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
 846		ret = -ENODEV;
 847goto out;
 848}
 849
 850/**
 851 *	aac_src_select_comm	-	Select communications method
 852 *	@dev: Adapter
 853 *	@comm: communications method
 854 */
 855static int aac_src_select_comm(struct aac_dev *dev, int comm)
 856{
 857	switch (comm) {
 858	case AAC_COMM_MESSAGE:
 
 859		dev->a_ops.adapter_intr = aac_src_intr_message;
 860		dev->a_ops.adapter_deliver = aac_src_deliver_message;
 861		break;
 862	default:
 863		return 1;
 864	}
 865	return 0;
 866}
 867
 868/**
 869 *  aac_src_init	-	initialize an Cardinal Frey Bar card
 870 *  @dev: device to configure
 871 *
 872 */
 873
 874int aac_src_init(struct aac_dev *dev)
 875{
 876	unsigned long start;
 877	unsigned long status;
 878	int restart = 0;
 879	int instance = dev->id;
 880	const char *name = dev->name;
 881
 882	dev->a_ops.adapter_ioremap = aac_src_ioremap;
 883	dev->a_ops.adapter_comm = aac_src_select_comm;
 884
 885	dev->base_size = AAC_MIN_SRC_BAR0_SIZE;
 886	if (aac_adapter_ioremap(dev, dev->base_size)) {
 887		printk(KERN_WARNING "%s: unable to map adapter.\n", name);
 888		goto error_iounmap;
 889	}
 890
 891	/* Failure to reset here is an option ... */
 892	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
 893	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
 894
 895	if (dev->init_reset) {
 896		dev->init_reset = false;
 897		if (!aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
 898			++restart;
 899	}
 900
 901	/*
 902	 *	Check to see if the board panic'd while booting.
 903	 */
 904	status = src_readl(dev, MUnit.OMR);
 905	if (status & KERNEL_PANIC) {
 906		if (aac_src_restart_adapter(dev,
 907			aac_src_check_health(dev), IOP_HWSOFT_RESET))
 908			goto error_iounmap;
 909		++restart;
 910	}
 911	/*
 912	 *	Check to see if the board failed any self tests.
 913	 */
 914	status = src_readl(dev, MUnit.OMR);
 915	if (status & SELF_TEST_FAILED) {
 916		printk(KERN_ERR "%s%d: adapter self-test failed.\n",
 917			dev->name, instance);
 918		goto error_iounmap;
 919	}
 920	/*
 921	 *	Check to see if the monitor panic'd while booting.
 922	 */
 923	if (status & MONITOR_PANIC) {
 924		printk(KERN_ERR "%s%d: adapter monitor panic.\n",
 925			dev->name, instance);
 926		goto error_iounmap;
 927	}
 928	start = jiffies;
 929	/*
 930	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
 931	 */
 932	while (!((status = src_readl(dev, MUnit.OMR)) &
 933		KERNEL_UP_AND_RUNNING)) {
 934		if ((restart &&
 935		  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
 936		  time_after(jiffies, start+HZ*startup_timeout)) {
 937			printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
 938					dev->name, instance, status);
 939			goto error_iounmap;
 940		}
 941		if (!restart &&
 942		  ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
 943		  time_after(jiffies, start + HZ *
 944		  ((startup_timeout > 60)
 945		    ? (startup_timeout - 60)
 946		    : (startup_timeout / 2))))) {
 947			if (likely(!aac_src_restart_adapter(dev,
 948				aac_src_check_health(dev), IOP_HWSOFT_RESET)))
 949				start = jiffies;
 950			++restart;
 951		}
 952		msleep(1);
 953	}
 954	if (restart && aac_commit)
 955		aac_commit = 1;
 956	/*
 957	 *	Fill in the common function dispatch table.
 958	 */
 959	dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
 960	dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
 961	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
 962	dev->a_ops.adapter_notify = aac_src_notify_adapter;
 963	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
 964	dev->a_ops.adapter_check_health = aac_src_check_health;
 965	dev->a_ops.adapter_restart = aac_src_restart_adapter;
 966	dev->a_ops.adapter_start = aac_src_start_adapter;
 967
 968	/*
 969	 *	First clear out all interrupts.  Then enable the one's that we
 970	 *	can handle.
 971	 */
 972	aac_adapter_comm(dev, AAC_COMM_MESSAGE);
 973	aac_adapter_disable_int(dev);
 974	src_writel(dev, MUnit.ODR_C, 0xffffffff);
 975	aac_adapter_enable_int(dev);
 976
 977	if (aac_init_adapter(dev) == NULL)
 978		goto error_iounmap;
 979	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
 980		goto error_iounmap;
 981
 982	dev->msi = !pci_enable_msi(dev->pdev);
 983
 984	dev->aac_msix[0].vector_no = 0;
 985	dev->aac_msix[0].dev = dev;
 986
 987	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
 988			IRQF_SHARED, "aacraid", &(dev->aac_msix[0]))  < 0) {
 989
 990		if (dev->msi)
 991			pci_disable_msi(dev->pdev);
 992
 993		printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
 994			name, instance);
 995		goto error_iounmap;
 996	}
 997	dev->dbg_base = pci_resource_start(dev->pdev, 2);
 998	dev->dbg_base_mapped = dev->regs.src.bar1;
 999	dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
1000	dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
1001
1002	aac_adapter_enable_int(dev);
1003
1004	if (!dev->sync_mode) {
1005		/*
1006		 * Tell the adapter that all is configured, and it can
1007		 * start accepting requests
1008		 */
1009		aac_src_start_adapter(dev);
1010	}
1011	return 0;
1012
1013error_iounmap:
1014
1015	return -1;
1016}
1017
1018static int aac_src_wait_sync(struct aac_dev *dev, int *status)
1019{
1020	unsigned long start = jiffies;
1021	unsigned long usecs = 0;
1022	int delay = 5 * HZ;
1023	int rc = 1;
1024
1025	while (time_before(jiffies, start+delay)) {
1026		/*
1027		 * Delay 5 microseconds to let Mon960 get info.
1028		 */
1029		udelay(5);
1030
1031		/*
1032		 * Mon960 will set doorbell0 bit when it has completed the
1033		 * command.
1034		 */
1035		if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) {
1036			/*
1037			 * Clear: the doorbell.
1038			 */
1039			if (dev->msi_enabled)
1040				aac_src_access_devreg(dev, AAC_CLEAR_SYNC_BIT);
1041			else
1042				src_writel(dev, MUnit.ODR_C,
1043					OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
1044			rc = 0;
1045
1046			break;
1047		}
1048
1049		/*
1050		 * Yield the processor in case we are slow
1051		 */
1052		usecs = 1 * USEC_PER_MSEC;
1053		usleep_range(usecs, usecs + 50);
1054	}
1055	/*
1056	 * Pull the synch status from Mailbox 0.
1057	 */
1058	if (status && !rc) {
1059		status[0] = readl(&dev->IndexRegs->Mailbox[0]);
1060		status[1] = readl(&dev->IndexRegs->Mailbox[1]);
1061		status[2] = readl(&dev->IndexRegs->Mailbox[2]);
1062		status[3] = readl(&dev->IndexRegs->Mailbox[3]);
1063		status[4] = readl(&dev->IndexRegs->Mailbox[4]);
1064	}
1065
1066	return rc;
1067}
1068
1069/**
1070 *  aac_src_soft_reset	-	perform soft reset to speed up
1071 *  access
1072 *
1073 *  Assumptions: That the controller is in a state where we can
1074 *  bring it back to life with an init struct. We can only use
1075 *  fast sync commands, as the timeout is 5 seconds.
1076 *
1077 *  @dev: device to configure
1078 *
1079 */
1080
1081static int aac_src_soft_reset(struct aac_dev *dev)
1082{
1083	u32 status_omr = src_readl(dev, MUnit.OMR);
1084	u32 status[5];
1085	int rc = 1;
1086	int state = 0;
1087	char *state_str[7] = {
1088		"GET_ADAPTER_PROPERTIES Failed",
1089		"GET_ADAPTER_PROPERTIES timeout",
1090		"SOFT_RESET not supported",
1091		"DROP_IO Failed",
1092		"DROP_IO timeout",
1093		"Check Health failed"
1094	};
1095
1096	if (status_omr == INVALID_OMR)
1097		return 1;       // pcie hosed
1098
1099	if (!(status_omr & KERNEL_UP_AND_RUNNING))
1100		return 1;       // not up and running
1101
1102	/*
1103	 * We go into soft reset mode to allow us to handle response
1104	 */
1105	dev->in_soft_reset = 1;
1106	dev->msi_enabled = status_omr & AAC_INT_MODE_MSIX;
1107
1108	/* Get adapter properties */
1109	rc = aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, 0, 0, 0,
1110		0, 0, 0, status+0, status+1, status+2, status+3, status+4);
1111	if (rc)
1112		goto out;
1113
1114	state++;
1115	if (aac_src_wait_sync(dev, status)) {
1116		rc = 1;
1117		goto out;
1118	}
1119
1120	state++;
1121	if (!(status[1] & le32_to_cpu(AAC_OPT_EXTENDED) &&
1122		(status[4] & le32_to_cpu(AAC_EXTOPT_SOFT_RESET)))) {
1123		rc = 2;
1124		goto out;
1125	}
1126
1127	if ((status[1] & le32_to_cpu(AAC_OPT_EXTENDED)) &&
1128		(status[4] & le32_to_cpu(AAC_EXTOPT_SA_FIRMWARE)))
1129		dev->sa_firmware = 1;
1130
1131	state++;
1132	rc = aac_adapter_sync_cmd(dev, DROP_IO, 0, 0, 0, 0, 0, 0,
1133		 status+0, status+1, status+2, status+3, status+4);
1134
1135	if (rc)
1136		goto out;
1137
1138	state++;
1139	if (aac_src_wait_sync(dev, status)) {
1140		rc = 3;
1141		goto out;
1142	}
1143
1144	if (status[1])
1145		dev_err(&dev->pdev->dev, "%s: %d outstanding I/O pending\n",
1146			__func__, status[1]);
1147
1148	state++;
1149	rc = aac_src_check_health(dev);
1150
1151out:
1152	dev->in_soft_reset = 0;
1153	dev->msi_enabled = 0;
1154	if (rc)
1155		dev_err(&dev->pdev->dev, "%s: %s status = %d", __func__,
1156			state_str[state], rc);
1157
1158return rc;
1159}
1160/**
1161 *  aac_srcv_init	-	initialize an SRCv card
1162 *  @dev: device to configure
1163 *
1164 */
1165
1166int aac_srcv_init(struct aac_dev *dev)
1167{
1168	unsigned long start;
1169	unsigned long status;
1170	int restart = 0;
1171	int instance = dev->id;
1172	const char *name = dev->name;
1173
1174	dev->a_ops.adapter_ioremap = aac_srcv_ioremap;
1175	dev->a_ops.adapter_comm = aac_src_select_comm;
1176
1177	dev->base_size = AAC_MIN_SRCV_BAR0_SIZE;
1178	if (aac_adapter_ioremap(dev, dev->base_size)) {
1179		printk(KERN_WARNING "%s: unable to map adapter.\n", name);
1180		goto error_iounmap;
1181	}
1182
1183	/* Failure to reset here is an option ... */
1184	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
1185	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
1186
1187	if (dev->init_reset) {
1188		dev->init_reset = false;
1189		if (aac_src_soft_reset(dev)) {
1190			aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET);
1191			++restart;
1192		}
1193	}
1194
1195	/*
1196	 *	Check to see if flash update is running.
1197	 *	Wait for the adapter to be up and running. Wait up to 5 minutes
1198	 */
1199	status = src_readl(dev, MUnit.OMR);
1200	if (status & FLASH_UPD_PENDING) {
1201		start = jiffies;
1202		do {
1203			status = src_readl(dev, MUnit.OMR);
1204			if (time_after(jiffies, start+HZ*FWUPD_TIMEOUT)) {
1205				printk(KERN_ERR "%s%d: adapter flash update failed.\n",
1206					dev->name, instance);
1207				goto error_iounmap;
1208			}
1209		} while (!(status & FLASH_UPD_SUCCESS) &&
1210			 !(status & FLASH_UPD_FAILED));
1211		/* Delay 10 seconds.
1212		 * Because right now FW is doing a soft reset,
1213		 * do not read scratch pad register at this time
1214		 */
1215		ssleep(10);
1216	}
1217	/*
1218	 *	Check to see if the board panic'd while booting.
1219	 */
1220	status = src_readl(dev, MUnit.OMR);
1221	if (status & KERNEL_PANIC) {
1222		if (aac_src_restart_adapter(dev,
1223			aac_src_check_health(dev), IOP_HWSOFT_RESET))
1224			goto error_iounmap;
1225		++restart;
1226	}
1227	/*
1228	 *	Check to see if the board failed any self tests.
1229	 */
1230	status = src_readl(dev, MUnit.OMR);
1231	if (status & SELF_TEST_FAILED) {
1232		printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
1233		goto error_iounmap;
1234	}
1235	/*
1236	 *	Check to see if the monitor panic'd while booting.
1237	 */
1238	if (status & MONITOR_PANIC) {
1239		printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
1240		goto error_iounmap;
1241	}
1242
1243	start = jiffies;
1244	/*
1245	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
1246	 */
1247	do {
1248		status = src_readl(dev, MUnit.OMR);
1249		if (status == INVALID_OMR)
1250			status = 0;
1251
1252		if ((restart &&
1253		  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
1254		  time_after(jiffies, start+HZ*startup_timeout)) {
1255			printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
1256					dev->name, instance, status);
1257			goto error_iounmap;
1258		}
1259		if (!restart &&
1260		  ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
1261		  time_after(jiffies, start + HZ *
1262		  ((startup_timeout > 60)
1263		    ? (startup_timeout - 60)
1264		    : (startup_timeout / 2))))) {
1265			if (likely(!aac_src_restart_adapter(dev,
1266				aac_src_check_health(dev), IOP_HWSOFT_RESET)))
1267				start = jiffies;
1268			++restart;
1269		}
1270		msleep(1);
1271	} while (!(status & KERNEL_UP_AND_RUNNING));
1272
1273	if (restart && aac_commit)
1274		aac_commit = 1;
1275	/*
1276	 *	Fill in the common function dispatch table.
 
1277	 */
1278	dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
1279	dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
1280	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
1281	dev->a_ops.adapter_notify = aac_src_notify_adapter;
1282	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
1283	dev->a_ops.adapter_check_health = aac_src_check_health;
1284	dev->a_ops.adapter_restart = aac_src_restart_adapter;
1285	dev->a_ops.adapter_start = aac_src_start_adapter;
1286
1287	/*
1288	 *	First clear out all interrupts.  Then enable the one's that we
1289	 *	can handle.
1290	 */
1291	aac_adapter_comm(dev, AAC_COMM_MESSAGE);
1292	aac_adapter_disable_int(dev);
1293	src_writel(dev, MUnit.ODR_C, 0xffffffff);
1294	aac_adapter_enable_int(dev);
1295
1296	if (aac_init_adapter(dev) == NULL)
1297		goto error_iounmap;
1298	if ((dev->comm_interface != AAC_COMM_MESSAGE_TYPE2) &&
1299		(dev->comm_interface != AAC_COMM_MESSAGE_TYPE3))
1300		goto error_iounmap;
1301	if (dev->msi_enabled)
1302		aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
1303
1304	if (aac_acquire_irq(dev))
1305		goto error_iounmap;
1306
1307	dev->dbg_base = pci_resource_start(dev->pdev, 2);
1308	dev->dbg_base_mapped = dev->regs.src.bar1;
1309	dev->dbg_size = AAC_MIN_SRCV_BAR1_SIZE;
1310	dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
1311
1312	aac_adapter_enable_int(dev);
1313
1314	if (!dev->sync_mode) {
1315		/*
1316		 * Tell the adapter that all is configured, and it can
1317		 * start accepting requests
1318		 */
1319		aac_src_start_adapter(dev);
1320	}
1321	return 0;
1322
1323error_iounmap:
1324
1325	return -1;
1326}
1327
1328void aac_src_access_devreg(struct aac_dev *dev, int mode)
1329{
1330	u_int32_t val;
1331
1332	switch (mode) {
1333	case AAC_ENABLE_INTERRUPT:
1334		src_writel(dev,
1335			   MUnit.OIMR,
1336			   dev->OIMR = (dev->msi_enabled ?
1337					AAC_INT_ENABLE_TYPE1_MSIX :
1338					AAC_INT_ENABLE_TYPE1_INTX));
1339		break;
1340
1341	case AAC_DISABLE_INTERRUPT:
1342		src_writel(dev,
1343			   MUnit.OIMR,
1344			   dev->OIMR = AAC_INT_DISABLE_ALL);
1345		break;
1346
1347	case AAC_ENABLE_MSIX:
1348		/* set bit 6 */
1349		val = src_readl(dev, MUnit.IDR);
1350		val |= 0x40;
1351		src_writel(dev,  MUnit.IDR, val);
1352		src_readl(dev, MUnit.IDR);
1353		/* unmask int. */
1354		val = PMC_ALL_INTERRUPT_BITS;
1355		src_writel(dev, MUnit.IOAR, val);
1356		val = src_readl(dev, MUnit.OIMR);
1357		src_writel(dev,
1358			   MUnit.OIMR,
1359			   val & (~(PMC_GLOBAL_INT_BIT2 | PMC_GLOBAL_INT_BIT0)));
1360		break;
1361
1362	case AAC_DISABLE_MSIX:
1363		/* reset bit 6 */
1364		val = src_readl(dev, MUnit.IDR);
1365		val &= ~0x40;
1366		src_writel(dev, MUnit.IDR, val);
1367		src_readl(dev, MUnit.IDR);
1368		break;
1369
1370	case AAC_CLEAR_AIF_BIT:
1371		/* set bit 5 */
1372		val = src_readl(dev, MUnit.IDR);
1373		val |= 0x20;
1374		src_writel(dev, MUnit.IDR, val);
1375		src_readl(dev, MUnit.IDR);
1376		break;
1377
1378	case AAC_CLEAR_SYNC_BIT:
1379		/* set bit 4 */
1380		val = src_readl(dev, MUnit.IDR);
1381		val |= 0x10;
1382		src_writel(dev, MUnit.IDR, val);
1383		src_readl(dev, MUnit.IDR);
1384		break;
1385
1386	case AAC_ENABLE_INTX:
1387		/* set bit 7 */
1388		val = src_readl(dev, MUnit.IDR);
1389		val |= 0x80;
1390		src_writel(dev, MUnit.IDR, val);
1391		src_readl(dev, MUnit.IDR);
1392		/* unmask int. */
1393		val = PMC_ALL_INTERRUPT_BITS;
1394		src_writel(dev, MUnit.IOAR, val);
1395		src_readl(dev, MUnit.IOAR);
1396		val = src_readl(dev, MUnit.OIMR);
1397		src_writel(dev, MUnit.OIMR,
1398				val & (~(PMC_GLOBAL_INT_BIT2)));
1399		break;
1400
1401	default:
1402		break;
1403	}
1404}
1405
1406static int aac_src_get_sync_status(struct aac_dev *dev)
1407{
1408	int msix_val = 0;
1409	int legacy_val = 0;
1410
1411	msix_val = src_readl(dev, MUnit.ODR_MSI) & SRC_MSI_READ_MASK ? 1 : 0;
1412
1413	if (!dev->msi_enabled) {
1414		/*
1415		 * if Legacy int status indicates cmd is not complete
1416		 * sample MSIx register to see if it indiactes cmd complete,
1417		 * if yes set the controller in MSIx mode and consider cmd
1418		 * completed
1419		 */
1420		legacy_val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT;
1421		if (!(legacy_val & 1) && msix_val)
1422			dev->msi_enabled = 1;
1423		return legacy_val;
1424	}
1425
1426	return msix_val;
1427}