summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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