Add scsi mode page 0 support (merge from v5)
authorMichael McMaster <michael@codesrc.com>
Wed, 22 May 2019 10:53:14 +0000 (20:53 +1000)
committerMichael McMaster <michael@codesrc.com>
Wed, 22 May 2019 10:53:14 +0000 (20:53 +1000)
src/firmware/inquiry.c
src/firmware/inquiry.h
src/firmware/mode.c

index 70dca30..99bb8dc 100755 (executable)
@@ -171,20 +171,19 @@ void s2s_scsiInquiry()
                scsiDev.dataLen = allocationLength;\r
 \r
                // Set the device type as needed.\r
+               scsiDev.data[0] = getDeviceTypeQualifier();\r
+\r
                switch (scsiDev.target->cfg->deviceType)\r
                {\r
                case S2S_CFG_OPTICAL:\r
-                       scsiDev.data[0] = 0x05; // device type\r
                        scsiDev.data[1] |= 0x80; // Removable bit.\r
                        break;\r
 \r
                case S2S_CFG_SEQUENTIAL:\r
-                       scsiDev.data[0] = 0x01; // device type\r
                        scsiDev.data[1] |= 0x80; // Removable bit.\r
                        break;\r
 \r
                case S2S_CFG_MO:\r
-                       scsiDev.data[0] = 0x07; // device type\r
                        scsiDev.data[1] |= 0x80; // Removable bit.\r
                        break;\r
 \r
@@ -227,3 +226,32 @@ uint32_t s2s_getStandardInquiry(
                sizeof(cfg->prodId) +\r
                sizeof(cfg->revision);\r
 }\r
+\r
+uint8_t getDeviceTypeQualifier()\r
+{\r
+       // Set the device type as needed.\r
+       switch (scsiDev.target->cfg->deviceType)\r
+       {\r
+       case S2S_CFG_OPTICAL:\r
+               return 0x05;\r
+               break;\r
+\r
+       case S2S_CFG_SEQUENTIAL:\r
+               return 0x01;\r
+               break;\r
+\r
+       case S2S_CFG_MO:\r
+               return 0x07;\r
+               break;\r
+\r
+       case S2S_CFG_FLOPPY_14MB:\r
+       case S2S_CFG_REMOVEABLE:\r
+               return 0;\r
+               break;\r
+\r
+       default:\r
+               // Accept defaults for a fixed disk.\r
+               return 0;\r
+       }\r
+}\r
+\r
index 29da777..963b659 100755 (executable)
@@ -19,5 +19,7 @@
 
 void s2s_scsiInquiry(void);
 uint32_t s2s_getStandardInquiry(const S2S_TargetCfg* cfg, uint8_t* out, uint32_t maxlen);
+uint8_t getDeviceTypeQualifier(void);
+
 
 #endif
index 773059a..fd4ba34 100755 (executable)
 #include "scsi.h"\r
 #include "mode.h"\r
 #include "disk.h"\r
+#include "inquiry.h"\r
 \r
 #include <string.h>\r
 \r
+// "Vendor" defined page which was included by Seagate, and required for\r\r
+// Amiga 500 using DKB SpitFire controller.\r\r
+static const uint8_t OperatingPage[] =\r
+{\r
+0x00, // Page code\r
+0x02, // Page length\r
+\r
+// Bit 4 = unit attension (0 = on, 1 = off).\r
+// Bit 7 = usage bit, EEPROM life exceeded warning = 1.\r
+0x80, \r
+\r
+// Bit 7 = reserved.\r
+// Bits 0:6: Device type qualifier, as per Inquiry data\r
+0x00\r
+};\r
+\r
 static const uint8_t ReadWriteErrorRecoveryPage[] =\r
 {\r
 0x01, // Page code\r
@@ -508,6 +525,21 @@ static void doModeSense(
                idx += sizeof(CCSCachingPage);\r
        }\r
 \r
+       // SCSI 2 standard says page 0 is always last.\r
+       if (pageCode == 0x00 || pageCode == 0x3F)\r
+       {\r
+               pageFound = 1;\r
+               pageIn(pc, idx, OperatingPage, sizeof(OperatingPage));\r
+\r
+               // Note inverted logic for the flag.\r
+               scsiDev.data[idx+2] =\r
+                       (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_UNIT_ATTENTION) ? 0x80 : 0x90;\r
+\r
+               scsiDev.data[idx+3] = getDeviceTypeQualifier();\r
+\r
+               idx += sizeof(OperatingPage);\r
+       }\r
+\r
        if (!pageFound)\r
        {\r
                // Unknown Page Code\r