Plextor PX-W1210A workaround

This commit is contained in:
chudov
2012-01-07 00:17:00 +00:00
parent 4520762a72
commit 7e966f42d9
5 changed files with 49 additions and 23 deletions

View File

@@ -2014,6 +2014,10 @@ namespace Bwg.Scsi
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
None,
/// <summary>
///
/// </summary>
UserData, UserData,
/// <summary> /// <summary>
/// ///
@@ -2056,7 +2060,7 @@ namespace Bwg.Scsi
byte b = (byte)((exp & 0x07) << 2); byte b = (byte)((exp & 0x07) << 2);
if (dap) if (dap)
b |= 0x02; 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) if (c2mode == C2ErrorMode.Mode294)
byte9 |= 0x02; byte9 |= 0x02;
else if (c2mode == C2ErrorMode.Mode296) else if (c2mode == C2ErrorMode.Mode296)
@@ -2066,7 +2070,6 @@ namespace Bwg.Scsi
cmd.SetCDB24(6, length); cmd.SetCDB24(6, length);
cmd.SetCDB8(9, byte9); // User data + possibly c2 errors cmd.SetCDB8(9, byte9); // User data + possibly c2 errors
cmd.SetCDB8(10, mode); // Subchannel cmd.SetCDB8(10, mode); // Subchannel
CommandStatus st = SendCommand(cmd); CommandStatus st = SendCommand(cmd);
if (st != CommandStatus.Success) if (st != CommandStatus.Success)
return st; return st;
@@ -2095,7 +2098,7 @@ namespace Bwg.Scsi
byte mode = (byte)(submode == SubChannelMode.QOnly ? 1 : submode == SubChannelMode.RWMode ? 2 : 0); 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); 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.SetCDB8(1, 0 << 5); // lun
cmd.SetCDB32(2, start); 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)) 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.SetCDB32(2, sector); // The sector number to start with
cmd.SetCDB24(6, length); // The length in sectors cmd.SetCDB24(6, length); // The length in sectors
cmd.SetCDB8(10, mode); // Corrected, de-interleaved P - W data cmd.SetCDB8(10, mode); // Corrected, de-interleaved P - W data

View File

@@ -408,11 +408,10 @@ namespace CUETools.AccurateRip
{ {
int discLen = (int)_toc.AudioLength * 588; int discLen = (int)_toc.AudioLength * 588;
int chunkLen = discLen - prefixSamples - suffixSamples; int chunkLen = discLen - prefixSamples - suffixSamples;
crc = Crc32.Combine( return 0xffffffff ^ Crc32.Combine(
_CRC32[0, prefixSamples], 0xffffffff ^ _CRC32[0, prefixSamples],
_CRC32[_toc.AudioTracks, 2 * maxOffset - suffixSamples], _CRC32[_toc.AudioTracks, 2 * maxOffset - suffixSamples],
chunkLen * 4); 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 posA = (int)_toc[iTrack + _toc.FirstAudio - 1].Start * 588 + (iTrack > 1 ? oi : prefixSamples);
int posB = iTrack < _toc.AudioTracks ? int posB = iTrack < _toc.AudioTracks ?
@@ -437,10 +436,8 @@ namespace CUETools.AccurateRip
_CRC32[iTrack, maxOffset * 2 + oi] : _CRC32[iTrack, maxOffset * 2 + oi] :
_CRC32[iTrack, maxOffset * 2 - suffixSamples]; _CRC32[iTrack, maxOffset * 2 - suffixSamples];
} }
crc = Crc32.Combine(crcA, crcB, (posB - posA) * 4);
// Use 0xffffffff as an initial state // Use 0xffffffff as an initial state
crc = Crc32.Combine(0xffffffff, crc, (posB - posA) * 4) ^ 0xffffffff; return 0xffffffff ^ Crc32.Combine(0xffffffff ^ crcA, crcB, (posB - posA) * 4);
return crc;
} }
public uint CTDBCRC(int offset) public uint CTDBCRC(int offset)

