summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-10-05 09:10:58 +0000
committermav <mav@FreeBSD.org>2015-10-05 09:10:58 +0000
commit985ffcba7f216148e92f5ccbf06fd8f79976b5e2 (patch)
tree8dc50d3f17c082e5b5c38af5fa44407e5fce98bd /sys/cam
parente563859fd225709afe1ce093768f0858d6782dad (diff)
downloadFreeBSD-src-985ffcba7f216148e92f5ccbf06fd8f79976b5e2.zip
FreeBSD-src-985ffcba7f216148e92f5ccbf06fd8f79976b5e2.tar.gz
MFC r287756:
Report INQUIRY DATA HAS CHANGED for related LUNs on port on-/offline.
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ctl/ctl.c30
-rw-r--r--sys/cam/ctl/ctl.h17
-rw-r--r--sys/cam/ctl/ctl_error.c5
-rw-r--r--sys/cam/ctl/ctl_frontend.c20
4 files changed, 54 insertions, 18 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index cb8007e..39597f0 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -407,14 +407,6 @@ static int ctl_scsiio_lun_check(struct ctl_lun *lun,
const struct ctl_cmd_entry *entry,
struct ctl_scsiio *ctsio);
static void ctl_failover_lun(struct ctl_lun *lun);
-static void ctl_est_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua);
-static void ctl_est_ua_port(struct ctl_lun *lun, int port, uint32_t except,
- ctl_ua_type ua);
-static void ctl_est_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua);
-static void ctl_clr_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua);
-static void ctl_clr_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua);
-static void ctl_clr_ua_allluns(struct ctl_softc *ctl_softc, uint32_t initidx,
- ctl_ua_type ua_type);
static int ctl_scsiio_precheck(struct ctl_softc *ctl_softc,
struct ctl_scsiio *ctsio);
static int ctl_scsiio(struct ctl_scsiio *ctsio);
@@ -804,6 +796,7 @@ static void
ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
{
struct ctl_port *port;
+ struct ctl_lun *lun;
int i, new;
port = softc->ctl_ports[msg->hdr.nexus.targ_port];
@@ -879,6 +872,15 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
__func__);
}
}
+ mtx_lock(&softc->ctl_lock);
+ STAILQ_FOREACH(lun, &softc->lun_list, links) {
+ if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ continue;
+ mtx_lock(&lun->lun_lock);
+ ctl_est_ua_all(lun, -1, CTL_UA_INQ_CHANGE);
+ mtx_unlock(&lun->lun_lock);
+ }
+ mtx_unlock(&softc->ctl_lock);
}
/*
@@ -1201,7 +1203,7 @@ ctl_copy_sense_data_back(union ctl_io *src, union ctl_ha_msg *dest)
dest->hdr.status = src->io_hdr.status;
}
-static void
+void
ctl_est_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua)
{
struct ctl_softc *softc = lun->ctl_softc;
@@ -1216,7 +1218,7 @@ ctl_est_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua)
pu[initidx % CTL_MAX_INIT_PER_PORT] |= ua;
}
-static void
+void
ctl_est_ua_port(struct ctl_lun *lun, int port, uint32_t except, ctl_ua_type ua)
{
int i;
@@ -1231,7 +1233,7 @@ ctl_est_ua_port(struct ctl_lun *lun, int port, uint32_t except, ctl_ua_type ua)
}
}
-static void
+void
ctl_est_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua)
{
struct ctl_softc *softc = lun->ctl_softc;
@@ -1242,7 +1244,7 @@ ctl_est_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua)
ctl_est_ua_port(lun, i, except, ua);
}
-static void
+void
ctl_clr_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua)
{
struct ctl_softc *softc = lun->ctl_softc;
@@ -1257,7 +1259,7 @@ ctl_clr_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua)
pu[initidx % CTL_MAX_INIT_PER_PORT] &= ~ua;
}
-static void
+void
ctl_clr_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua)
{
struct ctl_softc *softc = lun->ctl_softc;
@@ -1275,7 +1277,7 @@ ctl_clr_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua)
}
}
-static void
+void
ctl_clr_ua_allluns(struct ctl_softc *ctl_softc, uint32_t initidx,
ctl_ua_type ua_type)
{
diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h
index 630e3bb..d10bdf6 100644
--- a/sys/cam/ctl/ctl.h
+++ b/sys/cam/ctl/ctl.h
@@ -120,6 +120,7 @@ typedef enum {
CTL_UA_LUN_CHANGE = 0x0020,
CTL_UA_MODE_CHANGE = 0x0040,
CTL_UA_LOG_CHANGE = 0x0080,
+ CTL_UA_INQ_CHANGE = 0x0100,
CTL_UA_RES_PREEMPT = 0x0400,
CTL_UA_RES_RELEASE = 0x0800,
CTL_UA_REG_PREEMPT = 0x1000,
@@ -138,6 +139,10 @@ struct ctl_page_index;
SYSCTL_DECL(_kern_cam_ctl);
#endif
+struct ctl_lun;
+struct ctl_port;
+struct ctl_softc;
+
/*
* Put a string into an sbuf, escaping characters that are illegal or not
* recommended in XML. Note this doesn't escape everything, just > < and &.
@@ -174,9 +179,17 @@ void ctl_config_write_done(union ctl_io *io);
void ctl_portDB_changed(int portnum);
int ctl_ioctl_io(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td);
-struct ctl_lun;
+
+void ctl_est_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua);
+void ctl_est_ua_port(struct ctl_lun *lun, int port, uint32_t except,
+ ctl_ua_type ua);
+void ctl_est_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua);
+void ctl_clr_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua);
+void ctl_clr_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua);
+void ctl_clr_ua_allluns(struct ctl_softc *ctl_softc, uint32_t initidx,
+ ctl_ua_type ua_type);
+
void ctl_isc_announce_lun(struct ctl_lun *lun);
-struct ctl_port;
void ctl_isc_announce_port(struct ctl_port *port);
/*
diff --git a/sys/cam/ctl/ctl_error.c b/sys/cam/ctl/ctl_error.c
index 8ef5176..2265a03 100644
--- a/sys/cam/ctl/ctl_error.c
+++ b/sys/cam/ctl/ctl_error.c
@@ -446,6 +446,11 @@ ctl_build_ua(struct ctl_lun *lun, uint32_t initidx,
asc = 0x2A;
ascq = 0x02;
break;
+ case CTL_UA_INQ_CHANGE:
+ /* 3Fh/03h INQUIRY DATA HAS CHANGED */
+ asc = 0x3F;
+ ascq = 0x03;
+ break;
case CTL_UA_RES_PREEMPT:
/* 2Ah/03h RESERVATIONS PREEMPTED */
asc = 0x2A;
diff --git a/sys/cam/ctl/ctl_frontend.c b/sys/cam/ctl/ctl_frontend.c
index c9c75d4..1caab65 100644
--- a/sys/cam/ctl/ctl_frontend.c
+++ b/sys/cam/ctl/ctl_frontend.c
@@ -328,8 +328,16 @@ ctl_port_online(struct ctl_port *port)
}
if (port->port_online != NULL)
port->port_online(port->onoff_arg);
- /* XXX KDM need a lock here? */
+ mtx_lock(&softc->ctl_lock);
port->status |= CTL_PORT_STATUS_ONLINE;
+ STAILQ_FOREACH(lun, &softc->lun_list, links) {
+ if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ continue;
+ mtx_lock(&lun->lun_lock);
+ ctl_est_ua_all(lun, -1, CTL_UA_INQ_CHANGE);
+ mtx_unlock(&lun->lun_lock);
+ }
+ mtx_unlock(&softc->ctl_lock);
ctl_isc_announce_port(port);
}
@@ -355,8 +363,16 @@ ctl_port_offline(struct ctl_port *port)
port->lun_disable(port->targ_lun_arg, lun->lun);
}
}
- /* XXX KDM need a lock here? */
+ mtx_lock(&softc->ctl_lock);
port->status &= ~CTL_PORT_STATUS_ONLINE;
+ STAILQ_FOREACH(lun, &softc->lun_list, links) {
+ if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ continue;
+ mtx_lock(&lun->lun_lock);
+ ctl_est_ua_all(lun, -1, CTL_UA_INQ_CHANGE);
+ mtx_unlock(&lun->lun_lock);
+ }
+ mtx_unlock(&softc->ctl_lock);
ctl_isc_announce_port(port);
}
OpenPOWER on IntegriCloud