lkml.org 
[lkml]   [2011]   [May]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3/9] [SCSI] mvsas: Add driver version and interrupt coalescing to device attributes in sysfs
    Date
    From: Xiangliang Yu <yuxiangl@marvell.com>

    -- Add support for driver version and interrupt coalescing device attributes.

    Signed-off-by: Xiangliang Yu <yuxiangl@marvell.com>
    ---
    drivers/scsi/mvsas/mv_64xx.c | 25 +++++++++++++-
    drivers/scsi/mvsas/mv_94xx.c | 26 ++++++++++++++-
    drivers/scsi/mvsas/mv_init.c | 75 ++++++++++++++++++++++++++++++++++++++++++
    drivers/scsi/mvsas/mv_sas.h | 2 +
    4 files changed, 126 insertions(+), 2 deletions(-)

    diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c
    index 0e13e64..c88b8a7 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)
    tmp = 0;
    mw32(MVS_INT_COAL, tmp);

    - tmp = 0x100;
    + tmp = 0x10000 | interrupt_coalescing;
    mw32(MVS_INT_COAL_TMOUT, tmp);

    /* 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)
    }
    #endif

    +static void mvs_64xx_tune_interrupt(struct mvs_info *mvi, u32 time)
    +{
    + void __iomem *regs = mvi->regs;
    + u32 tmp = 0;
    + /* interrupt coalescing may cause missing HW interrput in some case,
    + * and the max count is 0x1ff, while our max slot is 0x200,
    + * it will make count 0.
    + */
    + if (time == 0) {
    + mw32(MVS_INT_COAL, 0);
    + mw32(MVS_INT_COAL_TMOUT, 0x10000);
    + } else {
    + if (MVS_CHIP_SLOT_SZ > 0x1ff)
    + mw32(MVS_INT_COAL, 0x1ff|COAL_EN);
    + else
    + mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN);
    +
    + tmp = 0x10000 | time;
    + mw32(MVS_INT_COAL_TMOUT, tmp);
    + }
    +}
    +
    const struct mvs_dispatch mvs_64xx_dispatch = {
    "mv64xx",
    mvs_64xx_init,
    @@ -811,6 +833,7 @@ const struct mvs_dispatch mvs_64xx_dispatch = {
    #ifndef DISABLE_HOTPLUG_DMA_FIX
    mvs_64xx_fix_dma,
    #endif
    + mvs_64xx_tune_interrupt,
    NULL,
    };

    diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c
    index 3f2ad93..e589f31 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)
    tmp = 0;
    mw32(MVS_INT_COAL, tmp);

    - tmp = 0x100;
    + tmp = 0x10000 | interrupt_coalescing;
    mw32(MVS_INT_COAL_TMOUT, tmp);

    /* ladies and gentlemen, start your engines */
    @@ -894,6 +894,29 @@ static void mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set,
    {
    }

    +static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time)
    +{
    + void __iomem *regs = mvi->regs;
    + u32 tmp = 0;
    + /* interrupt coalescing may cause missing HW interrput in some case,
    + * and the max count is 0x1ff, while our max slot is 0x200,
    + * it will make count 0.
    + */
    + if (time == 0) {
    + mw32(MVS_INT_COAL, 0);
    + mw32(MVS_INT_COAL_TMOUT, 0x10000);
    + } else {
    + if (MVS_CHIP_SLOT_SZ > 0x1ff)
    + mw32(MVS_INT_COAL, 0x1ff|COAL_EN);
    + else
    + mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN);
    +
    + tmp = 0x10000 | time;
    + mw32(MVS_INT_COAL_TMOUT, tmp);
    + }
    +
    +}
    +
    const struct mvs_dispatch mvs_94xx_dispatch = {
    "mv94xx",
    mvs_94xx_init,
    @@ -947,6 +970,7 @@ const struct mvs_dispatch mvs_94xx_dispatch = {
    #ifndef DISABLE_HOTPLUG_DMA_FIX
    mvs_94xx_fix_dma,
    #endif
    + mvs_94xx_tune_interrupt,
    mvs_94xx_non_spec_ncq_error,
    };

    diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
    index 9f1cccc..531093d 100644
    --- a/drivers/scsi/mvsas/mv_init.c
    +++ b/drivers/scsi/mvsas/mv_init.c
    @@ -34,6 +34,8 @@ MODULE_PARM_DESC(collector, "\n"
    "\tThe mvsas SAS LLDD supports both modes.\n"
    "\tDefault: 1 (Direct Mode).\n");

    +int interrupt_coalescing = 0x80;
    +
    static struct scsi_transport_template *mvs_stt;
    struct kmem_cache *mvs_task_list_cache;
    static const struct mvs_chip_info mvs_chips[] = {
    @@ -48,6 +50,8 @@ static const struct mvs_chip_info mvs_chips[] = {
    [chip_1320] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, },
    };

    +struct device_attribute *mvst_host_attrs[];
    +
    #define SOC_SAS_NUM 2
    #define SG_MX 64

    @@ -74,6 +78,7 @@ static struct scsi_host_template mvs_sht = {
    .slave_alloc = mvs_slave_alloc,
    .target_destroy = sas_target_destroy,
    .ioctl = sas_ioctl,
    + .shost_attrs = mvst_host_attrs,
    };

    static struct sas_domain_function_template mvs_transport_ops = {
    @@ -706,6 +711,70 @@ static struct pci_driver mvs_pci_driver = {
    .remove = __devexit_p(mvs_pci_remove),
    };

    +static ssize_t
    +mvs_show_driver_version(struct device *cdev,
    + struct device_attribute *attr, char *buffer)
    +{
    + return snprintf(buffer, PAGE_SIZE, "%s\n", DRV_VERSION);
    +}
    +
    +static DEVICE_ATTR(driver_version,
    + S_IRUGO,
    + mvs_show_driver_version,
    + NULL);
    +
    +static ssize_t
    +mvs_store_interrupt_coalescing(struct device *cdev,
    + struct device_attribute *attr,
    + const char *buffer, size_t size)
    +{
    + int val = 0;
    + struct mvs_info *mvi = NULL;
    + struct Scsi_Host *shost = class_to_shost(cdev);
    + struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
    + u8 i, core_nr;
    + if (buffer == NULL)
    + return size;
    +
    + if (sscanf(buffer, "%d", &val) != 1)
    + return -EINVAL;
    +
    + if (val >= 0x10000) {
    + mv_dprintk("interrupt coalescing timer %d us is"
    + "too long\n", val);
    + return strlen(buffer);
    + }
    +
    + interrupt_coalescing = val;
    +
    + 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 -EINVAL;
    +
    + for (i = 0; i < core_nr; i++) {
    + mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i];
    + if (MVS_CHIP_DISP->tune_interrupt)
    + MVS_CHIP_DISP->tune_interrupt(mvi,
    + interrupt_coalescing);
    + }
    + mv_dprintk("set interrupt coalescing time to %d us\n",
    + interrupt_coalescing);
    + return strlen(buffer);
    +}
    +
    +static ssize_t mvs_show_interrupt_coalescing(struct device *cdev,
    + struct device_attribute *attr, char *buffer)
    +{
    + return snprintf(buffer, PAGE_SIZE, "%d\n", interrupt_coalescing);
    +}
    +
    +static DEVICE_ATTR(interrupt_coalescing,
    + S_IRUGO|S_IWUSR,
    + mvs_show_interrupt_coalescing,
    + mvs_store_interrupt_coalescing);
    +
    /* task handler */
    struct task_struct *mvs_th;
    static int __init mvs_init(void)
    @@ -742,6 +811,12 @@ static void __exit mvs_exit(void)
    kmem_cache_destroy(mvs_task_list_cache);
    }

    +struct device_attribute *mvst_host_attrs[] = {
    + &dev_attr_driver_version,
    + &dev_attr_interrupt_coalescing,
    + NULL,
    +};
    +
    module_init(mvs_init);
    module_exit(mvs_exit);

    diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h
    index 8740b78..fed8495 100644
    --- a/drivers/scsi/mvsas/mv_sas.h
    +++ b/drivers/scsi/mvsas/mv_sas.h
    @@ -64,6 +64,7 @@
    #endif
    #define MV_MAX_U32 0xffffffff

    +extern int interrupt_coalescing;
    extern struct mvs_tgt_initiator mvs_tgt;
    extern struct mvs_info *tgt_mvi;
    extern const struct mvs_dispatch mvs_64xx_dispatch;
    @@ -170,6 +171,7 @@ struct mvs_dispatch {
    #ifndef DISABLE_HOTPLUG_DMA_FIX
    void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd);
    #endif
    + void (*tune_interrupt)(struct mvs_info *mvi, u32 time);
    void (*non_spec_ncq_error)(struct mvs_info *mvi);

    };
    --
    1.7.4.4


    \
     
     \ /
      Last update: 2011-05-24 16:35    [W:0.036 / U:0.328 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site