~ubuntu-branches/ubuntu/utopic/cdrdao/utopic

« back to all changes in this revision

Viewing changes to dao/RicohMP6200.cc

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Suffield
  • Date: 2004-06-24 22:33:16 UTC
  • Revision ID: james.westby@ubuntu.com-20040624223316-534onzugaeeyq61j
Tags: upstream-1.1.9
ImportĀ upstreamĀ versionĀ 1.1.9

Show diffs side-by-side

added added

removed removed

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