1 /* cdrdao - write audio CD-Rs in disc-at-once mode
2 *
3 * Copyright (C) 1998-2002 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 #include <config.h>
21
22 #include <string.h>
23 #include <time.h>
24 #include <assert.h>
25
26 #include "GenericMMC.h"
27
28 #include "port.h"
29 #include "Toc.h"
30 #include "log.h"
31 #include "PQSubChannel16.h"
32 #include "PWSubChannel96.h"
33 #include "CdTextEncoder.h"
34
35
36
37 // Variants for cue sheet generation
38
39 // do not set ctl flags for ISRC cue sheet entries
40 #define CUE_VAR_ISRC_NO_CTL 0x1
41
42 // do not set start of lead-in time in lead-in cue sheet entry
43 #define CUE_VAR_CDTEXT_NO_TIME 0x2
44
45 #define CUE_VAR_MAX 0x3
46
47
48 // Variants for write parameters mode page
49
50 //do not set data block type to block size 2448 if a CD-TEXT lead-in is written
51 #define WMP_VAR_CDTEXT_NO_DATA_BLOCK_TYPE 0x1
52
53 #define WMP_VAR_MAX 0x1
54
55
GenericMMC(ScsiIf * scsiIf,unsigned long options)56 GenericMMC::GenericMMC(ScsiIf *scsiIf, unsigned long options)
57 : CdrDriver(scsiIf, options)
58 {
59 int i;
60 driverName_ = "Generic SCSI-3/MMC - Version 2.0";
61
62 speed_ = 0;
63 rspeed_ = 0;
64 simulate_ = true;
65 encodingMode_ = 1;
66
67 scsiTimeout_ = 0;
68
69 cdTextEncoder_ = NULL;
70
71 driveInfo_ = NULL;
72
73 memset(&diskInfo_, 0, sizeof(DiskInfo));
74
75 for (i = 0; i < maxScannedSubChannels_; i++) {
76 if (options_ & OPT_MMC_USE_PQ)
77 scannedSubChannels_[i] = new PQSubChannel16;
78 else
79 scannedSubChannels_[i] = new PWSubChannel96;
80 }
81
82 // MMC drives usually return little endian samples
83 audioDataByteOrder_ = 0;
84 }
85
~GenericMMC()86 GenericMMC::~GenericMMC()
87 {
88 int i;
89
90 for (i = 0; i < maxScannedSubChannels_; i++) {
91 delete scannedSubChannels_[i];
92 scannedSubChannels_[i] = NULL;
93 }
94
95 delete cdTextEncoder_;
96 cdTextEncoder_ = NULL;
97
98 delete driveInfo_;
99 driveInfo_ = NULL;
100 }
101
102 // static constructor
instance(ScsiIf * scsiIf,unsigned long options)103 CdrDriver *GenericMMC::instance(ScsiIf *scsiIf, unsigned long options)
104 {
105 return new GenericMMC(scsiIf, options);
106 }
107
108
checkToc(const Toc * toc)109 int GenericMMC::checkToc(const Toc *toc)
110 {
111 int err = CdrDriver::checkToc(toc);
112 int e;
113
114 if (options_ & OPT_MMC_CD_TEXT) {
115 if ((e = toc->checkCdTextData()) > err)
116 err = e;
117 }
118
119 return err;
120 }
121
subChannelEncodingMode(TrackData::SubChannelMode sm) const122 int GenericMMC::subChannelEncodingMode(TrackData::SubChannelMode sm) const
123 {
124 int ret = 0;
125
126 switch (sm) {
127 case TrackData::SUBCHAN_NONE:
128 ret = 0;
129 break;
130
131 case TrackData::SUBCHAN_RW:
132 #if 0
133 if (options_ & OPT_MMC_NO_RW_PACKED)
134 ret = 1; // have to encode the R-W sub-channel data
135 else
136 ret = 0;
137 #endif
138 ret = 0;
139 break;
140
141 case TrackData::SUBCHAN_RW_RAW:
142 // raw R-W sub-channel writing is assumed to be always supported
143 ret = 1;
144 break;
145 }
146
147 return ret;
148 }
149
150 // sets speed
151 // return: 0: OK
152 // 1: illegal speed
speed(int s)153 int GenericMMC::speed(int s)
154 {
155 speed_ = s;
156
157 if (selectSpeed() != 0)
158 return 1;
159
160 return 0;
161 }
162
speed()163 int GenericMMC::speed()
164 {
165 const DriveInfo *di;
166
167 delete driveInfo_;
168 driveInfo_ = NULL;
169
170 if ((di = driveInfo(true)) == NULL) {
171 return 0;
172 }
173
174 return speed2Mult(di->currentWriteSpeed);
175
176 }
177
178 // sets fspeed
179 // return: true: OK
180 // false: illegal speed
rspeed(int s)181 bool GenericMMC::rspeed(int s)
182 {
183 rspeed_ = s;
184
185 if (selectSpeed() != 0)
186 return false;
187
188 return true;
189 }
190
rspeed()191 int GenericMMC::rspeed()
192 {
193 const DriveInfo *di;
194
195 delete driveInfo_;
196 driveInfo_ = NULL;
197
198 if ((di = driveInfo(true)) == NULL) {
199 return 0;
200 }
201
202 return speed2Mult(di->currentReadSpeed);
203 }
204
205
206 // loads ('unload' == 0) or ejects ('unload' == 1) tray
207 // return: 0: OK
208 // 1: scsi command failed
loadUnload(int unload) const209 int GenericMMC::loadUnload(int unload) const
210 {
211 unsigned char cmd[6];
212
213 memset(cmd, 0, 6);
214
215 cmd[0] = 0x1b; // START/STOP UNIT
216 if (unload) {
217 cmd[4] = 0x02; // LoUnlo=1, Start=0
218 }
219 else {
220 cmd[4] = 0x03; // LoUnlo=1, Start=1
221 }
222
223 if (sendCmd(cmd, 6, NULL, 0, NULL, 0) != 0) {
224 log_message(-2, "Cannot load/unload medium.");
225 return 1;
226 }
227
228 return 0;
229 }
230
231 // Checks for ready status of the drive after a write operation
232 // Return: 0: drive ready
233 // 1: error occured
234 // 2: drive not ready
235
checkDriveReady() const236 int GenericMMC::checkDriveReady() const
237 {
238 unsigned char cmd[10];
239 unsigned char data[4];
240 int ret;
241
242 ret = testUnitReady(0);
243
244 if (ret == 0) {
245 // testUnitReady reports ready status but this might actually not
246 // be the truth -> additionally check the READ DISK INFO command
247
248 memset(cmd, 0, 10);
249
250 cmd[0] = 0x51; // READ DISK INFORMATION
251 cmd[8] = 4;
252
253 ret = sendCmd(cmd, 10, NULL, 0, data, 4, 0);
254
255 if (ret == 2) {
256 const unsigned char *sense;
257 int senseLen;
258
259 ret = 0; // indicates ready status
260
261 sense = scsiIf_->getSense(senseLen);
262
263 if (senseLen >= 14 && (sense[2] & 0x0f) == 0x2 && sense[7] >= 6 &&
264 sense[12] == 0x4 &&
265 (sense[13] == 0x8 || sense[13] == 0x7)) {
266 // Not Ready, long write in progress
267 ret = 2; // indicates not ready status
268 }
269 }
270 }
271
272 return ret;
273 }
274
275 // Performs complete blanking of a CD-RW.
276 // return: 0: OK
277 // 1: scsi command failed
blankDisk(BlankingMode mode)278 int GenericMMC::blankDisk(BlankingMode mode)
279 {
280 unsigned char cmd[12];
281 int ret, progress;
282 time_t startTime, endTime;
283
284 setSimulationMode(0);
285
286
287 memset(cmd, 0, 12);
288
289 cmd[0] = 0xa1; // BLANK
290
291 switch (mode) {
292 case BLANK_FULL:
293 cmd[1] = 0x0; // erase complete disk
294 break;
295 case BLANK_MINIMAL:
296 cmd[1] = 0x1; // erase PMA, lead-in and 1st track's pre-gap
297 break;
298 }
299
300 cmd[1] |= 1 << 4; // immediate return
301
302 sendBlankCdProgressMsg(0);
303
304 if (sendCmd(cmd, 12, NULL, 0, NULL, 0, 1) != 0) {
305 log_message(-2, "Cannot erase CD-RW.");
306 return 1;
307 }
308
309 time(&startTime);
310 progress = 0;
311
312 do {
313 mSleep(2000);
314
315 ret = checkDriveReady();
316
317 if (ret == 1) {
318 log_message(-2, "Test Unit Ready command failed.");
319 }
320
321 progress += 10;
322 sendBlankCdProgressMsg(progress);
323
324 if (progress >= 1000)
325 progress = 0;
326
327 } while (ret == 2);
328
329 if (ret == 0)
330 sendBlankCdProgressMsg(1000);
331
332 time(&endTime);
333
334 log_message(2, "Blanking time: %ld seconds", endTime - startTime);
335
336 return ret;
337 }
338
339 // sets read/write speed and simulation mode
340 // return: 0: OK
341 // 1: scsi command failed
selectSpeed()342 int GenericMMC::selectSpeed()
343 {
344 unsigned char cmd[12];
345 int spd;
346
347 memset(cmd, 0, 12);
348
349 cmd[0] = 0xbb; // SET CD SPEED
350
351 // select maximum read speed
352 if (rspeed_ == 0) {
353 cmd[2] = 0xff;
354 cmd[3] = 0xff;
355 }
356 else {
357 spd = mult2Speed(rspeed_);
358 cmd[2] = spd >> 8;
359 cmd[3] = spd;
360 }
361
362 // select maximum write speed
363 if (speed_ == 0) {
364 cmd[4] = 0xff;
365 cmd[5] = 0xff;
366 }
367 else {
368 spd = mult2Speed(speed_);
369 cmd[4] = spd >> 8;
370 cmd[5] = spd;
371 }
372
373 if ((options_ & OPT_MMC_YAMAHA_FORCE_SPEED) != 0 &&
374 writeSpeedControl())
375 cmd[11] = 0x80; // enable Yamaha's force speed
376
377 if (sendCmd(cmd, 12, NULL, 0, NULL, 0) != 0) {
378 log_message(-2, "Cannot set cd speed.");
379 return 1;
380 }
381
382 return 0;
383 }
384
385 // Determins start and length of lead-in and length of lead-out.
386 // return: 0: OK
387 // 1: SCSI command failed
getSessionInfo()388 int GenericMMC::getSessionInfo()
389 {
390 unsigned char cmd[10];
391 unsigned long dataLen = 34;
392 unsigned char data[34];
393
394 memset(cmd, 0, 10);
395 memset(data, 0, dataLen);
396
397 cmd[0] = 0x51; // READ DISK INFORMATION
398 cmd[7] = dataLen >> 8;
399 cmd[8] = dataLen;
400
401 if (sendCmd(cmd, 10, NULL, 0, data, dataLen) != 0) {
402 log_message(-2, "Cannot retrieve disk information.");
403 return 1;
404 }
405
406 leadInStart_ = Msf(data[17], data[18], data[19]);
407
408 if (leadInStart_.lba() >= Msf(80, 0, 0).lba()) {
409 leadInLen_ = 450000 - leadInStart_.lba();
410
411 if (fullBurn_) {
412 leadOutLen_ = (userCapacity_ ? Msf(userCapacity_, 0, 0).lba() : diskInfo_.capacity) + Msf(1, 30, 0).lba() - toc_->length().lba() - diskInfo_.thisSessionLba - 150; // Fill all rest space <vladux>
413 if (leadOutLen_ < Msf(1, 30, 0).lba()) {
414 leadOutLen_ = Msf(1, 30, 0).lba(); // 90 seconds lead-out
415 }
416 } else {
417 leadOutLen_ = Msf(1, 30, 0).lba(); // 90 seconds lead-out
418 }
419 }
420 else {
421 leadInLen_ = Msf(1, 0, 0).lba();
422 leadOutLen_ = Msf(0, 30, 0).lba();
423 }
424
425
426 log_message(4, "Lead-in start: %s length: %ld", leadInStart_.str(),
427 leadInLen_);
428 log_message(4, "Lead-out length: %ld", leadOutLen_);
429
430 return 0;
431 }
432
readBufferCapacity(long * capacity,long * available)433 bool GenericMMC::readBufferCapacity(long *capacity, long *available)
434 {
435 unsigned char cmd[10];
436 unsigned char data[12];
437 long bufsize;
438
439 memset(cmd, 0, 10);
440 memset(data, 0, 12);
441
442 cmd[0] = 0x5c; // READ BUFFER CAPACITY
443 cmd[8] = 12;
444
445 if (sendCmd(cmd, 10, NULL, 0, data, 12) != 0) {
446 log_message(-2, "Read buffer capacity failed.");
447 return false;
448 }
449
450 *capacity = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
451 *available = (data[8] << 24) | (data[9] << 16) | (data[10] << 8) | data[11];
452
453 return true;
454 }
455
performPowerCalibration()456 int GenericMMC::performPowerCalibration()
457 {
458 unsigned char cmd[10];
459 int ret;
460 long old_timeout;
461
462 memset(cmd, 0, 10);
463
464 cmd[0] = 0x54; // SEND OPC INFORMATION
465 cmd[1] = 1;
466
467 log_message(2, "Executing power calibration...");
468
469 old_timeout = scsiIf_->timeout(30);
470 ret = sendCmd(cmd, 10, NULL, 0, NULL, 0);
471 (void)scsiIf_->timeout(old_timeout);
472
473 if (ret == 0) {
474 log_message(2, "Power calibration successful.");
475 return 0;
476 }
477 if (ret == 2) {
478 const unsigned char *sense;
479 int senseLen;
480
481 sense = scsiIf_->getSense(senseLen);
482
483 if (senseLen >= 14 && (sense[2] & 0x0f) == 0x5 && sense[7] >= 6 &&
484 sense[12] == 0x20 && sense[13] == 0x0) {
485 log_message(2, "Power calibration not supported.");
486 return 0;
487 } /* else fall trough */
488 }
489 log_message(-2, "Power calibration failed.");
490 return 1;
491 }
492
493 // Sets write parameters via mode page 0x05.
494 // return: 0: OK
495 // 1: scsi command failed
setWriteParameters(unsigned long variant)496 int GenericMMC::setWriteParameters(unsigned long variant)
497 {
498 unsigned char mp[0x38];
499 unsigned char mpHeader[8];
500 unsigned char blockDesc[8];
501
502 if (getModePage(5/*write parameters mode page*/, mp, 0x38,
503 mpHeader, blockDesc, 1) != 0) {
504 log_message(-2, "Cannot retrieve write parameters mode page.");
505 return 1;
506 }
507
508 mp[0] &= 0x7f; // clear PS flag
509
510 mp[2] &= 0xe0;
511 mp[2] |= 0x02; // write type: Session-at-once
512 if (simulate_) {
513 mp[2] |= 1 << 4; // test write
514 }
515
516 const DriveInfo *di;
517 if ((di = driveInfo(true)) != NULL) {
518 if (di->burnProof) {
519 // This drive has BURN-Proof function.
520 // Enable it unless explicitly disabled.
521 if (bufferUnderRunProtection()) {
522 log_message(2, "Turning BURN-Proof on");
523 mp[2] |= 0x40;
524 }
525 else {
526 log_message(2, "Turning BURN-Proof off");
527 mp[2] &= ~0x40;
528 }
529 }
530
531 RicohSetWriteOptions(di);
532 }
533
534 mp[3] &= 0x3f; // Multi-session: No B0 pointer, next session not allowed
535
536 if (multiSession_)
537 mp[3] |= 0x03 << 6; // open next session
538 else if (!diskInfo_.empty)
539 mp[3] |= 0x01 << 6; // use B0=FF:FF:FF when closing last session of a
540 // multi session CD-R
541
542 log_message(4, "Multi session mode: %d", mp[3] >> 6);
543
544 mp[4] &= 0xf0; // Data Block Type: raw data, block size: 2352 (I think not
545 // used for session at once writing)
546
547 if (cdTextEncoder_ != NULL) {
548 if ((variant & WMP_VAR_CDTEXT_NO_DATA_BLOCK_TYPE) == 0)
549 mp[4] |= 3; /* Data Block Type: raw data with raw P-W sub-channel data,
550 block size 2448, required for CD-TEXT lead-in writing
551 according to the SCSI/MMC-3 manual
552 */
553 }
554
555 log_message(4, "Data block type: %u", mp[4] & 0x0f);
556
557 mp[8] = sessionFormat();
558
559 if (!diskInfo_.empty) {
560 // use the toc type of the already recorded sessions
561 switch (diskInfo_.diskTocType) {
562 case 0x00:
563 case 0x10:
564 case 0x20:
565 mp[8] = diskInfo_.diskTocType;
566 break;
567 }
568 }
569
570 log_message(4, "Toc type: 0x%x", mp[8]);
571
572 if (setModePage(mp, mpHeader, NULL, 0) != 0) {
573 log_message(-2, "Cannot set write parameters mode page.");
574 return 1;
575 }
576
577 return 0;
578 }
579
580 // Sets simulation mode via mode page 0x05.
581 // return: 0: OK
582 // 1: scsi command failed
setSimulationMode(int showMessage)583 int GenericMMC::setSimulationMode(int showMessage)
584 {
585 unsigned char mp[0x38];
586 unsigned char mpHeader[8];
587
588 if (getModePage(5/*write parameters mode page*/, mp, 0x38,
589 mpHeader, NULL, showMessage) != 0) {
590 if (showMessage)
591 log_message(-2, "Cannot retrieve write parameters mode page.");
592 return 1;
593 }
594
595 mp[0] &= 0x7f; // clear PS flag
596
597 if (simulate_)
598 mp[2] |= 1 << 4; // test write
599 else
600 mp[2] &= ~(1 << 4);
601
602 if (setModePage(mp, mpHeader, NULL, showMessage) != 0) {
603 if (showMessage)
604 log_message(-2, "Cannot set write parameters mode page.");
605 return 1;
606 }
607
608 return 0;
609 }
610
getNWA(long * nwa)611 int GenericMMC::getNWA(long *nwa)
612 {
613 unsigned char cmd[10];
614 int infoblocklen = 16;
615 unsigned char info[16];
616 long lba = 0;
617
618 cmd[0] = 0x52; // READ TRACK INFORMATION
619 cmd[1] = 0x01; // track instead of lba designation
620 cmd[2] = 0x00;
621 cmd[3] = 0x00;
622 cmd[4] = 0x00;
623 cmd[5] = 0xff; // invisible track
624 cmd[6] = 0x00; // reserved
625 cmd[7] = infoblocklen << 8;
626 cmd[8] = infoblocklen; // alloc length
627 cmd[9] = 0x00; // Control Byte
628
629 if (sendCmd(cmd, 10, NULL, 0, info, infoblocklen) != 0) {
630 log_message(-2, "Cannot get Track Information Block.");
631 return 1;
632 }
633
634 #if 0
635 log_message(3,"Track Information Block");
636 for (int i=0;i<infoblocklen;i++) log_message(3,"byte %02x : %02x",i,info[i]);
637 #endif
638
639 if ((info[6] & 0x40) && (info[7] & 0x01) && !(info[6] & 0xb0))
640 {
641 log_message(4,"Track is Blank, Next Writable Address is valid");
642 lba |= info[12] << 24; // MSB of LBA
643 lba |= info[13] << 16;
644 lba |= info[14] << 8;
645 lba |= info[15]; // LSB of LBA
646 }
647
648 log_message(4, "NWA: %ld", lba);
649
650 if (nwa != NULL)
651 *nwa = lba;
652
653 return 0;
654 }
655
656 // Determines first writable address of data area of current empty session.
657 // lba: set to start of data area
658 // return: 0: OK
659 // 1: error occured
getStartOfSession(long * lba)660 int GenericMMC::getStartOfSession(long *lba)
661 {
662 unsigned char mp[0x38];
663 unsigned char mpHeader[8];
664
665 // first set the writing mode because it influences which address is
666 // returned with 'READ TRACK INFORMATION'
667
668 if (getModePage(5/*write parameters mode page*/, mp, 0x38,
669 mpHeader, NULL, 0) != 0) {
670 return 1;
671 }
672
673 mp[0] &= 0x7f; // clear PS flag
674
675 mp[2] &= 0xe0;
676 mp[2] |= 0x02; // write type: Session-at-once
677
678 if (setModePage(mp, mpHeader, NULL, 1) != 0) {
679 log_message(-2, "Cannot set write parameters mode page.");
680 return 1;
681 }
682
683 return getNWA(lba);
684 }
685
leadInOutDataMode(TrackData::Mode mode)686 static unsigned char leadInOutDataMode(TrackData::Mode mode)
687 {
688 unsigned char ret = 0;
689
690 switch (mode) {
691 case TrackData::AUDIO:
692 ret = 0x01;
693 break;
694
695 case TrackData::MODE0: // should not happen
696 case TrackData::MODE1:
697 case TrackData::MODE1_RAW:
698 ret = 0x14;
699 break;
700
701 case TrackData::MODE2_FORM1:
702 case TrackData::MODE2_FORM2:
703 case TrackData::MODE2_FORM_MIX:
704 case TrackData::MODE2_RAW: // assume it contains XA sectors
705 ret = 0x24;
706 break;
707
708 case TrackData::MODE2:
709 ret = 0x34;
710 break;
711 }
712
713 return ret;
714 }
715
716
subChannelDataForm(TrackData::SubChannelMode sm,int encodingMode)717 unsigned char GenericMMC::subChannelDataForm(TrackData::SubChannelMode sm,
718 int encodingMode)
719 {
720 unsigned char ret = 0;
721
722 switch (sm) {
723 case TrackData::SUBCHAN_NONE:
724 break;
725
726 case TrackData::SUBCHAN_RW:
727 case TrackData::SUBCHAN_RW_RAW:
728 if (encodingMode == 0)
729 ret = 0xc0;
730 else
731 ret = 0x40;
732 break;
733 }
734
735 return ret;
736 }
737
738
739 // Creates cue sheet for current toc.
740 // cueSheetLen: filled with length of cue sheet in bytes
741 // return: newly allocated cue sheet buffer or 'NULL' on error
createCueSheet(unsigned long variant,long * cueSheetLen)742 unsigned char *GenericMMC::createCueSheet(unsigned long variant,
743 long *cueSheetLen)
744 {
745 const Track *t;
746 int trackNr;
747 Msf start, end, index;
748 unsigned char *cueSheet;
749 long len = 3; // entries for lead-in, gap, lead-out
750 long n; // index into cue sheet
751 unsigned char ctl; // control nibbles of cue sheet entry CTL/ADR
752 long i;
753 unsigned char dataMode;
754 int trackOffset;
755 long lbaOffset;
756
757 if (!diskInfo_.empty && diskInfo_.append) {
758 if (toc_->firstTrackNo() != 0 && toc_->firstTrackNo() != diskInfo_.lastTrackNr + 1) {
759 log_message(-2, "Number of first track doesn't match");
760 return NULL;
761 }
762 #if 0
763 /* for progress message */
764 toc_->firstTrackNo(diskInfo_.lastTrackNr + 1);
765 #endif
766 trackOffset = diskInfo_.lastTrackNr;
767 lbaOffset = diskInfo_.thisSessionLba;
768 } else {
769 trackOffset = toc_->firstTrackNo() == 0 ? 0 : toc_->firstTrackNo() - 1;
770 lbaOffset = 0;
771 }
772 if (trackOffset + toc_->nofTracks() > 99) {
773 log_message(-2, "Track numbers too large");
774 return NULL;
775 }
776
777 TrackIterator itr(toc_);
778
779 if (itr.first(start, end) == NULL) {
780 return NULL;
781 }
782
783 if (toc_->catalogValid()) {
784 len += 2;
785 }
786
787 for (t = itr.first(start, end), trackNr = 1;
788 t != NULL; t = itr.next(start, end), trackNr++) {
789 len += 1; // entry for track
790 if (t->start().lba() != 0 && trackNr > 1) {
791 len += 1; // entry for pre-gap
792 }
793 if (t->type() == TrackData::AUDIO && t->isrcValid()) {
794 len += 2; // entries for ISRC code
795 }
796 len += t->nofIndices(); // entry for each index increment
797 }
798
799 cueSheet = new unsigned char[len * 8];
800 n = 0;
801
802 if (toc_->leadInMode() == TrackData::AUDIO) {
803 ctl = 0;
804 }
805 else {
806 ctl = 0x40;
807 }
808
809 if (toc_->catalogValid()) {
810 // fill catalog number entry
811 cueSheet[n*8] = 0x02 | ctl;
812 cueSheet[(n+1)*8] = 0x02 | ctl;
813 for (i = 1; i <= 13; i++) {
814 if (i < 8) {
815 cueSheet[n*8 + i] = toc_->catalog(i-1) + '0';
816 }
817 else {
818 cueSheet[(n+1)*8 + i - 7] = toc_->catalog(i-1) + '0';
819 }
820 }
821 cueSheet[(n+1)*8+7] = 0;
822 n += 2;
823 }
824
825 // entry for lead-in
826 cueSheet[n*8] = 0x01 | ctl; // CTL/ADR
827 cueSheet[n*8+1] = 0; // Track number
828 cueSheet[n*8+2] = 0; // Index
829
830 if (cdTextEncoder_ != NULL) {
831 cueSheet[n*8+3] = 0x41; // Data Form: CD-DA with P-W sub-channels,
832 // main channel data generated by device
833 }
834 else {
835 cueSheet[n*8+3] = leadInOutDataMode(toc_->leadInMode());
836 }
837
838 cueSheet[n*8+4] = 0; // Serial Copy Management System
839
840 if (cdTextEncoder_ != NULL &&
841 (variant & CUE_VAR_CDTEXT_NO_TIME) == 0) {
842 cueSheet[n*8+5] = leadInStart_.min();
843 cueSheet[n*8+6] = leadInStart_.sec();
844 cueSheet[n*8+7] = leadInStart_.frac();
845 }
846 else {
847 cueSheet[n*8+5] = 0; // MIN
848 cueSheet[n*8+6] = 0; // SEC
849 cueSheet[n*8+7] = 0; // FRAME
850 }
851
852 n++;
853
854 int firstTrack = 1;
855
856 for (t = itr.first(start, end), trackNr = trackOffset + 1;
857 t != NULL;
858 t = itr.next(start, end), trackNr++) {
859 if (encodingMode_ == 0) {
860 // just used for some experiments with raw writing
861 dataMode = 0;
862 }
863 else {
864 switch (t->type()) {
865 case TrackData::AUDIO:
866 dataMode = 0;
867 break;
868 case TrackData::MODE1:
869 case TrackData::MODE1_RAW:
870 dataMode = 0x10;
871 break;
872 case TrackData::MODE2:
873 dataMode = 0x30;
874 break;
875 case TrackData::MODE2_RAW: // assume it contains XA sectors
876 case TrackData::MODE2_FORM1:
877 case TrackData::MODE2_FORM2:
878 case TrackData::MODE2_FORM_MIX:
879 dataMode = 0x20;
880 break;
881 default:
882 dataMode = 0;
883 break;
884 }
885 }
886
887 // add mode for sub-channel writing
888 dataMode |= subChannelDataForm(t->subChannelType(),
889 subChannelEncodingMode(t->subChannelType()));
890
891 ctl = 0;
892 if (t->copyPermitted()) {
893 ctl |= 0x20;
894 }
895
896 if (t->type() == TrackData::AUDIO) {
897 // audio track
898 if (t->preEmphasis()) {
899 ctl |= 0x10;
900 }
901 if (t->audioType() == 1) {
902 ctl |= 0x80;
903 }
904
905 if (t->isrcValid()) {
906 if ((variant & CUE_VAR_ISRC_NO_CTL) == 0)
907 cueSheet[n*8] = ctl | 0x03;
908 else
909 cueSheet[n*8] = 0x03;
910
911 cueSheet[n*8+1] = trackNr;
912 cueSheet[n*8+2] = t->isrcCountry(0);
913 cueSheet[n*8+3] = t->isrcCountry(1);
914 cueSheet[n*8+4] = t->isrcOwner(0);
915 cueSheet[n*8+5] = t->isrcOwner(1);
916 cueSheet[n*8+6] = t->isrcOwner(2);
917 cueSheet[n*8+7] = t->isrcYear(0) + '0';
918 n++;
919
920 if ((variant & CUE_VAR_ISRC_NO_CTL) == 0)
921 cueSheet[n*8] = ctl | 0x03;
922 else
923 cueSheet[n*8] = 0x03;
924
925 cueSheet[n*8+1] = trackNr;
926 cueSheet[n*8+2] = t->isrcYear(1) + '0';
927 cueSheet[n*8+3] = t->isrcSerial(0) + '0';
928 cueSheet[n*8+4] = t->isrcSerial(1) + '0';
929 cueSheet[n*8+5] = t->isrcSerial(2) + '0';
930 cueSheet[n*8+6] = t->isrcSerial(3) + '0';
931 cueSheet[n*8+7] = t->isrcSerial(4) + '0';
932 n++;
933 }
934 }
935 else {
936 // data track
937 ctl |= 0x40;
938 }
939
940
941 if (firstTrack) {
942 Msf sessionStart(lbaOffset);
943
944 // entry for gap before first track
945 cueSheet[n*8] = ctl | 0x01;
946 cueSheet[n*8+1] = trackNr;
947 cueSheet[n*8+2] = 0; // Index 0
948 cueSheet[n*8+3] = dataMode; // Data Form
949 cueSheet[n*8+4] = 0; // Serial Copy Management System
950 cueSheet[n*8+5] = sessionStart.min();
951 cueSheet[n*8+6] = sessionStart.sec();
952 cueSheet[n*8+7] = sessionStart.frac();
953 n++;
954 }
955 else if (t->start().lba() != 0) {
956 // entry for pre-gap
957 Msf pstart(lbaOffset + start.lba() - t->start().lba() + 150);
958
959 cueSheet[n*8] = ctl | 0x01;
960 cueSheet[n*8+1] = trackNr;
961 cueSheet[n*8+2] = 0; // Index 0 indicates pre-gap
962 cueSheet[n*8+3] = dataMode; // Data Form
963 cueSheet[n*8+4] = 0; // no alternate copy bit
964 cueSheet[n*8+5] = pstart.min();
965 cueSheet[n*8+6] = pstart.sec();
966 cueSheet[n*8+7] = pstart.frac();
967 n++;
968 }
969
970 Msf tstart(lbaOffset + start.lba() + 150);
971
972 cueSheet[n*8] = ctl | 0x01;
973 cueSheet[n*8+1] = trackNr;
974 cueSheet[n*8+2] = 1; // Index 1
975 cueSheet[n*8+3] = dataMode; // Data Form
976 cueSheet[n*8+4] = 0; // no alternate copy bit
977 cueSheet[n*8+5] = tstart.min();
978 cueSheet[n*8+6] = tstart.sec();
979 cueSheet[n*8+7] = tstart.frac();
980 n++;
981
982 for (i = 0; i < t->nofIndices(); i++) {
983 index = tstart + t->getIndex(i);
984 cueSheet[n*8] = ctl | 0x01;
985 cueSheet[n*8+1] = trackNr;
986 cueSheet[n*8+2] = i+2; // Index
987 cueSheet[n*8+3] = dataMode; // Data Form
988 cueSheet[n*8+4] = 0; // no alternate copy bit
989 cueSheet[n*8+5] = index.min();
990 cueSheet[n*8+6] = index.sec();
991 cueSheet[n*8+7] = index.frac();
992 n++;
993 }
994
995 firstTrack = 0;
996 }
997
998 assert(n == len - 1);
999
1000 // entry for lead out
1001 Msf lostart(lbaOffset + toc_->length().lba() + 150);
1002 ctl = toc_->leadOutMode() == TrackData::AUDIO ? 0 : 0x40;
1003
1004 cueSheet[n*8] = ctl | 0x01;
1005 cueSheet[n*8+1] = 0xaa;
1006 cueSheet[n*8+2] = 1; // Index 1
1007 cueSheet[n*8+3] = leadInOutDataMode(toc_->leadOutMode());
1008 cueSheet[n*8+4] = 0; // no alternate copy bit
1009 cueSheet[n*8+5] = lostart.min();
1010 cueSheet[n*8+6] = lostart.sec();
1011 cueSheet[n*8+7] = lostart.frac();
1012
1013 log_message(3, "\nCue Sheet (variant %lx):", variant);
1014 log_message(3, "CTL/ TNO INDEX DATA SCMS MIN SEC FRAME");
1015 log_message(3, "ADR FORM");
1016 for (n = 0; n < len; n++) {
1017 log_message(3, "%02x %02x %02x %02x %02x %02d %02d %02d",
1018 cueSheet[n*8],
1019 cueSheet[n*8+1], cueSheet[n*8+2], cueSheet[n*8+3], cueSheet[n*8+4],
1020 cueSheet[n*8+5], cueSheet[n*8+6], cueSheet[n*8+7]);
1021 }
1022
1023 *cueSheetLen = len * 8;
1024 return cueSheet;
1025 }
1026
sendCueSheet()1027 int GenericMMC::sendCueSheet()
1028 {
1029 unsigned char cmd[10];
1030 long cueSheetLen;
1031 unsigned long variant;
1032 unsigned char *cueSheet;
1033 int cueSheetSent = 0;
1034
1035 for (variant = 0; variant <= CUE_VAR_MAX; variant++) {
1036
1037 if (cdTextEncoder_ == NULL &&
1038 (variant & CUE_VAR_CDTEXT_NO_TIME) != 0) {
1039 // skip CD-TEXT variants if no CD-TEXT has to be written
1040 continue;
1041 }
1042
1043 cueSheet = createCueSheet(variant, &cueSheetLen);
1044
1045 if (cueSheet != NULL) {
1046 memset(cmd, 0, 10);
1047
1048 cmd[0] = 0x5d; // SEND CUE SHEET
1049
1050 cmd[6] = cueSheetLen >> 16;
1051 cmd[7] = cueSheetLen >> 8;
1052 cmd[8] = cueSheetLen;
1053
1054 if (sendCmd(cmd, 10, cueSheet, cueSheetLen, NULL, 0, 0) != 0) {
1055 delete[] cueSheet;
1056 }
1057 else {
1058 log_message(3, "Drive accepted cue sheet variant %lx.", variant);
1059 delete[] cueSheet;
1060 cueSheetSent = 1;
1061 break;
1062 }
1063 }
1064 }
1065
1066 if (cueSheetSent) {
1067 return 0;
1068 }
1069 else {
1070 log_message(-2,
1071 "Drive does not accept any cue sheet variant - please report.");
1072 return 1;
1073 }
1074 }
1075
initDao(const Toc * toc)1076 int GenericMMC::initDao(const Toc *toc)
1077 {
1078 long n;
1079 blockLength_ = AUDIO_BLOCK_LEN + MAX_SUBCHANNEL_LEN;
1080 blocksPerWrite_ = scsiIf_->maxDataLen() / blockLength_;
1081
1082 assert(blocksPerWrite_ > 0);
1083
1084 toc_ = toc;
1085
1086 if (options_ & OPT_MMC_CD_TEXT) {
1087 delete cdTextEncoder_;
1088 cdTextEncoder_ = new CdTextEncoder(toc_);
1089 if (cdTextEncoder_->encode() != 0) {
1090 log_message(-2, "CD-TEXT encoding failed.");
1091 return 1;
1092 }
1093
1094 if (cdTextEncoder_->getSubChannels(&n) == NULL || n == 0) {
1095 delete cdTextEncoder_;
1096 cdTextEncoder_ = NULL;
1097 }
1098
1099 //return 1;
1100 }
1101
1102 diskInfo();
1103
1104 if (!diskInfo_.valid.empty || !diskInfo_.valid.append) {
1105 log_message(-2, "Cannot determine status of inserted medium.");
1106 return 1;
1107 }
1108
1109 if (!diskInfo_.append) {
1110 log_message(-2, "Inserted medium is not appendable.");
1111 return 1;
1112 }
1113
1114 if ((!diskInfo_.empty && diskInfo_.append) && toc_->firstTrackNo() != 0 ) {
1115 log_message(-1, "Cannot choose number of first track in append mode.");
1116 return 1;
1117 }
1118
1119 if (selectSpeed() != 0 ||
1120 getSessionInfo() != 0) {
1121 return 1;
1122 }
1123
1124
1125 // allocate buffer for writing zeros
1126 n = blocksPerWrite_ * blockLength_;
1127 delete[] zeroBuffer_;
1128 zeroBuffer_ = new char[n];
1129 memset(zeroBuffer_, 0, n);
1130
1131 return 0;
1132 }
1133
startDao()1134 int GenericMMC::startDao()
1135 {
1136 unsigned long variant;
1137 int writeParametersSet = 0;
1138
1139 scsiTimeout_ = scsiIf_->timeout(3 * 60);
1140
1141 for (variant = 0; variant <= WMP_VAR_MAX; variant++) {
1142 if (cdTextEncoder_ == NULL &&
1143 (variant & WMP_VAR_CDTEXT_NO_DATA_BLOCK_TYPE) != 0) {
1144 // skip CD-TEXT variants if no CD-TEXT has to be written
1145 continue;
1146 }
1147
1148 if (setWriteParameters(variant) == 0) {
1149 log_message(3, "Drive accepted write parameter mode page variant %lx.",
1150 variant);
1151 writeParametersSet = 1;
1152 break;
1153 }
1154 }
1155
1156 if (!writeParametersSet) {
1157 log_message(-2, "Cannot setup write parameters for session-at-once mode.");
1158 log_message(-2, "Please try to use the 'generic-mmc-raw' driver.");
1159 return 1;
1160 }
1161
1162 if (!simulate_) {
1163 if (performPowerCalibration() != 0) {
1164 if (!force()) {
1165 log_message(-2, "Use option --force to ignore this error.");
1166 return 1;
1167 }
1168 else {
1169 log_message(-2, "Ignored because of option --force.");
1170 }
1171 }
1172 }
1173
1174 // It does not hurt if the following command fails.
1175 // The Panasonic CW-7502 needs it, unfortunately it returns the wrong
1176 // data so we ignore the returned data and start writing always with
1177 // LBA -150.
1178 getNWA(NULL);
1179
1180 if (sendCueSheet() != 0)
1181 return 1;
1182
1183 //log_message(2, "Writing lead-in and gap...");
1184
1185 if (writeCdTextLeadIn() != 0) {
1186 return 1;
1187 }
1188
1189
1190 long lba = diskInfo_.thisSessionLba - 150;
1191
1192 TrackData::Mode mode = TrackData::AUDIO;
1193 TrackData::SubChannelMode subChanMode = TrackData::SUBCHAN_NONE;
1194 TrackIterator itr(toc_);
1195 const Track *tr;
1196
1197 if ((tr = itr.first()) != NULL) {
1198 mode = tr->type();
1199 subChanMode = tr->subChannelType();
1200 }
1201
1202 if (writeZeros(mode, subChanMode, lba, lba + 150, 150) != 0) {
1203 return 1;
1204 }
1205
1206 return 0;
1207 }
1208
finishDao()1209 int GenericMMC::finishDao()
1210 {
1211 int ret;
1212
1213 flushCache(); /* Some drives never return to a ready state after writing
1214 * the lead-out. This is a try to solve this problem.
1215 */
1216
1217 while ((ret = checkDriveReady()) == 2) {
1218 mSleep(2000);
1219 }
1220
1221 if (ret != 0)
1222 log_message(-1, "TEST UNIT READY failed after recording.");
1223
1224 log_message(2, "Flushing cache...");
1225
1226 if (flushCache() != 0) {
1227 return 1;
1228 }
1229
1230 scsiIf_->timeout(scsiTimeout_);
1231
1232 delete cdTextEncoder_;
1233 cdTextEncoder_ = NULL;
1234
1235 delete[] zeroBuffer_, zeroBuffer_ = NULL;
1236
1237 return 0;
1238 }
1239
abortDao()1240 void GenericMMC::abortDao()
1241 {
1242 flushCache();
1243
1244 delete cdTextEncoder_;
1245 cdTextEncoder_ = NULL;
1246 }
1247
1248 // Writes data to target, the block length depends on the actual writing
1249 // 'mode'. 'len' is number of blocks to write.
1250 // 'lba' specifies the next logical block address for writing and is updated
1251 // by this function.
1252 // return: 0: OK
1253 // 1: scsi command failed
writeData(TrackData::Mode mode,TrackData::SubChannelMode sm,long & lba,const char * buf,long len)1254 int GenericMMC::writeData(TrackData::Mode mode, TrackData::SubChannelMode sm,
1255 long &lba, const char *buf, long len)
1256 {
1257 assert(blocksPerWrite_ > 0);
1258 int writeLen = 0;
1259 unsigned char cmd[10];
1260 long blockLength = blockSize(mode, sm);
1261 int retry;
1262 int ret;
1263
1264 #if 0
1265 long bufferCapacity;
1266 int waitForBuffer;
1267 int speedFrac;
1268
1269 if (speed_ > 0)
1270 speedFrac = 75 * speed_;
1271 else
1272 speedFrac = 75 * 10; // adjust this value when the first >10x burner is out
1273 #endif
1274
1275 #if 0
1276 long sum, i;
1277
1278 sum = 0;
1279
1280 for (i = 0; i < len * blockLength; i++) {
1281 sum += buf[i];
1282 }
1283
1284 log_message(0, "W: %ld: %ld, %ld, %ld", lba, blockLength, len, sum);
1285 #endif
1286
1287 memset(cmd, 0, 10);
1288 cmd[0] = 0x2a; // WRITE1
1289
1290 while (len > 0) {
1291 writeLen = (len > blocksPerWrite_ ? blocksPerWrite_ : len);
1292
1293 cmd[2] = lba >> 24;
1294 cmd[3] = lba >> 16;
1295 cmd[4] = lba >> 8;
1296 cmd[5] = lba;
1297
1298 cmd[7] = writeLen >> 8;
1299 cmd[8] = writeLen & 0xff;
1300
1301 #if 0
1302 do {
1303 long available
1304 waitForBuffer = 0;
1305
1306 if (readBufferCapacity(&bufferCapacity, &available) == 0) {
1307 //log_message(0, "Buffer Capacity: %ld", bufferCapacity);
1308 if (bufferCapacity < writeLen * blockLength) {
1309 long t = 1000 * writeLen;
1310 t /= speedFrac;
1311 if (t <= 0)
1312 t = 1;
1313
1314 log_message(0, "Waiting for %ld msec at lba %ld", t, lba);
1315
1316 mSleep(t);
1317 waitForBuffer = 1;
1318 }
1319 }
1320 } while (waitForBuffer);
1321 #endif
1322
1323 do {
1324 retry = 0;
1325
1326 ret = sendCmd(cmd, 10, (unsigned char *)buf, writeLen * blockLength,
1327 NULL, 0, 0);
1328
1329 if(ret == 2) {
1330 const unsigned char *sense;
1331 int senseLen;
1332
1333 sense = scsiIf_->getSense(senseLen);
1334
1335 // check if drive rejected the command because the internal buffer
1336 // is filled
1337 if(senseLen >= 14 && (sense[2] & 0x0f) == 0x2 && sense[7] >= 6 &&
1338 sense[12] == 0x4 && sense[13] == 0x8) {
1339 // Not Ready, long write in progress
1340 mSleep(40);
1341 retry = 1;
1342 }
1343 else {
1344 scsiIf_->printError();
1345 }
1346 }
1347 } while (retry);
1348
1349 if (ret != 0) {
1350 log_message(-2, "Write data failed.");
1351 return 1;
1352 }
1353
1354 buf += writeLen * blockLength;
1355
1356 lba += writeLen;
1357 len -= writeLen;
1358 }
1359
1360 return 0;
1361 }
1362
writeCdTextLeadIn()1363 int GenericMMC::writeCdTextLeadIn()
1364 {
1365 unsigned char cmd[10];
1366 const PWSubChannel96 **cdTextSubChannels;
1367 long cdTextSubChannelCount;
1368 long channelsPerCmd;
1369 long scp = 0;
1370 long lba = -150 - leadInLen_;
1371 long len = leadInLen_;
1372 long n;
1373 long i;
1374 int retry;
1375 int ret;
1376 unsigned char *p;
1377
1378 if (cdTextEncoder_ == NULL)
1379 return 0;
1380
1381 channelsPerCmd = scsiIf_->maxDataLen() / 96;
1382
1383 cdTextSubChannels = cdTextEncoder_->getSubChannels(&cdTextSubChannelCount);
1384
1385 assert(channelsPerCmd > 0);
1386 assert(cdTextSubChannels != NULL);
1387 assert(cdTextSubChannelCount > 0);
1388
1389 log_message(2, "Writing CD-TEXT lead-in...");
1390
1391 log_message(4, "Start LBA: %ld, length: %ld", lba, len);
1392
1393 memset(cmd, 0, 10);
1394 cmd[0] = 0x2a; // WRITE1
1395
1396 while (len > 0) {
1397 n = (len > channelsPerCmd) ? channelsPerCmd : len;
1398
1399 cmd[2] = lba >> 24;
1400 cmd[3] = lba >> 16;
1401 cmd[4] = lba >> 8;
1402 cmd[5] = lba;
1403
1404 cmd[7] = n >> 8;
1405 cmd[8] = n;
1406
1407 p = transferBuffer_;
1408
1409 for (i = 0; i < n; i++) {
1410 memcpy(p, cdTextSubChannels[scp]->data(), 96);
1411 p += 96;
1412
1413 scp++;
1414 if (scp >= cdTextSubChannelCount)
1415 scp = 0;
1416 }
1417
1418 log_message(5, "Writing %ld CD-TEXT sub-channels at LBA %ld.", n, lba);
1419
1420 do {
1421 retry = 0;
1422
1423 ret = sendCmd(cmd, 10, transferBuffer_, n * 96, NULL, 0, 0);
1424
1425 if(ret == 2) {
1426 const unsigned char *sense;
1427 int senseLen;
1428
1429 sense = scsiIf_->getSense(senseLen);
1430
1431 // check if drive rejected the command because the internal buffer
1432 // is filled
1433 if(senseLen >= 14 && (sense[2] & 0x0f) == 0x2 && sense[7] >= 6 &&
1434 sense[12] == 0x4 && sense[13] == 0x8) {
1435 // Not Ready, long write in progress
1436 mSleep(40);
1437 retry = 1;
1438 }
1439 else {
1440 scsiIf_->printError();
1441 }
1442 }
1443 } while (retry);
1444
1445 if (ret != 0) {
1446 log_message(-2, "Writing of CD-TEXT data failed.");
1447 return 1;
1448 }
1449
1450
1451 len -= n;
1452 lba += n;
1453 }
1454
1455 return 0;
1456 }
1457
diskInfo()1458 DiskInfo *GenericMMC::diskInfo()
1459 {
1460 unsigned char cmd[10];
1461 unsigned long dataLen = 34;
1462 unsigned char data[34];
1463 char spd;
1464
1465 memset(&diskInfo_, 0, sizeof(DiskInfo));
1466
1467 // perform READ DISK INFORMATION
1468 memset(cmd, 0, 10);
1469 memset(data, 0, dataLen);
1470
1471 cmd[0] = 0x51; // READ DISK INFORMATION
1472 cmd[7] = dataLen >> 8;
1473 cmd[8] = dataLen;
1474
1475 if (sendCmd(cmd, 10, NULL, 0, data, dataLen, 0) == 0) {
1476 diskInfo_.cdrw = (data[2] & 0x10) ? 1 : 0;
1477 diskInfo_.valid.cdrw = 1;
1478
1479 switch (data[2] & 0x03) {
1480 case 0:
1481 // disc is empty
1482 diskInfo_.empty = 1;
1483 diskInfo_.append = 1;
1484
1485 diskInfo_.manufacturerId = Msf(data[17], data[18], data[19]);
1486 diskInfo_.valid.manufacturerId = 1;
1487 break;
1488
1489 case 1:
1490 // disc is not empty but appendable
1491 diskInfo_.sessionCnt = data[4];
1492 diskInfo_.lastTrackNr = data[6];
1493
1494 diskInfo_.diskTocType = data[8];
1495
1496 switch ((data[2] >> 2) & 0x03) {
1497 case 0:
1498 // last session is empty
1499 diskInfo_.append = 1;
1500
1501 // don't count the empty session and invisible track
1502 diskInfo_.sessionCnt -= 1;
1503 diskInfo_.lastTrackNr -= 1;
1504
1505 if (getStartOfSession(&(diskInfo_.thisSessionLba)) == 0) {
1506 // reserve space for pre-gap after lead-in
1507 diskInfo_.thisSessionLba += 150;
1508 }
1509 else {
1510 // try to guess start of data area from start of lead-in
1511 // reserve space for 4500 lead-in and 150 pre-gap sectors
1512 diskInfo_.thisSessionLba = Msf(data[17], data[18],
1513 data[19]).lba() - 150 + 4650;
1514 }
1515 break;
1516
1517 case 1:
1518 // last session is incomplete (not fixated)
1519 // we cannot append in DAO mode, just update the statistic data
1520
1521 diskInfo_.diskTocType = data[8];
1522
1523 // don't count the invisible track
1524 diskInfo_.lastTrackNr -= 1;
1525 break;
1526 }
1527 break;
1528
1529 case 2:
1530 // disk is complete
1531 diskInfo_.sessionCnt = data[4];
1532 diskInfo_.lastTrackNr = data[6];
1533 diskInfo_.diskTocType = data[8];
1534 break;
1535 }
1536
1537 diskInfo_.valid.empty = 1;
1538 diskInfo_.valid.append = 1;
1539
1540 if (data[21] != 0xff || data[22] != 0xff || data[23] != 0xff) {
1541 diskInfo_.valid.capacity = 1;
1542 diskInfo_.capacity = Msf(data[21], data[22], data[23]).lba() - 150;
1543 }
1544 }
1545
1546 // perform READ TOC to get session info
1547 memset(cmd, 0, 10);
1548 dataLen = 12;
1549 memset(data, 0, dataLen);
1550
1551 cmd[0] = 0x43; // READ TOC
1552 cmd[2] = 1; // get session info
1553 cmd[8] = dataLen; // allocation length
1554
1555 if (sendCmd(cmd, 10, NULL, 0, data, dataLen, 0) == 0) {
1556 diskInfo_.lastSessionLba = (data[8] << 24) | (data[9] << 16) |
1557 (data[10] << 8) | data[11];
1558
1559 if (!diskInfo_.valid.empty) {
1560 diskInfo_.valid.empty = 1;
1561 diskInfo_.empty = (data[3] == 0) ? 1 : 0;
1562
1563 diskInfo_.sessionCnt = data[3];
1564 }
1565 }
1566
1567 // read ATIP data
1568 dataLen = 28;
1569 memset(cmd, 0, 10);
1570 memset(data, 0, dataLen);
1571
1572 cmd[0] = 0x43; // READ TOC/PMA/ATIP
1573 cmd[1] = 0x00;
1574 cmd[2] = 4; // get ATIP
1575 cmd[7] = 0;
1576 cmd[8] = dataLen; // data length
1577
1578 if (sendCmd(cmd, 10, NULL, 0, data, dataLen, 0) == 0) {
1579 if (data[6] & 0x04) {
1580 diskInfo_.valid.recSpeed = 1;
1581 spd = (data[16] >> 4) & 0x07;
1582 diskInfo_.recSpeedLow = spd == 1 ? 2 : 0;
1583
1584 spd = (data[16] & 0x0f);
1585 diskInfo_.recSpeedHigh = spd >= 1 && spd <= 4 ? spd * 2 : 0;
1586 }
1587
1588 if (data[8] >= 80 && data[8] <= 99) {
1589 diskInfo_.manufacturerId = Msf(data[8], data[9], data[10]);
1590 diskInfo_.valid.manufacturerId = 1;
1591 }
1592 }
1593
1594 return &diskInfo_;
1595 }
1596
1597
1598 // tries to read catalog number from disk and adds it to 'toc'
1599 // return: 1 if valid catalog number was found, else 0
readCatalog(Toc * toc,long startLba,long endLba)1600 int GenericMMC::readCatalog(Toc *toc, long startLba, long endLba)
1601 {
1602 unsigned char cmd[10];
1603 unsigned char data[24];
1604 char catalog[14];
1605 int i;
1606
1607 if (options_ & OPT_MMC_SCAN_MCN) {
1608 if (readCatalogScan(catalog, startLba, endLba) == 0) {
1609 if (catalog[0] != 0) {
1610 if (toc->catalog(catalog) == 0)
1611 return 1;
1612 else
1613 log_message(-1, "Found illegal MCN data: %s", catalog);
1614 }
1615 }
1616 }
1617 else {
1618 memset(cmd, 0, 10);
1619 memset(data, 0, 24);
1620
1621 cmd[0] = 0x42; // READ SUB-CHANNEL
1622 cmd[2] = 1 << 6;
1623 cmd[3] = 0x02; // get media catalog number
1624 cmd[8] = 24; // transfer length
1625
1626 if (sendCmd(cmd, 10, NULL, 0, data, 24) != 0) {
1627 log_message(-2, "Cannot get catalog number.");
1628 return 0;
1629 }
1630
1631 if (data[8] & 0x80) {
1632 for (i = 0; i < 13; i++) {
1633 catalog[i] = data[0x09 + i];
1634 }
1635 catalog[13] = 0;
1636
1637 if (toc->catalog(catalog) == 0) {
1638 return 1;
1639 }
1640 }
1641 }
1642
1643 return 0;
1644 }
1645
readIsrc(int trackNr,char * buf)1646 int GenericMMC::readIsrc(int trackNr, char *buf)
1647 {
1648 unsigned char cmd[10];
1649 unsigned char data[24];
1650 int i;
1651
1652 buf[0] = 0;
1653
1654 memset(cmd, 0, 10);
1655 memset(data, 0, 24);
1656
1657 cmd[0] = 0x42; // READ SUB-CHANNEL
1658 cmd[2] = 1 << 6;
1659 cmd[3] = 0x03; // get ISRC
1660 cmd[6] = trackNr;
1661 cmd[8] = 24; // transfer length
1662
1663 if (sendCmd(cmd, 10, NULL, 0, data, 24) != 0) {
1664 log_message(-2, "Cannot get ISRC code.");
1665 return 0;
1666 }
1667
1668 if (data[8] & 0x80) {
1669 for (i = 0; i < 12; i++) {
1670 buf[i] = data[0x09 + i];
1671 }
1672 buf[12] = 0;
1673 }
1674
1675 return 0;
1676 }
1677
analyzeTrack(TrackData::Mode mode,int trackNr,long startLba,long endLba,Msf * indexIncrements,int * indexIncrementCnt,long * pregap,char * isrcCode,unsigned char * ctl)1678 int GenericMMC::analyzeTrack(TrackData::Mode mode, int trackNr, long startLba,
1679 long endLba, Msf *indexIncrements,
1680 int *indexIncrementCnt, long *pregap,
1681 char *isrcCode, unsigned char *ctl)
1682 {
1683 int ret;
1684 int noScan = 0;
1685
1686 selectSpeed();
1687
1688 if ((readCapabilities_ & CDR_AUDIO_SCAN_CAP) == 0) {
1689 ret = analyzeTrackSearch(mode, trackNr, startLba, endLba, indexIncrements,
1690 indexIncrementCnt, pregap, isrcCode, ctl);
1691 noScan = 1;
1692 }
1693 else {
1694 ret = analyzeTrackScan(mode, trackNr, startLba, endLba,
1695 indexIncrements, indexIncrementCnt, pregap,
1696 isrcCode, ctl);
1697 }
1698
1699 if (noScan || (options_ & OPT_MMC_READ_ISRC) != 0 ||
1700 (readCapabilities_ & CDR_READ_CAP_AUDIO_PQ_HEX) != 0) {
1701 // The ISRC code is usually not usable if the PQ channel data is
1702 // converted to hex numbers by the drive. Read them with the
1703 // appropriate command in this case
1704
1705 *isrcCode = 0;
1706 if (mode == TrackData::AUDIO)
1707 readIsrc(trackNr, isrcCode);
1708 }
1709
1710 return ret;
1711 }
1712
readSubChannels(TrackData::SubChannelMode sm,long lba,long len,SubChannel *** chans,Sample * audioData)1713 int GenericMMC::readSubChannels(TrackData::SubChannelMode sm,
1714 long lba, long len, SubChannel ***chans,
1715 Sample *audioData)
1716 {
1717 int retries = 5;
1718 unsigned char cmd[12];
1719 int i;
1720 long blockLen = 0;
1721 unsigned long subChanMode = 0;
1722
1723 cmd[0] = 0xbe; // READ CD
1724 cmd[1] = 0;
1725 cmd[2] = lba >> 24;
1726 cmd[3] = lba >> 16;
1727 cmd[4] = lba >> 8;
1728 cmd[5] = lba;
1729 cmd[6] = len >> 16;
1730 cmd[7] = len >> 8;
1731 cmd[8] = len;
1732 cmd[9] = 0xf8;
1733 cmd[11] = 0;
1734
1735 switch (sm) {
1736 case TrackData::SUBCHAN_NONE:
1737 // no sub-channel data selected choose what is available
1738
1739 if ((readCapabilities_ & CDR_READ_CAP_AUDIO_PW_RAW) != 0) {
1740 // reading of raw P-W sub-channel data is supported
1741 blockLen = AUDIO_BLOCK_LEN + 96;
1742 cmd[10] = 0x01; // raw P-W sub-channel data
1743
1744 subChanMode = CDR_READ_CAP_AUDIO_PW_RAW;
1745 }
1746 else if ((readCapabilities_ &
1747 (CDR_READ_CAP_AUDIO_PQ_BCD|CDR_READ_CAP_AUDIO_PQ_HEX)) != 0) {
1748 // reading of PQ sub-channel data is supported
1749 blockLen = AUDIO_BLOCK_LEN + 16;
1750 cmd[10] = 0x02; // PQ sub-channel data
1751
1752 if ((readCapabilities_ & CDR_READ_CAP_AUDIO_PQ_BCD) != 0)
1753 subChanMode = CDR_READ_CAP_AUDIO_PQ_BCD;
1754 else
1755 subChanMode = CDR_READ_CAP_AUDIO_PQ_HEX;
1756 }
1757 else {
1758 // no usable sub-channel reading mode is supported
1759 blockLen = AUDIO_BLOCK_LEN;
1760 cmd[10] = 0;
1761
1762 subChanMode = 0;
1763 }
1764 break;
1765
1766 case TrackData::SUBCHAN_RW:
1767 blockLen = AUDIO_BLOCK_LEN + 96;
1768 cmd[10] = 0x04;
1769 break;
1770
1771 case TrackData::SUBCHAN_RW_RAW:
1772 blockLen = AUDIO_BLOCK_LEN + 96;
1773 cmd[10] = 0x01;
1774 break;
1775 }
1776
1777 while (1) {
1778 if (sendCmd(cmd, 12, NULL, 0,
1779 transferBuffer_, len * blockLen, retries == 0 ? 1 : 0) != 0) {
1780 if (retries == 0)
1781 return 1;
1782 }
1783 else {
1784 break;
1785 }
1786
1787 retries--;
1788 }
1789
1790 #if 0
1791 if (lba > 5000) {
1792 char fname[200];
1793 sprintf(fname, "testout_%ld", lba);
1794 FILE *fp = fopen(fname, "w");
1795 fwrite(transferBuffer_, blockLen, len, fp);
1796 fclose(fp);
1797 }
1798 #endif
1799
1800 if (subChanMode != 0) {
1801 unsigned char *buf = transferBuffer_ + AUDIO_BLOCK_LEN;
1802
1803 for (i = 0; i < len; i++) {
1804 switch (subChanMode) {
1805 case CDR_READ_CAP_AUDIO_PQ_HEX:
1806 // All numbers in sub-channel data are hex conforming to the
1807 // MMC standard. We have to convert them back to BCD for the
1808 // 'SubChannel' class.
1809 buf[1] = SubChannel::bcd(buf[1]);
1810 buf[2] = SubChannel::bcd(buf[2]);
1811 buf[3] = SubChannel::bcd(buf[3]);
1812 buf[4] = SubChannel::bcd(buf[4]);
1813 buf[5] = SubChannel::bcd(buf[5]);
1814 buf[6] = SubChannel::bcd(buf[6]);
1815 buf[7] = SubChannel::bcd(buf[7]);
1816 buf[8] = SubChannel::bcd(buf[8]);
1817 buf[9] = SubChannel::bcd(buf[9]);
1818 // fall through
1819
1820 case CDR_READ_CAP_AUDIO_PQ_BCD:
1821 ((PQSubChannel16*)scannedSubChannels_[i])->init(buf);
1822 if (scannedSubChannels_[i]->type() != SubChannel::QMODE_ILLEGAL) {
1823 // the CRC of the sub-channel data is usually invalid -> mark the
1824 // sub-channel object that it should not try to verify the CRC
1825 scannedSubChannels_[i]->crcInvalid();
1826 }
1827 break;
1828
1829 case CDR_READ_CAP_AUDIO_PW_RAW:
1830 ((PWSubChannel96*)scannedSubChannels_[i])->init(buf);
1831 break;
1832 }
1833
1834 #if 0
1835 if (subChanMode == CDR_READ_CAP_AUDIO_PW_RAW) {
1836 // xxam!
1837 int j, k;
1838
1839 log_message(0, "");
1840 for (j = 0; j < 4; j++) {
1841 for (k = 0; k < 24; k++) {
1842 unsigned char data = buf[j * 24 + k];
1843 log_message(0, "%02x ", data&0x3f);
1844 }
1845 log_message(0, "");
1846 }
1847 }
1848 #endif
1849
1850 buf += blockLen;
1851 }
1852 }
1853
1854 if (audioData != NULL) {
1855 unsigned char *p = transferBuffer_;
1856
1857 for (i = 0; i < len; i++) {
1858 memcpy(audioData, p, AUDIO_BLOCK_LEN);
1859
1860 audioData += SAMPLES_PER_BLOCK;
1861
1862 switch (sm) {
1863 case TrackData::SUBCHAN_NONE:
1864 break;
1865
1866 case TrackData::SUBCHAN_RW:
1867 case TrackData::SUBCHAN_RW_RAW:
1868 memcpy(audioData, p + AUDIO_BLOCK_LEN, PW_SUBCHANNEL_LEN);
1869 audioData += PW_SUBCHANNEL_LEN / SAMPLE_LEN;
1870 break;
1871 }
1872
1873 p += blockLen;
1874 }
1875 }
1876
1877 if (subChanMode == 0)
1878 *chans = NULL;
1879 else
1880 *chans = scannedSubChannels_;
1881
1882 return 0;
1883 }
1884
1885
1886 // Tries to retrieve configuration feature 'feature' and fills data to
1887 // provided buffer 'buf' with maximum length 'bufLen'.
1888 // Return: 0: OK
1889 // 1: feature not available
1890 // 2: SCSI error
getFeature(unsigned int feature,unsigned char * buf,unsigned long bufLen,int showMsg)1891 int GenericMMC::getFeature(unsigned int feature, unsigned char *buf,
1892 unsigned long bufLen, int showMsg)
1893 {
1894 unsigned char header[8];
1895 unsigned char *data;
1896 unsigned char cmd[10];
1897 unsigned long len;
1898
1899 memset(cmd, 0, 10);
1900 memset(header, 0, 8);
1901
1902 cmd[0] = 0x46; // GET CONFIGURATION
1903 cmd[1] = 0x02; // return single feature descriptor
1904 cmd[2] = feature >> 8;
1905 cmd[3] = feature;
1906 cmd[8] = 8; // allocation length
1907
1908 if (sendCmd(cmd, 10, NULL, 0, header, 8, showMsg) != 0) {
1909 if (showMsg)
1910 log_message(-2, "Cannot get feature 0x%x.", feature);
1911 return 2;
1912 }
1913
1914 len = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3];
1915
1916 log_message(4, "getFeature: data len: %lu", len);
1917
1918 if (len < 8)
1919 return 1; // feature not defined
1920
1921 if (bufLen == 0)
1922 return 0;
1923
1924 len -= 4;
1925
1926 if (len > bufLen)
1927 len = bufLen;
1928
1929 data = new unsigned char[len + 8];
1930
1931 cmd[7] = (len + 8) >> 8;
1932 cmd[8] = (len + 8);
1933
1934 if (sendCmd(cmd, 10, NULL, 0, data, len + 8, showMsg) != 0) {
1935 if (showMsg)
1936 log_message(-2, "Cannot get data for feature 0x%x.", feature);
1937
1938 delete[] data;
1939 return 2;
1940 }
1941
1942 len = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3];
1943
1944 log_message(4, "getFeature: data len: %lu", len);
1945
1946 if (len < 8) {
1947 delete[] data;
1948 return 1; // feature not defined
1949 }
1950
1951 len -= 4;
1952
1953 if (len > bufLen)
1954 len = bufLen;
1955
1956 memcpy(buf, data + 8, len);
1957
1958 delete[] data;
1959
1960 return 0;
1961 }
1962
driveInfo(bool showErrorMsg)1963 const DriveInfo *GenericMMC::driveInfo(bool showErrorMsg)
1964 {
1965 unsigned char mp[32];
1966
1967 if (driveInfo_ != NULL)
1968 return driveInfo_;
1969
1970 driveInfo_ = new DriveInfo;
1971
1972 if (getModePage(0x2a, mp, 32, NULL, NULL, showErrorMsg) != 0) {
1973 if (showErrorMsg) {
1974 log_message(-2, "Cannot retrieve drive capabilities mode page.");
1975 }
1976 delete driveInfo_;
1977 driveInfo_ = NULL;
1978 return NULL;
1979 }
1980
1981 driveInfo_->burnProof = (mp[4] & 0x80) ? 1 : 0;
1982 driveInfo_->accurateAudioStream = mp[5] & 0x02 ? 1 : 0;
1983
1984 driveInfo_->maxReadSpeed = (mp[8] << 8) | mp[9];
1985 driveInfo_->currentReadSpeed = (mp[14] << 8) | mp[15];
1986
1987 driveInfo_->maxWriteSpeed = (mp[18] << 8) | mp[19];
1988 driveInfo_->currentWriteSpeed = (mp[20] << 8) | mp[21];
1989
1990 #if 0
1991 unsigned char cdMasteringFeature[8];
1992 if (getFeature(0x2e, cdMasteringFeature, 8, 1) == 0) {
1993 log_message(0, "Feature: %x %x %x %x %x %x %x %x", cdMasteringFeature[0],
1994 cdMasteringFeature[1], cdMasteringFeature[2],
1995 cdMasteringFeature[3], cdMasteringFeature[4],
1996 cdMasteringFeature[5], cdMasteringFeature[6],
1997 cdMasteringFeature[7]);
1998 }
1999 #endif
2000
2001 RicohGetWriteOptions();
2002
2003 return driveInfo_;
2004 }
2005
getTrackMode(int,long trackStartLba)2006 TrackData::Mode GenericMMC::getTrackMode(int, long trackStartLba)
2007 {
2008 unsigned char cmd[12];
2009 unsigned char data[AUDIO_BLOCK_LEN];
2010
2011 memset(cmd, 0, 12);
2012 cmd[0] = 0xbe; // READ CD
2013
2014 cmd[2] = trackStartLba >> 24;
2015 cmd[3] = trackStartLba >> 16;
2016 cmd[4] = trackStartLba >> 8;
2017 cmd[5] = trackStartLba;
2018
2019 cmd[8] = 1;
2020
2021 cmd[9] = 0xf8;
2022
2023 if (sendCmd(cmd, 12, NULL, 0, data, AUDIO_BLOCK_LEN) != 0) {
2024 log_message(-2, "Cannot read sector of track.");
2025 return TrackData::MODE0;
2026 }
2027
2028 if (memcmp(CdrDriver::syncPattern, data, 12) != 0) {
2029 // cannot be a data sector
2030 return TrackData::MODE0;
2031 }
2032
2033 TrackData::Mode mode = determineSectorMode(data + 12);
2034
2035 if (mode == TrackData::MODE0) {
2036 // illegal
2037 log_message(-2, "Found illegal mode in sector %ld.", trackStartLba);
2038 }
2039
2040 return mode;
2041 }
2042
getRawToc(int sessionNr,int * len)2043 CdRawToc *GenericMMC::getRawToc(int sessionNr, int *len)
2044 {
2045 unsigned char cmd[10];
2046 unsigned short dataLen;
2047 unsigned char *data = NULL;;
2048 unsigned char reqData[4]; // buffer for requestion the actual length
2049 unsigned char *p;
2050 int i, entries;
2051 CdRawToc *rawToc;
2052
2053 assert(sessionNr >= 1);
2054
2055 // read disk toc length
2056 memset(cmd, 0, 10);
2057 cmd[0] = 0x43; // READ TOC
2058 cmd[2] = 2;
2059 cmd[6] = sessionNr;
2060 cmd[8] = 4;
2061
2062 if (sendCmd(cmd, 10, NULL, 0, reqData, 4) != 0) {
2063 log_message(-2, "Cannot read disk toc.");
2064 return NULL;
2065 }
2066
2067 dataLen = ((reqData[0] << 8) | reqData[1]) + 2;
2068
2069 log_message(4, "Raw toc data len: %d", dataLen);
2070
2071 data = new unsigned char[dataLen];
2072
2073 // read disk toc
2074 cmd[7] = dataLen >> 8;
2075 cmd[8] = dataLen;
2076
2077 if (sendCmd(cmd, 10, NULL, 0, data, dataLen) != 0) {
2078 log_message(-2, "Cannot read disk toc.");
2079 delete[] data;
2080 return NULL;
2081 }
2082
2083 entries = (((data[0] << 8) | data[1]) - 2) / 11;
2084
2085 rawToc = new CdRawToc[entries];
2086
2087 for (i = 0, p = data + 4; i < entries; i++, p += 11 ) {
2088 #if 0
2089 log_message(5, "%d %02x %02d %2x %02d:%02d:%02d %02d %02d:%02d:%02d",
2090 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10]);
2091 #endif
2092 rawToc[i].sessionNr = p[0];
2093 rawToc[i].adrCtl = p[1];
2094 rawToc[i].point = p[3];
2095 rawToc[i].pmin = p[8];
2096 rawToc[i].psec = p[9];
2097 rawToc[i].pframe = p[10];
2098 }
2099
2100 delete[] data;
2101
2102 *len = entries;
2103
2104 return rawToc;
2105 }
2106
readTrackData(TrackData::Mode mode,TrackData::SubChannelMode sm,long lba,long len,unsigned char * buf)2107 long GenericMMC::readTrackData(TrackData::Mode mode,
2108 TrackData::SubChannelMode sm,
2109 long lba, long len, unsigned char *buf)
2110 {
2111 long i;
2112 long inBlockLen = AUDIO_BLOCK_LEN;
2113 unsigned char cmd[12];
2114 const unsigned char *sense;
2115 int senseLen;
2116
2117 memset(cmd, 0, 12);
2118
2119 cmd[0] = 0xbe; // READ CD
2120 cmd[1] = 0;
2121 cmd[2] = lba >> 24;
2122 cmd[3] = lba >> 16;
2123 cmd[4] = lba >> 8;
2124 cmd[5] = lba;
2125 cmd[6] = len >> 16;
2126 cmd[7] = len >> 8;
2127 cmd[8] = len;
2128 cmd[9] = 0xf8;
2129
2130 switch (sm) {
2131 case TrackData::SUBCHAN_NONE:
2132 cmd[10] = 0; // no sub-channel reading
2133 break;
2134
2135 case TrackData::SUBCHAN_RW:
2136 cmd[10] = 0x4;
2137 inBlockLen += PW_SUBCHANNEL_LEN;
2138 break;
2139
2140 case TrackData::SUBCHAN_RW_RAW:
2141 cmd[10] = 0x1;
2142 inBlockLen += PW_SUBCHANNEL_LEN;
2143 break;
2144 }
2145
2146 switch (sendCmd(cmd, 12, NULL, 0, transferBuffer_, len * inBlockLen, 0)) {
2147 case 0:
2148 break;
2149
2150 case 2:
2151 sense = scsiIf_->getSense(senseLen);
2152
2153 if (senseLen > 0x0c) {
2154 if ((sense[2] & 0x0f) == 5) { // Illegal request
2155 switch (sense[12]) {
2156 case 0x63: // End of user area encountered on this track
2157 case 0x64: // Illegal mode for this track
2158 return -2;
2159 break;
2160
2161 case 0x20: // INVALID COMMAND OPERATION CODE
2162 case 0x24: // INVALID FIELD IN CDB
2163 case 0x26: // INVALID FIELD IN PARAMETER LIST
2164 /* These error codes mean that something was wrong with the
2165 * command we are sending. Report them as hard errors to the
2166 * upper level.
2167 */
2168 scsiIf_->printError();
2169 return -1;
2170 break;
2171 }
2172 }
2173 else if ((sense[2] & 0x0f) == 4) { // Hardware Error
2174 switch (sense[12]) {
2175 case 0x9: // focus servo failure
2176 return -2;
2177 break;
2178 }
2179 }
2180 else if ((sense[2] & 0x0f) == 3) { // Medium error
2181 switch (sense[12]) {
2182 case 0x02: // No seek complete, sector not found
2183 case 0x06: // no reference position found
2184 case 0x11: // L-EC error
2185 case 0x15: // random positioning error
2186 return -2;
2187 break;
2188 }
2189 }
2190 }
2191
2192 /* All other errors are unexpected. They will be treated like L-EC errors
2193 * by the upper layer. Just print the error code so that we can decice
2194 * later to add the errors to the known possible error list.
2195 */
2196
2197 scsiIf_->printError();
2198 return -2;
2199 break;
2200
2201 default:
2202 log_message(-2, "Read error at LBA %ld, len %ld", lba, len);
2203 return -2;
2204 break;
2205 }
2206
2207 unsigned char *sector = transferBuffer_;
2208 for (i = 0; i < len; i++) {
2209 if (buf != NULL) {
2210 switch (mode) {
2211 case TrackData::MODE1:
2212 memcpy(buf, sector + 16, MODE1_BLOCK_LEN);
2213 buf += MODE1_BLOCK_LEN;
2214 break;
2215 case TrackData::MODE1_RAW:
2216 memcpy(buf, sector, AUDIO_BLOCK_LEN);
2217 buf += AUDIO_BLOCK_LEN;
2218 break;
2219 case TrackData::MODE2:
2220 case TrackData::MODE2_FORM_MIX:
2221 memcpy(buf, sector + 16, MODE2_BLOCK_LEN);
2222 buf += MODE2_BLOCK_LEN;
2223 break;
2224 case TrackData::MODE2_FORM1:
2225 memcpy(buf, sector + 24, MODE2_FORM1_DATA_LEN);
2226 buf += MODE2_FORM1_DATA_LEN;
2227 break;
2228 case TrackData::MODE2_FORM2:
2229 memcpy(buf, sector + 24, MODE2_FORM2_DATA_LEN);
2230 buf += MODE2_FORM2_DATA_LEN;
2231 break;
2232 case TrackData::MODE2_RAW:
2233 memcpy(buf, sector, AUDIO_BLOCK_LEN);
2234 buf += AUDIO_BLOCK_LEN;
2235 break;
2236 case TrackData::MODE0:
2237 case TrackData::AUDIO:
2238 log_message(-3, "GenericMMC::readTrackData: Illegal mode.");
2239 return 0;
2240 break;
2241 }
2242
2243 // copy sub-channel data
2244 switch (sm) {
2245 case TrackData::SUBCHAN_NONE:
2246 break;
2247
2248 case TrackData::SUBCHAN_RW:
2249 case TrackData::SUBCHAN_RW_RAW:
2250 memcpy(buf, sector + AUDIO_BLOCK_LEN, PW_SUBCHANNEL_LEN);
2251 buf += PW_SUBCHANNEL_LEN;
2252 break;
2253 }
2254 }
2255
2256 #if 0
2257 // xxam!
2258 int j, k;
2259
2260 log_message(0, "");
2261 for (j = 0; j < 4; j++) {
2262 for (k = 0; k < 24; k++) {
2263 unsigned char data = sector[AUDIO_BLOCK_LEN + j * 24 + k];
2264 log_message(0, "%02x ", data&0x3f);
2265 }
2266 log_message(0, "");
2267 }
2268 #endif
2269
2270 sector += inBlockLen;
2271 }
2272
2273 return len;
2274 }
2275
readAudioRange(ReadDiskInfo * rinfo,int fd,long start,long end,int startTrack,int endTrack,TrackInfo * info)2276 int GenericMMC::readAudioRange(ReadDiskInfo *rinfo, int fd, long start,
2277 long end, int startTrack,
2278 int endTrack, TrackInfo *info)
2279 {
2280 if (!onTheFly_) {
2281 if (((readCapabilities_ & CDR_READ_CAP_AUDIO_PQ_BCD) == 0 &&
2282 (readCapabilities_ & CDR_READ_CAP_AUDIO_PW_RAW) == 0) ||
2283 (options_ & OPT_MMC_READ_ISRC) != 0) {
2284 int t;
2285 long pregap = 0;
2286
2287 // The ISRC code is usually not usable if the PQ channel data is
2288 // converted to hex numbers by the drive. Read them with the
2289 // appropriate command in this case
2290
2291 log_message(1, "Analyzing...");
2292
2293
2294 for (t = startTrack; t <= endTrack; t++) {
2295 long totalProgress;
2296
2297 log_message(1, "Track %d...", t + 1);
2298
2299 totalProgress = t * 1000;
2300 totalProgress /= rinfo->tracks;
2301 sendReadCdProgressMsg(RCD_ANALYZING, rinfo->tracks, t + 1, 0,
2302 totalProgress);
2303
2304 if ((readCapabilities_ & CDR_AUDIO_SCAN_CAP) == 0) {
2305 // we have to use the binary search method to find pre-gap and
2306 // index marks if the drive cannot read sub-channel data
2307 if (!fastTocReading_) {
2308 long slba, elba;
2309 int i, indexCnt;
2310 Msf index[98];
2311 unsigned char ctl;
2312
2313 if (pregap > 0)
2314 log_message(2, "Found pre-gap: %s", Msf(pregap).str());
2315
2316 slba = info[t].start;
2317 if (info[t].mode == info[t + 1].mode)
2318 elba = info[t + 1].start;
2319 else
2320 elba = info[t + 1].start - 150;
2321
2322 pregap = 0;
2323 if (analyzeTrackSearch(TrackData::AUDIO, t + 1, slba, elba,
2324 index, &indexCnt, &pregap, info[t].isrcCode,
2325 &ctl) != 0)
2326 return 1;
2327
2328 for (i = 0; i < indexCnt; i++)
2329 info[t].index[i] = index[i].lba();
2330
2331 info[t].indexCnt = indexCnt;
2332
2333 if (t < endTrack)
2334 info[t + 1].pregap = pregap;
2335 }
2336 else {
2337 info[t].indexCnt = 0;
2338 info[t + 1].pregap = 0;
2339 }
2340 }
2341
2342
2343 info[t].isrcCode[0] = 0;
2344 readIsrc(t + 1, info[t].isrcCode);
2345 if (info[t].isrcCode[0] != 0)
2346 log_message(2, "Found ISRC code.");
2347
2348 totalProgress = (t + 1) * 1000;
2349 totalProgress /= rinfo->tracks;
2350 sendReadCdProgressMsg(RCD_ANALYZING, rinfo->tracks, t + 1, 1000,
2351 totalProgress);
2352 }
2353
2354 log_message(1, "Reading...");
2355 }
2356 }
2357
2358 if (subChanReadMode_ == TrackData::SUBCHAN_NONE) {
2359 return CdrDriver::readAudioRangeParanoia(rinfo, fd, start, end, startTrack,
2360 endTrack, info);
2361 }
2362 else {
2363 return CdrDriver::readAudioRangeStream(rinfo, fd, start, end, startTrack,
2364 endTrack, info);
2365 }
2366 }
2367
getTrackIndex(long lba,int * trackNr,int * indexNr,unsigned char * ctl)2368 int GenericMMC::getTrackIndex(long lba, int *trackNr, int *indexNr,
2369 unsigned char *ctl)
2370 {
2371 unsigned char cmd[12];
2372 unsigned short dataLen = 0x30;
2373 unsigned char data[0x30];
2374 int waitLoops = 10;
2375 int waitFailed = 0;
2376
2377 // play one audio block
2378 memset(cmd, 0, 10);
2379 cmd[0] = 0x45; // PLAY AUDIO
2380 cmd[2] = lba >> 24;
2381 cmd[3] = lba >> 16;
2382 cmd[4] = lba >> 8;
2383 cmd[5] = lba;
2384 cmd[7] = 0;
2385 cmd[8] = 1;
2386
2387 if (sendCmd(cmd, 10, NULL, 0, NULL, 0) != 0) {
2388 log_message(-2, "Cannot play audio block.");
2389 return 1;
2390 }
2391
2392 // wait until the play command finished
2393 memset(cmd, 0, 12);
2394 cmd[0] = 0xbd; // MECHANISM STATUS
2395 cmd[9] = 8;
2396
2397 while (waitLoops > 0) {
2398 if (sendCmd(cmd, 12, NULL, 0, data, 8, 0) == 0) {
2399 //log_message(0, "%d, %x", waitLoops, data[1]);
2400 if ((data[1] >> 5) == 1) // still playing?
2401 waitLoops--;
2402 else
2403 waitLoops = 0;
2404 }
2405 else {
2406 waitFailed = 1;
2407 waitLoops = 0;
2408 }
2409 }
2410
2411 if (waitFailed) {
2412 // The play operation immediately returns success status and the waiting
2413 // loop above failed. Wait here for a while until the desired block is
2414 // played. It takes ~13 msecs to play a block but access time is in the
2415 // order of several 100 msecs
2416 mSleep(300);
2417 }
2418
2419 // read sub channel information
2420 memset(cmd, 0, 10);
2421 cmd[0] = 0x42; // READ SUB CHANNEL
2422 cmd[2] = 0x40; // get sub channel data
2423 cmd[3] = 0x01; // get sub Q channel data
2424 cmd[6] = 0;
2425 cmd[7] = dataLen >> 8;
2426 cmd[8] = dataLen;
2427
2428 if (sendCmd(cmd, 10, NULL, 0, data, dataLen) != 0) {
2429 log_message(-2, "Cannot read sub Q channel data.");
2430 return 1;
2431 }
2432
2433 *trackNr = data[6];
2434 *indexNr = data[7];
2435 if (ctl != NULL) {
2436 *ctl = data[5] & 0x0f;
2437 }
2438
2439 //log_message(0, "%d %d", *trackNr, *indexNr);
2440
2441 return 0;
2442 }
2443
2444 /*
2445 * Checks if a certain sub-channel reading mode is supported.
2446 * lba: start address for reading
2447 * len: maximum number of sectors available for testing
2448 * subChanMode: 1: read PQ sub-channels
2449 * 2: read raw P-W sub-channels
2450 * 3: read cooked R-W sub-channels
2451 * Return: 0 sub-channel read mode not supported
2452 * 1 sub-channel read mode supported (BCD for PQ)
2453 * 2 sub-channel read mode supported (HEX for PQ)
2454 * 3 sub-channel read mode PQ supported but cannot determine data
2455 * format
2456 */
2457
readCdTest(long lba,long len,int subChanMode) const2458 int GenericMMC::readCdTest(long lba, long len, int subChanMode) const
2459 {
2460 unsigned char cmd[12];
2461 long blockLen;
2462 int ret;
2463 int successRead = 0;
2464 int pqSubChanBcdOk = 0;
2465 int pqSubChanHexOk = 0;
2466
2467 memset(cmd, 0, sizeof(cmd));
2468
2469 //log_message(0, "readCdTest: %ld %ld %d", lba, len, subChanMode);
2470
2471 if (len <= 0)
2472 return 0;
2473
2474 cmd[0] = 0xbe; // READ CD
2475 cmd[8] = 1; // transfer length: 1
2476 cmd[9] = 0xf8;
2477
2478 blockLen = AUDIO_BLOCK_LEN;
2479
2480 switch (subChanMode) {
2481 case 1: // PQ
2482 blockLen += PQ_SUBCHANNEL_LEN;
2483 cmd[10] = 0x02;
2484 if (len > 300)
2485 len = 300; /* we have to check many sub-channels here to determine the
2486 * data mode (BCD or HEX)
2487 */
2488 break;
2489
2490 case 2: // PW_RAW
2491 cmd[10] = 0x01;
2492 blockLen += PW_SUBCHANNEL_LEN;
2493 if (len > 10)
2494 len = 10;
2495 break;
2496
2497 case 3: // RW_COOKED
2498 cmd[10] = 0x04;
2499 blockLen += PW_SUBCHANNEL_LEN;
2500 if (len > 10)
2501 len = 10;
2502 break;
2503 }
2504
2505 while (len > 0) {
2506 cmd[2] = lba >> 24;
2507 cmd[3] = lba >> 16;
2508 cmd[4] = lba >> 8;
2509 cmd[5] = lba;
2510
2511 if ((ret = sendCmd(cmd, 12, NULL, 0, transferBuffer_, blockLen, 0)) == 0) {
2512 successRead++;
2513
2514 if (subChanMode == 1) {
2515 unsigned char *buf = transferBuffer_ + AUDIO_BLOCK_LEN;
2516
2517 #if 0
2518 {
2519 PQSubChannel16 chan;
2520 chan.init(buf);
2521 chan.print();
2522 }
2523 #endif
2524
2525 // check if Q sub-channel values are in BCD or HEX format
2526 if (SubChannel::isBcd(buf[1]) &&
2527 SubChannel::isBcd(buf[2]) &&
2528 SubChannel::isBcd(buf[3]) &&
2529 SubChannel::isBcd(buf[4]) &&
2530 SubChannel::isBcd(buf[5]) &&
2531 SubChannel::isBcd(buf[6]) &&
2532 SubChannel::isBcd(buf[7]) &&
2533 SubChannel::isBcd(buf[8]) &&
2534 SubChannel::isBcd(buf[9])) {
2535 PQSubChannel16 chan;
2536 chan.init(buf);
2537
2538 chan.type(SubChannel::QMODE1DATA);
2539
2540 int min = chan.amin();
2541 int sec = chan.asec();
2542 int frac = chan.aframe();
2543
2544 if ((frac >= 0 && frac < 75) &&
2545 (sec >= 0 && sec < 60) &&
2546 (min >= 0)) {
2547 long pqlba = Msf(min, sec, frac).lba() - 150;
2548
2549 long diff = pqlba - lba;
2550 if (diff < 0)
2551 diff = -diff;
2552
2553 if (diff < 20) {
2554 pqSubChanBcdOk++;
2555 }
2556 }
2557 }
2558
2559 if (buf[7] < 100 && buf[8] < 60 && buf[9] < 75) {
2560 long pqlba = Msf(buf[7], buf[8], buf[9]).lba() - 150;
2561
2562 //log_message(0, "readCdTest: pqlba: %ld", pqlba);
2563 long diff = pqlba - lba;
2564 if (diff < 0)
2565 diff = -diff;
2566
2567 if (diff < 20) {
2568 pqSubChanHexOk++;
2569 }
2570 }
2571 }
2572 }
2573
2574
2575 len--;
2576 lba++;
2577 }
2578
2579 if (successRead) {
2580 if (subChanMode == 1) {
2581 if (pqSubChanBcdOk > pqSubChanHexOk)
2582 return 1;
2583 else if (pqSubChanHexOk > pqSubChanBcdOk)
2584 return 2;
2585 else return 3;
2586 }
2587 else {
2588 return 1;
2589 }
2590 }
2591
2592 return 0;
2593 }
2594
getReadCapabilities(const CdToc * toc,int nofTracks) const2595 unsigned long GenericMMC::getReadCapabilities(const CdToc *toc,
2596 int nofTracks) const
2597 {
2598 unsigned long caps = 0;
2599 int audioRawPWChecked = 0;
2600 int audioPQChecked = 0;
2601 int audioCookedRWChecked = 0;
2602 int dataRawPWChecked = 0;
2603 int dataPQChecked = 0;
2604 int dataCookedRWChecked = 0;
2605 int t;
2606
2607 if ((options_ & OPT_MMC_NO_SUBCHAN) != 0) {
2608 // driver options indicate that PQ and raw RW sub-channel reading for
2609 // audio tracks is not supported so skip all corresponding tests
2610 audioPQChecked = 1;
2611 audioRawPWChecked = 1;
2612 }
2613 else if ((options_ & OPT_MMC_USE_PQ) != 0) {
2614 // driver options indicated that PQ sub-channel reading is supported for
2615 // audio/data tracks and RW sub-channel reading is not supported, skip
2616 // the corresponding checks and set the capabilities appropriately
2617 audioPQChecked = 1;
2618 audioRawPWChecked = 1;
2619 dataPQChecked = 1;
2620
2621 if ((options_ & OPT_MMC_PQ_BCD) != 0)
2622 caps |= CDR_READ_CAP_AUDIO_PQ_BCD | CDR_READ_CAP_DATA_PQ_BCD;
2623 else
2624 caps |= CDR_READ_CAP_AUDIO_PQ_HEX | CDR_READ_CAP_DATA_PQ_HEX;
2625 }
2626 else if ((options_ & OPT_MMC_USE_RAW_RW) != 0) {
2627 // driver options indicated that raw PW sub-channel reading is supported
2628 // audio tracks and raw PW sub-channel reading is not supported, skip
2629 // the corresponding checks and set the capabilities appropriately
2630 audioPQChecked = 1;
2631 audioRawPWChecked = 1;
2632
2633 caps |= CDR_READ_CAP_DATA_PW_RAW;
2634 }
2635
2636 for (t = 0; t < nofTracks; t++) {
2637 long tlen = toc[t+1].start - toc[t].start;
2638
2639 if ((toc[t].adrCtl & 0x04) != 0) {
2640 // data track
2641 if (!dataPQChecked) {
2642 dataPQChecked = 1;
2643
2644 log_message(3, "Checking for PQ sub-channel reading support (data track)...");
2645 switch (readCdTest(toc[t].start, tlen, 1)) {
2646 case 0:
2647 log_message(3, "PQ sub-channel reading (data track) not supported.");
2648 break;
2649
2650 case 1:
2651 log_message(2, "PQ sub-channel reading (data track) is supported, data format is BCD.");
2652 caps |= CDR_READ_CAP_DATA_PQ_BCD;
2653 break;
2654
2655 case 2:
2656 log_message(2, "PQ sub-channel reading (data track) is supported, data format is HEX.");
2657 caps |= CDR_READ_CAP_DATA_PQ_HEX;
2658 break;
2659
2660 case 3:
2661 log_message(2, "PQ sub-channel reading (data track) seems to be supported but cannot determine data format.");
2662 log_message(2, "Please use driver option '--driver generic-mmc:0x1' or '--driver generic-mmc:0x3' to set the data format explicitly.");
2663 break;
2664 }
2665 }
2666
2667 if (!dataRawPWChecked) {
2668 dataRawPWChecked = 1;
2669
2670 log_message(3, "Checking for raw P-W sub-channel reading support (data track)...");
2671 if (readCdTest(toc[t].start, tlen, 2)) {
2672 log_message(2, "Raw P-W sub-channel reading (data track) is supported.");
2673 caps |= CDR_READ_CAP_DATA_PW_RAW;
2674 }
2675 else {
2676 log_message(3, "Raw P-W sub-channel reading (data track) is not supported.");
2677 }
2678 }
2679
2680 if (!dataCookedRWChecked) {
2681 dataCookedRWChecked = 1;
2682
2683 log_message(3, "Checking for cooked R-W sub-channel reading support (data track)...");
2684 if (readCdTest(toc[t].start, tlen, 3)) {
2685 log_message(2, "Cooked R-W sub-channel reading (data track) is supported.");
2686 caps |= CDR_READ_CAP_DATA_RW_COOKED;
2687 }
2688 else {
2689 log_message(3, "Cooked R-W sub-channel reading (data track) is not supported.");
2690 }
2691 }
2692 }
2693 else {
2694 // audio track
2695 if (!audioPQChecked) {
2696 audioPQChecked = 1;
2697
2698 log_message(3, "Checking for PQ sub-channel reading support (audio track)...");
2699 switch (readCdTest(toc[t].start, tlen, 1)) {
2700 case 0:
2701 log_message(3, "PQ sub-channel reading (audio track) is not supported.");
2702 break;
2703
2704 case 1:
2705 log_message(2, "PQ sub-channel reading (audio track) is supported, data format is BCD.");
2706 caps |= CDR_READ_CAP_AUDIO_PQ_BCD;
2707 break;
2708
2709 case 2:
2710 log_message(2, "PQ sub-channel reading (audio track) is supported, data format is HEX.");
2711 caps |= CDR_READ_CAP_AUDIO_PQ_HEX;
2712 break;
2713
2714 case 3:
2715 log_message(2, "PQ sub-channel reading (audio track) seems to be supported but cannot determine data format.");
2716 log_message(2, "Please use driver option '--driver generic-mmc:0x1' or '--driver generic-mmc:0x3' to set the data format explicitly.");
2717 break;
2718 }
2719 }
2720
2721 if (!audioRawPWChecked) {
2722 audioRawPWChecked = 1;
2723
2724 log_message(3, "Checking for raw P-W sub-channel reading support (audio track)...");
2725 if (readCdTest(toc[t].start, tlen, 2)) {
2726 log_message(2, "Raw P-W sub-channel reading (audio track) is supported.");
2727 caps |= CDR_READ_CAP_AUDIO_PW_RAW;
2728 }
2729 else {
2730 log_message(3, "Raw P-W sub-channel reading (audio track) is not supported.");
2731 }
2732 }
2733
2734 if (!audioCookedRWChecked) {
2735 audioCookedRWChecked = 1;
2736
2737 log_message(3, "Checking for cooked R-W sub-channel reading support (audio track)...");
2738 if (readCdTest(toc[t].start, tlen, 3)) {
2739 log_message(2, "Cooked R-W sub-channel reading (audio track) is supported.");
2740 caps |= CDR_READ_CAP_AUDIO_RW_COOKED;
2741 }
2742 else {
2743 log_message(3, "Raw R-W sub-channel reading (audio track) is not supported.");
2744 }
2745 }
2746 }
2747 }
2748
2749 return caps;
2750 }
2751
RicohGetWriteOptions()2752 int GenericMMC::RicohGetWriteOptions()
2753 {
2754 unsigned char mp[14];
2755
2756 driveInfo_->ricohJustLink = 0;
2757 driveInfo_->ricohJustSpeed = 0;
2758
2759 if (getModePage(0x30, mp, 14, NULL, NULL, 0) != 0) {
2760 return 1;
2761 }
2762
2763 if (mp[1] != 14)
2764 return 1;
2765
2766 if (mp[2] & (1 << 5))
2767 driveInfo_->ricohJustSpeed = 1;
2768
2769 if (mp[2] & 0x01)
2770 driveInfo_->ricohJustLink = 1;
2771
2772 return 0;
2773 }
2774
RicohSetWriteOptions(const DriveInfo * di)2775 int GenericMMC::RicohSetWriteOptions(const DriveInfo *di)
2776 {
2777 unsigned char mp[14];
2778
2779 if (di->ricohJustLink == 0 && di->ricohJustSpeed == 0)
2780 return 0;
2781
2782 if (getModePage(0x30, mp, 14, NULL, NULL, 1) != 0) {
2783 log_message(-2, "Cannot retrieve Ricoh mode page 30.");
2784 return 1;
2785 }
2786
2787 if (di->ricohJustLink) {
2788 if (bufferUnderRunProtection()) {
2789 log_message(2, "Enabling JustLink.");
2790 mp[3] |= 0x1;
2791 }
2792 else {
2793 log_message(2, "Disabling JustLink.");
2794 mp[3] &= ~0x1;
2795 }
2796 }
2797
2798 if (di->ricohJustSpeed) {
2799 if (writeSpeedControl()) {
2800 log_message(2, "Enabling JustSpeed.");
2801 mp[3] &= ~(1 << 5); // clear bit to enable write speed control
2802 }
2803 else {
2804 log_message(2, "Disabling JustSpeed.");
2805 mp[3] |= (1 << 5); // set bit to disable write speed control
2806 }
2807 }
2808
2809 if (setModePage(mp, NULL, NULL, 1) != 0) {
2810 log_message(-2, "Cannot set Ricoh mode page 30.");
2811 return 1;
2812 }
2813
2814 return 0;
2815 }
2816