summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2016-04-09 14:50:47 +0000
committermav <mav@FreeBSD.org>2016-04-09 14:50:47 +0000
commit872f9979ca66f9de4958fee179e93aadf7de7dd8 (patch)
tree8233aab4aaa61bc3c06d71cd4b2f5d58b723cc99
parent6beb82443a9241c4c9035f9b1df9d1358154592c (diff)
downloadFreeBSD-src-872f9979ca66f9de4958fee179e93aadf7de7dd8.zip
FreeBSD-src-872f9979ca66f9de4958fee179e93aadf7de7dd8.tar.gz
Register symbolic port/node names in FC name server.
This is cosmetics that simplifies identification of new ports on FC switch. It would be good to use target name from CTL here instead of hostname, but it is not passed here through CAM now. MFC after: 2 weeks
-rw-r--r--sys/dev/isp/isp.c134
-rw-r--r--sys/dev/isp/isp_freebsd.h1
-rw-r--r--sys/dev/isp/isp_library.c23
-rw-r--r--sys/dev/isp/isp_library.h2
-rw-r--r--sys/dev/isp/isp_stds.h25
-rw-r--r--sys/dev/isp/ispmbox.h2
6 files changed, 181 insertions, 6 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index c4c7d80..5dd47bd 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -126,6 +126,8 @@ static int isp_send_change_request(ispsoftc_t *, int);
static int isp_register_fc4_type(ispsoftc_t *, int);
static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
static int isp_register_fc4_features_24xx(ispsoftc_t *, int);
+static int isp_register_port_name_24xx(ispsoftc_t *, int);
+static int isp_register_node_name_24xx(ispsoftc_t *, int);
static uint16_t isp_next_handle(ispsoftc_t *, uint16_t *);
static int isp_fw_state(ispsoftc_t *, int);
static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
@@ -3073,6 +3075,8 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
r = isp_register_fc4_type_24xx(isp, chan);
if (r == 0)
isp_register_fc4_features_24xx(isp, chan);
+ isp_register_port_name_24xx(isp, chan);
+ isp_register_node_name_24xx(isp, chan);
} else {
fcp->isp_sns_hdl = SNS_ID;
r = isp_register_fc4_type(isp, chan);
@@ -3577,8 +3581,6 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
/*
* Build the CT header and command in memory.
- *
- * Note that the CT header has to end up as Big Endian format in memory.
*/
ISP_MEMZERO(&ct, sizeof (ct));
ct.ct_revision = CT_REVISION;
@@ -3982,8 +3984,6 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
/*
* Build the CT header and command in memory.
- *
- * Note that the CT header has to end up as Big Endian format in memory.
*/
ISP_MEMZERO(&rp, sizeof(rp));
ct = &rp.rftid_hdr;
@@ -4034,8 +4034,6 @@ isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
/*
* Build the CT header and command in memory.
- *
- * Note that the CT header has to end up as Big Endian format in memory.
*/
ISP_MEMZERO(&rp, sizeof(rp));
ct = &rp.rffid_hdr;
@@ -4079,6 +4077,130 @@ isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
return (0);
}
+static int
+isp_register_port_name_24xx(ispsoftc_t *isp, int chan)
+{
+ fcparam *fcp = FCPARAM(isp, chan);
+ ct_hdr_t *ct;
+ rspn_id_t rp;
+ uint8_t *scp = fcp->isp_scratch;
+ int len;
+
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
+
+ /*
+ * Build the CT header and command in memory.
+ */
+ ISP_MEMZERO(&rp, sizeof(rp));
+ ct = &rp.rspnid_hdr;
+ ct->ct_revision = CT_REVISION;
+ ct->ct_fcs_type = CT_FC_TYPE_FC;
+ ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
+ ct->ct_cmd_resp = SNS_RSPN_ID;
+ rp.rspnid_portid[0] = fcp->isp_portid >> 16;
+ rp.rspnid_portid[1] = fcp->isp_portid >> 8;
+ rp.rspnid_portid[2] = fcp->isp_portid;
+ rp.rspnid_length = 0;
+ len = offsetof(rspn_id_t, rspnid_name);
+ mtx_lock(&prison0.pr_mtx);
+ rp.rspnid_length += sprintf(&scp[XTXOFF + len + rp.rspnid_length],
+ "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
+ mtx_unlock(&prison0.pr_mtx);
+ rp.rspnid_length += sprintf(&scp[XTXOFF + len + rp.rspnid_length],
+ ":%s", device_get_nameunit(isp->isp_dev));
+ if (chan != 0) {
+ rp.rspnid_length += sprintf(&scp[XTXOFF + len +
+ rp.rspnid_length], "/%d", chan);
+ }
+ len += rp.rspnid_length;
+ ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
+ isp_put_rspn_id(isp, &rp, (rspn_id_t *)&scp[XTXOFF]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT request", len, &scp[XTXOFF]);
+
+ if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ return (-1);
+ }
+
+ isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
+ FC_SCRATCH_RELEASE(isp, chan);
+ if (ct->ct_cmd_resp == LS_RJT) {
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
+ "Chan %d Register Symbolic Port Name rejected", chan);
+ return (-1);
+ } else if (ct->ct_cmd_resp == LS_ACC) {
+ isp_prt(isp, ISP_LOG_SANCFG,
+ "Chan %d Register Symbolic Port Name accepted", chan);
+ } else {
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d Register Symbolic Port Name: 0x%x", chan, ct->ct_cmd_resp);
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+isp_register_node_name_24xx(ispsoftc_t *isp, int chan)
+{
+ fcparam *fcp = FCPARAM(isp, chan);
+ ct_hdr_t *ct;
+ rsnn_nn_t rp;
+ uint8_t *scp = fcp->isp_scratch;
+ int len;
+
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
+
+ /*
+ * Build the CT header and command in memory.
+ */
+ ISP_MEMZERO(&rp, sizeof(rp));
+ ct = &rp.rsnnnn_hdr;
+ ct->ct_revision = CT_REVISION;
+ ct->ct_fcs_type = CT_FC_TYPE_FC;
+ ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
+ ct->ct_cmd_resp = SNS_RSNN_NN;
+ MAKE_NODE_NAME_FROM_WWN(rp.rsnnnn_nodename, fcp->isp_wwnn);
+ rp.rsnnnn_length = 0;
+ len = offsetof(rsnn_nn_t, rsnnnn_name);
+ mtx_lock(&prison0.pr_mtx);
+ rp.rsnnnn_length += sprintf(&scp[XTXOFF + len + rp.rsnnnn_length],
+ "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
+ mtx_unlock(&prison0.pr_mtx);
+ len += rp.rsnnnn_length;
+ ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
+ isp_put_rsnn_nn(isp, &rp, (rsnn_nn_t *)&scp[XTXOFF]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT request", len, &scp[XTXOFF]);
+
+ if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ return (-1);
+ }
+
+ isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
+ FC_SCRATCH_RELEASE(isp, chan);
+ if (ct->ct_cmd_resp == LS_RJT) {
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
+ "Chan %d Register Symbolic Node Name rejected", chan);
+ return (-1);
+ } else if (ct->ct_cmd_resp == LS_ACC) {
+ isp_prt(isp, ISP_LOG_SANCFG,
+ "Chan %d Register Symbolic Node Name accepted", chan);
+ } else {
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d Register Symbolic Node Name: 0x%x", chan, ct->ct_cmd_resp);
+ return (-1);
+ }
+ return (0);
+}
+
static uint16_t
isp_next_handle(ispsoftc_t *isp, uint16_t *ohp)
{
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index 7702ee6..3e77077 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -32,6 +32,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/endian.h>
+#include <sys/jail.h>
#include <sys/lock.h>
#include <sys/kernel.h>
#include <sys/queue.h>
diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c
index 78c7f6f..987e515 100644
--- a/sys/dev/isp/isp_library.c
+++ b/sys/dev/isp/isp_library.c
@@ -1988,6 +1988,17 @@ isp_put_rft_id(ispsoftc_t *isp, rft_id_t *src, rft_id_t *dst)
}
void
+isp_put_rspn_id(ispsoftc_t *isp, rspn_id_t *src, rspn_id_t *dst)
+{
+/* int i;*/
+ isp_put_ct_hdr(isp, &src->rspnid_hdr, &dst->rspnid_hdr);
+ ISP_IOZPUT_8(isp, src->rspnid_reserved, &dst->rspnid_reserved);
+ ISP_IOZPUT_8(isp, src->rspnid_length, &dst->rspnid_length);
+/* for (i = 0; i < src->rspnid_length; i++)
+ ISP_IOZPUT_8(isp, src->rspnid_name[i], &dst->rspnid_name[i]);*/
+}
+
+void
isp_put_rff_id(ispsoftc_t *isp, rff_id_t *src, rff_id_t *dst)
{
int i;
@@ -2002,6 +2013,18 @@ isp_put_rff_id(ispsoftc_t *isp, rff_id_t *src, rff_id_t *dst)
}
void
+isp_put_rsnn_nn(ispsoftc_t *isp, rsnn_nn_t *src, rsnn_nn_t *dst)
+{
+ int i;
+ isp_put_ct_hdr(isp, &src->rsnnnn_hdr, &dst->rsnnnn_hdr);
+ for (i = 0; i < 8; i++)
+ ISP_IOZPUT_8(isp, src->rsnnnn_nodename[i], &dst->rsnnnn_nodename[i]);
+ ISP_IOZPUT_8(isp, src->rsnnnn_length, &dst->rsnnnn_length);
+/* for (i = 0; i < src->rsnnnn_length; i++)
+ ISP_IOZPUT_8(isp, src->rsnnnn_name[i], &dst->rsnnnn_name[i]);*/
+}
+
+void
isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *src, ct_hdr_t *dst)
{
ISP_IOZGET_8(isp, &src->ct_revision, dst->ct_revision);
diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h
index 922a98b..c70b2cc 100644
--- a/sys/dev/isp/isp_library.h
+++ b/sys/dev/isp/isp_library.h
@@ -144,7 +144,9 @@ void isp_get_fc_hdr(ispsoftc_t *, fc_hdr_t *, fc_hdr_t *);
void isp_put_fc_hdr(ispsoftc_t *, fc_hdr_t *, fc_hdr_t *);
void isp_get_fcp_cmnd_iu(ispsoftc_t *, fcp_cmnd_iu_t *, fcp_cmnd_iu_t *);
void isp_put_rft_id(ispsoftc_t *, rft_id_t *, rft_id_t *);
+void isp_put_rspn_id(ispsoftc_t *, rspn_id_t *, rspn_id_t *);
void isp_put_rff_id(ispsoftc_t *, rff_id_t *, rff_id_t *);
+void isp_put_rsnn_nn(ispsoftc_t *, rsnn_nn_t *, rsnn_nn_t *);
void isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
void isp_put_fcp_rsp_iu(ispsoftc_t *isp, fcp_rsp_iu_t *, fcp_rsp_iu_t *);
diff --git a/sys/dev/isp/isp_stds.h b/sys/dev/isp/isp_stds.h
index 315870e..a83f08f 100644
--- a/sys/dev/isp/isp_stds.h
+++ b/sys/dev/isp/isp_stds.h
@@ -139,6 +139,19 @@ typedef struct {
} rft_id_t;
/*
+ * RSPN_ID Requet CT_IU
+ *
+ * Source: INCITS 463-2010 Generic Services 6 Section 5.2.5.32
+ */
+typedef struct {
+ ct_hdr_t rspnid_hdr;
+ uint8_t rspnid_reserved;
+ uint8_t rspnid_portid[3];
+ uint8_t rspnid_length;
+ uint8_t rspnid_name[0];
+} rspn_id_t;
+
+/*
* RFF_ID Requet CT_IU
*
* Source: INCITS 463-2010 Generic Services 6 Section 5.2.5.34
@@ -153,6 +166,18 @@ typedef struct {
} rff_id_t;
/*
+ * RSNN_NN Requet CT_IU
+ *
+ * Source: INCITS 463-2010 Generic Services 6 Section 5.2.5.35
+ */
+typedef struct {
+ ct_hdr_t rsnnnn_hdr;
+ uint8_t rsnnnn_nodename[8];
+ uint8_t rsnnnn_length;
+ uint8_t rsnnnn_name[0];
+} rsnn_nn_t;
+
+/*
* FCP Response IU and bits of interest
* Source: NCITS T10, Project 1828D, Revision 02b (aka FCP4r02b)
*/
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index 5a1306f..8bd4d1a 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -1548,7 +1548,9 @@ typedef struct {
#define SNS_GFF_ID 0x11F
#define SNS_GID_FT 0x171
#define SNS_RFT_ID 0x217
+#define SNS_RSPN_ID 0x218
#define SNS_RFF_ID 0x21F
+#define SNS_RSNN_NN 0x239
typedef struct {
uint16_t snscb_rblen; /* response buffer length (words) */
uint16_t snscb_reserved0;
OpenPOWER on IntegriCloud