Date: Tue, 23 Jun 2015 16:13:21 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r284727 - head/sys/dev/isp Message-ID: <201506231613.t5NGDL6l015357@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Tue Jun 23 16:13:20 2015 New Revision: 284727 URL: https://svnweb.freebsd.org/changeset/base/284727 Log: Add dev.isp.X.role sysctl in addition to tunable. It (mostly) allows to enable/disable initiator mode in run time. Target mode control is blocked here to force coordination with CTL. While there, add separate tunables/sysctls for virtual channels. Modified: head/sys/dev/isp/isp_freebsd.c head/sys/dev/isp/isp_pci.c Modified: head/sys/dev/isp/isp_freebsd.c ============================================================================== --- head/sys/dev/isp/isp_freebsd.c Tue Jun 23 15:49:12 2015 (r284726) +++ head/sys/dev/isp/isp_freebsd.c Tue Jun 23 16:13:20 2015 (r284727) @@ -84,6 +84,43 @@ static struct cdevsw isp_cdevsw = { }; static int +isp_role_sysctl(SYSCTL_HANDLER_ARGS) +{ + ispsoftc_t *isp = (ispsoftc_t *)arg1; + int chan = arg2; + int error, old, value; + + value = FCPARAM(isp, chan)->role; + + error = sysctl_handle_int(oidp, &value, 0, req); + if ((error != 0) || (req->newptr == NULL)) + return (error); + + if (value < ISP_ROLE_NONE || value > ISP_ROLE_BOTH) + return (EINVAL); + + ISP_LOCK(isp); + old = FCPARAM(isp, chan)->role; + + /* If nothing has changed -- we are done. */ + if (value == old) { + ISP_UNLOCK(isp); + return (0); + } + + /* We don't allow target mode switch from here. */ + if ((value ^ old) & ISP_ROLE_TARGET) { + ISP_UNLOCK(isp); + return (EPERM); + } + + /* Actually change the role. */ + error = isp_fc_change_role(isp, chan, value); + ISP_UNLOCK(isp); + return (error); +} + +static int isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan) { struct ccb_setasync csa; @@ -138,6 +175,9 @@ isp_attach_chan(ispsoftc_t *isp, struct } else { fcparam *fcp = FCPARAM(isp, chan); struct isp_fc *fc = ISP_FC_PC(isp, chan); + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(isp->isp_osinfo.dev); + struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev); + char name[16]; ISP_LOCK(isp); fc->sim = sim; @@ -178,17 +218,21 @@ isp_attach_chan(ispsoftc_t *isp, struct } ISP_FC_PC(isp, chan)->num_threads += 1; #endif - if (chan == 0) { - struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(isp->isp_osinfo.dev); - struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev); - SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwnn", CTLFLAG_RD, &FCPARAM(isp, 0)->isp_wwnn, "World Wide Node Name"); - SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwpn", CTLFLAG_RD, &FCPARAM(isp, 0)->isp_wwpn, "World Wide Port Name"); - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "loop_down_limit", CTLFLAG_RW, &ISP_FC_PC(isp, 0)->loop_down_limit, 0, "Loop Down Limit"); - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "gone_device_time", CTLFLAG_RW, &ISP_FC_PC(isp, 0)->gone_device_time, 0, "Gone Device Time"); + if (chan > 0) { + snprintf(name, sizeof(name), "chan%d", chan); + tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), + OID_AUTO, name, CTLFLAG_RW, 0, "Virtual channel"); + } + SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwnn", CTLFLAG_RD, &FCPARAM(isp, chan)->isp_wwnn, "World Wide Node Name"); + SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwpn", CTLFLAG_RD, &FCPARAM(isp, chan)->isp_wwpn, "World Wide Port Name"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "loop_down_limit", CTLFLAG_RW, &ISP_FC_PC(isp, chan)->loop_down_limit, 0, "Loop Down Limit"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "gone_device_time", CTLFLAG_RW, &ISP_FC_PC(isp, chan)->gone_device_time, 0, "Gone Device Time"); #if defined(ISP_TARGET_MODE) && defined(DEBUG) - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "inject_lost_data_frame", CTLFLAG_RW, &ISP_FC_PC(isp, 0)->inject_lost_data_frame, 0, "Cause a Lost Frame on a Read"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "inject_lost_data_frame", CTLFLAG_RW, &ISP_FC_PC(isp, chan)->inject_lost_data_frame, 0, "Cause a Lost Frame on a Read"); #endif - } + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "role", CTLTYPE_INT | CTLFLAG_RW, isp, chan, + isp_role_sysctl, "I", "Current role"); } return (0); } Modified: head/sys/dev/isp/isp_pci.c ============================================================================== --- head/sys/dev/isp/isp_pci.c Tue Jun 23 15:49:12 2015 (r284726) +++ head/sys/dev/isp/isp_pci.c Tue Jun 23 16:13:20 2015 (r284727) @@ -527,8 +527,15 @@ isp_get_specific_options(device_t dev, i { const char *sptr; int tval = 0; + char prefix[12], name[16]; - if (resource_int_value(device_get_name(dev), device_get_unit(dev), "iid", &tval)) { + if (chan == 0) + prefix[0] = 0; + else + snprintf(prefix, sizeof(prefix), "chan%d.", chan); + snprintf(name, sizeof(name), "%siid", prefix); + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + name, &tval)) { if (IS_FC(isp)) { ISP_FC_PC(isp, chan)->default_id = 109 - chan; } else { @@ -548,13 +555,15 @@ isp_get_specific_options(device_t dev, i } tval = -1; - if (resource_int_value(device_get_name(dev), device_get_unit(dev), "role", &tval) == 0) { + snprintf(name, sizeof(name), "%srole", prefix); + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + name, &tval) == 0) { switch (tval) { case ISP_ROLE_NONE: case ISP_ROLE_INITIATOR: case ISP_ROLE_TARGET: - case ISP_ROLE_INITIATOR|ISP_ROLE_TARGET: - device_printf(dev, "setting role to 0x%x\n", tval); + case ISP_ROLE_BOTH: + device_printf(dev, "Chan %d setting role to 0x%x\n", chan, tval); break; default: tval = -1; @@ -572,11 +581,15 @@ isp_get_specific_options(device_t dev, i ISP_FC_PC(isp, chan)->def_role = tval; tval = 0; - if (resource_int_value(device_get_name(dev), device_get_unit(dev), "fullduplex", &tval) == 0 && tval != 0) { + snprintf(name, sizeof(name), "%sfullduplex", prefix); + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + name, &tval) == 0 && tval != 0) { isp->isp_confopts |= ISP_CFG_FULL_DUPLEX; } sptr = 0; - if (resource_string_value(device_get_name(dev), device_get_unit(dev), "topology", (const char **) &sptr) == 0 && sptr != 0) { + snprintf(name, sizeof(name), "%stopology", prefix); + if (resource_string_value(device_get_name(dev), device_get_unit(dev), + name, (const char **) &sptr) == 0 && sptr != 0) { if (strcmp(sptr, "lport") == 0) { isp->isp_confopts |= ISP_CFG_LPORT; } else if (strcmp(sptr, "nport") == 0) { @@ -589,13 +602,17 @@ isp_get_specific_options(device_t dev, i } tval = 0; - (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "nofctape", &tval); + snprintf(name, sizeof(name), "%snofctape", prefix); + (void) resource_int_value(device_get_name(dev), device_get_unit(dev), + name, &tval); if (tval) { isp->isp_confopts |= ISP_CFG_NOFCTAPE; } tval = 0; - (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "fctape", &tval); + snprintf(name, sizeof(name), "%sfctape", prefix); + (void) resource_int_value(device_get_name(dev), device_get_unit(dev), + name, &tval); if (tval) { isp->isp_confopts &= ~ISP_CFG_NOFCTAPE; isp->isp_confopts |= ISP_CFG_FCTAPE; @@ -611,7 +628,9 @@ isp_get_specific_options(device_t dev, i * 'w' (e..g w50000000aaaa0001). Sigh. */ sptr = 0; - tval = resource_string_value(device_get_name(dev), device_get_unit(dev), "portwwn", (const char **) &sptr); + snprintf(name, sizeof(name), "%sportwwn", prefix); + tval = resource_string_value(device_get_name(dev), device_get_unit(dev), + name, (const char **) &sptr); if (tval == 0 && sptr != 0 && *sptr++ == 'w') { char *eptr = 0; ISP_FC_PC(isp, chan)->def_wwpn = strtouq(sptr, &eptr, 16); @@ -622,7 +641,9 @@ isp_get_specific_options(device_t dev, i } sptr = 0; - tval = resource_string_value(device_get_name(dev), device_get_unit(dev), "nodewwn", (const char **) &sptr); + snprintf(name, sizeof(name), "%snodewwn", prefix); + tval = resource_string_value(device_get_name(dev), device_get_unit(dev), + name, (const char **) &sptr); if (tval == 0 && sptr != 0 && *sptr++ == 'w') { char *eptr = 0; ISP_FC_PC(isp, chan)->def_wwnn = strtouq(sptr, &eptr, 16); @@ -633,7 +654,9 @@ isp_get_specific_options(device_t dev, i } tval = 0; - (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "hysteresis", &tval); + snprintf(name, sizeof(name), "%shysteresis", prefix); + (void) resource_int_value(device_get_name(dev), device_get_unit(dev), + "name", &tval); if (tval >= 0 && tval < 256) { ISP_FC_PC(isp, chan)->hysteresis = tval; } else { @@ -641,7 +664,9 @@ isp_get_specific_options(device_t dev, i } tval = -1; - (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "loop_down_limit", &tval); + snprintf(name, sizeof(name), "%sloop_down_limit", prefix); + (void) resource_int_value(device_get_name(dev), device_get_unit(dev), + name, &tval); if (tval >= 0 && tval < 0xffff) { ISP_FC_PC(isp, chan)->loop_down_limit = tval; } else { @@ -649,7 +674,9 @@ isp_get_specific_options(device_t dev, i } tval = -1; - (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "gone_device_time", &tval); + snprintf(name, sizeof(name), "%sgone_device_time", prefix); + (void) resource_int_value(device_get_name(dev), device_get_unit(dev), + name, &tval); if (tval >= 0 && tval < 0xffff) { ISP_FC_PC(isp, chan)->gone_device_time = tval; } else {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506231613.t5NGDL6l015357>