diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/os/sunmdi.c | 277 | ||||
-rw-r--r-- | usr/src/uts/common/sys/mdi_impldefs.h | 10 | ||||
-rw-r--r-- | usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h | 8 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sunmdi.h | 13 |
4 files changed, 181 insertions, 127 deletions
diff --git a/usr/src/uts/common/os/sunmdi.c b/usr/src/uts/common/os/sunmdi.c index 208136b2f9..df174f049a 100644 --- a/usr/src/uts/common/os/sunmdi.c +++ b/usr/src/uts/common/os/sunmdi.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -248,8 +247,14 @@ static void i_mdi_client_lock(mdi_client_t *, mdi_pathinfo_t *); static void i_mdi_client_unlock(mdi_client_t *); static int i_mdi_client_free(mdi_vhci_t *, mdi_client_t *); static mdi_client_t *i_devi_get_client(dev_info_t *); -static int i_mdi_pi_enable_disable(dev_info_t *, dev_info_t *, int, - int); +/* + * NOTE: this will be removed once the NWS files are changed to use the new + * mdi_{enable,disable}_path interfaces + */ +static int i_mdi_pi_enable_disable(dev_info_t *, dev_info_t *, + int, int); +static mdi_pathinfo_t *i_mdi_enable_disable_path(mdi_pathinfo_t *pip, + mdi_vhci_t *vh, int flags, int op); /* * Failover related function prototypes */ @@ -1912,8 +1917,8 @@ mdi_select_path(dev_info_t *cdip, struct buf *bp, int flags, * Since we are checking for state == ONLINE and the * same veriable is used for DISABLE/ENABLE information. */ - if (MDI_PI(pip)->pi_state == - MDI_PATHINFO_STATE_ONLINE && + if ((MDI_PI(pip)->pi_state == + MDI_PATHINFO_STATE_ONLINE) && preferred == MDI_PI(pip)->pi_preferred) { /* * Return the path in hold state. Caller should @@ -2040,6 +2045,22 @@ mdi_select_path(dev_info_t *cdip, struct buf *bp, int flags, MDI_PATHINFO_STATE_STANDBY)) && MDI_PI(pip)->pi_preferred == preferred) ? 1 : 0); + } else if (flags == + (MDI_SELECT_STANDBY_PATH | + MDI_SELECT_ONLINE_PATH | + MDI_SELECT_USER_DISABLE_PATH)) { + cond = (((MDI_PI(pip)->pi_state == + MDI_PATHINFO_STATE_ONLINE || + (MDI_PI(pip)->pi_state == + MDI_PATHINFO_STATE_STANDBY) || + (MDI_PI(pip)->pi_state == + (MDI_PATHINFO_STATE_ONLINE| + MDI_PATHINFO_STATE_USER_DISABLE)) || + (MDI_PI(pip)->pi_state == + (MDI_PATHINFO_STATE_STANDBY | + MDI_PATHINFO_STATE_USER_DISABLE)))&& + MDI_PI(pip)->pi_preferred == + preferred) ? 1 : 0); } else { cond = 0; } @@ -5230,10 +5251,61 @@ mdi_pi_kstat_iosupdate(mdi_pathinfo_t *pip, struct buf *bp) } /* + * Enable the path(specific client/target/initiator) + * Enabling a path means that MPxIO may select the enabled path for routing + * future I/O requests, subject to other path state constraints. + */ +int +mdi_pi_enable_path(mdi_pathinfo_t *pip, int flags) +{ + mdi_phci_t *ph; + + ph = i_devi_get_phci(mdi_pi_get_phci(pip)); + if (ph == NULL) { + MDI_DEBUG(1, (CE_NOTE, NULL, "!mdi_pi_enable_path:" + " failed. pip: %p ph = NULL\n", pip)); + return (MDI_FAILURE); + } + + (void) i_mdi_enable_disable_path(pip, ph->ph_vhci, flags, + MDI_ENABLE_OP); + MDI_DEBUG(5, (CE_NOTE, NULL, "!mdi_pi_enable_path:" + " Returning success pip = %p. ph = %p\n", pip, ph)); + return (MDI_SUCCESS); + +} + +/* + * Disable the path (specific client/target/initiator) + * Disabling a path means that MPxIO will not select the disabled path for + * routing any new I/O requests. + */ +int +mdi_pi_disable_path(mdi_pathinfo_t *pip, int flags) +{ + mdi_phci_t *ph; + + ph = i_devi_get_phci(mdi_pi_get_phci(pip)); + if (ph == NULL) { + MDI_DEBUG(1, (CE_NOTE, NULL, "!mdi_pi_disable_path:" + " failed. pip: %p ph = NULL\n", pip)); + return (MDI_FAILURE); + } + + (void) i_mdi_enable_disable_path(pip, + ph->ph_vhci, flags, MDI_DISABLE_OP); + MDI_DEBUG(5, (CE_NOTE, NULL, "!mdi_pi_disable_path:" + "Returning success pip = %p. ph = %p", pip, ph)); + return (MDI_SUCCESS); +} + +/* * disable the path to a particular pHCI (pHCI specified in the phci_path * argument) for a particular client (specified in the client_path argument). * Disabling a path means that MPxIO will not select the disabled path for * routing any new I/O requests. + * NOTE: this will be removed once the NWS files are changed to use the new + * mdi_{enable,disable}_path interfaces */ int mdi_pi_disable(dev_info_t *cdip, dev_info_t *pdip, int flags) @@ -5246,6 +5318,8 @@ mdi_pi_disable(dev_info_t *cdip, dev_info_t *pdip, int flags) * argument) for a particular client (specified in the client_path argument). * Enabling a path means that MPxIO may select the enabled path for routing * future I/O requests, subject to other path state constraints. + * NOTE: this will be removed once the NWS files are changed to use the new + * mdi_{enable,disable}_path interfaces */ int @@ -5254,9 +5328,81 @@ mdi_pi_enable(dev_info_t *cdip, dev_info_t *pdip, int flags) return (i_mdi_pi_enable_disable(cdip, pdip, flags, MDI_ENABLE_OP)); } +/* + * Common routine for doing enable/disable. + */ +static mdi_pathinfo_t * +i_mdi_enable_disable_path(mdi_pathinfo_t *pip, mdi_vhci_t *vh, int flags, + int op) +{ + int sync_flag = 0; + int rv; + mdi_pathinfo_t *next; + int (*f)() = NULL; + + f = vh->vh_ops->vo_pi_state_change; + + sync_flag = (flags << 8) & 0xf00; + + /* + * Do a callback into the mdi consumer to let it + * know that path is about to get enabled/disabled. + */ + if (f != NULL) { + rv = (*f)(vh->vh_dip, pip, 0, + MDI_PI_EXT_STATE(pip), + MDI_EXT_STATE_CHANGE | sync_flag | + op | MDI_BEFORE_STATE_CHANGE); + if (rv != MDI_SUCCESS) { + MDI_DEBUG(2, (CE_WARN, vh->vh_dip, + "!vo_pi_state_change: failed rv = %x", rv)); + } + } + MDI_PI_LOCK(pip); + next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link; + + switch (flags) { + case USER_DISABLE: + if (op == MDI_DISABLE_OP) + MDI_PI_SET_USER_DISABLE(pip); + else + MDI_PI_SET_USER_ENABLE(pip); + break; + case DRIVER_DISABLE: + if (op == MDI_DISABLE_OP) + MDI_PI_SET_DRV_DISABLE(pip); + else + MDI_PI_SET_DRV_ENABLE(pip); + break; + case DRIVER_DISABLE_TRANSIENT: + if (op == MDI_DISABLE_OP && rv == MDI_SUCCESS) + MDI_PI_SET_DRV_DISABLE_TRANS(pip); + else + MDI_PI_SET_DRV_ENABLE_TRANS(pip); + break; + } + MDI_PI_UNLOCK(pip); + /* + * Do a callback into the mdi consumer to let it + * know that path is now enabled/disabled. + */ + if (f != NULL) { + rv = (*f)(vh->vh_dip, pip, 0, + MDI_PI_EXT_STATE(pip), + MDI_EXT_STATE_CHANGE | sync_flag | + op | MDI_AFTER_STATE_CHANGE); + if (rv != MDI_SUCCESS) { + MDI_DEBUG(2, (CE_WARN, vh->vh_dip, + "!vo_pi_state_change: failed rv = %x", rv)); + } + } + return (next); +} /* * Common routine for doing enable/disable. + * NOTE: this will be removed once the NWS files are changed to use the new + * mdi_{enable,disable}_path has been putback */ int i_mdi_pi_enable_disable(dev_info_t *cdip, dev_info_t *pdip, int flags, int op) @@ -5267,9 +5413,6 @@ i_mdi_pi_enable_disable(dev_info_t *cdip, dev_info_t *pdip, int flags, int op) mdi_client_t *ct; mdi_pathinfo_t *next, *pip; int found_it; - int (*f)() = NULL; - int rv; - int sync_flag = 0; ph = i_devi_get_phci(pdip); MDI_DEBUG(5, (CE_NOTE, NULL, "!i_mdi_pi_enable_disable:" @@ -5286,10 +5429,7 @@ i_mdi_pi_enable_disable(dev_info_t *cdip, dev_info_t *pdip, int flags, int op) return (MDI_FAILURE); } - sync_flag = (flags << 8) & 0xf00; - vh = ph->ph_vhci; - f = vh->vh_ops->vo_pi_state_change; if (cdip == NULL) { /* @@ -5330,60 +5470,7 @@ i_mdi_pi_enable_disable(dev_info_t *cdip, dev_info_t *pdip, int flags, int op) */ pip = ph->ph_path_head; while (pip != NULL) { - /* - * Do a callback into the mdi consumer to let it - * know that path is about to be enabled/disabled. - */ - if (f != NULL) { - rv = (*f)(vh->vh_dip, pip, 0, - MDI_PI_EXT_STATE(pip), - MDI_EXT_STATE_CHANGE | sync_flag | - op | MDI_BEFORE_STATE_CHANGE); - if (rv != MDI_SUCCESS) { - MDI_DEBUG(2, (CE_WARN, vh->vh_dip, - "!vo_pi_state_change: failed rv = %x", rv)); - } - } - - MDI_PI_LOCK(pip); - next = - (mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link; - switch (flags) { - case USER_DISABLE: - if (op == MDI_DISABLE_OP) - MDI_PI_SET_USER_DISABLE(pip); - else - MDI_PI_SET_USER_ENABLE(pip); - break; - case DRIVER_DISABLE: - if (op == MDI_DISABLE_OP) - MDI_PI_SET_DRV_DISABLE(pip); - else - MDI_PI_SET_DRV_ENABLE(pip); - break; - case DRIVER_DISABLE_TRANSIENT: - if (op == MDI_DISABLE_OP && rv == MDI_SUCCESS) - MDI_PI_SET_DRV_DISABLE_TRANS(pip); - else - MDI_PI_SET_DRV_ENABLE_TRANS(pip); - break; - } - MDI_PI_UNLOCK(pip); - /* - * Do a callback into the mdi consumer to let it - * know that path is now enabled/disabled. - */ - if (f != NULL) { - rv = (*f)(vh->vh_dip, pip, 0, - MDI_PI_EXT_STATE(pip), - MDI_EXT_STATE_CHANGE | sync_flag | - op | MDI_AFTER_STATE_CHANGE); - if (rv != MDI_SUCCESS) { - MDI_DEBUG(2, (CE_WARN, vh->vh_dip, - "!vo_pi_state_change: failed rv = %x", rv)); - } - } - pip = next; + pip = i_mdi_enable_disable_path(pip, vh, flags, op); } MDI_PHCI_UNLOCK(ph); } else { @@ -5414,6 +5501,7 @@ i_mdi_pi_enable_disable(dev_info_t *cdip, dev_info_t *pdip, int flags, int op) pip = next; } + MDI_CLIENT_UNLOCK(ct); if (found_it == 0) { MDI_DEBUG(1, (CE_NOTE, NULL, @@ -5421,60 +5509,13 @@ i_mdi_pi_enable_disable(dev_info_t *cdip, dev_info_t *pdip, int flags, int op) " failed. Could not find corresponding pip\n")); return (MDI_FAILURE); } - /* - * Do a callback into the mdi consumer to let it - * know that path is about to get enabled/disabled. - */ - if (f != NULL) { - rv = (*f)(vh->vh_dip, pip, 0, - MDI_PI_EXT_STATE(pip), - MDI_EXT_STATE_CHANGE | sync_flag | - op | MDI_BEFORE_STATE_CHANGE); - if (rv != MDI_SUCCESS) { - MDI_DEBUG(2, (CE_WARN, vh->vh_dip, - "!vo_pi_state_change: failed rv = %x", rv)); - } - } - MDI_PI_LOCK(pip); - switch (flags) { - case USER_DISABLE: - if (op == MDI_DISABLE_OP) - MDI_PI_SET_USER_DISABLE(pip); - else - MDI_PI_SET_USER_ENABLE(pip); - break; - case DRIVER_DISABLE: - if (op == MDI_DISABLE_OP) - MDI_PI_SET_DRV_DISABLE(pip); - else - MDI_PI_SET_DRV_ENABLE(pip); - break; - case DRIVER_DISABLE_TRANSIENT: - if (op == MDI_DISABLE_OP && rv == MDI_SUCCESS) - MDI_PI_SET_DRV_DISABLE_TRANS(pip); - else - MDI_PI_SET_DRV_ENABLE_TRANS(pip); - break; - } - MDI_PI_UNLOCK(pip); - /* - * Do a callback into the mdi consumer to let it - * know that path is now enabled/disabled. - */ - if (f != NULL) { - rv = (*f)(vh->vh_dip, pip, 0, - MDI_PI_EXT_STATE(pip), - MDI_EXT_STATE_CHANGE | sync_flag | - op | MDI_AFTER_STATE_CHANGE); - if (rv != MDI_SUCCESS) { - MDI_DEBUG(2, (CE_WARN, vh->vh_dip, - "!vo_pi_state_change: failed rv = %x", rv)); - } - } + + (void) i_mdi_enable_disable_path(pip, vh, flags, op); } MDI_DEBUG(5, (CE_NOTE, NULL, "!i_mdi_pi_enable_disable:" - " Returning success pdip = %p cdip = %p\n", op, pdip, cdip)); + " Returning success op: %x pdip = %p cdip = %p\n", op, + pdip, cdip)); return (MDI_SUCCESS); } diff --git a/usr/src/uts/common/sys/mdi_impldefs.h b/usr/src/uts/common/sys/mdi_impldefs.h index 06b977985b..b861b2d779 100644 --- a/usr/src/uts/common/sys/mdi_impldefs.h +++ b/usr/src/uts/common/sys/mdi_impldefs.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1060,6 +1059,8 @@ dev_info_t *mdi_phci_path2devinfo(dev_info_t *, caddr_t); * * MDI_SELECT_ONLINE_PATH: select an ONLINE path * MDI_SELECT_STANDBY_PATH: select a STANDBY path + * MDI_SELECT_USER_DISABLE_PATH: select user disable for failover and + * auto_failback * * The selected paths are returned in a held state (ref_cnt) and caller should * release the hold by calling mdi_rele_path() at the end of operation. @@ -1077,6 +1078,7 @@ client_lb_t mdi_get_lb_policy(dev_info_t *); */ #define MDI_SELECT_ONLINE_PATH 0x0001 #define MDI_SELECT_STANDBY_PATH 0x0002 +#define MDI_SELECT_USER_DISABLE_PATH 0x0004 /* * MDI client device utility functions diff --git a/usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h b/usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h index b2b5346873..ed45f2f421 100644 --- a/usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h +++ b/usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -390,6 +390,12 @@ typedef struct scsi_vhci_lun { #define VLUN_QUIESCED_FLG 0x08 /* + * This flag is set to tell vhci_update_pathstates to call back + * into vhci_mpapi_update_tpg_acc_state. + */ +#define VLUN_UPDATE_TPG 0x10 + +/* * Various reset recovery depth. */ diff --git a/usr/src/uts/common/sys/sunmdi.h b/usr/src/uts/common/sys/sunmdi.h index 97fe1ea59a..31897d84bc 100644 --- a/usr/src/uts/common/sys/sunmdi.h +++ b/usr/src/uts/common/sys/sunmdi.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -161,8 +160,14 @@ int mdi_pi_online(mdi_pathinfo_t *, int); int mdi_pi_standby(mdi_pathinfo_t *, int); int mdi_pi_fault(mdi_pathinfo_t *, int); int mdi_pi_offline(mdi_pathinfo_t *, int); +/* + * NOTE: the next 2 interfaces will be removed once the NWS files are + * changed to use the new mdi_{enable,disable}_path interfaces + */ int mdi_pi_disable(dev_info_t *, dev_info_t *, int); int mdi_pi_enable(dev_info_t *, dev_info_t *, int); +int mdi_pi_disable_path(mdi_pathinfo_t *, int); +int mdi_pi_enable_path(mdi_pathinfo_t *, int); /* * MPxIO-PM stuff |