1
/* cdrdao - write audio CD-Rs in disc-at-once mode
3
* Copyright (C) 1998-2001 Andreas Mueller <andreas@daneb.de>
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.
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.
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.
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.
29
#include "RicohMP6200.h"
30
#include "SubChannel.h"
34
RicohMP6200::RicohMP6200(ScsiIf *scsiIf, unsigned long options)
35
: GenericMMC(scsiIf, options), CDD2600Base(this)
37
driverName_ = "Ricoh MP6200 - Version 0.1(alpha)";
43
RicohMP6200::~RicohMP6200()
48
CdrDriver *RicohMP6200::instance(ScsiIf *scsiIf, unsigned long options)
50
return new RicohMP6200(scsiIf, options);
54
// Sets write parameters via mode page 0x05.
56
// 1: scsi command failed
57
int RicohMP6200::setWriteParameters()
60
unsigned char mp[0x38];
62
if (getModePage(5/*write parameters mode page*/, mp, 0x38,
63
NULL, NULL, 1) != 0) {
64
message(-2, "Cannot retrieve write parameters mode page.");
68
mp[0] &= 0x7f; // clear PS flag
73
mp[2] |= 1 << 4; // test write
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
80
if (toc_->catalogValid()) {
83
for (i = 0; i < 13; i++)
84
mp[17 + i] = toc_->catalog(i) + '0';
93
if (setModePage(mp, NULL, NULL, 1) != 0) {
94
message(-2, "Cannot set write parameters mode page.");
102
int RicohMP6200::initDao(const Toc *toc)
105
blockLength_ = AUDIO_BLOCK_LEN;
106
blocksPerWrite_ = scsiIf_->maxDataLen() / blockLength_;
108
assert(blocksPerWrite_ > 0);
112
// the ATAPI version does not like the following command so a failure
114
modeSelectBlockSize(blockLength_, 0);
116
if (readSessionInfo(&leadInLen_, &leadOutLen_, 1) != 0 ||
117
setWriteParameters() != 0)
120
// allocate buffer for write zeros
121
n = blocksPerWrite_ * blockLength_;
122
delete[] zeroBuffer_;
123
zeroBuffer_ = new char[n];
124
memset(zeroBuffer_, 0, n);
129
int RicohMP6200::startDao()
133
if (writeSession(toc_, multiSession_, 0) != 0) {
137
message(2, "Writing lead-in and gap...");
140
if (writeZeros(toc_->leadInMode(), TrackData::SUBCHAN_NONE, lba, 0,
146
// write gap (2 seconds)
147
if (writeZeros(toc_->leadInMode(), TrackData::SUBCHAN_NONE, lba, 0, 150)
158
int RicohMP6200::finishDao()
160
long lba = toc_->length().lba();
162
message(2, "Writing lead-out...");
165
if (writeZeros(toc_->leadOutMode(), TrackData::SUBCHAN_NONE, lba, lba + 150,
171
message(2, "\nFlushing cache...");
173
if (flushCache() != 0) {
179
delete[] zeroBuffer_, zeroBuffer_ = NULL;
184
void RicohMP6200::abortDao()
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
194
// 1: scsi command failed
195
int RicohMP6200::writeData(TrackData::Mode mode, TrackData::SubChannelMode sm,
196
long &lba, const char *buf, long len)
198
assert(blocksPerWrite_ > 0);
199
assert(blockLength_ > 0);
200
assert(mode == TrackData::AUDIO);
203
unsigned char cmd[10];
206
cmd[0] = 0x2a; // WRITE1
209
writeLen = (len > blocksPerWrite_ ? blocksPerWrite_ : len);
211
cmd[7] = writeLen >> 8;
212
cmd[8] = writeLen & 0xff;
214
if (sendCmd(cmd, 10, (unsigned char *)(buf + (nwritten * blockLength_)),
215
writeLen * blockLength_, NULL, 0) != 0) {
216
message(-2, "Write data failed.");
223
nwritten += writeLen;
229
// loads ('unload' == 0) or ejects ('unload' == 1) tray
231
// 1: scsi command failed
233
int RicohMP6200::loadUnload(int unload) const
235
unsigned char cmd[10];
239
cmd[0] = 0xe7; // MEDIUM LOAD/UNLOAD
244
if (sendCmd(cmd, 10, NULL, 0, NULL, 0) != 0) {
245
message(-2, "Cannot load/unload medium.");