diff options
author | mav <mav@FreeBSD.org> | 2015-10-05 09:10:58 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2015-10-05 09:10:58 +0000 |
commit | 985ffcba7f216148e92f5ccbf06fd8f79976b5e2 (patch) | |
tree | 8dc50d3f17c082e5b5c38af5fa44407e5fce98bd | |
parent | e563859fd225709afe1ce093768f0858d6782dad (diff) | |
download | FreeBSD-src-985ffcba7f216148e92f5ccbf06fd8f79976b5e2.zip FreeBSD-src-985ffcba7f216148e92f5ccbf06fd8f79976b5e2.tar.gz |
MFC r287756:
Report INQUIRY DATA HAS CHANGED for related LUNs on port on-/offline.
-rw-r--r-- | sys/cam/ctl/ctl.c | 30 | ||||
-rw-r--r-- | sys/cam/ctl/ctl.h | 17 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_error.c | 5 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_frontend.c | 20 |
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); } |