[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1511316666.851478953@decadent.org.uk>
Date: Wed, 22 Nov 2017 02:11:06 +0000
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org,
"Saurav Kashyap" <saurav.kashyap@...gic.com>,
"Chad Dupuis" <chad.dupuis@...gic.com>,
"James Bottomley" <JBottomley@...allels.com>
Subject: [PATCH 3.2 29/61] [SCSI] qla2xxx: Add mutex around optrom calls
to serialize accesses.
3.2.96-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Chad Dupuis <chad.dupuis@...gic.com>
commit 7a8ab9c840b5dff9bb70328338a86444ed1c2415 upstream.
Signed-off-by: Chad Dupuis <chad.dupuis@...gic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@...gic.com>
Signed-off-by: James Bottomley <JBottomley@...allels.com>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
drivers/scsi/qla2xxx/qla_attr.c | 61 ++++++++++++++++++++++++++++-------------
drivers/scsi/qla2xxx/qla_bsg.c | 12 ++++++--
drivers/scsi/qla2xxx/qla_def.h | 1 +
drivers/scsi/qla2xxx/qla_os.c | 1 +
4 files changed, 54 insertions(+), 21 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -215,12 +215,17 @@ qla2x00_sysfs_read_optrom(struct file *f
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
struct device, kobj)));
struct qla_hw_data *ha = vha->hw;
+ ssize_t rval = 0;
if (ha->optrom_state != QLA_SREADING)
return 0;
- return memory_read_from_buffer(buf, count, &off, ha->optrom_buffer,
- ha->optrom_region_size);
+ mutex_lock(&ha->optrom_mutex);
+ rval = memory_read_from_buffer(buf, count, &off, ha->optrom_buffer,
+ ha->optrom_region_size);
+ mutex_unlock(&ha->optrom_mutex);
+
+ return rval;
}
static ssize_t
@@ -239,7 +244,9 @@ qla2x00_sysfs_write_optrom(struct file *
if (off + count > ha->optrom_region_size)
count = ha->optrom_region_size - off;
+ mutex_lock(&ha->optrom_mutex);
memcpy(&ha->optrom_buffer[off], buf, count);
+ mutex_unlock(&ha->optrom_mutex);
return count;
}
@@ -262,10 +269,10 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
struct device, kobj)));
struct qla_hw_data *ha = vha->hw;
-
uint32_t start = 0;
uint32_t size = ha->optrom_size;
int val, valid;
+ ssize_t rval = count;
if (off)
return -EINVAL;
@@ -278,12 +285,14 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
if (start > ha->optrom_size)
return -EINVAL;
+ mutex_lock(&ha->optrom_mutex);
switch (val) {
case 0:
if (ha->optrom_state != QLA_SREADING &&
- ha->optrom_state != QLA_SWRITING)
- return -EINVAL;
-
+ ha->optrom_state != QLA_SWRITING) {
+ rval = -EINVAL;
+ goto out;
+ }
ha->optrom_state = QLA_SWAITING;
ql_dbg(ql_dbg_user, vha, 0x7061,
@@ -294,8 +303,10 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
ha->optrom_buffer = NULL;
break;
case 1:
- if (ha->optrom_state != QLA_SWAITING)
- return -EINVAL;
+ if (ha->optrom_state != QLA_SWAITING) {
+ rval = -EINVAL;
+ goto out;
+ }
ha->optrom_region_start = start;
ha->optrom_region_size = start + size > ha->optrom_size ?
@@ -309,13 +320,15 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
"(%x).\n", ha->optrom_region_size);
ha->optrom_state = QLA_SWAITING;
- return -ENOMEM;
+ rval = -ENOMEM;
+ goto out;
}
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x7063,
"HBA not online, failing NVRAM update.\n");
- return -EAGAIN;
+ rval = -EAGAIN;
+ goto out;
}
ql_dbg(ql_dbg_user, vha, 0x7064,
@@ -327,8 +340,10 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
ha->optrom_region_start, ha->optrom_region_size);
break;
case 2:
- if (ha->optrom_state != QLA_SWAITING)
- return -EINVAL;
+ if (ha->optrom_state != QLA_SWAITING) {
+ rval = -EINVAL;
+ goto out;
+ }
/*
* We need to be more restrictive on which FLASH regions are
@@ -361,7 +376,8 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
if (!valid) {
ql_log(ql_log_warn, vha, 0x7065,
"Invalid start region 0x%x/0x%x.\n", start, size);
- return -EINVAL;
+ rval = -EINVAL;
+ goto out;
}
ha->optrom_region_start = start;
@@ -376,7 +392,8 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
"(%x)\n", ha->optrom_region_size);
ha->optrom_state = QLA_SWAITING;
- return -ENOMEM;
+ rval = -ENOMEM;
+ goto out;
}
ql_dbg(ql_dbg_user, vha, 0x7067,
@@ -386,13 +403,16 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
memset(ha->optrom_buffer, 0, ha->optrom_region_size);
break;
case 3:
- if (ha->optrom_state != QLA_SWRITING)
- return -EINVAL;
+ if (ha->optrom_state != QLA_SWRITING) {
+ rval = -EINVAL;
+ goto out;
+ }
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x7068,
"HBA not online, failing flash update.\n");
- return -EAGAIN;
+ rval = -EAGAIN;
+ goto out;
}
ql_dbg(ql_dbg_user, vha, 0x7069,
@@ -403,9 +423,12 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
ha->optrom_region_start, ha->optrom_region_size);
break;
default:
- return -EINVAL;
+ rval = -EINVAL;
}
- return count;
+
+out:
+ mutex_unlock(&ha->optrom_mutex);
+ return rval;
}
static struct bin_attribute sysfs_optrom_ctl_attr = {
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1400,9 +1400,12 @@ qla2x00_read_optrom(struct fc_bsg_job *b
struct qla_hw_data *ha = vha->hw;
int rval = 0;
+ mutex_lock(&ha->optrom_mutex);
rval = qla2x00_optrom_setup(bsg_job, vha, 0);
- if (rval)
+ if (rval) {
+ mutex_unlock(&ha->optrom_mutex);
return rval;
+ }
ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
ha->optrom_region_start, ha->optrom_region_size);
@@ -1416,6 +1419,7 @@ qla2x00_read_optrom(struct fc_bsg_job *b
vfree(ha->optrom_buffer);
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
+ mutex_unlock(&ha->optrom_mutex);
bsg_job->job_done(bsg_job);
return rval;
}
@@ -1428,9 +1432,12 @@ qla2x00_update_optrom(struct fc_bsg_job
struct qla_hw_data *ha = vha->hw;
int rval = 0;
+ mutex_lock(&ha->optrom_mutex);
rval = qla2x00_optrom_setup(bsg_job, vha, 1);
- if (rval)
+ if (rval) {
+ mutex_unlock(&ha->optrom_mutex);
return rval;
+ }
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, ha->optrom_buffer,
@@ -1443,6 +1450,7 @@ qla2x00_update_optrom(struct fc_bsg_job
vfree(ha->optrom_buffer);
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
+ mutex_unlock(&ha->optrom_mutex);
bsg_job->job_done(bsg_job);
return rval;
}
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2723,6 +2723,7 @@ struct qla_hw_data {
#define QLA_SWRITING 2
uint32_t optrom_region_start;
uint32_t optrom_region_size;
+ struct mutex optrom_mutex;
/* PCI expansion ROM image information. */
#define ROM_CODE_TYPE_BIOS 0
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2023,6 +2023,7 @@ qla2x00_probe_one(struct pci_dev *pdev,
ha->mem_only = mem_only;
spin_lock_init(&ha->hardware_lock);
spin_lock_init(&ha->vport_slock);
+ mutex_init(&ha->optrom_mutex);
/* Set ISP-type information. */
qla2x00_set_isp_flags(ha);
Powered by blists - more mailing lists