sym_hds.c revision 55e592a20765db6f52a590785ae2390c3b12fda9
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* 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
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Portions Copyright 2008 Hitachi Ltd. */
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Implementation of "scsi_vhci_f_sym_hds" asymmetric-active-active
* failover_ops. The device has a preferred(owner)/non-preferred
* with no action needed to use the non-preferred path. This is really
* more inline with symmetric device so am using that prefix.
*
* This file imports the standard "scsi_vhci_f_sym", but with HDS specific
* knowledge related to preferred/non-preferred path.
*/
/* Supported device table entries. */
char *hds_sym_dev_table[] = {
/* " 111111" */
/* "012345670123456789012345" */
/* "|-VID--||-----PID------|" */
"HITACHI DF",
};
static int hds_sym_device_probe(struct scsi_device *,
struct scsi_inquiry *, void **);
static void hds_sym_device_unprobe(struct scsi_device *, void *);
static void hds_sym_init();
#ifdef lint
#endif /* lint */
/*
* Use the following for the Asymmetric-Active-Active fops.
* A different fops may get used for the Symmetric-Active-Active.
*/
struct scsi_failover_ops scsi_vhci_failover_ops = {
SFO_NAME_SYM "_hds",
NULL,
NULL,
/* The rest of the implementation comes from SFO_NAME_SYM import */
};
&mod_miscops, "f_sym_hds"
};
static struct modlinkage modlinkage = {
};
#define HDS_MAX_INQ_BUF_SIZE 0xff
#define HDS_INQ_PAGE_E0 0xe0
#define HDS_SAA_TYPE "DF00"
#define ASYM_ACTIVE_ACTIVE 0
#define SYM_ACTIVE_ACTIVE 1
extern struct scsi_failover_ops *vhci_failover_ops_by_name(char *);
int
_init()
{
return (mod_install(&modlinkage));
}
int
_fini()
{
return (mod_remove(&modlinkage));
}
int
{
}
static void
{
/* clone SFO_NAME_SYM implementation for most things */
return;
}
}
/* ARGSUSED */
static int
void **ctprivp)
{
char **dt;
char *dftype;
unsigned char len;
unsigned char pv;
int ret;
continue;
if (len < 128) {
"hds_sym_device_probe: vidpid %s len error: %d\n",
return (SFO_DEVICE_PROBE_PHCI);
}
if (*dftype == 0) {
"hds_sym_device_probe: vidpid %s"
strlen(HDS_SAA_TYPE)) == 0) {
"hds_sym_device_probe: vidpid %s"
} else
if (ret == SFO_DEVICE_PROBE_VHCI) {
/* ctprivp is NULL for vhci_is_dev_supported() probe */
if (ctprivp) {
/*
* Allocate failover module's 'client' private
* data on the first successfull path probe.
* NOTE: 'client' private means per lun guid,
* not per-path.
*/
KM_SLEEP);
/* update private data */
}
} else {
"hds_sym_device_probe: vidpid %s"
" - unknown dftype: %d\n",
}
return (SFO_DEVICE_PROBE_PHCI);
}
return (SFO_DEVICE_PROBE_PHCI);
}
/* ARGSUSED */
static void
{
}
}
/*
* Local routine to get inquiry VPD page from the device.
*
* return 1 for failure
* return 0 for success
*/
static int
{
int retval = 0;
struct scsi_address *ap;
return (1);
}
return (1);
}
"hds_get_inquiry_vpd_page:"
"Failed to initialize packet"));
return (1);
}
/*
* Send the inquiry command for page xx to the target.
* Data is returned in the buf pointed to by buf.
*/
return (!retval);
}
/* ARGSUSED */
static int
void *ctpriv)
{
unsigned char inq_vpd_buf[HDS_MAX_INQ_BUF_SIZE];
opinfo->opinfo_xlf_capable = 0;
if (*((unsigned char *)ctpriv) == SYM_ACTIVE_ACTIVE) {
"hds_get_opinfo: sd(%p): sym_active_active "
"preferred bit set ", (void*)sd));
return (0);
}
/* check if this is the preferred path */
sizeof (inq_vpd_buf)) != 0) {
"hds_get_opinfo: sd(%p):Unable to "
return (1);
}
"hds_get_opinfo: sd(%p): preferred bit set ",
(void*)sd));
} else {
"hds_get_opinfo: sd(%p): non-preferred bit set ",
(void*)sd));
}
} else {
"hds_get_opinfo: sd(%p): "
(void*)sd, HDS_INQ_PAGE_E0);
return (1);
}
return (0);
}