summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c17
-rw-r--r--usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h4
2 files changed, 20 insertions, 1 deletions
diff --git a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
index 90ddbb8988..1dc8a27aef 100644
--- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
+++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
@@ -15274,6 +15274,15 @@ mptsas_tgt_alloc(mptsas_t *mpt, uint16_t devhdl, uint64_t wwid,
return (tmp_tgt);
}
+static void
+mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst)
+{
+ dst->m_devhdl = src->m_devhdl;
+ dst->m_deviceinfo = src->m_deviceinfo;
+ dst->m_pdevhdl = src->m_pdevhdl;
+ dst->m_pdevinfo = src->m_pdevinfo;
+}
+
static mptsas_smp_t *
mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
{
@@ -15283,8 +15292,14 @@ mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
addr.mta_wwn = data->m_addr.mta_wwn;
addr.mta_phymask = data->m_addr.mta_phymask;
ret_data = refhash_lookup(mpt->m_smp_targets, &addr);
+ /*
+ * If there's already a matching SMP target, update its fields
+ * in place. Since the address is not changing, it's safe to do
+ * this. We cannot just bcopy() here because the structure we've
+ * been given has invalid hash links.
+ */
if (ret_data != NULL) {
- bcopy(data, ret_data, sizeof (mptsas_smp_t)); /* XXX - dupl */
+ mptsas_smp_target_copy(data, ret_data);
return (ret_data);
}
diff --git a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h
index 9768c4ea80..96b9b11464 100644
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h
+++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h
@@ -224,6 +224,10 @@ typedef struct mptsas_target {
} mptsas_target_t;
+/*
+ * If you change this structure, be sure that mptsas_smp_target_copy()
+ * does the right thing.
+ */
typedef struct mptsas_smp {
mptsas_target_addr_t m_addr;
refhash_link_t m_link;