Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / icedax / scsi_cmds.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
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).
6  *
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.
10  *
11  */
12
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.
16  */
17 #undef  DEBUG_FULLTOC
18 #undef  WARN_FULLTOC
19 #define TESTSUBQFALLBACK        0
20
21 #include "config.h"
22 #include <stdio.h>
23 #include <standard.h>
24 #include <stdxlib.h>
25 #include <strdefs.h>
26 #include <schily.h>
27
28 #include <btorder.h>
29
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)
33
34
35 #include <usal/usalcmd.h>
36 #include <usal/scsidefs.h>
37 #include <usal/scsireg.h>
38
39 #include <usal/scsitransp.h>
40
41 #include "mytype.h"
42 #include "icedax.h"
43 #include "interface.h"
44 #include "byteorder.h"
45 #include "global.h"
46 #include "wodim.h"
47 #include "toc.h"
48 #include "scsi_cmds.h"
49 #include "exitcodes.h"
50
51 unsigned char *bufferTOC;
52 subq_chnl *SubQbuffer;
53 unsigned char *cmd;
54
55 static unsigned ReadFullTOCSony(SCSI *usalp);
56 static unsigned ReadFullTOCMMC(SCSI *usalp);
57
58
59 int SCSI_emulated_ATAPI_on(SCSI *usalp)
60 {
61 /*      return is_atapi;*/
62         if (usal_isatapi(usalp) > 0)
63                 return (TRUE);
64
65         (void) allow_atapi(usalp, TRUE);
66         return (allow_atapi(usalp, TRUE));
67 }
68
69 int heiko_mmc(SCSI *usalp)
70 {
71         unsigned char   mode[0x100];
72         int             was_atapi;
73         struct  cd_mode_page_2A *mp;
74         int retval;
75
76         fillbytes((caddr_t)mode, sizeof(mode), '\0');
77
78         was_atapi = allow_atapi(usalp, 1);
79         usalp->silent++;
80         mp = mmc_cap(usalp, mode);
81         usalp->silent--;
82         allow_atapi(usalp, was_atapi);
83         if (mp == NULL)
84                 return (0);
85
86         /* have a look at the capabilities */
87         if (mp->cd_da_supported == 0) {
88           retval = -1;
89         } else {
90           retval = 1 + mp->cd_da_accurate;
91         }
92         return retval;
93 }
94
95
96 int accepts_fua_bit;
97 unsigned char density = 0;
98 unsigned char orgmode4 = 0;
99 unsigned char orgmode10, orgmode11;
100
101 /* get current sector size from SCSI cdrom drive */
102 unsigned int 
103 get_orig_sectorsize(SCSI *usalp, unsigned char *m4, unsigned char *m10, 
104                     unsigned char *m11)
105 {
106       /* first get current values for density, etc. */
107
108       static unsigned char *modesense = NULL;
109    
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__);
114           return 0;
115         }
116       }
117
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");
122
123       /* FIXME: some drives dont deliver block descriptors !!! */
124       if (modesense[3] == 0)
125         return 0;
126
127 #if     0
128         modesense[4] = 0x81;
129         modesense[10] = 0x08;
130         modesense[11] = 0x00;
131 #endif
132
133       if (m4 != NULL)                       /* density */
134         *m4 = modesense[4];
135       if (m10 != NULL)                      /* MSB sector size */
136         *m10 = modesense[10];
137       if (m11 != NULL)                      /* LSB sector size */
138         *m11 = modesense[11];
139
140       return (modesense[10] << 8) + modesense[11];
141 }
142
143
144
145 /* switch CDROM scsi drives to given sector size  */
146 int set_sectorsize(SCSI *usalp, unsigned int secsize)
147 {
148   static unsigned char mode [4 + 8];
149   int retval;
150
151   if (orgmode4 == 0xff) {
152     get_orig_sectorsize(usalp, &orgmode4, &orgmode10, &orgmode11);
153   }
154   if (orgmode4 == 0x82 && secsize == 2048)
155     orgmode4 = 0x81;
156
157   /* prepare to read cds in the previous mode */
158
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 */
164
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");
169
170   return retval;
171 }
172
173
174 /* switch Toshiba/DEC and HP drives from/to cdda density */
175 void EnableCddaModeSelect(SCSI *usalp, int fAudioMode, unsigned uSectorsize)
176 {
177   /* reserved, Medium type=0, Dev spec Parm = 0, block descriptor len 0 oder 8,
178      Density (cd format) 
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,
182    */
183
184   /* MODE_SELECT, page = SCSI-2  save page disabled, reserved, reserved, 
185      parm list len, flags */
186   static unsigned char mode [4 + 8] = { 
187        /* mode section */
188                             0, 
189                             0, 0, 
190                             8,       /* Block Descriptor Length */
191        /* block descriptor */
192                             0,       /* Density Code */
193                             0, 0, 0, /* # of Blocks */
194                             0,       /* reserved */
195                             0, 0, 0};/* Blocklen */
196
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);
202     }
203   }
204
205   if (fAudioMode) {
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" */
210   } else {
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 */
215   }
216
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");
221 }
222
223
224 /* read CD Text information from the table of contents */
225 void ReadTocTextSCSIMMC(SCSI *usalp)
226 {
227     short datalength;
228
229 #if 1
230   /* READTOC, MSF, format, res, res, res, Start track/session, len msb,
231      len lsb, control */
232         unsigned char *p = bufferTOC;
233         register struct usal_cmd        *scmd = usalp->scmd;
234
235         fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
236         scmd->addr = (caddr_t)bufferTOC;
237         scmd->size = 4;
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);
246
247         usalp->silent++;
248         if (usalp->verbose) fprintf(stderr, "\nRead TOC CD Text size ...");
249
250         usalp->cmdname = "read toc size (text)";
251
252         if (usal_cmd(usalp) < 0) {
253           usalp->silent--;
254           if (global.quiet != 1)
255             fprintf (stderr, "Read TOC CD Text failed (probably not supported).\n");
256           p[0] = p[1] = '\0';
257           return ;
258         }
259         usalp->silent--;
260
261         datalength  = (p[0] << 8) | (p[1]);
262         if (datalength <= 2)
263                 return;
264
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);
276
277         usalp->silent++;
278         if (usalp->verbose) fprintf(stderr, "\nRead TOC CD Text data (length %hd)...", 2+datalength);
279
280         usalp->cmdname = "read toc data (text)";
281
282         if (usal_cmd(usalp) < 0) {
283           usalp->silent--;
284           if (global.quiet != 1)
285             fprintf (stderr,  "Read TOC CD Text data failed (probably not supported).\n");
286           p[0] = p[1] = '\0';
287           return ;
288         }
289         usalp->silent--;
290 #else
291         { FILE *fp;
292         int read_;
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]);
301         fclose(fp);
302         }
303 #endif
304 }
305
306 /* read the full TOC */
307 static unsigned ReadFullTOCSony(SCSI *usalp)
308 {
309   /* READTOC, MSF, format, res, res, res, Start track/session, len msb,
310      len lsb, control */
311         register struct usal_cmd        *scmd = usalp->scmd;
312         unsigned tracks = 99;
313
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 */
325
326         usalp->silent++;
327         if (usalp->verbose) fprintf(stderr, "\nRead Full TOC Sony ...");
328
329         usalp->cmdname = "read full toc sony";
330
331         if (usal_cmd(usalp) < 0) {
332           usalp->silent--;
333           if (global.quiet != 1)
334             fprintf (stderr, "Read Full TOC Sony failed (probably not supported).\n");
335           return 0;
336         }
337         usalp->silent--;
338
339         return (unsigned)((bufferTOC[0] << 8) | bufferTOC[1]);
340 }
341
342 struct msf_address {
343         unsigned char   mins;
344         unsigned char   secs;
345         unsigned char   frame;
346 };
347
348 struct zmsf_address {
349         unsigned char   zero;
350         unsigned char   mins;
351         unsigned char   secs;
352         unsigned char   frame;
353 };
354
355 #ifdef  WARN_FULLTOC
356 static unsigned lba(struct msf_address *ad);
357
358 static unsigned lba(struct msf_address *ad)
359 {
360         return  ad->mins*60*75 + ad->secs*75 + ad->frame;
361 }
362 #endif
363
364 static unsigned dvd_lba(struct zmsf_address *ad);
365
366 static unsigned dvd_lba(struct zmsf_address *ad)
367 {
368         return  ad->zero*1053696 + ad->mins*60*75 + ad->secs*75 + ad->frame;
369 }
370
371 struct tocdesc {
372         unsigned char   session;
373         unsigned char   adrctl;
374         unsigned char   tno;
375         unsigned char   point;
376         struct msf_address      adr1;
377         struct zmsf_address     padr2;
378 };
379
380 struct outer {
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];
386 };
387
388 static unsigned long first_session_leadout = 0;
389
390 static unsigned collect_tracks(struct outer *po, unsigned entries, 
391                                                                                  BOOL bcd_flag);
392
393 static unsigned collect_tracks(struct outer *po, unsigned entries, 
394                                BOOL bcd_flag)
395 {
396         unsigned tracks = 0;
397         int i;
398         unsigned session;
399         unsigned last_start;
400         unsigned leadout_start_orig;
401         unsigned leadout_start;
402         unsigned max_leadout = 0;
403
404 #ifdef  DEBUG_FULLTOC
405         for (i = 0; i < entries; i++) {
406 fprintf(stderr, "%3d: %d %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n" 
407         ,i
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)]
419         );
420         }
421 #endif
422         /* reformat to standard toc format */
423
424         bufferTOC[2] = 0;
425         bufferTOC[3] = 0;
426         session = 0;
427         last_start = 0;
428         leadout_start_orig = 0;
429         leadout_start = 0;
430
431         for (i = 0; i < entries; i++) {
432 #ifdef  WARN_FULLTOC
433                 if (po->ent[i].tno != 0) {
434                         fprintf(stderr,
435 "entry %d, tno is not 0: %d!\n",
436 i, po->ent[i].tno);
437                 }
438 #endif
439                 if (bcd_flag) {
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);
447                 }
448                 switch (po->ent[i].point) {
449                 case    0xa0:
450
451                         /* check if session is monotonous increasing */
452
453                         if (session+1 == po->ent[i].session) {
454                                 session = po->ent[i].session;
455                         }
456 #ifdef  WARN_FULLTOC
457                         else fprintf(stderr,
458 "entry %d, session anomaly %d != %d!\n",
459 i, session+1, po->ent[i].session);
460
461                         /* check the adrctl field */
462                         if (0x10 != (po->ent[i].adrctl & 0x10)) {
463                                 fprintf(stderr,
464 "entry %d, incorrect adrctl field %x!\n",
465 i, po->ent[i].adrctl);
466                         }
467 #endif
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;
472                         }
473 #ifdef  WARN_FULLTOC
474                         else
475                                 fprintf(stderr,
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]);
478 #endif
479                         break;
480
481                 case    0xa1:
482 #ifdef  WARN_FULLTOC
483                         /* check if session is constant */
484                         if (session != po->ent[i].session) {
485                                 fprintf(stderr,
486 "entry %d, session anomaly %d != %d!\n",
487 i, session, po->ent[i].session);
488                         }
489
490                         /* check the adrctl field */
491                         if (0x10 != (po->ent[i].adrctl & 0x10)) {
492                                 fprintf(stderr,
493 "entry %d, incorrect adrctl field %x!\n",
494 i, po->ent[i].adrctl);
495                         }
496 #endif
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;
501                         }
502 #ifdef  WARN_FULLTOC
503                         else
504                                 fprintf(stderr,
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]);
507 #endif
508                         break;
509
510                 case    0xa2:
511 #ifdef  WARN_FULLTOC
512                         /* check if session is constant */
513                         if (session != po->ent[i].session) {
514                                 fprintf(stderr,
515 "entry %d, session anomaly %d != %d!\n",
516 i, session, po->ent[i].session);
517                         }
518
519                         /* check the adrctl field */
520                         if (0x10 != (po->ent[i].adrctl & 0x10)) {
521                                 fprintf(stderr,
522 "entry %d, incorrect adrctl field %x!\n",
523 i, po->ent[i].adrctl);
524                         }
525 #endif
526                         /* register leadout position */
527                 {
528                         unsigned leadout_start_tmp  = 
529                                 dvd_lba(&po->ent[i].padr2);
530
531                         if (first_session_leadout  == 0)
532                                 first_session_leadout = leadout_start_tmp - 150;
533
534                         if (leadout_start_tmp > leadout_start) {
535                                 leadout_start_orig = leadout_start_tmp;
536                                 leadout_start = leadout_start_tmp;
537                         }
538 #ifdef  WARN_FULLTOC
539                         else
540                                 fprintf(stderr,
541 "entry %d, leadout position anomaly %u!\n",
542 i, leadout_start_tmp);
543 #endif
544                 }
545                         break;
546
547                 case    0xb0:
548 #ifdef  WARN_FULLTOC
549                         /* check if session is constant */
550                         if (session != po->ent[i].session) {
551                                 fprintf(stderr,
552 "entry %d, session anomaly %d != %d!\n",
553 i, session, po->ent[i].session);
554                         }
555
556                         /* check the adrctl field */
557                         if (0x50 != (po->ent[i].adrctl & 0x50)) {
558                                 fprintf(stderr,
559 "entry %d, incorrect adrctl field %x!\n",
560 i, po->ent[i].adrctl);
561                         }
562
563                         /* check the next program area */
564                         if (lba(&po->ent[i].adr1) < 6750 + leadout_start) {
565                                 fprintf(stderr,
566 "entry %d, next program area %u < leadout_start + 6750 = %u!\n",
567 i, lba(&po->ent[i].adr1), 6750 + leadout_start);
568                         }
569
570                         /* check the maximum leadout_start */
571                         if (max_leadout != 0 && dvd_lba(&po->ent[i].padr2) != max_leadout) {
572                                 fprintf(stderr,
573 "entry %d, max leadout_start %u != last max_leadout_start %u!\n",
574 i, dvd_lba(&po->ent[i].padr2), max_leadout);
575                         }
576 #endif
577                         if (max_leadout == 0)
578                                 max_leadout = dvd_lba(&po->ent[i].padr2);
579
580                         break;
581                 case    0xb1:
582                 case    0xb2:
583                 case    0xb3:
584                 case    0xb4:
585                 case    0xb5:
586                 case    0xb6:
587                         break;
588                 case    0xc0:
589                 case    0xc1:
590                         break;
591                 default:
592                         /* check if session is constant */
593                         if (session != po->ent[i].session) {
594 #ifdef  WARN_FULLTOC
595                                 fprintf(stderr,
596 "entry %d, session anomaly %d != %d!\n",
597 i, session, po->ent[i].session);
598 #endif
599                                 continue;
600                         }
601
602                         /* check tno */
603                         if (bcd_flag)
604                                 po->ent[i].point  = from_bcd(po->ent[i].point);
605
606                         if (po->ent[i].point < bufferTOC[2]
607                             || po->ent[i].point > bufferTOC[3]) {
608 #ifdef  WARN_FULLTOC
609                                 fprintf(stderr,
610 "entry %d, track number anomaly %d - %d - %d!\n",
611 i, bufferTOC[2], po->ent[i].point, bufferTOC[3]);
612 #endif
613                         } else {
614                                 /* check start position */
615                                 unsigned trackstart = dvd_lba(&po->ent[i].padr2);
616
617                                 /* correct illegal leadouts */
618                                 if (leadout_start < trackstart) {
619                                         leadout_start = trackstart+1;
620                                 }
621                                 if (trackstart < last_start || trackstart >= leadout_start) {
622 #ifdef  WARN_FULLTOC
623                                         fprintf(stderr,
624 "entry %d, track %d start position anomaly %d - %d - %d!\n",
625 i, po->ent[i].point, last_start, trackstart, leadout_start);
626 #endif
627                                 } else {
628                                         last_start = trackstart;
629                                         memcpy(&po->ent[tracks], &po->ent[i], sizeof(struct tocdesc));
630                                         tracks++;
631                                 }
632                         }
633                 }       /* switch */
634         }       /* for */
635
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;
648         tracks++;
649
650         /* length */
651         bufferTOC[0] = ((tracks * 8) + 2) >> 8;
652         bufferTOC[1] = ((tracks * 8) + 2) & 0xff;
653
654
655         /* reformat 11 byte blocks to 8 byte entries */
656
657         /* 1: Session   \       /       reserved
658            2: adr ctrl  |       |       adr ctrl
659            3: TNO       |       |       track number
660            4: Point     |       |       reserved
661            5: Min       +-->----+       0
662            6: Sec       |       |       Min
663            7: Frame     |       |       Sec
664            8: Zero      |       \       Frame
665            9: PMin      |
666            10: PSec     |
667            11: PFrame   /
668         */
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)];
679 #ifdef  DEBUG_FULLTOC
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]
687 );
688 #endif
689         }
690
691         TOC_entries(tracks, NULL, bufferTOC+4, 0);
692         return tracks;
693 }
694
695 /* read the table of contents from the cd and fill the TOC array */
696 unsigned ReadTocSony(SCSI *usalp)
697 {
698         unsigned tracks = 0;
699         unsigned return_length;
700
701         struct outer *po = (struct outer *)bufferTOC;
702
703         return_length = ReadFullTOCSony(usalp);
704
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 );
710         }
711
712         tracks = collect_tracks(po, ((return_length - 2) / 11), TRUE);
713
714         return --tracks;           /* without lead-out */
715 }
716
717 /* read the start of the lead-out from the first session TOC */
718 unsigned ReadFirstSessionTOCSony(SCSI *usalp)
719 {
720         unsigned return_length;
721         
722         if (first_session_leadout != 0)
723                 return first_session_leadout;
724
725         return_length = ReadFullTOCSony(usalp);
726         if (return_length >= 4 + (3 * 11) -2) {
727           unsigned off;
728
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) {
733             unsigned retval;
734
735             off = 4 + 2 * 11 + 8;
736             retval = bufferTOC[off] >> 4;
737             retval *= 10; retval += bufferTOC[off] & 0xf;
738             retval *= 60;
739             off++;
740             retval += 10 * (bufferTOC[off] >> 4) + (bufferTOC[off] & 0xf);
741             retval *= 75;
742             off++;
743             retval += 10 * (bufferTOC[off] >> 4) + (bufferTOC[off] & 0xf);
744             retval -= 150;
745
746             return retval;
747           }
748         }
749         return 0;
750 }
751
752 /* read the full TOC */
753 static unsigned ReadFullTOCMMC(SCSI *usalp)
754 {
755
756   /* READTOC, MSF, format, res, res, res, Start track/session, len msb,
757      len lsb, control */
758         register struct usal_cmd        *scmd = usalp->scmd;
759         unsigned tracks = 99;
760
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);
772
773         usalp->silent++;
774         if (usalp->verbose) fprintf(stderr, "\nRead Full TOC MMC...");
775
776         usalp->cmdname = "read full toc mmc";
777
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
782 #else
783           usalp->silent--;
784           return 0;
785 #endif
786         }
787         usalp->silent--;
788
789         return (unsigned)((bufferTOC[0] << 8) | bufferTOC[1]);
790 }
791
792 /* read the start of the lead-out from the first session TOC */
793 unsigned ReadFirstSessionTOCMMC(SCSI *usalp)
794 {
795         unsigned off;
796         unsigned return_length;
797
798         if (first_session_leadout != 0)
799                 return first_session_leadout;
800
801         return_length = ReadFullTOCMMC(usalp);
802
803         /* We want the entry with POINT = 0xA2, which has the start position
804              of the first session lead out */
805         off = 4 + 3;
806         while (off < return_length && bufferTOC[off] != 0xA2) {
807           off += 11;
808         }
809         if (off < return_length) {
810           off += 5;
811           return (bufferTOC[off]*60 + bufferTOC[off+1])*75 + bufferTOC[off+2] - 150;
812         }
813         return 0;
814 }
815
816 /* read the table of contents from the cd and fill the TOC array */
817 unsigned ReadTocMMC(SCSI *usalp)
818 {
819         unsigned tracks = 0;
820         unsigned return_length;
821
822         struct outer *po = (struct outer *)bufferTOC;
823
824         return_length = ReadFullTOCMMC(usalp);
825         if (return_length - 2 < 4*11 || ((return_length - 2) % 11) != 0)
826                 return ReadTocSCSI(usalp);
827
828         tracks = collect_tracks(po, ((return_length - 2) / 11), FALSE);
829         return --tracks;           /* without lead-out */
830 }
831
832 /* read the table of contents from the cd and fill the TOC array */
833 unsigned ReadTocSCSI(SCSI *usalp)
834 {
835     unsigned tracks;
836     int result;
837     unsigned char bufferTOCMSF[CD_FRAMESIZE];
838
839     /* first read the first and last track number */
840     /* READTOC, MSF format flag, res, res, res, res, Start track, len msb,
841        len lsb, flags */
842     register struct     usal_cmd        *scmd = usalp->scmd;
843
844     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
845     scmd->addr = (caddr_t)bufferTOC;
846     scmd->size = 4;
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);
854
855     if (usalp->verbose) fprintf(stderr, "\nRead TOC size (standard)...");
856     /* do the scsi cmd (read table of contents) */
857
858     usalp->cmdname = "read toc size";
859     if (usal_cmd(usalp) < 0)
860         FatalError ("Read TOC size failed.\n");
861     
862
863     tracks = ((bufferTOC [3] ) - bufferTOC [2] + 2) ;
864     if (tracks > MAXTRK) return 0;
865     if (tracks == 0) return 0;
866     
867     
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);
880
881     if (usalp->verbose) fprintf(stderr, "\nRead TOC tracks (standard MSF)...");
882     /* do the scsi cmd (read table of contents) */
883
884     usalp->cmdname = "read toc tracks ";
885     result = usal_cmd(usalp);
886
887     if (result < 0) {
888         /* MSF format did not succeeded */
889         memset(bufferTOCMSF, 0, sizeof(bufferTOCMSF));
890     } else {
891         int     i;
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);
894 #if     0
895 fprintf(stderr, "MSF %d %02x %02x %02x %02x %02x %02x %02x %02x\n" 
896         ,i
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)]
905         );
906 #endif
907         }
908     }
909
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);
922
923     if (usalp->verbose) fprintf(stderr, "\nRead TOC tracks (standard LBA)...");
924     /* do the scsi cmd (read table of contents) */
925
926     usalp->cmdname = "read toc tracks ";
927     if (usal_cmd(usalp) < 0) {
928         FatalError ("Read TOC tracks (lba) failed.\n");
929     }
930     {
931         int     i;
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);
934 #if     0
935 fprintf(stderr, "LBA %d %02x %02x %02x %02x %02x %02x %02x %02x\n" 
936         ,i
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)]
945         );
946 #endif
947         }
948     }
949     TOC_entries(tracks, bufferTOC+4, bufferTOCMSF+4, result);
950     return --tracks;           /* without lead-out */
951 }
952
953 /* ---------------- Read methods ------------------------------ */
954
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);
959
960 static int ReadStandardLowlevel(SCSI *usalp, UINT4 *p, unsigned lSector, 
961                                                                                   unsigned SectorBurstVal, unsigned secsize)
962 {
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;
966
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);
979
980         usalp->cmdname = "ReadStandard10";
981
982         if (usal_cmd(usalp)) return 0;
983
984         /* has all or something been read? */
985         return SectorBurstVal - usal_getresid(usalp)/secsize;
986 }
987
988
989 int 
990 ReadStandard(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal)
991 {
992         return ReadStandardLowlevel(usalp, p, lSector, SectorBurstVal, CD_FRAMESIZE_RAW);
993 }
994
995 int 
996 ReadStandardData(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal)
997 {
998         return ReadStandardLowlevel(usalp, p, lSector, SectorBurstVal, CD_FRAMESIZE);
999 }
1000
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)
1004 {
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;
1008
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...");
1021
1022         usalp->cmdname = "Read10 NEC";
1023
1024         if (usal_cmd(usalp)) return 0;
1025
1026         /* has all or something been read? */
1027         return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW;
1028 }
1029
1030
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)
1034 {
1035         register struct usal_cmd        *scmd = usalp->scmd;
1036
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);
1048
1049         if (usalp->verbose) fprintf(stderr, "\nReadSony12 CDDA...");
1050
1051         usalp->cmdname = "Read12";
1052
1053         if (usal_cmd(usalp)) return 0;
1054
1055         /* has all or something been read? */
1056         return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW;
1057 }
1058
1059 /* Read max. SectorBurst of cdda sectors to buffer
1060    via vendor-specific ReadCdda(12) command */
1061 /*
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).
1064 */
1065
1066 int ReadCdda12Matsushita(SCSI *usalp, UINT4 *p, unsigned lSector, 
1067                          unsigned SectorBurstVal)
1068 {
1069         register struct usal_cmd        *scmd = usalp->scmd;
1070
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);
1082
1083         if (usalp->verbose) fprintf(stderr, "\nReadMatsushita12 CDDA...");
1084
1085         usalp->cmdname = "Read12Matsushita";
1086
1087         if (usal_cmd(usalp)) return 0;
1088
1089         /* has all or something been read? */
1090         return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW;
1091 }
1092
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)
1097 {
1098         register struct usal_cmd        *scmd;
1099         scmd = usalp->scmd;
1100
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 */
1113
1114         if (usalp->verbose) fprintf(stderr, "\nReadMMC12 CDDA...");
1115
1116         usalp->cmdname = "ReadCD MMC 12";
1117
1118         if (usal_cmd(usalp)) return 0;
1119
1120         /* has all or something been read? */
1121         return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW;
1122 }
1123
1124 int ReadCddaFallbackMMC(SCSI *usalp, UINT4 *p, unsigned lSector, 
1125                         unsigned SectorBurstVal)
1126 {
1127         static int ReadCdda12_unknown = 0;
1128         int retval = -999;
1129
1130         usalp->silent++;
1131         if (ReadCdda12_unknown 
1132             || ((retval = ReadCdda12(usalp, p, lSector, SectorBurstVal)) <= 0)) {
1133                 /* if the command is not available, use the regular
1134                  * MMC ReadCd 
1135                  */
1136                 if (retval <= 0 && usal_sense_key(usalp) == 0x05) {
1137                         ReadCdda12_unknown = 1;
1138                 }
1139                 usalp->silent--;
1140                 ReadCdRom = ReadCddaMMC12;
1141                 ReadCdRomSub = ReadCddaSubMMC12;
1142                 return ReadCddaMMC12(usalp, p, lSector, SectorBurstVal);
1143         }
1144         usalp->silent--;
1145         return retval;
1146 }
1147
1148 /* Read the Sub-Q-Channel to SubQbuffer. This is the method for
1149  * drives that do not support subchannel parameters. */
1150 #ifdef  PROTOTYPES
1151 static subq_chnl *ReadSubQFallback (SCSI *usalp, unsigned char sq_format, unsigned char track)
1152 #else
1153 static subq_chnl *
1154 ReadSubQFallback(SCSI *usalp, unsigned char sq_format, unsigned char track)
1155 #endif
1156 {
1157         register struct usal_cmd        *scmd = usalp->scmd;
1158
1159         fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1160         scmd->addr = (caddr_t)SubQbuffer;
1161         scmd->size = 24;
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 */
1166                                                 /* use LBA */
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);
1172
1173         if (usalp->verbose) fprintf(stderr, "\nRead Subchannel_dumb...");
1174
1175         usalp->cmdname = "Read Subchannel_dumb";
1176
1177         if (usal_cmd(usalp) < 0) {
1178           fprintf( stderr, "Read SubQ failed\n");
1179         }
1180
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);
1187             return SubQbuffer;
1188           }
1189         }
1190
1191         /* FIXME: we might actively search for the requested info ... */
1192         return NULL;
1193 }
1194
1195 /* Read the Sub-Q-Channel to SubQbuffer */
1196 #ifdef  PROTOTYPES
1197 subq_chnl *ReadSubQSCSI (SCSI *usalp, unsigned char sq_format, unsigned char track)
1198 #else
1199 subq_chnl *
1200 ReadSubQSCSI(SCSI *usalp, unsigned char sq_format, unsigned char track)
1201 #endif
1202 {
1203         int resp_size;
1204         register struct usal_cmd        *scmd = usalp->scmd;
1205
1206         switch (sq_format) {
1207           case GET_POSITIONDATA:
1208             resp_size = 16;
1209             track = 0;
1210           break;
1211           case GET_CATALOGNUMBER:
1212             resp_size = 24;
1213             track = 0;
1214           break;
1215           case GET_TRACK_ISRC:
1216             resp_size = 24;
1217           break;
1218           default:
1219                 fprintf(stderr, "ReadSubQSCSI: unknown format %d\n", sq_format);
1220                 return NULL;
1221         }
1222
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;
1230                                                 /* use LBA */
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);
1236
1237         if (usalp->verbose) fprintf(stderr, "\nRead Subchannel...");
1238
1239         usalp->cmdname = "Read Subchannel";
1240
1241   if (usal_cmd(usalp) < 0) {
1242     /* in case of error do a fallback for dumb firmwares */
1243     return ReadSubQFallback(usalp, sq_format, track);
1244   }
1245
1246         if (sq_format == GET_POSITIONDATA)
1247                 SubQbuffer->control_adr = (SubQbuffer->control_adr << 4) | (SubQbuffer->control_adr >> 4);
1248   return SubQbuffer;
1249 }
1250
1251 static subq_chnl sc;
1252
1253 static subq_chnl* fill_subchannel(unsigned char bufferwithQ[]);
1254 static subq_chnl* fill_subchannel(unsigned char bufferwithQ[])
1255 {
1256         sc.subq_length = 0;
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];
1260         return &sc;
1261 }
1262
1263 int 
1264 ReadCddaSubSony(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal)
1265 {
1266         register struct usal_cmd        *scmd = usalp->scmd;
1267
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);
1280
1281         if (usalp->verbose) fprintf(stderr, "\nReadSony12 CDDA + SubChannels...");
1282
1283         usalp->cmdname = "Read12SubChannelsSony";
1284
1285         if (usal_cmd(usalp)) return -1;
1286
1287         /* has all or something been read? */
1288         return usal_getresid(usalp) != 0;
1289 }
1290
1291 int ReadCddaSub96Sony(SCSI *usalp, UINT4 *p, unsigned lSector, 
1292                                                          unsigned SectorBurstVal);
1293
1294 int ReadCddaSub96Sony(SCSI *usalp, UINT4 *p, unsigned lSector, 
1295                       unsigned SectorBurstVal)
1296 {
1297         register struct usal_cmd        *scmd = usalp->scmd;
1298
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);
1311
1312         if (usalp->verbose) fprintf(stderr, "\nReadSony12 CDDA + 96 byte SubChannels...");
1313
1314         usalp->cmdname = "Read12SubChannelsSony";
1315
1316         if (usal_cmd(usalp)) return -1;
1317
1318         /* has all or something been read? */
1319         return usal_getresid(usalp) != 0;
1320 }
1321
1322 subq_chnl *ReadSubChannelsSony(SCSI *usalp, unsigned lSector)
1323 {
1324         /*int retval = ReadCddaSub96Sony(usalp, (UINT4 *)bufferTOC, lSector, 1);*/
1325         int retval = ReadCddaSubSony(usalp, (UINT4 *)bufferTOC, lSector, 1);
1326         if (retval != 0) return NULL;
1327
1328         return fill_subchannel(bufferTOC);
1329 }
1330
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)
1334 {
1335         register struct usal_cmd        *scmd;
1336         scmd = usalp->scmd;
1337
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 */
1351
1352         if (usalp->verbose) fprintf(stderr, "\nReadMMC12 CDDA + SUB...");
1353
1354         usalp->cmdname = "ReadCD Sub MMC 12";
1355
1356         if (usal_cmd(usalp)) return -1;
1357
1358         /* has all or something been read? */
1359         return usal_getresid(usalp) != 0;
1360 }
1361
1362 static subq_chnl *ReadSubChannelsMMC(SCSI *usalp, unsigned lSector);
1363 static subq_chnl *ReadSubChannelsMMC(SCSI *usalp, unsigned lSector)
1364 {
1365         int retval = ReadCddaSubMMC12(usalp, (UINT4 *)bufferTOC, lSector, 1);
1366         if (retval != 0) return NULL;
1367
1368         return fill_subchannel(bufferTOC);
1369 }
1370
1371 subq_chnl *ReadSubChannelsFallbackMMC(SCSI *usalp, unsigned lSector)
1372 {
1373         static int ReadSubSony_unknown = 0;
1374         subq_chnl *retval = NULL;
1375
1376         usalp->silent++;
1377         if (ReadSubSony_unknown 
1378             || ((retval = ReadSubChannelsSony(usalp, lSector)) == NULL)) {
1379                 /* if the command is not available, use the regular
1380                  * MMC ReadCd 
1381                  */
1382                 if (retval == NULL && usal_sense_key(usalp) == 0x05) {
1383                         ReadSubSony_unknown = 1;
1384                 }
1385                 usalp->silent--;
1386                 return ReadSubChannelsMMC(usalp, lSector);
1387         }
1388         usalp->silent--;
1389         return retval;
1390 }
1391
1392 subq_chnl *ReadStandardSub(usalp, lSector)
1393         SCSI *usalp;
1394         unsigned lSector;
1395 {
1396         if (0 == ReadStandardLowlevel (usalp, (UINT4 *)bufferTOC, lSector, 1, CD_FRAMESIZE_RAW + 16 )) {
1397                 return NULL;
1398         }
1399 #if     0
1400 fprintf(stderr, "Subchannel Sec %x: %02x %02x %02x %02x\n"
1401         ,lSector
1402         ,bufferTOC[CD_FRAMESIZE_RAW + 0]
1403         ,bufferTOC[CD_FRAMESIZE_RAW + 1]
1404         ,bufferTOC[CD_FRAMESIZE_RAW + 2]
1405         ,bufferTOC[CD_FRAMESIZE_RAW + 3]
1406         );
1407 #endif
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]);
1412         return &sc;
1413 }
1414 /********* non standardized speed selects ***********************/
1415
1416 void SpeedSelectSCSIToshiba(SCSI *usalp, unsigned speed)
1417 {
1418   static unsigned char mode [4 + 3];
1419   unsigned char *page = mode + 4;
1420   int retval;
1421
1422   fillbytes((caddr_t)mode, sizeof(mode), '\0');
1423   /* the first 4 mode bytes are zero. */
1424   page[0] = 0x20;
1425   page[1] = 1;
1426   page[2] = speed;   /* 0 for single speed, 1 for double speed (3401) */
1427
1428   if (usalp->verbose) fprintf(stderr, "\nspeed select Toshiba...");
1429
1430   usalp->silent++;
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");
1434   usalp->silent--;
1435 }
1436
1437 void SpeedSelectSCSINEC(SCSI *usalp, unsigned speed)
1438 {
1439   static unsigned char mode [4 + 8];
1440   unsigned char *page = mode + 4;
1441   int retval;
1442         register struct usal_cmd        *scmd = usalp->scmd;
1443
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;
1450
1451         fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1452   scmd->addr = (caddr_t)mode;
1453   scmd->size = 12;
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);
1461
1462   if (usalp->verbose) fprintf(stderr, "\nspeed select NEC...");
1463   /* do the scsi cmd */
1464
1465         usalp->cmdname = "speed select NEC";
1466
1467   if ((retval = usal_cmd(usalp)) < 0)
1468         fprintf(stderr ,"speed select NEC failed\n");
1469 }
1470
1471 void SpeedSelectSCSIPhilipsCDD2600(SCSI *usalp, unsigned speed)
1472 {
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;
1477   int retval;
1478
1479   fillbytes((caddr_t)mode, sizeof(mode), '\0');
1480   /* the first 4 mode bytes are zero. */
1481   page[0] = 0x23;
1482   page[1] = 6;
1483   page[2] = page [4] = speed;
1484   page[3] = 1;
1485
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");
1490 }
1491
1492 void SpeedSelectSCSISony(SCSI *usalp, unsigned speed)
1493 {
1494   static unsigned char mode [4 + 4];
1495   unsigned char *page = mode + 4;
1496   int retval;
1497
1498   fillbytes((caddr_t)mode, sizeof(mode), '\0');
1499   /* the first 4 mode bytes are zero. */
1500   page[0] = 0x31;
1501   page[1] = 2;
1502   page[2] = speed;
1503
1504   if (usalp->verbose) fprintf(stderr, "\nspeed select Sony...");
1505   /* do the scsi cmd */
1506   usalp->silent++;
1507   if ((retval = mode_select(usalp, mode, 8, 0, usalp->inq->data_format >= 2)) < 0)
1508         fprintf (stderr, "speed select Sony failed\n");
1509   usalp->silent--;
1510 }
1511
1512 void SpeedSelectSCSIYamaha (usalp, speed)
1513         SCSI *usalp;
1514         unsigned speed;
1515 {
1516   static unsigned char mode [4 + 4];
1517   unsigned char *page = mode + 4;
1518   int retval;
1519
1520   fillbytes((caddr_t)mode, sizeof(mode), '\0');
1521   /* the first 4 mode bytes are zero. */
1522   page[0] = 0x31;
1523   page[1] = 2;
1524   page[2] = speed;
1525
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");
1530 }
1531
1532 void SpeedSelectSCSIMMC(SCSI *usalp, unsigned speed)
1533 {
1534   int spd;
1535         register struct usal_cmd        *scmd = usalp->scmd;
1536
1537    if (speed == 0 || speed == 0xFFFF) {
1538       spd = 0xFFFF;
1539    } else {
1540       spd = (1764 * speed) / 10;
1541    }
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);
1550
1551         if (usalp->verbose) fprintf(stderr, "\nspeed select MMC...");
1552
1553         usalp->cmdname = "set cd speed";
1554
1555         usalp->silent++;
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 */
1561                 } else {
1562                         usal_printerr(usalp);
1563                         fprintf (stderr, "speed select MMC failed\n");
1564                 }
1565         }
1566         usalp->silent--;
1567 }
1568
1569 /* request vendor brand and model */
1570 unsigned char *Inquiry(SCSI *usalp)
1571 {
1572   static unsigned char *Inqbuffer = NULL;
1573         register struct usal_cmd        *scmd = usalp->scmd;
1574
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__);
1579         return NULL;
1580     }
1581   }
1582
1583   fillbytes(Inqbuffer, 36, '\0');
1584         fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1585   scmd->addr = (caddr_t)Inqbuffer;
1586   scmd->size = 36;
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;
1593         
1594         usalp->cmdname = "inquiry";
1595
1596   if (usal_cmd(usalp) < 0)
1597      return (NULL);
1598
1599   /* define structure with inquiry data */
1600   memcpy(usalp->inq, Inqbuffer, sizeof(*usalp->inq)); 
1601
1602   if (usalp->verbose)
1603      usal_prbytes("Inquiry Data   :", (Uchar *)Inqbuffer, 22 - scmd->resid);
1604
1605   return (Inqbuffer);
1606 }
1607
1608 #define SC_CLASS_EXTENDED_SENSE 0x07
1609 #define TESTUNITREADY_CMD 0
1610 #define TESTUNITREADY_CMDLEN 6
1611
1612 #define ADD_SENSECODE 12
1613 #define ADD_SC_QUALIFIER 13
1614 #define NO_MEDIA_SC 0x3a
1615 #define NO_MEDIA_SCQ 0x00
1616
1617 int TestForMedium(SCSI *usalp)
1618 {
1619         register struct usal_cmd        *scmd = usalp->scmd;
1620
1621   if (interface != GENERIC_SCSI) {
1622     return 1;
1623   }
1624
1625   /* request READY status */
1626         fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1627   scmd->addr = (caddr_t)0;
1628   scmd->size = 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);
1634         
1635   if (usalp->verbose) fprintf(stderr, "\ntest unit ready...");
1636   usalp->silent++;
1637
1638         usalp->cmdname = "test unit ready";
1639
1640   if (usal_cmd(usalp) >= 0) {
1641     usalp->silent--;
1642     return 1;
1643   }
1644   usalp->silent--;
1645
1646   if (scmd->sense.code >= SC_CLASS_EXTENDED_SENSE) {
1647     return 
1648       scmd->u_sense.cmd_sense[ADD_SENSECODE] != NO_MEDIA_SC ||
1649       scmd->u_sense.cmd_sense[ADD_SC_QUALIFIER] != NO_MEDIA_SCQ;
1650   } else {
1651     /* analyse status. */
1652     /* 'check condition' is interpreted as not ready. */
1653     return (scmd->u_scb.cmd_scb[0] & 0x1e) != 0x02;
1654   }
1655 }
1656
1657 int StopPlaySCSI(SCSI *usalp)
1658 {
1659         register struct usal_cmd        *scmd = usalp->scmd;
1660
1661         fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1662   scmd->addr = NULL;
1663   scmd->size = 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);
1669
1670   if (usalp->verbose) fprintf(stderr, "\nstop audio play");
1671   /* do the scsi cmd */
1672
1673         usalp->cmdname = "stop audio play";
1674
1675   return usal_cmd(usalp) >= 0 ? 0 : -1;
1676 }
1677
1678 int Play_atSCSI(SCSI *usalp, unsigned int from_sector, unsigned int sectors)
1679 {
1680         register struct usal_cmd        *scmd = usalp->scmd;
1681
1682         fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
1683   scmd->addr = NULL;
1684   scmd->size = 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;
1696
1697   if (usalp->verbose) fprintf(stderr, "\nplay sectors...");
1698   /* do the scsi cmd */
1699
1700         usalp->cmdname = "play sectors";
1701
1702   return usal_cmd(usalp) >= 0 ? 0 : -1;
1703 }
1704
1705 static caddr_t scsibuffer;      /* page aligned scsi transfer buffer */
1706
1707 void init_scsibuf(SCSI *scsp, unsigned amt);
1708
1709 void init_scsibuf(SCSI *usalp, unsigned amt)
1710 {
1711         if (scsibuffer != NULL) {
1712                 fprintf(stderr, "the SCSI transfer buffer has already been allocated!\n");
1713                 exit(SETUPSCSI_ERROR);
1714         }
1715         scsibuffer = usal_getbuf(usalp, amt);
1716         if (scsibuffer == NULL) {
1717                 fprintf(stderr, "could not get SCSI transfer buffer!\n");
1718                 exit(SETUPSCSI_ERROR);
1719         }
1720 }