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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Implementation of "scsi_vhci_f_tape" tape failover_ops.
29 *
30 * This file was historically meant for only tape implementation. It has
31 * been extended to manage SUN "supported" tape controllers. The supported
32 * VID/PID shall be listed in the tape_dev_table.
33 */
34
35 #include <sys/conf.h>
36 #include <sys/file.h>
37 #include <sys/ddi.h>
38 #include <sys/sunddi.h>
39 #include <sys/scsi/scsi.h>
40 #include <sys/scsi/adapters/scsi_vhci.h>
41
42 /* Supported device table entries. */
43 static char *tape_dev_table[] = {
44 /* " 111111" */
45 /* "012345670123456789012345" */
46 /* "|-VID--||-----PID------|" */
47 "IBM ULTRIUM-TD3",
48 "IBM ULTRIUM-TD4",
49 NULL
50 };
51
52 /* Failover module plumbing. */
53 SCSI_FAILOVER_OP("f_tape", tape);
54
55 /* ARGSUSED */
56 static int
tape_device_probe(struct scsi_device * sd,struct scsi_inquiry * inquiry,void ** ctpriv)57 tape_device_probe(struct scsi_device *sd, struct scsi_inquiry *inquiry,
58 void **ctpriv)
59 {
60 int i;
61 int rval = SFO_DEVICE_PROBE_PHCI;
62
63 VHCI_DEBUG(6, (CE_NOTE, NULL, "!tape_device_probe: inquiry string %s\n",
64 inquiry->inq_vid));
65 /*
66 * See if this a device type that we want to care about.
67 */
68 switch (inquiry->inq_dtype & DTYPE_MASK) {
69 case DTYPE_SEQUENTIAL:
70 break;
71 case DTYPE_CHANGER:
72 rval = SFO_DEVICE_PROBE_VHCI;
73 goto done;
74 default:
75 /*
76 * Not interested.
77 */
78 return (rval);
79 }
80
81 /*
82 * If it reports that it supports tpgs and it got here it may have
83 * failed the tpgs commands. It might or might not support dual port
84 * but we'll go with it.
85 */
86 if (inquiry->inq_tpgs) {
87 VHCI_DEBUG(6, (CE_NOTE, NULL, "!has tpgs bits: %s\n",
88 inquiry->inq_vid));
89 rval = SFO_DEVICE_PROBE_VHCI;
90 } else if (inquiry->inq_dualp) {
91 /*
92 * Looks like it claims to have more then one port.
93 */
94 VHCI_DEBUG(6, (CE_NOTE, NULL, "!has dual port bits: %s\n",
95 inquiry->inq_vid));
96 rval = SFO_DEVICE_PROBE_VHCI;
97 } else {
98
99 /*
100 * See if this device is on the list.
101 */
102 for (i = 0; tape_dev_table[i]; i++) {
103
104 if (strncmp(inquiry->inq_vid, tape_dev_table[i],
105 strlen(tape_dev_table[i])) == 0) {
106 VHCI_DEBUG(6, (CE_NOTE, NULL,
107 "!was on the list: %s\n",
108 inquiry->inq_vid));
109 rval = SFO_DEVICE_PROBE_VHCI;
110 break;
111 }
112 }
113 }
114 done:
115 if (rval == SFO_DEVICE_PROBE_VHCI) {
116 /*
117 * Policy only applies to 'client' probe, not
118 * vhci_is_dev_supported() pHCI probe. Detect difference
119 * based on ctpriv.
120 */
121 if (ctpriv &&
122 (mdi_set_lb_policy(sd->sd_dev, LOAD_BALANCE_NONE) !=
123 MDI_SUCCESS)) {
124 VHCI_DEBUG(6, (CE_NOTE, NULL, "!fail load balance none"
125 ": %s\n", inquiry->inq_vid));
126 return (SFO_DEVICE_PROBE_PHCI);
127 }
128
129 }
130 return (rval);
131 }
132
133 /* ARGSUSED */
134 static void
tape_device_unprobe(struct scsi_device * sd,void * ctpriv)135 tape_device_unprobe(struct scsi_device *sd, void *ctpriv)
136 {
137 /*
138 * NO OP for tape.
139 */
140
141 }
142
143 /* ARGSUSED */
144 static int
tape_path_activate(struct scsi_device * sd,char * pathclass,void * ctpriv)145 tape_path_activate(struct scsi_device *sd, char *pathclass, void *ctpriv)
146 {
147 return (0);
148 }
149
150 /* ARGSUSED */
151 static int
tape_path_deactivate(struct scsi_device * sd,char * pathclass,void * ctpriv)152 tape_path_deactivate(struct scsi_device *sd, char *pathclass, void *ctpriv)
153 {
154 return (0);
155 }
156
157 /* ARGSUSED */
158 static int
tape_path_get_opinfo(struct scsi_device * sd,struct scsi_path_opinfo * opinfo,void * ctpriv)159 tape_path_get_opinfo(struct scsi_device *sd, struct scsi_path_opinfo *opinfo,
160 void *ctpriv)
161 {
162 opinfo->opinfo_rev = OPINFO_REV;
163 (void) strcpy(opinfo->opinfo_path_attr, PCLASS_PRIMARY);
164 opinfo->opinfo_path_state = SCSI_PATH_ACTIVE;
165 opinfo->opinfo_pswtch_best = 0; /* N/A */
166 opinfo->opinfo_pswtch_worst = 0; /* N/A */
167 opinfo->opinfo_xlf_capable = 0;
168 opinfo->opinfo_mode = SCSI_NO_FAILOVER;
169 opinfo->opinfo_preferred = 1;
170
171 return (0);
172 }
173
174 /* ARGSUSED */
175 static int
tape_path_ping(struct scsi_device * sd,void * ctpriv)176 tape_path_ping(struct scsi_device *sd, void *ctpriv)
177 {
178 return (1);
179 }
180
181 /* ARGSUSED */
182 static int
tape_analyze_sense(struct scsi_device * sd,uint8_t * sense,void * ctpriv)183 tape_analyze_sense(struct scsi_device *sd, uint8_t *sense,
184 void *ctpriv)
185 {
186 uint8_t skey, asc, ascq;
187
188 skey = scsi_sense_key(sense);
189 asc = scsi_sense_asc(sense);
190 ascq = scsi_sense_ascq(sense);
191
192 if (skey == KEY_ABORTED_COMMAND &&
193 asc == 0x4b &&
194 ascq == 0x83) {
195 return (SCSI_SENSE_INACTIVE);
196 }
197 if (skey == KEY_NOT_READY &&
198 asc == 0x4 &&
199 ascq == 0x1) {
200 return (SCSI_SENSE_NOT_READY);
201 }
202 return (SCSI_SENSE_NOFAILOVER);
203 }
204
205 /* ARGSUSED */
206 static int
tape_pathclass_next(char * cur,char ** nxt,void * ctpriv)207 tape_pathclass_next(char *cur, char **nxt, void *ctpriv)
208 {
209 if (cur == NULL) {
210 *nxt = PCLASS_PRIMARY;
211 return (0);
212 } else if (strcmp(cur, PCLASS_PRIMARY) == 0) {
213 return (ENOENT);
214 }
215 return (EINVAL);
216 }
217