1
/* @(#)scsi-linux-ata.c 1.6 04/05/20 Copyright 2002 J. Schilling */
3
static char ata_sccsid[] =
4
"@(#)scsi-linux-ata.c 1.6 04/05/20 Copyright 2002 J. Schilling";
7
* Interface for Linux generic SCSI implementation (sg).
9
* This is the interface for the broken Linux SCSI generic driver.
10
* This is a hack, that tries to emulate the functionality
13
* Warning: you may change this source, but if you do that
14
* you need to change the _scg_version and _scg_auth* string below.
15
* You may not return "schily" for an SCG_AUTHOR request anymore.
16
* Choose your name instead of "schily" and make clear that the version
17
* string is related to a modified source.
19
* Copyright (c) 2002 J. Schilling
21
* Thanks to Alexander Kern <alex.kern@gmx.de> for the idea and first
22
* code fragments for supporting the CDROM_SEND_PACKET ioctl() from
23
* the cdrom.c kernel driver. Please note that this interface in priciple
24
* is completely unneeded but the Linux kernel is just a cluster of
25
* code and does not support planned orthogonal interface systems.
26
* For this reason we need CDROM_SEND_PACKET in order to work around a
27
* bug in the linux kernel that prevents to use PCATA drives because
28
* the kernel panics if you try to put ide-scsi on top of the PCATA
32
* This program is free software; you can redistribute it and/or modify
33
* it under the terms of the GNU General Public License as published by
34
* the Free Software Foundation; either version 2, or (at your option)
37
* This program is distributed in the hope that it will be useful,
38
* but WITHOUT ANY WARRANTY; without even the implied warranty of
39
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40
* GNU General Public License for more details.
42
* You should have received a copy of the GNU General Public License along with
43
* this program; see the file COPYING. If not, write to the Free Software
44
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
49
LOCAL char _scg_atrans_version[] = "scsi-linux-ata.c-1.6"; /* The version for ATAPI transport*/
51
LOCAL char * scgo_aversion __PR((SCSI *scgp, int what));
52
LOCAL int scgo_ahelp __PR((SCSI *scgp, FILE *f));
53
LOCAL int scgo_aopen __PR((SCSI *scgp, char *device));
54
LOCAL int scgo_aclose __PR((SCSI *scgp));
55
LOCAL long scgo_amaxdma __PR((SCSI *scgp, long amt));
56
LOCAL BOOL scgo_ahavebus __PR((SCSI *scgp, int));
57
LOCAL int scgo_afileno __PR((SCSI *scgp, int, int, int));
58
LOCAL int scgo_ainitiator_id __PR((SCSI *scgp));
59
LOCAL int scgo_aisatapi __PR((SCSI *scgp));
60
LOCAL int scgo_areset __PR((SCSI *scgp, int what));
61
LOCAL int scgo_asend __PR((SCSI *scgp));
63
LOCAL scg_ops_t ata_ops = {
70
scgo_getbuf, /* Shared with SG driver */
71
scgo_freebuf, /* Shared with SG driver */
79
#define HOST_EMPTY 0xF
83
#define HOST_IEEE1389 0x3
84
#define HOST_PARALLEL 0x4
85
#define HOST_OTHER 0xE
88
#define typlocal(p, schillybus) scglocal(p)->bc[schillybus].typ
89
#define buslocal(p, schillybus) scglocal(p)->bc[schillybus].bus
90
#define hostlocal(p, schillybus) scglocal(p)->bc[schillybus].host
92
#define MAX_DMA_ATA (131072-1) /* EINVAL (hart) ENOMEM (weich) bei mehr ... */
93
/* Bei fehlerhaftem Sense Pointer kommt EFAULT */
95
LOCAL int scgo_send __PR((SCSI * scgp));
96
LOCAL BOOL sg_amapdev __PR((SCSI * scgp, int f, char *device, int *bus,
97
int *target, int *lun));
98
LOCAL BOOL sg_amapdev_scsi __PR((SCSI * scgp, int f, int *busp, int *tgtp,
99
int *lunp, int *chanp, int *inop));
100
LOCAL int scgo_aget_first_free_shillybus __PR((SCSI * scgp, int subsystem,
102
LOCAL int scgo_amerge __PR((char *path, char *readedlink,
103
char *buffer, int buflen));
106
* uncomment this when you will get a debug file #define DEBUG
109
#define LOGFILE "scsi-linux-ata.log"
110
#define log(a) sglog a
112
LOCAL void sglog __PR((const char *fmt, ...));
119
sglog(const char *fmt, ...)
128
FILE *f = fopen(LOGFILE, "a");
138
js_fprintf(f, "%r", fmt, args);
146
LOCAL int scan_internal __PR((SCSI * scgp, int *fatal));
149
* Return version information for the low level SCSI transport code.
150
* This has been introduced to make it easier to trace down problems
154
scgo_aversion(scgp, what)
158
if (scgp != (SCSI *)0) {
162
return (_scg_atrans_version);
164
* If you changed this source, you are not allowed to
165
* return "schily" for the SCG_AUTHOR request.
168
return (_scg_auth_schily);
181
__scg_help(f, "ATA", "ATA Packet specific SCSI transport",
182
"ATAPI:", "bus,target,lun", "ATAPI:1,2,0", TRUE, FALSE);
187
scgo_aopen(scgp, device)
191
int bus = scg_scsibus(scgp);
192
int target = scg_target(scgp);
193
int lun = scg_lun(scgp);
202
error("Warning: Using ATA Packet interface.\n");
203
if (scgp->overbose) {
204
error("Warning: The related libscg interface code is in pre alpha.\n");
205
error("Warning: There may be fatal problems.\n");
208
log(("\n<<<<<<<<<<<<<<<< LOGGING ON >>>>>>>>>>>>>>>>>\n"));
209
if (bus >= MAX_SCHILLY_HOSTS || target >= MAX_TGT || lun >= MAX_LUN) {
212
js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
213
"Illegal value for bus, target or lun '%d,%d,%d'",
219
if (scgp->local == NULL) {
220
scgp->local = malloc(sizeof (struct scg_local));
221
if (scgp->local == NULL) {
225
scglocal(scgp)->scgfile = -1;
226
scglocal(scgp)->pgbus = -2;
227
scglocal(scgp)->SCSIbuf = (char *)-1;
228
scglocal(scgp)->pack_id = 5;
229
scglocal(scgp)->drvers = -1;
230
scglocal(scgp)->isold = -1;
231
scglocal(scgp)->xbufsize = 0L;
232
scglocal(scgp)->xbuf = NULL;
235
for (b = 0; b < MAX_SCHILLY_HOSTS; b++) {
236
typlocal(scgp, b) = HOST_EMPTY;
237
for (t = 0; t < MAX_TGT; t++) {
238
for (l = 0; l < MAX_LUN; l++)
239
scglocal(scgp)->scgfiles[b][t][l] = (short) -1;
244
if (device != NULL && strcmp(device, "ATAPI") == 0)
247
/* if not scanning */
248
if ((device != NULL && *device != '\0') || (bus == -2 && target == -2))
252
if (scan_internal(scgp, &nopen)) {
254
js_printf(scgp->errstr, "INFO: scan_internal(...) failed");
260
if (device != NULL && strncmp(device, "ATAPI:", 6) == 0)
262
if (scgp->debug > 3) {
263
js_fprintf((FILE *) scgp->errfile, "INFO: do scgo_open openbydev");
265
if (device != NULL && *device != '\0') {
270
f = open(device, O_RDONLY | O_NONBLOCK);
274
js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
275
"Cannot open '%s'", device);
278
if (sg_amapdev(scgp, f, device, &schilly_bus, &starget, &slun)) {
279
scg_settarget(scgp, schilly_bus, starget, slun);
287
scan_internal(scgp, nopen)
298
* try always with devfs
299
* unfortunatelly the solution with test of existing
300
* of '/dev/.devfsd' don't work, because it root.root 700
301
* and i don't like run suid root
307
sprintf(device, "/dev/cdroms/cdrom%i", i);
308
if ((f = open(device, O_RDONLY | O_NONBLOCK)) < 0) {
309
if (errno != ENOENT && errno != ENXIO && errno != ENODEV && errno != EACCES) {
310
if (scgp->debug > 4) {
311
js_fprintf((FILE *) scgp->errfile,
312
"try open(%s) return %i, errno %i, cancel\n", device, f, errno);
315
} else if (errno == ENOENT || errno == ENODEV) {
316
if (scgp->debug > 4) {
317
js_fprintf((FILE *) scgp->errfile,
318
"try open(%s) return %i, errno %i\n", device, f, errno);
322
if (scgp->debug > 4) {
323
js_fprintf((FILE *) scgp->errfile,
324
"DEVFS not detected, continuing with old dev\n");
329
if (scgp->debug > 4) {
330
if (errno == EACCES) {
331
js_fprintf((FILE *) scgp->errfile,
332
"errno (EACCESS), you don't have the needed rights for %s\n",
335
js_fprintf((FILE *) scgp->errfile,
336
"try open(%s) return %i, errno %i, trying next cdrom\n",
340
if (scgp->debug > 4) {
341
js_fprintf((FILE *) scgp->errfile,
342
"try open(%s) return %i errno %i calling sg_mapdev(...)\n",
345
if (sg_amapdev(scgp, f, device, &schilly_bus, &target, &lun)) {
354
/* for /dev/sr0 - /dev/sr? */
356
sprintf(device, "/dev/sr%i", i);
357
if ((f = open(device, O_RDONLY | O_NONBLOCK)) < 0) {
358
if (errno != ENOENT && errno != ENXIO && errno != ENODEV && errno != EACCES) {
359
if (scgp->debug > 4) {
360
js_fprintf((FILE *) scgp->errfile,
361
"try open(%s) return %i, errno %i, cancel\n",
365
} else if (errno == ENOENT || errno == ENODEV) {
369
if (sg_amapdev(scgp, f, device, &schilly_bus, &target, &lun)) {
377
/* for /dev/hda - /dev/hdz */
378
for (i = 'a'; i <= 'z'; i++) {
379
sprintf(device, "/dev/hd%c", i);
380
if ((f = open(device, O_RDONLY | O_NONBLOCK)) < 0) {
381
if (errno != ENOENT && errno != ENXIO && errno != EACCES) {
382
if (scgp->debug > 4) {
383
js_fprintf((FILE *) scgp->errfile,
384
"try open(%s) return %i, errno %i, cancel\n",
388
} else if (errno == ENOENT || errno == ENODEV) {
392
/* ugly hack, make better, when you can. Alex */
393
if (0 > ioctl(f, CDROM_DRIVE_STATUS, CDSL_CURRENT)) {
394
if (scgp->debug > 4) {
395
js_fprintf((FILE *) scgp->errfile,
396
"%s is not a cdrom, skipping\n",
400
} else if (sg_amapdev(scgp, f, device, &schilly_bus, &target, &lun)) {
420
if (scgp->local == NULL)
423
for (h = 0; h < MAX_SCHILLY_HOSTS; h++) {
424
typlocal(scgp, h) = (HOST_EMPTY);
425
for (t = 0; t < MAX_TGT; t++) {
426
for (l = 0; l < MAX_LUN; l++) {
427
f = scglocal(scgp)->scgfiles[h][t][l];
430
scglocal(scgp)->scgfiles[h][t][l] = (short) -1;
435
if (scglocal(scgp)->xbuf != NULL) {
436
free(scglocal(scgp)->xbuf);
437
scglocal(scgp)->xbufsize = 0L;
438
scglocal(scgp)->xbuf = NULL;
440
log(("<<<<<<<<<<<<<<<< LOGGING OFF >>>>>>>>>>>>>>>>>\n\n"));
445
scgo_aget_first_free_shillybus(scgp, subsystem, host, bus)
451
int first_free_schilly_bus;
453
for (first_free_schilly_bus = 0;
454
first_free_schilly_bus < MAX_SCHILLY_HOSTS;
455
first_free_schilly_bus++) {
457
if (typlocal(scgp, first_free_schilly_bus) == HOST_EMPTY ||
458
(typlocal(scgp, first_free_schilly_bus) == subsystem &&
459
hostlocal(scgp, first_free_schilly_bus) == host &&
460
buslocal(scgp, first_free_schilly_bus) == bus))
464
if (first_free_schilly_bus >= MAX_SCHILLY_HOSTS) {
465
errmsgno(EX_BAD, "ERROR: in scgo_get_first_free_shillybus(...). Too many CDROMs, more than %i",
467
errmsgno(EX_BAD, "Increase MAX_SCHILLY_HOSTS in scsi-linux-ata.c and recompile!");
470
return (first_free_schilly_bus);
474
scgo_amerge(path, readedlink, buffer, buflen)
482
#define TOKEN_ARRAY 20
483
#define LAST_CHAR(x) (x)[strlen((x))-1]
484
#define ONE_CHAR_BACK(x) (x)[strlen((x))-1] = '\0'
485
char *ppa[TOKEN_ARRAY];
493
if (!path || !readedlink || !buffer)
496
if ('/' == readedlink[0]) {
497
aa = (char *) malloc(strlen(readedlink) + 1);
501
strcpy(aa, readedlink);
503
aa = (char *) malloc(strlen(path) + strlen(readedlink) + 1);
508
if (LAST_CHAR(aa) == '/') {
511
last_slash = strrchr(aa, '/');
512
if (last_slash == NULL)
515
*(++last_slash) = '\0';
516
strcat(aa, readedlink);
518
memset(ppa, 0x00, sizeof (ppa));
520
for (i = 0, pa = strtok(aa, seps);
521
i < TOKEN_ARRAY && pa != NULL;
522
++i, pa = strtok(NULL, seps)) {
526
if (i == TOKEN_ARRAY) {
530
for (i = 0; i < TOKEN_ARRAY && ppa[i]; i++) {
531
if (strcmp(ppa[i], "..") == 0) {
540
for (i = 0; i < TOKEN_ARRAY; i++) {
543
len += strlen(ppa[i]);
549
if (len + 1 <= buflen) {
551
for (i = 0; i < TOKEN_ARRAY; i++) {
554
strcat(buffer, ppa[i]);
558
if (strlen(buffer) == 0)
567
* /dev/cdroms/cdrom0 first CD-ROM
568
* /dev/cdroms/cdrom1 second CD-ROM
573
* To uniquely identify any SCSI device requires the following information:
575
* controller (host adapter)
578
* unit (Logical Unit Number)
580
* All SCSI devices are placed under /dev/scsi (assuming devfs is mounted on /dev).
581
* Hence, a SCSI device with the following parameters:
582
* c=1,b=2,t=3,u=4 would appear as:
584
* /dev/scsi/host1/bus2/target3/lun4 device directory
586
* Inside this directory, a number of device entries may be created,
587
* depending on which SCSI device-type drivers were installed.
589
* See the section on the disc naming scheme to see what entries
590
* the SCSI disc driver creates.
592
* See the section on the tape naming scheme to see what entries
593
* the SCSI tape driver creates.
595
* The SCSI CD-ROM driver creates: cd
596
* The SCSI generic driver creates: generic
600
* To uniquely identify any IDE device requires the following information:
603
* bus (0/1 aka. primary/secondary)
604
* target (0/1 aka. master/slave)
607
* All IDE devices are placed under /dev/ide, and uses a similar
608
* naming scheme to the SCSI subsystem.
611
* Example /dev/cdroms/cdrom0 -> /dev/scsi/host1/bus2/target3/lun4/cd
612
* Example /dev/cdroms/cdrom1 -> /dev/ide/host1/bus0/target1/lun4/cd
616
sg_amapdev(scgp, f, device, schillybus, target, lun)
646
#define TOKEN_DEV "dev"
647
#define TOKEN_SUBSYSTEM_SCSI "scsi"
648
#define TOKEN_SUBSYSTEM_IDE "ide"
649
#define TOKEN_HOST "host"
650
#define TOKEN_BUS "bus"
651
#define TOKEN_TARGET "target"
652
#define TOKEN_LUN "lun"
653
#define TOKEN_CD "cd"
655
#define ID_TOKEN_DEV 0
656
#define ID_TOKEN_SUBSYSTEM 1
657
#define ID_TOKEN_HOST 2
658
#define ID_TOKEN_BUS 3
659
#define ID_TOKEN_TARGET 4
660
#define ID_TOKEN_LUN 5
661
#define ID_TOKEN_CD 6
662
#define ID_TOKEN_LAST ID_TOKEN_CD
663
#define ID_TOKEN_MAX ID_TOKEN_LAST + 2
664
#define CHARTOINT(x) (abs(atoi(&x)))
666
char *token[ID_TOKEN_MAX],
675
#define LOCAL_MAX_PATH MAX_PATH
676
char tmp[LOCAL_MAX_PATH],
677
tmp1[LOCAL_MAX_PATH];
678
int first_free_schilly_bus;
679
int subsystem = HOST_EMPTY;
686
/* strtok need char* instead of const char* */
687
result = stat(device, &buf);
688
if (result || !S_ISBLK(buf.st_mode))
691
result = lstat(device, &buf);
692
if (!result && S_ISLNK(buf.st_mode)) {
693
result = readlink(device, tmp, LOCAL_MAX_PATH);
694
if (result > 0 && result < LOCAL_MAX_PATH) {
697
result = scgo_amerge(device, tmp, tmp1, LOCAL_MAX_PATH);
698
if (result > 0 && result < LOCAL_MAX_PATH) {
703
"ERROR: with link merging! base %s link %s, result of merging %i\n",
704
device, tmp, result);
709
"ERROR: with link reading! link %s, result of readlink %i\n",
714
strncpy(tmp, device, sizeof (tmp));
716
if (scgp->debug > 3) {
717
js_fprintf((FILE *) scgp->errfile, "INFO: %s -> %s\n", device, tmp);
719
memset(token, 0x00, sizeof (token));
721
token[i] = strtok(tmp, seps);
722
while (token[i] != NULL && (++i) && i < ID_TOKEN_MAX) {
723
token[i] = strtok(NULL, seps);
726
if (i == ID_TOKEN_MAX ||
727
!(token[ID_TOKEN_DEV]) ||
728
strcmp(token[ID_TOKEN_DEV], TOKEN_DEV)) {
730
errmsgno(EX_BAD, "ERROR: unknow format\n");
731
errmsgno(EX_BAD, "EXAMPLE: /dev/scsi/host1/bus2/target3/lun4/cd\n");
732
errmsgno(EX_BAD, "EXAMPLE: /dev/ide/host0/bus0/target1/lun0/cd\n");
733
errmsgno(EX_BAD, "EXAMPLE: /dev/hda or /dev/sr0\n");
736
if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_SCSI)) ||
737
!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_IDE))) {
738
h = CHARTOINT(((struct host *) token[ID_TOKEN_HOST])->host_no);
739
b = CHARTOINT(((struct bus *) token[ID_TOKEN_BUS])->bus_no);
740
t = CHARTOINT(((struct target *) token[ID_TOKEN_TARGET])->target_no);
741
l = CHARTOINT(((struct lun *) token[ID_TOKEN_LUN])->lun_no);
743
if (strncmp(token[ID_TOKEN_HOST], TOKEN_HOST, strlen(TOKEN_HOST))) {
744
log(("ERROR: invalid host specified\n"));
747
if (strncmp(token[ID_TOKEN_BUS], TOKEN_BUS, strlen(TOKEN_BUS))) {
748
log(("ERROR: invalid bus specified\n"));
751
if (strncmp(token[ID_TOKEN_TARGET], TOKEN_TARGET, strlen(TOKEN_TARGET))) {
752
log(("ERROR: invalid target specified\n"));
755
if (strncmp(token[ID_TOKEN_LUN], TOKEN_LUN, strlen(TOKEN_LUN))) {
756
log(("ERROR: invalid lun specified\n"));
759
if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_IDE))) {
760
if (b > 1 || t > 1) {
761
log(("ERROR: invalid bus or target for IDE specified\n"));
765
#endif /* PARANOID */
767
if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_IDE))) {
768
subsystem = HOST_IDE;
769
} else if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_SCSI))) {
770
subsystem = HOST_SCSI;
772
subsystem = HOST_OTHER;
774
} else if (!token[ID_TOKEN_HOST] &&
775
strlen(token[ID_TOKEN_SUBSYSTEM]) == sizeof (old_dev)) {
778
old_dev *pDev = (old_dev *) token[ID_TOKEN_SUBSYSTEM];
780
if (strncmp(pDev->prefix, "hd", 2) == 0) {
781
j = pDev->device - ('a');
783
subsystem = HOST_IDE;
788
} else if (strncmp(pDev->prefix, "sr", 2) == 0) {
790
if (pDev->device >= '0' && pDev->device <= '9')
791
j = pDev->device - ('0');
793
j = pDev->device - ('a');
801
/* other solution, with ioctl */
808
subsystem = HOST_SCSI;
809
sg_amapdev_scsi(scgp, f, &Bus, &Target, &Lun, &Chan, &Ino);
811
/* For old kernels try to make the best guess. */
815
n = sg_mapbus(scgp, Bus, Ino);
818
if (scgp->debug > 0) {
819
js_fprintf((FILE *)scgp->errfile,
820
"SCSI Bus: %d (mapped from %d)\n",
824
/* It is me too high ;-()*/
831
errmsgno(EX_BAD, "ERROR: unknow subsystem (%s) in (%s)\n",
832
token[ID_TOKEN_SUBSYSTEM], device);
836
errmsgno(EX_BAD, "ERROR: unknow subsystem (%s) in (%s)\n",
837
token[ID_TOKEN_SUBSYSTEM], device);
842
js_printf(scgp->errstr, "INFO: subsystem %s: h %i, b %i, t %i, l %i",
843
token[ID_TOKEN_SUBSYSTEM], h, b, t, l);
845
first_free_schilly_bus = scgo_aget_first_free_shillybus(scgp, subsystem, h, b);
846
if (-1 == first_free_schilly_bus) {
849
if (scglocal(scgp)->scgfiles[first_free_schilly_bus][t][l] != (-1)) {
850
errmsgno(EX_BAD, "ERROR: this cdrom is already mapped %s(%d,%d,%d)\n",
851
device, first_free_schilly_bus, t, l);
854
scglocal(scgp)->scgfiles[first_free_schilly_bus][t][l] = f;
855
typlocal(scgp, first_free_schilly_bus) = subsystem;
856
hostlocal(scgp, first_free_schilly_bus) = h;
857
buslocal(scgp, first_free_schilly_bus) = b;
858
*schillybus = first_free_schilly_bus;
862
if (scgp->debug > 1) {
863
js_fprintf((FILE *) scgp->errfile,
864
"INFO: /dev/%s, (host%d/bus%d/target%d/lun%d) will be mapped on the schilly bus No %d (%d,%d,%d)\n",
865
token[ID_TOKEN_SUBSYSTEM], h, b, t, l,
866
first_free_schilly_bus, first_free_schilly_bus, t, l);
873
sg_amapdev_scsi(scgp, f, busp, tgtp, lunp, chanp, inop)
883
long l1; /* target | lun << 8 | channel << 16 | low_ino << 24 */
884
long l2; /* Unique id */
892
if (ioctl(f, SCSI_IOCTL_GET_IDLUN, &sg_id))
895
if (scgp->debug > 0) {
896
js_fprintf((FILE *) scgp->errfile,
897
"INFO: l1: 0x%lX l2: 0x%lX\n", sg_id.l1, sg_id.l2);
899
if (ioctl(f, SCSI_IOCTL_GET_BUS_NUMBER, &Bus) < 0) {
902
Target = sg_id.l1 & 0xFF;
903
Lun = (sg_id.l1 >> 8) & 0xFF;
904
Chan = (sg_id.l1 >> 16) & 0xFF;
905
Ino = (sg_id.l1 >> 24) & 0xFF;
906
if (scgp->debug > 0) {
907
js_fprintf((FILE *) scgp->errfile,
908
"INFO: Bus: %d Target: %d Lun: %d Chan: %d Ino: %d\n",
909
Bus, Target, Lun, Chan, Ino);
922
scgo_amaxdma(scgp, amt)
927
* EINVAL (hart) ENOMEM (weich) bei mehr ...
928
* Bei fehlerhaftem Sense Pointer kommt EFAULT
930
return (MAX_DMA_ATA);
934
scgo_ahavebus(scgp, busno)
941
if (busno < 0 || busno >= MAX_SCHILLY_HOSTS)
944
if (scgp->local == NULL)
947
for (t = 0; t < MAX_TGT; t++) {
948
for (l = 0; l < MAX_LUN; l++)
949
if (scglocal(scgp)->scgfiles[busno][t][l] >= 0)
956
scgo_afileno(scgp, busno, tgt, tlun)
962
if (busno < 0 || busno >= MAX_SCHILLY_HOSTS ||
963
tgt < 0 || tgt >= MAX_TGT ||
964
tlun < 0 || tlun >= MAX_LUN)
967
if (scgp->local == NULL)
970
return ((int) scglocal(scgp)->scgfiles[busno][tgt][tlun]);
974
scgo_ainitiator_id(scgp)
977
js_printf(scgp->errstr, "NOT IMPELEMENTED: scgo_initiator_id");
985
int schillybus = scgp->addr.scsibus;
986
int typ = typlocal(scgp, schillybus);
987
if (typ == HOST_EMPTY)
989
if (typ != HOST_SCSI)
996
scgo_areset(scgp, what)
1000
if (what == SCG_RESET_NOP)
1003
if (what == SCG_RESET_TGT || what == SCG_RESET_BUS)
1004
return (ioctl(what, CDROMRESET));
1013
struct scg_cmd *sp = scgp->scmd;
1016
struct cdrom_generic_command sg_cgc;
1017
struct request_sense sense_cgc;
1029
sp->error = SCG_FATAL;
1033
if (sp->cdb_len > CDROM_PACKET_SIZE) {
1034
sp->error = SCG_FATAL;
1039
fillbytes((caddr_t) & sg_cgc, sizeof (sg_cgc), '\0');
1040
fillbytes((caddr_t) & sense_cgc, sizeof (sense_cgc), '\0');
1042
if (sp->flags & SCG_RECV_DATA) {
1043
sg_cgc.data_direction = CGC_DATA_READ;
1044
} else if (sp->size > 0) {
1045
sg_cgc.data_direction = CGC_DATA_WRITE;
1047
sg_cgc.data_direction = CGC_DATA_NONE;
1049
#if LINUX_VERSION_CODE >= 0x020403
1050
if (sp->flags & SCG_SILENT) {
1054
for (i = 0; i < sp->cdb_len; i++) {
1055
sg_cgc.cmd[i] = sp->cdb.cmd_cdb[i];
1058
sg_cgc.buflen = sp->size;
1059
sg_cgc.buffer = sp->addr;
1061
if (sp->sense_len > sizeof (sense_cgc))
1062
sense_cgc.add_sense_len = sizeof (sense_cgc) - 8;
1064
sense_cgc.add_sense_len = sp->sense_len - 8;
1066
sg_cgc.sense = &sense_cgc;
1067
#if LINUX_VERSION_CODE >= 0x020403
1068
sg_cgc.timeout = sp->timeout * 1000;
1071
strcpy(tmp_send, "send cmd:\n");
1072
for (j = 0; j < sp->cdb_len; j++) {
1073
sprintf(tmp1, " %02X", sp->cdb.cmd_cdb[j]);
1074
strcat(tmp_send, tmp1);
1076
strcat(tmp_send, "\n");
1078
if (sg_cgc.data_direction == CGC_DATA_WRITE) {
1081
sprintf(tmp1, "data_write: %i bytes\n", sp->size);
1082
strcat(tmp_send, tmp1);
1083
for (j = 0, z = 1; j < 80 && j < sp->size; j++, z++) {
1086
strcat(tmp_send, "\n");
1088
sprintf(tmp1, " %02X", (unsigned char) (sp->addr[j]));
1089
strcat(tmp_send, tmp1);
1091
strcat(tmp_send, "\n");
1093
if (sp->size > 80) {
1094
strcat(tmp_send, "...\n");
1098
if ((ret = ioctl(scgp->fd, CDROM_SEND_PACKET, &sg_cgc)) < 0)
1099
sp->ux_errno = geterrno();
1101
if (ret < 0 && scgp->debug > 4) {
1102
js_fprintf((FILE *) scgp->errfile,
1103
"ioctl(CDROM_SEND_PACKET) ret: %d\n", ret);
1106
* copy scsi data back
1108
if (sp->flags & SCG_RECV_DATA && ((void *) sp->addr != (void *) sg_cgc.buffer)) {
1109
memcpy(sp->addr, sg_cgc.buffer, (sp->size < sg_cgc.buflen) ? sp->size : sg_cgc.buflen);
1110
if (sg_cgc.buflen > sp->size)
1111
sp->resid = sg_cgc.buflen - sp->size;
1113
sp->error = SCG_NO_ERROR;
1116
switch (sp->ux_errno) {
1135
case EDRIVE_CANT_DO_THIS:
1136
p = "EDRIVE_CANT_DO_THIS";
1141
log(("%s", tmp_send));
1142
log(("ERROR: returns %i errno %i(%s)\n", ret, sp->ux_errno, p));
1147
* Check if SCSI command cound not be send at all.
1148
* Linux usually returns EINVAL for an unknoen ioctl.
1149
* In case somebody from the Linux kernel team learns that the
1150
* corect errno would be ENOTTY, we check for this errno too.
1152
if (sp->ux_errno == EINVAL) {
1154
* Try to work around broken Linux kernel design...
1155
* If SCSI Sense Key is 0x05 (Illegal request), Linux
1156
* returns a useless EINVAL making it close to
1157
* impossible distinct from "Illegal ioctl()" or
1158
* "Invalid parameter".
1160
if ((((Uchar *)sg_cgc.sense)[0] != 0) ||
1161
(((Uchar *)sg_cgc.sense)[2] != 0))
1164
} else if ((sp->ux_errno == ENOTTY || sp->ux_errno == EINVAL)) {
1166
* May be "Illegal ioctl()".
1170
if (sp->ux_errno == ENXIO || sp->ux_errno == EACCES) {
1173
} else if (ret == 0) {
1175
if (sg_cgc.data_direction == CGC_DATA_READ) {
1178
sprintf(tmp_read, "data_read: %i bytes\n", sp->size);
1179
for (j = 0, z = 1; j < 80 && j < sp->size; j++, z++) {
1182
strcat(tmp_read, "\n");
1184
sprintf(tmp1, " %02X", (unsigned char) (sp->addr[j]));
1185
strcat(tmp_read, tmp1);
1187
strcat(tmp_read, "\n");
1188
if (sp->size > 80) {
1189
strcat(tmp_read, "...\n");
1197
if (ret < 0 && sg_cgc.sense->error_code) {
1198
sp->sense_count = sense_cgc.add_sense_len + 8;
1200
sprintf(tmp_sense, "sense_data: length %i\n", sp->sense_count);
1201
for (j = 0; j < sp->sense_count; j++) {
1202
sprintf(tmp1, " %02X", (((unsigned char *) (&sense_cgc))[j]));
1203
strcat(tmp_sense, tmp1);
1205
log(("%s\n", tmp_sense));
1207
sprintf(tmp_sense, "sense_data: error code 0x%02X, sense key 0x%02X,"
1208
" additional length %i, ASC 0x%02X, ASCQ 0x%02X\n",
1209
sg_cgc.sense->error_code, sg_cgc.sense->sense_key,
1210
sg_cgc.sense->add_sense_len, sg_cgc.sense->asc,
1211
sg_cgc.sense->ascq);
1213
log(("%s\n", tmp_sense));
1215
memcpy(sp->u_sense.cmd_sense, /* (caddr_t) */ &sense_cgc, SCG_MAX_SENSE);
1216
sp->u_scb.cmd_scb[0] = ST_CHK_COND;
1218
switch (sg_cgc.sense->sense_key) {
1219
case SC_UNIT_ATTENTION:
1221
sp->error = SCG_RETRYABLE; /* may be BUS_BUSY */
1222
sp->u_scb.cmd_scb[0] |= ST_BUSY;
1224
case SC_ILLEGAL_REQUEST:
1230
sp->u_scb.cmd_scb[0] = 0x00;
1236
#endif /* USE_ATA */