GenericMMC.cc
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:42k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /*  cdrdao - write audio CD-Rs in disc-at-once mode
  2.  *
  3.  *  Copyright (C) 1998, 1999  Andreas Mueller <mueller@daneb.ping.de>
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19. /*
  20.  * $Log: GenericMMC.cc,v $
  21.  * Revision 1.12  1999/04/05 18:47:40  mueller
  22.  * Added driver options.
  23.  * Added option to read Q sub-channel data instead raw PW sub-channel data
  24.  * for 'read-toc'.
  25.  *
  26.  * Revision 1.11  1999/03/27 20:51:26  mueller
  27.  * Added data track support.
  28.  *
  29.  * Revision 1.10  1998/10/25 14:38:28  mueller
  30.  * Fixed comment.
  31.  *
  32.  * Revision 1.9  1998/10/24 14:48:55  mueller
  33.  * Added retrieval of next writable address. The Panasonic CW-7502 needs it.
  34.  *
  35.  * Revision 1.8  1998/10/03 15:08:44  mueller
  36.  * Moved 'writeZeros()' to base class 'CdrDriver'.
  37.  * Takes 'writeData()' from base class now.
  38.  *
  39.  * Revision 1.7  1998/09/27 19:18:48  mueller
  40.  * Added retrieval of control nibbles for track with 'analyzeTrack()'.
  41.  * Added multi session mode.
  42.  *
  43.  * Revision 1.6  1998/09/22 19:15:13  mueller
  44.  * Removed memory allocations during write process.
  45.  *
  46.  * Revision 1.5  1998/09/08 11:54:22  mueller
  47.  * Extended disk info structure because CDD2000 does not support the
  48.  * 'READ DISK INFO' command.
  49.  *
  50.  * Revision 1.4  1998/09/07 15:20:20  mueller
  51.  * Reorganized read-toc related code.
  52.  *
  53.  * Revision 1.3  1998/09/06 13:34:22  mueller
  54.  * Use 'message()' for printing messages.
  55.  *
  56.  * Revision 1.2  1998/08/30 19:17:56  mueller
  57.  * Fixed cue sheet generation and first writable address after testing
  58.  * with a Yamaha CDR400t.
  59.  *
  60.  * Revision 1.1  1998/08/15 20:44:58  mueller
  61.  * Initial revision
  62.  *
  63.  */
  64. static char rcsid[] = "$Id: GenericMMC.cc,v 1.12 1999/04/05 18:47:40 mueller Exp mueller $";
  65. #include <config.h>
  66. #include <string.h>
  67. #include <assert.h>
  68. #include "GenericMMC.h"
  69. #include "port.h"
  70. #include "Toc.h"
  71. #include "util.h"
  72. #include "PQSubChannel16.h"
  73. #include "PWSubChannel96.h"
  74. #include "CdTextEncoder.h"
  75. GenericMMC::GenericMMC(ScsiIf *scsiIf, unsigned long options)
  76.   : CdrDriver(scsiIf, options)
  77. {
  78.   int i;
  79.   driverName_ = "Generic SCSI-3/MMC - Version 1.0 (data)";
  80.   
  81.   speed_ = 0;
  82.   simulate_ = 1;
  83.   encodingMode_ = 1;
  84.   scsiTimeout_ = 0;
  85.   
  86.   cdTextEncoder_ = NULL;
  87.   memset(&diskInfo_, 0, sizeof(DiskInfo));
  88.   for (i = 0; i < maxScannedSubChannels_; i++) {
  89.     if (options_ & OPT_MMC_USE_PQ) 
  90.       scannedSubChannels_[i] = new PQSubChannel16;
  91.     else
  92.       scannedSubChannels_[i] = new PWSubChannel96;
  93.   }
  94.   // MMC drives usually return little endian samples
  95.   audioDataByteOrder_ = 0;
  96. }
  97. GenericMMC::~GenericMMC()
  98. {
  99.   int i;
  100.   for (i = 0; i < maxScannedSubChannels_; i++) {
  101.     delete scannedSubChannels_[i];
  102.     scannedSubChannels_[i] = NULL;
  103.   }
  104.   delete cdTextEncoder_;
  105.   cdTextEncoder_ = NULL;
  106. }
  107. // static constructor
  108. CdrDriver *GenericMMC::instance(ScsiIf *scsiIf, unsigned long options)
  109. {
  110.   return new GenericMMC(scsiIf, options);
  111. }
  112. int GenericMMC::checkToc(const Toc *toc)
  113. {
  114.   int err = CdrDriver::checkToc(toc);
  115.   int e;
  116.   if (options_ & OPT_MMC_CD_TEXT) {
  117.     if ((e = toc->checkCdTextData()) > err)
  118.       err = e;
  119.   }
  120.   return err;
  121. }
  122. // sets speed
  123. // return: 0: OK
  124. //         1: illegal speed
  125. int GenericMMC::speed(int s)
  126. {
  127.   speed_ = s;
  128.   if (selectSpeed(0) != 0)
  129.     return 1;
  130.   
  131.   return 0;
  132. }
  133. int GenericMMC::speed()
  134. {
  135.   DriveInfo di;
  136.   if (driveInfo(&di, 1) != 0) {
  137.     return 0;
  138.   }
  139.   return speed2Mult(di.currentWriteSpeed);
  140. }
  141. // loads ('unload' == 0) or ejects ('unload' == 1) tray
  142. // return: 0: OK
  143. //         1: scsi command failed
  144. int GenericMMC::loadUnload(int unload) const
  145. {
  146.   unsigned char cmd[6];
  147.   memset(cmd, 0, 6);
  148.   cmd[0] = 0x1b; // START/STOP UNIT
  149.   if (unload) {
  150.     cmd[4] = 0x02; // LoUnlo=1, Start=0
  151.   }
  152.   else {
  153.     cmd[4] = 0x03; // LoUnlo=1, Start=1
  154.   }
  155.   
  156.   if (sendCmd(cmd, 6, NULL, 0, NULL, 0) != 0) {
  157.     message(-2, "Cannot load/unload medium.");
  158.     return 1;
  159.   }
  160.   return 0;
  161. }
  162. // Performs complete blanking of a CD-RW.
  163. // return: 0: OK
  164. //         1: scsi command failed
  165. int GenericMMC::blankDisk()
  166. {
  167.   unsigned char cmd[12];
  168.   memset(cmd, 0, 12);
  169.   cmd[0] = 0xa1; // BLANK
  170.   cmd[1] = 1 << 4; // erase complete disk, immediate return
  171.   if (sendCmd(cmd, 12, NULL, 0, NULL, 0, 1) != 0) {
  172.     message(-2, "Cannot erase CD-RW.");
  173.     return 1;
  174.   }
  175.   return 0;
  176. }
  177. // sets read/write speed and simulation mode
  178. // return: 0: OK
  179. //         1: scsi command failed
  180. int GenericMMC::selectSpeed(int readSpeed)
  181. {
  182.   unsigned char cmd[12];
  183.   int spd;
  184.   memset(cmd, 0, 12);
  185.   cmd[0] = 0xbb; // SET CD SPEED
  186.   // select maximum read speed
  187.   if (readSpeed == 0) {
  188.     cmd[2] = 0xff;
  189.     cmd[3] = 0xff;
  190.   }
  191.   else {
  192.     spd = mult2Speed(readSpeed);
  193.     cmd[2] = spd >> 8;
  194.     cmd[3] = spd;
  195.   }
  196.   // select maximum write speed
  197.   if (speed_ == 0) {
  198.     cmd[4] = 0xff;
  199.     cmd[5] = 0xff;
  200.   }
  201.   else {
  202.     spd = mult2Speed(speed_);
  203.     cmd[4] = spd >> 8;
  204.     cmd[5] = spd;
  205.   }
  206.   if (sendCmd(cmd, 12, NULL, 0, NULL, 0) != 0) {
  207.     message(-2, "Cannot set cd speed.");
  208.     return 1;
  209.   }
  210.   return 0;
  211. }
  212. // Determins start and length of lead-in and length of lead-out.
  213. // return: 0: OK
  214. //         1: SCSI command failed
  215. int GenericMMC::getSessionInfo()
  216. {
  217.   unsigned char cmd[10];
  218.   unsigned long dataLen = 34;
  219.   unsigned char data[34];
  220.   memset(cmd, 0, 10);
  221.   memset(data, 0, dataLen);
  222.   cmd[0] = 0x51; // READ DISK INFORMATION
  223.   cmd[7] = dataLen >> 8;
  224.   cmd[8] = dataLen;
  225.   if (sendCmd(cmd, 10, NULL, 0, data, dataLen) != 0) {
  226.     message(-2, "Cannot retrieve disk information.");
  227.     return 1;
  228.   }
  229.   leadInStart_ = Msf(data[17], data[18], data[19]);
  230.   if (leadInStart_.lba() >= Msf(80, 0, 0).lba()) {
  231.     leadInLen_ = 450000 - leadInStart_.lba();
  232.     leadOutLen_ = Msf(1, 30, 0).lba(); // 90 seconds lead-out
  233.   }
  234.   else {
  235.     leadInLen_ = Msf(1, 0, 0).lba();
  236.     leadOutLen_ = Msf(0, 30, 0).lba();
  237.   }
  238.   message(3, "Lead-in start: %s length: %ld", leadInStart_.str(),
  239.   leadInLen_);
  240.   message(3, "Lead-out length: %ld", leadOutLen_);
  241.   return 0;
  242. }
  243. int GenericMMC::readBufferCapacity(long *capacity)
  244. {
  245.   unsigned char cmd[10];
  246.   unsigned char data[12];
  247.   memset(cmd, 0, 10);
  248.   memset(data, 0, 12);
  249.   cmd[0] = 0x5c; // READ BUFFER CAPACITY
  250.   cmd[8] = 12;
  251.   if (sendCmd(cmd, 10, NULL, 0, data, 12) != 0) {
  252.     message(-2, "Read buffer capacity failed.");
  253.     return 1;
  254.   }
  255.   *capacity = (data[8] << 24) | (data[9] << 16) | (data[10] << 8) | data[11];
  256.   return 0;
  257. }
  258. int GenericMMC::performPowerCalibration()
  259. {
  260.   unsigned char cmd[10];
  261.   memset(cmd, 0, 10);
  262.   cmd[0] = 0x54; // SEND OPC INFORMATION
  263.   cmd[1] = 1;
  264.   message(1, "Executing power calibration...");
  265.   if (sendCmd(cmd, 10, NULL, 0, NULL, 0) != 0) {
  266.     message(-2, "Power calibration failed.");
  267.     return 1;
  268.   }
  269.   
  270.   return 0;
  271. }
  272. // Sets write parameters via mode page 0x05.
  273. // return: 0: OK
  274. //         1: scsi command failed
  275. int GenericMMC::setWriteParameters()
  276. {
  277.   unsigned char mp[0x38];
  278.   unsigned char mpHeader[8];
  279.   unsigned char blockDesc[8];
  280.   if (getModePage(5/*write parameters mode page*/, mp, 0x38,
  281.   mpHeader, blockDesc, 1) != 0) {
  282.     message(-2, "Cannot retrieve write parameters mode page.");
  283.     return 1;
  284.   }
  285.   mp[0] &= 0x7f; // clear PS flag
  286.   mp[2] &= 0xe0;
  287.   mp[2] |= 0x02; // write type: Session-at-once
  288.   if (simulate_) {
  289.     mp[2] |= 1 << 4; // test write
  290.   }
  291.   mp[3] &= 0x3f; // Multi-session: No B0 pointer, next session not allowed
  292.   if (multiSession_ != 0)
  293.     mp[3] |= 0x03 << 6; // open next session
  294.   else if (!diskInfo_.empty)
  295.     mp[3] |= 0x01 << 6; // use B0=FF:FF:FF when closing last session of a
  296.                         // multi session CD-R
  297.   message(3, "Multi session mode: %d", mp[3] >> 6);
  298.   mp[4] &= 0xf0; // Data Block Type: raw data, block size: 2352 (I think not
  299.                  // used for session at once writing)
  300.   mp[8] = sessionFormat();
  301.   if (!diskInfo_.empty) {
  302.     // use the toc type of the already recorded sessions
  303.     switch (diskInfo_.diskTocType) {
  304.     case 0x00:
  305.     case 0x10:
  306.     case 0x20:
  307.       mp[8] = diskInfo_.diskTocType;
  308.       break;
  309.     }
  310.   }
  311.   message(3, "Toc type: 0x%x", mp[8]);
  312.   if (setModePage(mp, mpHeader, NULL, 1) != 0) {
  313.     message(-2, "Cannot set write parameters mode page.");
  314.     return 1;
  315.   }
  316.   return 0;
  317. }
  318. int GenericMMC::getNWA(long *nwa)
  319. {
  320.   unsigned char cmd[10];
  321.   int infoblocklen = 16;
  322.   unsigned char info[16];
  323.   long lba = 0;
  324.   cmd[0] = 0x52; // READ TRACK INFORMATION
  325.   cmd[1] = 0x01; // track instead of lba designation
  326.   cmd[2] = 0x00;
  327.   cmd[3] = 0x00;
  328.   cmd[4] = 0x00;
  329.   cmd[5] = 0xff; // invisible track
  330.   cmd[6] = 0x00; // reserved
  331.   cmd[7] = infoblocklen << 8;
  332.   cmd[8] = infoblocklen; // alloc length
  333.   cmd[9] = 0x00; // Control Byte
  334.   if (sendCmd(cmd, 10, NULL, 0, info, infoblocklen) != 0) {
  335.     message(-2, "Cannot get Track Information Block.");
  336.     return 1;
  337.   }
  338. #if 0
  339.   message(2,"Track Information Block");
  340.   for (int i=0;i<infoblocklen;i++) message(2,"byte %02x : %02x",i,info[i]);
  341. #endif
  342.   if ((info[6] & 0x40) && (info[7] & 0x01) && !(info[6] & 0xb0))
  343.   {
  344.       message(3,"Track is Blank, Next Writable Address is valid");
  345.       lba |= info[12] << 24; // MSB of LBA
  346.       lba |= info[13] << 16;
  347.       lba |= info[14] << 8;
  348.       lba |= info[15];       // LSB of LBA
  349.   }
  350.   message(3, "NWA: %ld", lba);
  351.   if (nwa != NULL) 
  352.     *nwa = lba;
  353.   return 0;
  354. }
  355. // Determines first writable address of data area of current empty session. 
  356. // lba: set to start of data area
  357. // return: 0: OK
  358. //         1: error occured
  359. int GenericMMC::getStartOfSession(long *lba)
  360. {
  361.   unsigned char mp[0x38];
  362.   unsigned char mpHeader[8];
  363.   // first set the writing mode because it influences which address is
  364.   // returned with 'READ TRACK INFORMATION'
  365.   if (getModePage(5/*write parameters mode page*/, mp, 0x38,
  366.   mpHeader, NULL, 0) != 0) {
  367.     return 1;
  368.   }
  369.   mp[0] &= 0x7f; // clear PS flag
  370.   mp[2] &= 0xe0;
  371.   mp[2] |= 0x02; // write type: Session-at-once
  372.   if (setModePage(mp, mpHeader, NULL, 1) != 0) {
  373.     message(-2, "Cannot set write parameters mode page.");
  374.     return 1;
  375.   }
  376.   return getNWA(lba);
  377. }
  378. // Creates cue sheet for current toc.
  379. // cueSheetLen: filled with length of cue sheet in bytes
  380. // return: newly allocated cue sheet buffer or 'NULL' on error
  381. unsigned char *GenericMMC::createCueSheet(long *cueSheetLen)
  382. {
  383.   const Track *t;
  384.   int trackNr;
  385.   Msf start, end, index;
  386.   unsigned char *cueSheet;
  387.   long len = 3; // entries for lead-in, gap, lead-out
  388.   long n; // index into cue sheet
  389.   unsigned char ctl; // control nibbles of cue sheet entry CTL/ADR
  390.   long i;
  391.   unsigned char dataMode;
  392.   int trackOffset = 0;
  393.   long lbaOffset = 0;
  394.   if (!diskInfo_.empty && diskInfo_.append) {
  395.     trackOffset = diskInfo_.lastTrackNr;
  396.     lbaOffset = diskInfo_.thisSessionLba;
  397.   }
  398.   TrackIterator itr(toc_);
  399.   if (itr.first(start, end) == NULL) {
  400.     return NULL;
  401.   }
  402.   if (toc_->catalogValid()) {
  403.     len += 2;
  404.   }
  405.   for (t = itr.first(start, end), trackNr = 1;
  406.        t != NULL; t = itr.next(start, end), trackNr++) {
  407.     len += 1; // entry for track
  408.     if (t->start().lba() != 0 && trackNr > 1) {
  409.       len += 1; // entry for pre-gap
  410.     }
  411.     if (t->type() == TrackData::AUDIO && t->isrcValid()) {
  412.       len += 2; // entries for ISRC code
  413.     }
  414.     len += t->nofIndices(); // entry for each index increment
  415.   }
  416.   cueSheet = new (unsigned char)[len * 8];
  417.   n = 0;
  418.   if (toc_->leadInMode() == TrackData::AUDIO) {
  419.     ctl = 0;
  420.   }
  421.   else {
  422.     ctl = 0x40;
  423.   }
  424.   if (toc_->catalogValid()) {
  425.     // fill catalog number entry
  426.     cueSheet[n*8] = 0x02 | ctl;
  427.     cueSheet[(n+1)*8] = 0x02 | ctl;
  428.     for (i = 1; i <= 13; i++) {
  429.       if (i < 8) {
  430. cueSheet[n*8 + i] = toc_->catalog(i-1) + '0';
  431.       }
  432.       else {
  433. cueSheet[(n+1)*8 + i - 7] = toc_->catalog(i-1) + '0';
  434.       }
  435.     }
  436.     cueSheet[(n+1)*8+7] = 0;
  437.     n += 2;
  438.   }
  439.   // entry for lead-in
  440.   cueSheet[n*8] = 0x01 | ctl; // CTL/ADR
  441.   cueSheet[n*8+1] = 0;    // Track number
  442.   cueSheet[n*8+2] = 0;    // Index
  443.   if (cdTextEncoder_ != NULL) {
  444.     cueSheet[n*8+3] = 0x41; // Data Form: CD-DA with P-W sub-channels,
  445.                             // main channel data generated by device
  446.   }
  447.   else {
  448.     cueSheet[n*8+3] = 0x01; // Data Form: CD-DA, generate data by device
  449.   }
  450.   cueSheet[n*8+4] = 0;    // Serial Copy Management System
  451.   cueSheet[n*8+5] = 0;    // MIN
  452.   cueSheet[n*8+6] = 0;    // SEC
  453.   cueSheet[n*8+7] = 0;    // FRAME
  454.   n++;
  455.   int firstTrack = 1;
  456.   for (t = itr.first(start, end), trackNr = trackOffset + 1;
  457.        t != NULL;
  458.        t = itr.next(start, end), trackNr++) {
  459.     if (encodingMode_ == 0) {
  460.       // just used for some experiments with raw writing
  461.       dataMode = 0;
  462.     }
  463.     else {
  464.       switch (t->type()) {
  465.       case TrackData::AUDIO:
  466. dataMode = 0;
  467. break;
  468.       case TrackData::MODE1:
  469.       case TrackData::MODE1_RAW:
  470. dataMode = 0x10;
  471. break;
  472.       case TrackData::MODE2:
  473. dataMode = 0x30;
  474. break;
  475.       case TrackData::MODE2_RAW: // assume it contains XA sectors
  476.       case TrackData::MODE2_FORM1:
  477.       case TrackData::MODE2_FORM2:
  478.       case TrackData::MODE2_FORM_MIX:
  479. dataMode = 0x20;
  480. break;
  481.       default:
  482. dataMode = 0;
  483. break;
  484.       }
  485.     }
  486.     ctl = 0;
  487.     if (t->copyPermitted()) {
  488.       ctl |= 0x20;
  489.     }
  490.     if (t->type() == TrackData::AUDIO) {
  491.       // audio track
  492.       if (t->preEmphasis()) {
  493. ctl |= 0x10;
  494.       }
  495.       if (t->audioType() == 1) {
  496. ctl |= 0x80;
  497.       }
  498.       if (t->isrcValid()) {
  499. cueSheet[n*8] = ctl | 0x03;
  500. cueSheet[n*8+1] = trackNr;
  501. cueSheet[n*8+2] = t->isrcCountry(0);
  502. cueSheet[n*8+3] = t->isrcCountry(1);
  503. cueSheet[n*8+4] = t->isrcOwner(0);  
  504. cueSheet[n*8+5] = t->isrcOwner(1);   
  505. cueSheet[n*8+6] = t->isrcOwner(2);  
  506. cueSheet[n*8+7] = t->isrcYear(0) + '0';
  507. n++;
  508. cueSheet[n*8] = ctl | 0x03;
  509. cueSheet[n*8+1] = trackNr;
  510. cueSheet[n*8+2] = t->isrcYear(1) + '0';
  511. cueSheet[n*8+3] = t->isrcSerial(0) + '0';
  512. cueSheet[n*8+4] = t->isrcSerial(1) + '0';
  513. cueSheet[n*8+5] = t->isrcSerial(2) + '0';
  514. cueSheet[n*8+6] = t->isrcSerial(3) + '0';
  515. cueSheet[n*8+7] = t->isrcSerial(4) + '0';
  516. n++;
  517.       }
  518.     }
  519.     else {
  520.       // data track
  521.       ctl |= 0x40;
  522.     }
  523.  
  524.     if (firstTrack) {
  525.       Msf sessionStart(lbaOffset);
  526.       // entry for gap before first track
  527.       cueSheet[n*8]   = ctl | 0x01;
  528.       cueSheet[n*8+1] = trackNr;
  529.       cueSheet[n*8+2] = 0;    // Index 0
  530.       cueSheet[n*8+3] = dataMode;    // Data Form
  531.       cueSheet[n*8+4] = 0;    // Serial Copy Management System
  532.       cueSheet[n*8+5] = sessionStart.min();
  533.       cueSheet[n*8+6] = sessionStart.sec();
  534.       cueSheet[n*8+7] = sessionStart.frac();
  535.       n++;
  536.     }
  537.     else if (t->start().lba() != 0) {
  538.       // entry for pre-gap
  539.       Msf pstart(lbaOffset + start.lba() - t->start().lba() + 150);
  540.       cueSheet[n*8]   = ctl | 0x01;
  541.       cueSheet[n*8+1] = trackNr;
  542.       cueSheet[n*8+2] = 0; // Index 0 indicates pre-gap
  543.       cueSheet[n*8+3] = dataMode; // Data Form
  544.       cueSheet[n*8+4] = 0; // no alternate copy bit
  545.       cueSheet[n*8+5] = pstart.min();
  546.       cueSheet[n*8+6] = pstart.sec();
  547.       cueSheet[n*8+7] = pstart.frac();
  548.       n++;
  549.     }
  550.     Msf tstart(lbaOffset + start.lba() + 150);
  551.     
  552.     cueSheet[n*8]   = ctl | 0x01;
  553.     cueSheet[n*8+1] = trackNr;
  554.     cueSheet[n*8+2] = 1; // Index 1
  555.     cueSheet[n*8+3] = dataMode; // Data Form
  556.     cueSheet[n*8+4] = 0; // no alternate copy bit
  557.     cueSheet[n*8+5] = tstart.min();
  558.     cueSheet[n*8+6] = tstart.sec();
  559.     cueSheet[n*8+7] = tstart.frac();
  560.     n++;
  561.     for (i = 0; i < t->nofIndices(); i++) {
  562.       index = tstart + t->getIndex(i);
  563.       cueSheet[n*8]   = ctl | 0x01;
  564.       cueSheet[n*8+1] = trackNr;
  565.       cueSheet[n*8+2] = i+2; // Index
  566.       cueSheet[n*8+3] = dataMode; // Data Form
  567.       cueSheet[n*8+4] = 0; // no alternate copy bit
  568.       cueSheet[n*8+5] = index.min();
  569.       cueSheet[n*8+6] = index.sec();
  570.       cueSheet[n*8+7] = index.frac();
  571.       n++;
  572.     }
  573.     firstTrack = 0;
  574.   }
  575.   assert(n == len - 1);
  576.   // entry for lead out
  577.   Msf lostart(lbaOffset + toc_->length().lba() + 150);
  578.   ctl = toc_->leadOutMode() == TrackData::AUDIO ? 0 : 0x40;
  579.     
  580.   cueSheet[n*8]   = ctl | 0x01;
  581.   cueSheet[n*8+1] = 0xaa;
  582.   cueSheet[n*8+2] = 1; // Index 1
  583.   cueSheet[n*8+3] = 0x01; // CD-DA data, data generated by device
  584.   cueSheet[n*8+4] = 0; // no alternate copy bit
  585.   cueSheet[n*8+5] = lostart.min();
  586.   cueSheet[n*8+6] = lostart.sec();
  587.   cueSheet[n*8+7] = lostart.frac();
  588.   message(2, "nCue Sheet:");
  589.   message(2, "CTL/  TNO  INDEX  DATA  SCMS  MIN  SEC  FRAME");
  590.   message(2, "ADR               FORM");
  591.   for (n = 0; n < len; n++) {
  592.     message(2, "%02x    %02x    %02x     %02x    %02x   %02d   %02d   %02d",
  593.    cueSheet[n*8],
  594.    cueSheet[n*8+1], cueSheet[n*8+2], cueSheet[n*8+3], cueSheet[n*8+4],
  595.    cueSheet[n*8+5], cueSheet[n*8+6], cueSheet[n*8+7]);
  596.   }
  597.   *cueSheetLen = len * 8;
  598.   return cueSheet;
  599. }
  600. int GenericMMC::sendCueSheet()
  601. {
  602.   unsigned char cmd[10];
  603.   long cueSheetLen;
  604.   unsigned char *cueSheet = createCueSheet(&cueSheetLen);
  605.   if (cueSheet == NULL) {
  606.     return 1;
  607.   }
  608.   memset(cmd, 0, 10);
  609.   cmd[0] = 0x5d; // SEND CUE SHEET
  610.   cmd[6] = cueSheetLen >> 16;
  611.   cmd[7] = cueSheetLen >> 8;
  612.   cmd[8] = cueSheetLen;
  613.   if (sendCmd(cmd, 10, cueSheet, cueSheetLen, NULL, 0) != 0) {
  614.     message(-2, "Cannot send cue sheet.");
  615.     delete[] cueSheet;
  616.     return 1;
  617.   }
  618.   delete[] cueSheet;
  619.   return 0;
  620. }
  621. int GenericMMC::initDao(const Toc *toc)
  622. {
  623.   long n;
  624.   blockLength_ = AUDIO_BLOCK_LEN;
  625.   blocksPerWrite_ = scsiIf_->maxDataLen() / blockLength_;
  626.   assert(blocksPerWrite_ > 0);
  627.   toc_ = toc;
  628.   if (options_ & OPT_MMC_CD_TEXT) {
  629.     delete cdTextEncoder_;
  630.     cdTextEncoder_ = new CdTextEncoder(toc_);
  631.     if (cdTextEncoder_->encode() != 0) {
  632.       message(-2, "CD-TEXT encoding failed.");
  633.       return 1;
  634.     }
  635.     if (cdTextEncoder_->getSubChannels(&n) == NULL || n == 0) {
  636.       delete cdTextEncoder_;
  637.       cdTextEncoder_ = NULL;
  638.     }
  639.     
  640.     //return 1;
  641.   }
  642.   diskInfo();
  643.   if (!diskInfo_.valid.empty || !diskInfo_.valid.append) {
  644.     message(-2, "Cannot determine status of inserted medium.");
  645.     return 1;
  646.   }
  647.   if (!diskInfo_.append) {
  648.     message(-2, "Inserted medium is not appendable.");
  649.     return 1;
  650.   }
  651.   if (selectSpeed(0) != 0 ||
  652.       getSessionInfo() != 0) {
  653.     return 1;
  654.   }
  655.   // allocate buffer for writing zeros
  656.   n = blocksPerWrite_ * blockLength_;
  657.   delete[] zeroBuffer_;
  658.   zeroBuffer_ = new char[n];
  659.   memset(zeroBuffer_, 0, n);
  660.   return 0;
  661. }
  662. int GenericMMC::startDao()
  663. {
  664.   scsiTimeout_ = scsiIf_->timeout(3 * 60);
  665.   if (setWriteParameters() != 0)
  666.     return 1;
  667.   performPowerCalibration();
  668.   // It does not hurt if the following command fails.
  669.   // The Panasonic CW-7502 needs it, unfortunately it returns the wrong
  670.   // data so we ignore the returned data and start writing always with
  671.   // LBA -150.
  672.   getNWA(NULL);
  673.   if (sendCueSheet() != 0)
  674.     return 1;
  675.   //message(1, "Writing lead-in and gap...");
  676.   if (writeCdTextLeadIn() != 0) {
  677.     return 1;
  678.   }
  679.   long lba = diskInfo_.thisSessionLba - 150;
  680.   if (writeZeros(toc_->leadInMode(), lba, lba + 150, 150) != 0) {
  681.     return 1;
  682.   }
  683.   
  684.   return 0;
  685. }
  686. int GenericMMC::finishDao()
  687. {
  688.   int ret;
  689.   //message(1, "Writing lead-out...");
  690.   while ((ret = testUnitReady(0)) == 2)
  691.     mSleep(2000);
  692.   if (ret != 0)
  693.     message(-1, "TEST UNIT READY failed after recording.");
  694.   
  695.   message(1, "Flushing cache...");
  696.   
  697.   if (flushCache() != 0) {
  698.     return 1;
  699.   }
  700.   scsiIf_->timeout(scsiTimeout_);
  701.   delete cdTextEncoder_;
  702.   cdTextEncoder_ = NULL;
  703.   delete[] zeroBuffer_, zeroBuffer_ = NULL;
  704.   return 0;
  705. }
  706. void GenericMMC::abortDao()
  707. {
  708.   flushCache();
  709.   delete cdTextEncoder_;
  710.   cdTextEncoder_ = NULL;
  711. }
  712. // Writes data to target, the block length depends on the actual writing
  713. // 'mode'. 'len' is number of blocks to write.
  714. // 'lba' specifies the next logical block address for writing and is updated
  715. // by this function.
  716. // return: 0: OK
  717. //         1: scsi command failed
  718. int GenericMMC::writeData(TrackData::Mode mode, long &lba, const char *buf,
  719.   long len)
  720. {
  721.   assert(blocksPerWrite_ > 0);
  722.   int writeLen = 0;
  723.   unsigned char cmd[10];
  724.   long blockLength = blockSize(mode);
  725.   int retry;
  726.   int ret;
  727. #if 0
  728.   long bufferCapacity;
  729.   int waitForBuffer;
  730.   int speedFrac;
  731.   if (speed_ > 0)
  732.     speedFrac = 75 * speed_;
  733.   else
  734.     speedFrac = 75 * 10; // adjust this value when the first >10x burner is out
  735. #endif
  736. #if 0
  737.   long sum, i;
  738.   sum = 0;
  739.   for (i = 0; i < len * blockLength; i++) {
  740.     sum += buf[i];
  741.   }
  742.   message(0, "W: %ld: %ld, %ld, %ld", lba, blockLength, len, sum);
  743. #endif
  744.   memset(cmd, 0, 10);
  745.   cmd[0] = 0x2a; // WRITE1
  746.   
  747.   while (len > 0) {
  748.     writeLen = (len > blocksPerWrite_ ? blocksPerWrite_ : len);
  749.     cmd[2] = lba >> 24;
  750.     cmd[3] = lba >> 16;
  751.     cmd[4] = lba >> 8;
  752.     cmd[5] = lba;
  753.     cmd[7] = writeLen >> 8;
  754.     cmd[8] = writeLen & 0xff;
  755. #if 0
  756.     do {
  757.       waitForBuffer = 0;
  758.       if (readBufferCapacity(&bufferCapacity) == 0) {
  759. //message(0, "Buffer Capacity: %ld", bufferCapacity);
  760. if (bufferCapacity < writeLen * blockLength) {
  761.   long t = 1000 * writeLen;
  762.   t /= speedFrac;
  763.   if (t <= 0)
  764.     t = 1;
  765.   message(0, "Waiting for %ld msec at lba %ld", t, lba);
  766.   mSleep(t);
  767.   waitForBuffer = 1;
  768. }
  769.       }
  770.     } while (waitForBuffer);
  771. #endif
  772.     do {
  773.       retry = 0;
  774.       ret = sendCmd(cmd, 10, (unsigned char *)buf, writeLen * blockLength,
  775.     NULL, 0, 0);
  776.       if(ret == 2) {
  777.         const unsigned char *sense;
  778.         int senseLen;
  779.         sense = scsiIf_->getSense(senseLen);
  780. // check if drive rejected the command because the internal buffer
  781. // is filled
  782. if(senseLen >= 14 && (sense[2] & 0x0f) == 0x2 && sense[7] >= 6 &&
  783.    sense[12] == 0x4 && sense[13] == 0x8) {
  784.   // Not Ready, long write in progress
  785.   mSleep(40);
  786.           retry = 1;
  787.         }
  788. else {
  789.   scsiIf_->printError();
  790. }
  791.       }
  792.     } while (retry);
  793.     if (ret != 0) {
  794.       message(-2, "Write data failed.");
  795.       return 1;
  796.     }
  797.     buf += writeLen * blockLength;
  798.     lba += writeLen;
  799.     len -= writeLen;
  800.   }
  801.       
  802.   return 0;
  803. }
  804. int GenericMMC::writeCdTextLeadIn()
  805. {
  806.   unsigned char cmd[10];
  807.   const PWSubChannel96 **cdTextSubChannels;
  808.   long cdTextSubChannelCount;
  809.   long channelsPerCmd = scsiIf_->maxDataLen() / 96;
  810.   long scp = 0;
  811.   long lba = -150 - leadInLen_;
  812.   long len = leadInLen_;
  813.   long n;
  814.   long i;
  815.   unsigned char *p;
  816.   if (cdTextEncoder_ == NULL)
  817.     return 0;
  818.   cdTextSubChannels = cdTextEncoder_->getSubChannels(&cdTextSubChannelCount);
  819.   assert(channelsPerCmd > 0);
  820.   assert(cdTextSubChannels != NULL);
  821.   assert(cdTextSubChannelCount > 0);
  822.   message(1, "Writing CD-TEXT lead-in...");
  823.   message(2, "Start LBA: %ld, length: %ld", lba, len);
  824.   memset(cmd, 0, 10);
  825.   cmd[0] = 0x2a; // WRITE1
  826.   while (len > 0) {
  827.     n = (len > channelsPerCmd) ? channelsPerCmd : len;
  828.     cmd[2] = lba >> 24;
  829.     cmd[3] = lba >> 16;
  830.     cmd[4] = lba >> 8;
  831.     cmd[5] = lba;
  832.     cmd[7] = n >> 8;
  833.     cmd[8] = n;
  834.     p = transferBuffer_;
  835.     
  836.     for (i = 0; i < n; i++) {
  837.       memcpy(p, cdTextSubChannels[scp]->data(), 96);
  838.       p += 96;
  839.       scp++;
  840.       if (scp >= cdTextSubChannelCount)
  841. scp = 0;
  842.     }
  843.     message(4, "Writing %ld CD-TEXT sub-channels at LBA %ld.", n, lba);
  844.     if (sendCmd(cmd, 10, transferBuffer_, n * 96, NULL, 0) != 0) {
  845.       message(-2, "Writing of CD-TEXT data failed.");
  846.       return 1;
  847.     }
  848.     len -= n;
  849.     lba += n;
  850.   }
  851.     
  852.   return 0;
  853. }
  854. DiskInfo *GenericMMC::diskInfo()
  855. {
  856.   unsigned char cmd[10];
  857.   unsigned long dataLen = 34;
  858.   unsigned char data[34];
  859.   char spd;
  860.   memset(&diskInfo_, 0, sizeof(DiskInfo));
  861.   // perform READ DISK INFORMATION
  862.   memset(cmd, 0, 10);
  863.   memset(data, 0, dataLen);
  864.   cmd[0] = 0x51; // READ DISK INFORMATION
  865.   cmd[7] = dataLen >> 8;
  866.   cmd[8] = dataLen;
  867.   if (sendCmd(cmd, 10, NULL, 0, data, dataLen, 0) == 0) {
  868.     diskInfo_.cdrw = (data[2] & 0x10) ? 1 : 0;
  869.     diskInfo_.valid.cdrw = 1;
  870.     switch (data[2] & 0x03) {
  871.     case 0:
  872.       // disc is empty
  873.       diskInfo_.empty = 1;
  874.       diskInfo_.append = 1;
  875.       diskInfo_.manufacturerId = Msf(data[17], data[18], data[19]);
  876.       diskInfo_.valid.manufacturerId = 1;
  877.       break;
  878.     case 1:
  879.       // disc is not empty but appendable
  880.       diskInfo_.sessionCnt = data[4];
  881.       diskInfo_.lastTrackNr = data[6];
  882.       diskInfo_.diskTocType = data[8];
  883.       switch ((data[2] >> 2) & 0x03) {
  884.       case 0:
  885. // last session is empty
  886. diskInfo_.append = 1;
  887. // don't count the empty session and invisible track
  888. diskInfo_.sessionCnt -= 1;
  889. diskInfo_.lastTrackNr -= 1;
  890. if (getStartOfSession(&(diskInfo_.thisSessionLba)) == 0) {
  891.   // reserve space for pre-gap after lead-in
  892.   diskInfo_.thisSessionLba += 150;
  893. }
  894. else {
  895.   // try to guess start of data area from start of lead-in
  896.   // reserve space for 4500 lead-in and 150 pre-gap sectors
  897.   diskInfo_.thisSessionLba = Msf(data[17], data[18],
  898.  data[19]).lba() - 150 + 4650;
  899. }
  900. break;
  901.       case 1:
  902. // last session is incomplete (not fixated)
  903. // we cannot append in DAO mode, just update the statistic data
  904. diskInfo_.diskTocType = data[8];
  905. // don't count the invisible track
  906. diskInfo_.lastTrackNr -= 1;
  907. break;
  908.       }
  909.       break;
  910.     case 2:
  911.       // disk is complete
  912.       diskInfo_.sessionCnt = data[4];
  913.       diskInfo_.lastTrackNr = data[6];
  914.       diskInfo_.diskTocType = data[8];
  915.       break;
  916.     }
  917.     diskInfo_.valid.empty = 1;
  918.     diskInfo_.valid.append = 1;
  919.     if (data[21] != 0xff || data[22] != 0xff || data[23] != 0xff) {
  920.       diskInfo_.valid.capacity = 1;
  921.       diskInfo_.capacity = Msf(data[21], data[22], data[23]).lba() - 150;
  922.     }
  923.   }
  924.   // perform READ TOC to get session info
  925.   memset(cmd, 0, 10);
  926.   dataLen = 12;
  927.   memset(data, 0, dataLen);
  928.   cmd[0] = 0x43; // READ TOC
  929.   cmd[2] = 1; // get session info
  930.   cmd[8] = dataLen; // allocation length
  931.   if (sendCmd(cmd, 10, NULL, 0, data, dataLen, 0) == 0) {
  932.     diskInfo_.lastSessionLba = (data[8] << 24) | (data[9] << 16) |
  933.                                (data[10] << 8) | data[11];
  934.     if (!diskInfo_.valid.empty) {
  935.       diskInfo_.valid.empty = 1;
  936.       diskInfo_.empty = (data[3] == 0) ? 1 : 0;
  937.       diskInfo_.sessionCnt = data[3];
  938.     }
  939.   }
  940.   // read ATIP data
  941.   dataLen = 28;
  942.   memset(cmd, 0, 10);
  943.   memset(data, 0, dataLen);
  944.   cmd[0] = 0x43; // READ TOC/PMA/ATIP
  945.   cmd[2] = 4; // get ATIP
  946.   cmd[7] = 0;
  947.   cmd[8] = dataLen; // data length
  948.   
  949.   if (sendCmd(cmd, 10, NULL, 0, data, dataLen, 0) == 0) {
  950.     if (data[6] & 0x04) {
  951.       diskInfo_.valid.recSpeed = 1;
  952.       spd = (data[16] >> 4) & 0x07;
  953.       diskInfo_.recSpeedLow = spd == 1 ? 2 : 0;
  954.       
  955.       spd = (data[16] & 0x0f);
  956.       diskInfo_.recSpeedHigh = spd >= 1 && spd <= 4 ? spd * 2 : 0;
  957.     }
  958.     if (data[8] >= 80 && data[8] <= 99) {
  959.       diskInfo_.manufacturerId = Msf(data[8], data[9], data[10]);
  960.       diskInfo_.valid.manufacturerId = 1;
  961.     }
  962.   }
  963.   return &diskInfo_;
  964. }
  965. // tries to read catalog number from disk and adds it to 'toc'
  966. // return: 1 if valid catalog number was found, else 0
  967. int GenericMMC::readCatalog(Toc *toc, long startLba, long endLba)
  968. {
  969.   unsigned char cmd[10];
  970.   unsigned char data[24];
  971.   char catalog[14];
  972.   int i;
  973.   if (options_ & OPT_MMC_SCAN_MCN) {
  974.     if (readCatalogScan(catalog, startLba, endLba) == 0) {
  975.       if (catalog[0] != 0) {
  976. if (toc->catalog(catalog) == 0)
  977.   return 1;
  978. else
  979.   message(-1, "Found illegal MCN data: %s", catalog);
  980.       }
  981.     }
  982.   }
  983.   else {
  984.     memset(cmd, 0, 10);
  985.     memset(data, 0, 24);
  986.     cmd[0] = 0x42; // READ SUB-CHANNEL
  987.     cmd[2] = 1 << 6;
  988.     cmd[3] = 0x02; // get media catalog number
  989.     cmd[8] = 24;   // transfer length
  990.     
  991.     if (sendCmd(cmd, 10, NULL, 0, data, 24) != 0) {
  992.       message(-2, "Cannot get catalog number.");
  993.       return 0;
  994.     }
  995.     
  996.     if (data[8] & 0x80) {
  997.       for (i = 0; i < 13; i++) {
  998. catalog[i] = data[0x09 + i];
  999.       }
  1000.       catalog[13] = 0;
  1001.       
  1002.       if (toc->catalog(catalog) == 0) {
  1003. return 1;
  1004.       }
  1005.     }
  1006.   }
  1007.   return 0;
  1008. }
  1009. int GenericMMC::readIsrc(int trackNr, char *buf)
  1010. {
  1011.   unsigned char cmd[10];
  1012.   unsigned char data[24];
  1013.   int i;
  1014.   buf[0] = 0;
  1015.   memset(cmd, 0, 10);
  1016.   memset(data, 0, 24);
  1017.   cmd[0] = 0x42; // READ SUB-CHANNEL
  1018.   cmd[2] = 1 << 6;
  1019.   cmd[3] = 0x03; // get media catalog number
  1020.   cmd[6] = trackNr;
  1021.   cmd[8] = 24;   // transfer length
  1022.   if (sendCmd(cmd, 10, NULL, 0, data, 24) != 0) {
  1023.     message(-2, "Cannot get ISRC code.");
  1024.     return 0;
  1025.   }
  1026.   if (data[8] & 0x80) {
  1027.     for (i = 0; i < 12; i++) {
  1028.       buf[i] = data[0x09 + i];
  1029.     }
  1030.     buf[12] = 0;
  1031.   }
  1032.   return 0;
  1033. }
  1034. int GenericMMC::analyzeTrack(TrackData::Mode mode, int trackNr, long startLba,
  1035.      long endLba, Msf *indexIncrements,
  1036.      int *indexIncrementCnt, long *pregap,
  1037.      char *isrcCode, unsigned char *ctl)
  1038. {
  1039.   int ret;
  1040.   selectSpeed(0);
  1041.   if (options_ & OPT_MMC_NO_SUBCHAN)
  1042.     ret = analyzeTrackSearch(mode, trackNr, startLba, endLba, indexIncrements,
  1043.      indexIncrementCnt, pregap, isrcCode, ctl);
  1044.   else
  1045.     ret = analyzeTrackScan(mode, trackNr, startLba, endLba,
  1046.    indexIncrements, indexIncrementCnt, pregap,
  1047.    isrcCode, ctl);
  1048.   if ((options_ & OPT_MMC_NO_SUBCHAN) ||
  1049.       (options_ & OPT_MMC_READ_ISRC) ||
  1050.       ((options_ & OPT_MMC_USE_PQ) && !(options_ & OPT_MMC_PQ_BCD))) {
  1051.     // The ISRC code is usually not usable if the PQ channel data is
  1052.     // converted to hex numbers by the drive. Read them with the
  1053.     // appropriate command in this case
  1054.     *isrcCode = 0;
  1055.     if (mode == TrackData::AUDIO)
  1056.       readIsrc(trackNr, isrcCode);
  1057.   }
  1058.   return ret;
  1059. }
  1060. int GenericMMC::readSubChannels(long lba, long len, SubChannel ***chans,
  1061. Sample *audioData)
  1062. {
  1063.   int retries = 5;
  1064.   unsigned char cmd[12];
  1065.   int i;
  1066.   long blockLen;
  1067.   if (options_ & OPT_MMC_NO_SUBCHAN) {
  1068.     blockLen = AUDIO_BLOCK_LEN;
  1069.   }
  1070.   else {
  1071.     if (options_ & OPT_MMC_USE_PQ) 
  1072.       blockLen = AUDIO_BLOCK_LEN + 16;
  1073.     else
  1074.       blockLen = AUDIO_BLOCK_LEN + 96;
  1075.   }
  1076.   cmd[0] = 0xbe;  // READ CD
  1077.   cmd[1] = 0;
  1078.   cmd[2] = lba >> 24;
  1079.   cmd[3] = lba >> 16;
  1080.   cmd[4] = lba >> 8;
  1081.   cmd[5] = lba;
  1082.   cmd[6] = len >> 16;
  1083.   cmd[7] = len >> 8;
  1084.   cmd[8] = len;
  1085.   cmd[9] = 0xf8;
  1086.   if (options_ & OPT_MMC_NO_SUBCHAN) {
  1087.     cmd[10] = 0;
  1088.   }
  1089.   else {
  1090.     if (options_ & OPT_MMC_USE_PQ) 
  1091.       cmd[10] = 0x02;  // PQ sub-channel data
  1092.     else
  1093.       cmd[10] = 0x01;  // raw PW sub-channel data
  1094.   }
  1095.   cmd[11] = 0;
  1096.   while (1) {
  1097.     if (sendCmd(cmd, 12, NULL, 0,
  1098. transferBuffer_, len * blockLen, retries == 0 ? 1 : 0) != 0) {
  1099.       if (retries == 0) 
  1100. return 1;
  1101.     }
  1102.     else {
  1103.       break;
  1104.     }
  1105.     retries--;
  1106.   }
  1107. #if 0
  1108.   if (lba > 5000) {
  1109.     char fname[200];
  1110.     sprintf(fname, "testout_%ld", lba);
  1111.     FILE *fp = fopen(fname, "w");
  1112.     fwrite(transferBuffer_, blockLen, len, fp);
  1113.     fclose(fp);
  1114.   }
  1115. #endif
  1116.   if ((options_ & OPT_MMC_NO_SUBCHAN) == 0) {
  1117.     unsigned char *buf = transferBuffer_ + AUDIO_BLOCK_LEN;
  1118.     for (i = 0; i < len; i++) {
  1119.       if (options_ & OPT_MMC_USE_PQ) {
  1120. if (!(options_ & OPT_MMC_PQ_BCD)) {
  1121.   // All numbers in sub-channel data are hex conforming to the
  1122.   // MMC standard. We have to convert them back to BCD for the
  1123.   // 'SubChannel' class.
  1124.   buf[1] = SubChannel::bcd(buf[1]);
  1125.   buf[2] = SubChannel::bcd(buf[2]);
  1126.   buf[3] = SubChannel::bcd(buf[3]);
  1127.   buf[4] = SubChannel::bcd(buf[4]);
  1128.   buf[5] = SubChannel::bcd(buf[5]);
  1129.   buf[6] = SubChannel::bcd(buf[6]);
  1130.   buf[7] = SubChannel::bcd(buf[7]);
  1131.   buf[8] = SubChannel::bcd(buf[8]);
  1132.   buf[9] = SubChannel::bcd(buf[9]);
  1133. }
  1134. ((PQSubChannel16*)scannedSubChannels_[i])->init(buf);
  1135. if (scannedSubChannels_[i]->type() != SubChannel::QMODE_ILLEGAL) {
  1136.   // the CRC of the sub-channel data is usually invalid -> mark the
  1137.   // sub-channel object that it should not try to verify the CRC
  1138.   scannedSubChannels_[i]->crcInvalid();
  1139. }
  1140.       }
  1141.       else {
  1142. ((PWSubChannel96*)scannedSubChannels_[i])->init(buf);
  1143.       }
  1144.       
  1145.       buf += blockLen;
  1146.     }
  1147.   }
  1148.   
  1149.   if (audioData != NULL) {
  1150.     unsigned char *p = transferBuffer_;
  1151.     for (i = 0; i < len; i++) {
  1152.       memcpy(audioData, p, AUDIO_BLOCK_LEN);
  1153.       p += blockLen;
  1154.       audioData += SAMPLES_PER_BLOCK;
  1155.     }
  1156.   }
  1157.   if (options_ & OPT_MMC_NO_SUBCHAN)
  1158.     *chans = NULL;
  1159.   else
  1160.     *chans = scannedSubChannels_;
  1161.   return 0;
  1162. }
  1163. int GenericMMC::driveInfo(DriveInfo *info, int showErrorMsg)
  1164. {
  1165.   unsigned char mp[22];
  1166.   if (getModePage(0x2a, mp, 22, NULL, NULL, showErrorMsg) != 0) {
  1167.     if (showErrorMsg) {
  1168.       message(-2, "Cannot retrieve CD capabilities mode page.");
  1169.     }
  1170.     return 1;
  1171.   }
  1172.   info->accurateAudioStream = mp[5] & 0x02 ? 1 : 0;
  1173.   info->maxReadSpeed = (mp[8] << 8) | mp[9];
  1174.   info->currentReadSpeed = (mp[14] << 8) | mp[15];
  1175.   info->maxWriteSpeed = (mp[18] << 8) | mp[19];
  1176.   info->currentWriteSpeed = (mp[20] << 8) | mp[21];
  1177.   return 0;
  1178. }
  1179. TrackData::Mode GenericMMC::getTrackMode(int, long trackStartLba)
  1180. {
  1181.   unsigned char cmd[12];
  1182.   unsigned char data[AUDIO_BLOCK_LEN];
  1183.   memset(cmd, 0, 12);
  1184.   cmd[0] = 0xbe;  // READ CD
  1185.   cmd[2] = trackStartLba >> 24;
  1186.   cmd[3] = trackStartLba >> 16;
  1187.   cmd[4] = trackStartLba >> 8;
  1188.   cmd[5] = trackStartLba;
  1189.   cmd[8] = 1;
  1190.   cmd[9] = 0xf8;
  1191.   if (sendCmd(cmd, 12, NULL, 0, data, AUDIO_BLOCK_LEN) != 0) {
  1192.     message(-2, "Cannot read sector of track.");
  1193.     return TrackData::MODE0;
  1194.   }
  1195.   if (memcmp(CdrDriver::syncPattern, data, 12) != 0) {
  1196.     // cannot be a data sector
  1197.     return TrackData::MODE0;
  1198.   }
  1199.   TrackData::Mode mode = determineSectorMode(data + 12);
  1200.   if (mode == TrackData::MODE0) {
  1201.     // illegal
  1202.     message(-2, "Found illegal mode in sector %ld.", trackStartLba);
  1203.   }
  1204.   return mode;
  1205. }
  1206. CdRawToc *GenericMMC::getRawToc(int sessionNr, int *len)
  1207. {
  1208.   unsigned char cmd[10];
  1209.   unsigned short dataLen;
  1210.   unsigned char *data = NULL;;
  1211.   unsigned char reqData[4]; // buffer for requestion the actual length
  1212.   unsigned char *p;
  1213.   int i, entries;
  1214.   CdRawToc *rawToc;
  1215.   assert(sessionNr >= 1);
  1216.   // read disk toc length
  1217.   memset(cmd, 0, 10);
  1218.   cmd[0] = 0x43; // READ TOC
  1219.   cmd[2] = 2;
  1220.   cmd[6] = sessionNr;
  1221.   cmd[8] = 4;
  1222.   if (sendCmd(cmd, 10, NULL, 0, reqData, 4) != 0) {
  1223.     message(-2, "Cannot read disk toc.");
  1224.     return NULL;
  1225.   }
  1226.   dataLen = ((reqData[0] << 8) | reqData[1]) + 2;
  1227.   
  1228.   message(3, "Raw toc data len: %d", dataLen);
  1229.   data = new (unsigned char)[dataLen];
  1230.   
  1231.   // read disk toc
  1232.   cmd[7] = dataLen >> 8;
  1233.   cmd[8] = dataLen;
  1234.   if (sendCmd(cmd, 10, NULL, 0, data, dataLen) != 0) {
  1235.     message(-2, "Cannot read disk toc.");
  1236.     delete[] data;
  1237.     return NULL;
  1238.   }
  1239.   entries = (((data[0] << 8) | data[1]) - 2) / 11;
  1240.   rawToc = new CdRawToc[entries];
  1241.   for (i = 0, p = data + 4; i < entries; i++, p += 11 ) {
  1242. #if 0
  1243.     message(0, "%d %02x %02d %2x %02d:%02d:%02d %02d %02d:%02d:%02d",
  1244.     p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10]);
  1245. #endif
  1246.     rawToc[i].sessionNr = p[0];
  1247.     rawToc[i].adrCtl = p[1];
  1248.     rawToc[i].point = p[3];
  1249.     rawToc[i].pmin = p[8];
  1250.     rawToc[i].psec = p[9];
  1251.     rawToc[i].pframe = p[10];
  1252.   }
  1253.   delete[] data;
  1254.   *len = entries;
  1255.   return rawToc;
  1256. }
  1257. long GenericMMC::readTrackData(TrackData::Mode mode, long lba, long len,
  1258.        unsigned char *buf)
  1259. {
  1260.   long i;
  1261.   long inBlockLen = AUDIO_BLOCK_LEN;
  1262.   unsigned char cmd[12];
  1263.   TrackData::Mode actMode;
  1264.   int ok = 0;
  1265.   const unsigned char *sense;
  1266.   int senseLen;
  1267.   int softError;
  1268.   memset(cmd, 0, 12);
  1269.   cmd[0] = 0xbe; // READ CD
  1270.   cmd[1] = 0;
  1271.   cmd[2] = lba >> 24;
  1272.   cmd[3] = lba >> 16;
  1273.   cmd[4] = lba >> 8;
  1274.   cmd[5] = lba;
  1275.   cmd[9] = 0xf8;
  1276.   while (len > 0 && !ok) {
  1277.     cmd[6] = len >> 16;
  1278.     cmd[7] = len >> 8;
  1279.     cmd[8] = len;
  1280.     memset(transferBuffer_, 0, len * inBlockLen);
  1281.     switch (sendCmd(cmd, 12, NULL, 0, transferBuffer_, len * inBlockLen, 0)) {
  1282.     case 0:
  1283.       ok = 1;
  1284.       break;
  1285.     case 2:
  1286.       softError = 0;
  1287.       sense = scsiIf_->getSense(senseLen);
  1288.       if (senseLen > 0x0c) {
  1289. if ((sense[2] & 0x0f) == 5) { // Illegal request
  1290.   switch (sense[12]) {
  1291.   case 0x63: // End of user area encountered on this track
  1292.   case 0x64: // Illegal mode for this track
  1293.     softError = 1;
  1294.     break;
  1295.   }
  1296. }
  1297. else if ((sense[2] & 0x0f) == 3) { // Medium error
  1298.   switch (sense[12]) {
  1299.   case 0x02: // No seek complete, sector not found
  1300.   case 0x11: // L-EC error
  1301.     return -2;
  1302.     break;
  1303.   }
  1304. }
  1305.       }
  1306.       if (!softError) {
  1307. scsiIf_->printError();
  1308. return -1;
  1309.       }
  1310.       break;
  1311.     default:
  1312.       message(-2, "Read error at LBA %ld, len %ld", lba, len);
  1313.       return -1;
  1314.       break;
  1315.     }
  1316.     if (!ok) {
  1317.       len--;
  1318.     }
  1319.   }
  1320.   unsigned char *sector = transferBuffer_;
  1321.   for (i = 0; i < len; i++) {
  1322.      
  1323.     if (memcmp(CdrDriver::syncPattern, sector, 12) != 0) {
  1324.       // can't be a data block
  1325.       message(3, "Stopped because no sync pattern found.");
  1326.       message(3, "%d %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", i, 
  1327.       sector[0], sector[1], sector[2], sector[3], sector[4], sector[5],
  1328.       sector[6], sector[7], sector[8], sector[9], sector[10],
  1329.       sector[11]);
  1330.       return i;
  1331.     }
  1332.     actMode = determineSectorMode(sector + 12);
  1333.     if (!(actMode == mode ||
  1334.   (mode == TrackData::MODE2_FORM_MIX &&
  1335.    (actMode == TrackData::MODE2_FORM1 ||
  1336.     actMode == TrackData::MODE2_FORM2)) ||
  1337.   (mode == TrackData::MODE1_RAW && actMode == TrackData::MODE1) ||
  1338.   (mode == TrackData::MODE2_RAW &&
  1339.    (actMode == TrackData::MODE2 ||
  1340.     actMode == TrackData::MODE2_FORM1 ||
  1341.     actMode == TrackData::MODE2_FORM2)))) {
  1342.       message(3, "Sector with not matching mode %s found.",
  1343.       TrackData::mode2String(actMode));
  1344.       message(3, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
  1345.       sector[12], sector[13], sector[14], sector[15], sector[16],
  1346.       sector[17], sector[18], sector[19], sector[20], sector[21],
  1347.       sector[22], sector[23]);
  1348.       return i;
  1349.     }
  1350.     if (buf != NULL) {
  1351.       switch (mode) {
  1352.       case TrackData::MODE1:
  1353. memcpy(buf, sector + 16, MODE1_BLOCK_LEN);
  1354. buf += MODE1_BLOCK_LEN;
  1355. break;
  1356.       case TrackData::MODE1_RAW:
  1357. memcpy(buf, sector, AUDIO_BLOCK_LEN);
  1358. buf += AUDIO_BLOCK_LEN;
  1359. break;
  1360.       case TrackData::MODE2:
  1361.       case TrackData::MODE2_FORM_MIX:
  1362. memcpy(buf, sector + 16, MODE2_BLOCK_LEN);
  1363. buf += MODE2_BLOCK_LEN;
  1364. break;
  1365.       case TrackData::MODE2_FORM1:
  1366. memcpy(buf, sector + 24, MODE2_FORM1_DATA_LEN);
  1367. buf += MODE2_FORM1_DATA_LEN;
  1368. break;
  1369.       case TrackData::MODE2_FORM2:
  1370. memcpy(buf, sector + 24, MODE2_FORM2_DATA_LEN);
  1371. buf += MODE2_FORM2_DATA_LEN;
  1372. break;
  1373.       case TrackData::MODE2_RAW:
  1374. memcpy(buf, sector, AUDIO_BLOCK_LEN);
  1375. buf += AUDIO_BLOCK_LEN;
  1376. break;
  1377.       case TrackData::MODE0:
  1378.       case TrackData::AUDIO:
  1379. message(-3, "GenericMMC::readTrackData: Illegal mode.");
  1380. return 0;
  1381. break;
  1382.       }
  1383.     }
  1384.     sector += inBlockLen;
  1385.   }
  1386.   return len;
  1387. }
  1388. int GenericMMC::readAudioRange(int fd, long start, long end, int startTrack,
  1389.        int endTrack, TrackInfo *info)
  1390. {
  1391.   if (!onTheFly_) {
  1392.     if ((options_ & OPT_MMC_NO_SUBCHAN) ||
  1393. (options_ & OPT_MMC_READ_ISRC) ||
  1394. ((options_ & OPT_MMC_USE_PQ) && !(options_ & OPT_MMC_PQ_BCD))) {
  1395.       int t;
  1396.       long pregap = 0;
  1397.       // The ISRC code is usually not usable if the PQ channel data is
  1398.       // converted to hex numbers by the drive. Read them with the
  1399.       // appropriate command in this case
  1400.       message(1, "Analyzing...");
  1401.       for (t = startTrack; t <= endTrack; t++) {
  1402. message(1, "Track %d...", t + 1);
  1403. if (options_ & OPT_MMC_NO_SUBCHAN) {
  1404.   // we have to use the binary search method to find pre-gap and
  1405.   // index marks if the drive cannot read sub-channel data
  1406.   if (!fastTocReading_) {
  1407.     long slba, elba;
  1408.     int i, indexCnt;
  1409.     Msf index[98];
  1410.     unsigned char ctl;
  1411.     if (pregap > 0)
  1412.       message(1, "Found pre-gap: %s", Msf(pregap).str());
  1413.     slba = info[t].start;
  1414.     if (info[t].mode == info[t + 1].mode)
  1415.       elba = info[t + 1].start;
  1416.     else
  1417.       elba = info[t + 1].start - 150;
  1418.     
  1419.     pregap = 0;
  1420.     if (analyzeTrackSearch(TrackData::AUDIO, t + 1, slba, elba,
  1421.    index, &indexCnt, &pregap, info[t].isrcCode,
  1422.    &ctl) != 0)
  1423.       return 1;
  1424.   
  1425.     for (i = 0; i < indexCnt; i++)
  1426.       info[t].index[i] = index[i].lba();
  1427.     
  1428.     info[t].indexCnt = indexCnt;
  1429.     
  1430.     if (t < endTrack)
  1431.       info[t + 1].pregap = pregap;
  1432.   }
  1433.   else {
  1434.     info[t].indexCnt = 0;
  1435.     info[t + 1].pregap = 0;
  1436.   }
  1437. }
  1438. info[t].isrcCode[0] = 0;
  1439. readIsrc(t + 1, info[t].isrcCode);
  1440. if (info[t].isrcCode[0] != 0)
  1441.   message(1, "Found ISRC code.");
  1442.       }
  1443.       message(1, "Reading...");
  1444.     }
  1445.   }
  1446.   return CdrDriver::readAudioRangeParanoia(fd, start, end, startTrack,
  1447.    endTrack, info);
  1448. }
  1449. int GenericMMC::getTrackIndex(long lba, int *trackNr, int *indexNr,
  1450.       unsigned char *ctl)
  1451. {
  1452.   unsigned char cmd[12];
  1453.   unsigned short dataLen = 0x30;
  1454.   unsigned char data[0x30];
  1455.   int waitLoops = 10;
  1456.   int waitFailed = 0;
  1457.   // play one audio block
  1458.   memset(cmd, 0, 10);
  1459.   cmd[0] = 0x45; // PLAY AUDIO
  1460.   cmd[2] = lba >> 24;
  1461.   cmd[3] = lba >> 16;
  1462.   cmd[4] = lba >> 8;
  1463.   cmd[5] = lba;
  1464.   cmd[7] = 0;
  1465.   cmd[8] = 1;
  1466.   if (sendCmd(cmd, 10, NULL, 0, NULL, 0) != 0) {
  1467.     message(-2, "Cannot play audio block.");
  1468.     return 1;
  1469.   }
  1470.   // wait until the play command finished
  1471.   memset(cmd, 0, 12);
  1472.   cmd[0] = 0xbd; // MECHANISM STATUS
  1473.   cmd[9] = 8;
  1474.   while (waitLoops > 0) {
  1475.     if (sendCmd(cmd, 12, NULL, 0, data, 8, 0) == 0) {
  1476.       //message(0, "%d, %x", waitLoops, data[1]);
  1477.       if ((data[1] >> 5) == 1) // still playing?
  1478. waitLoops--;
  1479.       else
  1480. waitLoops = 0;
  1481.     }
  1482.     else {
  1483.       waitFailed = 1;
  1484.       waitLoops = 0;
  1485.     }
  1486.   }
  1487.   if (waitFailed) {
  1488.     // The play operation immediately returns success status and the waiting
  1489.     // loop above failed. Wait here for a while until the desired block is
  1490.     // played. It takes ~13 msecs to play a block but access time is in the
  1491.     // order of several 100 msecs
  1492.     mSleep(300);
  1493.   }
  1494.   // read sub channel information
  1495.   memset(cmd, 0, 10);
  1496.   cmd[0] = 0x42; // READ SUB CHANNEL
  1497.   cmd[2] = 0x40; // get sub channel data
  1498.   cmd[3] = 0x01; // get sub Q channel data
  1499.   cmd[6] = 0;
  1500.   cmd[7] = dataLen >> 8;
  1501.   cmd[8] = dataLen;
  1502.   if (sendCmd(cmd, 10, NULL, 0, data, dataLen) != 0) {
  1503.     message(-2, "Cannot read sub Q channel data.");
  1504.     return 1;
  1505.   }
  1506.   *trackNr = data[6];
  1507.   *indexNr = data[7];
  1508.   if (ctl != NULL) {
  1509.     *ctl = data[5] & 0x0f;
  1510.   }
  1511.   //message(0, "%d %d", *trackNr, *indexNr);
  1512.   return 0;
  1513. }