View File

@@ -36,7 +36,7 @@
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath> <OutputPath>..\bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>

View File

@@ -72,7 +72,7 @@ namespace CUETools.Ripper.SCSI
Device.C2ErrorMode _c2ErrorMode = Device.C2ErrorMode.Mode296; Device.C2ErrorMode _c2ErrorMode = Device.C2ErrorMode.Mode296;
string _autodetectResult; string _autodetectResult;
byte[] _readBuffer = new byte[NSECTORS * CB_AUDIO]; byte[] _readBuffer = new byte[NSECTORS * CB_AUDIO];
byte[] _subchannelBuffer = new byte[CB_AUDIO]; byte[] _subchannelBuffer = new byte[NSECTORS * CB_AUDIO];
bool _qChannelInBCD = true; bool _qChannelInBCD = true;
private ReadProgressArgs progressArgs = new ReadProgressArgs(); private ReadProgressArgs progressArgs = new ReadProgressArgs();
@@ -474,7 +474,27 @@ namespace CUETools.Ripper.SCSI
if (_readCDCommand == ReadCDCommand.ReadCdBEh) 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) if (st == Device.CommandStatus.Success)
{ {
int[] goodsecs = new int[2]; int[] goodsecs = new int[2];
@@ -712,7 +732,7 @@ namespace CUETools.Ripper.SCSI
return true; return true;
//ReadCDCommand[] readmode = { ReadCDCommand.ReadCdBEh, ReadCDCommand.ReadCdD8h }; //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.C2ErrorMode[] c2mode = { Device.C2ErrorMode.Mode294, Device.C2ErrorMode.Mode296, Device.C2ErrorMode.None };
Device.MainChannelSelection[] mainmode = { Device.MainChannelSelection.UserData, Device.MainChannelSelection.F8h }; Device.MainChannelSelection[] mainmode = { Device.MainChannelSelection.UserData, Device.MainChannelSelection.F8h };
bool found = false; bool found = false;
@@ -731,7 +751,7 @@ namespace CUETools.Ripper.SCSI
_mainChannelMode = mainmode[m]; _mainChannelMode = mainmode[m];
if (_forceReadCommand != ReadCDCommand.Unknown && _readCDCommand != _forceReadCommand) if (_forceReadCommand != ReadCDCommand.Unknown && _readCDCommand != _forceReadCommand)
continue; 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; continue;
Array.Clear(_readBuffer, 0, _readBuffer.Length); // fill with something nasty instead? Array.Clear(_readBuffer, 0, _readBuffer.Length); // fill with something nasty instead?
DateTime tm = DateTime.Now; DateTime tm = DateTime.Now;
@@ -765,12 +785,16 @@ namespace CUETools.Ripper.SCSI
// break; // break;
// } // }
// } // }
TestGaps();
if (found) if (found)
{
TestGaps();
_autodetectResult += "Chosen " + CurrentReadCommand + "\n"; _autodetectResult += "Chosen " + CurrentReadCommand + "\n";
}
else else
{
_gapDetection = GapDetectionMethod.None;
_readCDCommand = ReadCDCommand.Unknown; _readCDCommand = ReadCDCommand.Unknown;
}
_currentStart = -1; _currentStart = -1;
_currentEnd = -1; _currentEnd = -1;

View File

@@ -375,7 +375,7 @@ namespace CUETools.TestParity
///Verifying rip that has errors ///Verifying rip that has errors
///</summary> ///</summary>
[TestMethod()] [TestMethod()]
//[Ignore] [Ignore]
public void CDRepairVerifyParitySpeedTest() public void CDRepairVerifyParitySpeedTest()
{ {
var generator1 = new TestImageGenerator("0 98011", seed, 32 * 588); var generator1 = new TestImageGenerator("0 98011", seed, 32 * 588);