Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 144 - (show annotations) (download)
Tue May 8 20:06:05 2007 UTC (16 years, 11 months ago) by niro
File size: 57470 byte(s)
-import

1 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