From 7e966f42d9596a4b767c499dac9457c455964fbb Mon Sep 17 00:00:00 2001 From: chudov Date: Sat, 7 Jan 2012 00:17:00 +0000 Subject: [PATCH] Plextor PX-W1210A workaround --- Bwg.Scsi/Device.cs | 13 ++++-- CUETools.AccurateRip/AccurateRip.cs | 11 ++--- .../CUETools.ConsoleRipper.csproj | 2 +- CUETools.Ripper.SCSI/SCSIDrive.cs | 44 ++++++++++++++----- .../CUETools.TestParity/CDRepairDecodeTest.cs | 2 +- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/Bwg.Scsi/Device.cs b/Bwg.Scsi/Device.cs index 3793fe7..213c106 100644 --- a/Bwg.Scsi/Device.cs +++ b/Bwg.Scsi/Device.cs @@ -2011,6 +2011,10 @@ namespace Bwg.Scsi /// public enum MainChannelSelection { + /// + /// + /// + None, /// /// /// @@ -2056,7 +2060,7 @@ namespace Bwg.Scsi byte b = (byte)((exp & 0x07) << 2); if (dap) b |= 0x02; - byte byte9 = (byte) (mainmode == MainChannelSelection.UserData ? 0x10 : 0xF8); + byte byte9 = (byte)(mainmode == MainChannelSelection.UserData ? 0x10 : mainmode == MainChannelSelection.F8h ? 0xF8 : 0); if (c2mode == C2ErrorMode.Mode294) byte9 |= 0x02; else if (c2mode == C2ErrorMode.Mode296) @@ -2066,8 +2070,7 @@ namespace Bwg.Scsi cmd.SetCDB24(6, length); cmd.SetCDB8(9, byte9); // User data + possibly c2 errors cmd.SetCDB8(10, mode); // Subchannel - - CommandStatus st = SendCommand(cmd); + CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } @@ -2095,7 +2098,7 @@ namespace Bwg.Scsi byte mode = (byte)(submode == SubChannelMode.QOnly ? 1 : submode == SubChannelMode.RWMode ? 2 : 0); int size = 4 * 588 + (submode == SubChannelMode.QOnly ? 16 : submode == SubChannelMode.RWMode ? 96 : 0); - using (Command cmd = new Command(ScsiCommandCode.ReadCDDA, 12, data, size, Command.CmdDirection.In, timeout)) + using (Command cmd = new Command(ScsiCommandCode.ReadCDDA, 12, data, (int)length * size, Command.CmdDirection.In, timeout)) { cmd.SetCDB8(1, 0 << 5); // lun cmd.SetCDB32(2, start); @@ -2205,6 +2208,8 @@ namespace Bwg.Scsi using (Command cmd = new Command(ScsiCommandCode.ReadCd, 12, (int)(length * bytes_per_sector), Command.CmdDirection.In, timeout)) { + byte b = (byte)(1 << 2); + cmd.SetCDB8(1, b); cmd.SetCDB32(2, sector); // The sector number to start with cmd.SetCDB24(6, length); // The length in sectors cmd.SetCDB8(10, mode); // Corrected, de-interleaved P - W data diff --git a/CUETools.AccurateRip/AccurateRip.cs b/CUETools.AccurateRip/AccurateRip.cs index 5bd66b4..bce758c 100644 --- a/CUETools.AccurateRip/AccurateRip.cs +++ b/CUETools.AccurateRip/AccurateRip.cs @@ -408,11 +408,10 @@ namespace CUETools.AccurateRip { int discLen = (int)_toc.AudioLength * 588; int chunkLen = discLen - prefixSamples - suffixSamples; - crc = Crc32.Combine( - _CRC32[0, prefixSamples], + return 0xffffffff ^ Crc32.Combine( + 0xffffffff ^ _CRC32[0, prefixSamples], _CRC32[_toc.AudioTracks, 2 * maxOffset - suffixSamples], chunkLen * 4); - return Crc32.Combine(0xffffffff, crc, chunkLen * 4) ^ 0xffffffff; } int posA = (int)_toc[iTrack + _toc.FirstAudio - 1].Start * 588 + (iTrack > 1 ? oi : prefixSamples); int posB = iTrack < _toc.AudioTracks ? @@ -437,10 +436,8 @@ namespace CUETools.AccurateRip _CRC32[iTrack, maxOffset * 2 + oi] : _CRC32[iTrack, maxOffset * 2 - suffixSamples]; } - crc = Crc32.Combine(crcA, crcB, (posB - posA) * 4); - // Use 0xffffffff as an initial state - crc = Crc32.Combine(0xffffffff, crc, (posB - posA) * 4) ^ 0xffffffff; - return crc; + // Use 0xffffffff as an initial state + return 0xffffffff ^ Crc32.Combine(0xffffffff ^ crcA, crcB, (posB - posA) * 4); } public uint CTDBCRC(int offset) diff --git a/CUETools.Ripper.Console/CUETools.ConsoleRipper.csproj b/CUETools.Ripper.Console/CUETools.ConsoleRipper.csproj index 25a9dca..a4b50bc 100644 --- a/CUETools.Ripper.Console/CUETools.ConsoleRipper.csproj +++ b/CUETools.Ripper.Console/CUETools.ConsoleRipper.csproj @@ -36,7 +36,7 @@ true full false - bin\Debug\ + ..\bin\Debug\ DEBUG;TRACE prompt 4 diff --git a/CUETools.Ripper.SCSI/SCSIDrive.cs b/CUETools.Ripper.SCSI/SCSIDrive.cs index dac9109..2787a25 100644 --- a/CUETools.Ripper.SCSI/SCSIDrive.cs +++ b/CUETools.Ripper.SCSI/SCSIDrive.cs @@ -72,7 +72,7 @@ namespace CUETools.Ripper.SCSI Device.C2ErrorMode _c2ErrorMode = Device.C2ErrorMode.Mode296; string _autodetectResult; byte[] _readBuffer = new byte[NSECTORS * CB_AUDIO]; - byte[] _subchannelBuffer = new byte[CB_AUDIO]; + byte[] _subchannelBuffer = new byte[NSECTORS * CB_AUDIO]; bool _qChannelInBCD = true; private ReadProgressArgs progressArgs = new ReadProgressArgs(); @@ -474,7 +474,27 @@ namespace CUETools.Ripper.SCSI if (_readCDCommand == ReadCDCommand.ReadCdBEh) { - st = m_device.ReadSubChannel(2, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)m_max_sectors, ref _subchannelBuffer, _timeout); + // PLEXTOR PX-W1210A always returns data, even if asked only for subchannel. + // So we fill the buffer with magic data, give extra space for command so it won't hang the drive, + // request subchannel data and check if magic data was overwritten. + bool overwritten = false; + for (int i = 0; i < 16; i++) + { + _subchannelBuffer[m_max_sectors * (588 * 4 + 16) - 16 + i] = (byte)(13 + i); + } + fixed (byte* data = _subchannelBuffer) + { + st = m_device.ReadCDAndSubChannel(Device.MainChannelSelection.None, Device.SubChannelMode.QOnly, Device.C2ErrorMode.None, 1, false, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)m_max_sectors, (IntPtr)((void*)data), _timeout); + } + for (int i = 0; i < 16; i++) + { + if (_subchannelBuffer[m_max_sectors * (588 * 4 + 16) - 16 + i] != (byte)(13 + i)) + overwritten = true; + } + if (overwritten) + st = Device.CommandStatus.NotSupported; + //else + // st = m_device.ReadSubChannel(2, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)m_max_sectors, ref _subchannelBuffer, _timeout); if (st == Device.CommandStatus.Success) { int[] goodsecs = new int[2]; @@ -712,7 +732,7 @@ namespace CUETools.Ripper.SCSI return true; //ReadCDCommand[] readmode = { ReadCDCommand.ReadCdBEh, ReadCDCommand.ReadCdD8h }; - ReadCDCommand[] readmode = { ReadCDCommand.ReadCdD8h, ReadCDCommand.ReadCdBEh }; + ReadCDCommand[] readmode = { ReadCDCommand.ReadCdBEh, ReadCDCommand.ReadCdD8h }; Device.C2ErrorMode[] c2mode = { Device.C2ErrorMode.Mode294, Device.C2ErrorMode.Mode296, Device.C2ErrorMode.None }; Device.MainChannelSelection[] mainmode = { Device.MainChannelSelection.UserData, Device.MainChannelSelection.F8h }; bool found = false; @@ -731,7 +751,7 @@ namespace CUETools.Ripper.SCSI _mainChannelMode = mainmode[m]; if (_forceReadCommand != ReadCDCommand.Unknown && _readCDCommand != _forceReadCommand) continue; - if (_readCDCommand == ReadCDCommand.ReadCdD8h) // && (_c2ErrorMode != Device.C2ErrorMode.None || _mainChannelMode != Device.MainChannelSelection.UserData)) + if (_readCDCommand == ReadCDCommand.ReadCdD8h && (_c2ErrorMode != Device.C2ErrorMode.None || _mainChannelMode != Device.MainChannelSelection.UserData)) continue; Array.Clear(_readBuffer, 0, _readBuffer.Length); // fill with something nasty instead? DateTime tm = DateTime.Now; @@ -765,12 +785,16 @@ namespace CUETools.Ripper.SCSI // break; // } // } - TestGaps(); - - if (found) - _autodetectResult += "Chosen " + CurrentReadCommand + "\n"; - else - _readCDCommand = ReadCDCommand.Unknown; + if (found) + { + TestGaps(); + _autodetectResult += "Chosen " + CurrentReadCommand + "\n"; + } + else + { + _gapDetection = GapDetectionMethod.None; + _readCDCommand = ReadCDCommand.Unknown; + } _currentStart = -1; _currentEnd = -1; diff --git a/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs b/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs index 3727fb6..512bebb 100644 --- a/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs +++ b/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs @@ -375,7 +375,7 @@ namespace CUETools.TestParity ///Verifying rip that has errors /// [TestMethod()] - //[Ignore] + [Ignore] public void CDRepairVerifyParitySpeedTest() { var generator1 = new TestImageGenerator("0 98011", seed, 32 * 588);