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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /*  cdrdao - write audio CD-Rs in disc-at-once mode
  2.  *
  3.  *  Copyright (C) 1998  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: RicohMP6200.cc,v $
  21.  * Revision 1.5  1999/04/05 11:04:10  mueller
  22.  * Added driver option flags.
  23.  *
  24.  * Revision 1.4  1999/03/27 20:50:24  mueller
  25.  * Adapted to changed writing interface.
  26.  * Fixed problems with the ATAPI version of these drives.
  27.  *
  28.  * Revision 1.3  1999/01/24 17:08:38  mueller
  29.  * Tried different load/unload SCSI command for ejecting the disk.
  30.  *
  31.  * Revision 1.2  1998/10/06 18:10:24  mueller
  32.  * Disabled setting of Catalogue Number.
  33.  *
  34.  * Revision 1.1  1998/10/03 15:04:37  mueller
  35.  * Initial revision
  36.  *
  37.  */
  38. /* Driver for the Ricoh MP6200 drive. It's mainly SCSI-3/mmc compatible but
  39.  * disk-at-once writing is done with the Philips CDD2x00 commands.
  40.  */
  41. static char rcsid[] = "$Id: RicohMP6200.cc,v 1.5 1999/04/05 11:04:10 mueller Exp mueller $";
  42. #include <config.h>
  43. #include <string.h>
  44. #include <assert.h>
  45. #include "RicohMP6200.h"
  46. #include "SubChannel.h"
  47. #include "Toc.h"
  48. #include "util.h"
  49. RicohMP6200::RicohMP6200(ScsiIf *scsiIf, unsigned long options)
  50.   : GenericMMC(scsiIf, options), CDD2600Base(this)
  51. {
  52.   driverName_ = "Ricoh MP6200 - Version 0.1(alpha)";
  53.   
  54.   simulate_ = 1;
  55.   encodingMode_ = 0;
  56. }
  57. RicohMP6200::~RicohMP6200()
  58. {
  59. }
  60. // static constructor
  61. CdrDriver *RicohMP6200::instance(ScsiIf *scsiIf, unsigned long options)
  62. {
  63.   return new RicohMP6200(scsiIf, options);
  64. }
  65. // Sets write parameters via mode page 0x05.
  66. // return: 0: OK
  67. //         1: scsi command failed
  68. int RicohMP6200::setWriteParameters()
  69. {
  70.   int i;
  71.   unsigned char mp[0x38];
  72.   if (getModePage(5/*write parameters mode page*/, mp, 0x38, 
  73.   NULL, NULL, 1) != 0) {
  74.     message(-2, "Cannot retrieve write parameters mode page.");
  75.     return 1;
  76.   }
  77.   mp[0] &= 0x7f; // clear PS flag
  78.   mp[2] &= 0xef;
  79.   if (simulate_) {
  80.     mp[2] |= 1 << 4; // test write
  81.   }
  82.   mp[3] &= 0x3f; // Multi-session: No B0 pointer, next session not allowed
  83.   if (multiSession_ != 0)
  84.     mp[3] |= 0x03 << 6; // open next session
  85.   if (toc_->catalogValid()) {
  86.     mp[16] = 0x80;
  87.     for (i = 0; i < 13; i++)
  88.       mp[17 + i] = toc_->catalog(i) + '0';
  89.     mp[30] = 0;
  90.     mp[31] = 0;
  91.   }
  92.   else {
  93.     mp[16] = 0;
  94.   }
  95.   
  96.   if (setModePage(mp, NULL, NULL, 1) != 0) {
  97.     message(-2, "Cannot set write parameters mode page.");
  98.     return 1;
  99.   }
  100.   return 0;
  101. }
  102. int RicohMP6200::initDao(const Toc *toc)
  103. {
  104.   long n;
  105.   blockLength_ = AUDIO_BLOCK_LEN;
  106.   blocksPerWrite_ = scsiIf_->maxDataLen() / blockLength_;
  107.   assert(blocksPerWrite_ > 0);
  108.   toc_ = toc;
  109.   // the ATAPI version does not like the following command so a failure
  110.   // is non fatal
  111.   modeSelectBlockSize(blockLength_, 0);
  112.   if (readSessionInfo(&leadInLen_, &leadOutLen_, 1) != 0 ||
  113.       setWriteParameters() != 0)
  114.     return 1;
  115.   // allocate buffer for write zeros
  116.   n = blocksPerWrite_ * blockLength_;
  117.   delete[] zeroBuffer_;
  118.   zeroBuffer_ = new char[n];
  119.   memset(zeroBuffer_, 0, n);
  120.   return 0;
  121. }
  122. int RicohMP6200::startDao()
  123. {
  124.   long lba = 0;
  125.   if (writeSession(toc_, multiSession_) != 0) {
  126.     return 1;
  127.   }
  128.   message(1, "Writing lead-in and gap...");
  129.   // write lead-in
  130.   if (writeZeros(toc_->leadInMode(), lba, 0, leadInLen_) != 0) {
  131.     flushCache();
  132.     return 1;
  133.   }
  134.   // write gap (2 seconds)
  135.   if (writeZeros(toc_->leadInMode(), lba, 0, 150) != 0) {
  136.     flushCache();
  137.     return 1;
  138.   }
  139.   message(1, "");
  140.   return 0;
  141. }
  142. int RicohMP6200::finishDao()
  143. {
  144.   long lba = toc_->length().lba();
  145.   message(1, "Writing lead-out...");
  146.   // write lead-out
  147.   if (writeZeros(toc_->leadOutMode(), lba, lba + 150, leadOutLen_) != 0) {
  148.     flushCache();
  149.     return 1;
  150.   }
  151.   message(1, "nFlushing cache...");
  152.   
  153.   if (flushCache() != 0) {
  154.     return 1;
  155.   }
  156.   message(1, "");
  157.   delete[] zeroBuffer_, zeroBuffer_ = NULL;
  158.   return 0;
  159. }
  160. void RicohMP6200::abortDao()
  161. {
  162.   flushCache();
  163. }
  164. // Writes data to target, the block length depends on the actual writing mode
  165. // and is stored internally. 'len' is number of blocks to write.
  166. // 'lba' specifies the next logical block address for writing and is updated
  167. // by this function but not used for writing
  168. // return: 0: OK
  169. //         1: scsi command failed
  170. int RicohMP6200::writeData(TrackData::Mode mode, long &lba, const char *buf,
  171.    long len)
  172. {
  173.   assert(blocksPerWrite_ > 0);
  174.   assert(blockLength_ > 0);
  175.   assert(mode == TrackData::AUDIO);
  176.   int nwritten = 0;
  177.   int writeLen = 0;
  178.   unsigned char cmd[10];
  179.   memset(cmd, 0, 10);
  180.   cmd[0] = 0x2a; // WRITE1
  181.   
  182.   while (len > 0) {
  183.     writeLen = (len > blocksPerWrite_ ? blocksPerWrite_ : len);
  184.     cmd[7] = writeLen >> 8;
  185.     cmd[8] = writeLen & 0xff;
  186.     if (sendCmd(cmd, 10, (unsigned char *)(buf + (nwritten * blockLength_)),
  187. writeLen * blockLength_, NULL, 0) != 0) {
  188.       message(-2, "Write data failed.");
  189.       return 1;
  190.     }
  191.     lba += writeLen;
  192.     len -= writeLen;
  193.     nwritten += writeLen;
  194.   }
  195.       
  196.   return 0;
  197. }
  198. // loads ('unload' == 0) or ejects ('unload' == 1) tray
  199. // return: 0: OK
  200. //         1: scsi command failed
  201. int RicohMP6200::loadUnload(int unload) const
  202. {
  203.   unsigned char cmd[10];
  204.   memset(cmd, 0, 10);
  205.   cmd[0] = 0xe7; // MEDIUM LOAD/UNLOAD
  206.   if (unload) {
  207.     cmd[8] |= 0x01;
  208.   }
  209.   
  210.   if (sendCmd(cmd, 10, NULL, 0, NULL, 0) != 0) {
  211.     message(-2, "Cannot load/unload medium.");
  212.     return 1;
  213.   }
  214.   return 0;
  215. }