2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)scsi_cmds.c 1.29 03/03/31 Copyright 1998-2002 Heiko Eissfeldt */
14 /* file for all SCSI commands
15 * FUA (Force Unit Access) bit handling copied from Monty's cdparanoia.
19 #define TESTSUBQFALLBACK 0
30 #define g5x_cdblen(cdb, len) ((cdb)->count[0] = ((len) >> 16L)& 0xFF,\
31 (cdb)->count[1] = ((len) >> 8L) & 0xFF,\
32 (cdb)->count[2] = (len) & 0xFF)
35 #include <usal/usalcmd.h>
36 #include <usal/scsidefs.h>
37 #include <usal/scsireg.h>
39 #include <usal/scsitransp.h>
43 #include "interface.h"
44 #include "byteorder.h"
48 #include "scsi_cmds.h"
49 #include "exitcodes.h"
51 unsigned char *bufferTOC;
52 subq_chnl *SubQbuffer;
55 static unsigned ReadFullTOCSony(SCSI *usalp);
56 static unsigned ReadFullTOCMMC(SCSI *usalp);
59 int SCSI_emulated_ATAPI_on(SCSI *usalp)
62 if (usal_isatapi(usalp) > 0)
65 (void) allow_atapi(usalp, TRUE);
66 return (allow_atapi(usalp, TRUE));
69 int heiko_mmc(SCSI *usalp)
71 unsigned char mode[0x100];
73 struct cd_mode_page_2A *mp;
76 fillbytes((caddr_t)mode, sizeof(mode), '\0');
78 was_atapi = allow_atapi(usalp, 1);
80 mp = mmc_cap(usalp, mode);
82 allow_atapi(usalp, was_atapi);
86 /* have a look at the capabilities */
87 if (mp->cd_da_supported == 0) {
90 retval = 1 + mp->cd_da_accurate;
97 unsigned char density = 0;
98 unsigned char orgmode4 = 0;
99 unsigned char orgmode10, orgmode11;
101 /* get current sector size from SCSI cdrom drive */
103 get_orig_sectorsize(SCSI *usalp, unsigned char *m4, unsigned char *m10,
106 /* first get current values for density, etc. */
108 static unsigned char *modesense = NULL;
110 if (modesense == NULL) {
111 modesense = malloc(12);
112 if (modesense == NULL) {
113 fprintf(stderr, "Cannot allocate memory for mode sense command in line %d\n", __LINE__);
118 /* do the scsi cmd */
119 if (usalp->verbose) fprintf(stderr, "\nget density and sector size...");
120 if (mode_sense(usalp, modesense, 12, 0x01, 0) < 0)
121 fprintf(stderr, "get_orig_sectorsize mode sense failed\n");
123 /* FIXME: some drives dont deliver block descriptors !!! */
124 if (modesense[3] == 0)
129 modesense[10] = 0x08;
130 modesense[11] = 0x00;
133 if (m4 != NULL) /* density */
135 if (m10 != NULL) /* MSB sector size */
136 *m10 = modesense[10];
137 if (m11 != NULL) /* LSB sector size */
138 *m11 = modesense[11];
140 return (modesense[10] << 8) + modesense[11];
145 /* switch CDROM scsi drives to given sector size */
146 int set_sectorsize(SCSI *usalp, unsigned int secsize)
148 static unsigned char mode [4 + 8];
151 if (orgmode4 == 0xff) {
152 get_orig_sectorsize(usalp, &orgmode4, &orgmode10, &orgmode11);
154 if (orgmode4 == 0x82 && secsize == 2048)
157 /* prepare to read cds in the previous mode */
159 fillbytes((caddr_t)mode, sizeof(mode), '\0');
160 mode[ 3] = 8; /* Block Descriptor Length */
161 mode[ 4] = orgmode4; /* normal density */
162 mode[10] = secsize >> 8; /* block length "msb" */
163 mode[11] = secsize & 0xFF; /* block length lsb */
165 if (usalp->verbose) fprintf(stderr, "\nset density and sector size...");
166 /* do the scsi cmd */
167 if ((retval = mode_select(usalp, mode, 12, 0, usalp->inq->data_format >= 2)) < 0)
168 fprintf (stderr, "setting sector size failed\n");
174 /* switch Toshiba/DEC and HP drives from/to cdda density */
175 void EnableCddaModeSelect(SCSI *usalp, int fAudioMode, unsigned uSectorsize)
177 /* reserved, Medium type=0, Dev spec Parm = 0, block descriptor len 0 oder 8,
179 (0=YellowBook, XA Mode 2=81h, XA Mode1=83h and raw audio via SCSI=82h),
180 # blks msb, #blks, #blks lsb, reserved,
181 blocksize, blocklen msb, blocklen lsb,
184 /* MODE_SELECT, page = SCSI-2 save page disabled, reserved, reserved,
185 parm list len, flags */
186 static unsigned char mode [4 + 8] = {
190 8, /* Block Descriptor Length */
191 /* block descriptor */
192 0, /* Density Code */
193 0, 0, 0, /* # of Blocks */
195 0, 0, 0};/* Blocklen */
197 if (orgmode4 == 0 && fAudioMode) {
198 if (0 == get_orig_sectorsize(usalp, &orgmode4, &orgmode10, &orgmode11)) {
199 /* cannot retrieve density, sectorsize */
200 orgmode10 = (CD_FRAMESIZE >> 8L);
201 orgmode11 = (CD_FRAMESIZE & 0xFF);
206 /* prepare to read audio cdda */
207 mode [4] = density; /* cdda density */
208 mode [10] = (uSectorsize >> 8L); /* block length "msb" */
209 mode [11] = (uSectorsize & 0xFF); /* block length "lsb" */
211 /* prepare to read cds in the previous mode */
212 mode [4] = orgmode4; /* 0x00; \* normal density */
213 mode [10] = orgmode10; /* (CD_FRAMESIZE >> 8L); \* block length "msb" */
214 mode [11] = orgmode11; /* (CD_FRAMESIZE & 0xFF); \* block length lsb */
217 if (usalp->verbose) fprintf(stderr, "\nset density/sector size (EnableCddaModeSelect)...\n");
218 /* do the scsi cmd */
219 if (mode_select(usalp, mode, 12, 0, usalp->inq->data_format >= 2) < 0)
220 fprintf (stderr, "Audio mode switch failed\n");
224 /* read CD Text information from the table of contents */
225 void ReadTocTextSCSIMMC(SCSI *usalp)
230 /* READTOC, MSF, format, res, res, res, Start track/session, len msb,
232 unsigned char *p = bufferTOC;
233 register struct usal_cmd *scmd = usalp->scmd;
235 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
236 scmd->addr = (caddr_t)bufferTOC;
238 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
239 scmd->cdb_len = SC_G1_CDBLEN;
240 scmd->sense_len = CCS_SENSE_LEN;
241 scmd->cdb.g1_cdb.cmd = 0x43; /* Read TOC command */
242 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
243 scmd->cdb.g1_cdb.addr[0] = 5; /* format field */
244 scmd->cdb.g1_cdb.res6 = 0; /* track/session is reserved */
245 g1_cdblen(&scmd->cdb.g1_cdb, 4);
248 if (usalp->verbose) fprintf(stderr, "\nRead TOC CD Text size ...");
250 usalp->cmdname = "read toc size (text)";
252 if (usal_cmd(usalp) < 0) {
254 if (global.quiet != 1)
255 fprintf (stderr, "Read TOC CD Text failed (probably not supported).\n");
261 datalength = (p[0] << 8) | (p[1]);
265 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
266 scmd->addr = (caddr_t)bufferTOC;
267 scmd->size = 2+datalength;
268 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
269 scmd->cdb_len = SC_G1_CDBLEN;
270 scmd->sense_len = CCS_SENSE_LEN;
271 scmd->cdb.g1_cdb.cmd = 0x43; /* Read TOC command */
272 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
273 scmd->cdb.g1_cdb.addr[0] = 5; /* format field */
274 scmd->cdb.g1_cdb.res6 = 0; /* track/session is reserved */
275 g1_cdblen(&scmd->cdb.g1_cdb, 2+datalength);
278 if (usalp->verbose) fprintf(stderr, "\nRead TOC CD Text data (length %hd)...", 2+datalength);
280 usalp->cmdname = "read toc data (text)";
282 if (usal_cmd(usalp) < 0) {
284 if (global.quiet != 1)
285 fprintf (stderr, "Read TOC CD Text data failed (probably not supported).\n");
293 /*fp = fopen("PearlJam.cdtext", "rb");*/
294 /*fp = fopen("celine.cdtext", "rb");*/
295 fp = fopen("japan.cdtext", "rb");
296 if (fp == NULL) { perror(""); return; }
297 fillbytes(bufferTOC, CD_FRAMESIZE, '\0');
298 read_ = fread(bufferTOC, 1, CD_FRAMESIZE, fp );
299 fprintf(stderr, "read %d bytes. sizeof(bufferTOC)=%u\n", read_, CD_FRAMESIZE);
300 datalength = (bufferTOC[0] << 8) | (bufferTOC[1]);
306 /* read the full TOC */
307 static unsigned ReadFullTOCSony(SCSI *usalp)
309 /* READTOC, MSF, format, res, res, res, Start track/session, len msb,
311 register struct usal_cmd *scmd = usalp->scmd;
312 unsigned tracks = 99;
314 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
315 scmd->addr = (caddr_t)bufferTOC;
316 scmd->size = 4 + (3 + tracks + 6) * 11;
317 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
318 scmd->cdb_len = SC_G1_CDBLEN;
319 scmd->sense_len = CCS_SENSE_LEN;
320 scmd->cdb.g1_cdb.cmd = 0x43; /* Read TOC command */
321 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
322 scmd->cdb.g1_cdb.res6 = 1; /* session */
323 g1_cdblen(&scmd->cdb.g1_cdb, 4 + (3 + tracks + 6) * 11);
324 scmd->cdb.g1_cdb.vu_97 = 1; /* format */
327 if (usalp->verbose) fprintf(stderr, "\nRead Full TOC Sony ...");
329 usalp->cmdname = "read full toc sony";
331 if (usal_cmd(usalp) < 0) {
333 if (global.quiet != 1)
334 fprintf (stderr, "Read Full TOC Sony failed (probably not supported).\n");
339 return (unsigned)((bufferTOC[0] << 8) | bufferTOC[1]);
348 struct zmsf_address {
356 static unsigned lba(struct msf_address *ad);
358 static unsigned lba(struct msf_address *ad)
360 return ad->mins*60*75 + ad->secs*75 + ad->frame;
364 static unsigned dvd_lba(struct zmsf_address *ad);
366 static unsigned dvd_lba(struct zmsf_address *ad)
368 return ad->zero*1053696 + ad->mins*60*75 + ad->secs*75 + ad->frame;
372 unsigned char session;
373 unsigned char adrctl;
376 struct msf_address adr1;
377 struct zmsf_address padr2;
381 unsigned char len_msb;
382 unsigned char len_lsb;
383 unsigned char first_track;
384 unsigned char last_track;
385 struct tocdesc ent[1];
388 static unsigned long first_session_leadout = 0;
390 static unsigned collect_tracks(struct outer *po, unsigned entries,
393 static unsigned collect_tracks(struct outer *po, unsigned entries,
400 unsigned leadout_start_orig;
401 unsigned leadout_start;
402 unsigned max_leadout = 0;
405 for (i = 0; i < entries; i++) {
406 fprintf(stderr, "%3d: %d %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"
408 ,bufferTOC[4+0 + (i * 11)]
409 ,bufferTOC[4+1 + (i * 11)]
410 ,bufferTOC[4+2 + (i * 11)]
411 ,bufferTOC[4+3 + (i * 11)]
412 ,bufferTOC[4+4 + (i * 11)]
413 ,bufferTOC[4+5 + (i * 11)]
414 ,bufferTOC[4+6 + (i * 11)]
415 ,bufferTOC[4+7 + (i * 11)]
416 ,bufferTOC[4+8 + (i * 11)]
417 ,bufferTOC[4+9 + (i * 11)]
418 ,bufferTOC[4+10 + (i * 11)]
422 /* reformat to standard toc format */
428 leadout_start_orig = 0;
431 for (i = 0; i < entries; i++) {
433 if (po->ent[i].tno != 0) {
435 "entry %d, tno is not 0: %d!\n",
440 po->ent[i].session = from_bcd(po->ent[i].session);
441 po->ent[i].adr1.mins = from_bcd(po->ent[i].adr1.mins);
442 po->ent[i].adr1.secs = from_bcd(po->ent[i].adr1.secs);
443 po->ent[i].adr1.frame = from_bcd(po->ent[i].adr1.frame);
444 po->ent[i].padr2.mins = from_bcd(po->ent[i].padr2.mins);
445 po->ent[i].padr2.secs = from_bcd(po->ent[i].padr2.secs);
446 po->ent[i].padr2.frame = from_bcd(po->ent[i].padr2.frame);
448 switch (po->ent[i].point) {
451 /* check if session is monotonous increasing */
453 if (session+1 == po->ent[i].session) {
454 session = po->ent[i].session;
458 "entry %d, session anomaly %d != %d!\n",
459 i, session+1, po->ent[i].session);
461 /* check the adrctl field */
462 if (0x10 != (po->ent[i].adrctl & 0x10)) {
464 "entry %d, incorrect adrctl field %x!\n",
465 i, po->ent[i].adrctl);
468 /* first track number */
469 if (bufferTOC[2] < po->ent[i].padr2.mins
470 && bufferTOC[3] < po->ent[i].padr2.mins) {
471 bufferTOC[2] = po->ent[i].padr2.mins;
476 "entry %d, session %d: start tracknumber anomaly: %d <= %d,%d(last)!\n",
477 i, session, po->ent[i].padr2.mins, bufferTOC[2], bufferTOC[3]);
483 /* check if session is constant */
484 if (session != po->ent[i].session) {
486 "entry %d, session anomaly %d != %d!\n",
487 i, session, po->ent[i].session);
490 /* check the adrctl field */
491 if (0x10 != (po->ent[i].adrctl & 0x10)) {
493 "entry %d, incorrect adrctl field %x!\n",
494 i, po->ent[i].adrctl);
497 /* last track number */
498 if (bufferTOC[2] <= po->ent[i].padr2.mins
499 && bufferTOC[3] < po->ent[i].padr2.mins) {
500 bufferTOC[3] = po->ent[i].padr2.mins;
505 "entry %d, session %d: end tracknumber anomaly: %d <= %d,%d(last)!\n",
506 i, session, po->ent[i].padr2.mins, bufferTOC[2], bufferTOC[3]);
512 /* check if session is constant */
513 if (session != po->ent[i].session) {
515 "entry %d, session anomaly %d != %d!\n",
516 i, session, po->ent[i].session);
519 /* check the adrctl field */
520 if (0x10 != (po->ent[i].adrctl & 0x10)) {
522 "entry %d, incorrect adrctl field %x!\n",
523 i, po->ent[i].adrctl);
526 /* register leadout position */
528 unsigned leadout_start_tmp =
529 dvd_lba(&po->ent[i].padr2);
531 if (first_session_leadout == 0)
532 first_session_leadout = leadout_start_tmp - 150;
534 if (leadout_start_tmp > leadout_start) {
535 leadout_start_orig = leadout_start_tmp;
536 leadout_start = leadout_start_tmp;
541 "entry %d, leadout position anomaly %u!\n",
542 i, leadout_start_tmp);
549 /* check if session is constant */
550 if (session != po->ent[i].session) {
552 "entry %d, session anomaly %d != %d!\n",
553 i, session, po->ent[i].session);
556 /* check the adrctl field */
557 if (0x50 != (po->ent[i].adrctl & 0x50)) {
559 "entry %d, incorrect adrctl field %x!\n",
560 i, po->ent[i].adrctl);
563 /* check the next program area */
564 if (lba(&po->ent[i].adr1) < 6750 + leadout_start) {
566 "entry %d, next program area %u < leadout_start + 6750 = %u!\n",
567 i, lba(&po->ent[i].adr1), 6750 + leadout_start);
570 /* check the maximum leadout_start */
571 if (max_leadout != 0 && dvd_lba(&po->ent[i].padr2) != max_leadout) {
573 "entry %d, max leadout_start %u != last max_leadout_start %u!\n",
574 i, dvd_lba(&po->ent[i].padr2), max_leadout);
577 if (max_leadout == 0)
578 max_leadout = dvd_lba(&po->ent[i].padr2);
592 /* check if session is constant */
593 if (session != po->ent[i].session) {
596 "entry %d, session anomaly %d != %d!\n",
597 i, session, po->ent[i].session);
604 po->ent[i].point = from_bcd(po->ent[i].point);
606 if (po->ent[i].point < bufferTOC[2]
607 || po->ent[i].point > bufferTOC[3]) {
610 "entry %d, track number anomaly %d - %d - %d!\n",
611 i, bufferTOC[2], po->ent[i].point, bufferTOC[3]);
614 /* check start position */
615 unsigned trackstart = dvd_lba(&po->ent[i].padr2);
617 /* correct illegal leadouts */
618 if (leadout_start < trackstart) {
619 leadout_start = trackstart+1;
621 if (trackstart < last_start || trackstart >= leadout_start) {
624 "entry %d, track %d start position anomaly %d - %d - %d!\n",
625 i, po->ent[i].point, last_start, trackstart, leadout_start);
628 last_start = trackstart;
629 memcpy(&po->ent[tracks], &po->ent[i], sizeof(struct tocdesc));
636 /* patch leadout track */
637 po->ent[tracks].session = session;
638 po->ent[tracks].adrctl = 0x10;
639 po->ent[tracks].tno = 0;
640 po->ent[tracks].point = 0xAA;
641 po->ent[tracks].adr1.mins = 0;
642 po->ent[tracks].adr1.secs = 0;
643 po->ent[tracks].adr1.frame = 0;
644 po->ent[tracks].padr2.zero = leadout_start_orig / (1053696);
645 po->ent[tracks].padr2.mins = (leadout_start_orig / (60*75)) % 100;
646 po->ent[tracks].padr2.secs = (leadout_start_orig / 75) % 60;
647 po->ent[tracks].padr2.frame = leadout_start_orig % 75;
651 bufferTOC[0] = ((tracks * 8) + 2) >> 8;
652 bufferTOC[1] = ((tracks * 8) + 2) & 0xff;
655 /* reformat 11 byte blocks to 8 byte entries */
657 /* 1: Session \ / reserved
658 2: adr ctrl | | adr ctrl
659 3: TNO | | track number
660 4: Point | | reserved
669 for (i = 0; i < tracks; i++) {
670 bufferTOC[4+0 + (i << 3)] = 0;
671 bufferTOC[4+1 + (i << 3)] = bufferTOC[4+1 + (i*11)];
672 bufferTOC[4+1 + (i << 3)] = (bufferTOC[4+1 + (i << 3)] >> 4) | (bufferTOC[4+1 + (i << 3)] << 4);
673 bufferTOC[4+2 + (i << 3)] = bufferTOC[4+3 + (i*11)];
674 bufferTOC[4+3 + (i << 3)] = 0;
675 bufferTOC[4+4 + (i << 3)] = bufferTOC[4+7 + (i*11)];
676 bufferTOC[4+5 + (i << 3)] = bufferTOC[4+8 + (i*11)];
677 bufferTOC[4+6 + (i << 3)] = bufferTOC[4+9 + (i*11)];
678 bufferTOC[4+7 + (i << 3)] = bufferTOC[4+10 + (i*11)];
680 fprintf(stderr, "%02x %02x %02x %02x %02x %02x\n"
681 ,bufferTOC[4+ 1 + i*8]
682 ,bufferTOC[4+ 2 + i*8]
683 ,bufferTOC[4+ 4 + i*8]
684 ,bufferTOC[4+ 5 + i*8]
685 ,bufferTOC[4+ 6 + i*8]
686 ,bufferTOC[4+ 7 + i*8]
691 TOC_entries(tracks, NULL, bufferTOC+4, 0);
695 /* read the table of contents from the cd and fill the TOC array */
696 unsigned ReadTocSony(SCSI *usalp)
699 unsigned return_length;
701 struct outer *po = (struct outer *)bufferTOC;
703 return_length = ReadFullTOCSony(usalp);
705 /* Check if the format was understood */
706 if ((return_length & 7) == 2 && (bufferTOC[3] - bufferTOC[2]) == (return_length >> 3)) {
707 /* The extended format seems not be understood, fallback to
708 * the classical format. */
709 return ReadTocSCSI( usalp );
712 tracks = collect_tracks(po, ((return_length - 2) / 11), TRUE);
714 return --tracks; /* without lead-out */
717 /* read the start of the lead-out from the first session TOC */
718 unsigned ReadFirstSessionTOCSony(SCSI *usalp)
720 unsigned return_length;
722 if (first_session_leadout != 0)
723 return first_session_leadout;
725 return_length = ReadFullTOCSony(usalp);
726 if (return_length >= 4 + (3 * 11) -2) {
729 /* We want the entry with POINT = 0xA2, which has the start position
730 of the first session lead out */
731 off = 4 + 2 * 11 + 3;
732 if (bufferTOC[off-3] == 1 && bufferTOC[off] == 0xA2) {
735 off = 4 + 2 * 11 + 8;
736 retval = bufferTOC[off] >> 4;
737 retval *= 10; retval += bufferTOC[off] & 0xf;
740 retval += 10 * (bufferTOC[off] >> 4) + (bufferTOC[off] & 0xf);
743 retval += 10 * (bufferTOC[off] >> 4) + (bufferTOC[off] & 0xf);
752 /* read the full TOC */
753 static unsigned ReadFullTOCMMC(SCSI *usalp)
756 /* READTOC, MSF, format, res, res, res, Start track/session, len msb,
758 register struct usal_cmd *scmd = usalp->scmd;
759 unsigned tracks = 99;
761 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
762 scmd->addr = (caddr_t)bufferTOC;
763 scmd->size = 4 + (tracks + 8) * 11;
764 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
765 scmd->cdb_len = SC_G1_CDBLEN;
766 scmd->sense_len = CCS_SENSE_LEN;
767 scmd->cdb.g1_cdb.cmd = 0x43; /* Read TOC command */
768 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
769 scmd->cdb.g1_cdb.addr[0] = 2; /* format */
770 scmd->cdb.g1_cdb.res6 = 1; /* session */
771 g1_cdblen(&scmd->cdb.g1_cdb, 4 + (tracks + 8) * 11);
774 if (usalp->verbose) fprintf(stderr, "\nRead Full TOC MMC...");
776 usalp->cmdname = "read full toc mmc";
778 if (usal_cmd(usalp) < 0) {
779 if (global.quiet != 1)
780 fprintf (stderr, "Read Full TOC MMC failed (probably not supported).\n");
781 #ifdef B_BEOS_VERSION
789 return (unsigned)((bufferTOC[0] << 8) | bufferTOC[1]);
792 /* read the start of the lead-out from the first session TOC */
793 unsigned ReadFirstSessionTOCMMC(SCSI *usalp)
796 unsigned return_length;
798 if (first_session_leadout != 0)
799 return first_session_leadout;
801 return_length = ReadFullTOCMMC(usalp);
803 /* We want the entry with POINT = 0xA2, which has the start position
804 of the first session lead out */
806 while (off < return_length && bufferTOC[off] != 0xA2) {
809 if (off < return_length) {
811 return (bufferTOC[off]*60 + bufferTOC[off+1])*75 + bufferTOC[off+2] - 150;
816 /* read the table of contents from the cd and fill the TOC array */
817 unsigned ReadTocMMC(SCSI *usalp)
820 unsigned return_length;
822 struct outer *po = (struct outer *)bufferTOC;
824 return_length = ReadFullTOCMMC(usalp);
825 if (return_length - 2 < 4*11 || ((return_length - 2) % 11) != 0)
826 return ReadTocSCSI(usalp);
828 tracks = collect_tracks(po, ((return_length - 2) / 11), FALSE);
829 return --tracks; /* without lead-out */
832 /* read the table of contents from the cd and fill the TOC array */
833 unsigned ReadTocSCSI(SCSI *usalp)
837 unsigned char bufferTOCMSF[CD_FRAMESIZE];
839 /* first read the first and last track number */
840 /* READTOC, MSF format flag, res, res, res, res, Start track, len msb,
842 register struct usal_cmd *scmd = usalp->scmd;
844 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
845 scmd->addr = (caddr_t)bufferTOC;
847 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
848 scmd->cdb_len = SC_G1_CDBLEN;
849 scmd->sense_len = CCS_SENSE_LEN;
850 scmd->cdb.g1_cdb.cmd = 0x43; /* read TOC command */
851 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
852 scmd->cdb.g1_cdb.res6 = 1; /* start track */
853 g1_cdblen(&scmd->cdb.g1_cdb, 4);
855 if (usalp->verbose) fprintf(stderr, "\nRead TOC size (standard)...");
856 /* do the scsi cmd (read table of contents) */
858 usalp->cmdname = "read toc size";
859 if (usal_cmd(usalp) < 0)
860 FatalError ("Read TOC size failed.\n");
863 tracks = ((bufferTOC [3] ) - bufferTOC [2] + 2) ;
864 if (tracks > MAXTRK) return 0;
865 if (tracks == 0) return 0;
868 memset(bufferTOCMSF, 0, sizeof(bufferTOCMSF));
869 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
870 scmd->addr = (caddr_t)bufferTOCMSF;
871 scmd->size = 4 + tracks * 8;
872 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
873 scmd->cdb_len = SC_G1_CDBLEN;
874 scmd->sense_len = CCS_SENSE_LEN;
875 scmd->cdb.g1_cdb.cmd = 0x43; /* read TOC command */
876 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
877 scmd->cdb.g1_cdb.res = 1; /* MSF format */
878 scmd->cdb.g1_cdb.res6 = 1; /* start track */
879 g1_cdblen(&scmd->cdb.g1_cdb, 4 + tracks * 8);
881 if (usalp->verbose) fprintf(stderr, "\nRead TOC tracks (standard MSF)...");
882 /* do the scsi cmd (read table of contents) */
884 usalp->cmdname = "read toc tracks ";
885 result = usal_cmd(usalp);
888 /* MSF format did not succeeded */
889 memset(bufferTOCMSF, 0, sizeof(bufferTOCMSF));
892 for (i = 0; i < tracks; i++) {
893 bufferTOCMSF[4+1 + (i << 3)] = (bufferTOCMSF[4+1 + (i << 3)] >> 4) | (bufferTOCMSF[4+1 + (i << 3)] << 4);
895 fprintf(stderr, "MSF %d %02x %02x %02x %02x %02x %02x %02x %02x\n"
897 ,bufferTOCMSF[4+0 + (i * 8)]
898 ,bufferTOCMSF[4+1 + (i * 8)]
899 ,bufferTOCMSF[4+2 + (i * 8)]
900 ,bufferTOCMSF[4+3 + (i * 8)]
901 ,bufferTOCMSF[4+4 + (i * 8)]
902 ,bufferTOCMSF[4+5 + (i * 8)]
903 ,bufferTOCMSF[4+6 + (i * 8)]
904 ,bufferTOCMSF[4+7 + (i * 8)]
910 /* LBA format for cd burners like Philips CD-522 */
911 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
912 scmd->addr = (caddr_t)bufferTOC;
913 scmd->size = 4 + tracks * 8;
914 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
915 scmd->cdb_len = SC_G1_CDBLEN;
916 scmd->sense_len = CCS_SENSE_LEN;
917 scmd->cdb.g1_cdb.cmd = 0x43; /* read TOC command */
918 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
919 scmd->cdb.g1_cdb.res = 0; /* LBA format */
920 scmd->cdb.g1_cdb.res6 = 1; /* start track */
921 g1_cdblen(&scmd->cdb.g1_cdb, 4 + tracks * 8);
923 if (usalp->verbose) fprintf(stderr, "\nRead TOC tracks (standard LBA)...");
924 /* do the scsi cmd (read table of contents) */
926 usalp->cmdname = "read toc tracks ";
927 if (usal_cmd(usalp) < 0) {
928 FatalError ("Read TOC tracks (lba) failed.\n");
932 for (i = 0; i < tracks; i++) {
933 bufferTOC[4+1 + (i << 3)] = (bufferTOC[4+1 + (i << 3)] >> 4) | (bufferTOC[4+1 + (i << 3)] << 4);
935 fprintf(stderr, "LBA %d %02x %02x %02x %02x %02x %02x %02x %02x\n"
937 ,bufferTOC[4+0 + (i * 8)]
938 ,bufferTOC[4+1 + (i * 8)]
939 ,bufferTOC[4+2 + (i * 8)]
940 ,bufferTOC[4+3 + (i * 8)]
941 ,bufferTOC[4+4 + (i * 8)]
942 ,bufferTOC[4+5 + (i * 8)]
943 ,bufferTOC[4+6 + (i * 8)]
944 ,bufferTOC[4+7 + (i * 8)]
949 TOC_entries(tracks, bufferTOC+4, bufferTOCMSF+4, result);
950 return --tracks; /* without lead-out */
953 /* ---------------- Read methods ------------------------------ */
955 /* Read max. SectorBurst of cdda sectors to buffer
956 via standard SCSI-2 Read(10) command */
957 static int ReadStandardLowlevel(SCSI *usalp, UINT4 *p, unsigned lSector,
958 unsigned SectorBurstVal, unsigned secsize);
960 static int ReadStandardLowlevel(SCSI *usalp, UINT4 *p, unsigned lSector,
961 unsigned SectorBurstVal, unsigned secsize)
963 /* READ10, flags, block1 msb, block2, block3, block4 lsb, reserved,
964 transfer len msb, transfer len lsb, block addressing mode */
965 register struct usal_cmd *scmd = usalp->scmd;
967 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
968 scmd->addr = (caddr_t)p;
969 scmd->size = SectorBurstVal * secsize;
970 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
971 scmd->cdb_len = SC_G1_CDBLEN;
972 scmd->sense_len = CCS_SENSE_LEN;
973 scmd->cdb.g1_cdb.cmd = 0x28; /* read 10 command */
974 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
975 scmd->cdb.g1_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0);
976 g1_cdbaddr(&scmd->cdb.g1_cdb, lSector);
977 g1_cdblen(&scmd->cdb.g1_cdb, SectorBurstVal);
978 if (usalp->verbose) fprintf(stderr, "\nReadStandard10 %s (%u)...", secsize > 2048 ? "CDDA" : "CD_DATA", secsize);
980 usalp->cmdname = "ReadStandard10";
982 if (usal_cmd(usalp)) return 0;
984 /* has all or something been read? */
985 return SectorBurstVal - usal_getresid(usalp)/secsize;
990 ReadStandard(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal)
992 return ReadStandardLowlevel(usalp, p, lSector, SectorBurstVal, CD_FRAMESIZE_RAW);
996 ReadStandardData(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal)
998 return ReadStandardLowlevel(usalp, p, lSector, SectorBurstVal, CD_FRAMESIZE);
1001 /* Read max. SectorBurst of cdda sectors to buffer
1002 via vendor-specific ReadCdda(10) command */
1003 int ReadCdda10(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal)
1005 /* READ10, flags, block1 msb, block2, block3, block4 lsb, reserved,
1006 transfer len msb, transfer len lsb, block addressing mode */
1007 register struct usal_cmd *scmd = usalp->scmd;
1009 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1010 scmd->addr = (caddr_t)p;
1011 scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW;
1012 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1013 scmd->cdb_len = SC_G1_CDBLEN;
1014 scmd->sense_len = CCS_SENSE_LEN;
1015 scmd->cdb.g1_cdb.cmd = 0xd4; /* Read audio command */
1016 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
1017 scmd->cdb.g1_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0);
1018 g1_cdbaddr(&scmd->cdb.g1_cdb, lSector);
1019 g1_cdblen(&scmd->cdb.g1_cdb, SectorBurstVal);
1020 if (usalp->verbose) fprintf(stderr, "\nReadNEC10 CDDA...");
1022 usalp->cmdname = "Read10 NEC";
1024 if (usal_cmd(usalp)) return 0;
1026 /* has all or something been read? */
1027 return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW;
1031 /* Read max. SectorBurst of cdda sectors to buffer
1032 via vendor-specific ReadCdda(12) command */
1033 int ReadCdda12(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal)
1035 register struct usal_cmd *scmd = usalp->scmd;
1037 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1038 scmd->addr = (caddr_t)p;
1039 scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW;
1040 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1041 scmd->cdb_len = SC_G5_CDBLEN;
1042 scmd->sense_len = CCS_SENSE_LEN;
1043 scmd->cdb.g5_cdb.cmd = 0xd8; /* read audio command */
1044 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
1045 scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0);
1046 g5_cdbaddr(&scmd->cdb.g5_cdb, lSector);
1047 g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal);
1049 if (usalp->verbose) fprintf(stderr, "\nReadSony12 CDDA...");
1051 usalp->cmdname = "Read12";
1053 if (usal_cmd(usalp)) return 0;
1055 /* has all or something been read? */
1056 return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW;
1059 /* Read max. SectorBurst of cdda sectors to buffer
1060 via vendor-specific ReadCdda(12) command */
1062 > It uses a 12 Byte CDB with 0xd4 as opcode, the start sector is coded as
1063 > normal and the number of sectors is coded in Byte 8 and 9 (begining with 0).
1066 int ReadCdda12Matsushita(SCSI *usalp, UINT4 *p, unsigned lSector,
1067 unsigned SectorBurstVal)
1069 register struct usal_cmd *scmd = usalp->scmd;
1071 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1072 scmd->addr = (caddr_t)p;
1073 scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW;
1074 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1075 scmd->cdb_len = SC_G5_CDBLEN;
1076 scmd->sense_len = CCS_SENSE_LEN;
1077 scmd->cdb.g5_cdb.cmd = 0xd4; /* read audio command */
1078 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
1079 scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0);
1080 g5_cdbaddr(&scmd->cdb.g5_cdb, lSector);
1081 g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal);
1083 if (usalp->verbose) fprintf(stderr, "\nReadMatsushita12 CDDA...");
1085 usalp->cmdname = "Read12Matsushita";
1087 if (usal_cmd(usalp)) return 0;
1089 /* has all or something been read? */
1090 return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW;
1093 /* Read max. SectorBurst of cdda sectors to buffer
1094 via MMC standard READ CD command */
1095 int ReadCddaMMC12(SCSI *usalp, UINT4 *p, unsigned lSector,
1096 unsigned SectorBurstVal)
1098 register struct usal_cmd *scmd;
1101 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1102 scmd->addr = (caddr_t)p;
1103 scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW;
1104 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1105 scmd->cdb_len = SC_G5_CDBLEN;
1106 scmd->sense_len = CCS_SENSE_LEN;
1107 scmd->cdb.g5_cdb.cmd = 0xbe; /* read cd command */
1108 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
1109 scmd->cdb.g5_cdb.res = 1 << 1; /* expected sector type field CDDA */
1110 g5_cdbaddr(&scmd->cdb.g5_cdb, lSector);
1111 g5x_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal);
1112 scmd->cdb.g5_cdb.count[3] = 1 << 4; /* User data */
1114 if (usalp->verbose) fprintf(stderr, "\nReadMMC12 CDDA...");
1116 usalp->cmdname = "ReadCD MMC 12";
1118 if (usal_cmd(usalp)) return 0;
1120 /* has all or something been read? */
1121 return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW;
1124 int ReadCddaFallbackMMC(SCSI *usalp, UINT4 *p, unsigned lSector,
1125 unsigned SectorBurstVal)
1127 static int ReadCdda12_unknown = 0;
1131 if (ReadCdda12_unknown
1132 || ((retval = ReadCdda12(usalp, p, lSector, SectorBurstVal)) <= 0)) {
1133 /* if the command is not available, use the regular
1136 if (retval <= 0 && usal_sense_key(usalp) == 0x05) {
1137 ReadCdda12_unknown = 1;
1140 ReadCdRom = ReadCddaMMC12;
1141 ReadCdRomSub = ReadCddaSubMMC12;
1142 return ReadCddaMMC12(usalp, p, lSector, SectorBurstVal);
1148 /* Read the Sub-Q-Channel to SubQbuffer. This is the method for
1149 * drives that do not support subchannel parameters. */
1151 static subq_chnl *ReadSubQFallback (SCSI *usalp, unsigned char sq_format, unsigned char track)
1154 ReadSubQFallback(SCSI *usalp, unsigned char sq_format, unsigned char track)
1157 register struct usal_cmd *scmd = usalp->scmd;
1159 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1160 scmd->addr = (caddr_t)SubQbuffer;
1162 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1163 scmd->cdb_len = SC_G1_CDBLEN;
1164 scmd->sense_len = CCS_SENSE_LEN;
1165 scmd->cdb.g1_cdb.cmd = 0x42; /* Read SubQChannel */
1167 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
1168 scmd->cdb.g1_cdb.addr[0] = 0x40; /* SubQ info */
1169 scmd->cdb.g1_cdb.addr[1] = 0; /* parameter list: all */
1170 scmd->cdb.g1_cdb.res6 = track; /* track number */
1171 g1_cdblen(&scmd->cdb.g1_cdb, 24);
1173 if (usalp->verbose) fprintf(stderr, "\nRead Subchannel_dumb...");
1175 usalp->cmdname = "Read Subchannel_dumb";
1177 if (usal_cmd(usalp) < 0) {
1178 fprintf( stderr, "Read SubQ failed\n");
1181 /* check, if the requested format is delivered */
1182 { unsigned char *p = (unsigned char *) SubQbuffer;
1183 if ((((unsigned)p[2] << 8) | p[3]) /* LENGTH */ > ULONG_C(11) &&
1184 (p[5] >> 4) /* ADR */ == sq_format) {
1185 if (sq_format == GET_POSITIONDATA)
1186 p[5] = (p[5] << 4) | (p[5] >> 4);
1191 /* FIXME: we might actively search for the requested info ... */
1195 /* Read the Sub-Q-Channel to SubQbuffer */
1197 subq_chnl *ReadSubQSCSI (SCSI *usalp, unsigned char sq_format, unsigned char track)
1200 ReadSubQSCSI(SCSI *usalp, unsigned char sq_format, unsigned char track)
1204 register struct usal_cmd *scmd = usalp->scmd;
1206 switch (sq_format) {
1207 case GET_POSITIONDATA:
1211 case GET_CATALOGNUMBER:
1215 case GET_TRACK_ISRC:
1219 fprintf(stderr, "ReadSubQSCSI: unknown format %d\n", sq_format);
1223 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1224 scmd->addr = (caddr_t)SubQbuffer;
1225 scmd->size = resp_size;
1226 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1227 scmd->cdb_len = SC_G1_CDBLEN;
1228 scmd->sense_len = CCS_SENSE_LEN;
1229 scmd->cdb.g1_cdb.cmd = 0x42;
1231 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
1232 scmd->cdb.g1_cdb.addr[0] = 0x40; /* SubQ info */
1233 scmd->cdb.g1_cdb.addr[1] = sq_format; /* parameter list: all */
1234 scmd->cdb.g1_cdb.res6 = track; /* track number */
1235 g1_cdblen(&scmd->cdb.g1_cdb, resp_size);
1237 if (usalp->verbose) fprintf(stderr, "\nRead Subchannel...");
1239 usalp->cmdname = "Read Subchannel";
1241 if (usal_cmd(usalp) < 0) {
1242 /* in case of error do a fallback for dumb firmwares */
1243 return ReadSubQFallback(usalp, sq_format, track);
1246 if (sq_format == GET_POSITIONDATA)
1247 SubQbuffer->control_adr = (SubQbuffer->control_adr << 4) | (SubQbuffer->control_adr >> 4);
1251 static subq_chnl sc;
1253 static subq_chnl* fill_subchannel(unsigned char bufferwithQ[]);
1254 static subq_chnl* fill_subchannel(unsigned char bufferwithQ[])
1257 sc.control_adr = bufferwithQ[CD_FRAMESIZE_RAW + 0];
1258 sc.track = bufferwithQ[CD_FRAMESIZE_RAW + 1];
1259 sc.index = bufferwithQ[CD_FRAMESIZE_RAW + 2];
1264 ReadCddaSubSony(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal)
1266 register struct usal_cmd *scmd = usalp->scmd;
1268 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1269 scmd->addr = (caddr_t)p;
1270 scmd->size = SectorBurstVal*(CD_FRAMESIZE_RAW + 16);
1271 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1272 scmd->cdb_len = SC_G5_CDBLEN;
1273 scmd->sense_len = CCS_SENSE_LEN;
1274 scmd->cdb.g5_cdb.cmd = 0xd8; /* read audio command */
1275 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
1276 scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0);
1277 scmd->cdb.g5_cdb.res10 = 0x01; /* subcode 1 -> cdda + 16 * q sub */
1278 g5_cdbaddr(&scmd->cdb.g5_cdb, lSector);
1279 g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal);
1281 if (usalp->verbose) fprintf(stderr, "\nReadSony12 CDDA + SubChannels...");
1283 usalp->cmdname = "Read12SubChannelsSony";
1285 if (usal_cmd(usalp)) return -1;
1287 /* has all or something been read? */
1288 return usal_getresid(usalp) != 0;
1291 int ReadCddaSub96Sony(SCSI *usalp, UINT4 *p, unsigned lSector,
1292 unsigned SectorBurstVal);
1294 int ReadCddaSub96Sony(SCSI *usalp, UINT4 *p, unsigned lSector,
1295 unsigned SectorBurstVal)
1297 register struct usal_cmd *scmd = usalp->scmd;
1299 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1300 scmd->addr = (caddr_t)p;
1301 scmd->size = SectorBurstVal*(CD_FRAMESIZE_RAW + 96);
1302 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1303 scmd->cdb_len = SC_G5_CDBLEN;
1304 scmd->sense_len = CCS_SENSE_LEN;
1305 scmd->cdb.g5_cdb.cmd = 0xd8; /* read audio command */
1306 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
1307 scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0);
1308 scmd->cdb.g5_cdb.res10 = 0x02; /* subcode 2 -> cdda + 96 * q sub */
1309 g5_cdbaddr(&scmd->cdb.g5_cdb, lSector);
1310 g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal);
1312 if (usalp->verbose) fprintf(stderr, "\nReadSony12 CDDA + 96 byte SubChannels...");
1314 usalp->cmdname = "Read12SubChannelsSony";
1316 if (usal_cmd(usalp)) return -1;
1318 /* has all or something been read? */
1319 return usal_getresid(usalp) != 0;
1322 subq_chnl *ReadSubChannelsSony(SCSI *usalp, unsigned lSector)
1324 /*int retval = ReadCddaSub96Sony(usalp, (UINT4 *)bufferTOC, lSector, 1);*/
1325 int retval = ReadCddaSubSony(usalp, (UINT4 *)bufferTOC, lSector, 1);
1326 if (retval != 0) return NULL;
1328 return fill_subchannel(bufferTOC);
1331 /* Read max. SectorBurst of cdda sectors to buffer
1332 via MMC standard READ CD command */
1333 int ReadCddaSubMMC12(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal)
1335 register struct usal_cmd *scmd;
1338 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1339 scmd->addr = (caddr_t)p;
1340 scmd->size = SectorBurstVal*(CD_FRAMESIZE_RAW + 16);
1341 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1342 scmd->cdb_len = SC_G5_CDBLEN;
1343 scmd->sense_len = CCS_SENSE_LEN;
1344 scmd->cdb.g5_cdb.cmd = 0xbe; /* read cd command */
1345 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
1346 scmd->cdb.g5_cdb.res = 1 << 1; /* expected sector type field CDDA */
1347 g5_cdbaddr(&scmd->cdb.g5_cdb, lSector);
1348 g5x_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal);
1349 scmd->cdb.g5_cdb.count[3] = 1 << 4; /* User data */
1350 scmd->cdb.g5_cdb.res10 = 0x02; /* subcode 2 -> cdda + 16 * q sub */
1352 if (usalp->verbose) fprintf(stderr, "\nReadMMC12 CDDA + SUB...");
1354 usalp->cmdname = "ReadCD Sub MMC 12";
1356 if (usal_cmd(usalp)) return -1;
1358 /* has all or something been read? */
1359 return usal_getresid(usalp) != 0;
1362 static subq_chnl *ReadSubChannelsMMC(SCSI *usalp, unsigned lSector);
1363 static subq_chnl *ReadSubChannelsMMC(SCSI *usalp, unsigned lSector)
1365 int retval = ReadCddaSubMMC12(usalp, (UINT4 *)bufferTOC, lSector, 1);
1366 if (retval != 0) return NULL;
1368 return fill_subchannel(bufferTOC);
1371 subq_chnl *ReadSubChannelsFallbackMMC(SCSI *usalp, unsigned lSector)
1373 static int ReadSubSony_unknown = 0;
1374 subq_chnl *retval = NULL;
1377 if (ReadSubSony_unknown
1378 || ((retval = ReadSubChannelsSony(usalp, lSector)) == NULL)) {
1379 /* if the command is not available, use the regular
1382 if (retval == NULL && usal_sense_key(usalp) == 0x05) {
1383 ReadSubSony_unknown = 1;
1386 return ReadSubChannelsMMC(usalp, lSector);
1392 subq_chnl *ReadStandardSub(usalp, lSector)
1396 if (0 == ReadStandardLowlevel (usalp, (UINT4 *)bufferTOC, lSector, 1, CD_FRAMESIZE_RAW + 16 )) {
1400 fprintf(stderr, "Subchannel Sec %x: %02x %02x %02x %02x\n"
1402 ,bufferTOC[CD_FRAMESIZE_RAW + 0]
1403 ,bufferTOC[CD_FRAMESIZE_RAW + 1]
1404 ,bufferTOC[CD_FRAMESIZE_RAW + 2]
1405 ,bufferTOC[CD_FRAMESIZE_RAW + 3]
1408 sc.control_adr = (bufferTOC[CD_FRAMESIZE_RAW + 0] << 4)
1409 | bufferTOC[CD_FRAMESIZE_RAW + 1];
1410 sc.track = from_bcd(bufferTOC[CD_FRAMESIZE_RAW + 2]);
1411 sc.index = from_bcd(bufferTOC[CD_FRAMESIZE_RAW + 3]);
1414 /********* non standardized speed selects ***********************/
1416 void SpeedSelectSCSIToshiba(SCSI *usalp, unsigned speed)
1418 static unsigned char mode [4 + 3];
1419 unsigned char *page = mode + 4;
1422 fillbytes((caddr_t)mode, sizeof(mode), '\0');
1423 /* the first 4 mode bytes are zero. */
1426 page[2] = speed; /* 0 for single speed, 1 for double speed (3401) */
1428 if (usalp->verbose) fprintf(stderr, "\nspeed select Toshiba...");
1431 /* do the scsi cmd */
1432 if ((retval = mode_select(usalp, mode, 7, 0, usalp->inq->data_format >= 2)) < 0)
1433 fprintf (stderr, "speed select Toshiba failed\n");
1437 void SpeedSelectSCSINEC(SCSI *usalp, unsigned speed)
1439 static unsigned char mode [4 + 8];
1440 unsigned char *page = mode + 4;
1442 register struct usal_cmd *scmd = usalp->scmd;
1444 fillbytes((caddr_t)mode, sizeof(mode), '\0');
1445 /* the first 4 mode bytes are zero. */
1446 page [0] = 0x0f; /* page code */
1447 page [1] = 6; /* parameter length */
1448 /* bit 5 == 1 for single speed, otherwise double speed */
1449 page [2] = speed == 1 ? 1 << 5 : 0;
1451 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1452 scmd->addr = (caddr_t)mode;
1454 scmd->flags = SCG_DISRE_ENA;
1455 scmd->cdb_len = SC_G1_CDBLEN;
1456 scmd->sense_len = CCS_SENSE_LEN;
1457 scmd->cdb.g1_cdb.cmd = 0xC5;
1458 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
1459 scmd->cdb.g1_cdb.addr[0] = 0 ? 1 : 0 | 1 ? 0x10 : 0;
1460 g1_cdblen(&scmd->cdb.g1_cdb, 12);
1462 if (usalp->verbose) fprintf(stderr, "\nspeed select NEC...");
1463 /* do the scsi cmd */
1465 usalp->cmdname = "speed select NEC";
1467 if ((retval = usal_cmd(usalp)) < 0)
1468 fprintf(stderr ,"speed select NEC failed\n");
1471 void SpeedSelectSCSIPhilipsCDD2600(SCSI *usalp, unsigned speed)
1473 /* MODE_SELECT, page = SCSI-2 save page disabled, reserved, reserved,
1474 parm list len, flags */
1475 static unsigned char mode [4 + 8];
1476 unsigned char *page = mode + 4;
1479 fillbytes((caddr_t)mode, sizeof(mode), '\0');
1480 /* the first 4 mode bytes are zero. */
1483 page[2] = page [4] = speed;
1486 if (usalp->verbose) fprintf(stderr, "\nspeed select Philips...");
1487 /* do the scsi cmd */
1488 if ((retval = mode_select(usalp, mode, 12, 0, usalp->inq->data_format >= 2)) < 0)
1489 fprintf (stderr, "speed select PhilipsCDD2600 failed\n");
1492 void SpeedSelectSCSISony(SCSI *usalp, unsigned speed)
1494 static unsigned char mode [4 + 4];
1495 unsigned char *page = mode + 4;
1498 fillbytes((caddr_t)mode, sizeof(mode), '\0');
1499 /* the first 4 mode bytes are zero. */
1504 if (usalp->verbose) fprintf(stderr, "\nspeed select Sony...");
1505 /* do the scsi cmd */
1507 if ((retval = mode_select(usalp, mode, 8, 0, usalp->inq->data_format >= 2)) < 0)
1508 fprintf (stderr, "speed select Sony failed\n");
1512 void SpeedSelectSCSIYamaha (usalp, speed)
1516 static unsigned char mode [4 + 4];
1517 unsigned char *page = mode + 4;
1520 fillbytes((caddr_t)mode, sizeof(mode), '\0');
1521 /* the first 4 mode bytes are zero. */
1526 if (usalp->verbose) fprintf(stderr, "\nspeed select Yamaha...");
1527 /* do the scsi cmd */
1528 if ((retval = mode_select(usalp, mode, 8, 0, usalp->inq->data_format >= 2)) < 0)
1529 fprintf (stderr, "speed select Yamaha failed\n");
1532 void SpeedSelectSCSIMMC(SCSI *usalp, unsigned speed)
1535 register struct usal_cmd *scmd = usalp->scmd;
1537 if (speed == 0 || speed == 0xFFFF) {
1540 spd = (1764 * speed) / 10;
1542 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1543 scmd->flags = SCG_DISRE_ENA;
1544 scmd->cdb_len = SC_G5_CDBLEN;
1545 scmd->sense_len = CCS_SENSE_LEN;
1546 scmd->cdb.g5_cdb.cmd = 0xBB;
1547 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
1548 i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], spd);
1549 i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], 0xffff);
1551 if (usalp->verbose) fprintf(stderr, "\nspeed select MMC...");
1553 usalp->cmdname = "set cd speed";
1556 if (usal_cmd(usalp) < 0) {
1557 if (usal_sense_key(usalp) == 0x05 &&
1558 usal_sense_code(usalp) == 0x20 &&
1559 usal_sense_qual(usalp) == 0x00) {
1560 /* this optional command is not implemented */
1562 usal_printerr(usalp);
1563 fprintf (stderr, "speed select MMC failed\n");
1569 /* request vendor brand and model */
1570 unsigned char *Inquiry(SCSI *usalp)
1572 static unsigned char *Inqbuffer = NULL;
1573 register struct usal_cmd *scmd = usalp->scmd;
1575 if (Inqbuffer == NULL) {
1576 Inqbuffer = malloc(36);
1577 if (Inqbuffer == NULL) {
1578 fprintf(stderr, "Cannot allocate memory for inquiry command in line %d\n", __LINE__);
1583 fillbytes(Inqbuffer, 36, '\0');
1584 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1585 scmd->addr = (caddr_t)Inqbuffer;
1587 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1588 scmd->cdb_len = SC_G0_CDBLEN;
1589 scmd->sense_len = CCS_SENSE_LEN;
1590 scmd->cdb.g0_cdb.cmd = SC_INQUIRY;
1591 scmd->cdb.g0_cdb.lun = usal_lun(usalp);
1592 scmd->cdb.g0_cdb.count = 36;
1594 usalp->cmdname = "inquiry";
1596 if (usal_cmd(usalp) < 0)
1599 /* define structure with inquiry data */
1600 memcpy(usalp->inq, Inqbuffer, sizeof(*usalp->inq));
1603 usal_prbytes("Inquiry Data :", (Uchar *)Inqbuffer, 22 - scmd->resid);
1608 #define SC_CLASS_EXTENDED_SENSE 0x07
1609 #define TESTUNITREADY_CMD 0
1610 #define TESTUNITREADY_CMDLEN 6
1612 #define ADD_SENSECODE 12
1613 #define ADD_SC_QUALIFIER 13
1614 #define NO_MEDIA_SC 0x3a
1615 #define NO_MEDIA_SCQ 0x00
1617 int TestForMedium(SCSI *usalp)
1619 register struct usal_cmd *scmd = usalp->scmd;
1621 if (interface != GENERIC_SCSI) {
1625 /* request READY status */
1626 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1627 scmd->addr = (caddr_t)0;
1629 scmd->flags = SCG_DISRE_ENA | (1 ? SCG_SILENT:0);
1630 scmd->cdb_len = SC_G0_CDBLEN;
1631 scmd->sense_len = CCS_SENSE_LEN;
1632 scmd->cdb.g0_cdb.cmd = SC_TEST_UNIT_READY;
1633 scmd->cdb.g0_cdb.lun = usal_lun(usalp);
1635 if (usalp->verbose) fprintf(stderr, "\ntest unit ready...");
1638 usalp->cmdname = "test unit ready";
1640 if (usal_cmd(usalp) >= 0) {
1646 if (scmd->sense.code >= SC_CLASS_EXTENDED_SENSE) {
1648 scmd->u_sense.cmd_sense[ADD_SENSECODE] != NO_MEDIA_SC ||
1649 scmd->u_sense.cmd_sense[ADD_SC_QUALIFIER] != NO_MEDIA_SCQ;
1651 /* analyse status. */
1652 /* 'check condition' is interpreted as not ready. */
1653 return (scmd->u_scb.cmd_scb[0] & 0x1e) != 0x02;
1657 int StopPlaySCSI(SCSI *usalp)
1659 register struct usal_cmd *scmd = usalp->scmd;
1661 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1664 scmd->flags = SCG_DISRE_ENA;
1665 scmd->cdb_len = SC_G0_CDBLEN;
1666 scmd->sense_len = CCS_SENSE_LEN;
1667 scmd->cdb.g0_cdb.cmd = 0x1b;
1668 scmd->cdb.g0_cdb.lun = usal_lun(usalp);
1670 if (usalp->verbose) fprintf(stderr, "\nstop audio play");
1671 /* do the scsi cmd */
1673 usalp->cmdname = "stop audio play";
1675 return usal_cmd(usalp) >= 0 ? 0 : -1;
1678 int Play_atSCSI(SCSI *usalp, unsigned int from_sector, unsigned int sectors)
1680 register struct usal_cmd *scmd = usalp->scmd;
1682 fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1685 scmd->flags = SCG_DISRE_ENA;
1686 scmd->cdb_len = SC_G1_CDBLEN;
1687 scmd->sense_len = CCS_SENSE_LEN;
1688 scmd->cdb.g1_cdb.cmd = 0x47;
1689 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
1690 scmd->cdb.g1_cdb.addr[1] = (from_sector + 150) / (60*75);
1691 scmd->cdb.g1_cdb.addr[2] = ((from_sector + 150) / 75) % 60;
1692 scmd->cdb.g1_cdb.addr[3] = (from_sector + 150) % 75;
1693 scmd->cdb.g1_cdb.res6 = (from_sector + 150 + sectors) / (60*75);
1694 scmd->cdb.g1_cdb.count[0] = ((from_sector + 150 + sectors) / 75) % 60;
1695 scmd->cdb.g1_cdb.count[1] = (from_sector + 150 + sectors) % 75;
1697 if (usalp->verbose) fprintf(stderr, "\nplay sectors...");
1698 /* do the scsi cmd */
1700 usalp->cmdname = "play sectors";
1702 return usal_cmd(usalp) >= 0 ? 0 : -1;
1705 static caddr_t scsibuffer; /* page aligned scsi transfer buffer */
1707 void init_scsibuf(SCSI *scsp, unsigned amt);
1709 void init_scsibuf(SCSI *usalp, unsigned amt)
1711 if (scsibuffer != NULL) {
1712 fprintf(stderr, "the SCSI transfer buffer has already been allocated!\n");
1713 exit(SETUPSCSI_ERROR);
1715 scsibuffer = usal_getbuf(usalp, amt);
1716 if (scsibuffer == NULL) {
1717 fprintf(stderr, "could not get SCSI transfer buffer!\n");
1718 exit(SETUPSCSI_ERROR);