mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-11 07:30:16 +00:00
[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>
This commit is contained in:
parent
f1f82a919d
commit
83c7b61cf4
@ -402,7 +402,7 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi)
|
|||||||
tmp = 0;
|
tmp = 0;
|
||||||
mw32(MVS_INT_COAL, tmp);
|
mw32(MVS_INT_COAL, tmp);
|
||||||
|
|
||||||
tmp = 0x100;
|
tmp = 0x10000 | interrupt_coalescing;
|
||||||
mw32(MVS_INT_COAL_TMOUT, tmp);
|
mw32(MVS_INT_COAL_TMOUT, tmp);
|
||||||
|
|
||||||
/* ladies and gentlemen, start your engines */
|
/* 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
|
#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 = {
|
const struct mvs_dispatch mvs_64xx_dispatch = {
|
||||||
"mv64xx",
|
"mv64xx",
|
||||||
mvs_64xx_init,
|
mvs_64xx_init,
|
||||||
@ -811,6 +833,7 @@ const struct mvs_dispatch mvs_64xx_dispatch = {
|
|||||||
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
||||||
mvs_64xx_fix_dma,
|
mvs_64xx_fix_dma,
|
||||||
#endif
|
#endif
|
||||||
|
mvs_64xx_tune_interrupt,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -475,7 +475,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi)
|
|||||||
tmp = 0;
|
tmp = 0;
|
||||||
mw32(MVS_INT_COAL, tmp);
|
mw32(MVS_INT_COAL, tmp);
|
||||||
|
|
||||||
tmp = 0x100;
|
tmp = 0x10000 | interrupt_coalescing;
|
||||||
mw32(MVS_INT_COAL_TMOUT, tmp);
|
mw32(MVS_INT_COAL_TMOUT, tmp);
|
||||||
|
|
||||||
/* ladies and gentlemen, start your engines */
|
/* 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 = {
|
const struct mvs_dispatch mvs_94xx_dispatch = {
|
||||||
"mv94xx",
|
"mv94xx",
|
||||||
mvs_94xx_init,
|
mvs_94xx_init,
|
||||||
@ -947,6 +970,7 @@ const struct mvs_dispatch mvs_94xx_dispatch = {
|
|||||||
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
||||||
mvs_94xx_fix_dma,
|
mvs_94xx_fix_dma,
|
||||||
#endif
|
#endif
|
||||||
|
mvs_94xx_tune_interrupt,
|
||||||
mvs_94xx_non_spec_ncq_error,
|
mvs_94xx_non_spec_ncq_error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ MODULE_PARM_DESC(collector, "\n"
|
|||||||
"\tThe mvsas SAS LLDD supports both modes.\n"
|
"\tThe mvsas SAS LLDD supports both modes.\n"
|
||||||
"\tDefault: 1 (Direct Mode).\n");
|
"\tDefault: 1 (Direct Mode).\n");
|
||||||
|
|
||||||
|
int interrupt_coalescing = 0x80;
|
||||||
|
|
||||||
static struct scsi_transport_template *mvs_stt;
|
static struct scsi_transport_template *mvs_stt;
|
||||||
struct kmem_cache *mvs_task_list_cache;
|
struct kmem_cache *mvs_task_list_cache;
|
||||||
static const struct mvs_chip_info mvs_chips[] = {
|
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, },
|
[chip_1320] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct device_attribute *mvst_host_attrs[];
|
||||||
|
|
||||||
#define SOC_SAS_NUM 2
|
#define SOC_SAS_NUM 2
|
||||||
#define SG_MX 64
|
#define SG_MX 64
|
||||||
|
|
||||||
@ -74,6 +78,7 @@ static struct scsi_host_template mvs_sht = {
|
|||||||
.slave_alloc = mvs_slave_alloc,
|
.slave_alloc = mvs_slave_alloc,
|
||||||
.target_destroy = sas_target_destroy,
|
.target_destroy = sas_target_destroy,
|
||||||
.ioctl = sas_ioctl,
|
.ioctl = sas_ioctl,
|
||||||
|
.shost_attrs = mvst_host_attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sas_domain_function_template mvs_transport_ops = {
|
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),
|
.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 */
|
/* task handler */
|
||||||
struct task_struct *mvs_th;
|
struct task_struct *mvs_th;
|
||||||
static int __init mvs_init(void)
|
static int __init mvs_init(void)
|
||||||
@ -742,6 +811,12 @@ static void __exit mvs_exit(void)
|
|||||||
kmem_cache_destroy(mvs_task_list_cache);
|
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_init(mvs_init);
|
||||||
module_exit(mvs_exit);
|
module_exit(mvs_exit);
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#define MV_MAX_U32 0xffffffff
|
#define MV_MAX_U32 0xffffffff
|
||||||
|
|
||||||
|
extern int interrupt_coalescing;
|
||||||
extern struct mvs_tgt_initiator mvs_tgt;
|
extern struct mvs_tgt_initiator mvs_tgt;
|
||||||
extern struct mvs_info *tgt_mvi;
|
extern struct mvs_info *tgt_mvi;
|
||||||
extern const struct mvs_dispatch mvs_64xx_dispatch;
|
extern const struct mvs_dispatch mvs_64xx_dispatch;
|
||||||
@ -170,6 +171,7 @@ struct mvs_dispatch {
|
|||||||
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
||||||
void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd);
|
void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd);
|
||||||
#endif
|
#endif
|
||||||
|
void (*tune_interrupt)(struct mvs_info *mvi, u32 time);
|
||||||
void (*non_spec_ncq_error)(struct mvs_info *mvi);
|
void (*non_spec_ncq_error)(struct mvs_info *mvi);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user