Created
January 10, 2021 05:19
-
-
Save lpproj/47fb1bc33a62fe47b90c63ee86354c46 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
a patch against RaSCSI 1.47 | |
to (minimal) support SCSI-2 compliant LUN (specified by IDENTIFY messages) | |
only tested on Windows XP + Adaptec SlimSCSI 1450C | |
desctiption (日本語): | |
RaSCSIをWindowsに接続したとき、ひとつのIDに0~7まですべてのLUNでドライブが認識されてしまう問題に対する暫定的な修正 | |
history: | |
2021-01-10 lpproj * test (initial) | |
diff --git a/src/raspberrypi/disk.cpp b/src/raspberrypi/disk.cpp | |
--- a/src/raspberrypi/disk.cpp | |
+++ b/src/raspberrypi/disk.cpp | |
@@ -2593,6 +2593,7 @@ int FASTCALL SCSIHD::Inquiry( | |
memset(buf, 0, 8); | |
// SCSI-2 本の p.104 4.4.3 不当なロジカルユニットの処理 | |
+ // (todo: fetch_lun() needed?) | |
if (((cdb[1] >> 5) & 0x07) != disk.lun) { | |
buf[0] = 0x7f; | |
} | |
@@ -6081,6 +6082,9 @@ void FASTCALL SASIDEV::Reset() | |
ctrl.next = 0; | |
ctrl.offset = 0; | |
ctrl.length = 0; | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ ctrl.identify_lun = identify_lun_unspecified; | |
+#endif | |
// ユニット初期化 | |
for (i = 0; i < UnitMax; i++) { | |
@@ -6254,7 +6258,7 @@ Disk* FASTCALL SASIDEV::GetBusyUnit() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
return ctrl.unit[lun]; | |
} | |
@@ -6364,6 +6368,9 @@ void FASTCALL SASIDEV::BusFree() | |
// ステータスとメッセージを初期化 | |
ctrl.status = 0x00; | |
ctrl.message = 0x00; | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ ctrl.identify_lun = identify_lun_unspecified; // to be safe... | |
+#endif | |
return; | |
} | |
@@ -6405,6 +6412,10 @@ void FASTCALL SASIDEV::Selection() | |
// フェーズチェンジ | |
ctrl.phase = BUS::selection; | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ ctrl.identify_lun = identify_lun_unspecified; | |
+#endif | |
+ | |
// BSYを上げて応答 | |
ctrl.bus->SetBSY(TRUE); | |
return; | |
@@ -6926,7 +6937,7 @@ void FASTCALL SASIDEV::Error() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
// ステータスとメッセージを設定(CHECK CONDITION) | |
ctrl.status = (lun << 5) | 0x02; | |
@@ -6952,7 +6963,7 @@ void FASTCALL SASIDEV::CmdTestUnitReady() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -6987,7 +6998,7 @@ void FASTCALL SASIDEV::CmdRezero() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -7021,13 +7032,27 @@ void FASTCALL SASIDEV::CmdRequestSense() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ if (!ctrl.unit[lun] && (IsSCSI() && !ctrl.unit[0])) { | |
+#else | |
if (!ctrl.unit[lun]) { | |
+#endif | |
Error(); | |
return; | |
} | |
// ドライブでコマンド処理 | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ if (IsSCSI() && lun >= 1 && lun <= 7 && !ctrl.unit[lun]) { | |
+ // prepare request data by using unit0 handler (workaround) | |
+ DWORD code0 = ctrl.unit[0]->GetDiskErrorCode(); | |
+ ctrl.unit[0]->SetDiskErrorCode(DISK_INVALIDLUN); | |
+ ctrl.length = ctrl.unit[0]->RequestSense(ctrl.cmd, ctrl.buffer); | |
+ ctrl.unit[0]->SetDiskErrorCode(code0); | |
+ } | |
+ else | |
+#endif | |
ctrl.length = ctrl.unit[lun]->RequestSense(ctrl.cmd, ctrl.buffer); | |
ASSERT(ctrl.length > 0); | |
@@ -7056,7 +7081,7 @@ void FASTCALL SASIDEV::CmdFormat() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -7091,7 +7116,7 @@ void FASTCALL SASIDEV::CmdReassign() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -7122,7 +7147,7 @@ void FASTCALL SASIDEV::CmdRead6() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -7172,7 +7197,7 @@ void FASTCALL SASIDEV::CmdWrite6() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -7226,7 +7251,7 @@ void FASTCALL SASIDEV::CmdSeek6() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -7261,7 +7286,7 @@ void FASTCALL SASIDEV::CmdAssign() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -7299,7 +7324,7 @@ void FASTCALL SASIDEV::CmdSpecify() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -7336,7 +7361,7 @@ void FASTCALL SASIDEV::CmdInvalid() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (ctrl.unit[lun]) { | |
// ドライブでコマンド処理 | |
ctrl.unit[lun]->InvalidCmd(); | |
@@ -7668,7 +7693,7 @@ BOOL FASTCALL SASIDEV::XferIn(BYTE *buf) | |
ASSERT(ctrl.phase == BUS::datain); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
return FALSE; | |
} | |
@@ -7718,7 +7743,7 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) | |
ASSERT(ctrl.phase == BUS::dataout); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
return FALSE; | |
} | |
@@ -7804,7 +7829,7 @@ void FASTCALL SASIDEV::FlushUnit() | |
ASSERT(ctrl.phase == BUS::dataout); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
return; | |
} | |
@@ -8067,6 +8092,9 @@ void FASTCALL SCSIDEV::Selection() | |
// フェーズ設定 | |
ctrl.phase = BUS::selection; | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ ctrl.identify_lun = identify_lun_unspecified; | |
+#endif | |
// BSYを上げて応答 | |
ctrl.bus->SetBSY(TRUE); | |
@@ -8389,6 +8417,19 @@ void FASTCALL SCSIDEV::CmdInquiry() | |
// 有効なユニットを探す | |
disk = NULL; | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ lun = ctrl.identify_lun; | |
+ if (lun >= 1 && lun <= identify_lun_max) { | |
+ if (ctrl.unit[lun]) | |
+ disk = ctrl.unit[lun]; | |
+ if (!disk) { | |
+ ctrl.length = 0; | |
+ Error(); | |
+ return; | |
+ } | |
+ } | |
+ else | |
+#endif | |
for (lun = 0; lun < UnitMax; lun++) { | |
if (ctrl.unit[lun]) { | |
disk = ctrl.unit[lun]; | |
@@ -8441,7 +8482,7 @@ void FASTCALL SCSIDEV::CmdModeSelect() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8475,7 +8516,7 @@ void FASTCALL SCSIDEV::CmdModeSense() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8514,7 +8555,7 @@ void FASTCALL SCSIDEV::CmdStartStop() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8549,7 +8590,7 @@ void FASTCALL SCSIDEV::CmdSendDiag() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8584,7 +8625,7 @@ void FASTCALL SCSIDEV::CmdRemoval() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8619,7 +8660,7 @@ void FASTCALL SCSIDEV::CmdReadCapacity() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8653,7 +8694,7 @@ void FASTCALL SCSIDEV::CmdRead10() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8715,7 +8756,7 @@ void FASTCALL SCSIDEV::CmdWrite10() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8782,7 +8823,7 @@ void FASTCALL SCSIDEV::CmdSeek10() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8814,7 +8855,7 @@ void FASTCALL SCSIDEV::CmdVerify() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8885,7 +8926,7 @@ void FASTCALL SCSIDEV::CmdSynchronizeCache() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8913,7 +8954,7 @@ void FASTCALL SCSIDEV::CmdReadDefectData10() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8944,7 +8985,7 @@ void FASTCALL SCSIDEV::CmdReadToc() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -8975,7 +9016,7 @@ void FASTCALL SCSIDEV::CmdPlayAudio10() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -9006,7 +9047,7 @@ void FASTCALL SCSIDEV::CmdPlayAudioMSF() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -9037,7 +9078,7 @@ void FASTCALL SCSIDEV::CmdPlayAudioTrack() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -9071,7 +9112,7 @@ void FASTCALL SCSIDEV::CmdModeSelect10() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -9105,7 +9146,7 @@ void FASTCALL SCSIDEV::CmdModeSense10() | |
#endif // DISK_LOG | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -9140,7 +9181,7 @@ void FASTCALL SCSIDEV::CmdGetMessage10() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -9189,7 +9230,7 @@ void FASTCALL SCSIDEV::CmdSendMessage10() | |
ASSERT(this); | |
// 論理ユニット | |
- lun = (ctrl.cmd[1] >> 5) & 0x07; | |
+ lun = fetch_lun(); // (ctrl.cmd[1] >> 5) & 0x07; | |
if (!ctrl.unit[lun]) { | |
Error(); | |
return; | |
@@ -9622,6 +9663,11 @@ void FASTCALL SCSIDEV::ReceiveNext() | |
Log(Log::Normal, | |
"メッセージコード IDENTIFY $%02X", data); | |
#endif // DISK_LOG | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ if ((data & 0x20) == 0) { // LUNTAR == 0 | |
+ ctrl.identify_lun = data & 0x07; | |
+ } | |
+#endif | |
} | |
// 拡張メッセージ | |
diff --git a/src/raspberrypi/disk.h b/src/raspberrypi/disk.h | |
--- a/src/raspberrypi/disk.h | |
+++ b/src/raspberrypi/disk.h | |
@@ -20,6 +20,8 @@ | |
#include "log.h" | |
#include "scsi.h" | |
+#define SUPPORT_SCSI2_LUN 1 | |
+ | |
//--------------------------------------------------------------------------- | |
// | |
// エラー定義(REQUEST SENSEで返されるセンスコード) | |
@@ -352,6 +354,11 @@ protected: | |
// パス(GetPath用) | |
BOOL cache_wb; | |
// キャッシュモード | |
+#ifdef SUPPORT_SCSI2_LUN | |
+public: | |
+ DWORD GetDiskErrorCode() { return disk.code; } | |
+ void SetDiskErrorCode(DWORD code) { disk.code = code; } | |
+#endif | |
}; | |
//=========================================================================== | |
@@ -881,6 +888,11 @@ public: | |
// 論理ユニット | |
Disk *unit[UnitMax]; | |
// 論理ユニット | |
+ | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ // logical unit number, specified by IDENTIFY message (optional in SCSI-1, mandatory in SCSI-2) | |
+ int identify_lun; | |
+#endif | |
} ctrl_t; | |
public: | |
@@ -1012,6 +1024,18 @@ protected: | |
ctrl_t ctrl; | |
// 内部データ | |
+ | |
+public: | |
+#ifdef SUPPORT_SCSI2_LUN | |
+ enum { | |
+ identify_lun_unspecified = -1, | |
+ identify_lun_min = 0, | |
+ identify_lun_max = 7 | |
+ }; | |
+ inline DWORD fetch_lun() { return (ctrl.identify_lun >= identify_lun_min && ctrl.identify_lun <= identify_lun_max) ? (DWORD)(ctrl.identify_lun) : ((ctrl.cmd[1] >> 5) & 0x07); } | |
+#else | |
+ inline DWORD fetch_lun() { return (ctrl.cmd[1] >> 5) & 0x07; } | |
+#endif | |
}; | |
//=========================================================================== |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment