7bc7346c0c75ced7da727f63c2772fd53809244dcm/*
7bc7346c0c75ced7da727f63c2772fd53809244dcm * CDDL HEADER START
7bc7346c0c75ced7da727f63c2772fd53809244dcm *
7bc7346c0c75ced7da727f63c2772fd53809244dcm * The contents of this file are subject to the terms of the
7bc7346c0c75ced7da727f63c2772fd53809244dcm * Common Development and Distribution License (the "License").
7bc7346c0c75ced7da727f63c2772fd53809244dcm * You may not use this file except in compliance with the License.
7bc7346c0c75ced7da727f63c2772fd53809244dcm *
7bc7346c0c75ced7da727f63c2772fd53809244dcm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7bc7346c0c75ced7da727f63c2772fd53809244dcm * or http://www.opensolaris.org/os/licensing.
7bc7346c0c75ced7da727f63c2772fd53809244dcm * See the License for the specific language governing permissions
7bc7346c0c75ced7da727f63c2772fd53809244dcm * and limitations under the License.
7bc7346c0c75ced7da727f63c2772fd53809244dcm *
7bc7346c0c75ced7da727f63c2772fd53809244dcm * When distributing Covered Code, include this CDDL HEADER in each
7bc7346c0c75ced7da727f63c2772fd53809244dcm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7bc7346c0c75ced7da727f63c2772fd53809244dcm * If applicable, add the following below this CDDL HEADER, with the
7bc7346c0c75ced7da727f63c2772fd53809244dcm * fields enclosed by brackets "[]" replaced with your own identifying
7bc7346c0c75ced7da727f63c2772fd53809244dcm * information: Portions Copyright [yyyy] [name of copyright owner]
7bc7346c0c75ced7da727f63c2772fd53809244dcm *
7bc7346c0c75ced7da727f63c2772fd53809244dcm * CDDL HEADER END
7bc7346c0c75ced7da727f63c2772fd53809244dcm */
7bc7346c0c75ced7da727f63c2772fd53809244dcm
123a66144b2f6baecdc28fa277b0de6d1608d441cm/* Portions Copyright 2008 Hitachi Ltd. */
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm/*
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
7bc7346c0c75ced7da727f63c2772fd53809244dcm * Use is subject to license terms.
7bc7346c0c75ced7da727f63c2772fd53809244dcm */
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm/*
7bc7346c0c75ced7da727f63c2772fd53809244dcm * Implementation of "scsi_vhci_f_sym_hds" asymmetric-active-active
7bc7346c0c75ced7da727f63c2772fd53809244dcm * failover_ops. The device has a preferred(owner)/non-preferred
7bc7346c0c75ced7da727f63c2772fd53809244dcm * with no action needed to use the non-preferred path. This is really
7bc7346c0c75ced7da727f63c2772fd53809244dcm * more inline with symmetric device so am using that prefix.
7bc7346c0c75ced7da727f63c2772fd53809244dcm *
7bc7346c0c75ced7da727f63c2772fd53809244dcm * This file imports the standard "scsi_vhci_f_sym", but with HDS specific
7bc7346c0c75ced7da727f63c2772fd53809244dcm * knowledge related to preferred/non-preferred path.
7bc7346c0c75ced7da727f63c2772fd53809244dcm */
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm#include <sys/conf.h>
7bc7346c0c75ced7da727f63c2772fd53809244dcm#include <sys/file.h>
7bc7346c0c75ced7da727f63c2772fd53809244dcm#include <sys/ddi.h>
7bc7346c0c75ced7da727f63c2772fd53809244dcm#include <sys/sunddi.h>
7bc7346c0c75ced7da727f63c2772fd53809244dcm#include <sys/scsi/scsi.h>
7bc7346c0c75ced7da727f63c2772fd53809244dcm#include <sys/scsi/adapters/scsi_vhci.h>
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm/* Supported device table entries. */
7bc7346c0c75ced7da727f63c2772fd53809244dcmchar *hds_sym_dev_table[] = {
7bc7346c0c75ced7da727f63c2772fd53809244dcm/* " 111111" */
7bc7346c0c75ced7da727f63c2772fd53809244dcm/* "012345670123456789012345" */
7bc7346c0c75ced7da727f63c2772fd53809244dcm/* "|-VID--||-----PID------|" */
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm "HITACHI DF",
7bc7346c0c75ced7da727f63c2772fd53809244dcm NULL
7bc7346c0c75ced7da727f63c2772fd53809244dcm};
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic int hds_sym_device_probe(struct scsi_device *,
7bc7346c0c75ced7da727f63c2772fd53809244dcm struct scsi_inquiry *, void **);
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic void hds_sym_device_unprobe(struct scsi_device *, void *);
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic void hds_sym_init();
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic int hds_sym_get_opinfo(struct scsi_device *sd,
7bc7346c0c75ced7da727f63c2772fd53809244dcm struct scsi_path_opinfo *opinfo, void *ctpriv);
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm#ifdef lint
7bc7346c0c75ced7da727f63c2772fd53809244dcm#define scsi_vhci_failover_ops scsi_vhci_failover_ops_f_sym_hds
7bc7346c0c75ced7da727f63c2772fd53809244dcm#endif /* lint */
7bc7346c0c75ced7da727f63c2772fd53809244dcm/*
7bc7346c0c75ced7da727f63c2772fd53809244dcm * Use the following for the Asymmetric-Active-Active fops.
7bc7346c0c75ced7da727f63c2772fd53809244dcm * A different fops may get used for the Symmetric-Active-Active.
7bc7346c0c75ced7da727f63c2772fd53809244dcm */
7bc7346c0c75ced7da727f63c2772fd53809244dcmstruct scsi_failover_ops scsi_vhci_failover_ops = {
7bc7346c0c75ced7da727f63c2772fd53809244dcm SFO_REV,
7bc7346c0c75ced7da727f63c2772fd53809244dcm SFO_NAME_SYM "_hds",
7bc7346c0c75ced7da727f63c2772fd53809244dcm hds_sym_dev_table,
7bc7346c0c75ced7da727f63c2772fd53809244dcm hds_sym_init,
7bc7346c0c75ced7da727f63c2772fd53809244dcm hds_sym_device_probe,
7bc7346c0c75ced7da727f63c2772fd53809244dcm hds_sym_device_unprobe,
7bc7346c0c75ced7da727f63c2772fd53809244dcm NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm hds_sym_get_opinfo,
7bc7346c0c75ced7da727f63c2772fd53809244dcm /* The rest of the implementation comes from SFO_NAME_SYM import */
7bc7346c0c75ced7da727f63c2772fd53809244dcm};
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic struct modlmisc modlmisc = {
39b361b2ebefcef5612a54ae5cbd2179e19be296Richard Bean &mod_miscops, "f_sym_hds"
7bc7346c0c75ced7da727f63c2772fd53809244dcm};
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic struct modlinkage modlinkage = {
7bc7346c0c75ced7da727f63c2772fd53809244dcm MODREV_1, (void *)&modlmisc, NULL
7bc7346c0c75ced7da727f63c2772fd53809244dcm};
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm#define HDS_MAX_INQ_BUF_SIZE 0xff
7bc7346c0c75ced7da727f63c2772fd53809244dcm#define HDS_INQ_PAGE_E0 0xe0
7bc7346c0c75ced7da727f63c2772fd53809244dcm#define HDS_SAA_TYPE "DF00"
7bc7346c0c75ced7da727f63c2772fd53809244dcm#define ASYM_ACTIVE_ACTIVE 0
7bc7346c0c75ced7da727f63c2772fd53809244dcm#define SYM_ACTIVE_ACTIVE 1
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcmextern struct scsi_failover_ops *vhci_failover_ops_by_name(char *);
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcmint
7bc7346c0c75ced7da727f63c2772fd53809244dcm_init()
7bc7346c0c75ced7da727f63c2772fd53809244dcm{
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (mod_install(&modlinkage));
7bc7346c0c75ced7da727f63c2772fd53809244dcm}
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcmint
7bc7346c0c75ced7da727f63c2772fd53809244dcm_fini()
7bc7346c0c75ced7da727f63c2772fd53809244dcm{
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (mod_remove(&modlinkage));
7bc7346c0c75ced7da727f63c2772fd53809244dcm}
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcmint
7bc7346c0c75ced7da727f63c2772fd53809244dcm_info(struct modinfo *modinfop)
7bc7346c0c75ced7da727f63c2772fd53809244dcm{
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (mod_info(&modlinkage, modinfop));
7bc7346c0c75ced7da727f63c2772fd53809244dcm}
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic void
7bc7346c0c75ced7da727f63c2772fd53809244dcmhds_sym_init()
7bc7346c0c75ced7da727f63c2772fd53809244dcm{
7bc7346c0c75ced7da727f63c2772fd53809244dcm struct scsi_failover_ops *sfo, *ssfo, clone;
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm /* clone SFO_NAME_SYM implementation for most things */
7bc7346c0c75ced7da727f63c2772fd53809244dcm ssfo = vhci_failover_ops_by_name(SFO_NAME_SYM);
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (ssfo == NULL) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm VHCI_DEBUG(4, (CE_NOTE, NULL, "!hds_sym_init: "
7bc7346c0c75ced7da727f63c2772fd53809244dcm "can't import " SFO_NAME_SYM "\n"));
7bc7346c0c75ced7da727f63c2772fd53809244dcm return;
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm sfo = &scsi_vhci_failover_ops;
7bc7346c0c75ced7da727f63c2772fd53809244dcm clone = *ssfo;
7bc7346c0c75ced7da727f63c2772fd53809244dcm clone.sfo_rev = sfo->sfo_rev;
7bc7346c0c75ced7da727f63c2772fd53809244dcm clone.sfo_name = sfo->sfo_name;
7bc7346c0c75ced7da727f63c2772fd53809244dcm clone.sfo_devices = sfo->sfo_devices;
7bc7346c0c75ced7da727f63c2772fd53809244dcm clone.sfo_init = sfo->sfo_init;
7bc7346c0c75ced7da727f63c2772fd53809244dcm clone.sfo_device_probe = sfo->sfo_device_probe;
7bc7346c0c75ced7da727f63c2772fd53809244dcm clone.sfo_device_unprobe = sfo->sfo_device_unprobe;
7bc7346c0c75ced7da727f63c2772fd53809244dcm clone.sfo_path_get_opinfo = sfo->sfo_path_get_opinfo;
7bc7346c0c75ced7da727f63c2772fd53809244dcm *sfo = clone;
7bc7346c0c75ced7da727f63c2772fd53809244dcm}
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm/* ARGSUSED */
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic int
7bc7346c0c75ced7da727f63c2772fd53809244dcmhds_sym_device_probe(struct scsi_device *sd, struct scsi_inquiry *stdinq,
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs void **ctprivp)
7bc7346c0c75ced7da727f63c2772fd53809244dcm{
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs char **dt;
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs char *dftype;
7bc7346c0c75ced7da727f63c2772fd53809244dcm unsigned char len;
7bc7346c0c75ced7da727f63c2772fd53809244dcm unsigned char *inq_data = (unsigned char *)stdinq;
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs unsigned char pv;
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs int ret;
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm VHCI_DEBUG(6, (CE_NOTE, NULL, "hds_sym_device_probe: vidpid %s\n",
7bc7346c0c75ced7da727f63c2772fd53809244dcm stdinq->inq_vid));
7bc7346c0c75ced7da727f63c2772fd53809244dcm for (dt = hds_sym_dev_table; *dt; dt++) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (strncmp(stdinq->inq_vid, *dt, strlen(*dt)))
7bc7346c0c75ced7da727f63c2772fd53809244dcm continue;
7bc7346c0c75ced7da727f63c2772fd53809244dcm len = inq_data[4];
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (len < 128) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm vhci_log(CE_NOTE, NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm "hds_sym_device_probe: vidpid %s len error: %d\n",
7bc7346c0c75ced7da727f63c2772fd53809244dcm stdinq->inq_vid, len);
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (SFO_DEVICE_PROBE_PHCI);
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs
7bc7346c0c75ced7da727f63c2772fd53809244dcm dftype = (char *)&inq_data[128];
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (*dftype == 0) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm VHCI_DEBUG(4, (CE_NOTE, NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm "hds_sym_device_probe: vidpid %s"
7bc7346c0c75ced7da727f63c2772fd53809244dcm " ASYM_ACTIVE_ACTIVE\n", stdinq->inq_vid));
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs pv = ASYM_ACTIVE_ACTIVE;
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs ret = SFO_DEVICE_PROBE_VHCI;
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs } else if (strncmp(dftype, HDS_SAA_TYPE,
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs strlen(HDS_SAA_TYPE)) == 0) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm VHCI_DEBUG(4, (CE_NOTE, NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm "hds_sym_device_probe: vidpid %s"
7bc7346c0c75ced7da727f63c2772fd53809244dcm " SYM_ACTIVE_ACTIVE\n", stdinq->inq_vid));
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs pv = SYM_ACTIVE_ACTIVE;
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs ret = SFO_DEVICE_PROBE_VHCI;
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs } else
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs ret = SFO_DEVICE_PROBE_PHCI;
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs if (ret == SFO_DEVICE_PROBE_VHCI) {
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs /* ctprivp is NULL for vhci_is_dev_supported() probe */
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs if (ctprivp) {
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs /*
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs * Allocate failover module's 'client' private
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs * data on the first successfull path probe.
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs * NOTE: 'client' private means per lun guid,
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs * not per-path.
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs */
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs if (*ctprivp == NULL)
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs *ctprivp = kmem_alloc(sizeof (pv),
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs KM_SLEEP);
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs /* update private data */
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs *((unsigned char *)*ctprivp) = pv;
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs }
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs } else {
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs VHCI_DEBUG(4, (CE_NOTE, NULL,
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs "hds_sym_device_probe: vidpid %s"
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs " - unknown dftype: %d\n",
55e592a20765db6f52a590785ae2390c3b12fda9Randall Ralphs stdinq->inq_vid, *dftype));
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (SFO_DEVICE_PROBE_PHCI);
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (SFO_DEVICE_PROBE_PHCI);
7bc7346c0c75ced7da727f63c2772fd53809244dcm}
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm/* ARGSUSED */
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic void
7bc7346c0c75ced7da727f63c2772fd53809244dcmhds_sym_device_unprobe(struct scsi_device *sd, void *ctpriv)
7bc7346c0c75ced7da727f63c2772fd53809244dcm{
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (ctpriv != NULL) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm kmem_free(ctpriv, sizeof (unsigned char));
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm}
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm/*
7bc7346c0c75ced7da727f63c2772fd53809244dcm * Local routine to get inquiry VPD page from the device.
7bc7346c0c75ced7da727f63c2772fd53809244dcm *
7bc7346c0c75ced7da727f63c2772fd53809244dcm * return 1 for failure
7bc7346c0c75ced7da727f63c2772fd53809244dcm * return 0 for success
7bc7346c0c75ced7da727f63c2772fd53809244dcm */
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic int
7bc7346c0c75ced7da727f63c2772fd53809244dcmhds_get_inquiry_vpd_page(struct scsi_device *sd, unsigned char page,
7bc7346c0c75ced7da727f63c2772fd53809244dcm unsigned char *buf, int size)
7bc7346c0c75ced7da727f63c2772fd53809244dcm{
7bc7346c0c75ced7da727f63c2772fd53809244dcm int retval = 0;
7bc7346c0c75ced7da727f63c2772fd53809244dcm struct buf *bp;
7bc7346c0c75ced7da727f63c2772fd53809244dcm struct scsi_pkt *pkt;
7bc7346c0c75ced7da727f63c2772fd53809244dcm struct scsi_address *ap;
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm if ((buf == NULL) || (size == 0)) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (1);
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm bp = getrbuf(KM_NOSLEEP);
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (bp == NULL) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (1);
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm bp->b_un.b_addr = (char *)buf;
7bc7346c0c75ced7da727f63c2772fd53809244dcm bp->b_flags = B_READ;
7bc7346c0c75ced7da727f63c2772fd53809244dcm bp->b_bcount = size;
7bc7346c0c75ced7da727f63c2772fd53809244dcm bp->b_resid = 0;
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm ap = &sd->sd_address;
7bc7346c0c75ced7da727f63c2772fd53809244dcm pkt = scsi_init_pkt(ap, NULL, bp, CDB_GROUP0,
7bc7346c0c75ced7da727f63c2772fd53809244dcm sizeof (struct scsi_arq_status), 0, 0, NULL, NULL);
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (pkt == NULL) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm VHCI_DEBUG(4, (CE_WARN, NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm "hds_get_inquiry_vpd_page:"
7bc7346c0c75ced7da727f63c2772fd53809244dcm "Failed to initialize packet"));
7bc7346c0c75ced7da727f63c2772fd53809244dcm freerbuf(bp);
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (1);
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm /*
7bc7346c0c75ced7da727f63c2772fd53809244dcm * Send the inquiry command for page xx to the target.
7bc7346c0c75ced7da727f63c2772fd53809244dcm * Data is returned in the buf pointed to by buf.
7bc7346c0c75ced7da727f63c2772fd53809244dcm */
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm pkt->pkt_cdbp[0] = SCMD_INQUIRY;
7bc7346c0c75ced7da727f63c2772fd53809244dcm pkt->pkt_cdbp[1] = 0x1;
7bc7346c0c75ced7da727f63c2772fd53809244dcm pkt->pkt_cdbp[2] = page;
7bc7346c0c75ced7da727f63c2772fd53809244dcm pkt->pkt_cdbp[4] = (unsigned char)size;
7bc7346c0c75ced7da727f63c2772fd53809244dcm pkt->pkt_time = 90;
7bc7346c0c75ced7da727f63c2772fd53809244dcm retval = vhci_do_scsi_cmd(pkt);
7bc7346c0c75ced7da727f63c2772fd53809244dcm scsi_destroy_pkt(pkt);
7bc7346c0c75ced7da727f63c2772fd53809244dcm freerbuf(bp);
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (!retval);
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm}
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm/* ARGSUSED */
7bc7346c0c75ced7da727f63c2772fd53809244dcmstatic int
7bc7346c0c75ced7da727f63c2772fd53809244dcmhds_sym_get_opinfo(struct scsi_device *sd, struct scsi_path_opinfo *opinfo,
7bc7346c0c75ced7da727f63c2772fd53809244dcm void *ctpriv)
7bc7346c0c75ced7da727f63c2772fd53809244dcm{
7bc7346c0c75ced7da727f63c2772fd53809244dcm unsigned char inq_vpd_buf[HDS_MAX_INQ_BUF_SIZE];
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm opinfo->opinfo_rev = OPINFO_REV;
7bc7346c0c75ced7da727f63c2772fd53809244dcm (void) strcpy(opinfo->opinfo_path_attr, "primary");
7bc7346c0c75ced7da727f63c2772fd53809244dcm opinfo->opinfo_path_state = SCSI_PATH_ACTIVE;
7bc7346c0c75ced7da727f63c2772fd53809244dcm opinfo->opinfo_pswtch_best = 0; /* N/A */
7bc7346c0c75ced7da727f63c2772fd53809244dcm opinfo->opinfo_pswtch_worst = 0; /* N/A */
7bc7346c0c75ced7da727f63c2772fd53809244dcm opinfo->opinfo_xlf_capable = 0;
7bc7346c0c75ced7da727f63c2772fd53809244dcm opinfo->opinfo_mode = SCSI_NO_FAILOVER;
7bc7346c0c75ced7da727f63c2772fd53809244dcm ASSERT(ctpriv != NULL);
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (*((unsigned char *)ctpriv) == SYM_ACTIVE_ACTIVE) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm VHCI_DEBUG(4, (CE_NOTE, NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm "hds_get_opinfo: sd(%p): sym_active_active "
7bc7346c0c75ced7da727f63c2772fd53809244dcm "preferred bit set ", (void*)sd));
7bc7346c0c75ced7da727f63c2772fd53809244dcm opinfo->opinfo_preferred = PCLASS_PREFERRED;
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (0);
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm /* check if this is the preferred path */
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (hds_get_inquiry_vpd_page(sd, HDS_INQ_PAGE_E0, inq_vpd_buf,
7bc7346c0c75ced7da727f63c2772fd53809244dcm sizeof (inq_vpd_buf)) != 0) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm VHCI_DEBUG(4, (CE_WARN, NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm "hds_get_opinfo: sd(%p):Unable to "
7bc7346c0c75ced7da727f63c2772fd53809244dcm "get inquiry Page %x", (void*)sd, HDS_INQ_PAGE_E0));
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (1);
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (inq_vpd_buf[4] & 0x80) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm if (inq_vpd_buf[4] & 0x40) {
7bc7346c0c75ced7da727f63c2772fd53809244dcm VHCI_DEBUG(4, (CE_NOTE, NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm "hds_get_opinfo: sd(%p): preferred bit set ",
7bc7346c0c75ced7da727f63c2772fd53809244dcm (void*)sd));
7bc7346c0c75ced7da727f63c2772fd53809244dcm opinfo->opinfo_preferred = PCLASS_PREFERRED;
7bc7346c0c75ced7da727f63c2772fd53809244dcm } else {
7bc7346c0c75ced7da727f63c2772fd53809244dcm VHCI_DEBUG(4, (CE_NOTE, NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm "hds_get_opinfo: sd(%p): non-preferred bit set ",
7bc7346c0c75ced7da727f63c2772fd53809244dcm (void*)sd));
7bc7346c0c75ced7da727f63c2772fd53809244dcm opinfo->opinfo_preferred = PCLASS_NONPREFERRED;
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm } else {
7bc7346c0c75ced7da727f63c2772fd53809244dcm vhci_log(CE_NOTE, NULL,
7bc7346c0c75ced7da727f63c2772fd53809244dcm "hds_get_opinfo: sd(%p): "
7bc7346c0c75ced7da727f63c2772fd53809244dcm "get inquiry Page %x has invalid P/SVid bit set",
7bc7346c0c75ced7da727f63c2772fd53809244dcm (void*)sd, HDS_INQ_PAGE_E0);
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (1);
7bc7346c0c75ced7da727f63c2772fd53809244dcm }
7bc7346c0c75ced7da727f63c2772fd53809244dcm
7bc7346c0c75ced7da727f63c2772fd53809244dcm return (0);
7bc7346c0c75ced7da727f63c2772fd53809244dcm}