Magellan Linux

Annotation of /trunk/cdparanoia/patches/cdparanoia-3.9.8-sgio.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 144 - (hide annotations) (download)
Tue May 8 20:06:05 2007 UTC (17 years, 1 month ago) by niro
File size: 57470 byte(s)
-import

1 niro 144 diff --exclude CVS -u -N -r cdparanoia-III-alpha9.8/interface/cdda_interface.h paranoia-III/interface/cdda_interface.h
2     --- cdparanoia-III-alpha9.8/interface/cdda_interface.h 2004-02-21 13:16:47.000000000 -0500
3     +++ cdparanoia-III-alpha9.8/interface/cdda_interface.h 2004-02-25 21:42:15.000000000 -0500
4     @@ -99,10 +99,46 @@
5    
6     } cdrom_drive;
7    
8     +/* buffers for use with the scsi code. d->sg_buffer is unused,
9     + and d->sg points to this struct. We can't really change struct
10     + cdrom_drive without breaking binary compatibility, so we do this
11     + instead. */
12     +struct sg_info {
13     +#ifdef SG_IO
14     + struct sg_io_hdr *hdr;
15     +#else
16     + struct sg_header *hdr;
17     +#endif
18     +
19     + char *cmdp;
20     + ssize_t cmd_len;
21     + ssize_t cmdp_buffer_len;
22     +
23     + char *dxferp;
24     + ssize_t dxferp_buffer_len;
25     + ssize_t dxferp_max_buffer_len;
26     +
27     + unsigned char bytefill;
28     + int bytecheck;
29     +
30     + int in_size;
31     + int out_size;
32     +
33     + int (*handle_scsi_cmd)(struct cdrom_drive *d);
34     + void (*setup_scsi_cmd)(struct cdrom_drive *d,
35     + char *cmdp, unsigned int cmd_len,
36     + unsigned int in_size, unsigned int out_size);
37     +};
38     +
39     +
40     #define IS_AUDIO(d,i) (!(d->disc_toc[i].bFlags & 0x04))
41    
42     /******** Identification/autosense functions */
43    
44     +#ifdef SG_IO
45     +extern int check_fd_sgio(int fd);
46     +#endif
47     +
48     extern cdrom_drive *cdda_find_a_cdrom(int messagedest, char **message);
49     extern cdrom_drive *cdda_identify(const char *device, int messagedest,
50     char **message);
51     diff --exclude CVS -u -N -r cdparanoia-III-alpha9.8/interface/interface.c paranoia-III/interface/interface.c
52     --- cdparanoia-III-alpha9.8/interface/interface.c 2004-02-21 13:16:49.000000000 -0500
53     +++ cdparanoia-III-alpha9.8/interface/interface.c 2004-02-25 11:17:37.000000000 -0500
54     @@ -30,7 +30,7 @@
55    
56     _clean_messages(d);
57     if(d->cdda_device_name)free(d->cdda_device_name);
58     - if(d->ioctl_device_name)free(d->ioctl_device_name);
59     + if(d->ioctl_device_name && d->ioctl_device_name!=d->cdda_device_name)free(d->ioctl_device_name);
60     if(d->drive_model)free(d->drive_model);
61     if(d->cdda_fd!=-1)close(d->cdda_fd);
62     if(d->ioctl_fd!=-1 && d->ioctl_fd!=d->cdda_fd)close(d->ioctl_fd);
63     diff --exclude CVS -u -N -r cdparanoia-III-alpha9.8/interface/scan_devices.c paranoia-III/interface/scan_devices.c
64     --- cdparanoia-III-alpha9.8/interface/scan_devices.c 2004-02-21 13:16:51.000000000 -0500
65     +++ cdparanoia-III-alpha9.8/interface/scan_devices.c 2004-02-26 19:26:15.000000000 -0500
66     @@ -14,8 +14,8 @@
67     #include <pwd.h>
68     #include <sys/stat.h>
69     #include <sys/types.h>
70     -#include "cdda_interface.h"
71     #include "low_interface.h"
72     +#include "cdda_interface.h"
73     #include "common_interface.h"
74     #include "utils.h"
75    
76     @@ -50,6 +50,8 @@
77     "/dev/gscd",
78     "/dev/optcd",NULL};
79    
80     +extern void sg2_init_sg_info(cdrom_drive *d);
81     +extern void sgio_init_sg_info(cdrom_drive *d);
82     /* Functions here look for a cdrom drive; full init of a drive type
83     happens in interface.c */
84    
85     @@ -117,8 +119,13 @@
86     }
87     #endif
88    
89     - d=cdda_identify_cooked(device,messagedest,messages);
90     +#ifdef SG_IO
91     + d=cdda_identify_scsi(device,NULL,messagedest,messages);
92     + if(!d)d=cdda_identify_cooked(device,messagedest,messages);
93     +#else
94     if(!d)d=cdda_identify_scsi(device,NULL,messagedest,messages);
95     + d=cdda_identify_cooked(device,messagedest,messages);
96     +#endif
97    
98     #ifdef CDDA_TEST
99     if(!d)d=cdda_identify_test(device,messagedest,messages);
100     @@ -412,17 +419,19 @@
101     "\nFound an accessible SCSI CDROM drive."
102     "\nLooking at revision of the SG interface in use...","");
103    
104     - if(ioctl(d->cdda_fd,SG_GET_VERSION_NUM,&version)){
105     + if((version = ioctl(d->cdda_fd,SG_GET_VERSION_NUM,&major)) < 0){
106     /* Up, guess not. */
107     idmessage(messagedest,messages,
108     "\tOOPS! Old 2.0/early 2.1/early 2.2.x (non-ac patch) style "
109     "SG.\n\tCdparanoia no longer supports the old interface.\n","");
110     return(0);
111     }
112     - major=version/10000;
113     - version-=major*10000;
114     - minor=version/100;
115     - version-=minor*100;
116     + if (!version)
117     + version = major;
118     +
119     + major = (version >> 16) & 0xff;
120     + minor = (version >> 8) & 0xff;
121     + version &= 0xff;
122    
123     sprintf(buffer,"\tSG interface version %d.%d.%d; OK.",
124     major,minor,version);
125     @@ -431,6 +440,138 @@
126     return(major);
127     }
128    
129     +#ifdef SG_IO
130     +int get_sgio_fd(const char *device, int messagedest, char **messages) {
131     + int fd;
132     +
133     + if (!device)
134     + return -errno;
135     + /* we don't really care what type of device it is -- if it can do
136     + * SG_IO, then we'll put it through the normal mmc/atapi/etc tests
137     + * later, but it's good enough for now. */
138     + fd = open(device, O_RDWR|O_EXCL|O_NONBLOCK);
139     + if (fd < 0)
140     + return -errno;
141     + return check_fd_sgio(fd);
142     +}
143     +
144     +/* removing generic_device breaks ABI; instead, just test both devices */
145     +static cdrom_drive *sgio_cdda_identify_scsi(const char *generic_device,
146     + const char *ioctl_device, int messagedest,
147     + char **messages){
148     + cdrom_drive *d = NULL;
149     + char *device = NULL;
150     + int fd = -1, g_fd = -1;
151     + char *p;
152     +
153     + /* with SG_IO in 2.6, we much prefer /dev/hdc and /dev/scd0, so
154     + * test ioctl_device before testing generic_device */
155     +
156     + /* we need to resolve any symlinks for the lookup code to work */
157     + if (ioctl_device)
158     + device = test_resolve_symlink(ioctl_device, messagedest, messages);
159     + /* test again, in case symlink resolution failed */
160     + if (device) {
161     + fd = get_sgio_fd(ioctl_device, messagedest, messages);
162     + if (fd < 0) {
163     + /* ioctl_device didn't work, so we don't need to keep the strdup of its
164     + * real path around */
165     + free(device);
166     + device = NULL;
167     + }
168     + }
169     + if (fd < 0) {
170     + if (!generic_device)
171     + goto cdda_identify_scsi_fail_free;
172     + device = test_resolve_symlink(generic_device, messagedest, messages);
173     + /* test again, in case symlink resolution failed */
174     + if (!device)
175     + goto cdda_identify_scsi_fail_return;
176     + g_fd = get_sgio_fd(device, messagedest, messages);
177     + if (g_fd < 0)
178     + goto cdda_identify_scsi_fail_free;
179     + fd = g_fd;
180     + }
181     +
182     + d=calloc(1,sizeof(cdrom_drive));
183     +
184     + d->drive_type=SCSI_CDROM_MAJOR;
185     + d->cdda_fd=fd;
186     + d->ioctl_fd=fd;
187     + d->bigendianp=-1; /* We don't know yet... */
188     + d->nsectors=-1;
189     +
190     + d->interface=GENERIC_SCSI;
191     +
192     + /* alloc our big buffer for scsi commands */
193     + d->sg=calloc(1, sizeof (struct sg_info));
194     + ((struct sg_info *)d->sg)->dxferp_max_buffer_len = CD_FRAMESIZE_RAW;
195     + if (check_fd_sgio(d->cdda_fd))
196     + sgio_init_sg_info(d);
197     + else
198     + sg2_init_sg_info(d);
199     +
200     + /* get the lun -- this used to set 0 on failure, maybe still should */
201     + d->lun = -1;
202     +
203     + p = scsi_inquiry(d);
204     + if (!p)
205     + goto cdda_identify_scsi_fail_free_device;
206     +
207     + /* It would seem some TOSHIBA CDROMs gets things wrong */
208     +
209     + if (!strncmp (p + 8, "TOSHIBA", 7) &&
210     + !strncmp (p + 16, "CD-ROM", 6) &&
211     + p[0] == TYPE_DISK) {
212     + p[0] = TYPE_ROM;
213     + p[1] |= 0x80; /* removable */
214     + }
215     +
216     + if (!p || (*p != TYPE_ROM && *p != TYPE_WORM)) {
217     + idmessage(messagedest, messages,
218     + "\t\tDrive is neither a CDROM nor a WORM device\n", NULL);
219     + goto cdda_identify_scsi_fail_free_device;
220     + }
221     +
222     + memcpy(d->inqbytes, p, 4);
223     + d->cdda_device_name = device;
224     + d->ioctl_device_name = device;
225     +
226     + d->drive_model = calloc(1, 36);
227     + strscat(d->drive_model, p+8, 8);
228     + strscat(d->drive_model, p+16, 16);
229     + strscat(d->drive_model, p+32, 4);
230     +
231     + idmessage(messagedest, messages, "\nCDROM model sensed sensed: %s", d->drive_model);
232     +
233     + return d;
234     +
235     +cdda_identify_scsi_fail_free_device:
236     + if (d) {
237     + if (d->drive_model)
238     + free(d->drive_model);
239     + if (d->sg) {
240     + struct sg_info *sgi = (struct sg_info *)d->sg;
241     +
242     + if (sgi->cmdp_buffer_len)
243     + free(sgi->cmdp);
244     + if (sgi->dxferp_buffer_len)
245     + free(sgi->dxferp);
246     + if (sgi->hdr)
247     + free(sgi->hdr);
248     + free(d->sg);
249     + }
250     + free(d);
251     + }
252     + if (fd >= 0)
253     + close(fd);
254     +cdda_identify_scsi_fail_free:
255     + if (device)
256     + free(device);
257     +cdda_identify_scsi_fail_return:
258     + return NULL;
259     +}
260     +#endif
261     cdrom_drive *cdda_identify_scsi(const char *generic_device,
262     const char *ioctl_device, int messagedest,
263     char **messages){
264     @@ -444,6 +585,12 @@
265     int type;
266     char *p;
267    
268     +#ifdef SG_IO
269     + d = sgio_cdda_identify_scsi(generic_device, ioctl_device, messagedest, messages);
270     + if (d)
271     + return d;
272     +#endif
273     +
274     if(generic_device)
275     idmessage(messagedest,messages,"\tTesting %s for SCSI interface",
276     generic_device);
277     @@ -580,7 +727,6 @@
278     "major number",generic_device);
279     goto cdda_identify_scsi_fail;
280     }
281     -
282    
283     d=calloc(1,sizeof(cdrom_drive));
284    
285     @@ -601,8 +747,9 @@
286     }
287    
288     /* malloc our big buffer for scsi commands */
289     - d->sg=malloc(MAX_BIG_BUFF_SIZE);
290     - d->sg_buffer=d->sg+SG_OFF;
291     + d->sg=calloc(1, sizeof (struct sg_info));
292     + ((struct sg_info *)d->sg)->dxferp_max_buffer_len = CD_FRAMESIZE_RAW;
293     + sg2_init_sg_info(d);
294    
295     {
296     /* get the lun */
297     @@ -614,6 +761,8 @@
298     }
299    
300     p = scsi_inquiry(d);
301     + if (!p)
302     + goto cdda_identify_scsi_fail;
303    
304     /* It would seem some TOSHIBA CDROMs gets things wrong */
305    
306     @@ -632,12 +781,11 @@
307     goto cdda_identify_scsi_fail;
308     }
309    
310     - d->drive_model=calloc(36,1);
311     memcpy(d->inqbytes,p,4);
312     d->cdda_device_name=copystring(generic_device);
313     d->ioctl_device_name=copystring(ioctl_device);
314    
315     - d->drive_model=calloc(36,1);
316     + d->drive_model=calloc(1, 36);
317     strscat(d->drive_model,p+8,8);
318     strscat(d->drive_model,p+16,16);
319     strscat(d->drive_model,p+32,4);
320     @@ -647,6 +795,22 @@
321     return(d);
322    
323     cdda_identify_scsi_fail:
324     + if (d) {
325     + if (d->drive_model)
326     + free(d->drive_model);
327     + if (d->sg) {
328     + struct sg_info *sgi = (struct sg_info *)d->sg;
329     +
330     + if (sgi->cmdp_buffer_len)
331     + free(sgi->cmdp);
332     + if (sgi->dxferp_buffer_len)
333     + free(sgi->dxferp);
334     + if (sgi->hdr)
335     + free(sgi->hdr);
336     + free(d->sg);
337     + }
338     + free(d);
339     + }
340     if(generic_device)free((char *)generic_device);
341     if(ioctl_device)free((char *)ioctl_device);
342     if(i_fd!=-1)close(i_fd);
343     --- cdparanoia-III-alpha9.8/interface/scsi_interface.c.sgio 2001-03-23 20:15:46.000000000 -0500
344     +++ cdparanoia-III-alpha9.8/interface/scsi_interface.c 2004-03-30 14:19:29.826011776 -0500
345     @@ -3,6 +3,7 @@
346     * Original interface.c Copyright (C) 1994-1997
347     * Eissfeldt heiko@colossus.escape.de
348     * Current blenderization Copyright (C) 1998-1999 Monty xiphmont@mit.edu
349     + * Copyright 2004 Peter Jones <pjones@redhat.com>
350     *
351     * Generic SCSI interface specific code.
352     *
353     @@ -11,6 +12,7 @@
354     #include "low_interface.h"
355     #include "common_interface.h"
356     #include "utils.h"
357     +#include "scsi_cmds.h"
358    
359     /* hook */
360     static int Dummy (cdrom_drive *d,int s){
361     @@ -19,7 +21,290 @@
362    
363     #include "drive_exceptions.h"
364    
365     -static void tweak_SG_buffer(cdrom_drive *d){
366     +static void reset_scsi(cdrom_drive *d){
367     + struct sg_info *sgi = (struct sg_info *)d->sg;
368     + struct sg_io_hdr *hdr = sgi->hdr;
369     + unsigned char key, ASC, ASCQ;
370     + int arg, ret, tries;
371     + char cmd[6];
372     +
373     + d->enable_cdda(d,0);
374     +
375     + cdmessage(d,"sending SG SCSI reset... ");
376     + if(ioctl(d->cdda_fd,SG_SCSI_RESET,&arg))
377     + cdmessage(d,"FAILED: EBUSY\n");
378     + else
379     + cdmessage(d,"OK\n");
380     +
381     + tries = 0;
382     + while(1) {
383     + memcpy(cmd, SCSI_TEST_UNIT_READY_6, 6);
384     + sgi->setup_scsi_cmd(d, cmd, 6, 0, 56);
385     + ret = sgi->handle_scsi_cmd(d);
386     +
387     + key = hdr->sbp[2] & 0xf;
388     + ASC = hdr->sbp[12];
389     + ASCQ = hdr->sbp[13];
390     +
391     + if(key == 2 & ASC == 4 & ASCQ == 1 & tries < 10) {
392     + tries++;
393     + usleep(10);
394     + continue;
395     + }
396     + break;
397     + }
398     +
399     + d->enable_cdda(d,1);
400     +}
401     +
402     +static int check_sbp_error(const char *sbp) {
403     + char key = sbp[2] & 0xf;
404     + char ASC = sbp[12];
405     + char ASCQ = sbp[13];
406     +
407     + if (sbp[0]) {
408     + switch (key){
409     + case 0:
410     + if (errno==0)
411     + errno = EIO;
412     + return(TR_UNKNOWN);
413     + case 1:
414     + break;
415     + case 2:
416     + if (errno==0)
417     + errno = EBUSY;
418     + return(TR_BUSY);
419     + case 3:
420     + if ((ASC==0x0C) & (ASCQ==0x09)) {
421     + /* loss of streaming */
422     + if (errno==0)
423     + errno = EIO;
424     + return(TR_STREAMING);
425     + } else {
426     + if (errno==0)
427     + errno = EIO;
428     + return(TR_MEDIUM);
429     + }
430     + case 4:
431     + if (errno==0)
432     + errno = EIO;
433     + return(TR_FAULT);
434     + case 5:
435     + if (errno==0)
436     + errno = EINVAL;
437     + return(TR_ILLEGAL);
438     + default:
439     + if (errno==0)
440     + errno = EIO;
441     + return(TR_UNKNOWN);
442     + }
443     + }
444     + return 0;
445     +}
446     +
447     +#ifdef SG_IO
448     +int check_fd_sgio(int fd) {
449     + struct sg_io_hdr hdr;
450     +
451     + if (fd < 0)
452     + return fd;
453     +
454     + memset(&hdr, 0, sizeof (struct sg_io_hdr));
455     + /* First try with interface_id = 'A'; for all but the sg case,
456     + * that'll get us a -EINVAL if it supports SG_IO, and some other
457     + * error for all other cases. */
458     + hdr.interface_id = 'A';
459     + if (ioctl(fd, SG_IO, &hdr)) {
460     + switch (errno) {
461     + /* sr and ata give us EINVAL when SG_IO is supported
462     + * but interface_id is bad. */
463     + case EINVAL:
464     + /* sg gives us ENOSYS when SG_IO is supported but
465     + * interface_id is bad. IMHO, this is wrong and
466     + * needs fixing in the kernel. */
467     + case ENOSYS:
468     + return fd;
469     + /* everything else gives ENOTTY, I think. I'm just
470     + * going to be paranoid and reject everything else. */
471     + default:
472     + return -errno;
473     + }
474     + }
475     + /* if we get here, something is dreadfuly wrong. ioctl(fd,SG_IO,&hdr)
476     + * handled SG_IO, but took hdr.interface_id = 'A' as valid, and an empty
477     + * command as good. Don't trust it. */
478     + return -1;
479     +}
480     +
481     +static void sgio_tweak_SG_buffer(cdrom_drive *d) {
482     + int table, reserved, cur, err;
483     + char buffer[256];
484     +
485     + /* SG_SET_RESERVED_SIZE doesn't actually allocate or reserve anything.
486     + * what it _does_ do is give you an error if you ask for a value
487     + * larger than q->max_sectors (the length of the device's bio request
488     + * queue). So we walk it up from 1 sector until it fails, then get
489     + * the value we set it to last.
490     + */
491     + /* start with 2 frames, round down to our queue's sector size */
492     + cur = 1;
493     + do {
494     + cur <<= 1; reserved = cur * (1<<9);
495     + err = ioctl(d->cdda_fd, SG_SET_RESERVED_SIZE, &reserved);
496     + } while(err >= 0);
497     + ioctl(d->cdda_fd, SG_GET_RESERVED_SIZE, &reserved);
498     +
499     + cur = 0;
500     + /* this doesn't currently ever work, but someday somebody might
501     + implement working sg lists with SG_IO devices, so who knows... */
502     + table=1;
503     + if (ioctl(d->cdda_fd, SG_GET_SG_TABLESIZE, &table) < 0)
504     + table=1;
505     +
506     + sprintf(buffer,"\tDMA scatter/gather table entries: %d\n\t"
507     + "table entry size: %d bytes\n\t"
508     + "maximum theoretical transfer: %d sectors\n",
509     + table, reserved, table*reserved/CD_FRAMESIZE_RAW);
510     + cdmessage(d,buffer);
511     +
512     + cur=table*reserved;
513     +
514     + ((struct sg_info *)d->sg)->dxferp_max_buffer_len = cur;
515     +
516     + /* so since we never go above q->max_sectors, we should never get -EIO.
517     + * we might still get -ENOMEM, but we back off for that later. Monty
518     + * had an old comment: "not too much; new kernels have trouble with DMA
519     + * "allocation, so be more conservative: 32kB max until I test more
520     + * thoroughly". We're not currently honoring that, because we should
521     + * always get -ENOMEM.
522     + */
523     +#if 0
524     + cur=(cur>1024*32?1024*32:cur);
525     +#endif
526     + d->nsectors=cur/CD_FRAMESIZE_RAW;
527     + d->bigbuff=cur;
528     +
529     + sprintf(buffer,"\tSetting default read size to %d sectors (%d bytes).\n\n",
530     + d->nsectors,d->nsectors*CD_FRAMESIZE_RAW);
531     + cdmessage(d,buffer);
532     +}
533     +
534     +static void sgio_setup_scsi_cmd(cdrom_drive *d,
535     + char *cmdp,
536     + unsigned int cmd_len,
537     + unsigned int in_size,
538     + unsigned int out_size) {
539     + struct sg_info *sgi = (struct sg_info *)d->sg;
540     + struct sg_io_hdr *hdr = sgi->hdr;
541     +
542     + memset(hdr->cmdp, 0, sgi->cmdp_buffer_len);
543     + memset(hdr->dxferp, sgi->bytefill, sgi->dxferp_buffer_len);
544     + memcpy(hdr->cmdp, cmdp, cmd_len);
545     +
546     + hdr->cmd_len = cmd_len;
547     +
548     + sgi->in_size = in_size;
549     + sgi->out_size = out_size;
550     +}
551     +
552     +static int sgio_handle_scsi_cmd(cdrom_drive *d) {
553     + int status = 0;
554     + struct sg_info *sgi = (struct sg_info *)d->sg;
555     + struct sg_io_hdr *hdr = sgi->hdr;
556     +
557     + if (sgi->in_size) {
558     + hdr->dxfer_len = sgi->in_size;
559     + hdr->dxfer_direction = SG_DXFER_TO_DEV;
560     +
561     + errno = 0;
562     + status = ioctl(d->cdda_fd, SG_IO, hdr);
563     + if (status >= 0)
564     + if (hdr->status)
565     + status = check_sbp_error(hdr->sbp);
566     + if (status < 0)
567     + return TR_EWRITE;
568     + }
569     + if (!sgi->in_size | sgi->out_size) {
570     + hdr->dxfer_len = sgi->out_size;
571     + hdr->dxfer_direction = sgi->out_size ? SG_DXFER_FROM_DEV : SG_DXFER_NONE;
572     +
573     + errno = 0;
574     + status = ioctl(d->cdda_fd, SG_IO, hdr);
575     + if (status < 0)
576     + return TR_EREAD;
577     + if (status >= 0)
578     + if (hdr->status)
579     + status = check_sbp_error(hdr->sbp);
580     + }
581     + if (status)
582     + return status;
583     +
584     + errno = 0;
585     + return 0;
586     +}
587     +
588     +void sgio_init_sg_info(cdrom_drive *d) {
589     + struct sg_info *sgi = (struct sg_info *)d->sg;
590     + struct sg_io_hdr *hdr;
591     +
592     + hdr = calloc(sizeof (struct sg_io_hdr), 1);
593     +
594     + sgi->cmdp = hdr->cmdp = calloc(128, 1);
595     + sgi->cmdp_buffer_len = 128;
596     +
597     + hdr->sbp = calloc(SG_MAX_SENSE,1);
598     + hdr->mx_sb_len = SG_MAX_SENSE;
599     +
600     + sgi->bytefill = '\xff';
601     + sgi->bytecheck = 0;
602     +
603     + hdr->timeout = 5000;
604     + hdr->interface_id = 'S';
605     +
606     + sgi->hdr = hdr;
607     +
608     + sgi->setup_scsi_cmd = sgio_setup_scsi_cmd;
609     + sgi->handle_scsi_cmd = sgio_handle_scsi_cmd;
610     +
611     + sgio_tweak_SG_buffer(d);
612     +
613     + sgi->dxferp = hdr->dxferp = calloc(sgi->dxferp_max_buffer_len, 1);
614     + sgi->dxferp_buffer_len = sgi->dxferp_max_buffer_len;
615     +}
616     +#endif
617     +
618     +static void sg2_clear_garbage(cdrom_drive *d){
619     + fd_set fdset;
620     + struct timeval tv;
621     + struct sg_header *sg_hd = (struct sg_header *)((struct sg_info *)d->sg)->hdr;
622     + int flag = 0;
623     +
624     + /* clear out any possibly preexisting garbage */
625     + FD_ZERO(&fdset);
626     + FD_SET(d->cdda_fd,&fdset);
627     + tv.tv_sec=0;
628     + tv.tv_usec=0;
629     +
630     + /* I like select */
631     + while(select(d->cdda_fd+1,&fdset,NULL,NULL,&tv)==1){
632     +
633     + sg_hd->twelve_byte = 0;
634     + sg_hd->result = 0;
635     + sg_hd->reply_len = SG_OFF;
636     + read(d->cdda_fd, sg_hd, 1);
637     +
638     + /* reset for select */
639     + FD_ZERO(&fdset);
640     + FD_SET(d->cdda_fd,&fdset);
641     + tv.tv_sec=0;
642     + tv.tv_usec=0;
643     + if(!flag && d->report_all)
644     + cdmessage(d,"Clearing previously returned data from SCSI buffer\n");
645     + flag=1;
646     + }
647     +}
648     +
649     +static void sg2_tweak_SG_buffer(cdrom_drive *d){
650     int table,reserved;
651     char buffer[256];
652    
653     @@ -58,74 +343,47 @@
654     if(ioctl(d->cdda_fd,SG_SET_COMMAND_Q,&reserved)){
655     cdmessage(d,"\tCouldn't disable command queue! Continuing anyway...\n");
656     }
657     -
658     }
659    
660     -static void reset_scsi(cdrom_drive *d){
661     - int arg;
662     - d->enable_cdda(d,0);
663     -
664     - cdmessage(d,"sending SG SCSI reset... ");
665     - if(ioctl(d->cdda_fd,SG_SCSI_RESET,&arg))
666     - cdmessage(d,"FAILED: EBUSY\n");
667     - else
668     - cdmessage(d,"OK\n");
669     -
670     - d->enable_cdda(d,1);
671     -}
672     +/* process a complete scsi command. */
673    
674     -static void clear_garbage(cdrom_drive *d){
675     - fd_set fdset;
676     - struct timeval tv;
677     - struct sg_header *sg_hd=(struct sg_header *)d->sg;
678     - int flag=0;
679     +static void sg2_setup_scsi_cmd(cdrom_drive *d,
680     + char *cmdp,
681     + unsigned int cmd_len,
682     + unsigned int in_size,
683     + unsigned int out_size) {
684     + struct sg_info *sgi = (struct sg_info *)d->sg;
685     + struct sg_header *hdr = (struct sg_header *)sgi->hdr;
686    
687     - /* clear out any possibly preexisting garbage */
688     - FD_ZERO(&fdset);
689     - FD_SET(d->cdda_fd,&fdset);
690     - tv.tv_sec=0;
691     - tv.tv_usec=0;
692     + sgi->cmdp = (char *)hdr + sizeof (struct sg_header);
693     + memcpy(sgi->cmdp, cmdp, cmd_len);
694    
695     - /* I like select */
696     - while(select(d->cdda_fd+1,&fdset,NULL,NULL,&tv)==1){
697     -
698     - sg_hd->twelve_byte = 0;
699     - sg_hd->result = 0;
700     - sg_hd->reply_len = SG_OFF;
701     - read(d->cdda_fd, sg_hd, 1);
702     + sgi->dxferp = sgi->cmdp + cmd_len;
703     + memset(sgi->dxferp, sgi->bytefill, sgi->dxferp_max_buffer_len - cmd_len);
704    
705     - /* reset for select */
706     - FD_ZERO(&fdset);
707     - FD_SET(d->cdda_fd,&fdset);
708     - tv.tv_sec=0;
709     - tv.tv_usec=0;
710     - if(!flag && d->report_all)
711     - cdmessage(d,"Clearing previously returned data from SCSI buffer\n");
712     - flag=1;
713     - }
714     + sgi->in_size = in_size;
715     + sgi->out_size = out_size;
716     }
717    
718     -/* process a complete scsi command. */
719     -static int handle_scsi_cmd(cdrom_drive *d,
720     - unsigned int cmd_len,
721     - unsigned int in_size,
722     - unsigned int out_size,
723     -
724     - unsigned char bytefill,
725     - int bytecheck){
726     +static int sg2_handle_scsi_cmd(cdrom_drive *d) {
727     int status = 0;
728     - struct sg_header *sg_hd=(struct sg_header *)d->sg;
729     - long writebytes=SG_OFF+cmd_len+in_size;
730     + struct sg_info *sgi = (struct sg_info *)d->sg;
731     + struct sg_header *sg_hd = (struct sg_header *)sgi->hdr;
732     +
733     + int out_size = sgi->out_size;
734     + int in_size = sgi->in_size;
735     +
736     + long writebytes = (int)(sg_hd) + SG_OFF + sgi->cmd_len + sgi->in_size;
737    
738     /* generic scsi device services */
739    
740     /* clear out any possibly preexisting garbage */
741     - clear_garbage(d);
742     + sg2_clear_garbage(d);
743    
744     - memset(sg_hd,0,sizeof(sg_hd));
745     - sg_hd->twelve_byte = cmd_len == 12;
746     + memset(sg_hd,0, SG_OFF);
747     + sg_hd->twelve_byte = sgi->cmd_len == 12;
748     sg_hd->result = 0;
749     - sg_hd->reply_len = SG_OFF + out_size;
750     + sg_hd->reply_len = SG_OFF + sgi->out_size;
751    
752     /* The following is one of the scariest hacks I've ever had to use.
753     The idea is this: We want to know if a command fails. The
754     @@ -135,8 +393,8 @@
755     length for a command that doesn't take data) such that we can
756     tell if the command failed. Scared yet? */
757    
758     - if(bytecheck && out_size>in_size){
759     - memset(d->sg_buffer+cmd_len+in_size,bytefill,out_size-in_size);
760     + if(sgi->bytecheck && out_size>in_size){
761     + /* the memset for this is done in sg2_setup_scsi_cmd() */
762     /* the size does not remove cmd_len due to the way the kernel
763     driver copies buffers */
764     writebytes+=(out_size-in_size);
765     @@ -224,40 +482,10 @@
766     if(errno==0)errno=EIO;
767     return(TR_EREAD);
768     }
769     -
770     - if(sg_hd->sense_buffer[0]){
771     - char key=sg_hd->sense_buffer[2]&0xf;
772     - char ASC=sg_hd->sense_buffer[12];
773     - char ASCQ=sg_hd->sense_buffer[13];
774     - switch(key){
775     - case 0:
776     - if(errno==0)errno=EIO;
777     - return(TR_UNKNOWN);
778     - case 1:
779     - break;
780     - case 2:
781     - if(errno==0)errno=EBUSY;
782     - return(TR_BUSY);
783     - case 3:
784     - if(ASC==0x0C && ASCQ==0x09){
785     - /* loss of streaming */
786     - if(errno==0)errno=EIO;
787     - return(TR_STREAMING);
788     - }else{
789     - if(errno==0)errno=EIO;
790     - return(TR_MEDIUM);
791     - }
792     - case 4:
793     - if(errno==0)errno=EIO;
794     - return(TR_FAULT);
795     - case 5:
796     - if(errno==0)errno=EINVAL;
797     - return(TR_ILLEGAL);
798     - default:
799     - if(errno==0)errno=EIO;
800     - return(TR_UNKNOWN);
801     - }
802     - }
803     +
804     + status = check_sbp_error(sg_hd->sense_buffer);
805     + if (status)
806     + return status;
807    
808     /* still not foolproof; the following doesn't guarantee that we got
809     all the data, just that the command was not rejected. */
810     @@ -266,10 +494,11 @@
811     commands still get through. Perhaps no data comes back even
812     though the target reports success? */
813    
814     - if(bytecheck && in_size+cmd_len<out_size){
815     + if(sgi->bytecheck && sgi->in_size+sgi->cmd_len<sgi->out_size){
816     long i,flag=0;
817     - for(i=in_size;i<out_size;i++)
818     - if(d->sg_buffer[i]!=bytefill){
819     + for(i=sgi->in_size; i<sgi->out_size; i++)
820     + /* XXX check this offset */
821     + if((sgi->dxferp[i])!=(sgi->bytefill)){
822     flag=1;
823     break;
824     }
825     @@ -284,61 +513,67 @@
826     return(0);
827     }
828    
829     -/* Group 1 (10b) command */
830     +void sg2_init_sg_info(cdrom_drive *d) {
831     + struct sg_info *sgi = (struct sg_info *)d->sg;
832     + struct sg_header *hdr;
833    
834     -static int mode_sense_atapi(cdrom_drive *d,int size,int page){
835     - memcpy(d->sg_buffer,
836     - (char []) {0x5A, /* MODE_SENSE */
837     - 0x00, /* reserved */
838     - 0x00, /* page */
839     - 0, /* reserved */
840     - 0, /* reserved */
841     - 0, /* reserved */
842     - 0, /* reserved */
843     - 0, /* MSB (0) */
844     - 0, /* sizeof(modesense - SG_OFF) */
845     - 0}, /* reserved */
846     - 10);
847     -
848     - d->sg_buffer[1]=d->lun<<5;
849     - d->sg_buffer[2]=0x3F&page;
850     - d->sg_buffer[8]=size+4;
851     + hdr = calloc(sizeof (struct sg_header)+sgi->dxferp_max_buffer_len, 1);
852    
853     - if (handle_scsi_cmd (d, 10, 0, size+4,'\377',1)) return(1);
854     + sgi->cmdp = (char *)hdr + sizeof (struct sg_header);
855     + sgi->cmdp_buffer_len = 0;
856    
857     - {
858     - char *b=d->sg_buffer;
859     - if(b[0])return(1); /* Handles only up to 256 bytes */
860     - if(b[6])return(1); /* Handles only up to 256 bytes */
861     -
862     - b[0]=b[1]-3;
863     - b[1]=b[2];
864     - b[2]=b[3];
865     - b[3]=b[7];
866     + sgi->bytefill = '\xff';
867     + sgi->bytecheck = 1;
868    
869     - memmove(b+4,b+8,size);
870     - }
871     - return(0);
872     + sgi->setup_scsi_cmd = sg2_setup_scsi_cmd;
873     + sgi->handle_scsi_cmd = sg2_handle_scsi_cmd;
874     +
875     + sg2_tweak_SG_buffer(d);
876     +
877     + // sgi->dxferp = hdr + sizeof (struct sg_header);
878     + sgi->dxferp = NULL;
879     + sgi->dxferp_buffer_len = 0;
880     +}
881     +
882     +static int mode_sense_atapi(cdrom_drive *d, int size, int page) {
883     + char *buffer;
884     +
885     + ((struct sg_info *)d->sg)->setup_scsi_cmd(d, SCSI_MODE_SENSE_10(page,size), 10, 0, size);
886     +
887     + buffer = ((struct sg_info *)d->sg)->dxferp;
888     +#if 0
889     + buffer[1]=d->lun<<5;
890     +#endif
891     +
892     + if (((struct sg_info *)d->sg)->handle_scsi_cmd(d))
893     + return 1;
894     +
895     + if(buffer[0])return(1); /* Handles only up to 256 bytes */
896     + if(buffer[6])return(1); /* Handles only up to 256 bytes */
897     +
898     + buffer[0]=buffer[1]-3;
899     + buffer[1]=buffer[2];
900     + buffer[2]=buffer[3];
901     + buffer[3]=buffer[7];
902     +
903     + memmove(buffer+4,buffer+8,size);
904     + return 0;
905     }
906    
907     /* group 0 (6b) command */
908    
909     static int mode_sense_scsi(cdrom_drive *d,int size,int page){
910     - memcpy(d->sg_buffer,
911     - (char []) {0x1A, /* MODE_SENSE */
912     - 0x00, /* return block descriptor/lun */
913     - 0x00, /* page */
914     - 0, /* reserved */
915     - 0, /* sizeof(modesense - SG_OFF) */
916     - 0}, /* control */
917     - 6);
918     + char *buffer;
919     + ((struct sg_info *)d->sg)->setup_scsi_cmd(d, SCSI_MODE_SENSE_6(page, size), 6, 0, size);
920    
921     - d->sg_buffer[1]=d->lun<<5;
922     - d->sg_buffer[2]=(0x3F&page);
923     - d->sg_buffer[4]=size;
924     -
925     - if (handle_scsi_cmd (d, 6, 0, size, '\377',1)) return(1);
926     - return(0);
927     + buffer = ((struct sg_info *)d->sg)->dxferp;
928     +#if 0
929     + buffer[1]=d->lun<<5;
930     +#endif
931     +
932     + if (((struct sg_info *)d->sg)->handle_scsi_cmd(d))
933     + return 1;
934     + return 0;
935     }
936    
937     static int mode_sense(cdrom_drive *d,int size,int page){
938     @@ -347,80 +582,77 @@
939     return(mode_sense_scsi(d,size,page));
940     }
941    
942     -static int mode_select(cdrom_drive *d,int density,int secsize){
943     - /* short circut the way Heiko does it; less flexible, but shorter */
944     - if(d->is_atapi){
945     - unsigned char *mode = d->sg_buffer + 18;
946     +static int atapi_mode_select(cdrom_drive *d, int density, int secsize) {
947     + unsigned char *mode;
948    
949     - memcpy(d->sg_buffer,
950     - (char []) { 0x55, /* MODE_SELECT */
951     - 0x10, /* no save page */
952     - 0, /* reserved */
953     - 0, /* reserved */
954     - 0, /* reserved */
955     - 0, /* reserved */
956     - 0, /* reserved */
957     - 0, /* reserved */
958     - 12, /* sizeof(mode) */
959     - 0, /* reserved */
960     -
961     - /* mode parameter header */
962     - 0, 0, 0, 0, 0, 0, 0,
963     - 8, /* Block Descriptor Length */
964     -
965     - /* descriptor block */
966     - 0, /* Density Code */
967     - 0, 0, 0, /* # of Blocks */
968     - 0, /* reserved */
969     - 0, 0, 0},/* Blocklen */
970     - 26);
971     -
972     - d->sg_buffer[1]|=d->lun<<5;
973     -
974     - /* prepare to read cds in the previous mode */
975     - mode [0] = density;
976     - mode [6] = secsize >> 8; /* block length "msb" */
977     - mode [7] = secsize & 0xFF; /* block length lsb */
978     + ((struct sg_info *)d->sg)->setup_scsi_cmd(d, SCSI_MODE_SELECT_10, 10, 16, 0);
979     + memcpy(((struct sg_info *)d->sg)->dxferp,(char []) {
980     + /* mode parameter header */
981     + 0, 0, 0, 0, 0, 0, 0,
982     + 8, /* Block Descriptor Length */
983     + /* descriptor block */
984     + 0, /* Density Code */
985     + 0, 0, 0, /* # of Blocks */
986     + 0, /* reserved */
987     + 0, 0, 0},/* Blocklen */
988     + 16);
989     +
990     + mode = ((struct sg_info *)d->sg)->dxferp;
991     +#if 0
992     + mode[1] |= d->lun << 5;
993     +#endif
994     + /* prepare to read cds in the previous mode */
995     + mode[8] = density;
996     + mode[14] = secsize >> 8; /* block length "msb" */
997     + mode[15] = secsize & 0xFF; /* block length lsb */
998     +
999     + /* do the scsi cmd */
1000     + return ((struct sg_info *)d->sg)->handle_scsi_cmd(d);
1001     +}
1002     +
1003     +static int scsi_mode_select(cdrom_drive *d, int density, int secsize) {
1004     + unsigned char *mode;
1005     +
1006     + ((struct sg_info *)d->sg)->setup_scsi_cmd(d, SCSI_MODE_SELECT_6, 6, 12, 0);
1007     + memcpy(((struct sg_info *)d->sg)->dxferp,(char []) {
1008     + /* mode section */
1009     + 0,
1010     + 0, 0,
1011     + 8, /* Block Descriptor Length */
1012     + 0, /* Density Code */
1013     + 0, 0, 0, /* # of Blocks */
1014     + 0, /* reserved */
1015     + 0, 0, 0},/* Blocklen */
1016     + 12);
1017     +
1018     + /* prepare to read cds in the previous mode */
1019     + mode = ((struct sg_info *)d->sg)->dxferp;
1020     + mode [4] = density;
1021     + mode [10] = secsize >> 8; /* block length "msb" */
1022     + mode [11] = secsize & 0xFF; /* block length lsb */
1023    
1024     /* do the scsi cmd */
1025     - return(handle_scsi_cmd (d,10, 16, 0,0,0));
1026     -
1027     - }else{
1028     - unsigned char *mode = d->sg_buffer + 10;
1029     -
1030     - memcpy(d->sg_buffer,
1031     - (char []) { 0x15, /* MODE_SELECT */
1032     - 0x10, /* no save page */
1033     - 0, /* reserved */
1034     - 0, /* reserved */
1035     - 12, /* sizeof(mode) */
1036     - 0, /* reserved */
1037     - /* mode section */
1038     - 0,
1039     - 0, 0,
1040     - 8, /* Block Descriptor Length */
1041     - 0, /* Density Code */
1042     - 0, 0, 0, /* # of Blocks */
1043     - 0, /* reserved */
1044     - 0, 0, 0},/* Blocklen */
1045     - 18);
1046     -
1047     - /* prepare to read cds in the previous mode */
1048     - mode [0] = density;
1049     - mode [6] = secsize >> 8; /* block length "msb" */
1050     - mode [7] = secsize & 0xFF; /* block length lsb */
1051     + return ((struct sg_info *)d->sg)->handle_scsi_cmd(d);
1052     +}
1053    
1054     - /* do the scsi cmd */
1055     - return(handle_scsi_cmd (d,6, 12, 0,0,0));
1056     - }
1057     +static int mode_select(cdrom_drive *d, int density, int secsize) {
1058     + /* short circut the way Heiko does it; less flexible, but shorter */
1059     + if (d->is_atapi)
1060     + return atapi_mode_select(d, density, secsize);
1061     + return scsi_mode_select(d, density, secsize);
1062     }
1063    
1064     /* get current sector size from SCSI cdrom drive */
1065     static unsigned int get_orig_sectorsize(cdrom_drive *d){
1066     - if(mode_sense(d,12,0x01))return(-1);
1067     + if (mode_sense(d,12,0x01))
1068     + return -1;
1069     +
1070     + d->orgdens = ((struct sg_info *)d->sg)->dxferp[4];
1071     +
1072     + d->orgsize = (int)(((struct sg_info *)d->sg)->dxferp[10]<<8);
1073     + d->orgsize += (int)((struct sg_info *)d->sg)->dxferp[11];
1074    
1075     - d->orgdens = d->sg_buffer[4];
1076     - return(d->orgsize = ((int)(d->sg_buffer[10])<<8)+d->sg_buffer[11]);
1077     + return d->orgsize;
1078     }
1079    
1080     /* switch CDROM scsi drives to given sector size */
1081     @@ -463,23 +695,23 @@
1082     fails on at least one Kodak drive. */
1083    
1084     static int scsi_read_toc (cdrom_drive *d){
1085     + struct sg_info *sgi = (struct sg_info *)d->sg;
1086     int i,first,last;
1087     unsigned tracks;
1088     -
1089     - /* READTOC, MSF format flag, res, res, res, res, Start track, len msb,
1090     - len lsb, flags */
1091     + scsi_TOC *toc;
1092    
1093     /* read the header first */
1094     - memcpy(d->sg_buffer, (char []){ 0x43, 0, 0, 0, 0, 0, 1, 0, 12, 0}, 10);
1095     - d->sg_buffer[1]=d->lun<<5;
1096     -
1097     - if (handle_scsi_cmd (d,10, 0, 12,'\377',1)){
1098     + sgi->setup_scsi_cmd(d, SCSI_READ_TOC(1), 10, 0, 12);
1099     +#if 0
1100     + sgi->dxferp[1] = d->lun << 5;
1101     +#endif
1102     + if (sgi->handle_scsi_cmd(d)) {
1103     cderror(d,"004: Unable to read table of contents header\n");
1104     return(-4);
1105     }
1106    
1107     - first=d->sg_buffer[2];
1108     - last=d->sg_buffer[3];
1109     + first = sgi->dxferp[2];
1110     + last = sgi->dxferp[3];
1111     tracks=last-first+1;
1112    
1113     if (last > MAXTRK || first > MAXTRK || last<0 || first<0) {
1114     @@ -488,335 +720,208 @@
1115     }
1116    
1117     for (i = first; i <= last; i++){
1118     - memcpy(d->sg_buffer, (char []){ 0x43, 0, 0, 0, 0, 0, 0, 0, 12, 0}, 10);
1119     - d->sg_buffer[1]=d->lun<<5;
1120     - d->sg_buffer[6]=i;
1121     + sgi->setup_scsi_cmd(d, SCSI_READ_TOC(i), 10, 0, 12);
1122     +#if 0
1123     + sgi->dxferp[1] = d->lun << 5;
1124     +#endif
1125    
1126     - if (handle_scsi_cmd (d,10, 0, 12,'\377',1)){
1127     + if (sgi->handle_scsi_cmd(d)) {
1128     cderror(d,"005: Unable to read table of contents entry\n");
1129     return(-5);
1130     }
1131     - {
1132     - scsi_TOC *toc=(scsi_TOC *)(d->sg_buffer+4);
1133     -
1134     - d->disc_toc[i-first].bFlags=toc->bFlags;
1135     - d->disc_toc[i-first].bTrack=i;
1136     - d->disc_toc[i-first].dwStartSector= d->adjust_ssize *
1137     - (((int)(toc->start_MSB)<<24) |
1138     - (toc->start_1<<16)|
1139     - (toc->start_2<<8)|
1140     - (toc->start_LSB));
1141     - }
1142     - }
1143     + toc = (scsi_TOC *)(sgi->dxferp+4);
1144     + d->disc_toc[i-first].bFlags = toc->bFlags;
1145     + d->disc_toc[i-first].bTrack = i;
1146     + d->disc_toc[i-first].dwStartSector =
1147     + d->adjust_ssize * (
1148     + ((int)(toc->start_MSB)<<24) | (toc->start_1 << 16) |
1149     + (toc->start_2 << 8) | (toc->start_LSB)
1150     + );
1151     + }
1152     +
1153     + sgi->setup_scsi_cmd(d, SCSI_READ_TOC(0xAA), 10, 0, 12);
1154     +#if 0
1155     + sgi->dxferp[1] = d->lun << 5;
1156     +#endif
1157    
1158     - memcpy(d->sg_buffer, (char []){ 0x43, 0, 0, 0, 0, 0, 0, 0, 12, 0}, 10);
1159     - d->sg_buffer[1]=d->lun<<5;
1160     - d->sg_buffer[6]=0xAA;
1161     -
1162     - if (handle_scsi_cmd (d,10, 0, 12,'\377',1)){
1163     + if (sgi->handle_scsi_cmd(d)) {
1164     cderror(d,"002: Unable to read table of contents lead-out\n");
1165     return(-2);
1166     }
1167     - {
1168     - scsi_TOC *toc=(scsi_TOC *)(d->sg_buffer+4);
1169     -
1170     - d->disc_toc[i-first].bFlags=toc->bFlags;
1171     - d->disc_toc[i-first].bTrack=0xAA;
1172     - d->disc_toc[i-first].dwStartSector= d->adjust_ssize *
1173     - (((int)(toc->start_MSB)<<24) |
1174     - (toc->start_1<<16)|
1175     - (toc->start_2<<8)|
1176     - (toc->start_LSB));
1177     - }
1178     +
1179     + toc = (scsi_TOC *)(sgi->dxferp+4);
1180     + d->disc_toc[i-first].bFlags = toc->bFlags;
1181     + d->disc_toc[i-first].bTrack = 0xAA;
1182     + d->disc_toc[i-first].dwStartSector =
1183     + d->adjust_ssize * (
1184     + ((int)(toc->start_MSB)<<24) | (toc->start_1 << 16) |
1185     + (toc->start_2 << 8) | (toc->start_LSB)
1186     + );
1187    
1188     d->cd_extra = FixupTOC(d,tracks+1); /* include lead-out */
1189     - return(tracks);
1190     + return tracks;
1191     }
1192    
1193     /* a contribution from Boris for IMS cdd 522 */
1194     /* check this for ACER/Creative/Foo 525,620E,622E, etc? */
1195     static int scsi_read_toc2 (cdrom_drive *d){
1196     - u_int32_t foo,bar;
1197     + struct sg_info *sgi = (struct sg_info *)d->sg;
1198     + u_int32_t msb,lsb;
1199    
1200     int i;
1201     unsigned tracks;
1202    
1203     - memcpy(d->sg_buffer, (char[]){ 0xe5, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10);
1204     - d->sg_buffer[5]=1;
1205     - d->sg_buffer[8]=255;
1206     -
1207     - if (handle_scsi_cmd (d,10, 0, 256,'\377',1)){
1208     + sgi->setup_scsi_cmd(d, CDD522_READ_TOC(1), 10, 0, 256);
1209     + if (sgi->handle_scsi_cmd(d)) {
1210     cderror(d,"004: Unable to read table of contents header\n");
1211     return(-4);
1212     }
1213    
1214     /* copy to our structure and convert start sector */
1215     - tracks = d->sg_buffer[1];
1216     + tracks = sgi->dxferp[1];
1217     if (tracks > MAXTRK) {
1218     cderror(d,"003: CDROM reporting illegal number of tracks\n");
1219     return(-3);
1220     }
1221    
1222     for (i = 0; i < tracks; i++){
1223     - memcpy(d->sg_buffer, (char[]){ 0xe5, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10);
1224     - d->sg_buffer[5]=i+1;
1225     - d->sg_buffer[8]=255;
1226     + sgi->setup_scsi_cmd(d, CDD522_READ_TOC(i+1), 10, 0, 256);
1227    
1228     - if (handle_scsi_cmd (d,10, 0, 256,'\377',1)){
1229     + if (sgi->handle_scsi_cmd(d)) {
1230     cderror(d,"005: Unable to read table of contents entry\n");
1231     return(-5);
1232     }
1233    
1234     - d->disc_toc[i].bFlags = d->sg_buffer[10];
1235     + d->disc_toc[i].bFlags = sgi->dxferp[10];
1236     d->disc_toc[i].bTrack = i + 1;
1237    
1238     - d->disc_toc[i].dwStartSector= d->adjust_ssize *
1239     - (((signed char)(d->sg_buffer[2])<<24) |
1240     - (d->sg_buffer[3]<<16)|
1241     - (d->sg_buffer[4]<<8)|
1242     - (d->sg_buffer[5]));
1243     + d->disc_toc[i].dwStartSector = d->adjust_ssize * (
1244     + ((signed char)(sgi->dxferp[2])<<24) |
1245     + (sgi->dxferp[3]<<16) |
1246     + (sgi->dxferp[4]<<8) |
1247     + (sgi->dxferp[5])
1248     + );
1249     }
1250    
1251     d->disc_toc[i].bFlags = 0;
1252     d->disc_toc[i].bTrack = i + 1;
1253     - memcpy (&foo, d->sg_buffer+2, 4);
1254     - memcpy (&bar, d->sg_buffer+6, 4);
1255     - d->disc_toc[i].dwStartSector = d->adjust_ssize * (be32_to_cpu(foo) +
1256     - be32_to_cpu(bar));
1257     -
1258     - d->disc_toc[i].dwStartSector= d->adjust_ssize *
1259     - ((((signed char)(d->sg_buffer[2])<<24) |
1260     - (d->sg_buffer[3]<<16)|
1261     - (d->sg_buffer[4]<<8)|
1262     - (d->sg_buffer[5]))+
1263     -
1264     - ((((signed char)(d->sg_buffer[6])<<24) |
1265     - (d->sg_buffer[7]<<16)|
1266     - (d->sg_buffer[8]<<8)|
1267     - (d->sg_buffer[9]))));
1268     -
1269     + memcpy (&msb, sgi->dxferp+2, 4);
1270     + memcpy (&lsb, sgi->dxferp+6, 4);
1271     + d->disc_toc[i].dwStartSector = d->adjust_ssize *
1272     + (be32_to_cpu(msb) + be32_to_cpu(lsb));
1273     +
1274     + d->disc_toc[i].dwStartSector= d->adjust_ssize * (
1275     + ((((signed char)(sgi->dxferp[2])<<24) |
1276     + (sgi->dxferp[3]<<16) |
1277     + (sgi->dxferp[4]<<8) |
1278     + (sgi->dxferp[5])
1279     + ) + (
1280     + ((signed char)(sgi->dxferp[6])<<24) |
1281     + (sgi->dxferp[7]<<16) |
1282     + (sgi->dxferp[8]<<8) |
1283     + (sgi->dxferp[9])))
1284     + );
1285    
1286     d->cd_extra = FixupTOC(d,tracks+1);
1287     - return(tracks);
1288     + return tracks;
1289     }
1290    
1291     /* These do one 'extra' copy in the name of clean code */
1292    
1293     -static int i_read_28 (cdrom_drive *d, void *p, long begin, long sectors){
1294     +static int generic_scsi_read(cdrom_drive *d, void *p, long begin, long sectors,
1295     + char *read_cmd, int len, int in_size, int out_size) {
1296     + struct sg_info *sgi = (struct sg_info *)d->sg;
1297     int ret;
1298     - memcpy(d->sg_buffer,(char []){0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0},10);
1299     -
1300     - if(d->fua)
1301     - d->sg_buffer[1]=0x08;
1302    
1303     - d->sg_buffer[1]|=d->lun<<5;
1304     + sgi->setup_scsi_cmd(d, read_cmd, len, in_size, out_size);
1305     +#if 0
1306     + sgi->dxferp[1] = d->lun << 5;
1307     +#endif
1308    
1309     - d->sg_buffer[3] = (begin >> 16) & 0xFF;
1310     - d->sg_buffer[4] = (begin >> 8) & 0xFF;
1311     - d->sg_buffer[5] = begin & 0xFF;
1312     - d->sg_buffer[8] = sectors;
1313     - if((ret=handle_scsi_cmd(d,10,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1314     - return(ret);
1315     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1316     - return(0);
1317     + ret = sgi->handle_scsi_cmd(d);
1318     + if (ret)
1319     + return ret;
1320     + if (p)
1321     + memcpy(p, sgi->dxferp, sectors * CD_FRAMESIZE_RAW);
1322     + return 0;
1323     }
1324    
1325     -static int i_read_A8 (cdrom_drive *d, void *p, long begin, long sectors){
1326     - int ret;
1327     - memcpy(d->sg_buffer,(char []){0xA8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},12);
1328     -
1329     - if(d->fua)
1330     - d->sg_buffer[1]=0x08;
1331     -
1332     - d->sg_buffer[1]|=d->lun<<5;
1333     -
1334     - d->sg_buffer[3] = (begin >> 16) & 0xFF;
1335     - d->sg_buffer[4] = (begin >> 8) & 0xFF;
1336     - d->sg_buffer[5] = begin & 0xFF;
1337     - d->sg_buffer[9] = sectors;
1338     - if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1339     - return(ret);
1340     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1341     - return(0);
1342     +static int i_read_28(cdrom_drive *d, void *p, long begin, long sectors){
1343     + return generic_scsi_read(d, p, begin, sectors,
1344     + SCSI_READ_10(d->fua, begin, sectors), 10, 0, sectors * CD_FRAMESIZE_RAW);
1345     }
1346    
1347     -static int i_read_D4_10 (cdrom_drive *d, void *p, long begin, long sectors){
1348     - int ret;
1349     - memcpy(d->sg_buffer,(char []){0xd4, 0, 0, 0, 0, 0, 0, 0, 0, 0},10);
1350     -
1351     - if(d->fua)
1352     - d->sg_buffer[1]=0x08;
1353     -
1354     - d->sg_buffer[1]|=d->lun<<5;
1355     - d->sg_buffer[3] = (begin >> 16) & 0xFF;
1356     - d->sg_buffer[4] = (begin >> 8) & 0xFF;
1357     - d->sg_buffer[5] = begin & 0xFF;
1358     - d->sg_buffer[8] = sectors;
1359     - if((ret=handle_scsi_cmd(d,10,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1360     - return(ret);
1361     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1362     - return(0);
1363     +static int i_read_A8(cdrom_drive *d, void *p, long begin, long sectors){
1364     + return generic_scsi_read(d, p, begin, sectors,
1365     + SCSI_READ_12(d->fua, begin, sectors), 12, 0, sectors * CD_FRAMESIZE_RAW);
1366     }
1367    
1368     -static int i_read_D4_12 (cdrom_drive *d, void *p, long begin, long sectors){
1369     - int ret;
1370     - memcpy(d->sg_buffer,(char []){0xd4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},12);
1371     -
1372     - if(d->fua)
1373     - d->sg_buffer[1]=0x08;
1374     -
1375     - d->sg_buffer[1]|=d->lun<<5;
1376     - d->sg_buffer[3] = (begin >> 16) & 0xFF;
1377     - d->sg_buffer[4] = (begin >> 8) & 0xFF;
1378     - d->sg_buffer[5] = begin & 0xFF;
1379     - d->sg_buffer[9] = sectors;
1380     - if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1381     - return(ret);
1382     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1383     - return(0);
1384     +static int i_read_D4_10(cdrom_drive *d, void *p, long begin, long sectors){
1385     + return generic_scsi_read(d, p, begin, sectors,
1386     + D4_READ_10(begin, sectors), 10, 0, sectors * CD_FRAMESIZE_RAW);
1387     }
1388    
1389     -static int i_read_D5 (cdrom_drive *d, void *p, long begin, long sectors){
1390     - int ret;
1391     - memcpy(d->sg_buffer,(char []){0xd5, 0, 0, 0, 0, 0, 0, 0, 0, 0},10);
1392     -
1393     - if(d->fua)
1394     - d->sg_buffer[1]=0x08;
1395     -
1396     - d->sg_buffer[1]|=d->lun<<5;
1397     - d->sg_buffer[3] = (begin >> 16) & 0xFF;
1398     - d->sg_buffer[4] = (begin >> 8) & 0xFF;
1399     - d->sg_buffer[5] = begin & 0xFF;
1400     - d->sg_buffer[8] = sectors;
1401     - if((ret=handle_scsi_cmd(d,10,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1402     - return(ret);
1403     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1404     - return(0);
1405     +static int i_read_D4_12(cdrom_drive *d, void *p, long begin, long sectors){
1406     + return generic_scsi_read(d, p, begin, sectors,
1407     + D4_READ_12(begin, sectors), 12, 0, sectors * CD_FRAMESIZE_RAW);
1408     }
1409    
1410     -static int i_read_D8 (cdrom_drive *d, void *p, long begin, long sectors){
1411     - int ret;
1412     - memcpy(d->sg_buffer,(char []){0xd8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},12);
1413     -
1414     - if(d->fua)
1415     - d->sg_buffer[1]=0x08;
1416     -
1417     - d->sg_buffer[1]|=d->lun<<5;
1418     - d->sg_buffer[3] = (begin >> 16) & 0xFF;
1419     - d->sg_buffer[4] = (begin >> 8) & 0xFF;
1420     - d->sg_buffer[5] = begin & 0xFF;
1421     - d->sg_buffer[9] = sectors;
1422     - if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1423     - return(ret);
1424     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1425     - return(0);
1426     +static int i_read_D5(cdrom_drive *d, void *p, long begin, long sectors){
1427     + return generic_scsi_read(d, p, begin, sectors,
1428     + D5_READ_10(begin, sectors), 10, 0, sectors * CD_FRAMESIZE_RAW);
1429     }
1430    
1431     -static int i_read_mmc (cdrom_drive *d, void *p, long begin, long sectors){
1432     - int ret;
1433     - /* if(begin<=12007 && begin+sectors>12000){
1434     - errno=EIO;
1435     - return(TR_ILLEGAL);
1436     - }*/
1437     -
1438     - memcpy(d->sg_buffer,(char []){0xbe, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0},12);
1439     -
1440     - d->sg_buffer[3] = (begin >> 16) & 0xFF;
1441     - d->sg_buffer[4] = (begin >> 8) & 0xFF;
1442     - d->sg_buffer[5] = begin & 0xFF;
1443     - d->sg_buffer[8] = sectors;
1444     - if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1445     - return(ret);
1446     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1447     - return(0);
1448     +static int i_read_D8(cdrom_drive *d, void *p, long begin, long sectors){
1449     + return generic_scsi_read(d, p, begin, sectors,
1450     + D8_READ_12(begin, sectors), 12, 0, sectors * CD_FRAMESIZE_RAW);
1451     }
1452    
1453     -static int i_read_mmc2 (cdrom_drive *d, void *p, long begin, long sectors){
1454     - int ret;
1455     - memcpy(d->sg_buffer,(char []){0xbe, 0, 0, 0, 0, 0, 0, 0, 0, 0xf8, 0, 0},12);
1456     -
1457     - d->sg_buffer[3] = (begin >> 16) & 0xFF;
1458     - d->sg_buffer[4] = (begin >> 8) & 0xFF;
1459     - d->sg_buffer[5] = begin & 0xFF;
1460     - d->sg_buffer[8] = sectors;
1461     - if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1462     - return(ret);
1463     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1464     - return(0);
1465     +static int i_read_mmc(cdrom_drive *d, void *p, long begin, long sectors){
1466     + return generic_scsi_read(d, p, begin, sectors,
1467     + READ_CD_12(begin, sectors), 12, 0, sectors * CD_FRAMESIZE_RAW);
1468     }
1469    
1470     -static int i_read_mmc3 (cdrom_drive *d, void *p, long begin, long sectors){
1471     - int ret;
1472     - memcpy(d->sg_buffer,(char []){0xbe, 4, 0, 0, 0, 0, 0, 0, 0, 0xf8, 0, 0},12);
1473     +static int i_read_mmc2(cdrom_drive *d, void *p, long begin, long sectors){
1474     + char cmd[12];
1475    
1476     - d->sg_buffer[3] = (begin >> 16) & 0xFF;
1477     - d->sg_buffer[4] = (begin >> 8) & 0xFF;
1478     - d->sg_buffer[5] = begin & 0xFF;
1479     - d->sg_buffer[8] = sectors;
1480     - if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1481     - return(ret);
1482     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1483     - return(0);
1484     + memcpy(cmd, READ_CD_12(begin, sectors), 12);
1485     + cmd[9] = 0xf8;
1486     + return generic_scsi_read(d, p, begin, sectors,
1487     + cmd, 12, 0, sectors * CD_FRAMESIZE_RAW);
1488     }
1489    
1490     -/* straight from the MMC3 spec */
1491     -static inline void LBA_to_MSF(long lba,
1492     - unsigned char *M,
1493     - unsigned char *S,
1494     - unsigned char *F){
1495     - if(lba>=-150){
1496     - *M=(lba+150)/(60*75);
1497     - lba-=(*M)*60*75;
1498     - *S=(lba+150)/75;
1499     - lba-=(*S)*75;
1500     - *F=(lba+150);
1501     - }else{
1502     - *M=(lba+450150)/(60*75);
1503     - lba-=(*M)*60*75;
1504     - *S=(lba+450150)/75;
1505     - lba-=(*S)*75;
1506     - *F=(lba+450150);
1507     - }
1508     -}
1509     -
1510     -
1511     -static int i_read_msf (cdrom_drive *d, void *p, long begin, long sectors){
1512     - int ret;
1513     - memcpy(d->sg_buffer,(char []){0xb9, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0},12);
1514     +static int i_read_mmc3(cdrom_drive *d, void *p, long begin, long sectors){
1515     + char cmd[12];
1516    
1517     - LBA_to_MSF(begin,d->sg_buffer+3,d->sg_buffer+4,d->sg_buffer+5);
1518     - LBA_to_MSF(begin+sectors,d->sg_buffer+6,d->sg_buffer+7,d->sg_buffer+8);
1519     + memcpy(cmd, READ_CD_12(begin, sectors), 12);
1520     + cmd[1] = 4;
1521     + cmd[9] = 0xf8;
1522     + return generic_scsi_read(d, p, begin, sectors,
1523     + cmd, 12, 0, sectors * CD_FRAMESIZE_RAW);
1524     +}
1525    
1526     - if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1527     - return(ret);
1528     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1529     - return(0);
1530     +static int i_read_msf(cdrom_drive *d, void *p, long begin, long sectors){
1531     + return generic_scsi_read(d, p, begin, sectors,
1532     + READ_CD_MSF_12(begin, sectors), 12, 0, sectors * CD_FRAMESIZE_RAW);
1533     }
1534    
1535     static int i_read_msf2 (cdrom_drive *d, void *p, long begin, long sectors){
1536     - int ret;
1537     - memcpy(d->sg_buffer,(char []){0xb9, 0, 0, 0, 0, 0, 0, 0, 0, 0xf8, 0, 0},12);
1538     + char cmd[12];
1539    
1540     - LBA_to_MSF(begin,d->sg_buffer+3,d->sg_buffer+4,d->sg_buffer+5);
1541     - LBA_to_MSF(begin+sectors,d->sg_buffer+6,d->sg_buffer+7,d->sg_buffer+8);
1542     -
1543     - if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1544     - return(ret);
1545     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1546     - return(0);
1547     + memcpy(cmd, READ_CD_MSF_12(begin, sectors), 12);
1548     + cmd[9] = 0xf8;
1549     + return generic_scsi_read(d, p, begin, sectors,
1550     + cmd, 12, 0, sectors * CD_FRAMESIZE_RAW);
1551     }
1552    
1553     static int i_read_msf3 (cdrom_drive *d, void *p, long begin, long sectors){
1554     - int ret;
1555     - memcpy(d->sg_buffer,(char []){0xb9, 4, 0, 0, 0, 0, 0, 0, 0, 0xf8, 0, 0},12);
1556     + char cmd[12];
1557    
1558     - LBA_to_MSF(begin,d->sg_buffer+3,d->sg_buffer+4,d->sg_buffer+5);
1559     - LBA_to_MSF(begin+sectors,d->sg_buffer+6,d->sg_buffer+7,d->sg_buffer+8);
1560     -
1561     - if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
1562     - return(ret);
1563     - if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
1564     - return(0);
1565     + memcpy(cmd, READ_CD_MSF_12(begin, sectors), 12);
1566     + cmd[1] = 4;
1567     + cmd[9] = 0xf8;
1568     + return generic_scsi_read(d, p, begin, sectors,
1569     + cmd, 12, 0, sectors * CD_FRAMESIZE_RAW);
1570     }
1571    
1572     static long scsi_read_map (cdrom_drive *d, void *p, long begin, long sectors,
1573     @@ -824,6 +929,10 @@
1574     int retry_count,err;
1575     char *buffer=(char *)p;
1576    
1577     + struct sg_info *sgi = (struct sg_info *)d->sg;
1578     + struct sg_io_hdr *hdr = sgi->hdr;
1579     + unsigned char key, ASC, ASCQ;
1580     +
1581     /* read d->nsectors at a time, max. */
1582     sectors=(sectors>d->nsectors?d->nsectors:sectors);
1583     sectors=(sectors<1?1:sectors);
1584     @@ -832,17 +941,32 @@
1585    
1586     while(1) {
1587     if((err=map(d,(p?buffer:NULL),begin,sectors))){
1588     + /* Dunno if we even need this now that scsi_reset does it,
1589     + * but try to take "device is becoming ready" into account */
1590     + key = hdr->sbp[2] & 0xf;
1591     + ASC = hdr->sbp[12];
1592     + ASCQ = hdr->sbp[13];
1593     +
1594     + if(key == 2 & ASC == 4 & ASCQ == 1) {
1595     + if(retry_count > MAX_RETRIES-1) {
1596     + char b[256];
1597     + sprintf(b,"010: Unable to access sector %ld\n",
1598     + begin);
1599     + cderror(d,b);
1600     + return(-10);
1601     + } else {
1602     + retry_count++;
1603     + usleep(100);
1604     + continue;
1605     + }
1606     + }
1607     if(d->report_all){
1608     - struct sg_header *sg_hd=(struct sg_header *)d->sg;
1609     char b[256];
1610     -
1611     sprintf(b,"scsi_read error: sector=%ld length=%ld retry=%d\n",
1612     begin,sectors,retry_count);
1613     cdmessage(d,b);
1614     sprintf(b," Sense key: %x ASC: %x ASCQ: %x\n",
1615     - (int)(sg_hd->sense_buffer[2]&0xf),
1616     - (int)(sg_hd->sense_buffer[12]),
1617     - (int)(sg_hd->sense_buffer[13]));
1618     + key, ASC, ASCQ);
1619     cdmessage(d,b);
1620     sprintf(b," Transport error: %s\n",strerror_tr[err]);
1621     cdmessage(d,b);
1622     @@ -852,9 +976,7 @@
1623     fprintf(stderr,"scsi_read error: sector=%ld length=%ld retry=%d\n",
1624     begin,sectors,retry_count);
1625     fprintf(stderr," Sense key: %x ASC: %x ASCQ: %x\n",
1626     - (int)(sg_hd->sense_buffer[2]&0xf),
1627     - (int)(sg_hd->sense_buffer[12]),
1628     - (int)(sg_hd->sense_buffer[13]));
1629     + key, ASC, ASCQ);
1630     fprintf(stderr," Transport error: %s\n",strerror_tr[err]);
1631     fprintf(stderr," System error: %s\n",strerror(errno));
1632     }
1633     @@ -1014,7 +1136,7 @@
1634     static int count_2352_bytes(cdrom_drive *d){
1635     long i;
1636     for(i=2351;i>=0;i--)
1637     - if(d->sg_buffer[i]!=(unsigned char)'\177')
1638     + if(((struct sg_info *)d->sg)->dxferp[i]!=(unsigned char)'\177')
1639     return(((i+3)>>2)<<2);
1640    
1641     return(0);
1642     @@ -1023,7 +1145,7 @@
1643     static int verify_nonzero(cdrom_drive *d){
1644     long i,flag=0;
1645     for(i=0;i<2352;i++)
1646     - if(d->sg_buffer[i]!=0){
1647     + if(((struct sg_info *)d->sg)->dxferp[i]!=0){
1648     flag=1;
1649     break;
1650     }
1651     @@ -1307,7 +1429,17 @@
1652     return;
1653     }
1654    
1655     -static int check_atapi(cdrom_drive *d){
1656     +static int check_sgio(cdrom_drive *d) {
1657     + int fd = d->cdda_fd;
1658     +
1659     +#ifdef SG_IO
1660     + if (fd == check_fd_sgio(fd))
1661     + return 1;
1662     +#endif
1663     + return 0;
1664     +}
1665     +
1666     +static int check_atapi(cdrom_drive *d, int using_sgio){
1667     int atapiret=-1;
1668     int fd = d->cdda_fd; /* this is the correct fd (not ioctl_fd), as the
1669     generic device is the device we need to check */
1670     @@ -1321,7 +1453,7 @@
1671     if(atapiret==1){
1672     cdmessage(d,"\tDrive is ATAPI (using SCSI host adaptor emulation)\n");
1673     /* Disable kernel SCSI command translation layer for access through sg */
1674     - if (ioctl(fd,SG_SET_TRANSFORM,0))
1675     + if (!using_sgio && ioctl(fd,SG_SET_TRANSFORM,0))
1676     cderror(d,"\tCouldn't disable kernel command translation layer\n");
1677     d->is_atapi=1;
1678     }else{
1679     @@ -1340,7 +1472,7 @@
1680     d->is_mmc=0;
1681     if(mode_sense(d,22,0x2A)==0){
1682    
1683     - b=d->sg_buffer;
1684     + b=((struct sg_info *)d->sg)->dxferp;
1685     b+=b[3]+4;
1686    
1687     if((b[0]&0x3F)==0x2A){
1688     @@ -1380,21 +1512,27 @@
1689     }
1690    
1691     /* request vendor brand and model */
1692     -unsigned char *scsi_inquiry(cdrom_drive *d){
1693     - memcpy(d->sg_buffer,(char[]){ 0x12,0,0,0,56,0},6);
1694     +unsigned char *scsi_inquiry(cdrom_drive *d) {
1695     + static char ret[56];
1696     + struct sg_info *sgi = (struct sg_info *)d->sg;
1697    
1698     - if(handle_scsi_cmd(d,6, 0, 56,'\377',1)) {
1699     + if (sgi->hdr == NULL)
1700     + scsi_init_drive(d);
1701     +
1702     + sgi->setup_scsi_cmd(d, SCSI_INQUIRY_6(56), 6, 0, 56);
1703     + if (sgi->handle_scsi_cmd(d)) {
1704     cderror(d,"008: Unable to identify CDROM model\n");
1705     - return(NULL);
1706     + return NULL;
1707     }
1708     - return (d->sg_buffer);
1709     + memcpy(ret, ((struct sg_info *)d->sg)->dxferp, 56);
1710     + return ret;
1711     }
1712    
1713     -
1714     int scsi_init_drive(cdrom_drive *d){
1715     - int ret;
1716     + int ret, is_sgio;
1717    
1718     - check_atapi(d);
1719     + is_sgio = check_sgio(d);
1720     + check_atapi(d, is_sgio);
1721     check_mmc(d);
1722    
1723     /* generic Sony type defaults; specialize from here */
1724     @@ -1451,15 +1589,16 @@
1725     if(d->tracks<1)
1726     return(d->tracks);
1727    
1728     - tweak_SG_buffer(d);
1729     d->opened=1;
1730    
1731     if((ret=verify_read_command(d)))return(ret);
1732     check_fua_bit(d);
1733    
1734     d->error_retry=1;
1735     - d->sg=realloc(d->sg,d->nsectors*CD_FRAMESIZE_RAW + SG_OFF + 128);
1736     - d->sg_buffer=d->sg+SG_OFF;
1737     +#if 0
1738     + ((struct sg_info *)d->sg)=realloc(((struct sg_info *)d->sg),d->nsectors*CD_FRAMESIZE_RAW + SG_OFF + 128);
1739     + ((struct sg_info *)d->sg)_buffer=((struct sg_info *)d->sg)+SG_OFF;
1740     +#endif
1741     d->report_all=1;
1742     return(0);
1743     }
1744     --- cdparanoia-III-alpha9.8/interface/scsi_cmds.h.sgio 2004-03-30 12:46:03.306332320 -0500
1745     +++ cdparanoia-III-alpha9.8/interface/scsi_cmds.h 2004-03-30 14:09:53.760587032 -0500
1746     @@ -0,0 +1,197 @@
1747     +/******************************************************************
1748     + * CopyPolicy: GNU General Public License version 2
1749     + * Copyright 2004 Peter Jones <pjones@redhat.com>
1750     + *
1751     + * macros to generate scsi commands.
1752     + *
1753     + ******************************************************************/
1754     +
1755     +#ifndef _SCSI_CMDS_H
1756     +#define _SCSI_CMDS_H 1
1757     +#include <scsi/scsi.h>
1758     +
1759     +/* from the MMC3 spec, rewritten as seperate macros */
1760     +#define LBA_to_M(lba) (lba>=-150?((lba+150)/(60*75)):((lba+450150)/(60*75)))
1761     +#define LBA_to_S(lba) (lba>=-150?((lba+150)/75):((lba+450150)/75))
1762     +#define LBA_to_F(lba) (lba>=-150?(lba+150):(lba+450150))
1763     +
1764     +/* Group 1 (10b) command */
1765     +#define SCSI_TWELVE_BYTE(a,b,c,d,e,f,g,h,i,j,k,l) ((char []) {a,b,c,d,e,f,g,h,i,j,k,l})
1766     +#define SCSI_READ_12(fua, a, l) SCSI_TWELVE_BYTE( \
1767     + READ_12, /* READ_10 */ \
1768     + (fua & 1) << 3, /* force unit access */ \
1769     + (a >> 24) & 0xff, /* lba byte 3 */ \
1770     + (a >> 16) & 0xff, /* lba byte 2 */ \
1771     + (a >> 8) & 0xff, /* lba byte 1 */ \
1772     + a & 0xff, /* lba byte 0 */ \
1773     + 0, /* reserved */ \
1774     + (l >> 24) & 0xff, /* len byte 3 */ \
1775     + (l >> 16) & 0xff, /* len byte 2 */ \
1776     + (l >> 8) & 0xff, /* len byte 1 */ \
1777     + l & 0xff, /* len byte 0 */ \
1778     + 0 /* control */ \
1779     +)
1780     +#define D4_READ_12(a, l) SCSI_TWELVE_BYTE( \
1781     + 0xD4, /* 0xD4 */ \
1782     + 0, /* lun */ \
1783     + 0, /* ? */ \
1784     + (a >> 16) & 0xff, /* lba byte 2 */ \
1785     + (a >> 8) & 0xff, /* lba byte 1 */ \
1786     + a & 0xff, /* lba byte 0 */ \
1787     + 0, /* reserved */ \
1788     + 0, /* ? */ \
1789     + 0, /* ? */ \
1790     + l & 0xff, /* len byte 0 */ \
1791     + 0, 0 /* ? */ \
1792     +)
1793     +#define D8_READ_12(a, l) SCSI_TWELVE_BYTE( \
1794     + 0xD8, /* 0xD4 */ \
1795     + 0, /* lun */ \
1796     + 0, /* ? */ \
1797     + (a >> 16) & 0xff, /* lba byte 2 */ \
1798     + (a >> 8) & 0xff, /* lba byte 1 */ \
1799     + a & 0xff, /* lba byte 0 */ \
1800     + 0, /* reserved */ \
1801     + 0, /* ? */ \
1802     + 0, /* ? */ \
1803     + l & 0xff, /* len byte 0 */ \
1804     + 0, 0 /* ? */ \
1805     +)
1806     +#define READ_CD_12(a, l) SCSI_TWELVE_BYTE( \
1807     + 0xBE, /* 0xD4 */ \
1808     + 0, /* ? */ \
1809     + (a >> 24) & 0xff, /* lba byte 3 */ \
1810     + (a >> 16) & 0xff, /* lba byte 2 */ \
1811     + (a >> 8) & 0xff, /* lba byte 1 */ \
1812     + a & 0xff, /* lba byte 0 */ \
1813     + (l >> 16) & 0xff, /* len byte 2 */ \
1814     + (l >> 8) & 0xff, /* len byte 1 */ \
1815     + l & 0xff, /* len byte 0 */ \
1816     + 10, /* ecc */ \
1817     + 0, 0 /* ? */ \
1818     +)
1819     +#define READ_CD_MSF_12(a, l) SCSI_TWELVE_BYTE( \
1820     + 0xB9, /* 0xD4 */ \
1821     + 0, /* ? */ \
1822     + 0, /* ? */ \
1823     + LBA_to_M((a)), /* start M */ \
1824     + LBA_to_S((a)), /* start S */ \
1825     + LBA_to_F((a)), /* start F */ \
1826     + LBA_to_M((a)+(l)), /* start M */ \
1827     + LBA_to_S((a)+(l)), /* start S */ \
1828     + LBA_to_F((a)+(l)), /* start F */ \
1829     + 10, /* ecc */ \
1830     + 0, 0 /* ? */ \
1831     +)
1832     +
1833     +#define SCSI_TEN_BYTE(a,b,c,d,e,f,g,h,i,j) ((char []) {a,b,c,d,e,f,g,h,i,j})
1834     +#define SCSI_MODE_SENSE_10(page, size) SCSI_TEN_BYTE( \
1835     + MODE_SENSE_10, /* MODE_SENSE */ \
1836     + 0x00, /* reserved */ \
1837     + page & 0x3F, /* page */ \
1838     + 0, /* reserved */ \
1839     + 0, /* reserved */ \
1840     + 0, /* reserved */ \
1841     + 0, /* reserved */ \
1842     + 0, /* MSB (0) */ \
1843     + size, /* sizeof(modesense - SG_OFF) */ \
1844     + 0 /* reserved */ \
1845     +)
1846     +#define SCSI_MODE_SELECT_10 SCSI_TEN_BYTE( \
1847     + MODE_SELECT_10, /* MODE_SELECT */ \
1848     + 0x10, /* no save page */ \
1849     + 0, /* reserved */ \
1850     + 0, /* reserved */ \
1851     + 0, /* reserved */ \
1852     + 0, /* reserved */ \
1853     + 0, /* reserved */ \
1854     + 0, /* reserved */ \
1855     + 12, /* sizeof(mode) */ \
1856     + 0 /* reserved */ \
1857     +)
1858     +#define SCSI_READ_TOC(track_number) SCSI_TEN_BYTE( \
1859     + READ_TOC, /* READ_TOC */ \
1860     + 0, /* MSF format */ \
1861     + 0, \
1862     + 0, \
1863     + 0, \
1864     + 0, \
1865     + track_number, /* start track */ \
1866     + 0, /* len msb */ \
1867     + 12, /* len lsb */ \
1868     + 0 /* flags */ \
1869     +)
1870     +/* a contribution from Boris for IMS cdd 522 */
1871     +/* check this for ACER/Creative/Foo 525,620E,622E, etc? */
1872     +#define CDD522_READ_TOC(track_number) SCSI_TEN_BYTE( \
1873     + 0xE5, /* CDD522_READ_TOC */ \
1874     + 0, 0, 0, 0, /* res */ \
1875     + track_number, /* start track */ \
1876     + 0, 0, 0, 0 /* ? */ \
1877     +)
1878     +#define SCSI_READ_10(fua, a, l) SCSI_TEN_BYTE( \
1879     + READ_10, /* READ_10 */ \
1880     + (fua?8:0), /* force unit access */ \
1881     + (a >> 24) & 0xff, /* lba byte 3 */ \
1882     + (a >> 16) & 0xff, /* lba byte 2 */ \
1883     + (a >> 8) & 0xff, /* lba byte 1 */ \
1884     + a & 0xff, /* lba byte 0 */ \
1885     + 0, /* reserved */ \
1886     + (l >> 8) & 0xff, /* len byte 1 */ \
1887     + l & 0xff, /* len byte 0 */ \
1888     + 0 /* control */ \
1889     +)
1890     +#define D4_READ_10(a, l) SCSI_TEN_BYTE( \
1891     + 0xD4, /* 0xD4 */ \
1892     + 0, /* ? */ \
1893     + 0, /* ? */ \
1894     + (a >> 16) & 0xff, /* lba byte 2 */ \
1895     + (a >> 8) & 0xff, /* lba byte 1 */ \
1896     + a & 0xff, /* lba byte 0 */ \
1897     + 0, /* reserved */ \
1898     + 0, /* ? */ \
1899     + l & 0xff, /* len byte 0 */ \
1900     + 0 /* control */ \
1901     +)
1902     +#define D5_READ_10(a, l) SCSI_TEN_BYTE( \
1903     + 0xD5, /* 0xD5 */ \
1904     + 0, /* lun */ \
1905     + 0, /* ? */ \
1906     + (a >> 16) & 0xff, /* lba byte 2 */ \
1907     + (a >> 8) & 0xff, /* lba byte 1 */ \
1908     + a & 0xff, /* lba byte 0 */ \
1909     + 0, /* reserved */ \
1910     + 0, /* ? */ \
1911     + l & 0xff, /* len byte 0 */ \
1912     + 0 /* control */ \
1913     +)
1914     +
1915     +
1916     +#define SCSI_SIX_BYTE(a,b,c,d,e,f) ((char []) {a,b,c,d,e,f})
1917     +#define SCSI_MODE_SENSE_6(page, size) SCSI_SIX_BYTE( \
1918     + MODE_SENSE, /* MODE_SENSE */ \
1919     + 0x00, /* return block descriptor/lun */ \
1920     + page & 0x3F, /* page */ \
1921     + 0, /* reserved */ \
1922     + size, /* sizeof(modesense - SG_OFF) */ \
1923     + 0 /* control */ \
1924     +)
1925     +#define SCSI_MODE_SELECT_6 SCSI_SIX_BYTE( \
1926     + MODE_SELECT, /* MODE_SELECT */ \
1927     + 0x10, /* no save page */ \
1928     + 0, /* reserved */ \
1929     + 0, /* reserved */ \
1930     + 12, /* sizeof(mode) */ \
1931     + 0 /* reserved */ \
1932     +)
1933     +#define SCSI_INQUIRY_6(len) SCSI_SIX_BYTE( \
1934     + INQUIRY, /* INQUIRY */ \
1935     + 0, 0, 0, /* ? */ \
1936     + len, 0 /* len, ? */ \
1937     +)
1938     +#define SCSI_TEST_UNIT_READY_6 SCSI_SIX_BYTE( \
1939     + TEST_UNIT_READY,/* TEST_UNIT_READY */ \
1940     + 0, 0, 0, 0, /* reserved */ \
1941     + 0 /* control */ \
1942     +)
1943     +#endif