1 /* @(#)scsi_scan.c 1.38 17/08/06 Copyright 1997-2017 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)scsi_scan.c 1.38 17/08/06 Copyright 1997-2017 J. Schilling";
6 #endif
7 /*
8 * Scan SCSI Bus.
9 * Stolen from sformat. Need a more general form to
10 * re-use it in sformat too.
11 *
12 * Copyright (c) 1997-2017 J. Schilling
13 */
14 /*
15 * The contents of this file are subject to the terms of the
16 * Common Development and Distribution License, Version 1.0 only
17 * (the "License"). You may not use this file except in compliance
18 * with the License.
19 *
20 * See the file CDDL.Schily.txt in this distribution for details.
21 * A copy of the CDDL is also available via the Internet at
22 * http://www.opensource.org/licenses/cddl1.txt
23 *
24 * When distributing Covered Code, include this CDDL HEADER in each
25 * file and include the License file CDDL.Schily.txt from this distribution.
26 */
27
28 #include <schily/mconfig.h>
29 #include <schily/stdio.h>
30 #include <schily/stdlib.h>
31 #include <schily/standard.h>
32 #include <schily/btorder.h>
33 #include <schily/errno.h>
34 #include <schily/schily.h>
35 #include <schily/nlsdefs.h>
36
37 #include <scg/scgcmd.h>
38 #include <scg/scsidefs.h>
39 #include <scg/scsireg.h>
40 #include <scg/scsitransp.h>
41
42 #include "scsi_scan.h"
43 #include "cdrecord.h"
44
45 LOCAL void print_product __PR((FILE *f, struct scsi_inquiry *ip));
46 EXPORT int select_target __PR((SCSI *scgp, FILE *f));
47 EXPORT int find_target __PR((SCSI *scgp, int type, int idx));
48 LOCAL int _select_target __PR((SCSI *scgp, FILE *f, int type, int idx));
49 #ifdef __ready__
50 LOCAL int select_unit __PR((SCSI *scgp, FILE *f));
51 #endif
52
53 LOCAL void
print_product(f,ip)54 print_product(f, ip)
55 FILE *f;
56 struct scsi_inquiry *ip;
57 {
58 fprintf(f, "'%.8s' ", ip->inq_vendor_info);
59 fprintf(f, "'%.16s' ", ip->inq_prod_ident);
60 fprintf(f, "'%.4s' ", ip->inq_prod_revision);
61 if (ip->add_len < 31) {
62 fprintf(f, "NON CCS ");
63 }
64 scg_fprintdev(f, ip);
65 }
66
67 EXPORT int
select_target(scgp,f)68 select_target(scgp, f)
69 SCSI *scgp;
70 FILE *f;
71 {
72 return (_select_target(scgp, f, -1, -1));
73 }
74
75 EXPORT int
find_target(scgp,type,idx)76 find_target(scgp, type, idx)
77 SCSI *scgp;
78 int type;
79 int idx;
80 {
81 return (_select_target(scgp, (FILE *)NULL, type, idx));
82 }
83
84 LOCAL int
_select_target(scgp,f,type,idx)85 _select_target(scgp, f, type, idx)
86 SCSI *scgp;
87 FILE *f;
88 int type;
89 int idx;
90 {
91 int initiator;
92 int cscsibus = scg_scsibus(scgp);
93 int ctarget = scg_target(scgp);
94 int clun = scg_lun(scgp);
95 int numbus = scg_numbus(scgp);
96 int n;
97 int low = -1;
98 int high = -1;
99 int amt = -1;
100 int bus;
101 int tgt;
102 int lun = 0;
103 int err;
104 BOOL have_tgt;
105
106 if (numbus < 0)
107 numbus = 1024;
108 scgp->silent++;
109
110 for (bus = 0; bus < numbus; bus++) {
111 scg_settarget(scgp, bus, 0, 0);
112
113 if (!scg_havebus(scgp, bus))
114 continue;
115
116 initiator = scg_initiator_id(scgp);
117 if (f)
118 fprintf(f, "scsibus%d:\n", bus);
119
120 for (tgt = 0; tgt < 16; tgt++) {
121 n = bus*100 + tgt;
122
123 scg_settarget(scgp, bus, tgt, lun);
124 seterrno(0);
125 have_tgt = unit_ready(scgp) || scgp->scmd->error != SCG_FATAL;
126 err = geterrno();
127 if (err == EPERM || err == EACCES)
128 return (-1);
129
130 if (!have_tgt && tgt > 7) {
131 if (scgp->scmd->ux_errno == EINVAL)
132 break;
133 continue;
134 }
135 if (f) {
136 #ifdef FMT
137 if (print_disknames(bus, tgt, -1) < 8)
138 fprintf(f, "\t");
139 else
140 fprintf(f, " ");
141 #else
142 fprintf(f, "\t");
143 #endif
144 if (fprintf(f, "%d,%d,%d", bus, tgt, lun) < 8)
145 fprintf(f, "\t");
146 else
147 fprintf(f, " ");
148 fprintf(f, "%3d) ", n);
149 }
150 if (tgt == initiator) {
151 if (f)
152 fprintf(f, "HOST ADAPTOR\n");
153 continue;
154 }
155 if (!have_tgt) {
156 /*
157 * Hack: fd -> -2 means no access
158 */
159 if (f) {
160 fprintf(f, "%c\n",
161 scgp->fd == -2 ? '?':'*');
162 }
163 continue;
164 }
165 if (low < 0)
166 low = n;
167 high = n;
168
169 getdev(scgp, FALSE);
170 if (f)
171 print_product(f, scgp->inq);
172 if (type >= 0 && scgp->inq->type == type) {
173 amt++;
174 if (amt == 0) /* amt starts at -1 */
175 amt++;
176 if (amt == idx) {
177 scgp->silent--;
178 return (amt);
179 }
180 } else if (type < 0) {
181 amt++;
182 }
183 if (amt == 0) /* amt starts at -1 */
184 amt++;
185 }
186 }
187 scgp->silent--;
188
189 if (low < 0) {
190 errmsgno(EX_BAD, _("No target found.\n"));
191 return (0);
192 }
193 n = -1;
194 #ifdef FMT
195 getint(_("Select target"), &n, low, high);
196 bus = n/100;
197 tgt = n%100;
198 scg_settarget(scgp, bus, tgt, lun);
199 return (select_unit(scgp));
200 #else
201 scg_settarget(scgp, cscsibus, ctarget, clun);
202 return (amt);
203 #endif
204 }
205
206 #ifdef __ready__
207 LOCAL int
select_unit(scgp,f)208 select_unit(scgp, f)
209 SCSI *scgp;
210 FILE *f;
211 {
212 int initiator;
213 int clun = scg_lun(scgp);
214 int low = -1;
215 int high = -1;
216 int lun;
217
218 scgp->silent++;
219
220 fprintf(f, _("scsibus%d target %d:\n"), scg_scsibus(scgp), scg_target(scgp));
221
222 initiator = scg_initiator_id(scgp);
223 for (lun = 0; lun < 8; lun++) {
224
225 #ifdef FMT
226 if (print_disknames(scg_scsibus(scgp), scg_target(scgp), lun) < 8)
227 fprintf(f, "\t");
228 else
229 fprintf(f, " ");
230 #else
231 fprintf(f, "\t");
232 #endif
233 if (fprintf(f, "%d,%d,%d", scg_scsibus(scgp), scg_target(scgp), lun) < 8)
234 fprintf(f, "\t");
235 else
236 fprintf(f, " ");
237 fprintf(f, "%3d) ", lun);
238 if (scg_target(scgp) == initiator) {
239 fprintf(f, "HOST ADAPTOR\n");
240 continue;
241 }
242 scg_settarget(scgp, scg_scsibus(scgp), scg_target(scgp), lun);
243 if (!unit_ready(scgp) && scgp->scmd->error == SCG_FATAL) {
244 fprintf(f, "*\n");
245 continue;
246 }
247 if (unit_ready(scgp)) {
248 /* non extended sense illegal lun */
249 if (scgp->scmd->sense.code == 0x25) {
250 fprintf(f, "BAD UNIT\n");
251 continue;
252 }
253 }
254 if (low < 0)
255 low = lun;
256 high = lun;
257
258 getdev(scgp, FALSE);
259 print_product(f, scgp->inq);
260 }
261 scgp->silent--;
262
263 if (low < 0) {
264 errmsgno(EX_BAD, _("No lun found.\n"));
265 return (0);
266 }
267 lun = -1;
268 #ifdef FMT
269 getint(_("Select lun"), &lun, low, high);
270 scg_settarget(scgp, scg_scsibus(scgp), scg_target(scgp), lun);
271 format_one(scgp);
272 return (1);
273 #else
274 scg_settarget(scgp, scg_scsibus(scgp), scg_target(scgp), clun);
275 return (1);
276 #endif
277 }
278 #endif /* __ready__ */
279