From: Quinn Tran
This patch adds capability to poll for an interrupt, If hardware
does not generate any interrupt for 2 seconds.
Signed-off-by: Quinn Tran
Signed-off-by: Himanshu Madhani
---
drivers/scsi/qla2xxx/qla_def.h| 8 +
drivers/scsi/qla2xxx/qla_dfs.c| 75 +++
drivers/scsi/qla2xxx/qla_gbl.h| 1 +
drivers/scsi/qla2xxx/qla_isr.c| 22 ++--
drivers/scsi/qla2xxx/qla_os.c | 31
drivers/scsi/qla2xxx/qla_target.c | 6
6 files changed, 141 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 6bf7ff9..09da61f 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2921,6 +2921,10 @@ struct qla_msix_entry {
void *handle;
struct irq_affinity_notify irq_notify;
int cpuid;
+ irqreturn_t (*irq_handler)(int, void *);
+ u32 intr_cnt;
+ u32 last_intr_cnt;
+ struct work_struct intr_work;
};
#defineWATCH_INTERVAL 1 /* number of seconds */
@@ -3826,6 +3830,10 @@ struct qla_hw_data {
struct qlt_hw_data tgt;
int allow_cna_fw_dump;
+
+ int irqpoll_interval, irqpoll_cnt;
+ struct dentry *dfs_irqpoll;
+#define MAX_IRQPOLL_INTV 30
};
struct qla_tgt_counters {
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index f69ff52..18cedf7 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -12,6 +12,68 @@
static struct dentry *qla2x00_dfs_root;
static atomic_t qla2x00_dfs_root_count;
+
+static int
+qla_dfs_irqpoll_show(struct seq_file *s, void *unused)
+{
+ struct scsi_qla_host *vha = s->private;
+ struct qla_hw_data *ha = vha->hw;
+
+ seq_printf(s, "IRQ poll interval: %d Seconds (max=%d, def=0/off)\n",
+ha->irqpoll_interval, MAX_IRQPOLL_INTV);
+
+ return 0;
+}
+
+static ssize_t qla_dfs_irqpoll_write(struct file *file, const char __user
*ubuf,
+ size_t len, loff_t *offp)
+{
+ struct seq_file *s = file->private_data;
+ char *buf;
+ int ret = 0;
+ int interval = 0;
+ struct scsi_qla_host *vha = s->private;
+ struct qla_hw_data *ha = vha->hw;
+
+ buf = memdup_user(ubuf, len);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
+ if (sscanf(buf, "%d", &interval) != 1)
+ return -EINVAL;
+
+ if (interval > MAX_IRQPOLL_INTV || interval < 0)
+ return -ERANGE;
+
+ ha->irqpoll_interval = interval;
+
+ if (ha->irqpoll_interval == 0)
+ ql_log(ql_log_info, vha, 0x,
+ "IRQ Poll turned off.\n");
+ else
+ ql_log(ql_log_info, vha, 0x,
+ "IRQ Poll turned on(%d).\n", ha->irqpoll_interval);
+
+
+ kfree(buf);
+ return (ret) ? ret : len;
+}
+
+static int
+qla_dfs_irqpoll_open(struct inode *inode, struct file *file)
+{
+ struct scsi_qla_host *vha = inode->i_private;
+ return single_open(file, qla_dfs_irqpoll_show, vha);
+}
+
+static const struct file_operations dfs_irqpoll = {
+ .open = qla_dfs_irqpoll_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release= single_release,
+ .write = qla_dfs_irqpoll_write,
+};
+
static int
qla2x00_dfs_irq_cpuid_show(struct seq_file *s, void *unused)
{
@@ -357,6 +419,14 @@
goto out;
}
+ ha->dfs_irqpoll = debugfs_create_file("irq_poll_interval",
+ S_IRUSR, ha->dfs_dir, vha, &dfs_irqpoll);
+ if (!ha->dfs_irqpoll) {
+ ql_log(ql_log_warn, vha, 0x,
+ "Unable to create debugFS irq_poll_interval node.\n");
+ goto out;
+ }
+
out:
return 0;
@@ -367,6 +437,11 @@
{
struct qla_hw_data *ha = vha->hw;
+ if (ha->dfs_irqpoll) {
+ debugfs_remove(ha->dfs_irqpoll);
+ ha->dfs_irqpoll = NULL;
+ }
+
if (ha->dfs_irq_cpuid) {
debugfs_remove(ha->dfs_irq_cpuid);
ha->dfs_irq_cpuid = NULL;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 3593a39..944f37a 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -140,6 +140,7 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *,
port_id_t *,
extern int ql2xexlogins;
extern int ql2xexchoffld;
extern int ql2xfwholdabts;
+extern struct workqueue_struct *qla_wq;
extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index c7f73b1..eee98c9 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -3003,6 +3003,7 @@ void qla24xx_process_respon