1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * CDDL HEADER START
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth *
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * The contents of this file are subject to the terms of the
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * Common Development and Distribution License (the "License").
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * You may not use this file except in compliance with the License.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth *
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * or http://www.opensolaris.org/os/licensing.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * See the License for the specific language governing permissions
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * and limitations under the License.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth *
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * When distributing Covered Code, include this CDDL HEADER in each
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * If applicable, add the following below this CDDL HEADER, with the
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * fields enclosed by brackets "[]" replaced with your own identifying
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * information: Portions Copyright [yyyy] [name of copyright owner]
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth *
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * CDDL HEADER END
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/*
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * Implementation of "scsi_vhci_f_tpgs" T10 standard based failover_ops.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth *
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * NOTE: for non-sequential devices only.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth#include <sys/conf.h>
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth#include <sys/file.h>
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth#include <sys/ddi.h>
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth#include <sys/sunddi.h>
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth#include <sys/scsi/scsi.h>
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth#include <sys/scsi/adapters/scsi_vhci.h>
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs#include <sys/scsi/adapters/scsi_vhci_tpgs.h>
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* Supported device table entries. */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthchar *std_dev_table[] = { NULL };
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* Failover module plumbing. */
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. NelsonSCSI_FAILOVER_OP(SFO_NAME_TPGS, std);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth#define STD_FO_CMD_RETRY_DELAY 1000000 /* 1 seconds */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth#define STD_FO_RETRY_DELAY 2000000 /* 2 seconds */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * max time for failover to complete is 3 minutes. Compute
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * number of retries accordingly, to ensure we wait for at least
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * 3 minutes
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth#define STD_FO_MAX_RETRIES (3*60*1000000)/STD_FO_RETRY_DELAY
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* ARGSUSED */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic int
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstd_device_probe(struct scsi_device *sd, struct scsi_inquiry *inq,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs void **ctpriv)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth int mode, state, xlf, preferred = 0;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(6, (CE_NOTE, NULL, "std_device_probe: vidpid %s\n",
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth inq->inq_vid));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
d91393a8e4d666dd6b6588c980c59cec667835f4Chris Horne if (inq->inq_tpgs == TPGS_FAILOVER_NONE) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_WARN, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!std_device_probe: not a standard tpgs device"));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (SFO_DEVICE_PROBE_PHCI);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs if (inq->inq_dtype == DTYPE_SEQUENTIAL) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_NOTE, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!std_device_probe: Detected a "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "Standard Asymmetric device "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "not yet supported\n"));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (SFO_DEVICE_PROBE_PHCI);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs if (vhci_tpgs_get_target_fo_mode(sd, &mode, &state, &xlf, &preferred)) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_WARN, NULL, "!unable to fetch fo "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "mode: sd(%p)", (void *) sd));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (SFO_DEVICE_PROBE_PHCI);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
d91393a8e4d666dd6b6588c980c59cec667835f4Chris Horne if (inq->inq_tpgs == TPGS_FAILOVER_IMPLICIT) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(1, (CE_NOTE, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!std_device_probe: Detected a "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "Standard Asymmetric device "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "with implicit failover\n"));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (SFO_DEVICE_PROBE_VHCI);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
d91393a8e4d666dd6b6588c980c59cec667835f4Chris Horne if (inq->inq_tpgs == TPGS_FAILOVER_EXPLICIT) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(1, (CE_NOTE, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!std_device_probe: Detected a "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "Standard Asymmetric device "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "with explicit failover\n"));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (SFO_DEVICE_PROBE_VHCI);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
d91393a8e4d666dd6b6588c980c59cec667835f4Chris Horne if (inq->inq_tpgs == TPGS_FAILOVER_BOTH) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(1, (CE_NOTE, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!std_device_probe: Detected a "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "Standard Asymmetric device "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "which supports both implicit and explicit failover\n"));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (SFO_DEVICE_PROBE_VHCI);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(1, (CE_WARN, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!std_device_probe: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "Unknown tpgs_bits: %x", inq->inq_tpgs));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (SFO_DEVICE_PROBE_PHCI);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* ARGSUSED */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic void
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstd_device_unprobe(struct scsi_device *sd, void *ctpriv)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth /*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * For future use
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* ARGSUSED */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic int
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstd_activate_explicit(struct scsi_device *sd, int xlf_capable)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth cmn_err(CE_NOTE, "Explicit Activation is done by "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "vhci_tpgs_set_target_groups() call from MPAPI");
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * Process the packet reason of CMD_PKT_CMPLT - return 0 if no
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * retry and 1 if a retry should be done
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic int
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstd_process_cmplt_pkt(struct scsi_device *sd, struct scsi_pkt *pkt,
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li int *retry_cnt, int *retval)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li *retval = 1; /* fail */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth switch (SCBP_C(pkt)) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case STATUS_GOOD:
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li *retval = 0;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth break;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case STATUS_CHECK:
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li if (pkt->pkt_state & STATE_ARQ_DONE) {
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li uint8_t *sns, skey, asc, ascq;
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li sns = (uint8_t *)
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li &(((struct scsi_arq_status *)(uintptr_t)
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li (pkt->pkt_scbp))->sts_sensedata);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li skey = scsi_sense_key(sns);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li asc = scsi_sense_asc(sns);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li ascq = scsi_sense_ascq(sns);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li if (skey == KEY_UNIT_ATTENTION) {
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li /*
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * tpgs access state changed
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li */
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li if (asc == STD_SCSI_ASC_STATE_CHG &&
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li ascq ==
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li STD_SCSI_ASCQ_STATE_CHG_SUCC) {
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li /* XXX: update path info? */
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li cmn_err(CE_WARN,
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li "!Device failover"
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li " state change");
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li }
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li return (1);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li } else if (skey == KEY_NOT_READY) {
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li if (asc ==
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li STD_LOGICAL_UNIT_NOT_ACCESSIBLE &&
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li ascq == STD_TGT_PORT_STANDBY) {
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li /*
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * Don't retry on the path
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * which is indicated as
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * standby, return failure.
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li */
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li return (0);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li } else if ((*retry_cnt)++ >=
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li STD_FO_MAX_RETRIES) {
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li cmn_err(CE_WARN,
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li "!Device failover failed: "
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li "timed out waiting for "
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li "path to become active");
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li return (0);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li }
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li VHCI_DEBUG(6, (CE_NOTE, NULL,
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li "!(sd:%p)lun becoming active...\n",
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li (void *)sd));
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li drv_usecwait(STD_FO_RETRY_DELAY);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li return (1);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li }
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li cmn_err(CE_NOTE, "!Failover failed;"
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li " sense key:%x, ASC: %x, "
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li "ASCQ:%x", skey, asc, ascq);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li return (0);
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_WARN, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!(sd:%p):"
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth " status returned CHECK during std"
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth " path activation", (void *)sd));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (0);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case STATUS_QFULL:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(6, (CE_NOTE, NULL, "QFULL "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "status returned QFULL during std "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "path activation for %p\n", (void *)sd));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth drv_usecwait(5000);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case STATUS_BUSY:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(6, (CE_NOTE, NULL, "BUSY "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "status returned BUSY during std "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "path activation for %p\n", (void *)sd));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth drv_usecwait(5000);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth default:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_WARN, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!(sd:%p) Bad status returned during std "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "activation (pkt %p, status %x)",
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void *)sd, (void *)pkt, SCBP_C(pkt)));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (0);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (0);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * For now we are going to use primary/online and secondary/online.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * There is no standby path returned by the dsp and we may have
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * to do something different for other devices that use standby
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* ARGSUSED */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic int
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstd_path_activate(struct scsi_device *sd, char *pathclass,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs void *ctpriv)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth struct buf *bp;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth struct scsi_pkt *pkt;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth struct scsi_address *ap;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth int err, retry_cnt, retry_cmd_cnt;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth int mode, state, retval, xlf, preferred;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth ap = &sd->sd_address;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth mode = state = 0;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs if (vhci_tpgs_get_target_fo_mode(sd, &mode, &state, &xlf, &preferred)) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(1, (CE_NOTE, NULL, "!std_path_activate:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " failed vhci_tpgs_get_target_fo_mode\n"));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if ((state == STD_ACTIVE_OPTIMIZED) ||
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (state == STD_ACTIVE_NONOPTIMIZED)) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_NOTE, NULL, "!path already active for %p\n",
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void *)sd));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (0);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
cc25db92ff252ca1b7f63bd54f087f4ddf0dda4eChris Liu if (mode == SCSI_EXPLICIT_FAILOVER) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_NOTE, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!mode is EXPLICIT for %p xlf %x\n",
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void *)sd, xlf));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth retval = std_activate_explicit(sd, xlf);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if (retval != 0) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_NOTE, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!(sd:%p)std_path_activate failed(1)\n",
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void *)sd));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth } else {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_NOTE, NULL, "STD mode is IMPLICIT for %p\n",
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void *)sd));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth bp = scsi_alloc_consistent_buf(ap, (struct buf *)NULL, DEV_BSIZE,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth B_READ, NULL, NULL);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if (!bp) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_WARN, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!(sd:%p)std_path_activate failed to alloc buffer",
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void *)sd));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth pkt = scsi_init_pkt(ap, NULL, bp, CDB_GROUP1,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth sizeof (struct scsi_arq_status), 0, PKT_CONSISTENT, NULL, NULL);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if (!pkt) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_WARN, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!(sd:%p)std_path_activate failed to initialize packet",
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void *)sd));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth scsi_free_consistent_buf(bp);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void) scsi_setup_cdb((union scsi_cdb *)(uintptr_t)pkt->pkt_cdbp,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth SCMD_READ, 1, 1, 0);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth pkt->pkt_time = 3*30;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth pkt->pkt_flags |= FLAG_NOINTR;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth retry_cnt = 0;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth retry_cmd_cnt = 0;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthretry:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth err = scsi_transport(pkt);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if (err != TRAN_ACCEPT) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth /*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * Retry TRAN_BUSY till STD_FO_MAX_RETRIES is exhausted.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * All other errors are fatal and should not be retried.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if ((err == TRAN_BUSY) &&
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (retry_cnt++ < STD_FO_MAX_RETRIES)) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth drv_usecwait(STD_FO_RETRY_DELAY);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth goto retry;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth cmn_err(CE_WARN, "Failover failed, "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "couldn't transport packet");
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth scsi_destroy_pkt(pkt);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth scsi_free_consistent_buf(bp);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth switch (pkt->pkt_reason) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case CMD_CMPLT:
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li /*
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * Re-initialize retry_cmd_cnt. Allow transport and
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * cmd errors to go through a full retry count when
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * these are encountered. This way TRAN/CMD errors
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * retry count is not exhausted due to CMD_CMPLTs
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * delay. This allows the system
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * to brave a hick-up on the link at any given time,
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li * while waiting for the fo to complete.
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth retry_cmd_cnt = 0;
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li if (std_process_cmplt_pkt(sd, pkt, &retry_cnt,
40764c95159232b912f6f16cb1fb1a41897fb0a7Victor Li &retval) != 0) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth goto retry;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth break;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case CMD_TIMEOUT:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth cmn_err(CE_WARN, "!Failover failed: timed out ");
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth retval = 1;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth break;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case CMD_INCOMPLETE:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case CMD_RESET:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case CMD_ABORTED:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth case CMD_TRAN_ERR:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth /*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * Increased the number of retries when these error
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * cases are encountered. Also added a 1 sec wait
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * before retrying.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if (retry_cmd_cnt++ < STD_FO_MAX_CMD_RETRIES) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth drv_usecwait(STD_FO_CMD_RETRY_DELAY);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_WARN, NULL,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "!Retrying path activation due to "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "pkt reason:%x, retry cnt:%d",
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth pkt->pkt_reason, retry_cmd_cnt));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth goto retry;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth /* FALLTHROUGH */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth default:
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth cmn_err(CE_WARN, "!Path activation did not "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "complete successfully,"
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "(pkt reason %x)", pkt->pkt_reason);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth retval = 1;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth break;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth scsi_destroy_pkt(pkt);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth scsi_free_consistent_buf(bp);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (retval);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* ARGSUSED */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic int std_path_deactivate(struct scsi_device *sd, char *pathclass,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs void *ctpriv)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (0);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* ARGSUSED */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic int
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphsstd_path_get_opinfo(struct scsi_device *sd, struct scsi_path_opinfo *opinfo,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs void *ctpriv)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth int mode, preferred, state, xlf;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_rev = OPINFO_REV;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs if (vhci_tpgs_get_target_fo_mode(sd, &mode, &state, &xlf, &preferred)) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(1, (CE_NOTE, NULL, "!std_path_getopinfo:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " failed vhci_tpgs_get_target_fo_mode\n"));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if (state == STD_ACTIVE_OPTIMIZED) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_path_state = SCSI_PATH_ACTIVE;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth } else if (state == STD_ACTIVE_NONOPTIMIZED) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_path_state = SCSI_PATH_ACTIVE_NONOPT;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth } else if (state == STD_STANDBY) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_path_state = SCSI_PATH_INACTIVE;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth } else if (state == STD_UNAVAILABLE) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_path_state = SCSI_PATH_INACTIVE;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if (preferred) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void) strcpy(opinfo->opinfo_path_attr, PCLASS_PRIMARY);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth } else {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth (void) strcpy(opinfo->opinfo_path_attr, PCLASS_SECONDARY);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_NOTE, NULL, "std_path_get_opinfo: "
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "class: %s state: %s\n", opinfo->opinfo_path_attr,
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_path_state == SCSI_PATH_ACTIVE ?
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth "ACTIVE" : "INACTIVE"));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_xlf_capable = 0;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_pswtch_best = 30;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_pswtch_worst = 3*30;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_preferred = (uint16_t)preferred;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth opinfo->opinfo_mode = (uint16_t)mode;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (0);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* ARGSUSED */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic int std_path_ping(struct scsi_device *sd, void *ctpriv)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth /*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * For future use
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (1);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * Analyze the sense code to determine whether failover process
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* ARGSUSED */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic int
0c45178b5714d692c44817c2235320c3f2b030abwlstd_analyze_sense(struct scsi_device *sd, uint8_t *sense,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs void *ctpriv)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth int rval = SCSI_SENSE_UNKNOWN;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
0c45178b5714d692c44817c2235320c3f2b030abwl uint8_t skey, asc, ascq;
0c45178b5714d692c44817c2235320c3f2b030abwl
0c45178b5714d692c44817c2235320c3f2b030abwl skey = scsi_sense_key(sense);
0c45178b5714d692c44817c2235320c3f2b030abwl asc = scsi_sense_asc(sense);
0c45178b5714d692c44817c2235320c3f2b030abwl ascq = scsi_sense_ascq(sense);
0c45178b5714d692c44817c2235320c3f2b030abwl
0c45178b5714d692c44817c2235320c3f2b030abwl if ((skey == KEY_UNIT_ATTENTION) &&
0c45178b5714d692c44817c2235320c3f2b030abwl (asc == STD_SCSI_ASC_STATE_CHG) &&
0c45178b5714d692c44817c2235320c3f2b030abwl (ascq == STD_SCSI_ASCQ_STATE_CHG_SUCC)) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth rval = SCSI_SENSE_STATE_CHANGED;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_NOTE, NULL, "!std_analyze_sense:"
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth " sense_key:%x, add_code: %x, qual_code:%x"
0c45178b5714d692c44817c2235320c3f2b030abwl " sense:%x\n", skey, asc, ascq, rval));
0c45178b5714d692c44817c2235320c3f2b030abwl } else if ((skey == KEY_NOT_READY) &&
0c45178b5714d692c44817c2235320c3f2b030abwl (asc == STD_LOGICAL_UNIT_NOT_ACCESSIBLE) &&
377116851d972902caefc86c848359c0273d8487wl ((ascq == STD_TGT_PORT_UNAVAILABLE) ||
377116851d972902caefc86c848359c0273d8487wl (ascq == STD_TGT_PORT_STANDBY))) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth rval = SCSI_SENSE_INACTIVE;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(4, (CE_NOTE, NULL, "!std_analyze_sense:"
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth " sense_key:%x, add_code: %x, qual_code:%x"
0c45178b5714d692c44817c2235320c3f2b030abwl " sense:%x\n", skey, asc, ascq, rval));
0c45178b5714d692c44817c2235320c3f2b030abwl } else if ((skey == KEY_ILLEGAL_REQUEST) &&
0c45178b5714d692c44817c2235320c3f2b030abwl (asc == STD_SCSI_ASC_INVAL_PARAM_LIST)) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth rval = SCSI_SENSE_NOFAILOVER;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(1, (CE_NOTE, NULL, "!std_analyze_sense:"
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth " sense_key:%x, add_code: %x, qual_code:%x"
0c45178b5714d692c44817c2235320c3f2b030abwl " sense:%x\n", skey, asc, ascq, rval));
0c45178b5714d692c44817c2235320c3f2b030abwl } else if ((skey == KEY_ILLEGAL_REQUEST) &&
0c45178b5714d692c44817c2235320c3f2b030abwl (asc == STD_SCSI_ASC_INVAL_CMD_OPCODE)) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth rval = SCSI_SENSE_NOFAILOVER;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(1, (CE_NOTE, NULL, "!std_analyze_sense:"
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth " sense_key:%x, add_code: %x, qual_code:%x"
0c45178b5714d692c44817c2235320c3f2b030abwl " sense:%x\n", skey, asc, ascq, rval));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth } else {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth /*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * At this point sense data may be for power-on-reset
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * UNIT ATTN hardware errors, vendor unqiue sense data etc.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * For all these cases, return SCSI_SENSE_UNKNOWN.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth VHCI_DEBUG(1, (CE_NOTE, NULL, "!Analyze sense UNKNOWN:"
0c45178b5714d692c44817c2235320c3f2b030abwl " sense key:%x, ASC:%x, ASCQ:%x\n", skey, asc, ascq));
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (rval);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth/* ARGSUSED */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstatic int
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcthstd_pathclass_next(char *cur, char **nxt, void *ctpriv)
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth{
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth /*
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * The first phase does not have a standby path so
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * there will be no explicit failover - when standard tpgs.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * standard defines preferred flag then we should start
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * using this as the selection mechanism - there can be
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * preferred primary standby that we should fail to first and then
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth * nonpreferred secondary standby.
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth */
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth if (cur == NULL) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth *nxt = PCLASS_PRIMARY;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (0);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth } else if (strcmp(cur, PCLASS_PRIMARY) == 0) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth *nxt = PCLASS_SECONDARY;
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (0);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth } else if (strcmp(cur, PCLASS_SECONDARY) == 0) {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (ENOENT);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth } else {
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth return (EINVAL);
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth }
1e1ddd6cc98ab5af8293f7ebd132be62900730fdcth}