Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83c7b61c authored by Xiangliang Yu's avatar Xiangliang Yu Committed by James Bottomley
Browse files

[SCSI] mvsas: Add driver version and interrupt coalescing to device attributes in sysfs

parent f1f82a91
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -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,
};
+25 −1
Original line number Diff line number Diff line
@@ -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,
};
+75 −0
Original line number Diff line number Diff line
@@ -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);

+2 −0
Original line number Diff line number Diff line
@@ -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);

};