Commit 6f8ac161 authored by Xiangliang Yu's avatar Xiangliang Yu Committed by James Bottomley

[SCSI] mvsas: Add support for interrupt tasklet

Add support for interrupt tasklet, which will improve performance.
Correct spelling of "20011"

[jejb: simplified ifdefs and fixed unused variable problem]
Signed-off-by: default avatarXiangliang Yu <yuxiangl@marvell.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent e144f7ef
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
# Copyright 2007 Red Hat, Inc. # Copyright 2007 Red Hat, Inc.
# Copyright 2008 Marvell. <kewei@marvell.com> # Copyright 2008 Marvell. <kewei@marvell.com>
# Copyright 2009-20011 Marvell. <yuxiangl@marvell.com> # Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
# #
# This file is licensed under GPLv2. # This file is licensed under GPLv2.
# #
...@@ -41,3 +41,10 @@ config SCSI_MVSAS_DEBUG ...@@ -41,3 +41,10 @@ config SCSI_MVSAS_DEBUG
help help
Compiles the 88SE64XX/88SE94XX driver in debug mode. In debug mode, Compiles the 88SE64XX/88SE94XX driver in debug mode. In debug mode,
the driver prints some messages to the console. the driver prints some messages to the console.
config SCSI_MVSAS_TASKLET
bool "Support for interrupt tasklet"
default n
depends on SCSI_MVSAS
help
Compiles the 88SE64xx/88SE94xx driver in interrupt tasklet mode.In this mode,
the interrupt will schedule a tasklet.
...@@ -471,13 +471,11 @@ static irqreturn_t mvs_64xx_isr(struct mvs_info *mvi, int irq, u32 stat) ...@@ -471,13 +471,11 @@ static irqreturn_t mvs_64xx_isr(struct mvs_info *mvi, int irq, u32 stat)
/* clear CMD_CMPLT ASAP */ /* clear CMD_CMPLT ASAP */
mw32_f(MVS_INT_STAT, CINT_DONE); mw32_f(MVS_INT_STAT, CINT_DONE);
#ifndef MVS_USE_TASKLET
spin_lock(&mvi->lock); spin_lock(&mvi->lock);
#endif
mvs_int_full(mvi); mvs_int_full(mvi);
#ifndef MVS_USE_TASKLET
spin_unlock(&mvi->lock); spin_unlock(&mvi->lock);
#endif
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -579,13 +579,10 @@ static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat) ...@@ -579,13 +579,10 @@ static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat)
if (((stat & IRQ_SAS_A) && mvi->id == 0) || if (((stat & IRQ_SAS_A) && mvi->id == 0) ||
((stat & IRQ_SAS_B) && mvi->id == 1)) { ((stat & IRQ_SAS_B) && mvi->id == 1)) {
mw32_f(MVS_INT_STAT, CINT_DONE); mw32_f(MVS_INT_STAT, CINT_DONE);
#ifndef MVS_USE_TASKLET
spin_lock(&mvi->lock); spin_lock(&mvi->lock);
#endif
mvs_int_full(mvi); mvs_int_full(mvi);
#ifndef MVS_USE_TASKLET
spin_unlock(&mvi->lock); spin_unlock(&mvi->lock);
#endif
} }
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -170,11 +170,9 @@ static void mvs_free(struct mvs_info *mvi) ...@@ -170,11 +170,9 @@ static void mvs_free(struct mvs_info *mvi)
kfree(mvi); kfree(mvi);
} }
#ifdef MVS_USE_TASKLET #ifdef CONFIG_SCSI_MVSAS_TASKLET
struct tasklet_struct mv_tasklet;
static void mvs_tasklet(unsigned long opaque) static void mvs_tasklet(unsigned long opaque)
{ {
unsigned long flags;
u32 stat; u32 stat;
u16 core_nr, i = 0; u16 core_nr, i = 0;
...@@ -187,35 +185,49 @@ static void mvs_tasklet(unsigned long opaque) ...@@ -187,35 +185,49 @@ static void mvs_tasklet(unsigned long opaque)
if (unlikely(!mvi)) if (unlikely(!mvi))
BUG_ON(1); BUG_ON(1);
stat = MVS_CHIP_DISP->isr_status(mvi, mvi->pdev->irq);
if (!stat)
goto out;
for (i = 0; i < core_nr; i++) { for (i = 0; i < core_nr; i++) {
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i];
stat = MVS_CHIP_DISP->isr_status(mvi, mvi->irq); MVS_CHIP_DISP->isr(mvi, mvi->pdev->irq, stat);
if (stat)
MVS_CHIP_DISP->isr(mvi, mvi->irq, stat);
} }
out:
MVS_CHIP_DISP->interrupt_enable(mvi);
} }
#endif #endif
static irqreturn_t mvs_interrupt(int irq, void *opaque) static irqreturn_t mvs_interrupt(int irq, void *opaque)
{ {
u32 core_nr, i = 0; u32 core_nr;
u32 stat; u32 stat;
struct mvs_info *mvi; struct mvs_info *mvi;
struct sas_ha_struct *sha = opaque; struct sas_ha_struct *sha = opaque;
#ifndef CONFIG_SCSI_MVSAS_TASKLET
u32 i;
#endif
core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];
if (unlikely(!mvi)) if (unlikely(!mvi))
return IRQ_NONE; return IRQ_NONE;
#ifdef CONFIG_SCSI_MVSAS_TASKLET
MVS_CHIP_DISP->interrupt_disable(mvi);
#endif
stat = MVS_CHIP_DISP->isr_status(mvi, irq); stat = MVS_CHIP_DISP->isr_status(mvi, irq);
if (!stat) if (!stat) {
#ifdef CONFIG_SCSI_MVSAS_TASKLET
MVS_CHIP_DISP->interrupt_enable(mvi);
#endif
return IRQ_NONE; return IRQ_NONE;
}
#ifdef MVS_USE_TASKLET #ifdef CONFIG_SCSI_MVSAS_TASKLET
tasklet_schedule(&mv_tasklet); tasklet_schedule(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
#else #else
for (i = 0; i < core_nr; i++) { for (i = 0; i < core_nr; i++) {
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i];
...@@ -388,9 +400,6 @@ static struct mvs_info *__devinit mvs_pci_alloc(struct pci_dev *pdev, ...@@ -388,9 +400,6 @@ static struct mvs_info *__devinit mvs_pci_alloc(struct pci_dev *pdev,
mvi->id = id; mvi->id = id;
mvi->sas = sha; mvi->sas = sha;
mvi->shost = shost; mvi->shost = shost;
#ifdef MVS_USE_TASKLET
tasklet_init(&mv_tasklet, mvs_tasklet, (unsigned long)sha);
#endif
mvi->tags = kzalloc(MVS_CHIP_SLOT_SZ>>3, GFP_KERNEL); mvi->tags = kzalloc(MVS_CHIP_SLOT_SZ>>3, GFP_KERNEL);
if (!mvi->tags) if (!mvi->tags)
...@@ -535,6 +544,7 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev, ...@@ -535,6 +544,7 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
{ {
unsigned int rc, nhost = 0; unsigned int rc, nhost = 0;
struct mvs_info *mvi; struct mvs_info *mvi;
struct mvs_prv_info *mpi;
irq_handler_t irq_handler = mvs_interrupt; irq_handler_t irq_handler = mvs_interrupt;
struct Scsi_Host *shost = NULL; struct Scsi_Host *shost = NULL;
const struct mvs_chip_info *chip; const struct mvs_chip_info *chip;
...@@ -599,8 +609,9 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev, ...@@ -599,8 +609,9 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
} }
nhost++; nhost++;
} while (nhost < chip->n_host); } while (nhost < chip->n_host);
#ifdef MVS_USE_TASKLET mpi = (struct mvs_prv_info *)(SHOST_TO_SAS_HA(shost)->lldd_ha);
tasklet_init(&mv_tasklet, mvs_tasklet, #ifdef CONFIG_SCSI_MVSAS_TASKLET
tasklet_init(&(mpi->mv_tasklet), mvs_tasklet,
(unsigned long)SHOST_TO_SAS_HA(shost)); (unsigned long)SHOST_TO_SAS_HA(shost));
#endif #endif
...@@ -645,8 +656,8 @@ static void __devexit mvs_pci_remove(struct pci_dev *pdev) ...@@ -645,8 +656,8 @@ static void __devexit mvs_pci_remove(struct pci_dev *pdev)
core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];
#ifdef MVS_USE_TASKLET #ifdef CONFIG_SCSI_MVSAS_TASKLET
tasklet_kill(&mv_tasklet); tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
#endif #endif
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
......
...@@ -420,6 +420,7 @@ struct mvs_prv_info{ ...@@ -420,6 +420,7 @@ struct mvs_prv_info{
u8 scan_finished; u8 scan_finished;
u8 reserve; u8 reserve;
struct mvs_info *mvi[2]; struct mvs_info *mvi[2];
struct tasklet_struct mv_tasklet;
}; };
struct mvs_wq { struct mvs_wq {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment