]> localhost Git - SCSI2SD-V6.git/commitdiff
Move blockDev states into device independent struct and deal with config loading
authorMichael McMaster <michael@codesrc.com>
Tue, 8 Dec 2020 12:28:37 +0000 (22:28 +1000)
committerMichael McMaster <michael@codesrc.com>
Tue, 8 Dec 2020 12:28:37 +0000 (22:28 +1000)
14 files changed:
src/firmware/config.c
src/firmware/config.h
src/firmware/device.c
src/firmware/device.h
src/firmware/disk.c
src/firmware/disk.h
src/firmware/main.c
src/firmware/mode.c
src/firmware/mode.h
src/firmware/scsi.c
src/firmware/scsiPhy.c
src/firmware/sd.c
src/firmware/sd.h
src/firmware/usb_device/usbd_msc_storage_sd.c

index 1c7b21c33ee86f2faee4ff457f85a423d55a24f0..b19492e47894dfd0f89c312c7b98243f399b2ae5 100755 (executable)
 \r
 #include <string.h>\r
 \r
-static const uint16_t FIRMWARE_VERSION = 0x0632;\r
-\r
-// Optional static config\r
-extern uint8_t* __fixed_config;\r
+static const uint16_t FIRMWARE_VERSION = 0x0640;\r
 \r
 // 1 flash row\r
-static const uint8_t DEFAULT_CONFIG[128] =\r
+const uint8_t DEFAULT_TARGET_CONFIG[128] =\r
 {\r
        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00,\r
        0x00, 0x02, 0x3F, 0x00, 0xFF, 0x00, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x73,\r
@@ -90,40 +87,7 @@ void s2s_configInit(S2S_BoardCfg* config)
 {\r
        usbInEpState = USB_IDLE;\r
 \r
-       if (memcmp(__fixed_config, "BCFG", 4) == 0)\r
-       {\r
-               // Use hardcoded config\r
-               memcpy(s2s_cfg, __fixed_config, S2S_CFG_SIZE);\r
-               memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
-       }\r
-\r
-       else if ((blockDev.state & DISK_PRESENT) && sdCard.capacity)\r
-       {\r
-               int cfgSectors = (S2S_CFG_SIZE + 511) / 512;\r
-               BSP_SD_ReadBlocks_DMA(\r
-                       (uint32_t*) &s2s_cfg[0],\r
-                       (sdCard.capacity - cfgSectors) * 512ll,\r
-                       512,\r
-                       cfgSectors);\r
-\r
-               memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
-\r
-               if (memcmp(config->magic, "BCFG", 4))\r
-               {\r
-                       // Invalid SD card config, use default.\r
-                       memset(&s2s_cfg[0], 0, S2S_CFG_SIZE);\r
-                       memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
-                       memcpy(config->magic, "BCFG", 4);\r
-                       config->selectionDelay = 255; // auto\r
-                       config->flags6 = S2S_CFG_ENABLE_TERMINATOR;\r
-\r
-                       memcpy(\r
-                               &s2s_cfg[0] + sizeof(S2S_BoardCfg),\r
-                               DEFAULT_CONFIG,\r
-                               sizeof(S2S_TargetCfg));\r
-               }\r
-       }\r
-       else\r
+       if (!s2s_DeviceGetBoardConfig(config))\r
        {\r
                // No SD card, use existing config if valid\r
                if (memcmp(config->magic, "BCFG", 4))\r
@@ -225,7 +189,7 @@ debugCommand()
        response[23] = scsiDev.msgCount;\r
        response[24] = scsiDev.cmdCount;\r
        response[25] = scsiDev.watchdogTick;\r
-       response[26] = blockDev.state;\r
+       response[26] = 0; // OBSOLETE. Previously media state;\r
        response[27] = scsiDev.lastSenseASC >> 8;\r
        response[28] = scsiDev.lastSenseASC;\r
        response[29] = *SCSI_STS_DBX & 0xff; // What we've read\r
@@ -435,39 +399,3 @@ void s2s_debugTimer()
 }\r
 \r
 \r
-\r
-// Public method for storing MODE SELECT results.\r
-void s2s_configSave(int scsiId, uint16_t bytesPerSector)\r
-{\r
-       S2S_TargetCfg* cfg = (S2S_TargetCfg*) s2s_getConfigById(scsiId);\r
-       cfg->bytesPerSector = bytesPerSector;\r
-\r
-       BSP_SD_WriteBlocks_DMA(\r
-               (uint32_t*) &s2s_cfg[0],\r
-               (sdCard.capacity - S2S_CFG_SIZE) * 512ll,\r
-               512,\r
-               (S2S_CFG_SIZE + 511) / 512);\r
-}\r
-\r
-\r
-const S2S_TargetCfg* s2s_getConfigByIndex(int i)\r
-{\r
-       return (const S2S_TargetCfg*)\r
-               (s2s_cfg + sizeof(S2S_BoardCfg) + (i * sizeof(S2S_TargetCfg)));\r
-}\r
-\r
-const S2S_TargetCfg* s2s_getConfigById(int scsiId)\r
-{\r
-       int i;\r
-       for (i = 0; i < S2S_MAX_TARGETS; ++i)\r
-       {\r
-               const S2S_TargetCfg* tgt = s2s_getConfigByIndex(i);\r
-               if ((tgt->scsiId & S2S_CFG_TARGET_ID_BITS) == scsiId)\r
-               {\r
-                       return tgt;\r
-               }\r
-       }\r
-       return NULL;\r
-\r
-}\r
-\r
index bed86a4cc68c8f126f7888b417bcd0d1aa556976..e415528cf49fb0a85440c7d1e1a1804b508e56da 100755 (executable)
 #define S2S_Config_H\r
 \r
 #include "scsi2sd.h"\r
+#include "device.h"\r
 \r
 void s2s_configInit(S2S_BoardCfg* config);\r
 void s2s_debugInit(void);\r
 void s2s_configPoll(void);\r
-void s2s_configSave(int scsiId, uint16_t byesPerSector);\r
 \r
-const S2S_TargetCfg* s2s_getConfigByIndex(int index);\r
-const S2S_TargetCfg* s2s_getConfigById(int scsiId);\r
+extern const uint8_t DEFAULT_TARGET_CONFIG[128];\r
+\r
+// Optional static config\r
+extern uint8_t* __fixed_config;\r
+\r
 \r
 #endif\r
index e3ff9ea03044e425037f32c14a80317d19d5f619..78e74fac1e8b067adb0b50fbc1246edc4372e779 100644 (file)
 #include "sd.h"
 
 #include <stddef.h>
+#include <string.h>
+
+int s2s_DeviceGetBoardConfig(S2S_BoardCfg* config)
+{
+       int deviceCount;
+       S2S_Device* devices = s2s_GetDevices(&deviceCount);
+       for (int deviceIdx = 0; deviceIdx < deviceCount; ++deviceIdx)
+       {
+               const S2S_BoardCfg* devCfg = devices[deviceIdx].getBoardConfig(devices + deviceIdx);
+               if (devCfg)
+               {
+                       memcpy(config, devCfg, sizeof(S2S_BoardCfg));
+                       return 1;
+               }
+       }
+
+       return 0;
+}
 
 S2S_Target* s2s_DeviceFindByScsiId(int scsiId)
 {
@@ -33,7 +51,7 @@ S2S_Target* s2s_DeviceFindByScsiId(int scsiId)
                        S2S_Target* target = targets + targetIdx;
                        if (target &&
                                (target->cfg->scsiId & S2S_CFG_TARGET_ENABLED) &&
-                               ((target->cfg->scsiId & 7) == scsiId))
+                               ((target->cfg->scsiId & S2S_CFG_TARGET_ID_BITS) == scsiId))
                        {
                                return target;
                        }
@@ -49,3 +67,25 @@ S2S_Device* s2s_GetDevices(int* count)
        return sdDevice;
 }
 
+void s2s_deviceEarlyInit()
+{
+       int count;
+       S2S_Device* devices = s2s_GetDevices(&count);
+       for (int i = 0; i < count; ++i)
+       {
+               devices[i].earlyInit(&(devices[i]));
+       }
+}
+
+int s2s_pollMediaChange()
+{
+       int result = 0;
+       int count;
+       S2S_Device* devices = s2s_GetDevices(&count);
+       for (int i = 0; i < count; ++i)
+       {
+               int devResult = devices[i].pollMediaChange(&(devices[i]));
+               result = result || devResult;
+       }
+       return result;
+}
index 324c266c40f859dde3b95c87b8ddaa2528415201..73a6a7d6bd608b03bffcb46cae806edcb31ba880 100644 (file)
@@ -31,6 +31,14 @@ typedef struct S2S_TargetStruct S2S_Target;
 struct S2S_TargetStateStruct;
 typedef struct S2S_TargetStateStruct S2S_TargetState;
 
+typedef enum
+{
+       MEDIA_STARTED = 1,     // Controlled via START STOP UNIT
+       MEDIA_PRESENT = 2,     // SD card is physically present
+       MEDIA_INITIALISED = 4, // SD card responded to init sequence
+       MEDIA_WP = 8           // Write-protect.
+} MEDIA_STATE;
+
 struct S2S_TargetStateStruct
 {
        ScsiSense sense;
@@ -52,8 +60,6 @@ struct S2S_TargetStateStruct
 
 struct S2S_TargetStruct
 {
-       uint8_t id;
-
        S2S_Device* device;
        S2S_TargetCfg* cfg;
 
@@ -62,20 +68,28 @@ struct S2S_TargetStruct
 
 struct S2S_DeviceStruct
 {
+       void (*earlyInit)(S2S_Device* dev);
+
        const S2S_BoardCfg* (*getBoardConfig)(S2S_Device* dev);
-       //const S2S_Target* (*findByScsiId)(S2S_Device* dev, int scsiId);
        S2S_Target* (*getTargets)(S2S_Device* dev, int* count);
 
        // Get the number of 512 byte blocks
        uint32_t (*getCapacity)(S2S_Device* dev);
 
+       int (*pollMediaChange)(S2S_Device* dev);
+
+       void (*saveConfig)(S2S_Target* target);
+
+       MEDIA_STATE mediaState;
 };
 
-void s2s_DeviceGetBoardConfig(S2S_BoardCfg* config);
+int s2s_DeviceGetBoardConfig(S2S_BoardCfg* config);
 S2S_Target* s2s_DeviceFindByScsiId(int scsiId);
 
 S2S_Device* s2s_GetDevices(int* count);
 
+void s2s_deviceEarlyInit();
+int s2s_pollMediaChange();
 #endif
 
 
index 79951b0a834267a218f42add00fa809d770a8b16..99f5624b5b574afbfc6fa3b66c4bc399d516582a 100755 (executable)
 #include <string.h>\r
 \r
 // Global\r
-BlockDevice blockDev;\r
 Transfer transfer;\r
 \r
-static int doSdInit()\r
-{\r
-       int result = 0;\r
-       if (blockDev.state & DISK_PRESENT)\r
-       {\r
-               blockDev.state = blockDev.state | DISK_INITIALISED;\r
-       }\r
-       return result;\r
-}\r
-\r
 // Callback once all data has been read in the data out phase.\r
 static void doFormatUnitComplete(void)\r
 {\r
@@ -94,9 +83,7 @@ static void doFormatUnitHeader(void)
        if (! DSP) // disable save parameters\r
        {\r
                // Save the "MODE SELECT savable parameters"\r
-               s2s_configSave(\r
-                       scsiDev.target->id,\r
-                       scsiDev.target->state.bytesPerSector);\r
+               scsiDev.target->device->saveConfig(scsiDev.target);\r
        }\r
 \r
        if (IP)\r
@@ -178,7 +165,7 @@ static void doWrite(uint32_t lba, uint32_t blocks)
 \r
        uint32_t bytesPerSector = scsiDev.target->state.bytesPerSector;\r
 \r
-       if (unlikely(blockDev.state & DISK_WP) ||\r
+       if (unlikely(scsiDev.target->device->mediaState & MEDIA_WP) ||\r
                unlikely(scsiDev.target->cfg->deviceType == S2S_CFG_OPTICAL))\r
 \r
        {\r
@@ -213,15 +200,6 @@ static void doWrite(uint32_t lba, uint32_t blocks)
                // No need for single-block writes atm.  Overhead of the\r
                // multi-block write is minimal.\r
                transfer.multiBlock = 1;\r
-\r
-\r
-               // TODO uint32_t sdLBA =\r
-// TODO                        SCSISector2SD(\r
-       // TODO                         scsiDev.target->cfg->sdSectorStart,\r
-               // TODO                 bytesPerSector,\r
-                       // TODO         lba);\r
-               // TODO uint32_t sdBlocks = blocks * SDSectorsPerSCSISector(bytesPerSector);\r
-               // TODO sdWriteMultiSectorPrep(sdLBA, sdBlocks);\r
        }\r
 }\r
 \r
@@ -308,12 +286,14 @@ static void doSeek(uint32_t lba)
 \r
 static int doTestUnitReady()\r
 {\r
+       MEDIA_STATE* mediaState = &(scsiDev.target->device->mediaState);\r
+\r
        int ready = 1;\r
-       if (likely(blockDev.state == (DISK_STARTED | DISK_PRESENT | DISK_INITIALISED)))\r
+       if (likely(*mediaState == (MEDIA_STARTED | MEDIA_PRESENT | MEDIA_INITIALISED)))\r
        {\r
                // nothing to do.\r
        }\r
-       else if (unlikely(!(blockDev.state & DISK_STARTED)))\r
+       else if (unlikely(!(*mediaState & MEDIA_STARTED)))\r
        {\r
                ready = 0;\r
                scsiDev.status = CHECK_CONDITION;\r
@@ -321,7 +301,7 @@ static int doTestUnitReady()
                scsiDev.target->state.sense.asc = LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED;\r
                scsiDev.phase = STATUS;\r
        }\r
-       else if (unlikely(!(blockDev.state & DISK_PRESENT)))\r
+       else if (unlikely(!(*mediaState & MEDIA_PRESENT)))\r
        {\r
                ready = 0;\r
                scsiDev.status = CHECK_CONDITION;\r
@@ -329,7 +309,7 @@ static int doTestUnitReady()
                scsiDev.target->state.sense.asc = MEDIUM_NOT_PRESENT;\r
                scsiDev.phase = STATUS;\r
        }\r
-       else if (unlikely(!(blockDev.state & DISK_INITIALISED)))\r
+       else if (unlikely(!(*mediaState & MEDIA_INITIALISED)))\r
        {\r
                ready = 0;\r
                scsiDev.status = CHECK_CONDITION;\r
@@ -354,17 +334,21 @@ int scsiDiskCommand()
                //int immed = scsiDev.cdb[1] & 1;\r
                int start = scsiDev.cdb[4] & 1;\r
 \r
+               MEDIA_STATE* mediaState = &(scsiDev.target->device->mediaState);\r
                if (start)\r
                {\r
-                       blockDev.state = blockDev.state | DISK_STARTED;\r
-                       if (!(blockDev.state & DISK_INITIALISED))\r
+                       *mediaState = *mediaState | MEDIA_STARTED;\r
+                       if (!(*mediaState & MEDIA_INITIALISED))\r
                        {\r
-                               doSdInit();\r
+                               if (*mediaState & MEDIA_PRESENT)\r
+                               {\r
+                                       *mediaState = *mediaState | MEDIA_INITIALISED;\r
+                               }\r
                        }\r
                }\r
                else\r
                {\r
-                       blockDev.state &= ~DISK_STARTED;\r
+                       *mediaState &= ~MEDIA_STARTED;\r
                }\r
        }\r
        else if (unlikely(command == 0x00))\r
@@ -965,8 +949,5 @@ void scsiDiskReset()
 void scsiDiskInit()\r
 {\r
        scsiDiskReset();\r
-\r
-       // Don't require the host to send us a START STOP UNIT command\r
-       blockDev.state = DISK_STARTED;\r
 }\r
 \r
index b1f958fb9352e8f91d9ebf6b6cf5cc02355a2844..0456e2a86cc9019d61362b51522261ffa12459f2 100755 (executable)
 #ifndef DISK_H
 #define DISK_H
 
-typedef enum
-{
-       DISK_STARTED = 1,     // Controlled via START STOP UNIT
-       DISK_PRESENT = 2,     // SD card is physically present
-       DISK_INITIALISED = 4, // SD card responded to init sequence
-       DISK_WP = 8           // Write-protect.
-} DISK_STATE;
-
 typedef enum
 {
        TRANSFER_READ,
        TRANSFER_WRITE
 } TRANSFER_DIR;
 
-typedef struct
-{
-       int state;
-} BlockDevice;
-
 typedef struct
 {
        int multiBlock; // True if we're using a multi-block SPI transfer.
@@ -45,7 +32,6 @@ typedef struct
        uint32_t currentBlock;
 } Transfer;
 
-extern BlockDevice blockDev;
 extern Transfer transfer;
 
 void scsiDiskInit(void);
index 6392c4fbabe09d983e72f03688ed50a2f028deb8..f3041f81713072b14b34dc78d3db8d1a90025d09 100755 (executable)
@@ -33,7 +33,6 @@
 #include "usb_device/usbd_msc_storage_sd.h"\r
 \r
 const char* Notice = "Copyright (C) 2020 Michael McMaster <michael@codesrc.com>";\r
-uint32_t lastSDPoll;\r
 \r
 static int isUsbStarted;\r
 \r
@@ -53,7 +52,7 @@ void mainInit()
 \r
        s2s_ledInit();\r
        s2s_fpgaInit();\r
-\r
+       s2s_deviceEarlyInit();\r
        scsiPhyInit();\r
 \r
        scsiDiskInit();\r
@@ -79,7 +78,6 @@ void mainInit()
                ++delaySeconds;\r
        }\r
 \r
-       lastSDPoll = s2s_getTime_ms();\r
 }\r
 \r
 void mainLoop()\r
@@ -91,89 +89,22 @@ void mainLoop()
        s2s_configPoll();\r
        s2s_usbDevicePoll();\r
 \r
-#if 0\r
-       sdPoll();\r
-#endif\r
-\r
        if (unlikely(scsiDev.phase == BUS_FREE))\r
        {\r
-               if (unlikely(s2s_elapsedTime_ms(lastSDPoll) > 200))\r
-               {\r
-                       lastSDPoll = s2s_getTime_ms();\r
-                       if (sdInit())\r
-                       {\r
-                               s2s_configInit(&scsiDev.boardCfg);\r
-                               scsiPhyConfig();\r
-                               scsiInit();\r
-\r
-                               // Is a USB host connected ?\r
-/* TODO DEAL WITH THIS\r
-                               if (isUsbStarted)\r
-                               {\r
-                                       USBD_Stop(&hUsbDeviceFS);\r
-                                       s2s_delay_ms(128);\r
-                                       USBD_Start(&hUsbDeviceFS);\r
-                               }\r
-*/                     \r
-                       }\r
-\r
-/* TODO DEAL WITH THIS\r
-                       // Can we speed up the SD card ?\r
-                       // Don't combine with the above block because that won't\r
-                       // run if the SD card is present at startup.\r
-                       // Don't use VBUS monitoring because that just tells us about\r
-                       // power, which could be from a charger\r
-                       if ((blockDev.state & DISK_PRESENT) &&\r
-                               isUsbStarted &&\r
-                               (scsiDev.cmdCount > 0) && // no need for speed without scsi\r
-                               !USBD_Composite_IsConfigured(&hUsbDeviceFS) &&\r
-                               (scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_TURBO))\r
-                       {\r
-                               if (HAL_SD_HighSpeed(&hsd) == SD_OK)\r
-                               {\r
-                                       USBD_Stop(&hUsbDeviceFS);\r
-                                       s2s_setFastClock();\r
-                                       isUsbStarted = 0;\r
-                               }\r
-                       }\r
-\r
-                       else if (!(blockDev.state & DISK_PRESENT) && !isUsbStarted)\r
-                       {\r
-                               // Good time to restart USB.\r
-                               s2s_setNormalClock();\r
-                               USBD_Start(&hUsbDeviceFS);\r
-                               isUsbStarted = 1;\r
-                       }\r
-       */\r
-               }\r
-               else\r
+               if (s2s_pollMediaChange())\r
                {\r
-                       // TODO this hurts performance significantly! Work out why __WFI()\r
-                       // doesn't wake up immediately !\r
-#if 0\r
-                       // Wait for our 1ms timer to save some power.\r
-                       // There's an interrupt on the SEL signal to ensure we respond\r
-                       // quickly to any SCSI commands. The selection abort time is\r
-                       // only 250us, and new SCSI-3 controllers time-out very\r
-                       // not long after that, so we need to ensure we wake up quickly.\r
-                       uint32_t interruptState = __get_PRIMASK();\r
-                       __disable_irq();\r
-\r
-                       if (!*SCSI_STS_SELECTED)\r
-                       {\r
-                               //__WFI(); // Will wake on interrupt, regardless of mask\r
-                       }\r
-                       if (!interruptState)\r
-                       {\r
-                               __enable_irq();\r
-                       }\r
-#endif\r
+                       s2s_configInit(&scsiDev.boardCfg);\r
+                       scsiPhyConfig();\r
+                       scsiInit();\r
                }\r
        }\r
+#warning MOVE THIS CODE TO SD READ/WRITE METHODS\r
+#if 0\r
        else if ((scsiDev.phase >= 0) && (blockDev.state & DISK_PRESENT))\r
        {\r
                // don't waste time scanning SD cards while we're doing disk IO\r
                lastSDPoll = s2s_getTime_ms();\r
        }\r
+#endif\r
 }\r
 \r
index 64823e7ba0d1aee3c6d6a4b44d5df1222b14287a..6fa6641d0eb3fc41cfd31422a78f7c82497cd020 100755 (executable)
@@ -257,7 +257,12 @@ static void pageIn(int pc, int dataIdx, const uint8_t* pageData, int pageLen)
 }\r
 \r
 static void doModeSense(\r
-       int sixByteCmd, int dbd, int pc, int pageCode, int allocLength)\r
+       S2S_Device* dev,\r
+       int sixByteCmd,\r
+       int dbd,\r
+       int pc,\r
+       int pageCode,\r
+       int allocLength)\r
 {\r
        ////////////// Mode Parameter Header\r
        ////////////////////////////////////\r
@@ -276,14 +281,14 @@ static void doModeSense(
                mediumType = 0; // We should support various floppy types here!\r
                // Contains cache bits (0) and a Write-Protect bit.\r
                deviceSpecificParam =\r
-                       (blockDev.state & DISK_WP) ? 0x80 : 0;\r
+                       (dev->mediaState & MEDIA_WP) ? 0x80 : 0;\r
                density = 0; // reserved for direct access\r
                break;\r
 \r
        case S2S_CFG_FLOPPY_14MB:\r
                mediumType = 0x1E; // 90mm/3.5"\r
                deviceSpecificParam =\r
-                       (blockDev.state & DISK_WP) ? 0x80 : 0;\r
+                       (dev->mediaState & MEDIA_WP) ? 0x80 : 0;\r
                density = 0; // reserved for direct access\r
                break;\r
 \r
@@ -296,14 +301,14 @@ static void doModeSense(
        case S2S_CFG_SEQUENTIAL:\r
                mediumType = 0; // reserved\r
                deviceSpecificParam =\r
-                       (blockDev.state & DISK_WP) ? 0x80 : 0;\r
-               density = 0x13; // DAT Data Storage, X3B5/88-185A \r
+                       (dev->mediaState & MEDIA_WP) ? 0x80 : 0;\r
+               density = 0x13; // DAT Data Storage, X3B5/88-185A\r
                break;\r
 \r
        case S2S_CFG_MO:\r
         mediumType = 0x03; // Optical reversible or erasable medium\r
                deviceSpecificParam =\r
-                       (blockDev.state & DISK_WP) ? 0x80 : 0;\r
+                       (dev->mediaState & MEDIA_WP) ? 0x80 : 0;\r
                density = 0x00; // Default\r
                break;\r
 \r
@@ -611,7 +616,7 @@ static void doModeSelect(void)
                                scsiDev.target->state.bytesPerSector = bytesPerSector;\r
                                if (bytesPerSector != scsiDev.target->cfg->bytesPerSector)\r
                                {\r
-                                       s2s_configSave(scsiDev.target->id, bytesPerSector);\r
+                                       scsiDev.target->device->saveConfig(scsiDev.target);\r
                                }\r
                        }\r
                }\r
@@ -644,7 +649,7 @@ static void doModeSelect(void)
                                scsiDev.target->state.bytesPerSector = bytesPerSector;\r
                                if (scsiDev.cdb[1] & 1) // SP Save Pages flag\r
                                {\r
-                                       s2s_configSave(scsiDev.target->id, bytesPerSector);\r
+                                       scsiDev.target->device->saveConfig(scsiDev.target);\r
                                }\r
                        }\r
                        break;\r
@@ -667,7 +672,7 @@ out:
        scsiDev.phase = STATUS;\r
 }\r
 \r
-int scsiModeCommand()\r
+int scsiModeCommand(S2S_Device* dev)\r
 {\r
        int commandHandled = 1;\r
 \r
@@ -687,7 +692,7 @@ int scsiModeCommand()
                // SCSI1 standard: (CCS X3T9.2/86-52)\r
                // "An Allocation Length of zero indicates that no MODE SENSE data shall\r
                // be transferred. This condition shall not be considered as an error."\r
-               doModeSense(1, dbd, pc, pageCode, allocLength);\r
+               doModeSense(dev, 1, dbd, pc, pageCode, allocLength);\r
        }\r
        else if (command == 0x5A)\r
        {\r
@@ -698,7 +703,7 @@ int scsiModeCommand()
                int allocLength =\r
                        (((uint16_t) scsiDev.cdb[7]) << 8) +\r
                        scsiDev.cdb[8];\r
-               doModeSense(0, dbd, pc, pageCode, allocLength);\r
+               doModeSense(dev, 0, dbd, pc, pageCode, allocLength);\r
        }\r
        else if (command == 0x15)\r
        {\r
index 819b1f531803c8fa5ab580a339a880331e7cdeb4..887e91ab6029058bed512dda782b4c2e71bd8284 100755 (executable)
@@ -17,6 +17,6 @@
 #ifndef MODE_H
 #define MODE_H
 
-int scsiModeCommand(void);
+int scsiModeCommand(S2S_Device* dev);
 
 #endif
index 51f686841e077e156a576633970453e977b8c852..db7224df7ef7f2e18d90b3b857b74b8454db0f70 100755 (executable)
@@ -190,7 +190,7 @@ void process_Status()
        }\r
        else if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_OMTI)\r
        {\r
-               scsiDev.status |= (scsiDev.target->id & 0x03) << 5;\r
+               scsiDev.status |= (scsiDev.target->cfg->scsiId & 0x03) << 5;\r
                scsiWriteByte(scsiDev.status);\r
        }\r
        else\r
@@ -479,7 +479,7 @@ static void process_Command()
        {\r
                scsiReadBuffer();\r
        }\r
-       else if (!scsiModeCommand() && !scsiVendorCommand())\r
+       else if (!scsiModeCommand(scsiDev.target->device) && !scsiVendorCommand())\r
        {\r
                scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
                scsiDev.target->state.sense.asc = INVALID_COMMAND_OPERATION_CODE;\r
@@ -1152,11 +1152,6 @@ void scsiInit()
 \r
                        state->syncOffset = 0;\r
                        state->syncPeriod = 0;\r
-\r
-                       // TODO This should probably be done in a device-specific init function.\r
-                       targets[i].cfg = s2s_getConfigByIndex(i);\r
-                       targets[i].id = targets[i].cfg->scsiId;\r
-                       targets[i].device = &(devices[deviceIdx]);\r
                }\r
        }\r
        firstInit = 0;\r
index 887b3d088079741c69d093a9e7f93af37a6b6ad5..b4623e97913689630ebc6a08a70aa803c2952f8c 100755 (executable)
@@ -875,8 +875,8 @@ void scsiPhyConfig()
        uint8_t idMask = 0;\r
        for (int i = 0; i < 8; ++i)\r
        {\r
-               const S2S_TargetCfg* cfg = s2s_getConfigById(i);\r
-               if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))\r
+               const S2S_Target* tgt = s2s_DeviceFindByScsiId(i);\r
+               if (tgt && (tgt->cfg->scsiId & S2S_CFG_TARGET_ENABLED))\r
                {\r
                        idMask |= (1 << i);\r
                }\r
index 7f4b7e8b195588360a7fe30835037f49781516b3..e694b8932de338094f756094188105cca9d58067 100755 (executable)
 \r
 #include <string.h>\r
 \r
+static void sd_earlyInit(S2S_Device* dev);\r
 static const S2S_BoardCfg* sd_getBoardConfig(S2S_Device* dev);\r
-//static const S2S_TargetCfg* sd_findByScsiId(S2S_Device* dev, int scsiId);\r
 static S2S_Target* sd_getTargets(S2S_Device* dev, int* count);\r
 static uint32_t sd_getCapacity(S2S_Device* dev);\r
+static int sd_pollMediaChange(S2S_Device* dev);\r
+static void sd_saveConfig(S2S_Target* target);\r
 \r
 // Global\r
 SdCard sdCard S2S_DMA_ALIGN = {\r
                {\r
+                       sd_earlyInit,\r
                        sd_getBoardConfig,\r
-                       //sd_findByScsiId,\r
                        sd_getTargets,\r
-                       sd_getCapacity\r
+                       sd_getCapacity,\r
+                       sd_pollMediaChange,\r
+                       sd_saveConfig\r
                }\r
 };\r
 \r
 S2S_Device* sdDevice = &(sdCard.dev);\r
 \r
-static int sdCmdActive = 0;\r
+static int sdCmdActive = 0; // TODO MOVE to sdCard\r
 \r
 int\r
 sdReadDMAPoll(uint32_t remainingSectors)\r
@@ -160,7 +164,7 @@ static int sdDoInit()
                memcpy(sdCard.csd, &SDCardInfo.SD_csd, sizeof(sdCard.csd));\r
                memcpy(sdCard.cid, &SDCardInfo.SD_cid, sizeof(sdCard.cid));\r
                sdCard.capacity = SDCardInfo.CardCapacity / SD_SECTOR_SIZE;\r
-               blockDev.state |= DISK_PRESENT | DISK_INITIALISED;\r
+               sdCard.dev.mediaState |= MEDIA_PRESENT | MEDIA_INITIALISED;\r
                result = 1;\r
 \r
                // SD Benchmark code\r
@@ -193,7 +197,7 @@ static int sdDoInit()
        }\r
 \r
 //bad:\r
-       blockDev.state &= ~(DISK_PRESENT | DISK_INITIALISED);\r
+       sdCard.dev.mediaState &= ~(MEDIA_PRESENT | MEDIA_INITIALISED);\r
 \r
        sdCard.capacity = 0;\r
 \r
@@ -211,7 +215,7 @@ int sdInit()
 \r
        if (firstInit)\r
        {\r
-               blockDev.state &= ~(DISK_PRESENT | DISK_INITIALISED);\r
+               sdCard.dev.mediaState &= ~(MEDIA_PRESENT | MEDIA_INITIALISED);\r
                sdClear();\r
                sdInitDMA();\r
        }\r
@@ -221,7 +225,7 @@ int sdInit()
                uint8_t cs = HAL_GPIO_ReadPin(nSD_CD_GPIO_Port, nSD_CD_Pin) ? 0 : 1;\r
                uint8_t wp = HAL_GPIO_ReadPin(nSD_WP_GPIO_Port, nSD_WP_Pin) ? 0 : 1;\r
 \r
-               if (cs && !(blockDev.state & DISK_PRESENT))\r
+               if (cs && !(sdCard.dev.mediaState & MEDIA_PRESENT))\r
                {\r
                        s2s_ledOn();\r
 \r
@@ -233,15 +237,15 @@ int sdInit()
 \r
                        if (sdDoInit())\r
                        {\r
-                               blockDev.state |= DISK_PRESENT | DISK_INITIALISED;\r
+                               sdCard.dev.mediaState |= MEDIA_PRESENT | MEDIA_INITIALISED;\r
 \r
                                if (wp)\r
                                {\r
-                                       blockDev.state |= DISK_WP;\r
+                                       sdCard.dev.mediaState |= MEDIA_WP;\r
                                }\r
                                else\r
                                {\r
-                                       blockDev.state &= ~DISK_WP;\r
+                                       sdCard.dev.mediaState &= ~MEDIA_WP;\r
                                }\r
 \r
                                // Always "start" the device. Many systems (eg. Apple System 7)\r
@@ -249,7 +253,7 @@ int sdInit()
                                // LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED sense\r
                                // code, even if they stopped it first with\r
                                // START STOP UNIT command.\r
-                               blockDev.state |= DISK_STARTED;\r
+                               sdCard.dev.mediaState |= MEDIA_STARTED;\r
 \r
                                result = 1;\r
 \r
@@ -268,11 +272,11 @@ int sdInit()
                                s2s_ledOff();\r
                        }\r
                }\r
-               else if (!cs && (blockDev.state & DISK_PRESENT))\r
+               else if (!cs && (sdCard.dev.mediaState & MEDIA_PRESENT))\r
                {\r
                        sdCard.capacity = 0;\r
-                       blockDev.state &= ~DISK_PRESENT;\r
-                       blockDev.state &= ~DISK_INITIALISED;\r
+                       sdCard.dev.mediaState &= ~MEDIA_PRESENT;\r
+                       sdCard.dev.mediaState &= ~MEDIA_INITIALISED;\r
                        int i;\r
                        for (i = 0; i < S2S_MAX_TARGETS; ++i)\r
                        {\r
@@ -287,22 +291,52 @@ int sdInit()
        return result;\r
 }\r
 \r
+static void sd_earlyInit(S2S_Device* dev)\r
+{\r
+       SdCard* sdCardDevice = (SdCard*)dev;\r
+\r
+       for (int i = 0; i < S2S_MAX_TARGETS; ++i)\r
+       {\r
+               sdCardDevice->targets[i].device = dev;\r
+               sdCardDevice->targets[i].cfg = (const S2S_TargetCfg*)\r
+                       (&(sdCardDevice->cfg[0]) + sizeof(S2S_BoardCfg) + (i * sizeof(S2S_TargetCfg)));\r
+       }\r
+       sdCardDevice->lastPollMediaTime = s2s_getTime_ms();\r
+\r
+       // Don't require the host to send us a START STOP UNIT command\r
+       sdCardDevice->dev.mediaState = MEDIA_STARTED;\r
+\r
+}\r
+\r
 static const S2S_BoardCfg* sd_getBoardConfig(S2S_Device* dev)\r
 {\r
        SdCard* sdCardDevice = (SdCard*)dev;\r
 \r
-       if ((blockDev.state & DISK_PRESENT) && sdCardDevice->capacity)\r
+       if (memcmp(__fixed_config, "BCFG", 4) == 0)\r
+       {\r
+               // Use hardcoded config if available. Hardcoded config always refers\r
+               // to the SD card.\r
+               memcpy(&(sdCardDevice->cfg[0]), __fixed_config, S2S_CFG_SIZE);\r
+               return (S2S_BoardCfg*) &(sdCardDevice->cfg[0]);\r
+       }\r
+       else if ((sdCard.dev.mediaState & MEDIA_PRESENT) && sdCardDevice->capacity)\r
        {\r
                int cfgSectors = (S2S_CFG_SIZE + 511) / 512;\r
                BSP_SD_ReadBlocks_DMA(\r
-                       (uint32_t*) &(sdCardDevice->boardCfg[0]),\r
+                       (uint32_t*) &(sdCardDevice->cfg[0]),\r
                        (sdCardDevice->capacity - cfgSectors) * 512ll,\r
                        512,\r
                        cfgSectors);\r
 \r
-               S2S_BoardCfg* cfg = (S2S_BoardCfg*) &(sdCardDevice->boardCfg[0]);\r
+               S2S_BoardCfg* cfg = (S2S_BoardCfg*) &(sdCardDevice->cfg[0]);\r
                if (memcmp(cfg->magic, "BCFG", 4))\r
                {\r
+                       // Set a default Target disk config\r
+                       memcpy(\r
+                               &(sdCardDevice->cfg[0]) + sizeof(S2S_BoardCfg),\r
+                               DEFAULT_TARGET_CONFIG,\r
+                               sizeof(DEFAULT_TARGET_CONFIG));\r
+\r
                        return NULL;\r
                }\r
                else\r
@@ -314,7 +348,6 @@ static const S2S_BoardCfg* sd_getBoardConfig(S2S_Device* dev)
        return NULL;\r
 }\r
 \r
-//static const S2S_TargetCfg* sd_findByScsiId(S2S_Device* dev, int scsiId)\r
 static S2S_Target* sd_getTargets(S2S_Device* dev, int* count)\r
 {\r
        SdCard* sdCardDevice = (SdCard*)dev;\r
@@ -327,3 +360,29 @@ static uint32_t sd_getCapacity(S2S_Device* dev)
        SdCard* sdCardDevice = (SdCard*)dev;\r
        return sdCardDevice->capacity;\r
 }\r
+\r
+static int sd_pollMediaChange(S2S_Device* dev)\r
+{\r
+       SdCard* sdCardDevice = (SdCard*)dev;\r
+       if (s2s_elapsedTime_ms(sdCardDevice->lastPollMediaTime) > 200)\r
+       {\r
+               sdCardDevice->lastPollMediaTime = s2s_getTime_ms();\r
+               return sdInit();\r
+       }\r
+       else\r
+       {\r
+               return 0;\r
+       }\r
+}\r
+\r
+static void sd_saveConfig(S2S_Target* target)\r
+{\r
+       SdCard* sdCardDevice = (SdCard*)target->device;\r
+       target->cfg->bytesPerSector = target->state.bytesPerSector;\r
+\r
+       BSP_SD_WriteBlocks_DMA(\r
+               (uint32_t*) (&(sdCardDevice->cfg[0])),\r
+               (sdCardDevice->capacity - S2S_CFG_SIZE) * 512ll,\r
+               512,\r
+               (S2S_CFG_SIZE + 511) / 512);\r
+}\r
index 3a3fd556260de61b659af7da3ec72bdc52a17aeb..31a75f733070eb36f7b37e3894cf88e02a849ce6 100755 (executable)
@@ -27,7 +27,7 @@ typedef struct
 {
        S2S_Device dev;
 
-       uint8_t boardCfg[S2S_CFG_SIZE] S2S_DMA_ALIGN;
+       uint8_t cfg[S2S_CFG_SIZE] S2S_DMA_ALIGN;
 
        S2S_Target targets[S2S_MAX_TARGETS];
 
@@ -36,6 +36,9 @@ typedef struct
 
        uint8_t csd[16]; // Unparsed CSD
        uint8_t cid[16]; // Unparsed CID
+
+       uint32_t lastPollMediaTime;
+
 } SdCard;
 
 extern SdCard sdCard; // TODO move to .c file
index b9666ad9edf5f534b79d1189c9af83be11fcb517..8ec82db99aa05df7025d4a09356815f52fd1cf87 100755 (executable)
@@ -129,15 +129,16 @@ int8_t s2s_usbd_storage_IsReady (uint8_t lun)
        const S2S_Target* target = getUsbTarget(lun);
        return (
                        target &&
-                       (blockDev.state & DISK_PRESENT) &&
-                       (blockDev.state & DISK_INITIALISED)
+                       (target->device->mediaState & MEDIA_PRESENT) &&
+                       (target->device->mediaState & MEDIA_INITIALISED)
                        ) ? 0 : 1; // inverse logic
 }
 
 
 int8_t s2s_usbd_storage_IsWriteProtected (uint8_t lun)
 {
-       return blockDev.state & DISK_WP;
+       const S2S_Target* target = getUsbTarget(lun);
+       return target->device->mediaState & MEDIA_WP;
 }
 
 int8_t s2s_usbd_storage_Read (uint8_t lun,