summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-10-05 08:30:49 +0000
committermav <mav@FreeBSD.org>2015-10-05 08:30:49 +0000
commit9b07ecd0998dda43886587a22afa4d7bb60c8ffd (patch)
tree91ebf7467161bde1bba4da2156cbaf84810dea46
parent587443b8f97f656b62f9baeabd7245ca7841a5fc (diff)
downloadFreeBSD-src-9b07ecd0998dda43886587a22afa4d7bb60c8ffd.zip
FreeBSD-src-9b07ecd0998dda43886587a22afa4d7bb60c8ffd.tar.gz
MFC r285155:
Make first step toward supporting target and initiator roles same time. To avoid conflicts between target and initiator devices in CAM, make CTL use target ID reported by HBA as its initiator_id in XPT_PATH_INQ. That target ID is known to never be used for initiator role, so it won't conflict. For Fibre Channel and FireWire HBAs this specific ID choice is irrelevant since all target IDs there are virtual. Same time for SPI HBAs it seems could be even requirement to use same target ID for both initiator and target roles. While there are some more things to polish in isp(4) driver, first tests of using both roles same time on the same port appeared successfull: # camcontrol devlist -v scbus0 on isp0 bus 0: <FREEBSD CTLDISK 0001> at scbus0 target 1 lun 0 (da20,pass21) <> at scbus0 target 256 lun 0 (ctl0) <> at scbus0 target -1 lun ffffffff (ctl1)
-rw-r--r--sys/cam/ctl/scsi_ctl.c18
-rw-r--r--sys/dev/isp/isp_freebsd.c41
2 files changed, 10 insertions, 49 deletions
diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c
index 6bd0196..367d8c9 100644
--- a/sys/cam/ctl/scsi_ctl.c
+++ b/sys/cam/ctl/scsi_ctl.c
@@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$");
struct ctlfe_softc {
struct ctl_port port;
path_id_t path_id;
+ target_id_t target_id;
u_int maxio;
struct cam_sim *sim;
char port_name[DEV_IDLEN];
@@ -357,6 +358,7 @@ ctlfeasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
}
softc->path_id = cpi->ccb_h.path_id;
+ softc->target_id = cpi->initiator_id;
softc->sim = xpt_path_sim(path);
if (cpi->maxio != 0)
softc->maxio = cpi->maxio;
@@ -1557,6 +1559,8 @@ ctlfe_onoffline(void *arg, int online)
}
ccb = xpt_alloc_ccb();
xpt_setup_ccb(&ccb->ccb_h, path, CAM_PRIORITY_NONE);
+ ccb->ccb_h.func_code = XPT_GET_SIM_KNOB;
+ xpt_action(ccb);
/*
* Copan WWN format:
@@ -1570,15 +1574,7 @@ ctlfe_onoffline(void *arg, int online)
* 3 == NL-Port
* Bits 7-0: 0 == Node Name, >0 == Port Number
*/
-
if (online != 0) {
-
- ccb->ccb_h.func_code = XPT_GET_SIM_KNOB;
-
-
- xpt_action(ccb);
-
-
if ((ccb->knob.xport_specific.valid & KNOB_VALID_ADDRESS) != 0){
#ifdef RANDOM_WWNN
uint64_t random_bits;
@@ -1677,9 +1673,9 @@ ctlfe_onoffline(void *arg, int online)
ccb->knob.xport_specific.valid |= KNOB_VALID_ADDRESS;
if (online != 0)
- ccb->knob.xport_specific.fc.role = KNOB_ROLE_TARGET;
+ ccb->knob.xport_specific.fc.role |= KNOB_ROLE_TARGET;
else
- ccb->knob.xport_specific.fc.role = KNOB_ROLE_NONE;
+ ccb->knob.xport_specific.fc.role &= ~KNOB_ROLE_TARGET;
xpt_action(ccb);
@@ -1809,7 +1805,7 @@ ctlfe_lun_enable(void *arg, int lun_id)
bus_softc = (struct ctlfe_softc *)arg;
status = xpt_create_path(&path, /*periph*/ NULL,
- bus_softc->path_id, 0, lun_id);
+ bus_softc->path_id, bus_softc->target_id, lun_id);
/* XXX KDM need some way to return status to CTL here? */
if (status != CAM_REQ_CMP) {
printf("%s: could not create path, status %#x\n", __func__,
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 194049a..c3b45cb 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -462,24 +462,11 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
retval = EINVAL;
break;
}
- if (IS_FC(isp)) {
- /*
- * We don't really support dual role at present on FC cards.
- *
- * We should, but a bunch of things are currently broken,
- * so don't allow it.
- */
- if (nr == ISP_ROLE_BOTH) {
- isp_prt(isp, ISP_LOGERR, "cannot support dual role at present");
- retval = EINVAL;
- break;
- }
- ISP_LOCK(isp);
+ ISP_LOCK(isp);
+ if (IS_FC(isp))
*(int *)addr = FCPARAM(isp, chan)->role;
- } else {
- ISP_LOCK(isp);
+ else
*(int *)addr = SDPARAM(isp, chan)->role;
- }
retval = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, nr);
ISP_UNLOCK(isp);
retval = 0;
@@ -1262,11 +1249,6 @@ isp_enable_lun(ispsoftc_t *isp, union ccb *ccb)
target = ccb->ccb_h.target_id;
lun = ccb->ccb_h.target_lun;
ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "enabling lun %u\n", lun);
- if (target != CAM_TARGET_WILDCARD && target != 0) {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
ccb->ccb_h.status = CAM_LUN_INVALID;
xpt_done(ccb);
@@ -1479,12 +1461,6 @@ isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
target = ccb->ccb_h.target_id;
lun = ccb->ccb_h.target_lun;
ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "disabling lun %u\n", lun);
- if (target != CAM_TARGET_WILDCARD && target != 0) {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
-
if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
ccb->ccb_h.status = CAM_LUN_INVALID;
xpt_done(ccb);
@@ -5437,21 +5413,10 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
}
break;
case KNOB_ROLE_BOTH:
-#if 0
if (fcp->role != ISP_ROLE_BOTH) {
rchange = 1;
newrole = ISP_ROLE_BOTH;
}
-#else
- /*
- * We don't really support dual role at present on FC cards.
- *
- * We should, but a bunch of things are currently broken,
- * so don't allow it.
- */
- isp_prt(isp, ISP_LOGERR, "cannot support dual role at present");
- ccb->ccb_h.status = CAM_REQ_INVALID;
-#endif
break;
}
if (rchange) {
OpenPOWER on IntegriCloud