Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
#
# Copyright 2007 Red Hat, Inc.
# 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.
#
@@ -41,3 +41,10 @@ config SCSI_MVSAS_DEBUG
	help
		Compiles the 88SE64XX/88SE94XX driver in debug mode.  In debug mode,
		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.
+2 −4
Original line number Diff line number Diff line
@@ -471,13 +471,11 @@ static irqreturn_t mvs_64xx_isr(struct mvs_info *mvi, int irq, u32 stat)

	/* clear CMD_CMPLT ASAP */
	mw32_f(MVS_INT_STAT, CINT_DONE);
#ifndef MVS_USE_TASKLET

	spin_lock(&mvi->lock);
#endif
	mvs_int_full(mvi);
#ifndef MVS_USE_TASKLET
	spin_unlock(&mvi->lock);
#endif

	return IRQ_HANDLED;
}

+1 −4
Original line number Diff line number Diff line
@@ -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) ||
			((stat & IRQ_SAS_B) && mvi->id == 1)) {
		mw32_f(MVS_INT_STAT, CINT_DONE);
	#ifndef MVS_USE_TASKLET

		spin_lock(&mvi->lock);
	#endif
		mvs_int_full(mvi);
	#ifndef MVS_USE_TASKLET
		spin_unlock(&mvi->lock);
	#endif
	}
	return IRQ_HANDLED;
}
+28 −17
Original line number Diff line number Diff line
@@ -170,11 +170,9 @@ static void mvs_free(struct mvs_info *mvi)
	kfree(mvi);
}

#ifdef MVS_USE_TASKLET
struct tasklet_struct	mv_tasklet;
#ifdef CONFIG_SCSI_MVSAS_TASKLET
static void mvs_tasklet(unsigned long opaque)
{
	unsigned long flags;
	u32 stat;
	u16 core_nr, i = 0;

@@ -187,35 +185,49 @@ static void mvs_tasklet(unsigned long opaque)
	if (unlikely(!mvi))
		BUG_ON(1);

	stat = MVS_CHIP_DISP->isr_status(mvi, mvi->pdev->irq);
	if (!stat)
		goto out;

	for (i = 0; i < core_nr; i++) {
		mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i];
		stat = MVS_CHIP_DISP->isr_status(mvi, mvi->irq);
		if (stat)
			MVS_CHIP_DISP->isr(mvi, mvi->irq, stat);
		MVS_CHIP_DISP->isr(mvi, mvi->pdev->irq, stat);
	}
out:
	MVS_CHIP_DISP->interrupt_enable(mvi);

}
#endif

static irqreturn_t mvs_interrupt(int irq, void *opaque)
{
	u32 core_nr, i = 0;
	u32 core_nr;
	u32 stat;
	struct mvs_info *mvi;
	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;
	mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];

	if (unlikely(!mvi))
		return IRQ_NONE;
#ifdef CONFIG_SCSI_MVSAS_TASKLET
	MVS_CHIP_DISP->interrupt_disable(mvi);
#endif

	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;
	}

#ifdef MVS_USE_TASKLET
	tasklet_schedule(&mv_tasklet);
#ifdef CONFIG_SCSI_MVSAS_TASKLET
	tasklet_schedule(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
#else
	for (i = 0; i < core_nr; 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->sas = sha;
	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);
	if (!mvi->tags)
@@ -535,6 +544,7 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
{
	unsigned int rc, nhost = 0;
	struct mvs_info *mvi;
	struct mvs_prv_info *mpi;
	irq_handler_t irq_handler = mvs_interrupt;
	struct Scsi_Host *shost = NULL;
	const struct mvs_chip_info *chip;
@@ -599,8 +609,9 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
		}
		nhost++;
	} while (nhost < chip->n_host);
#ifdef MVS_USE_TASKLET
	tasklet_init(&mv_tasklet, mvs_tasklet,
	mpi = (struct mvs_prv_info *)(SHOST_TO_SAS_HA(shost)->lldd_ha);
#ifdef CONFIG_SCSI_MVSAS_TASKLET
	tasklet_init(&(mpi->mv_tasklet), mvs_tasklet,
		     (unsigned long)SHOST_TO_SAS_HA(shost));
#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;
	mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];

#ifdef MVS_USE_TASKLET
	tasklet_kill(&mv_tasklet);
#ifdef CONFIG_SCSI_MVSAS_TASKLET
	tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
#endif

	pci_set_drvdata(pdev, NULL);
+1 −0
Original line number Diff line number Diff line
@@ -420,6 +420,7 @@ struct mvs_prv_info{
	u8 scan_finished;
	u8 reserve;
	struct mvs_info *mvi[2];
	struct tasklet_struct mv_tasklet;
};

struct mvs_wq {