diff options
| author | Xiangliang Yu <yuxiangl@marvell.com> | 2011-06-30 22:27:36 +0800 | 
|---|---|---|
| committer | James Bottomley <JBottomley@Parallels.com> | 2011-07-26 12:59:55 +0400 | 
| commit | 6f8ac161b8b3332a9d96d6650ed3bae81baab30b (patch) | |
| tree | 2cd89c7bbe9678ad5ec38cd9a15df726e01731a4 | |
| parent | e144f7ef49ec85e9dfdf130f3a9a2372fe5fe39b (diff) | |
| download | olio-linux-3.10-6f8ac161b8b3332a9d96d6650ed3bae81baab30b.tar.xz olio-linux-3.10-6f8ac161b8b3332a9d96d6650ed3bae81baab30b.zip  | |
[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>
| -rw-r--r-- | drivers/scsi/mvsas/Kconfig | 9 | ||||
| -rw-r--r-- | drivers/scsi/mvsas/mv_64xx.c | 6 | ||||
| -rw-r--r-- | drivers/scsi/mvsas/mv_94xx.c | 5 | ||||
| -rw-r--r-- | drivers/scsi/mvsas/mv_init.c | 45 | ||||
| -rw-r--r-- | drivers/scsi/mvsas/mv_sas.h | 1 | 
5 files changed, 40 insertions, 26 deletions
diff --git a/drivers/scsi/mvsas/Kconfig b/drivers/scsi/mvsas/Kconfig index c82b012aba3..78f7e20a0c1 100644 --- a/drivers/scsi/mvsas/Kconfig +++ b/drivers/scsi/mvsas/Kconfig @@ -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. diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c index dec5f96f47a..8ba47229049 100644 --- a/drivers/scsi/mvsas/mv_64xx.c +++ b/drivers/scsi/mvsas/mv_64xx.c @@ -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;  } diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index f4a995c29eb..3501291618f 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c @@ -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;  } diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index cf4aaa9db5f..4e9af66fd1d 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -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); diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index 25fae4f6aff..44d7885a4a1 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -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 {  |