summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/dpcsup.c
diff options
context:
space:
mode:
authorMahesh Rajashekhara2011-03-17 10:10:32 +0100
committerJames Bottomley2011-03-23 17:36:58 +0100
commite8b12f0fb8352237525961f14ec933e915848840 (patch)
treecdbf1209bdb6dc300434a6608e5ac73d536e47c0 /drivers/scsi/aacraid/dpcsup.c
parent[SCSI] mpt2sas : Added customer specific display support (diff)
downloadkernel-qcow2-linux-e8b12f0fb8352237525961f14ec933e915848840.tar.gz
kernel-qcow2-linux-e8b12f0fb8352237525961f14ec933e915848840.tar.xz
kernel-qcow2-linux-e8b12f0fb8352237525961f14ec933e915848840.zip
[SCSI] aacraid: Add new code for PMC-Sierra's SRC based controller family
Added new hardware device 0x28b interface for PMC-Sierra's SRC based controller family. - new src.c file for 0x28b specific functions - new XPORT header required - sync. command interface: doorbell bits shifted (SRC_ODR_SHIFT, SRC_IDR_SHIFT) - async. Interface: different inbound queue handling, no outbound I2O queue available, using doorbell ("PmDoorBellResponseSent") and response buffer on the host ("host_rrq") for status - changed AIF (adapter initiated FIBs) interface: "DoorBellAifPending" bit to inform about pending AIF, "AifRequest" command to read AIF, "NoMoreAifDataAvailable" to mark the end of the AIFs Signed-off-by: Mahesh Rajashekhara <aacraid@pmc-sierra.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/aacraid/dpcsup.c')
-rw-r--r--drivers/scsi/aacraid/dpcsup.c85
1 files changed, 74 insertions, 11 deletions
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index 9c7408fe8c7d..f0c66a80ad13 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -5,7 +5,8 @@
* based on the old aacraid driver that is..
* Adaptec aacraid device driver for Linux.
*
- * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com)
+ * Copyright (c) 2000-2010 Adaptec, Inc.
+ * 2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -228,6 +229,48 @@ unsigned int aac_command_normal(struct aac_queue *q)
return 0;
}
+/*
+ *
+ * aac_aif_callback
+ * @context: the context set in the fib - here it is scsi cmd
+ * @fibptr: pointer to the fib
+ *
+ * Handles the AIFs - new method (SRC)
+ *
+ */
+
+static void aac_aif_callback(void *context, struct fib * fibptr)
+{
+ struct fib *fibctx;
+ struct aac_dev *dev;
+ struct aac_aifcmd *cmd;
+ int status;
+
+ fibctx = (struct fib *)context;
+ BUG_ON(fibptr == NULL);
+ dev = fibptr->dev;
+
+ if (fibptr->hw_fib_va->header.XferState &
+ cpu_to_le32(NoMoreAifDataAvailable)) {
+ aac_fib_complete(fibptr);
+ aac_fib_free(fibptr);
+ return;
+ }
+
+ aac_intr_normal(dev, 0, 1, 0, fibptr->hw_fib_va);
+
+ aac_fib_init(fibctx);
+ cmd = (struct aac_aifcmd *) fib_data(fibctx);
+ cmd->command = cpu_to_le32(AifReqEvent);
+
+ status = aac_fib_send(AifRequest,
+ fibctx,
+ sizeof(struct hw_fib)-sizeof(struct aac_fibhdr),
+ FsaNormal,
+ 0, 1,
+ (fib_callback)aac_aif_callback, fibctx);
+}
+
/**
* aac_intr_normal - Handle command replies
@@ -238,19 +281,17 @@ unsigned int aac_command_normal(struct aac_queue *q)
* know there is a response on our normal priority queue. We will pull off
* all QE there are and wake up all the waiters before exiting.
*/
-
-unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
+unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
+ int isAif, int isFastResponse, struct hw_fib *aif_fib)
{
unsigned long mflags;
dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index));
- if ((index & 0x00000002L)) {
+ if (isAif == 1) { /* AIF - common */
struct hw_fib * hw_fib;
struct fib * fib;
struct aac_queue *q = &dev->queues->queue[HostNormCmdQueue];
unsigned long flags;
- if (index == 0xFFFFFFFEL) /* Special Case */
- return 0; /* Do nothing */
/*
* Allocate a FIB. For non queued stuff we can just use
* the stack so we are happy. We need a fib object in order to
@@ -263,8 +304,13 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
kfree (fib);
return 1;
}
- memcpy(hw_fib, (struct hw_fib *)(((uintptr_t)(dev->regs.sa)) +
- (index & ~0x00000002L)), sizeof(struct hw_fib));
+ if (aif_fib != NULL) {
+ memcpy(hw_fib, aif_fib, sizeof(struct hw_fib));
+ } else {
+ memcpy(hw_fib,
+ (struct hw_fib *)(((uintptr_t)(dev->regs.sa)) +
+ index), sizeof(struct hw_fib));
+ }
INIT_LIST_HEAD(&fib->fiblink);
fib->type = FSAFS_NTC_FIB_CONTEXT;
fib->size = sizeof(struct fib);
@@ -277,9 +323,26 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
wake_up_interruptible(&q->cmdready);
spin_unlock_irqrestore(q->lock, flags);
return 1;
+ } else if (isAif == 2) { /* AIF - new (SRC) */
+ struct fib *fibctx;
+ struct aac_aifcmd *cmd;
+
+ fibctx = aac_fib_alloc(dev);
+ if (!fibctx)
+ return 1;
+ aac_fib_init(fibctx);
+
+ cmd = (struct aac_aifcmd *) fib_data(fibctx);
+ cmd->command = cpu_to_le32(AifReqEvent);
+
+ return aac_fib_send(AifRequest,
+ fibctx,
+ sizeof(struct hw_fib)-sizeof(struct aac_fibhdr),
+ FsaNormal,
+ 0, 1,
+ (fib_callback)aac_aif_callback, fibctx);
} else {
- int fast = index & 0x01;
- struct fib * fib = &dev->fibs[index >> 2];
+ struct fib *fib = &dev->fibs[index];
struct hw_fib * hwfib = fib->hw_fib_va;
/*
@@ -298,7 +361,7 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
return 0;
}
- if (fast) {
+ if (isFastResponse) {
/*
* Doctor the fib
*/