[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: Xiangliang Yu <yuxiangl@marvell.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Родитель
e144f7ef49
Коммит
6f8ac161b8
|
@ -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
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
}
|
}
|
||||||
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)
|
||||||
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{
|
||||||
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 {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче