sym.c revision 7878:da545a376610
155714Skris/*
255714Skris * CDDL HEADER START
355714Skris *
455714Skris * The contents of this file are subject to the terms of the
555714Skris * Common Development and Distribution License (the "License").
655714Skris * You may not use this file except in compliance with the License.
755714Skris *
855714Skris * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
955714Skris * or http://www.opensolaris.org/os/licensing.
1055714Skris * See the License for the specific language governing permissions
1155714Skris * and limitations under the License.
1255714Skris *
1355714Skris * When distributing Covered Code, include this CDDL HEADER in each
1455714Skris * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1555714Skris * If applicable, add the following below this CDDL HEADER, with the
1655714Skris * fields enclosed by brackets "[]" replaced with your own identifying
1755714Skris * information: Portions Copyright [yyyy] [name of copyright owner]
18238405Sjkim *
19160814Ssimon * CDDL HEADER END
2055714Skris */
2155714Skris
2255714Skris/*
23109998Smarkm * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24238405Sjkim * Use is subject to license terms.
25160814Ssimon */
26109998Smarkm
2755714Skris/*
2855714Skris * Implementation of "scsi_vhci_f_sym" symmetric failover_ops.
2955714Skris *
3055714Skris * This file was historically meant for only symmetric implementation.  It has
3155714Skris * been extended to manage SUN "supported" symmetric controllers. The supported
3255714Skris * VID/PID shall be listed in the symmetric_dev_table.
3355714Skris */
3455714Skris
3555714Skris#include <sys/conf.h>
3655714Skris#include <sys/file.h>
3755714Skris#include <sys/ddi.h>
3855714Skris#include <sys/sunddi.h>
3955714Skris#include <sys/scsi/scsi.h>
4055714Skris#include <sys/scsi/adapters/scsi_vhci.h>
4155714Skris
4255714Skris/* Supported device table entries.  */
4355714Skrischar *symmetric_dev_table[] = {
4455714Skris/*	"                  111111" */
4555714Skris/*	"012345670123456789012345" */
4655714Skris/*	"|-VID--||-----PID------|" */
4755714Skris				/* disks */
4855714Skris	"IBM     DDYFT",
4955714Skris	"IBM     IC",
5055714Skris	"SEAGATE ST",
5155714Skris				/* enclosures */
5255714Skris	"SUN     SENA",			/* SES device */
5376866Skris	"SUN     SESS01",		/* VICOM SVE box */
54238405Sjkim	"SUNW    SUNWGS",		/* Daktari enclosure */
5555714Skris				/* arrays */
5668651Skris	"HITACHI OPEN",			/* Hitachi storage */
5776866Skris	"SUN     PSX1000",		/* Pirus Matterhorn */
58160814Ssimon	"SUN     SE6920",		/* Pirus */
5976866Skris	"SUN     SE6940",		/* DSP - Nauset */
6076866Skris	"SUN     StorEdge 3510",	/* Minnow FC */
61109998Smarkm	"SUN     StorEdge 3511",	/* Minnow SATA RAID */
62109998Smarkm	"SUN     StorageTek 6920",	/* DSP */
63109998Smarkm	"SUN     StorageTek 6940",	/* DSP - Nauset */
64109998Smarkm	"SUN     StorageTek NAS",	/* StorageTek NAS */
65109998Smarkm	"SUN     MRA300_R",		/* Shamrock - Controller */
66109998Smarkm	"SUN     MRA300_E",		/* Shamrock - Expansion */
67109998Smarkm
68109998Smarkm	NULL
69109998Smarkm};
70109998Smarkm
7176866Skris/* Failover module plumbing. */
7268651SkrisSCSI_FAILOVER_OP(SFO_NAME_SYM, symmetric);
7355714Skris
74/* ARGSUSED */
75static int
76symmetric_device_probe(struct scsi_device *sd, struct scsi_inquiry *stdinq,
77void **ctpriv)
78{
79	char	**dt;
80
81	VHCI_DEBUG(6, (CE_NOTE, NULL, "!inq str: %s\n", stdinq->inq_vid));
82	for (dt = symmetric_dev_table; *dt; dt++)
83		if (strncmp(stdinq->inq_vid, *dt, strlen(*dt)) == 0)
84			return (SFO_DEVICE_PROBE_VHCI);
85
86	/*
87	 * No match, check for generic Sun supported disks:
88	 *
89	 *	"|-VID--||-----PID------|"
90	 *	"012345670123456789012345"
91	 *	".................SUN..G."
92	 *	".................SUN..T."
93	 *	".................SUN...G"
94	 *	".................SUN...T"
95	 */
96	if (bcmp(&stdinq->inq_pid[9], "SUN", 3) == 0) {
97		if ((stdinq->inq_pid[14] == 'G' || stdinq->inq_pid[15] == 'G' ||
98		    stdinq->inq_pid[14] == 'T' || stdinq->inq_pid[15] == 'T') &&
99		    (stdinq->inq_dtype == DTYPE_DIRECT)) {
100			return (SFO_DEVICE_PROBE_VHCI);
101		}
102	}
103	if (bcmp(&stdinq->inq_vid[0], "ATA     ", 8) == 0) {
104		return (SFO_DEVICE_PROBE_VHCI);
105	}
106	return (SFO_DEVICE_PROBE_PHCI);
107}
108
109/* ARGSUSED */
110static void
111symmetric_device_unprobe(struct scsi_device *sd, void *ctpriv)
112{
113	/*
114	 * NOP for symmetric
115	 */
116}
117
118/* ARGSUSED */
119static int
120symmetric_path_activate(struct scsi_device *sd, char *pathclass, void *ctpriv)
121{
122	return (0);
123}
124
125/* ARGSUSED */
126static int
127symmetric_path_deactivate(struct scsi_device *sd, char *pathclass,
128void *ctpriv)
129{
130	return (0);
131}
132
133/* ARGSUSED */
134static int
135symmetric_path_get_opinfo(struct scsi_device *sd,
136struct scsi_path_opinfo *opinfo, void *ctpriv)
137{
138	opinfo->opinfo_rev = OPINFO_REV;
139	(void) strcpy(opinfo->opinfo_path_attr, "primary");
140	opinfo->opinfo_path_state  = SCSI_PATH_ACTIVE;
141	opinfo->opinfo_pswtch_best = 0;		/* N/A */
142	opinfo->opinfo_pswtch_worst = 0;	/* N/A */
143	opinfo->opinfo_xlf_capable = 0;
144	opinfo->opinfo_mode = SCSI_NO_FAILOVER;
145	opinfo->opinfo_preferred = 1;
146
147	return (0);
148}
149
150/* ARGSUSED */
151static int
152symmetric_path_ping(struct scsi_device *sd, void *ctpriv)
153{
154	return (1);
155}
156
157/* ARGSUSED */
158static int
159symmetric_analyze_sense(struct scsi_device *sd,
160struct scsi_extended_sense *sense, void *ctpriv)
161{
162	return (SCSI_SENSE_NOFAILOVER);
163}
164
165/* ARGSUSED */
166static int
167symmetric_pathclass_next(char *cur, char **nxt, void *ctpriv)
168{
169	if (cur == NULL) {
170		*nxt = PCLASS_PRIMARY;
171		return (0);
172	} else if (strcmp(cur, PCLASS_PRIMARY) == 0) {
173		return (ENOENT);
174	} else {
175		return (EINVAL);
176	}
177}
178