1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 * Implementation of "scsi_vhci_f_sym" symmetric failover_ops.
28 *
29 * This file was historically meant for only symmetric implementation. It has
30 * been extended to manage SUN "supported" symmetric controllers. The supported
31 * VID/PID shall be listed in the symmetric_dev_table.
32 */
33
34 #include <sys/conf.h>
35 #include <sys/file.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/scsi/scsi.h>
39 #include <sys/scsi/adapters/scsi_vhci.h>
40
41 /* Supported device table entries. */
42 char *symmetric_dev_table[] = {
43 /* " 111111" */
44 /* "012345670123456789012345" */
45 /* "|-VID--||-----PID------|" */
46 /* disks */
47 "IBM DDYFT",
48 "IBM IC",
49 "SEAGATE ST",
50 /* enclosures */
51 "SUN SENA", /* SES device */
52 "SUN SESS01", /* VICOM SVE box */
53 "SUNW SUNWGS", /* Daktari enclosure */
54 /* arrays */
55 "HITACHI OPEN", /* Hitachi storage */
56 "SUN PSX1000", /* Pirus Matterhorn */
57 "SUN SE6920", /* Pirus */
58 "SUN SE6940", /* DSP - Nauset */
59 "SUN StorEdge 3510", /* Minnow FC */
60 "SUN StorEdge 3511", /* Minnow SATA RAID */
61 "SUN StorageTek 6920", /* DSP */
62 "SUN StorageTek 6940", /* DSP - Nauset */
63 "SUN StorageTek NAS", /* StorageTek NAS */
64 "SUN MRA300_R", /* Shamrock - Controller */
65 "SUN MRA300_E", /* Shamrock - Expansion */
66 "STEC ZeusIOPs", /* Zeus SAS SSD */
67
68 NULL
69 };
70
71 /* Failover module plumbing. */
72 SCSI_FAILOVER_OP(SFO_NAME_SYM, symmetric);
73
74 /* ARGSUSED */
75 static int
symmetric_device_probe(struct scsi_device * sd,struct scsi_inquiry * stdinq,void ** ctpriv)76 symmetric_device_probe(struct scsi_device *sd, struct scsi_inquiry *stdinq,
77 void **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 */
110 static void
symmetric_device_unprobe(struct scsi_device * sd,void * ctpriv)111 symmetric_device_unprobe(struct scsi_device *sd, void *ctpriv)
112 {
113 /*
114 * NOP for symmetric
115 */
116 }
117
118 /* ARGSUSED */
119 static int
symmetric_path_activate(struct scsi_device * sd,char * pathclass,void * ctpriv)120 symmetric_path_activate(struct scsi_device *sd, char *pathclass, void *ctpriv)
121 {
122 return (0);
123 }
124
125 /* ARGSUSED */
126 static int
symmetric_path_deactivate(struct scsi_device * sd,char * pathclass,void * ctpriv)127 symmetric_path_deactivate(struct scsi_device *sd, char *pathclass,
128 void *ctpriv)
129 {
130 return (0);
131 }
132
133 /* ARGSUSED */
134 static int
symmetric_path_get_opinfo(struct scsi_device * sd,struct scsi_path_opinfo * opinfo,void * ctpriv)135 symmetric_path_get_opinfo(struct scsi_device *sd,
136 struct 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 */
151 static int
symmetric_path_ping(struct scsi_device * sd,void * ctpriv)152 symmetric_path_ping(struct scsi_device *sd, void *ctpriv)
153 {
154 return (1);
155 }
156
157 /* ARGSUSED */
158 static int
symmetric_analyze_sense(struct scsi_device * sd,uint8_t * sense,void * ctpriv)159 symmetric_analyze_sense(struct scsi_device *sd,
160 uint8_t *sense, void *ctpriv)
161 {
162 return (SCSI_SENSE_NOFAILOVER);
163 }
164
165 /* ARGSUSED */
166 static int
symmetric_pathclass_next(char * cur,char ** nxt,void * ctpriv)167 symmetric_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