aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/mvsas/Kconfig9
-rw-r--r--drivers/scsi/mvsas/mv_64xx.c6
-rw-r--r--drivers/scsi/mvsas/mv_94xx.c5
-rw-r--r--drivers/scsi/mvsas/mv_init.c45
-rw-r--r--drivers/scsi/mvsas/mv_sas.h1
5 files changed, 40 insertions, 26 deletions
diff --git a/drivers/scsi/mvsas/Kconfig b/drivers/scsi/mvsas/Kconfig
index c82b012aba37..78f7e20a0c1c 100644
--- a/drivers/scsi/mvsas/Kconfig
+++ b/drivers/scsi/mvsas/Kconfig
@@ -3,7 +3,7 @@
3# 3#
4# Copyright 2007 Red Hat, Inc. 4# Copyright 2007 Red Hat, Inc.
5# Copyright 2008 Marvell. <kewei@marvell.com> 5# Copyright 2008 Marvell. <kewei@marvell.com>
6# Copyright 2009-20011 Marvell. <yuxiangl@marvell.com> 6# Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
7# 7#
8# This file is licensed under GPLv2. 8# This file is licensed under GPLv2.
9# 9#
@@ -41,3 +41,10 @@ config SCSI_MVSAS_DEBUG
41 help 41 help
42 Compiles the 88SE64XX/88SE94XX driver in debug mode. In debug mode, 42 Compiles the 88SE64XX/88SE94XX driver in debug mode. In debug mode,
43 the driver prints some messages to the console. 43 the driver prints some messages to the console.
44config SCSI_MVSAS_TASKLET
45 bool "Support for interrupt tasklet"
46 default n
47 depends on SCSI_MVSAS
48 help
49 Compiles the 88SE64xx/88SE94xx driver in interrupt tasklet mode.In this mode,
50 the interrupt will schedule a tasklet.
diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c
index dec5f96f47a0..8ba47229049f 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)
471 471
472 /* clear CMD_CMPLT ASAP */ 472 /* clear CMD_CMPLT ASAP */
473 mw32_f(MVS_INT_STAT, CINT_DONE); 473 mw32_f(MVS_INT_STAT, CINT_DONE);
474#ifndef MVS_USE_TASKLET 474
475 spin_lock(&mvi->lock); 475 spin_lock(&mvi->lock);
476#endif
477 mvs_int_full(mvi); 476 mvs_int_full(mvi);
478#ifndef MVS_USE_TASKLET
479 spin_unlock(&mvi->lock); 477 spin_unlock(&mvi->lock);
480#endif 478
481 return IRQ_HANDLED; 479 return IRQ_HANDLED;
482} 480}
483 481
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c
index f4a995c29eb1..3501291618fd 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)
579 if (((stat & IRQ_SAS_A) && mvi->id == 0) || 579 if (((stat & IRQ_SAS_A) && mvi->id == 0) ||
580 ((stat & IRQ_SAS_B) && mvi->id == 1)) { 580 ((stat & IRQ_SAS_B) && mvi->id == 1)) {
581 mw32_f(MVS_INT_STAT, CINT_DONE); 581 mw32_f(MVS_INT_STAT, CINT_DONE);
582 #ifndef MVS_USE_TASKLET 582
583 spin_lock(&mvi->lock); 583 spin_lock(&mvi->lock);
584 #endif
585 mvs_int_full(mvi); 584 mvs_int_full(mvi);
586 #ifndef MVS_USE_TASKLET
587 spin_unlock(&mvi->lock); 585 spin_unlock(&mvi->lock);
588 #endif
589 } 586 }
590 return IRQ_HANDLED; 587 return IRQ_HANDLED;
591} 588}
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index cf4aaa9db5fe..4e9af66fd1d3 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)
170 kfree(mvi); 170 kfree(mvi);
171} 171}
172 172
173#ifdef MVS_USE_TASKLET 173#ifdef CONFIG_SCSI_MVSAS_TASKLET
174struct tasklet_struct mv_tasklet;
175static void mvs_tasklet(unsigned long opaque) 174static void mvs_tasklet(unsigned long opaque)
176{ 175{
177 unsigned long flags;
178 u32 stat; 176 u32 stat;
179 u16 core_nr, i = 0; 177 u16 core_nr, i = 0;
180 178
@@ -187,35 +185,49 @@ static void mvs_tasklet(unsigned long opaque)
187 if (unlikely(!mvi)) 185 if (unlikely(!mvi))
188 BUG_ON(1); 186 BUG_ON(1);
189 187
188 stat = MVS_CHIP_DISP->isr_status(mvi, mvi->pdev->irq);
189 if (!stat)
190 goto out;
191
190 for (i = 0; i < core_nr; i++) { 192 for (i = 0; i < core_nr; i++) {
191 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; 193 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i];
192 stat = MVS_CHIP_DISP->isr_status(mvi, mvi->irq); 194 MVS_CHIP_DISP->isr(mvi, mvi->pdev->irq, stat);
193 if (stat)
194 MVS_CHIP_DISP->isr(mvi, mvi->irq, stat);
195 } 195 }
196out:
197 MVS_CHIP_DISP->interrupt_enable(mvi);
196 198
197} 199}
198#endif 200#endif
199 201
200static irqreturn_t mvs_interrupt(int irq, void *opaque) 202static irqreturn_t mvs_interrupt(int irq, void *opaque)
201{ 203{
202 u32 core_nr, i = 0; 204 u32 core_nr;
203 u32 stat; 205 u32 stat;
204 struct mvs_info *mvi; 206 struct mvs_info *mvi;
205 struct sas_ha_struct *sha = opaque; 207 struct sas_ha_struct *sha = opaque;
208#ifndef CONFIG_SCSI_MVSAS_TASKLET
209 u32 i;
210#endif
206 211
207 core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; 212 core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
208 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; 213 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];
209 214
210 if (unlikely(!mvi)) 215 if (unlikely(!mvi))
211 return IRQ_NONE; 216 return IRQ_NONE;
217#ifdef CONFIG_SCSI_MVSAS_TASKLET
218 MVS_CHIP_DISP->interrupt_disable(mvi);
219#endif
212 220
213 stat = MVS_CHIP_DISP->isr_status(mvi, irq); 221 stat = MVS_CHIP_DISP->isr_status(mvi, irq);
214 if (!stat) 222 if (!stat) {
223 #ifdef CONFIG_SCSI_MVSAS_TASKLET
224 MVS_CHIP_DISP->interrupt_enable(mvi);
225 #endif
215 return IRQ_NONE; 226 return IRQ_NONE;
227 }
216 228
217#ifdef MVS_USE_TASKLET 229#ifdef CONFIG_SCSI_MVSAS_TASKLET
218 tasklet_schedule(&mv_tasklet); 230 tasklet_schedule(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
219#else 231#else
220 for (i = 0; i < core_nr; i++) { 232 for (i = 0; i < core_nr; i++) {
221 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; 233 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 mvi->id = id; 400 mvi->id = id;
389 mvi->sas = sha; 401 mvi->sas = sha;
390 mvi->shost = shost; 402 mvi->shost = shost;
391#ifdef MVS_USE_TASKLET
392 tasklet_init(&mv_tasklet, mvs_tasklet, (unsigned long)sha);
393#endif
394 403
395 mvi->tags = kzalloc(MVS_CHIP_SLOT_SZ>>3, GFP_KERNEL); 404 mvi->tags = kzalloc(MVS_CHIP_SLOT_SZ>>3, GFP_KERNEL);
396 if (!mvi->tags) 405 if (!mvi->tags)
@@ -535,6 +544,7 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
535{ 544{
536 unsigned int rc, nhost = 0; 545 unsigned int rc, nhost = 0;
537 struct mvs_info *mvi; 546 struct mvs_info *mvi;
547 struct mvs_prv_info *mpi;
538 irq_handler_t irq_handler = mvs_interrupt; 548 irq_handler_t irq_handler = mvs_interrupt;
539 struct Scsi_Host *shost = NULL; 549 struct Scsi_Host *shost = NULL;
540 const struct mvs_chip_info *chip; 550 const struct mvs_chip_info *chip;
@@ -599,8 +609,9 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
599 } 609 }
600 nhost++; 610 nhost++;
601 } while (nhost < chip->n_host); 611 } while (nhost < chip->n_host);
602#ifdef MVS_USE_TASKLET 612 mpi = (struct mvs_prv_info *)(SHOST_TO_SAS_HA(shost)->lldd_ha);
603 tasklet_init(&mv_tasklet, mvs_tasklet, 613#ifdef CONFIG_SCSI_MVSAS_TASKLET
614 tasklet_init(&(mpi->mv_tasklet), mvs_tasklet,
604 (unsigned long)SHOST_TO_SAS_HA(shost)); 615 (unsigned long)SHOST_TO_SAS_HA(shost));
605#endif 616#endif
606 617
@@ -645,8 +656,8 @@ static void __devexit mvs_pci_remove(struct pci_dev *pdev)
645 core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; 656 core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
646 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; 657 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];
647 658
648#ifdef MVS_USE_TASKLET 659#ifdef CONFIG_SCSI_MVSAS_TASKLET
649 tasklet_kill(&mv_tasklet); 660 tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
650#endif 661#endif
651 662
652 pci_set_drvdata(pdev, NULL); 663 pci_set_drvdata(pdev, NULL);
diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h
index 25fae4f6aff2..44d7885a4a1d 100644
--- a/drivers/scsi/mvsas/mv_sas.h
+++ b/drivers/scsi/mvsas/mv_sas.h
@@ -420,6 +420,7 @@ struct mvs_prv_info{
420 u8 scan_finished; 420 u8 scan_finished;
421 u8 reserve; 421 u8 reserve;
422 struct mvs_info *mvi[2]; 422 struct mvs_info *mvi[2];
423 struct tasklet_struct mv_tasklet;
423}; 424};
424 425
425struct mvs_wq { 426struct mvs_wq {