* [PATCH 2/7]MVSAS:add supporting MSI feature
@ 2009-11-09 12:08 Andy Yan
2009-11-14 18:19 ` James Bottomley
2009-11-14 22:56 ` Matthew Wilcox
0 siblings, 2 replies; 3+ messages in thread
From: Andy Yan @ 2009-11-09 12:08 UTC (permalink / raw)
To: james.bottomley, jeff, linux-scsi; +Cc: jfeng, qswang
>From 8b51aa63e8b123046a334d630ae045f479acbf6c Mon Sep 17 00:00:00 2001
From: andy <ayan@marvell.com>
Date: Fri, 6 Nov 2009 17:03:21 +0800
Subject: [PATCH 2/7] Add supporting MSI feature
MSI feature is implemented with mvsas driver.
Signed-off-by: Andy <ayan@marvell.com>
Signed-off-by: Jacky <jfeng@marvell.com>
Signed-off-by: Ke <kewei@marvell.com>
---
drivers/scsi/mvsas/mv_init.c | 113 ++++++++++++++++++++++++++++++++++++++++--
drivers/scsi/mvsas/mv_sas.c | 28 ++++++-----
drivers/scsi/mvsas/mv_sas.h | 2 +
3 files changed, 126 insertions(+), 17 deletions(-)
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index c790d45..d030959 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -25,6 +25,10 @@
#include "mv_sas.h"
+static int msi;
+module_param(msi, int, 0);
+MODULE_PARM_DESC(msi, "Enable Message Signaled Interrupts(0=off, 1=on)");
+int io_delay;
static struct scsi_transport_template *mvs_stt;
static const struct mvs_chip_info mvs_chips[] = {
[chip_6320] = { 1, 2, 0x400, 17, 16, 9, &mvs_64xx_dispatch, },
@@ -36,11 +40,13 @@ 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
static struct scsi_host_template mvs_sht = {
.module = THIS_MODULE,
- .name = DRV_NAME,
+ .name = "Marvell Storage Controller",
+ .proc_name = DRV_NAME,
.queuecommand = sas_queuecommand,
.target_alloc = sas_target_alloc,
.slave_configure = mvs_slave_configure,
@@ -61,6 +67,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 = {
@@ -89,6 +96,7 @@ static void __devinit mvs_phy_init(struct mvs_info *mvi, int phy_id)
struct asd_sas_phy *sas_phy = &phy->sas_phy;
phy->mvi = mvi;
+ phy->port = NULL;
init_timer(&phy->timer);
sas_phy->enabled = (phy_id < mvi->chip->n_phy) ? 1 : 0;
sas_phy->class = SAS;
@@ -118,7 +126,7 @@ static void mvs_free(struct mvs_info *mvi)
if (mvi->flags & MVF_FLAG_SOC)
slot_nr = MVS_SOC_SLOTS;
else
- slot_nr = MVS_SLOTS;
+ slot_nr = MVS_CHIP_SLOT_SZ;
for (i = 0; i < mvi->tags_num; i++) {
struct mvs_slot_info *slot = &mvi->slot_info[i];
@@ -183,6 +191,30 @@ static void mvs_tasklet(unsigned long opaque)
}
#endif
+void mvs_enable_msi(struct mvs_info *mvi)
+{
+ u32 tmp;
+ pci_read_config_dword(mvi->pdev, PCR_CMD, &tmp);
+ tmp |= 1 << 10; /* disable interrupt */
+ pci_write_config_dword(mvi->pdev, PCR_CMD, tmp);
+
+ pci_read_config_dword(mvi->pdev, PCR_MSI_CTRL, &tmp);
+ tmp |= 1 << 16; /* enable MSI */
+ pci_write_config_dword(mvi->pdev, PCR_MSI_CTRL, tmp);
+}
+void mvs_disable_msi(struct mvs_info *mvi)
+{
+ u32 tmp;
+ pci_read_config_dword(mvi->pdev, PCR_CMD, &tmp);
+ tmp &= ~(1 << 10); /* enable interrupt */
+ pci_write_config_dword(mvi->pdev, PCR_CMD, tmp);
+
+ pci_read_config_dword(mvi->pdev, PCR_MSI_CTRL, &tmp);
+ tmp &= ~(1 << 16); /* disable MSI */
+ pci_write_config_dword(mvi->pdev, PCR_MSI_CTRL, tmp);
+}
+
+
static irqreturn_t mvs_interrupt(int irq, void *opaque)
{
u32 core_nr, i = 0;
@@ -519,6 +551,7 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
dev_printk(KERN_INFO, &pdev->dev,
"mvsas: driver version %s\n", DRV_VERSION);
+ io_delay = 0;
rc = pci_enable_device(pdev);
if (rc)
goto err_out_enable;
@@ -563,6 +596,8 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
rc = -ENOMEM;
goto err_out_regions;
}
+ if (msi)
+ mvi->flags |= MVF_MSI;
mvs_init_sas_add(mvi);
@@ -581,13 +616,22 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
if (rc)
goto err_out_shost;
+ if (mvi->flags & MVF_MSI) {
+ pci_enable_msi(pdev);
+ mvs_enable_msi(mvi);
+ }
rc = sas_register_ha(SHOST_TO_SAS_HA(shost));
if (rc)
goto err_out_shost;
rc = request_irq(pdev->irq, irq_handler, IRQF_SHARED,
DRV_NAME, SHOST_TO_SAS_HA(shost));
- if (rc)
+ if (rc) {
+ if (mvi->flags & MVF_MSI) {
+ mvs_disable_msi(mvi);
+ pci_disable_msi(pdev);
+ }
goto err_not_sas;
+ }
MVS_CHIP_DISP->interrupt_enable(mvi);
@@ -620,13 +664,16 @@ static void __devexit mvs_pci_remove(struct pci_dev *pdev)
tasklet_kill(&mv_tasklet);
#endif
- pci_set_drvdata(pdev, NULL);
sas_unregister_ha(sha);
sas_remove_host(mvi->shost);
scsi_remove_host(mvi->shost);
MVS_CHIP_DISP->interrupt_disable(mvi);
free_irq(mvi->irq, sha);
+ if (mvi->flags & MVF_MSI) {
+ mvs_disable_msi(mvi);
+ pci_disable_msi(pdev);
+ }
for (i = 0; i < core_nr; i++) {
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i];
mvs_free(mvi);
@@ -634,6 +681,7 @@ static void __devexit mvs_pci_remove(struct pci_dev *pdev)
kfree(sha->sas_phy);
kfree(sha->sas_port);
kfree(sha);
+ pci_set_drvdata(pdev, NULL);
pci_release_regions(pdev);
pci_disable_device(pdev);
return;
@@ -668,6 +716,57 @@ 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_io_delay(struct device *cdev,
+ struct device_attribute *attr,
+ const char *buffer, size_t size)
+{
+
+ int val = 0;
+
+ if (buffer == NULL)
+ return size;
+
+ if (sscanf(buffer, "%d", &val) != 1)
+ return -EINVAL;
+
+ io_delay = val;
+ if (io_delay > 10) {
+ printk(KERN_NOTICE "io delay time %d seconds is too long, \
+ max is 10s\n", io_delay);
+ io_delay = 10;
+ return strlen(buffer);
+ }
+ printk(KERN_NOTICE "set io delay time to %d seconds\n", io_delay);
+ return strlen(buffer);
+}
+
+static ssize_t mvs_show_io_delay(struct device *cdev,
+ struct device_attribute *attr,
+ char *buffer)
+{
+ return snprintf(buffer, PAGE_SIZE, "%d\n", io_delay);
+}
+
+
+static DEVICE_ATTR(io_delay,
+ S_IRUGO|S_IWUSR,
+ mvs_show_io_delay,
+ mvs_store_io_delay);
+
/* task handler */
struct task_struct *mvs_th;
static int __init mvs_init(void)
@@ -695,6 +794,12 @@ static void __exit mvs_exit(void)
sas_release_transport(mvs_stt);
}
+struct device_attribute *mvst_host_attrs[] = {
+ &dev_attr_driver_version,
+ &dev_attr_io_delay,
+ NULL,
+};
+
module_init(mvs_init);
module_exit(mvs_exit);
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 0d21386..4fe365a 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -1935,15 +1935,15 @@ static void mvs_work_queue(struct work_struct *work)
struct delayed_work *dw = container_of(work, struct delayed_work, work);
struct mvs_wq *mwq = container_of(dw, struct mvs_wq, work_q);
struct mvs_info *mvi = mwq->mvi;
- unsigned long flags;
- spin_lock_irqsave(&mvi->lock, flags);
- if (mwq->handler & PHY_PLUG_EVENT) {
u32 phy_no = (unsigned long) mwq->data;
struct sas_ha_struct *sas_ha = mvi->sas;
struct mvs_phy *phy = &mvi->phy[phy_no];
struct asd_sas_phy *sas_phy = &phy->sas_phy;
+ unsigned long flags;
+ spin_lock_irqsave(&mvi->lock, flags);
+ if (mwq->handler & PHY_PLUG_EVENT) {
if (phy->phy_event & PHY_PLUG_OUT) {
u32 tmp;
struct sas_identify_frame *id;
@@ -1964,6 +1964,10 @@ static void mvs_work_queue(struct work_struct *work)
mv_dprintk("phy%d Attached Device\n", phy_no);
}
}
+ } else if (mwq->handler & EXP_BRCT_CHG) {
+ phy->phy_event &= ~EXP_BRCT_CHG;
+ sas_ha->notify_port_event(sas_phy,
+ PORTE_BROADCAST_RCVD);
}
list_del(&mwq->entry);
spin_unlock_irqrestore(&mvi->lock, flags);
@@ -1982,7 +1986,7 @@ static int mvs_handle_event(struct mvs_info *mvi, void *data, int handler)
mwq->handler = handler;
MV_INIT_DELAYED_WORK(&mwq->work_q, mvs_work_queue, mwq);
list_add_tail(&mwq->entry, &mvi->wq_list);
- schedule_delayed_work(&mwq->work_q, HZ * 2);
+ schedule_delayed_work(&mwq->work_q, HZ * io_delay);
} else
ret = -ENOMEM;
@@ -2014,14 +2018,14 @@ static void mvs_sig_remove_timer(struct mvs_phy *phy)
void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
{
u32 tmp;
- struct sas_ha_struct *sas_ha = mvi->sas;
struct mvs_phy *phy = &mvi->phy[phy_no];
struct asd_sas_phy *sas_phy = &phy->sas_phy;
phy->irq_status = MVS_CHIP_DISP->read_port_irq_stat(mvi, phy_no);
- mv_dprintk("port %d ctrl sts=0x%X.\n", phy_no+mvi->id*mvi->chip->n_phy,
+ MVS_CHIP_DISP->write_port_irq_stat(mvi, phy_no, phy->irq_status);
+ mv_dprintk("phy %d ctrl sts=%08X.\n", phy_no+mvi->id*mvi->chip->n_phy,
MVS_CHIP_DISP->read_phy_ctl(mvi, phy_no));
- mv_dprintk("Port %d irq sts = 0x%X\n", phy_no+mvi->id*mvi->chip->n_phy,
+ mv_dprintk("phy %d irq sts = %08X\n", phy_no+mvi->id*mvi->chip->n_phy,
phy->irq_status);
/*
@@ -2096,13 +2100,11 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
phy_no + mvi->id*mvi->chip->n_phy);
}
} else if (phy->irq_status & PHYEV_BROAD_CH) {
- mv_dprintk("port %d broadcast change.\n",
- phy_no + mvi->id*mvi->chip->n_phy);
- /* exception for Samsung disk drive*/
- mdelay(1000);
- sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
+ mv_dprintk("phy %d broadcast change.\n",
+ phy_no + mvi->id*mvi->chip->n_phy);
+ mvs_handle_event(mvi, (void *)(unsigned long)phy_no,
+ EXP_BRCT_CHG);
}
- MVS_CHIP_DISP->write_port_irq_stat(mvi, phy_no, phy->irq_status);
}
int mvs_int_rx(struct mvs_info *mvi, bool self_clear)
diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h
index aa2270a..7d3e5f6 100644
--- a/drivers/scsi/mvsas/mv_sas.h
+++ b/drivers/scsi/mvsas/mv_sas.h
@@ -61,6 +61,7 @@
#endif
#define MV_MAX_U32 0xffffffff
+extern int io_delay;
extern struct mvs_tgt_initiator mvs_tgt;
extern struct mvs_info *tgt_mvi;
extern const struct mvs_dispatch mvs_64xx_dispatch;
@@ -93,6 +94,7 @@ extern const struct mvs_dispatch mvs_94xx_dispatch;
enum dev_status {
MVS_DEV_NORMAL = 0x0,
MVS_DEV_EH = 0x1,
+ MVS_DEV_OFF = 0x2,
};
--
1.6.2.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 2/7]MVSAS:add supporting MSI feature
2009-11-09 12:08 [PATCH 2/7]MVSAS:add supporting MSI feature Andy Yan
@ 2009-11-14 18:19 ` James Bottomley
2009-11-14 22:56 ` Matthew Wilcox
1 sibling, 0 replies; 3+ messages in thread
From: James Bottomley @ 2009-11-14 18:19 UTC (permalink / raw)
To: ayan; +Cc: jeff, linux-scsi, jfeng, qswang
On Mon, 2009-11-09 at 20:08 +0800, Andy Yan wrote:
> From 8b51aa63e8b123046a334d630ae045f479acbf6c Mon Sep 17 00:00:00 2001
> From: andy <ayan@marvell.com>
> Date: Fri, 6 Nov 2009 17:03:21 +0800
> Subject: [PATCH 2/7] Add supporting MSI feature
>
> MSI feature is implemented with mvsas driver.
>
> Signed-off-by: Andy <ayan@marvell.com>
> Signed-off-by: Jacky <jfeng@marvell.com>
> Signed-off-by: Ke <kewei@marvell.com>
This doesn't compile:
CC [M] drivers/scsi/mvsas/mv_init.o
drivers/scsi/mvsas/mv_init.c: In function ‘mvs_enable_msi’:
drivers/scsi/mvsas/mv_init.c:197: error: ‘PCR_CMD’ undeclared (first use in this function)
drivers/scsi/mvsas/mv_init.c:197: error: (Each undeclared identifier is reported only once
drivers/scsi/mvsas/mv_init.c:197: error: for each function it appears in.)
drivers/scsi/mvsas/mv_init.c:201: error: ‘PCR_MSI_CTRL’ undeclared (first use in this function)
drivers/scsi/mvsas/mv_init.c: In function ‘mvs_disable_msi’:
drivers/scsi/mvsas/mv_init.c:208: error: ‘PCR_CMD’ undeclared (first use in this function)
drivers/scsi/mvsas/mv_init.c:212: error: ‘PCR_MSI_CTRL’ undeclared (first use in this function)
It looks like these definitions are added in patch 3 (after this
one) ... you can't do that: a patch series has to be bisectable
James
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 2/7]MVSAS:add supporting MSI feature
2009-11-09 12:08 [PATCH 2/7]MVSAS:add supporting MSI feature Andy Yan
2009-11-14 18:19 ` James Bottomley
@ 2009-11-14 22:56 ` Matthew Wilcox
1 sibling, 0 replies; 3+ messages in thread
From: Matthew Wilcox @ 2009-11-14 22:56 UTC (permalink / raw)
To: Andy Yan; +Cc: james.bottomley, jeff, linux-scsi, jfeng, qswang
On Mon, Nov 09, 2009 at 08:08:18PM +0800, Andy Yan wrote:
> +void mvs_enable_msi(struct mvs_info *mvi)
> +{
> + u32 tmp;
> + pci_read_config_dword(mvi->pdev, PCR_CMD, &tmp);
> + tmp |= 1 << 10; /* disable interrupt */
> + pci_write_config_dword(mvi->pdev, PCR_CMD, tmp);
What makes you think the pci_enable_msi() code doesn't set this bit?
> + pci_read_config_dword(mvi->pdev, PCR_MSI_CTRL, &tmp);
> + tmp |= 1 << 16; /* enable MSI */
> + pci_write_config_dword(mvi->pdev, PCR_MSI_CTRL, tmp);
... and what makes you think it doesn't set this bit either?
> +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);
> +}
There's a lot of code in this patch not related to enabling MSI.
--
Matthew Wilcox Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-11-14 22:56 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-09 12:08 [PATCH 2/7]MVSAS:add supporting MSI feature Andy Yan
2009-11-14 18:19 ` James Bottomley
2009-11-14 22:56 ` Matthew Wilcox
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.