Skip to content

Instantly share code, notes, and snippets.

@lpproj
Created January 10, 2021 05:19
Show Gist options
  • Save lpproj/47fb1bc33a62fe47b90c63ee86354c46 to your computer and use it in GitHub Desktop.
Save lpproj/47fb1bc33a62fe47b90c63ee86354c46 to your computer and use it in GitHub Desktop.
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