summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp.c
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-07-04 21:50:39 +0000
committerdim <dim@FreeBSD.org>2015-07-04 21:50:39 +0000
commit6f44bd3256388beb23fd03fdf43ad5d53cf43e29 (patch)
tree37590f5c697f4198fdddec33c58aefdef0a5f485 /sys/dev/isp/isp.c
parentcea4c167517a0678c7dbf92a0324088dcbac1035 (diff)
parent76b8ff88e56f9ad0639b7e23dd9d1128a0750026 (diff)
downloadFreeBSD-src-6f44bd3256388beb23fd03fdf43ad5d53cf43e29.zip
FreeBSD-src-6f44bd3256388beb23fd03fdf43ad5d53cf43e29.tar.gz
Merge ^/head r284737 through r285152.
Diffstat (limited to 'sys/dev/isp/isp.c')
-rw-r--r--sys/dev/isp/isp.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 5a18958..dd203a4 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -1848,7 +1848,7 @@ isp_fibre_init(ispsoftc_t *isp)
icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
}
#endif
- if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
+ if (fcp->isp_wwnn && fcp->isp_wwpn) {
icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
@@ -2075,7 +2075,7 @@ isp_fibre_init_2400(ispsoftc_t *isp)
}
icbp->icb_logintime = ICB_LOGIN_TOV;
- if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
+ if (fcp->isp_wwnn && fcp->isp_wwpn) {
icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
@@ -2223,6 +2223,36 @@ isp_fibre_init_2400(ispsoftc_t *isp)
}
static void
+isp_del_all_init_entries(ispsoftc_t *isp, int chan)
+{
+ fcparam *fcp = FCPARAM(isp, chan);
+ fcportdb_t *lp;
+ int i;
+
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ lp = &fcp->portdb[i];
+ if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode)
+ continue;
+ /*
+ * It's up to the outer layers to clear isp_dev_map.
+ */
+ lp->state = FC_PORTDB_STATE_NIL;
+ isp_async(isp, ISPASYNC_DEV_GONE, chan, lp, 1);
+ if (lp->autologin == 0) {
+ (void) isp_plogx(isp, chan, lp->handle,
+ lp->portid,
+ PLOGX_FLG_CMD_LOGO |
+ PLOGX_FLG_IMPLICIT |
+ PLOGX_FLG_FREE_NPHDL, 0);
+ } else {
+ lp->autologin = 0;
+ }
+ lp->new_prli_word3 = 0;
+ lp->new_portid = 0;
+ }
+}
+
+static void
isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
{
fcparam *fcp = FCPARAM(isp, chan);
@@ -2981,7 +3011,7 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
* It's up to the outer layers to clear isp_dev_map.
*/
lp->state = FC_PORTDB_STATE_NIL;
- isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
+ isp_async(isp, ISPASYNC_DEV_GONE, chan, lp, 0);
if (lp->autologin == 0) {
(void) isp_plogx(isp, chan, lp->handle,
lp->portid,
@@ -4990,6 +5020,28 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
return (r);
}
+ case ISPCTL_CHANGE_ROLE:
+ {
+ int role, r;
+
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ role = va_arg(ap, int);
+ va_end(ap);
+ if (IS_FC(isp)) {
+#ifdef ISP_TARGET_MODE
+ if ((role & ISP_ROLE_TARGET) == 0)
+ isp_del_all_wwn_entries(isp, chan);
+#endif
+ if ((role & ISP_ROLE_INITIATOR) == 0)
+ isp_del_all_init_entries(isp, chan);
+ r = isp_fc_change_role(isp, chan, role);
+ } else {
+ SDPARAM(isp, chan)->role = role;
+ r = 0;
+ }
+ return (r);
+ }
default:
isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
break;
OpenPOWER on IntegriCloud