xref: /aosp_15_r20/external/sg3_utils/src/sg_map.c (revision 44704f698541f6367e81f991ef8bb54ccbf3fc18)
1*44704f69SBart Van Assche /*
2*44704f69SBart Van Assche  * Utility program for the Linux OS SCSI generic ("sg") device driver.
3*44704f69SBart Van Assche  *     Copyright (C) 2000-2017 D. Gilbert
4*44704f69SBart Van Assche  * This program is free software; you can redistribute it and/or modify
5*44704f69SBart Van Assche  * it under the terms of the GNU General Public License as published by
6*44704f69SBart Van Assche  * the Free Software Foundation; either version 2, or (at your option)
7*44704f69SBart Van Assche  * any later version.
8*44704f69SBart Van Assche  *
9*44704f69SBart Van Assche  * SPDX-License-Identifier: GPL-2.0-or-later
10*44704f69SBart Van Assche 
11*44704f69SBart Van Assche    This shows the mapping from "sg" devices to other scsi devices
12*44704f69SBart Van Assche    (i.e. sd, scd or st) if any.
13*44704f69SBart Van Assche 
14*44704f69SBart Van Assche    Note: This program requires sg version 2 or better.
15*44704f69SBart Van Assche 
16*44704f69SBart Van Assche    Version 0.19 20041203
17*44704f69SBart Van Assche 
18*44704f69SBart Van Assche    Version 1.02 20050511
19*44704f69SBart Van Assche         - allow for sparse disk name with up to 3 letter SCSI
20*44704f69SBart Van Assche           disk device node names (e.g. /dev/sdaaa)
21*44704f69SBart Van Assche           [Nate Dailey < Nate dot Dailey at stratus dot com >]
22*44704f69SBart Van Assche */
23*44704f69SBart Van Assche 
24*44704f69SBart Van Assche #ifndef _GNU_SOURCE
25*44704f69SBart Van Assche #define _GNU_SOURCE 1
26*44704f69SBart Van Assche #endif
27*44704f69SBart Van Assche 
28*44704f69SBart Van Assche #include <unistd.h>
29*44704f69SBart Van Assche #include <fcntl.h>
30*44704f69SBart Van Assche #include <stdio.h>
31*44704f69SBart Van Assche #include <stdlib.h>
32*44704f69SBart Van Assche #include <stdarg.h>
33*44704f69SBart Van Assche #include <stdbool.h>
34*44704f69SBart Van Assche #include <string.h>
35*44704f69SBart Van Assche #include <errno.h>
36*44704f69SBart Van Assche #include <dirent.h>
37*44704f69SBart Van Assche #include <libgen.h>
38*44704f69SBart Van Assche #include <sys/ioctl.h>
39*44704f69SBart Van Assche #include <sys/types.h>
40*44704f69SBart Van Assche #include <sys/stat.h>
41*44704f69SBart Van Assche 
42*44704f69SBart Van Assche #ifdef HAVE_CONFIG_H
43*44704f69SBart Van Assche #include "config.h"
44*44704f69SBart Van Assche #endif
45*44704f69SBart Van Assche #include "sg_lib.h"
46*44704f69SBart Van Assche #include "sg_cmds_basic.h"
47*44704f69SBart Van Assche #include "sg_io_linux.h"
48*44704f69SBart Van Assche 
49*44704f69SBart Van Assche 
50*44704f69SBart Van Assche static const char * version_str = "1.12 20171010";
51*44704f69SBart Van Assche 
52*44704f69SBart Van Assche static const char * devfs_id = "/dev/.devfsd";
53*44704f69SBart Van Assche 
54*44704f69SBart Van Assche #define NUMERIC_SCAN_DEF true /* set to false to make alpha scan default */
55*44704f69SBart Van Assche 
56*44704f69SBart Van Assche #define INQUIRY_RESP_INITIAL_LEN 36
57*44704f69SBart Van Assche #define MAX_SG_DEVS 4096
58*44704f69SBart Van Assche #define PRESENT_ARRAY_SIZE MAX_SG_DEVS
59*44704f69SBart Van Assche 
60*44704f69SBart Van Assche static const char * sysfs_sg_dir = "/sys/class/scsi_generic";
61*44704f69SBart Van Assche static char gen_index_arr[PRESENT_ARRAY_SIZE];
62*44704f69SBart Van Assche static int has_sysfs_sg = 0;
63*44704f69SBart Van Assche 
64*44704f69SBart Van Assche 
65*44704f69SBart Van Assche typedef struct my_map_info
66*44704f69SBart Van Assche {
67*44704f69SBart Van Assche     int active;
68*44704f69SBart Van Assche     int lin_dev_type;
69*44704f69SBart Van Assche     int oth_dev_num;
70*44704f69SBart Van Assche     struct sg_scsi_id sg_dat;
71*44704f69SBart Van Assche     char vendor[8];
72*44704f69SBart Van Assche     char product[16];
73*44704f69SBart Van Assche     char revision[4];
74*44704f69SBart Van Assche } my_map_info_t;
75*44704f69SBart Van Assche 
76*44704f69SBart Van Assche 
77*44704f69SBart Van Assche #define MAX_SD_DEVS (26 + 26*26 + 26*26*26) /* sdX, sdXX, sdXXX */
78*44704f69SBart Van Assche                  /* (26 + 676 + 17576) = 18278 */
79*44704f69SBart Van Assche #define MAX_SR_DEVS 128
80*44704f69SBart Van Assche #define MAX_ST_DEVS 128
81*44704f69SBart Van Assche #define MAX_OSST_DEVS 128
82*44704f69SBart Van Assche #define MAX_ERRORS 5
83*44704f69SBart Van Assche 
84*44704f69SBart Van Assche static my_map_info_t map_arr[MAX_SG_DEVS];
85*44704f69SBart Van Assche 
86*44704f69SBart Van Assche #define LIN_DEV_TYPE_UNKNOWN 0
87*44704f69SBart Van Assche #define LIN_DEV_TYPE_SD 1
88*44704f69SBart Van Assche #define LIN_DEV_TYPE_SR 2
89*44704f69SBart Van Assche #define LIN_DEV_TYPE_ST 3
90*44704f69SBart Van Assche #define LIN_DEV_TYPE_SCD 4
91*44704f69SBart Van Assche #define LIN_DEV_TYPE_OSST 5
92*44704f69SBart Van Assche 
93*44704f69SBart Van Assche 
94*44704f69SBart Van Assche typedef struct my_scsi_idlun {
95*44704f69SBart Van Assche /* why can't userland see this structure ??? */
96*44704f69SBart Van Assche     int dev_id;
97*44704f69SBart Van Assche     int host_unique_id;
98*44704f69SBart Van Assche } My_scsi_idlun;
99*44704f69SBart Van Assche 
100*44704f69SBart Van Assche 
101*44704f69SBart Van Assche #define EBUFF_SZ 256
102*44704f69SBart Van Assche static char ebuff[EBUFF_SZ];
103*44704f69SBart Van Assche 
104*44704f69SBart Van Assche static void scan_dev_type(const char * leadin, int max_dev, bool do_numeric,
105*44704f69SBart Van Assche                           int lin_dev_type, int last_sg_ind);
106*44704f69SBart Van Assche 
usage()107*44704f69SBart Van Assche static void usage()
108*44704f69SBart Van Assche {
109*44704f69SBart Van Assche     printf("Usage: sg_map [-a] [-h] [-i] [-n] [-sd] [-scd or -sr] [-st] "
110*44704f69SBart Van Assche            "[-V] [-x]\n");
111*44704f69SBart Van Assche     printf("  where:\n");
112*44704f69SBart Van Assche     printf("    -a      do alphabetic scan (ie sga, sgb, sgc)\n");
113*44704f69SBart Van Assche     printf("    -h or -?    show this usage message then exit\n");
114*44704f69SBart Van Assche     printf("    -i      also show device INQUIRY strings\n");
115*44704f69SBart Van Assche     printf("    -n      do numeric scan (i.e. sg0, sg1, sg2) "
116*44704f69SBart Van Assche            "(default)\n");
117*44704f69SBart Van Assche     printf("    -sd     show mapping to disks\n");
118*44704f69SBart Van Assche     printf("    -scd    show mapping to cdroms (look for /dev/scd<n>\n");
119*44704f69SBart Van Assche     printf("    -sr     show mapping to cdroms (look for /dev/sr<n>\n");
120*44704f69SBart Van Assche     printf("    -st     show mapping to tapes (st and osst devices)\n");
121*44704f69SBart Van Assche     printf("    -V      print version string then exit\n");
122*44704f69SBart Van Assche     printf("    -x      also show bus,chan,id,lun and type\n\n");
123*44704f69SBart Van Assche     printf("If no '-s*' arguments given then show all mappings. This "
124*44704f69SBart Van Assche            "utility\nis DEPRECATED, do not use in Linux 2.6 series or "
125*44704f69SBart Van Assche            "later.\n");
126*44704f69SBart Van Assche }
127*44704f69SBart Van Assche 
scandir_select(const struct dirent * s)128*44704f69SBart Van Assche static int scandir_select(const struct dirent * s)
129*44704f69SBart Van Assche {
130*44704f69SBart Van Assche     int k;
131*44704f69SBart Van Assche 
132*44704f69SBart Van Assche     if (1 == sscanf(s->d_name, "sg%d", &k)) {
133*44704f69SBart Van Assche         if ((k >= 0) && (k < PRESENT_ARRAY_SIZE)) {
134*44704f69SBart Van Assche             gen_index_arr[k] = 1;
135*44704f69SBart Van Assche             return 1;
136*44704f69SBart Van Assche         }
137*44704f69SBart Van Assche     }
138*44704f69SBart Van Assche     return 0;
139*44704f69SBart Van Assche }
140*44704f69SBart Van Assche 
sysfs_sg_scan(const char * dir_name)141*44704f69SBart Van Assche static int sysfs_sg_scan(const char * dir_name)
142*44704f69SBart Van Assche {
143*44704f69SBart Van Assche     struct dirent ** namelist;
144*44704f69SBart Van Assche     int num, k;
145*44704f69SBart Van Assche 
146*44704f69SBart Van Assche     num = scandir(dir_name, &namelist, scandir_select, NULL);
147*44704f69SBart Van Assche     if (num < 0)
148*44704f69SBart Van Assche         return -errno;
149*44704f69SBart Van Assche     for (k = 0; k < num; ++k)
150*44704f69SBart Van Assche         free(namelist[k]);
151*44704f69SBart Van Assche     free(namelist);
152*44704f69SBart Van Assche     return num;
153*44704f69SBart Van Assche }
154*44704f69SBart Van Assche 
make_dev_name(char * fname,const char * leadin,int k,bool do_numeric)155*44704f69SBart Van Assche static void make_dev_name(char * fname, const char * leadin, int k,
156*44704f69SBart Van Assche                           bool do_numeric)
157*44704f69SBart Van Assche {
158*44704f69SBart Van Assche     char buff[64];
159*44704f69SBart Van Assche     int  ones,tens,hundreds; /* for lack of a better name */
160*44704f69SBart Van Assche     int  buff_idx;
161*44704f69SBart Van Assche 
162*44704f69SBart Van Assche     strcpy(fname, leadin ? leadin : "/dev/sg");
163*44704f69SBart Van Assche     if (do_numeric) {
164*44704f69SBart Van Assche         sprintf(buff, "%d", k);
165*44704f69SBart Van Assche         strcat(fname, buff);
166*44704f69SBart Van Assche     }
167*44704f69SBart Van Assche     else if (k >= (26 + 26*26 + 26*26*26)) {
168*44704f69SBart Van Assche         strcat(fname, "xxxx");
169*44704f69SBart Van Assche     }
170*44704f69SBart Van Assche     else {
171*44704f69SBart Van Assche         ones = k % 26;
172*44704f69SBart Van Assche 
173*44704f69SBart Van Assche         if ((k - 26) >= 0)
174*44704f69SBart Van Assche             tens = ((k-26)/26) % 26;
175*44704f69SBart Van Assche         else tens = -1;
176*44704f69SBart Van Assche 
177*44704f69SBart Van Assche         if ((k - (26 + 26*26)) >= 0)
178*44704f69SBart Van Assche              hundreds = ((k - (26 + 26*26))/(26*26)) % 26;
179*44704f69SBart Van Assche         else hundreds = -1;
180*44704f69SBart Van Assche 
181*44704f69SBart Van Assche         buff_idx = 0;
182*44704f69SBart Van Assche         if (hundreds >= 0) buff[buff_idx++] = 'a' + (char)hundreds;
183*44704f69SBart Van Assche         if (tens >= 0) buff[buff_idx++] = 'a' + (char)tens;
184*44704f69SBart Van Assche         buff[buff_idx++] = 'a' + (char)ones;
185*44704f69SBart Van Assche         buff[buff_idx] = '\0';
186*44704f69SBart Van Assche         strcat(fname, buff);
187*44704f69SBart Van Assche     }
188*44704f69SBart Van Assche }
189*44704f69SBart Van Assche 
190*44704f69SBart Van Assche 
main(int argc,char * argv[])191*44704f69SBart Van Assche int main(int argc, char * argv[])
192*44704f69SBart Van Assche {
193*44704f69SBart Van Assche     bool do_all_s = true;
194*44704f69SBart Van Assche     bool do_extra = false;
195*44704f69SBart Van Assche     bool do_inquiry = false;
196*44704f69SBart Van Assche     bool do_numeric = NUMERIC_SCAN_DEF;
197*44704f69SBart Van Assche     bool do_osst = false;
198*44704f69SBart Van Assche     bool do_scd = false;
199*44704f69SBart Van Assche     bool do_sd = false;
200*44704f69SBart Van Assche     bool do_sr = false;
201*44704f69SBart Van Assche     bool do_st = false;
202*44704f69SBart Van Assche     bool eacces_err = false;
203*44704f69SBart Van Assche     int sg_fd, res, k;
204*44704f69SBart Van Assche     int num_errors = 0;
205*44704f69SBart Van Assche     int num_silent = 0;
206*44704f69SBart Van Assche     int last_sg_ind = -1;
207*44704f69SBart Van Assche     char fname[64];
208*44704f69SBart Van Assche     struct stat a_stat;
209*44704f69SBart Van Assche 
210*44704f69SBart Van Assche     for (k = 1; k < argc; ++k) {
211*44704f69SBart Van Assche         if (0 == strcmp("-n", argv[k]))
212*44704f69SBart Van Assche             do_numeric = true;
213*44704f69SBart Van Assche         else if (0 == strcmp("-a", argv[k]))
214*44704f69SBart Van Assche             do_numeric = false;
215*44704f69SBart Van Assche         else if (0 == strcmp("-x", argv[k]))
216*44704f69SBart Van Assche             do_extra = true;
217*44704f69SBart Van Assche         else if (0 == strcmp("-i", argv[k]))
218*44704f69SBart Van Assche             do_inquiry = true;
219*44704f69SBart Van Assche         else if (0 == strcmp("-sd", argv[k])) {
220*44704f69SBart Van Assche             do_sd = true;
221*44704f69SBart Van Assche             do_all_s = false;
222*44704f69SBart Van Assche         } else if (0 == strcmp("-st", argv[k])) {
223*44704f69SBart Van Assche             do_st = true;
224*44704f69SBart Van Assche             do_osst = true;
225*44704f69SBart Van Assche             do_all_s = false;
226*44704f69SBart Van Assche         } else if (0 == strcmp("-sr", argv[k])) {
227*44704f69SBart Van Assche             do_sr = true;
228*44704f69SBart Van Assche             do_all_s = false;
229*44704f69SBart Van Assche         } else if (0 == strcmp("-scd", argv[k])) {
230*44704f69SBart Van Assche             do_scd = true;
231*44704f69SBart Van Assche             do_all_s = false;
232*44704f69SBart Van Assche         } else if (0 == strcmp("-V", argv[k])) {
233*44704f69SBart Van Assche             fprintf(stderr, "Version string: %s\n", version_str);
234*44704f69SBart Van Assche             exit(0);
235*44704f69SBart Van Assche         } else if ((0 == strcmp("-?", argv[k])) ||
236*44704f69SBart Van Assche                    (0 == strncmp("-h", argv[k], 2))) {
237*44704f69SBart Van Assche             printf(
238*44704f69SBart Van Assche             "Show mapping from sg devices to other scsi device names\n\n");
239*44704f69SBart Van Assche             usage();
240*44704f69SBart Van Assche             return SG_LIB_SYNTAX_ERROR;
241*44704f69SBart Van Assche         } else if (*argv[k] == '-') {
242*44704f69SBart Van Assche             printf("Unknown switch: %s\n", argv[k]);
243*44704f69SBart Van Assche             usage();
244*44704f69SBart Van Assche             return SG_LIB_SYNTAX_ERROR;
245*44704f69SBart Van Assche         } else if (*argv[k] != '-') {
246*44704f69SBart Van Assche             printf("Unknown argument\n");
247*44704f69SBart Van Assche             usage();
248*44704f69SBart Van Assche             return SG_LIB_SYNTAX_ERROR;
249*44704f69SBart Van Assche         }
250*44704f69SBart Van Assche     }
251*44704f69SBart Van Assche 
252*44704f69SBart Van Assche     if ((stat(sysfs_sg_dir, &a_stat) >= 0) && (S_ISDIR(a_stat.st_mode)))
253*44704f69SBart Van Assche         has_sysfs_sg = sysfs_sg_scan(sysfs_sg_dir);
254*44704f69SBart Van Assche 
255*44704f69SBart Van Assche     if (stat(devfs_id, &a_stat) == 0)
256*44704f69SBart Van Assche         printf("# Note: the devfs pseudo file system is present\n");
257*44704f69SBart Van Assche 
258*44704f69SBart Van Assche     for (k = 0, res = 0; (k < MAX_SG_DEVS) && (num_errors < MAX_ERRORS);
259*44704f69SBart Van Assche          ++k, res = (sg_fd >= 0) ? close(sg_fd) : 0) {
260*44704f69SBart Van Assche         if (res < 0) {
261*44704f69SBart Van Assche             snprintf(ebuff, EBUFF_SZ, "Error closing %s ", fname);
262*44704f69SBart Van Assche             perror("sg_map: close error");
263*44704f69SBart Van Assche             return SG_LIB_FILE_ERROR;
264*44704f69SBart Van Assche         }
265*44704f69SBart Van Assche         if (has_sysfs_sg) {
266*44704f69SBart Van Assche            if (0 == gen_index_arr[k]) {
267*44704f69SBart Van Assche                 sg_fd = -1;
268*44704f69SBart Van Assche                 continue;
269*44704f69SBart Van Assche             }
270*44704f69SBart Van Assche             make_dev_name(fname, "/dev/sg", k, true);
271*44704f69SBart Van Assche         } else
272*44704f69SBart Van Assche             make_dev_name(fname, "/dev/sg", k, do_numeric);
273*44704f69SBart Van Assche 
274*44704f69SBart Van Assche         sg_fd = open(fname, O_RDONLY | O_NONBLOCK);
275*44704f69SBart Van Assche         if (sg_fd < 0) {
276*44704f69SBart Van Assche             if (EBUSY == errno) {
277*44704f69SBart Van Assche                 map_arr[k].active = -2;
278*44704f69SBart Van Assche                 continue;
279*44704f69SBart Van Assche             }
280*44704f69SBart Van Assche             else if ((ENODEV == errno) || (ENOENT == errno) ||
281*44704f69SBart Van Assche                      (ENXIO == errno)) {
282*44704f69SBart Van Assche                 ++num_errors;
283*44704f69SBart Van Assche                 ++num_silent;
284*44704f69SBart Van Assche                 map_arr[k].active = -1;
285*44704f69SBart Van Assche                 continue;
286*44704f69SBart Van Assche             }
287*44704f69SBart Van Assche             else {
288*44704f69SBart Van Assche                 if (EACCES == errno)
289*44704f69SBart Van Assche                     eacces_err = true;
290*44704f69SBart Van Assche                 snprintf(ebuff, EBUFF_SZ, "Error opening %s ", fname);
291*44704f69SBart Van Assche                 perror(ebuff);
292*44704f69SBart Van Assche                 ++num_errors;
293*44704f69SBart Van Assche                 continue;
294*44704f69SBart Van Assche             }
295*44704f69SBart Van Assche         }
296*44704f69SBart Van Assche         res = ioctl(sg_fd, SG_GET_SCSI_ID, &map_arr[k].sg_dat);
297*44704f69SBart Van Assche         if (res < 0) {
298*44704f69SBart Van Assche             snprintf(ebuff, EBUFF_SZ,
299*44704f69SBart Van Assche                      "device %s failed on sg ioctl, skip", fname);
300*44704f69SBart Van Assche             perror(ebuff);
301*44704f69SBart Van Assche             ++num_errors;
302*44704f69SBart Van Assche             continue;
303*44704f69SBart Van Assche         }
304*44704f69SBart Van Assche         if (do_inquiry) {
305*44704f69SBart Van Assche             char buff[INQUIRY_RESP_INITIAL_LEN];
306*44704f69SBart Van Assche 
307*44704f69SBart Van Assche             if (0 == sg_ll_inquiry(sg_fd, false, false, 0, buff, sizeof(buff),
308*44704f69SBart Van Assche                                    true, 0)) {
309*44704f69SBart Van Assche                 memcpy(map_arr[k].vendor, &buff[8], 8);
310*44704f69SBart Van Assche                 memcpy(map_arr[k].product, &buff[16], 16);
311*44704f69SBart Van Assche                 memcpy(map_arr[k].revision, &buff[32], 4);
312*44704f69SBart Van Assche             }
313*44704f69SBart Van Assche         }
314*44704f69SBart Van Assche         map_arr[k].active = 1;
315*44704f69SBart Van Assche         map_arr[k].oth_dev_num = -1;
316*44704f69SBart Van Assche         last_sg_ind = k;
317*44704f69SBart Van Assche     }
318*44704f69SBart Van Assche     if ((num_errors >= MAX_ERRORS) && (num_silent < num_errors)) {
319*44704f69SBart Van Assche         printf("Stopping because there are too many error\n");
320*44704f69SBart Van Assche         if (eacces_err)
321*44704f69SBart Van Assche             printf("    root access may be required\n");
322*44704f69SBart Van Assche         return SG_LIB_FILE_ERROR;
323*44704f69SBart Van Assche     }
324*44704f69SBart Van Assche     if (last_sg_ind < 0) {
325*44704f69SBart Van Assche         printf("Stopping because no sg devices found\n");
326*44704f69SBart Van Assche     }
327*44704f69SBart Van Assche 
328*44704f69SBart Van Assche     if (do_all_s || do_sd)
329*44704f69SBart Van Assche         scan_dev_type("/dev/sd", MAX_SD_DEVS, 0, LIN_DEV_TYPE_SD, last_sg_ind);
330*44704f69SBart Van Assche     if (do_all_s || do_sr)
331*44704f69SBart Van Assche         scan_dev_type("/dev/sr", MAX_SR_DEVS, 1, LIN_DEV_TYPE_SR, last_sg_ind);
332*44704f69SBart Van Assche     if (do_all_s || do_scd)
333*44704f69SBart Van Assche         scan_dev_type("/dev/scd", MAX_SR_DEVS, 1, LIN_DEV_TYPE_SCD,
334*44704f69SBart Van Assche                       last_sg_ind);
335*44704f69SBart Van Assche     if (do_all_s || do_st)
336*44704f69SBart Van Assche         scan_dev_type("/dev/nst", MAX_ST_DEVS, 1, LIN_DEV_TYPE_ST,
337*44704f69SBart Van Assche                       last_sg_ind);
338*44704f69SBart Van Assche     if (do_all_s || do_osst)
339*44704f69SBart Van Assche         scan_dev_type("/dev/osst", MAX_OSST_DEVS, 1, LIN_DEV_TYPE_OSST,
340*44704f69SBart Van Assche                       last_sg_ind);
341*44704f69SBart Van Assche 
342*44704f69SBart Van Assche     for (k = 0; k <= last_sg_ind; ++k) {
343*44704f69SBart Van Assche         if (has_sysfs_sg) {
344*44704f69SBart Van Assche            if (0 == gen_index_arr[k]) {
345*44704f69SBart Van Assche                 continue;
346*44704f69SBart Van Assche             }
347*44704f69SBart Van Assche             make_dev_name(fname, "/dev/sg", k, true);
348*44704f69SBart Van Assche         } else
349*44704f69SBart Van Assche             make_dev_name(fname, "/dev/sg", k, do_numeric);
350*44704f69SBart Van Assche         printf("%s", fname);
351*44704f69SBart Van Assche         switch (map_arr[k].active)
352*44704f69SBart Van Assche         {
353*44704f69SBart Van Assche         case -2:
354*44704f69SBart Van Assche             printf(do_extra ? "  -2 -2 -2 -2  -2" : "  busy");
355*44704f69SBart Van Assche             break;
356*44704f69SBart Van Assche         case -1:
357*44704f69SBart Van Assche             printf(do_extra ? "  -1 -1 -1 -1  -1" : "  not present");
358*44704f69SBart Van Assche             break;
359*44704f69SBart Van Assche         case 0:
360*44704f69SBart Van Assche             printf(do_extra ? "  -3 -3 -3 -3  -3" : "  some error");
361*44704f69SBart Van Assche             break;
362*44704f69SBart Van Assche         case 1:
363*44704f69SBart Van Assche             if (do_extra)
364*44704f69SBart Van Assche                 printf("  %d %d %d %d  %d", map_arr[k].sg_dat.host_no,
365*44704f69SBart Van Assche                        map_arr[k].sg_dat.channel, map_arr[k].sg_dat.scsi_id,
366*44704f69SBart Van Assche                        map_arr[k].sg_dat.lun, map_arr[k].sg_dat.scsi_type);
367*44704f69SBart Van Assche             switch (map_arr[k].lin_dev_type)
368*44704f69SBart Van Assche             {
369*44704f69SBart Van Assche             case LIN_DEV_TYPE_SD:
370*44704f69SBart Van Assche                 make_dev_name(fname, "/dev/sd" , map_arr[k].oth_dev_num, 0);
371*44704f69SBart Van Assche                 printf("  %s", fname);
372*44704f69SBart Van Assche                 break;
373*44704f69SBart Van Assche             case LIN_DEV_TYPE_ST:
374*44704f69SBart Van Assche                 make_dev_name(fname, "/dev/nst" , map_arr[k].oth_dev_num, 1);
375*44704f69SBart Van Assche                 printf("  %s", fname);
376*44704f69SBart Van Assche                 break;
377*44704f69SBart Van Assche             case LIN_DEV_TYPE_OSST:
378*44704f69SBart Van Assche                 make_dev_name(fname, "/dev/osst" , map_arr[k].oth_dev_num, 1);
379*44704f69SBart Van Assche                 printf("  %s", fname);
380*44704f69SBart Van Assche                 break;
381*44704f69SBart Van Assche             case LIN_DEV_TYPE_SR:
382*44704f69SBart Van Assche                 make_dev_name(fname, "/dev/sr" , map_arr[k].oth_dev_num, 1);
383*44704f69SBart Van Assche                 printf("  %s", fname);
384*44704f69SBart Van Assche                 break;
385*44704f69SBart Van Assche             case LIN_DEV_TYPE_SCD:
386*44704f69SBart Van Assche                 make_dev_name(fname, "/dev/scd" , map_arr[k].oth_dev_num, 1);
387*44704f69SBart Van Assche                 printf("  %s", fname);
388*44704f69SBart Van Assche                 break;
389*44704f69SBart Van Assche             default:
390*44704f69SBart Van Assche                 break;
391*44704f69SBart Van Assche             }
392*44704f69SBart Van Assche             if (do_inquiry)
393*44704f69SBart Van Assche                 printf("  %.8s  %.16s  %.4s", map_arr[k].vendor,
394*44704f69SBart Van Assche                        map_arr[k].product, map_arr[k].revision);
395*44704f69SBart Van Assche             break;
396*44704f69SBart Van Assche         default:
397*44704f69SBart Van Assche             printf("  bad logic\n");
398*44704f69SBart Van Assche             break;
399*44704f69SBart Van Assche         }
400*44704f69SBart Van Assche         printf("\n");
401*44704f69SBart Van Assche     }
402*44704f69SBart Van Assche     return 0;
403*44704f69SBart Van Assche }
404*44704f69SBart Van Assche 
find_dev_in_sg_arr(My_scsi_idlun * my_idlun,int host_no,int last_sg_ind)405*44704f69SBart Van Assche static int find_dev_in_sg_arr(My_scsi_idlun * my_idlun, int host_no,
406*44704f69SBart Van Assche                               int last_sg_ind)
407*44704f69SBart Van Assche {
408*44704f69SBart Van Assche     int k;
409*44704f69SBart Van Assche     struct sg_scsi_id * sidp;
410*44704f69SBart Van Assche 
411*44704f69SBart Van Assche     for (k = 0; k <= last_sg_ind; ++k) {
412*44704f69SBart Van Assche         sidp = &(map_arr[k].sg_dat);
413*44704f69SBart Van Assche         if ((host_no == sidp->host_no) &&
414*44704f69SBart Van Assche             ((my_idlun->dev_id & 0xff) == sidp->scsi_id) &&
415*44704f69SBart Van Assche             (((my_idlun->dev_id >> 8) & 0xff) == sidp->lun) &&
416*44704f69SBart Van Assche             (((my_idlun->dev_id >> 16) & 0xff) == sidp->channel))
417*44704f69SBart Van Assche             return k;
418*44704f69SBart Van Assche     }
419*44704f69SBart Van Assche     return -1;
420*44704f69SBart Van Assche }
421*44704f69SBart Van Assche 
scan_dev_type(const char * leadin,int max_dev,bool do_numeric,int lin_dev_type,int last_sg_ind)422*44704f69SBart Van Assche static void scan_dev_type(const char * leadin, int max_dev, bool do_numeric,
423*44704f69SBart Van Assche                           int lin_dev_type, int last_sg_ind)
424*44704f69SBart Van Assche {
425*44704f69SBart Van Assche     int k, res, ind, sg_fd = 0;
426*44704f69SBart Van Assche     int num_errors = 0;
427*44704f69SBart Van Assche     int num_silent = 0;
428*44704f69SBart Van Assche     int host_no = -1;
429*44704f69SBart Van Assche     My_scsi_idlun my_idlun;
430*44704f69SBart Van Assche     char fname[64];
431*44704f69SBart Van Assche 
432*44704f69SBart Van Assche     for (k = 0, res = 0; (k < max_dev)  && (num_errors < MAX_ERRORS);
433*44704f69SBart Van Assche          ++k, res = (sg_fd >= 0) ? close(sg_fd) : 0) {
434*44704f69SBart Van Assche 
435*44704f69SBart Van Assche /* ignore close() errors */
436*44704f69SBart Van Assche #if 0
437*44704f69SBart Van Assche         if (res < 0) {
438*44704f69SBart Van Assche             snprintf(ebuff, EBUFF_SZ, "Error closing %s ", fname);
439*44704f69SBart Van Assche             perror("sg_map: close error");
440*44704f69SBart Van Assche #ifndef IGN_CLOSE_ERR
441*44704f69SBart Van Assche             return;
442*44704f69SBart Van Assche #else
443*44704f69SBart Van Assche             ++num_errors;
444*44704f69SBart Van Assche             sg_fd = 0;
445*44704f69SBart Van Assche #endif
446*44704f69SBart Van Assche         }
447*44704f69SBart Van Assche #endif
448*44704f69SBart Van Assche         make_dev_name(fname, leadin, k, do_numeric);
449*44704f69SBart Van Assche #ifdef DEBUG
450*44704f69SBart Van Assche         printf ("Trying %s: ", fname);
451*44704f69SBart Van Assche #endif
452*44704f69SBart Van Assche 
453*44704f69SBart Van Assche         sg_fd = open(fname, O_RDONLY | O_NONBLOCK);
454*44704f69SBart Van Assche         if (sg_fd < 0) {
455*44704f69SBart Van Assche #ifdef DEBUG
456*44704f69SBart Van Assche             printf ("ERROR %i\n", errno);
457*44704f69SBart Van Assche #endif
458*44704f69SBart Van Assche             if (EBUSY == errno) {
459*44704f69SBart Van Assche                 printf("Device %s is busy\n", fname);
460*44704f69SBart Van Assche                 ++num_errors;
461*44704f69SBart Van Assche             } else if ((ENODEV == errno) || (ENXIO == errno)) {
462*44704f69SBart Van Assche                 ++num_errors;
463*44704f69SBart Van Assche                 ++num_silent;
464*44704f69SBart Van Assche             } else if (ENOENT != errno) { /* ignore ENOENT for sparse names */
465*44704f69SBart Van Assche                 snprintf(ebuff, EBUFF_SZ, "Error opening %s ", fname);
466*44704f69SBart Van Assche                 perror(ebuff);
467*44704f69SBart Van Assche                 ++num_errors;
468*44704f69SBart Van Assche             }
469*44704f69SBart Van Assche             continue;
470*44704f69SBart Van Assche         }
471*44704f69SBart Van Assche 
472*44704f69SBart Van Assche         res = ioctl(sg_fd, SCSI_IOCTL_GET_IDLUN, &my_idlun);
473*44704f69SBart Van Assche         if (res < 0) {
474*44704f69SBart Van Assche             snprintf(ebuff, EBUFF_SZ,
475*44704f69SBart Van Assche                      "device %s failed on scsi ioctl(idlun), skip", fname);
476*44704f69SBart Van Assche             perror(ebuff);
477*44704f69SBart Van Assche             ++num_errors;
478*44704f69SBart Van Assche #ifdef DEBUG
479*44704f69SBart Van Assche             printf ("Couldn't get IDLUN!\n");
480*44704f69SBart Van Assche #endif
481*44704f69SBart Van Assche             continue;
482*44704f69SBart Van Assche         }
483*44704f69SBart Van Assche         res = ioctl(sg_fd, SCSI_IOCTL_GET_BUS_NUMBER, &host_no);
484*44704f69SBart Van Assche         if (res < 0) {
485*44704f69SBart Van Assche             snprintf(ebuff, EBUFF_SZ,
486*44704f69SBart Van Assche                  "device %s failed on scsi ioctl(bus_number), skip", fname);
487*44704f69SBart Van Assche             perror(ebuff);
488*44704f69SBart Van Assche             ++num_errors;
489*44704f69SBart Van Assche #ifdef DEBUG
490*44704f69SBart Van Assche             printf ("Couldn't get BUS!\n");
491*44704f69SBart Van Assche #endif
492*44704f69SBart Van Assche             continue;
493*44704f69SBart Van Assche         }
494*44704f69SBart Van Assche #ifdef DEBUG
495*44704f69SBart Van Assche         printf ("%i(%x) %i %i %i %i\n", host_no, my_idlun.host_unique_id,
496*44704f69SBart Van Assche                 (my_idlun.dev_id>>24)&0xff, (my_idlun.dev_id>>16)&0xff,
497*44704f69SBart Van Assche                 (my_idlun.dev_id>>8)&0xff, my_idlun.dev_id&0xff);
498*44704f69SBart Van Assche #endif
499*44704f69SBart Van Assche         ind = find_dev_in_sg_arr(&my_idlun, host_no, last_sg_ind);
500*44704f69SBart Van Assche         if (ind >= 0) {
501*44704f69SBart Van Assche             map_arr[ind].oth_dev_num = k;
502*44704f69SBart Van Assche             map_arr[ind].lin_dev_type = lin_dev_type;
503*44704f69SBart Van Assche         }
504*44704f69SBart Van Assche         else
505*44704f69SBart Van Assche             printf("Strange, could not find device %s mapped to sg device??\n",
506*44704f69SBart Van Assche                    fname);
507*44704f69SBart Van Assche     }
508*44704f69SBart Van Assche }
509