1 /* @(#)scsi-linux-ata.c 1.16 13/05/28 Copyright 2002-2013 J. Schilling */
2 #ifndef lint
3 static char ata_sccsid[] =
4 "@(#)scsi-linux-ata.c 1.16 13/05/28 Copyright 2002-2013 J. Schilling";
5 #endif
6 /*
7 * Interface for Linux generic SCSI implementation (sg).
8 *
9 * This inteface is ised with dev=ATAPI:b,t,l
10 *
11 * This is the interface for the broken Linux SCSI generic driver.
12 * This is a hack, that tries to emulate the functionality
13 * of the scg driver.
14 *
15 * Warning: you may change this source, but if you do that
16 * you need to change the _scg_version and _scg_auth* string below.
17 * You may not return "schily" for an SCG_AUTHOR request anymore.
18 * Choose your name instead of "schily" and make clear that the version
19 * string is related to a modified source.
20 *
21 * Copyright (c) 2002-2013 J. Schilling
22 *
23 * Thanks to Alexander Kern <alex.kern@gmx.de> for the idea and first
24 * code fragments for supporting the CDROM_SEND_PACKET ioctl() from
25 * the cdrom.c kernel driver. Please note that this interface in priciple
26 * is completely unneeded but the Linux kernel is just a cluster of
27 * code and does not support planned orthogonal interface systems.
28 * For this reason we need CDROM_SEND_PACKET in order to work around a
29 * bug in the linux kernel that prevents to use PCATA drives because
30 * the kernel panics if you try to put ide-scsi on top of the PCATA
31 * driver.
32 */
33 /*
34 * The contents of this file are subject to the terms of the
35 * Common Development and Distribution License, Version 1.0 only
36 * (the "License"). You may not use this file except in compliance
37 * with the License.
38 *
39 * See the file CDDL.Schily.txt in this distribution for details.
40 * A copy of the CDDL is also available via the Internet at
41 * http://www.opensource.org/licenses/cddl1.txt
42 *
43 * The following exceptions apply:
44 * CDDL �3.6 needs to be replaced by: "You may create a Larger Work by
45 * combining Covered Software with other code if all other code is governed by
46 * the terms of a license that is OSI approved (see www.opensource.org) and
47 * you may distribute the Larger Work as a single product. In such a case,
48 * You must make sure the requirements of this License are fulfilled for
49 * the Covered Software."
50 *
51 * When distributing Covered Code, include this CDDL HEADER in each
52 * file and include the License file CDDL.Schily.txt from this distribution.
53 */
54
55 #ifdef USE_ATAPI
56
57 LOCAL char _scg_atrans_version[] = "scsi-linux-ata.c-1.16"; /* The version for ATAPI transport*/
58
59 LOCAL char * scgo_aversion __PR((SCSI *scgp, int what));
60 LOCAL int scgo_ahelp __PR((SCSI *scgp, FILE *f));
61 LOCAL int scgo_aopen __PR((SCSI *scgp, char *device));
62 LOCAL int scgo_aclose __PR((SCSI *scgp));
63 LOCAL long scgo_amaxdma __PR((SCSI *scgp, long amt));
64 LOCAL int scgo_anumbus __PR((SCSI *scgp));
65 LOCAL BOOL scgo_ahavebus __PR((SCSI *scgp, int));
66 LOCAL int scgo_afileno __PR((SCSI *scgp, int, int, int));
67 LOCAL int scgo_ainitiator_id __PR((SCSI *scgp));
68 LOCAL int scgo_aisatapi __PR((SCSI *scgp));
69 LOCAL int scgo_areset __PR((SCSI *scgp, int what));
70 LOCAL int scgo_asend __PR((SCSI *scgp));
71
72 LOCAL scg_ops_t atapi_ops = {
73 scgo_asend,
74 scgo_aversion,
75 scgo_ahelp,
76 scgo_aopen,
77 scgo_aclose,
78 scgo_amaxdma,
79 scgo_getbuf, /* Shared with SG driver */
80 scgo_freebuf, /* Shared with SG driver */
81 scgo_anumbus,
82 scgo_ahavebus,
83 scgo_afileno,
84 scgo_ainitiator_id,
85 scgo_aisatapi,
86 scgo_areset,
87 };
88
89 #define HOST_EMPTY 0xF
90 #define HOST_SCSI 0x0
91 #define HOST_IDE 0x1
92 #define HOST_USB 0x2
93 #define HOST_IEEE1389 0x3
94 #define HOST_PARALLEL 0x4
95 #define HOST_OTHER 0xE
96
97
98 #define typlocal(p, atapibus) scglocal(p)->bc[atapibus].typ
99 #define buslocal(p, atapibus) scglocal(p)->bc[atapibus].bus
100 #define hostlocal(p, atapibus) scglocal(p)->bc[atapibus].host
101
102 #define MAX_DMA_ATA (131072-1) /* EINVAL (hart) ENOMEM (weich) bei mehr ... */
103 /* Bei fehlerhaftem Sense Pointer kommt EFAULT */
104
105 LOCAL int scgo_send __PR((SCSI * scgp));
106 LOCAL BOOL sg_amapdev __PR((SCSI * scgp, int f, char *device, int *bus,
107 int *target, int *lun));
108 LOCAL BOOL sg_amapdev_scsi __PR((SCSI * scgp, int f, int *busp, int *tgtp,
109 int *lunp, int *chanp, int *inop));
110 LOCAL int scgo_aget_first_free_atapibus __PR((SCSI * scgp, int subsystem,
111 int host, int bus));
112 LOCAL int scgo_amerge __PR((char *path, char *readedlink,
113 char *buffer, int buflen));
114
115 /*
116 * uncomment this when you will get a debug file #define DEBUG
117 */
118 #ifdef DEBUG
119 #define LOGFILE "scsi-linux-ata.log"
120 #define log(a) sglog a
121
122 LOCAL void sglog __PR((const char *fmt, ...));
123
124 #include <schily/varargs.h>
125
126 /* VARARGS1 */
127 #ifdef PROTOTYPES
128 LOCAL void
sglog(const char * fmt,...)129 sglog(const char *fmt, ...)
130 #else
131 LOCAL void
132 error(fmt, va_alist)
133 char *fmt;
134 va_dcl
135 #endif
136 {
137 va_list args;
138 FILE *f = fopen(LOGFILE, "a");
139
140 if (f == NULL)
141 return;
142
143 #ifdef PROTOTYPES
144 va_start(args, fmt);
145 #else
146 va_start(args);
147 #endif
148 js_fprintf(f, "%r", fmt, args);
149 va_end(args);
150 fclose(f);
151 }
152 #else
153 #define log(a)
154 #endif /* DEBUG */
155
156 LOCAL int scan_internal __PR((SCSI * scgp, int *fatal));
157
158 /*
159 * Return version information for the low level SCSI transport code.
160 * This has been introduced to make it easier to trace down problems
161 * in applications.
162 */
163 LOCAL char *
scgo_aversion(scgp,what)164 scgo_aversion(scgp, what)
165 SCSI *scgp;
166 int what;
167 {
168 if (scgp != (SCSI *)0) {
169 switch (what) {
170
171 case SCG_VERSION:
172 return (_scg_atrans_version);
173 /*
174 * If you changed this source, you are not allowed to
175 * return "schily" for the SCG_AUTHOR request.
176 */
177 case SCG_AUTHOR:
178 return (_scg_auth_schily);
179 case SCG_SCCS_ID:
180 return (ata_sccsid);
181 }
182 }
183 return ((char *)0);
184 }
185
186 LOCAL int
scgo_ahelp(scgp,f)187 scgo_ahelp(scgp, f)
188 SCSI *scgp;
189 FILE *f;
190 {
191 __scg_help(f, "ATA", "ATA Packet specific SCSI transport",
192 "ATAPI:", "bus,target,lun", "ATAPI:1,2,0", TRUE, FALSE);
193 return (0);
194 }
195
196 LOCAL int
scgo_aopen(scgp,device)197 scgo_aopen(scgp, device)
198 SCSI *scgp;
199 char *device;
200 {
201 int bus = scg_scsibus(scgp);
202 int target = scg_target(scgp);
203 int lun = scg_lun(scgp);
204
205 register int f;
206 register int b;
207 register int t;
208 register int l;
209 int nopen = 0;
210
211 if (scgp->overbose) {
212 error("Warning: dev=ATA: is preferred over dev=ATAPI:.\n");
213 error("Warning: Using ATA Packet interface.\n");
214 }
215 if (scgp->overbose) {
216 error("Warning: The related Linux kernel interface code seems to be unmaintained.\n");
217 error("Warning: There is absolutely NO DMA, operations thus are slow.\n");
218 }
219
220 log(("\n<<<<<<<<<<<<<<<< LOGGING ON >>>>>>>>>>>>>>>>>\n"));
221 if (bus >= MAX_ATAPI_HOSTS || target >= MAX_TGT || lun >= MAX_LUN) {
222 errno = EINVAL;
223 if (scgp->errstr)
224 js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
225 "Illegal value for bus, target or lun '%d,%d,%d'",
226 bus, target, lun);
227
228 return (-1);
229 }
230
231 if (scgp->local == NULL) {
232 scgp->local = malloc(sizeof (struct scg_local));
233 if (scgp->local == NULL) {
234 return (0);
235 }
236
237 scglocal(scgp)->scgfile = -1;
238 scglocal(scgp)->pgbus = -2;
239 scglocal(scgp)->SCSIbuf = (char *)-1;
240 scglocal(scgp)->pack_id = 5;
241 scglocal(scgp)->drvers = -1;
242 scglocal(scgp)->isold = -1;
243 scglocal(scgp)->xbufsize = 0L;
244 scglocal(scgp)->xbuf = NULL;
245
246
247 for (b = 0; b < MAX_ATAPI_HOSTS; b++) {
248 typlocal(scgp, b) = HOST_EMPTY;
249 for (t = 0; t < MAX_TGT; t++) {
250 for (l = 0; l < MAX_LUN; l++)
251 scglocal(scgp)->scgfiles[b][t][l] = (short) -1;
252 }
253 }
254 }
255
256 if (device != NULL && strcmp(device, "ATAPI") == 0)
257 goto atascan;
258
259 /* if not scanning */
260 if ((device != NULL && *device != '\0') || (bus == -2 && target == -2))
261 goto openbydev;
262
263 atascan:
264 if (scan_internal(scgp, &nopen)) {
265 if (scgp->errstr)
266 js_printf(scgp->errstr, "INFO: scan_internal(...) failed");
267 return (-1);
268 }
269 return (nopen);
270
271 openbydev:
272 if (device != NULL && strncmp(device, "ATAPI:", 6) == 0)
273 device += 6;
274 if (scgp->debug > 3) {
275 js_fprintf((FILE *) scgp->errfile, "INFO: do scgo_open openbydev");
276 }
277 if (device != NULL && *device != '\0') {
278 int atapi_bus,
279 starget,
280 slun;
281
282 f = open(device, O_RDONLY | O_NONBLOCK);
283
284 if (f < 0) {
285 if (scgp->errstr)
286 js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
287 "Cannot open '%s'", device);
288 return (0);
289 }
290 if (sg_amapdev(scgp, f, device, &atapi_bus, &starget, &slun)) {
291 scg_settarget(scgp, atapi_bus, starget, slun);
292 return (++nopen);
293 }
294 }
295 return (nopen);
296 }
297
298 LOCAL int
scan_internal(scgp,nopen)299 scan_internal(scgp, nopen)
300 SCSI *scgp;
301 int *nopen;
302 {
303 int i,
304 f;
305 int atapi_bus,
306 target,
307 lun;
308 char device[128];
309 /*
310 * try always with devfs
311 * unfortunatelly the solution with test of existing
312 * of '/dev/.devfsd' don't work, because it root.root 700
313 * and i don't like run suid root
314 */
315 BOOL DEVFS = TRUE;
316
317 if (DEVFS) {
318 for (i = 0; ; i++) {
319 sprintf(device, "/dev/cdroms/cdrom%i", i);
320 if ((f = open(device, O_RDONLY | O_NONBLOCK)) < 0) {
321 if (errno != ENOENT && errno != ENXIO && errno != ENODEV && errno != EACCES) {
322 if (scgp->debug > 4) {
323 js_fprintf((FILE *) scgp->errfile,
324 "try open(%s) return %i, errno %i, cancel\n", device, f, errno);
325 }
326 return (-2);
327 } else if (errno == ENOENT || errno == ENODEV) {
328 if (scgp->debug > 4) {
329 js_fprintf((FILE *) scgp->errfile,
330 "try open(%s) return %i, errno %i\n", device, f, errno);
331 }
332 if (0 == i) {
333 DEVFS = FALSE;
334 if (scgp->debug > 4) {
335 js_fprintf((FILE *) scgp->errfile,
336 "DEVFS not detected, continuing with old dev\n");
337 }
338 }
339 break;
340 }
341 if (scgp->debug > 4) {
342 if (errno == EACCES) {
343 js_fprintf((FILE *) scgp->errfile,
344 "errno (EACCESS), you don't have the needed rights for %s\n",
345 device);
346 }
347 js_fprintf((FILE *) scgp->errfile,
348 "try open(%s) return %i, errno %i, trying next cdrom\n",
349 device, f, errno);
350 }
351 } else {
352 if (scgp->debug > 4) {
353 js_fprintf((FILE *) scgp->errfile,
354 "try open(%s) return %i errno %i calling sg_mapdev(...)\n",
355 device, f, errno);
356 }
357 if (sg_amapdev(scgp, f, device, &atapi_bus, &target, &lun)) {
358 (++(*nopen));
359 } else {
360 close(f);
361 }
362 }
363 }
364 }
365 if (!DEVFS) {
366 /* for /dev/sr0 - /dev/sr? */
367 for (i = 0; ; i++) {
368 sprintf(device, "/dev/sr%i", i);
369 if ((f = open(device, O_RDONLY | O_NONBLOCK)) < 0) {
370 if (errno != ENOENT && errno != ENXIO && errno != ENODEV && errno != EACCES) {
371 if (scgp->debug > 4) {
372 js_fprintf((FILE *) scgp->errfile,
373 "try open(%s) return %i, errno %i, cancel\n",
374 device, f, errno);
375 }
376 return (-2);
377 } else if (errno == ENOENT || errno == ENODEV) {
378 break;
379 }
380 } else {
381 if (sg_amapdev(scgp, f, device, &atapi_bus, &target, &lun)) {
382 (++(*nopen));
383 } else {
384 close(f);
385 }
386 }
387 }
388
389 /* for /dev/hda - /dev/hdz */
390 for (i = 'a'; i <= 'z'; i++) {
391 sprintf(device, "/dev/hd%c", i);
392 if ((f = open(device, O_RDONLY | O_NONBLOCK)) < 0) {
393 if (errno != ENOENT && errno != ENXIO && errno != EACCES) {
394 if (scgp->debug > 4) {
395 js_fprintf((FILE *) scgp->errfile,
396 "try open(%s) return %i, errno %i, cancel\n",
397 device, f, errno);
398 }
399 return (-2);
400 } else if (errno == ENOENT || errno == ENODEV) {
401 break;
402 }
403 } else {
404 /* ugly hack, make better, when you can. Alex */
405 if (0 > ioctl(f, CDROM_DRIVE_STATUS, CDSL_CURRENT)) {
406 if (scgp->debug > 4) {
407 js_fprintf((FILE *) scgp->errfile,
408 "%s is not a cdrom, skipping\n",
409 device);
410 }
411 close(f);
412 } else if (sg_amapdev(scgp, f, device, &atapi_bus, &target, &lun)) {
413 (++(*nopen));
414 } else {
415 close(f);
416 }
417 }
418 }
419 }
420 return (0);
421 }
422
423 LOCAL int
scgo_aclose(scgp)424 scgo_aclose(scgp)
425 SCSI *scgp;
426 {
427 register int f;
428 register int h;
429 register int t;
430 register int l;
431
432 if (scgp->local == NULL)
433 return (-1);
434
435 for (h = 0; h < MAX_ATAPI_HOSTS; h++) {
436 typlocal(scgp, h) = (HOST_EMPTY);
437 for (t = 0; t < MAX_TGT; t++) {
438 for (l = 0; l < MAX_LUN; l++) {
439 f = scglocal(scgp)->scgfiles[h][t][l];
440 if (f >= 0)
441 close(f);
442 scglocal(scgp)->scgfiles[h][t][l] = (short) -1;
443 }
444 }
445 }
446
447 if (scglocal(scgp)->xbuf != NULL) {
448 free(scglocal(scgp)->xbuf);
449 scglocal(scgp)->xbufsize = 0L;
450 scglocal(scgp)->xbuf = NULL;
451 }
452 log(("<<<<<<<<<<<<<<<< LOGGING OFF >>>>>>>>>>>>>>>>>\n\n"));
453 return (0);
454 }
455
456 LOCAL int
scgo_aget_first_free_atapibus(scgp,subsystem,host,bus)457 scgo_aget_first_free_atapibus(scgp, subsystem, host, bus)
458 SCSI *scgp;
459 int subsystem;
460 int host;
461 int bus;
462 {
463 int first_free_atapi_bus;
464
465 for (first_free_atapi_bus = 0;
466 first_free_atapi_bus < MAX_ATAPI_HOSTS;
467 first_free_atapi_bus++) {
468
469 if (typlocal(scgp, first_free_atapi_bus) == HOST_EMPTY ||
470 (typlocal(scgp, first_free_atapi_bus) == subsystem &&
471 hostlocal(scgp, first_free_atapi_bus) == host &&
472 buslocal(scgp, first_free_atapi_bus) == bus))
473 break;
474 }
475
476 if (first_free_atapi_bus >= MAX_ATAPI_HOSTS) {
477 errmsgno(EX_BAD, "ERROR: in scgo_get_first_free_atapibus(...). Too many CDROMs, more than %i",
478 MAX_ATAPI_HOSTS);
479 errmsgno(EX_BAD, "Increase MAX_ATAPI_HOSTS in scsi-linux-ata.c and recompile!");
480 return (-1);
481 }
482 return (first_free_atapi_bus);
483 }
484
485 LOCAL int
scgo_amerge(path,readedlink,buffer,buflen)486 scgo_amerge(path, readedlink, buffer, buflen)
487 char *path;
488 char *readedlink;
489 char *buffer;
490 int buflen;
491 {
492 char *aa;
493
494 #define TOKEN_ARRAY 20
495 #define LAST_CHAR(x) (x)[strlen((x))-1]
496 #define ONE_CHAR_BACK(x) (x)[strlen((x))-1] = '\0'
497 char *ppa[TOKEN_ARRAY];
498 char *pa;
499
500 int i;
501 int len;
502 char seps[] = "/";
503 char *last_slash;
504
505 if (!path || !readedlink || !buffer)
506 return (-EINVAL);
507
508 if ('/' == readedlink[0]) {
509 aa = (char *) malloc(strlen(readedlink) + 1);
510 if (!aa)
511 return (-ENOMEM);
512
513 strcpy(aa, readedlink);
514 } else {
515 aa = (char *) malloc(strlen(path) + strlen(readedlink) + 1);
516 if (!aa)
517 return (-ENOMEM);
518
519 strcpy(aa, path);
520 if (LAST_CHAR(aa) == '/') {
521 ONE_CHAR_BACK(aa);
522 }
523 last_slash = strrchr(aa, '/');
524 if (last_slash == NULL)
525 strcpy(aa, "/");
526 else
527 *(++last_slash) = '\0';
528 strcat(aa, readedlink);
529 }
530 memset(ppa, 0x00, sizeof (ppa));
531
532 for (i = 0, pa = strtok(aa, seps);
533 i < TOKEN_ARRAY && pa != NULL;
534 ++i, pa = strtok(NULL, seps)) {
535 ppa[i] = pa;
536 }
537
538 if (i == TOKEN_ARRAY) {
539 free(aa);
540 return (-ENOMEM);
541 }
542 for (i = 0; i < TOKEN_ARRAY && ppa[i]; i++) {
543 if (strcmp(ppa[i], "..") == 0) {
544 ppa[i] = NULL;
545 if (i > 1)
546 ppa[i - 1] = NULL;
547 }
548 }
549
550 /* dry run */
551 len = 0;
552 for (i = 0; i < TOKEN_ARRAY; i++) {
553 if (ppa[i]) {
554 len += 1;
555 len += strlen(ppa[i]);
556 }
557 }
558 if (0 == len)
559 len = 1;
560
561 if (len + 1 <= buflen) {
562 strcpy(buffer, "");
563 for (i = 0; i < TOKEN_ARRAY; i++) {
564 if (ppa[i]) {
565 strcat(buffer, "/");
566 strcat(buffer, ppa[i]);
567 }
568 }
569
570 if (strlen(buffer) == 0)
571 strcpy(buffer, "/");
572 }
573 free(aa);
574
575 return (len + 1);
576 }
577
578 /*
579 * /dev/cdroms/cdrom0 first CD-ROM
580 * /dev/cdroms/cdrom1 second CD-ROM
581 *
582 *
583 * SCSI Devices
584 *
585 * To uniquely identify any SCSI device requires the following information:
586 *
587 * controller (host adapter)
588 * bus (SCSI channel)
589 * target (SCSI ID)
590 * unit (Logical Unit Number)
591 *
592 * All SCSI devices are placed under /dev/scsi (assuming devfs is mounted on /dev).
593 * Hence, a SCSI device with the following parameters:
594 * c=1,b=2,t=3,u=4 would appear as:
595 *
596 * /dev/scsi/host1/bus2/target3/lun4 device directory
597 *
598 * Inside this directory, a number of device entries may be created,
599 * depending on which SCSI device-type drivers were installed.
600 *
601 * See the section on the disc naming scheme to see what entries
602 * the SCSI disc driver creates.
603 *
604 * See the section on the tape naming scheme to see what entries
605 * the SCSI tape driver creates.
606 *
607 * The SCSI CD-ROM driver creates: cd
608 * The SCSI generic driver creates: generic
609 *
610 * IDE Devices
611 *
612 * To uniquely identify any IDE device requires the following information:
613 *
614 * controller
615 * bus (0/1 aka. primary/secondary)
616 * target (0/1 aka. master/slave)
617 * unit
618 *
619 * All IDE devices are placed under /dev/ide, and uses a similar
620 * naming scheme to the SCSI subsystem.
621 *
622 *
623 * Example /dev/cdroms/cdrom0 -> /dev/scsi/host1/bus2/target3/lun4/cd
624 * Example /dev/cdroms/cdrom1 -> /dev/ide/host1/bus0/target1/lun4/cd
625 *
626 */
627 LOCAL BOOL
sg_amapdev(scgp,f,device,atapibus,target,lun)628 sg_amapdev(scgp, f, device, atapibus, target, lun)
629 SCSI *scgp;
630 int f;
631 char *device;
632 int *atapibus;
633 int *target;
634 int *lun;
635 {
636 struct host {
637 char host[4];
638 char host_no;
639 };
640 struct bus {
641 char bus[3];
642 char bus_no;
643 };
644 struct target {
645 char target[6];
646 char target_no;
647 };
648 struct lun {
649 char lun[3];
650 char lun_no;
651 };
652
653 int h,
654 b,
655 t,
656 l;
657
658 #define TOKEN_DEV "dev"
659 #define TOKEN_SUBSYSTEM_SCSI "scsi"
660 #define TOKEN_SUBSYSTEM_IDE "ide"
661 #define TOKEN_HOST "host"
662 #define TOKEN_BUS "bus"
663 #define TOKEN_TARGET "target"
664 #define TOKEN_LUN "lun"
665 #define TOKEN_CD "cd"
666
667 #define ID_TOKEN_DEV 0
668 #define ID_TOKEN_SUBSYSTEM 1
669 #define ID_TOKEN_HOST 2
670 #define ID_TOKEN_BUS 3
671 #define ID_TOKEN_TARGET 4
672 #define ID_TOKEN_LUN 5
673 #define ID_TOKEN_CD 6
674 #define ID_TOKEN_LAST ID_TOKEN_CD
675 #define ID_TOKEN_MAX ID_TOKEN_LAST + 2
676 #define CHARTOINT(x) (abs(atoi(&x)))
677
678 char *token[ID_TOKEN_MAX],
679 *seps = "/";
680 int i,
681 result;
682 struct stat buf;
683
684 #ifndef MAX_PATH
685 #define MAX_PATH 260
686 #endif
687 #define LOCAL_MAX_PATH MAX_PATH
688 char tmp[LOCAL_MAX_PATH],
689 tmp1[LOCAL_MAX_PATH];
690 int first_free_atapi_bus;
691 int subsystem = HOST_EMPTY;
692
693 /* old DEV */
694 typedef struct {
695 char prefix[2];
696 char device;
697 } old_dev;
698 /* strtok need char* instead of const char* */
699 result = stat(device, &buf);
700 if (result || !S_ISBLK(buf.st_mode))
701 return (FALSE);
702
703 result = lstat(device, &buf);
704 if (!result && S_ISLNK(buf.st_mode)) {
705 result = readlink(device, tmp, LOCAL_MAX_PATH);
706 if (result > 0 && result < LOCAL_MAX_PATH) {
707 tmp[result] = '\0';
708
709 result = scgo_amerge(device, tmp, tmp1, LOCAL_MAX_PATH);
710 if (result > 0 && result < LOCAL_MAX_PATH) {
711 tmp1[result] = '\0';
712 strcpy(tmp, tmp1);
713 } else {
714 errmsgno(EX_BAD,
715 "ERROR: with link merging! base %s link %s, result of merging %i\n",
716 device, tmp, result);
717 return (FALSE);
718 }
719 } else {
720 errmsgno(EX_BAD,
721 "ERROR: with link reading! link %s, result of readlink %i\n",
722 device, result);
723 return (FALSE);
724 }
725 } else {
726 strncpy(tmp, device, sizeof (tmp));
727 }
728 if (scgp->debug > 3) {
729 js_fprintf((FILE *) scgp->errfile, "INFO: %s -> %s\n", device, tmp);
730 }
731 memset(token, 0x00, sizeof (token));
732 i = 0;
733 token[i] = strtok(tmp, seps);
734 while (token[i] != NULL && (++i) && i < ID_TOKEN_MAX) {
735 token[i] = strtok(NULL, seps);
736 }
737
738 if (i == ID_TOKEN_MAX ||
739 !(token[ID_TOKEN_DEV]) ||
740 strcmp(token[ID_TOKEN_DEV], TOKEN_DEV)) {
741
742 errmsgno(EX_BAD, "ERROR: unknow format\n");
743 errmsgno(EX_BAD, "EXAMPLE: /dev/scsi/host1/bus2/target3/lun4/cd\n");
744 errmsgno(EX_BAD, "EXAMPLE: /dev/ide/host0/bus0/target1/lun0/cd\n");
745 errmsgno(EX_BAD, "EXAMPLE: /dev/hda or /dev/sr0\n");
746 return (FALSE);
747 }
748 if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_SCSI)) ||
749 !(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_IDE))) {
750 h = CHARTOINT(((struct host *) token[ID_TOKEN_HOST])->host_no);
751 b = CHARTOINT(((struct bus *) token[ID_TOKEN_BUS])->bus_no);
752 t = CHARTOINT(((struct target *) token[ID_TOKEN_TARGET])->target_no);
753 l = CHARTOINT(((struct lun *) token[ID_TOKEN_LUN])->lun_no);
754 #ifdef PARANOID
755 if (strncmp(token[ID_TOKEN_HOST], TOKEN_HOST, strlen(TOKEN_HOST))) {
756 log(("ERROR: invalid host specified\n"));
757 return (FALSE);
758 }
759 if (strncmp(token[ID_TOKEN_BUS], TOKEN_BUS, strlen(TOKEN_BUS))) {
760 log(("ERROR: invalid bus specified\n"));
761 return (FALSE);
762 }
763 if (strncmp(token[ID_TOKEN_TARGET], TOKEN_TARGET, strlen(TOKEN_TARGET))) {
764 log(("ERROR: invalid target specified\n"));
765 return (FALSE);
766 }
767 if (strncmp(token[ID_TOKEN_LUN], TOKEN_LUN, strlen(TOKEN_LUN))) {
768 log(("ERROR: invalid lun specified\n"));
769 return (FALSE);
770 }
771 if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_IDE))) {
772 if (b > 1 || t > 1) {
773 log(("ERROR: invalid bus or target for IDE specified\n"));
774 return (FALSE);
775 }
776 }
777 #endif /* PARANOID */
778
779 if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_IDE))) {
780 subsystem = HOST_IDE;
781 } else if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_SCSI))) {
782 subsystem = HOST_SCSI;
783 } else {
784 subsystem = HOST_OTHER;
785 }
786 } else if (!token[ID_TOKEN_HOST] &&
787 strlen(token[ID_TOKEN_SUBSYSTEM]) == sizeof (old_dev)) {
788 char j;
789
790 old_dev *pDev = (old_dev *) token[ID_TOKEN_SUBSYSTEM];
791
792 if (strncmp(pDev->prefix, "hd", 2) == 0) {
793 j = pDev->device - ('a');
794
795 subsystem = HOST_IDE;
796 h = j / 4;
797 b = (j % 4) / 2;
798 t = (j % 4) % 2;
799 l = 0;
800 } else if (strncmp(pDev->prefix, "sr", 2) == 0) {
801 #ifdef nonono
802 if (pDev->device >= '0' && pDev->device <= '9')
803 j = pDev->device - ('0');
804 else
805 j = pDev->device - ('a');
806
807
808 h = j / 4;
809 b = (j % 4) / 2;
810 t = (j % 4) % 2;
811 l = 0;
812 #endif /* nonono */
813 /* other solution, with ioctl */
814 int Chan = -1,
815 Ino = -1,
816 Bus = -1,
817 Target = -1,
818 Lun = -1;
819
820 subsystem = HOST_SCSI;
821 sg_amapdev_scsi(scgp, f, &Bus, &Target, &Lun, &Chan, &Ino);
822
823 /* For old kernels try to make the best guess. */
824 #ifdef nonono
825 int n;
826 Ino |= Chan << 8;
827 n = sg_mapbus(scgp, Bus, Ino);
828 if (Bus == -1) {
829 Bus = n;
830 if (scgp->debug > 0) {
831 js_fprintf((FILE *)scgp->errfile,
832 "SCSI Bus: %d (mapped from %d)\n",
833 Bus, Ino);
834 }
835 }
836 /* It is me too high ;-()*/
837 #endif /* nonono */
838 h = Ino;
839 b = Chan;
840 t = Target;
841 l = Lun;
842 } else {
843 errmsgno(EX_BAD, "ERROR: unknow subsystem (%s) in (%s)\n",
844 token[ID_TOKEN_SUBSYSTEM], device);
845 return (FALSE);
846 }
847 } else {
848 errmsgno(EX_BAD, "ERROR: unknow subsystem (%s) in (%s)\n",
849 token[ID_TOKEN_SUBSYSTEM], device);
850 return (FALSE);
851 }
852
853 if (scgp->verbose)
854 js_printf(scgp->errstr, "INFO: subsystem %s: h %i, b %i, t %i, l %i",
855 token[ID_TOKEN_SUBSYSTEM], h, b, t, l);
856
857 first_free_atapi_bus = scgo_aget_first_free_atapibus(scgp, subsystem, h, b);
858 if (-1 == first_free_atapi_bus) {
859 return (FALSE);
860 }
861 if (scglocal(scgp)->scgfiles[first_free_atapi_bus][t][l] != (-1)) {
862 errmsgno(EX_BAD, "ERROR: this cdrom is already mapped %s(%d,%d,%d)\n",
863 device, first_free_atapi_bus, t, l);
864 return (FALSE);
865 } else {
866 scglocal(scgp)->scgfiles[first_free_atapi_bus][t][l] = f;
867 typlocal(scgp, first_free_atapi_bus) = subsystem;
868 hostlocal(scgp, first_free_atapi_bus) = h;
869 buslocal(scgp, first_free_atapi_bus) = b;
870 *atapibus = first_free_atapi_bus;
871 *target = t;
872 *lun = l;
873
874 if (scgp->debug > 1) {
875 js_fprintf((FILE *) scgp->errfile,
876 "INFO: /dev/%s, (host%d/bus%d/target%d/lun%d) will be mapped on the atapi bus No %d (%d,%d,%d)\n",
877 token[ID_TOKEN_SUBSYSTEM], h, b, t, l,
878 first_free_atapi_bus, first_free_atapi_bus, t, l);
879 }
880 }
881 return (TRUE);
882 }
883
884 LOCAL BOOL
sg_amapdev_scsi(scgp,f,busp,tgtp,lunp,chanp,inop)885 sg_amapdev_scsi(scgp, f, busp, tgtp, lunp, chanp, inop)
886 SCSI *scgp;
887 int f;
888 int *busp;
889 int *tgtp;
890 int *lunp;
891 int *chanp;
892 int *inop;
893 {
894 struct sg_id {
895 long l1; /* target | lun << 8 | channel << 16 | low_ino << 24 */
896 long l2; /* Unique id */
897 } sg_id;
898 int Chan;
899 int Ino;
900 int Bus;
901 int Target;
902 int Lun;
903
904 if (ioctl(f, SCSI_IOCTL_GET_IDLUN, &sg_id))
905 return (FALSE);
906
907 if (scgp->debug > 0) {
908 js_fprintf((FILE *) scgp->errfile,
909 "INFO: l1: 0x%lX l2: 0x%lX\n", sg_id.l1, sg_id.l2);
910 }
911 if (ioctl(f, SCSI_IOCTL_GET_BUS_NUMBER, &Bus) < 0) {
912 Bus = -1;
913 }
914 Target = sg_id.l1 & 0xFF;
915 Lun = (sg_id.l1 >> 8) & 0xFF;
916 Chan = (sg_id.l1 >> 16) & 0xFF;
917 Ino = (sg_id.l1 >> 24) & 0xFF;
918 if (scgp->debug > 0) {
919 js_fprintf((FILE *) scgp->errfile,
920 "INFO: Bus: %d Target: %d Lun: %d Chan: %d Ino: %d\n",
921 Bus, Target, Lun, Chan, Ino);
922 }
923 *busp = Bus;
924 *tgtp = Target;
925 *lunp = Lun;
926 if (chanp)
927 *chanp = Chan;
928 if (inop)
929 *inop = Ino;
930 return (TRUE);
931 }
932
933 LOCAL long
scgo_amaxdma(scgp,amt)934 scgo_amaxdma(scgp, amt)
935 SCSI *scgp;
936 long amt;
937 {
938 /*
939 * EINVAL (hart) ENOMEM (weich) bei mehr ...
940 * Bei fehlerhaftem Sense Pointer kommt EFAULT
941 */
942 return (MAX_DMA_ATA);
943 }
944
945 LOCAL int
scgo_anumbus(scgp)946 scgo_anumbus(scgp)
947 SCSI *scgp;
948 {
949 return (MAX_ATAPI_HOSTS);
950 }
951
952 LOCAL BOOL
scgo_ahavebus(scgp,busno)953 scgo_ahavebus(scgp, busno)
954 SCSI *scgp;
955 int busno;
956 {
957 register int t;
958 register int l;
959
960 if (busno < 0 || busno >= MAX_ATAPI_HOSTS)
961 return (FALSE);
962
963 if (scgp->local == NULL)
964 return (FALSE);
965
966 for (t = 0; t < MAX_TGT; t++) {
967 for (l = 0; l < MAX_LUN; l++)
968 if (scglocal(scgp)->scgfiles[busno][t][l] >= 0)
969 return (TRUE);
970 }
971 return (FALSE);
972 }
973
974 LOCAL int
scgo_afileno(scgp,busno,tgt,tlun)975 scgo_afileno(scgp, busno, tgt, tlun)
976 SCSI *scgp;
977 int busno;
978 int tgt;
979 int tlun;
980 {
981 if (busno < 0 || busno >= MAX_ATAPI_HOSTS ||
982 tgt < 0 || tgt >= MAX_TGT ||
983 tlun < 0 || tlun >= MAX_LUN)
984 return (-1);
985
986 if (scgp->local == NULL)
987 return (-1);
988
989 return ((int) scglocal(scgp)->scgfiles[busno][tgt][tlun]);
990 }
991
992 LOCAL int
scgo_ainitiator_id(scgp)993 scgo_ainitiator_id(scgp)
994 SCSI *scgp;
995 {
996 js_printf(scgp->errstr, "NOT IMPELEMENTED: scgo_initiator_id");
997 return (-1);
998 }
999
1000 LOCAL int
scgo_aisatapi(scgp)1001 scgo_aisatapi(scgp)
1002 SCSI *scgp;
1003 {
1004 int atapibus = scgp->addr.scsibus;
1005 int typ = typlocal(scgp, atapibus);
1006 if (typ == HOST_EMPTY)
1007 return (-1);
1008 if (typ != HOST_SCSI)
1009 return (1);
1010 else
1011 return (0);
1012 }
1013
1014 LOCAL int
scgo_areset(scgp,what)1015 scgo_areset(scgp, what)
1016 SCSI *scgp;
1017 int what;
1018 {
1019 if (what == SCG_RESET_NOP)
1020 return (0);
1021
1022 if (what == SCG_RESET_TGT || what == SCG_RESET_BUS)
1023 return (ioctl(what, CDROMRESET));
1024
1025 return (-1);
1026 }
1027
1028 LOCAL int
scgo_asend(scgp)1029 scgo_asend(scgp)
1030 SCSI *scgp;
1031 {
1032 struct scg_cmd *sp = scgp->scmd;
1033 int ret,
1034 i;
1035 struct cdrom_generic_command sg_cgc;
1036 struct request_sense sense_cgc;
1037 static uid_t cureuid = 0; /* XXX Hack until we have uid management */
1038
1039 #ifdef DEBUG
1040 char tmp_send[340],
1041 tmp_read[340],
1042 tmp_sense[340],
1043 tmp1[30];
1044 int j;
1045 char *p;
1046 #endif
1047
1048 if (scgp->fd < 0) {
1049 sp->error = SCG_FATAL;
1050 sp->ux_errno = EIO;
1051 return (0);
1052 }
1053 if (sp->cdb_len > CDROM_PACKET_SIZE) {
1054 sp->error = SCG_FATAL;
1055 sp->ux_errno = EIO;
1056 return (0);
1057 }
1058 /* initialize */
1059 fillbytes((caddr_t) & sg_cgc, sizeof (sg_cgc), '\0');
1060 fillbytes((caddr_t) & sense_cgc, sizeof (sense_cgc), '\0');
1061
1062 if (sp->flags & SCG_RECV_DATA) {
1063 sg_cgc.data_direction = CGC_DATA_READ;
1064 } else if (sp->size > 0) {
1065 sg_cgc.data_direction = CGC_DATA_WRITE;
1066 } else {
1067 sg_cgc.data_direction = CGC_DATA_NONE;
1068 }
1069 #if LINUX_VERSION_CODE >= 0x020403
1070 if (sp->flags & SCG_SILENT) {
1071 sg_cgc.quiet = 1;
1072 }
1073 #endif
1074 for (i = 0; i < sp->cdb_len; i++) {
1075 sg_cgc.cmd[i] = sp->cdb.cmd_cdb[i];
1076 }
1077
1078 sg_cgc.buflen = sp->size;
1079 sg_cgc.buffer = (void *)sp->addr; /* Workaround silly type in sg_cgc */
1080
1081 if (sp->sense_len > sizeof (sense_cgc))
1082 sense_cgc.add_sense_len = sizeof (sense_cgc) - 8;
1083 else
1084 sense_cgc.add_sense_len = sp->sense_len - 8;
1085
1086 sg_cgc.sense = &sense_cgc;
1087 #if LINUX_VERSION_CODE >= 0x020403
1088 sg_cgc.timeout = sp->timeout * 1000;
1089 #endif
1090 #ifdef DEBUG
1091 strcpy(tmp_send, "send cmd:\n");
1092 for (j = 0; j < sp->cdb_len; j++) {
1093 sprintf(tmp1, " %02X", sp->cdb.cmd_cdb[j]);
1094 strcat(tmp_send, tmp1);
1095 }
1096 strcat(tmp_send, "\n");
1097
1098 if (sg_cgc.data_direction == CGC_DATA_WRITE) {
1099 int z;
1100
1101 sprintf(tmp1, "data_write: %i bytes\n", sp->size);
1102 strcat(tmp_send, tmp1);
1103 for (j = 0, z = 1; j < 80 && j < sp->size; j++, z++) {
1104 if (z > 16) {
1105 z = 1;
1106 strcat(tmp_send, "\n");
1107 }
1108 sprintf(tmp1, " %02X", (unsigned char) (sp->addr[j]));
1109 strcat(tmp_send, tmp1);
1110 }
1111 strcat(tmp_send, "\n");
1112
1113 if (sp->size > 80) {
1114 strcat(tmp_send, "...\n");
1115 }
1116 }
1117 #endif /* DEBUG */
1118
1119 if (cureuid != 0)
1120 seteuid(0);
1121 again:
1122 errno = 0;
1123 if ((ret = ioctl(scgp->fd, CDROM_SEND_PACKET, &sg_cgc)) < 0)
1124 sp->ux_errno = geterrno();
1125 if (ret < 0 && geterrno() == EPERM) { /* XXX Hack until we have uid management */
1126 cureuid = geteuid();
1127 if (seteuid(0) >= 0)
1128 goto again;
1129 }
1130 if (cureuid != 0)
1131 seteuid(cureuid);
1132
1133 if (ret < 0 && scgp->debug > 4) {
1134 js_fprintf((FILE *) scgp->errfile,
1135 "ioctl(CDROM_SEND_PACKET) ret: %d\n", ret);
1136 }
1137 /*
1138 * copy scsi data back
1139 */
1140 if (sp->flags & SCG_RECV_DATA && ((void *) sp->addr != (void *) sg_cgc.buffer)) {
1141 memcpy(sp->addr, sg_cgc.buffer, (sp->size < sg_cgc.buflen) ? sp->size : sg_cgc.buflen);
1142 if (sg_cgc.buflen > sp->size)
1143 sp->resid = sg_cgc.buflen - sp->size;
1144 }
1145 sp->error = SCG_NO_ERROR;
1146 #ifdef DEBUG
1147 if (ret < 0) {
1148 switch (sp->ux_errno) {
1149 case ENOTTY:
1150 p = "ENOTTY";
1151 break;
1152 case EINVAL:
1153 p = "EINVAL";
1154 break;
1155 case ENXIO:
1156 p = "ENXIO";
1157 break;
1158 case EPERM:
1159 p = "EPERM";
1160 break;
1161 case EACCES:
1162 p = "EACCES";
1163 break;
1164 case EIO:
1165 p = "EIO";
1166 break;
1167 case ENOMEDIUM:
1168 p = "ENOMEDIUM";
1169 break;
1170 case EDRIVE_CANT_DO_THIS:
1171 p = "EDRIVE_CANT_DO_THIS";
1172 break;
1173 default:
1174 p = "UNKNOW";
1175 };
1176 log(("%s", tmp_send));
1177 log(("ERROR: returns %i errno %i(%s)\n", ret, sp->ux_errno, p));
1178 }
1179 #endif /* DEBUG */
1180 if (ret < 0) {
1181 /*
1182 * Check if SCSI command could not be send at all.
1183 * Linux usually returns EINVAL for an unknown ioctl.
1184 * In case somebody from the Linux kernel team learns that the
1185 * corect errno would be ENOTTY, we check for this errno too.
1186 */
1187 if (sp->ux_errno == EINVAL) {
1188 /*
1189 * Try to work around broken Linux kernel design...
1190 * If SCSI Sense Key is 0x05 (Illegal request), Linux
1191 * returns a useless EINVAL making it close to
1192 * impossible distinct from "Illegal ioctl()" or
1193 * "Invalid parameter".
1194 */
1195 if ((((Uchar *)sg_cgc.sense)[0] != 0) ||
1196 (((Uchar *)sg_cgc.sense)[2] != 0))
1197 sp->ux_errno = EIO;
1198
1199 } else if ((sp->ux_errno == ENOTTY || sp->ux_errno == EINVAL)) {
1200 /*
1201 * May be "Illegal ioctl()".
1202 */
1203 return (-1);
1204 }
1205 if (sp->ux_errno == ENXIO ||
1206 sp->ux_errno == EPERM ||
1207 sp->ux_errno == EACCES) {
1208 return (-1);
1209 }
1210 } else if (ret == 0) {
1211 #ifdef DEBUG
1212 if (sg_cgc.data_direction == CGC_DATA_READ) {
1213 int z;
1214
1215 sprintf(tmp_read, "data_read: %i bytes\n", sp->size);
1216 for (j = 0, z = 1; j < 80 && j < sp->size; j++, z++) {
1217 if (z > 16) {
1218 z = 1;
1219 strcat(tmp_read, "\n");
1220 }
1221 sprintf(tmp1, " %02X", (unsigned char) (sp->addr[j]));
1222 strcat(tmp_read, tmp1);
1223 }
1224 strcat(tmp_read, "\n");
1225 if (sp->size > 80) {
1226 strcat(tmp_read, "...\n");
1227 }
1228 }
1229 #endif /* DEBUG */
1230 }
1231 /*
1232 * copy sense back
1233 */
1234 if (ret < 0 && sg_cgc.sense->error_code) {
1235 sp->sense_count = sense_cgc.add_sense_len + 8;
1236 #ifdef DEBUG
1237 sprintf(tmp_sense, "sense_data: length %i\n", sp->sense_count);
1238 for (j = 0; j < sp->sense_count; j++) {
1239 sprintf(tmp1, " %02X", (((unsigned char *) (&sense_cgc))[j]));
1240 strcat(tmp_sense, tmp1);
1241 }
1242 log(("%s\n", tmp_sense));
1243
1244 sprintf(tmp_sense, "sense_data: error code 0x%02X, sense key 0x%02X,"
1245 " additional length %i, ASC 0x%02X, ASCQ 0x%02X\n",
1246 sg_cgc.sense->error_code, sg_cgc.sense->sense_key,
1247 sg_cgc.sense->add_sense_len, sg_cgc.sense->asc,
1248 sg_cgc.sense->ascq);
1249
1250 log(("%s\n", tmp_sense));
1251 #endif /* DEBUG */
1252 memcpy(sp->u_sense.cmd_sense, /* (caddr_t) */ &sense_cgc, SCG_MAX_SENSE);
1253 sp->u_scb.cmd_scb[0] = ST_CHK_COND;
1254
1255 switch (sg_cgc.sense->sense_key) {
1256 case SC_UNIT_ATTENTION:
1257 case SC_NOT_READY:
1258 sp->error = SCG_RETRYABLE; /* may be BUS_BUSY */
1259 sp->u_scb.cmd_scb[0] |= ST_BUSY;
1260 break;
1261 case SC_ILLEGAL_REQUEST:
1262 break;
1263 default:
1264 break;
1265 }
1266 } else {
1267 sp->u_scb.cmd_scb[0] = 0x00;
1268 }
1269
1270 sp->resid = 0;
1271 return (0);
1272 }
1273 #endif /* USE_ATAPI */
1274