aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorXiangliang Yu <yuxiangl@marvell.com>2011-05-24 10:31:47 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-26 02:33:11 -0400
commit83c7b61cf49c2659829050fec240601415c7f9d9 (patch)
tree44dda12fb01e6e6d4e1a3e9b0f9994ed72b16c00 /drivers/scsi
parentf1f82a919d7fff21ee8c0ef4b9731fb38f2a65db (diff)
[SCSI] mvsas: Add driver version and interrupt coalescing to device attributes in sysfs
Signed-off-by: Xiangliang Yu <yuxiangl@marvell.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/mvsas/mv_64xx.c25
-rw-r--r--drivers/scsi/mvsas/mv_94xx.c26
-rw-r--r--drivers/scsi/mvsas/mv_init.c75
-rw-r--r--drivers/scsi/mvsas/mv_sas.h2
4 files changed, 126 insertions, 2 deletions
diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c
index 0e13e6441da..c88b8a7ed39 100644
--- a/drivers/scsi/mvsas/mv_64xx.c
+++ b/drivers/scsi/mvsas/mv_64xx.c
@@ -402,7 +402,7 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi)
402 tmp = 0; 402 tmp = 0;
403 mw32(MVS_INT_COAL, tmp); 403 mw32(MVS_INT_COAL, tmp);
404 404
405 tmp = 0x100; 405 tmp = 0x10000 | interrupt_coalescing;
406 mw32(MVS_INT_COAL_TMOUT, tmp); 406 mw32(MVS_INT_COAL_TMOUT, tmp);
407 407
408 /* ladies and gentlemen, start your engines */ 408 /* ladies and gentlemen, start your engines */
@@ -758,6 +758,28 @@ void mvs_64xx_fix_dma(dma_addr_t buf_dma, int buf_len, int from, void *prd)
758} 758}
759#endif 759#endif
760 760
761static void mvs_64xx_tune_interrupt(struct mvs_info *mvi, u32 time)
762{
763 void __iomem *regs = mvi->regs;
764 u32 tmp = 0;
765 /* interrupt coalescing may cause missing HW interrput in some case,
766 * and the max count is 0x1ff, while our max slot is 0x200,
767 * it will make count 0.
768 */
769 if (time == 0) {
770 mw32(MVS_INT_COAL, 0);
771 mw32(MVS_INT_COAL_TMOUT, 0x10000);
772 } else {
773 if (MVS_CHIP_SLOT_SZ > 0x1ff)
774 mw32(MVS_INT_COAL, 0x1ff|COAL_EN);
775 else
776 mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN);
777
778 tmp = 0x10000 | time;
779 mw32(MVS_INT_COAL_TMOUT, tmp);
780 }
781}
782
761const struct mvs_dispatch mvs_64xx_dispatch = { 783const struct mvs_dispatch mvs_64xx_dispatch = {
762 "mv64xx", 784 "mv64xx",
763 mvs_64xx_init, 785 mvs_64xx_init,
@@ -811,6 +833,7 @@ const struct mvs_dispatch mvs_64xx_dispatch = {
811#ifndef DISABLE_HOTPLUG_DMA_FIX 833#ifndef DISABLE_HOTPLUG_DMA_FIX
812 mvs_64xx_fix_dma, 834 mvs_64xx_fix_dma,
813#endif 835#endif
836 mvs_64xx_tune_interrupt,
814 NULL, 837 NULL,
815}; 838};
816 839
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c
index 3f2ad934c91..e589f31cb2b 100644
--- a/drivers/scsi/mvsas/mv_94xx.c
+++ b/drivers/scsi/mvsas/mv_94xx.c
@@ -475,7 +475,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi)
475 tmp = 0; 475 tmp = 0;
476 mw32(MVS_INT_COAL, tmp); 476 mw32(MVS_INT_COAL, tmp);
477 477
478 tmp = 0x100; 478 tmp = 0x10000 | interrupt_coalescing;
479 mw32(MVS_INT_COAL_TMOUT, tmp); 479 mw32(MVS_INT_COAL_TMOUT, tmp);
480 480
481 /* ladies and gentlemen, start your engines */ 481 /* ladies and gentlemen, start your engines */
@@ -894,6 +894,29 @@ static void mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set,
894{ 894{
895} 895}
896 896
897static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time)
898{
899 void __iomem *regs = mvi->regs;
900 u32 tmp = 0;
901 /* interrupt coalescing may cause missing HW interrput in some case,
902 * and the max count is 0x1ff, while our max slot is 0x200,
903 * it will make count 0.
904 */
905 if (time == 0) {
906 mw32(MVS_INT_COAL, 0);
907 mw32(MVS_INT_COAL_TMOUT, 0x10000);
908 } else {
909 if (MVS_CHIP_SLOT_SZ > 0x1ff)
910 mw32(MVS_INT_COAL, 0x1ff|COAL_EN);
911 else
912 mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN);
913
914 tmp = 0x10000 | time;
915 mw32(MVS_INT_COAL_TMOUT, tmp);
916 }
917
918}
919
897const struct mvs_dispatch mvs_94xx_dispatch = { 920const struct mvs_dispatch mvs_94xx_dispatch = {
898 "mv94xx", 921 "mv94xx",
899 mvs_94xx_init, 922 mvs_94xx_init,
@@ -947,6 +970,7 @@ const struct mvs_dispatch mvs_94xx_dispatch = {
947#ifndef DISABLE_HOTPLUG_DMA_FIX 970#ifndef DISABLE_HOTPLUG_DMA_FIX
948 mvs_94xx_fix_dma, 971 mvs_94xx_fix_dma,
949#endif 972#endif
973 mvs_94xx_tune_interrupt,
950 mvs_94xx_non_spec_ncq_error, 974 mvs_94xx_non_spec_ncq_error,
951}; 975};
952 976
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 9f1cccc2a3e..531093ddc41 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -34,6 +34,8 @@ MODULE_PARM_DESC(collector, "\n"
34 "\tThe mvsas SAS LLDD supports both modes.\n" 34 "\tThe mvsas SAS LLDD supports both modes.\n"
35 "\tDefault: 1 (Direct Mode).\n"); 35 "\tDefault: 1 (Direct Mode).\n");
36 36
37int interrupt_coalescing = 0x80;
38
37static struct scsi_transport_template *mvs_stt; 39static struct scsi_transport_template *mvs_stt;
38struct kmem_cache *mvs_task_list_cache; 40struct kmem_cache *mvs_task_list_cache;
39static const struct mvs_chip_info mvs_chips[] = { 41static const struct mvs_chip_info mvs_chips[] = {
@@ -48,6 +50,8 @@ static const struct mvs_chip_info mvs_chips[] = {
48 [chip_1320] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, }, 50 [chip_1320] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, },
49}; 51};
50 52
53struct device_attribute *mvst_host_attrs[];
54
51#define SOC_SAS_NUM 2 55#define SOC_SAS_NUM 2
52#define SG_MX 64 56#define SG_MX 64
53 57
@@ -74,6 +78,7 @@ static struct scsi_host_template mvs_sht = {
74 .slave_alloc = mvs_slave_alloc, 78 .slave_alloc = mvs_slave_alloc,
75 .target_destroy = sas_target_destroy, 79 .target_destroy = sas_target_destroy,
76 .ioctl = sas_ioctl, 80 .ioctl = sas_ioctl,
81 .shost_attrs = mvst_host_attrs,
77}; 82};
78 83
79static struct sas_domain_function_template mvs_transport_ops = { 84static struct sas_domain_function_template mvs_transport_ops = {
@@ -706,6 +711,70 @@ static struct pci_driver mvs_pci_driver = {
706 .remove = __devexit_p(mvs_pci_remove), 711 .remove = __devexit_p(mvs_pci_remove),
707}; 712};
708 713
714static ssize_t
715mvs_show_driver_version(struct device *cdev,
716 struct device_attribute *attr, char *buffer)
717{
718 return snprintf(buffer, PAGE_SIZE, "%s\n", DRV_VERSION);
719}
720
721static DEVICE_ATTR(driver_version,
722 S_IRUGO,
723 mvs_show_driver_version,
724 NULL);
725
726static ssize_t
727mvs_store_interrupt_coalescing(struct device *cdev,
728 struct device_attribute *attr,
729 const char *buffer, size_t size)
730{
731 int val = 0;
732 struct mvs_info *mvi = NULL;
733 struct Scsi_Host *shost = class_to_shost(cdev);
734 struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
735 u8 i, core_nr;
736 if (buffer == NULL)
737 return size;
738
739 if (sscanf(buffer, "%d", &val) != 1)
740 return -EINVAL;
741
742 if (val >= 0x10000) {
743 mv_dprintk("interrupt coalescing timer %d us is"
744 "too long\n", val);
745 return strlen(buffer);
746 }
747
748 interrupt_coalescing = val;
749
750 core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
751 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];
752
753 if (unlikely(!mvi))
754 return -EINVAL;
755
756 for (i = 0; i < core_nr; i++) {
757 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i];
758 if (MVS_CHIP_DISP->tune_interrupt)
759 MVS_CHIP_DISP->tune_interrupt(mvi,
760 interrupt_coalescing);
761 }
762 mv_dprintk("set interrupt coalescing time to %d us\n",
763 interrupt_coalescing);
764 return strlen(buffer);
765}
766
767static ssize_t mvs_show_interrupt_coalescing(struct device *cdev,
768 struct device_attribute *attr, char *buffer)
769{
770 return snprintf(buffer, PAGE_SIZE, "%d\n", interrupt_coalescing);
771}
772
773static DEVICE_ATTR(interrupt_coalescing,
774 S_IRUGO|S_IWUSR,
775 mvs_show_interrupt_coalescing,
776 mvs_store_interrupt_coalescing);
777
709/* task handler */ 778/* task handler */
710struct task_struct *mvs_th; 779struct task_struct *mvs_th;
711static int __init mvs_init(void) 780static int __init mvs_init(void)
@@ -742,6 +811,12 @@ static void __exit mvs_exit(void)
742 kmem_cache_destroy(mvs_task_list_cache); 811 kmem_cache_destroy(mvs_task_list_cache);
743} 812}
744 813
814struct device_attribute *mvst_host_attrs[] = {
815 &dev_attr_driver_version,
816 &dev_attr_interrupt_coalescing,
817 NULL,
818};
819
745module_init(mvs_init); 820module_init(mvs_init);
746module_exit(mvs_exit); 821module_exit(mvs_exit);
747 822
diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h
index ccd622f7f84..089ef1ef386 100644
--- a/drivers/scsi/mvsas/mv_sas.h
+++ b/drivers/scsi/mvsas/mv_sas.h
@@ -64,6 +64,7 @@
64#endif 64#endif
65#define MV_MAX_U32 0xffffffff 65#define MV_MAX_U32 0xffffffff
66 66
67extern int interrupt_coalescing;
67extern struct mvs_tgt_initiator mvs_tgt; 68extern struct mvs_tgt_initiator mvs_tgt;
68extern struct mvs_info *tgt_mvi; 69extern struct mvs_info *tgt_mvi;
69extern const struct mvs_dispatch mvs_64xx_dispatch; 70extern const struct mvs_dispatch mvs_64xx_dispatch;
@@ -170,6 +171,7 @@ struct mvs_dispatch {
170#ifndef DISABLE_HOTPLUG_DMA_FIX 171#ifndef DISABLE_HOTPLUG_DMA_FIX
171 void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd); 172 void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd);
172#endif 173#endif
174 void (*tune_interrupt)(struct mvs_info *mvi, u32 time);
173 void (*non_spec_ncq_error)(struct mvs_info *mvi); 175 void (*non_spec_ncq_error)(struct mvs_info *mvi);
174 176
175}; 177};