]> localhost Git - SCSI2SD-V6.git/commitdiff
Refactor code to make getCapacity calls not specific to SD
authorMichael McMaster <michael@codesrc.com>
Tue, 1 Dec 2020 11:24:50 +0000 (11:24 +0000)
committerMichael McMaster <michael@codesrc.com>
Tue, 1 Dec 2020 11:24:50 +0000 (11:24 +0000)
18 files changed:
Makefile
src/firmware/cdrom.c
src/firmware/config.c
src/firmware/device.c [new file with mode: 0644]
src/firmware/device.h [new file with mode: 0644]
src/firmware/diagnostic.c
src/firmware/disk.c
src/firmware/geometry.c
src/firmware/geometry.h
src/firmware/hwversion.c
src/firmware/inquiry.c
src/firmware/mode.c
src/firmware/scsi.c
src/firmware/scsi.h
src/firmware/scsiPhy.c
src/firmware/sd.c
src/firmware/sd.h
src/firmware/usb_device/usbd_msc_storage_sd.c

index df9d40c6a1a981555a9c70419336a2b04274ee34..c92e3dbd6b3c2114bdee793cccd4fef5a3415a2c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -115,6 +115,7 @@ SRC = \
        src/firmware/bsp.c \
        src/firmware/cdrom.c \
        src/firmware/config.c \
+       src/firmware/device.c \
        src/firmware/disk.c \
        src/firmware/diagnostic.c \
        src/firmware/fpga.c \
index c2dc148f82da2c55679402dce2f74a492875082d..de94ca7722b4d5d3e655838d3da870cce1d8b05c 100755 (executable)
@@ -153,8 +153,8 @@ static void doReadTOC(int MSF, uint8_t track, uint16_t allocationLength)
        if (track > 1)
        {
                scsiDev.status = CHECK_CONDITION;
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;
                scsiDev.phase = STATUS;
        }
        else
@@ -163,8 +163,9 @@ static void doReadTOC(int MSF, uint8_t track, uint16_t allocationLength)
                memcpy(scsiDev.data, SimpleTOC, len);
 
                uint32_t capacity = getScsiCapacity(
+                       scsiDev.target->device,
                        scsiDev.target->cfg->sdSectorStart,
-                       scsiDev.target->liveCfg.bytesPerSector,
+                       scsiDev.target->state.bytesPerSector,
                        scsiDev.target->cfg->scsiSectors);
 
                // Replace start of leadout track
@@ -214,8 +215,8 @@ static void doReadFullTOC(int convertBCD, uint8_t session, uint16_t allocationLe
        if (session > 1)
        {
                scsiDev.status = CHECK_CONDITION;
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;
                scsiDev.phase = STATUS;
        }
        else
@@ -298,8 +299,8 @@ int scsiCDRomCommand()
                        default:
                        {
                                scsiDev.status = CHECK_CONDITION;
-                               scsiDev.target->sense.code = ILLEGAL_REQUEST;
-                               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
+                               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;
+                               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;
                                scsiDev.phase = STATUS;
                        }
                }
index df19f9a18b0731a98c49fe2983f0a12c1520cef8..1c7b21c33ee86f2faee4ff457f85a423d55a24f0 100755 (executable)
@@ -97,12 +97,12 @@ void s2s_configInit(S2S_BoardCfg* config)
                memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
        }\r
 \r
-       else if ((blockDev.state & DISK_PRESENT) && sdDev.capacity)\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
-                       (sdDev.capacity - cfgSectors) * 512ll,\r
+                       (sdCard.capacity - cfgSectors) * 512ll,\r
                        512,\r
                        cfgSectors);\r
 \r
@@ -170,9 +170,9 @@ pingCommand()
 static void\r
 sdInfoCommand()\r
 {\r
-       uint8_t response[sizeof(sdDev.csd) + sizeof(sdDev.cid)];\r
-       memcpy(response, sdDev.csd, sizeof(sdDev.csd));\r
-       memcpy(response + sizeof(sdDev.csd), sdDev.cid, sizeof(sdDev.cid));\r
+       uint8_t response[sizeof(sdCard.csd) + sizeof(sdCard.cid)];\r
+       memcpy(response, sdCard.csd, sizeof(sdCard.csd));\r
+       memcpy(response + sizeof(sdCard.csd), sdCard.cid, sizeof(sdCard.cid));\r
 \r
        hidPacket_send(response, sizeof(response));\r
 }\r
@@ -197,10 +197,10 @@ scsiDevInfoCommand()
        {\r
                FIRMWARE_VERSION >> 8,\r
                FIRMWARE_VERSION & 0xff,\r
-               sdDev.capacity >> 24,\r
-               sdDev.capacity >> 16,\r
-               sdDev.capacity >> 8,\r
-               sdDev.capacity,\r
+               sdCard.capacity >> 24,\r
+               sdCard.capacity >> 16,\r
+               sdCard.capacity >> 8,\r
+               sdCard.capacity,\r
                1 // useSdConfig, always true for V6.\r
        };\r
        hidPacket_send(response, sizeof(response));\r
@@ -217,8 +217,8 @@ debugCommand()
        response[15] = scsiDev.lastSense;\r
        response[16] = scsiDev.phase;\r
        response[17] = *SCSI_STS_SCSI;\r
-       response[18] = scsiDev.target != NULL ? scsiDev.target->syncOffset : 0;\r
-       response[19] = scsiDev.target != NULL ? scsiDev.target->syncPeriod : 0;\r
+       response[18] = scsiDev.target != NULL ? scsiDev.target->state.syncOffset : 0;\r
+       response[19] = scsiDev.target != NULL ? scsiDev.target->state.syncPeriod : 0;\r
        response[20] = scsiDev.minSyncPeriod;\r
        response[21] = scsiDev.rstCount;\r
        response[22] = scsiDev.selCount;\r
@@ -444,7 +444,7 @@ void s2s_configSave(int scsiId, uint16_t bytesPerSector)
 \r
        BSP_SD_WriteBlocks_DMA(\r
                (uint32_t*) &s2s_cfg[0],\r
-               (sdDev.capacity - S2S_CFG_SIZE) * 512ll,\r
+               (sdCard.capacity - S2S_CFG_SIZE) * 512ll,\r
                512,\r
                (S2S_CFG_SIZE + 511) / 512);\r
 }\r
diff --git a/src/firmware/device.c b/src/firmware/device.c
new file mode 100644 (file)
index 0000000..e3ff9ea
--- /dev/null
@@ -0,0 +1,51 @@
+//     Copyright (C) 2020 Michael McMaster <michael@codesrc.com>
+//
+//     This file is part of SCSI2SD.
+//
+//     SCSI2SD is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+//
+//     SCSI2SD is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+//
+//     You should have received a copy of the GNU General Public License
+//     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
+#include "device.h"
+
+#include "sd.h"
+
+#include <stddef.h>
+
+S2S_Target* s2s_DeviceFindByScsiId(int scsiId)
+{
+       int deviceCount;
+       S2S_Device* devices = s2s_GetDevices(&deviceCount);
+       for (int deviceIdx = 0; deviceIdx < deviceCount; ++deviceIdx)
+       {
+               int targetCount;
+               S2S_Target* targets = devices[deviceIdx].getTargets(devices + deviceIdx, &targetCount);
+               for (int targetIdx = 0; targetIdx < targetCount; ++targetIdx)
+               {
+                       S2S_Target* target = targets + targetIdx;
+                       if (target &&
+                               (target->cfg->scsiId & S2S_CFG_TARGET_ENABLED) &&
+                               ((target->cfg->scsiId & 7) == scsiId))
+                       {
+                               return target;
+                       }
+               }
+       }
+
+       return NULL;
+}
+
+S2S_Device* s2s_GetDevices(int* count)
+{
+       *count = 1;
+       return sdDevice;
+}
+
diff --git a/src/firmware/device.h b/src/firmware/device.h
new file mode 100644 (file)
index 0000000..324c266
--- /dev/null
@@ -0,0 +1,81 @@
+//     Copyright (C) 2020 Michael McMaster <michael@codesrc.com>
+//
+//     This file is part of SCSI2SD.
+//
+//     SCSI2SD is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+//
+//     SCSI2SD is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+//
+//     You should have received a copy of the GNU General Public License
+//     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
+#ifndef S2S_DEVICE_H
+#define S2S_DEVICE_H
+
+#include "scsi2sd.h"
+#include "sense.h"
+
+#include <stdint.h>
+
+struct S2S_DeviceStruct;
+typedef struct S2S_DeviceStruct S2S_Device;
+
+struct S2S_TargetStruct;
+typedef struct S2S_TargetStruct S2S_Target;
+
+struct S2S_TargetStateStruct;
+typedef struct S2S_TargetStateStruct S2S_TargetState;
+
+struct S2S_TargetStateStruct
+{
+       ScsiSense sense;
+
+       uint16_t unitAttention; // Set to the sense qualifier key to be returned.
+
+       // Only let the reserved initiator talk to us.
+       // A 3rd party may be sending the RESERVE/RELEASE commands
+       int reservedId; // 0 -> 7 if reserved. -1 if not reserved.
+       int reserverId; // 0 -> 7 if reserved. -1 if not reserved.
+
+       uint8_t syncOffset;
+       uint8_t syncPeriod;
+
+       // Shadow parameters, possibly not saved to flash yet.
+       // Set via Mode Select
+       uint16_t bytesPerSector;
+};
+
+struct S2S_TargetStruct
+{
+       uint8_t id;
+
+       S2S_Device* device;
+       S2S_TargetCfg* cfg;
+
+       S2S_TargetState state;
+};
+
+struct S2S_DeviceStruct
+{
+       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);
+
+};
+
+void s2s_DeviceGetBoardConfig(S2S_BoardCfg* config);
+S2S_Target* s2s_DeviceFindByScsiId(int scsiId);
+
+S2S_Device* s2s_GetDevices(int* count);
+
+#endif
+
+
index aeead0fcd5143850310a2a9d73c1446aa12d4edf..819af1ae4df94333f53dcb2ea03bb87bbd443bac 100755 (executable)
@@ -50,8 +50,8 @@ void scsiSendDiagnostic()
                        // Nowhere to store this data!\r
                        // Shouldn't happen - our buffer should be many magnitudes larger\r
                        // than the required size for diagnostic parameters.\r
-                       scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-                       scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+                       scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+                       scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                        scsiDev.status = CHECK_CONDITION;\r
                        scsiDev.phase = STATUS;\r
                }\r
@@ -95,14 +95,14 @@ void scsiReceiveDiagnostic()
                // 64bit linear address, then convert back again.\r
                uint64_t fromByteAddr =\r
                        scsiByteAddress(\r
-                               scsiDev.target->liveCfg.bytesPerSector,\r
+                               scsiDev.target->state.bytesPerSector,\r
                                scsiDev.target->cfg->headsPerCylinder,\r
                                scsiDev.target->cfg->sectorsPerTrack,\r
                                suppliedFmt,\r
                                &scsiDev.data[6]);\r
 \r
                scsiSaveByteAddress(\r
-                       scsiDev.target->liveCfg.bytesPerSector,\r
+                       scsiDev.target->state.bytesPerSector,\r
                        scsiDev.target->cfg->headsPerCylinder,\r
                        scsiDev.target->cfg->sectorsPerTrack,\r
                        translateFmt,\r
@@ -121,8 +121,8 @@ void scsiReceiveDiagnostic()
        {\r
                // error.\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                scsiDev.phase = STATUS;\r
        }\r
 \r
@@ -189,8 +189,8 @@ void scsiReadBuffer()
        {\r
                // error.\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                scsiDev.phase = STATUS;\r
        }\r
 }\r
@@ -228,8 +228,8 @@ void scsiWriteBuffer()
        {\r
                // error.\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                scsiDev.phase = STATUS;\r
        }\r
 }\r
@@ -239,7 +239,7 @@ void scsiWriteBuffer()
 // Section 4.3.14\r
 void scsiWriteSectorBuffer()\r
 {\r
-       scsiDev.dataLen = scsiDev.target->liveCfg.bytesPerSector;\r
+       scsiDev.dataLen = scsiDev.target->state.bytesPerSector;\r
        scsiDev.phase = DATA_OUT;\r
        scsiDev.postDataOutHook = doWriteBuffer;\r
 }\r
index f1fd8c869c1da091f0b182381137b2364925720f..79951b0a834267a218f42add00fa809d770a8b16 100755 (executable)
@@ -95,8 +95,8 @@ static void doFormatUnitHeader(void)
        {\r
                // Save the "MODE SELECT savable parameters"\r
                s2s_configSave(\r
-                       scsiDev.target->targetId,\r
-                       scsiDev.target->liveCfg.bytesPerSector);\r
+                       scsiDev.target->id,\r
+                       scsiDev.target->state.bytesPerSector);\r
        }\r
 \r
        if (IP)\r
@@ -126,8 +126,9 @@ static void doReadCapacity()
        int pmi = scsiDev.cdb[8] & 1;\r
 \r
        uint32_t capacity = getScsiCapacity(\r
+               scsiDev.target->device,\r
                scsiDev.target->cfg->sdSectorStart,\r
-               scsiDev.target->liveCfg.bytesPerSector,\r
+               scsiDev.target->state.bytesPerSector,\r
                scsiDev.target->cfg->scsiSectors);\r
 \r
        if (!pmi && lba)\r
@@ -137,8 +138,8 @@ static void doReadCapacity()
                // assume that delays are constant across each block. But the spec\r
                // says we must return this error if pmi is specified incorrectly.\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                scsiDev.phase = STATUS;\r
        }\r
        else if (capacity > 0)\r
@@ -150,7 +151,7 @@ static void doReadCapacity()
                scsiDev.data[2] = highestBlock >> 8;\r
                scsiDev.data[3] = highestBlock;\r
 \r
-               uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
+               uint32_t bytesPerSector = scsiDev.target->state.bytesPerSector;\r
                scsiDev.data[4] = bytesPerSector >> 24;\r
                scsiDev.data[5] = bytesPerSector >> 16;\r
                scsiDev.data[6] = bytesPerSector >> 8;\r
@@ -161,8 +162,8 @@ static void doReadCapacity()
        else\r
        {\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = NOT_READY;\r
-               scsiDev.target->sense.asc = MEDIUM_NOT_PRESENT;\r
+               scsiDev.target->state.sense.code = NOT_READY;\r
+               scsiDev.target->state.sense.asc = MEDIUM_NOT_PRESENT;\r
                scsiDev.phase = STATUS;\r
        }\r
 }\r
@@ -175,19 +176,20 @@ static void doWrite(uint32_t lba, uint32_t blocks)
                s2s_delay_ms(10);\r
        }\r
 \r
-       uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
+       uint32_t bytesPerSector = scsiDev.target->state.bytesPerSector;\r
 \r
        if (unlikely(blockDev.state & DISK_WP) ||\r
                unlikely(scsiDev.target->cfg->deviceType == S2S_CFG_OPTICAL))\r
 \r
        {\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = WRITE_PROTECTED;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = WRITE_PROTECTED;\r
                scsiDev.phase = STATUS;\r
        }\r
        else if (unlikely(((uint64_t) lba) + blocks >\r
                getScsiCapacity(\r
+                       scsiDev.target->device,\r
                        scsiDev.target->cfg->sdSectorStart,\r
                        bytesPerSector,\r
                        scsiDev.target->cfg->scsiSectors\r
@@ -195,8 +197,8 @@ static void doWrite(uint32_t lba, uint32_t blocks)
                ))\r
        {\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;\r
                scsiDev.phase = STATUS;\r
        }\r
        else\r
@@ -233,14 +235,15 @@ static void doRead(uint32_t lba, uint32_t blocks)
        }\r
 \r
        uint32_t capacity = getScsiCapacity(\r
+               scsiDev.target->device,\r
                scsiDev.target->cfg->sdSectorStart,\r
-               scsiDev.target->liveCfg.bytesPerSector,\r
+               scsiDev.target->state.bytesPerSector,\r
                scsiDev.target->cfg->scsiSectors);\r
        if (unlikely(((uint64_t) lba) + blocks > capacity))\r
        {\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;\r
                scsiDev.phase = STATUS;\r
        }\r
        else\r
@@ -251,7 +254,7 @@ static void doRead(uint32_t lba, uint32_t blocks)
                scsiDev.phase = DATA_IN;\r
                scsiDev.dataLen = 0; // No data yet\r
 \r
-               uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
+               uint32_t bytesPerSector = scsiDev.target->state.bytesPerSector;\r
                uint32_t sdSectorPerSCSISector = SDSectorsPerSCSISector(bytesPerSector);\r
                uint32_t sdSectors =\r
                        blocks * sdSectorPerSCSISector;\r
@@ -286,14 +289,15 @@ static void doSeek(uint32_t lba)
 {\r
        if (lba >=\r
                getScsiCapacity(\r
+                       scsiDev.target->device,\r
                        scsiDev.target->cfg->sdSectorStart,\r
-                       scsiDev.target->liveCfg.bytesPerSector,\r
+                       scsiDev.target->state.bytesPerSector,\r
                        scsiDev.target->cfg->scsiSectors)\r
                )\r
        {\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;\r
                scsiDev.phase = STATUS;\r
        }\r
        else\r
@@ -313,24 +317,24 @@ static int doTestUnitReady()
        {\r
                ready = 0;\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = NOT_READY;\r
-               scsiDev.target->sense.asc = LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED;\r
+               scsiDev.target->state.sense.code = NOT_READY;\r
+               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
        {\r
                ready = 0;\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = NOT_READY;\r
-               scsiDev.target->sense.asc = MEDIUM_NOT_PRESENT;\r
+               scsiDev.target->state.sense.code = NOT_READY;\r
+               scsiDev.target->state.sense.asc = MEDIUM_NOT_PRESENT;\r
                scsiDev.phase = STATUS;\r
        }\r
        else if (unlikely(!(blockDev.state & DISK_INITIALISED)))\r
        {\r
                ready = 0;\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = NOT_READY;\r
-               scsiDev.target->sense.asc = LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE;\r
+               scsiDev.target->state.sense.code = NOT_READY;\r
+               scsiDev.target->state.sense.asc = LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE;\r
                scsiDev.phase = STATUS;\r
        }\r
        return ready;\r
@@ -516,8 +520,8 @@ int scsiDiskCommand()
                        // TODO. This means they are supplying data to verify against.\r
                        // Technically we should probably grab the data and compare it.\r
                        scsiDev.status = CHECK_CONDITION;\r
-                       scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-                       scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+                       scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+                       scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                        scsiDev.phase = STATUS;\r
                }\r
        }\r
@@ -575,7 +579,7 @@ calcReadahead(uint32_t totalBytes, uint32_t sdSpeedKBs, uint32_t scsiSpeedKBs)
 \r
 void scsiDiskPoll()\r
 {\r
-       uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
+       uint32_t bytesPerSector = scsiDev.target->state.bytesPerSector;\r
 \r
        if (scsiDev.phase == DATA_IN &&\r
                transfer.currentBlock != transfer.blocks)\r
@@ -925,8 +929,8 @@ void scsiDiskPoll()
                        if (parityError &&\r
                                (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY))\r
                        {\r
-                               scsiDev.target->sense.code = ABORTED_COMMAND;\r
-                               scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
+                               scsiDev.target->state.sense.code = ABORTED_COMMAND;\r
+                               scsiDev.target->state.sense.asc = SCSI_PARITY_ERROR;\r
                                scsiDev.status = CHECK_CONDITION;;\r
                        }\r
                        scsiDev.phase = STATUS;\r
index 44a2e82bc3619f55bdcd5d5bb670f1cf3af42f61..314964a877d27dd563341e472accce79eec13e49 100755 (executable)
 #include <string.h>\r
 \r
 uint32_t getScsiCapacity(\r
+       S2S_Device* device,\r
        uint32_t sdSectorStart,\r
        uint16_t bytesPerSector,\r
        uint32_t scsiSectors)\r
 {\r
+       uint32_t devCapacity = device->getCapacity(device);\r
+\r
        uint32_t capacity =\r
-               (sdDev.capacity - sdSectorStart - S2S_CFG_SIZE) /\r
+               (devCapacity - sdSectorStart - S2S_CFG_SIZE) /\r
                        SDSectorsPerSCSISector(bytesPerSector);\r
 \r
-\r
-       if (sdDev.capacity == 0)\r
+       if (devCapacity == 0)\r
        {\r
                capacity = 0;\r
        }\r
-       else if (sdSectorStart >= (sdDev.capacity - S2S_CFG_SIZE))\r
+       else if (sdSectorStart >= (devCapacity - S2S_CFG_SIZE))\r
        {\r
                capacity = 0;\r
        }\r
index 83de38a76dd4e5321deccffefe4a42041c83ee95..c1d38ca687d36181e3a83794d12d9c0432461b42 100755 (executable)
@@ -18,7 +18,7 @@
 #define GEOMETRY_H
 
 #include "config.h"
-// TODO #include "sd.h"
+#include "device.h"
 #define SD_SECTOR_SIZE 512
 
 typedef enum
@@ -34,6 +34,7 @@ static inline int SDSectorsPerSCSISector(uint16_t bytesPerSector)
 }
 
 uint32_t getScsiCapacity(
+       S2S_Device* device,
        uint32_t sdSectorStart,
        uint16_t bytesPerSector,
        uint32_t scsiSectors);
index 9cd06cc4e73a4c87ba721cc1560af789b200a491..9330f9957c3c1838fd1b579738a6edc41175aa86 100755 (executable)
 // Values for STM32F401RE
 const size_t OTP_SIZE = 512;
 const size_t OTP_BLOCKS = 16;
-const size_t OTP_BLOCK_SIZE = OTP_SIZE / OTP_BLOCKS;
+const size_t OTP_BLOCK_SIZE = 32;//OTP_SIZE / OTP_BLOCKS;
 
 const size_t OTP_BLOCK_NUM = 0;
 
-// Define some pointers for writing, but also to allow easy reading back values
 #define FLASH_OTP_BASE 0x1FFF7800
-const uint8_t *otp = (uint8_t*)(FLASH_OTP_BASE + OTP_BLOCK_NUM * OTP_BLOCK_SIZE);
-const uint32_t *otp32 = (uint32_t*)(FLASH_OTP_BASE + OTP_BLOCK_NUM * OTP_BLOCK_SIZE);
-const uint8_t *lock = (uint8_t*)(FLASH_OTP_BASE + OTP_SIZE + OTP_BLOCK_NUM);
 
 const uint32_t marker = 0x06002020;
 
@@ -59,6 +55,11 @@ s2s_checkHwVersion()
 {
        checkHwSensePins();
 
+       // Define some pointers for writing, but also to allow easy reading back values
+       const uint8_t *otp = (uint8_t*)(FLASH_OTP_BASE + OTP_BLOCK_NUM * OTP_BLOCK_SIZE);
+       const uint32_t *otp32 = (uint32_t*)(FLASH_OTP_BASE + OTP_BLOCK_NUM * OTP_BLOCK_SIZE);
+       const uint8_t *lock = (uint8_t*)(FLASH_OTP_BASE + OTP_SIZE + OTP_BLOCK_NUM);
+
        // Write a marker to flash that can be read by dfu-util now that we know
        // the version is correct.
        if (*otp32 != marker)
index 138e8c2182d6ef4acf3b42911fb50181cbeed834..a538be7951f7ba446c8bca67c5347d922f16a85f 100755 (executable)
@@ -98,8 +98,8 @@ void s2s_scsiInquiry()
                {\r
                        // error.\r
                        scsiDev.status = CHECK_CONDITION;\r
-                       scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-                       scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+                       scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+                       scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                        scsiDev.phase = STATUS;\r
                }\r
                else\r
@@ -147,8 +147,8 @@ void s2s_scsiInquiry()
        {\r
                // error.\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                scsiDev.phase = STATUS;\r
        }\r
 \r
index 5235e4480e5f6fb51d0d1d4bd5be3fef2af2a412..64823e7ba0d1aee3c6d6a4b44d5df1222b14287a 100755 (executable)
@@ -356,7 +356,7 @@ static void doModeSense(
                scsiDev.data[idx++] = 0; // reserved\r
 \r
                // Block length\r
-               uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
+               uint32_t bytesPerSector = scsiDev.target->state.bytesPerSector;\r
                scsiDev.data[idx++] = bytesPerSector >> 16;\r
                scsiDev.data[idx++] = bytesPerSector >> 8;\r
                scsiDev.data[idx++] = bytesPerSector & 0xFF;\r
@@ -405,7 +405,7 @@ static void doModeSense(
                        scsiDev.data[idx+11] = sectorsPerTrack & 0xFF;\r
 \r
                        // Fill out the configured bytes-per-sector\r
-                       uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
+                       uint32_t bytesPerSector = scsiDev.target->state.bytesPerSector;\r
                        scsiDev.data[idx+12] = bytesPerSector >> 8;\r
                        scsiDev.data[idx+13] = bytesPerSector & 0xFF;\r
                }\r
@@ -439,8 +439,9 @@ static void doModeSense(
                        uint32_t sector;\r
                        LBA2CHS(\r
                                getScsiCapacity(\r
+                                       scsiDev.target->device,\r
                                        scsiDev.target->cfg->sdSectorStart,\r
-                                       scsiDev.target->liveCfg.bytesPerSector,\r
+                                       scsiDev.target->state.bytesPerSector,\r
                                        scsiDev.target->cfg->scsiSectors),\r
                                &cyl,\r
                                &head,\r
@@ -547,8 +548,8 @@ static void doModeSense(
                // Unknown Page Code\r
                pageFound = 0;\r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                scsiDev.phase = STATUS;\r
        }\r
        else\r
@@ -607,10 +608,10 @@ static void doModeSelect(void)
                        }\r
                        else\r
                        {\r
-                               scsiDev.target->liveCfg.bytesPerSector = bytesPerSector;\r
+                               scsiDev.target->state.bytesPerSector = bytesPerSector;\r
                                if (bytesPerSector != scsiDev.target->cfg->bytesPerSector)\r
                                {\r
-                                       s2s_configSave(scsiDev.target->targetId, bytesPerSector);\r
+                                       s2s_configSave(scsiDev.target->id, bytesPerSector);\r
                                }\r
                        }\r
                }\r
@@ -640,10 +641,10 @@ static void doModeSelect(void)
                                        goto bad;\r
                                }\r
 \r
-                               scsiDev.target->liveCfg.bytesPerSector = bytesPerSector;\r
+                               scsiDev.target->state.bytesPerSector = bytesPerSector;\r
                                if (scsiDev.cdb[1] & 1) // SP Save Pages flag\r
                                {\r
-                                       s2s_configSave(scsiDev.target->targetId, bytesPerSector);\r
+                                       s2s_configSave(scsiDev.target->id, bytesPerSector);\r
                                }\r
                        }\r
                        break;\r
@@ -659,8 +660,8 @@ static void doModeSelect(void)
        goto out;\r
 bad:\r
        scsiDev.status = CHECK_CONDITION;\r
-       scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-       scsiDev.target->sense.asc = INVALID_FIELD_IN_PARAMETER_LIST;\r
+       scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+       scsiDev.target->state.sense.asc = INVALID_FIELD_IN_PARAMETER_LIST;\r
 \r
 out:\r
        scsiDev.phase = STATUS;\r
index 016ecbb523f05d58bbc768c1442c425cf9290354..6369fb38701c7353ac07f2dc6d14af31f35a1717 100755 (executable)
@@ -131,8 +131,8 @@ static void enter_Status(uint8_t status)
        scsiDev.phase = STATUS;\r
 \r
        scsiDev.lastStatus = scsiDev.status;\r
-       scsiDev.lastSense = scsiDev.target->sense.code;\r
-       scsiDev.lastSenseASC = scsiDev.target->sense.asc;\r
+       scsiDev.lastSense = scsiDev.target->state.sense.code;\r
+       scsiDev.lastSenseASC = scsiDev.target->state.sense.asc;\r
 }\r
 \r
 void process_Status()\r
@@ -190,7 +190,7 @@ void process_Status()
        }\r
        else if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_OMTI)\r
        {\r
-               scsiDev.status |= (scsiDev.target->targetId & 0x03) << 5;\r
+               scsiDev.status |= (scsiDev.target->id & 0x03) << 5;\r
                scsiWriteByte(scsiDev.status);\r
        }\r
        else\r
@@ -199,8 +199,8 @@ void process_Status()
        }\r
 \r
        scsiDev.lastStatus = scsiDev.status;\r
-       scsiDev.lastSense = scsiDev.target->sense.code;\r
-       scsiDev.lastSenseASC = scsiDev.target->sense.asc;\r
+       scsiDev.lastSense = scsiDev.target->state.sense.code;\r
+       scsiDev.lastSenseASC = scsiDev.target->state.sense.asc;\r
 \r
        // Command Complete occurs AFTER a valid status has been\r
        // sent. then we go bus-free.\r
@@ -258,8 +258,8 @@ static void process_DataOut()
                if (parityError &&\r
                        (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY))\r
                {\r
-                       scsiDev.target->sense.code = ABORTED_COMMAND;\r
-                       scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
+                       scsiDev.target->state.sense.code = ABORTED_COMMAND;\r
+                       scsiDev.target->state.sense.asc = SCSI_PARITY_ERROR;\r
                        enter_Status(CHECK_CONDITION);\r
                }\r
        }\r
@@ -323,15 +323,11 @@ static void process_Command()
        // http://bitsavers.trailing-edge.com/pdf/xebec/104524C_S1410Man_Aug83.pdf\r
        if ((scsiDev.lun > 0) && (scsiDev.boardCfg.flags & S2S_CFG_MAP_LUNS_TO_IDS))\r
        {\r
-               int tgtIndex;\r
-               for (tgtIndex = 0; tgtIndex < S2S_MAX_TARGETS; ++tgtIndex)\r
+               S2S_Target* lunTarget = s2s_DeviceFindByScsiId(scsiDev.lun);\r
+               if (lunTarget != NULL)\r
                {\r
-                       if (scsiDev.targets[tgtIndex].targetId == scsiDev.lun)\r
-                       {\r
-                               scsiDev.target = &scsiDev.targets[tgtIndex];\r
-                               scsiDev.lun = 0;\r
-                               break;\r
-                       }\r
+                       scsiDev.target = lunTarget;\r
+                       scsiDev.lun = 0;\r
                }\r
        }\r
 \r
@@ -350,8 +346,8 @@ static void process_Command()
        else if (parityError &&\r
                (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY))\r
        {\r
-               scsiDev.target->sense.code = ABORTED_COMMAND;\r
-               scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
+               scsiDev.target->state.sense.code = ABORTED_COMMAND;\r
+               scsiDev.target->state.sense.asc = SCSI_PARITY_ERROR;\r
                enter_Status(CHECK_CONDITION);\r
        }\r
        else if ((control & 0x02) && ((control & 0x01) == 0) &&\r
@@ -359,8 +355,8 @@ static void process_Command()
                likely(scsiDev.target->cfg->quirks != S2S_CFG_QUIRKS_XEBEC))\r
        {\r
                // FLAG set without LINK flag.\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                enter_Status(CHECK_CONDITION);\r
        }\r
        else if (command == 0x12)\r
@@ -376,11 +372,11 @@ static void process_Command()
                {\r
                        // Completely non-standard\r
                        allocLength = 4;\r
-                       if (scsiDev.target->sense.code == NO_SENSE)\r
+                       if (scsiDev.target->state.sense.code == NO_SENSE)\r
                                scsiDev.data[0] = 0;\r
-                       else if (scsiDev.target->sense.code == ILLEGAL_REQUEST)\r
+                       else if (scsiDev.target->state.sense.code == ILLEGAL_REQUEST)\r
                                scsiDev.data[0] = 0x20; // Illegal command\r
-                       else if (scsiDev.target->sense.code == NOT_READY)\r
+                       else if (scsiDev.target->state.sense.code == NOT_READY)\r
                                scsiDev.data[0] = 0x04; // Drive not ready\r
                        else\r
                                scsiDev.data[0] = 0x11;  // Uncorrectable data error\r
@@ -397,7 +393,7 @@ static void process_Command()
 \r
                        memset(scsiDev.data, 0, 256); // Max possible alloc length\r
                        scsiDev.data[0] = 0xF0;\r
-                       scsiDev.data[2] = scsiDev.target->sense.code & 0x0F;\r
+                       scsiDev.data[2] = scsiDev.target->state.sense.code & 0x0F;\r
 \r
                        scsiDev.data[3] = transfer.lba >> 24;\r
                        scsiDev.data[4] = transfer.lba >> 16;\r
@@ -406,45 +402,45 @@ static void process_Command()
 \r
                        // Additional bytes if there are errors to report\r
                        scsiDev.data[7] = 10; // additional length\r
-                       scsiDev.data[12] = scsiDev.target->sense.asc >> 8;\r
-                       scsiDev.data[13] = scsiDev.target->sense.asc;\r
+                       scsiDev.data[12] = scsiDev.target->state.sense.asc >> 8;\r
+                       scsiDev.data[13] = scsiDev.target->state.sense.asc;\r
                }\r
 \r
                // Silently truncate results. SCSI-2 spec 8.2.14.\r
                enter_DataIn(allocLength);\r
 \r
                // This is a good time to clear out old sense information.\r
-               scsiDev.target->sense.code = NO_SENSE;\r
-               scsiDev.target->sense.asc = NO_ADDITIONAL_SENSE_INFORMATION;\r
+               scsiDev.target->state.sense.code = NO_SENSE;\r
+               scsiDev.target->state.sense.asc = NO_ADDITIONAL_SENSE_INFORMATION;\r
        }\r
        // Some old SCSI drivers do NOT properly support\r
        // unitAttention. eg. the Mac Plus would trigger a SCSI reset\r
        // on receiving the unit attention response on boot, thus\r
        // triggering another unit attention condition.\r
-       else if (scsiDev.target->unitAttention &&\r
+       else if (scsiDev.target->state.unitAttention &&\r
                (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_UNIT_ATTENTION))\r
        {\r
-               scsiDev.target->sense.code = UNIT_ATTENTION;\r
-               scsiDev.target->sense.asc = scsiDev.target->unitAttention;\r
+               scsiDev.target->state.sense.code = UNIT_ATTENTION;\r
+               scsiDev.target->state.sense.asc = scsiDev.target->state.unitAttention;\r
 \r
                // If initiator doesn't do REQUEST SENSE for the next command, then\r
                // data is lost.\r
-               scsiDev.target->unitAttention = 0;\r
+               scsiDev.target->state.unitAttention = 0;\r
 \r
                enter_Status(CHECK_CONDITION);\r
        }\r
        else if (scsiDev.lun)\r
        {\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = LOGICAL_UNIT_NOT_SUPPORTED;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = LOGICAL_UNIT_NOT_SUPPORTED;\r
                enter_Status(CHECK_CONDITION);\r
        }\r
        else if (command == 0x17 || command == 0x16)\r
        {\r
                doReserveRelease();\r
        }\r
-       else if ((scsiDev.target->reservedId >= 0) &&\r
-               (scsiDev.target->reservedId != scsiDev.initiatorId))\r
+       else if ((scsiDev.target->state.reservedId >= 0) &&\r
+               (scsiDev.target->state.reservedId != scsiDev.initiatorId))\r
        {\r
                enter_Status(CONFLICT);\r
        }\r
@@ -485,8 +481,8 @@ static void process_Command()
        }\r
        else if (!scsiModeCommand() && !scsiVendorCommand())\r
        {\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_COMMAND_OPERATION_CODE;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = INVALID_COMMAND_OPERATION_CODE;\r
                enter_Status(CHECK_CONDITION);\r
        }\r
 \r
@@ -506,25 +502,25 @@ static void doReserveRelease()
        uint8_t command = scsiDev.cdb[0];\r
 \r
        int canRelease =\r
-               (!thirdPty && (scsiDev.initiatorId == scsiDev.target->reservedId)) ||\r
+               (!thirdPty && (scsiDev.initiatorId == scsiDev.target->state.reservedId)) ||\r
                        (thirdPty &&\r
-                               (scsiDev.target->reserverId == scsiDev.initiatorId) &&\r
-                               (scsiDev.target->reservedId == thirdPtyId)\r
+                               (scsiDev.target->state.reserverId == scsiDev.initiatorId) &&\r
+                               (scsiDev.target->state.reservedId == thirdPtyId)\r
                        );\r
 \r
        if (extentReservation)\r
        {\r
                // Not supported.\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+               scsiDev.target->state.sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->state.sense.asc = INVALID_FIELD_IN_CDB;\r
                enter_Status(CHECK_CONDITION);\r
        }\r
        else if (command == 0x17) // release\r
        {\r
-               if ((scsiDev.target->reservedId < 0) || canRelease)\r
+               if ((scsiDev.target->state.reservedId < 0) || canRelease)\r
                {\r
-                       scsiDev.target->reservedId = -1;\r
-                       scsiDev.target->reserverId = -1;\r
+                       scsiDev.target->state.reservedId = -1;\r
+                       scsiDev.target->state.reserverId = -1;\r
                }\r
                else\r
                {\r
@@ -533,16 +529,16 @@ static void doReserveRelease()
        }\r
        else // assume reserve.\r
        {\r
-               if ((scsiDev.target->reservedId < 0) || canRelease)\r
+               if ((scsiDev.target->state.reservedId < 0) || canRelease)\r
                {\r
-                       scsiDev.target->reserverId = scsiDev.initiatorId;\r
+                       scsiDev.target->state.reserverId = scsiDev.initiatorId;\r
                        if (thirdPty)\r
                        {\r
-                               scsiDev.target->reservedId = thirdPtyId;\r
+                               scsiDev.target->state.reservedId = thirdPtyId;\r
                        }\r
                        else\r
                        {\r
-                               scsiDev.target->reservedId = scsiDev.initiatorId;\r
+                               scsiDev.target->state.reservedId = scsiDev.initiatorId;\r
                        }\r
                }\r
                else\r
@@ -571,21 +567,28 @@ static void scsiReset()
 \r
        if (scsiDev.target)\r
        {\r
-               if (scsiDev.target->unitAttention != POWER_ON_RESET)\r
+               if (scsiDev.target->state.unitAttention != POWER_ON_RESET)\r
                {\r
-                       scsiDev.target->unitAttention = SCSI_BUS_RESET;\r
+                       scsiDev.target->state.unitAttention = SCSI_BUS_RESET;\r
                }\r
-               scsiDev.target->reservedId = -1;\r
-               scsiDev.target->reserverId = -1;\r
-               scsiDev.target->sense.code = NO_SENSE;\r
-               scsiDev.target->sense.asc = NO_ADDITIONAL_SENSE_INFORMATION;\r
+               scsiDev.target->state.reservedId = -1;\r
+               scsiDev.target->state.reserverId = -1;\r
+               scsiDev.target->state.sense.code = NO_SENSE;\r
+               scsiDev.target->state.sense.asc = NO_ADDITIONAL_SENSE_INFORMATION;\r
        }\r
        scsiDev.target = NULL;\r
 \r
-       for (int i = 0; i < S2S_MAX_TARGETS; ++i)\r
+       int deviceCount;\r
+       S2S_Device* allDevices = s2s_GetDevices(&deviceCount);\r
+       for (int devIdx = 0; devIdx < deviceCount; ++devIdx)\r
        {\r
-               scsiDev.targets[i].syncOffset = 0;\r
-               scsiDev.targets[i].syncPeriod = 0;\r
+               int targetCount;\r
+               S2S_Target* allTargets = allDevices[devIdx].getTargets(allDevices + devIdx, &targetCount);\r
+               for (int i = 0; i < targetCount; ++i)\r
+               {\r
+                       allTargets[i].state.syncOffset = 0;\r
+                       allTargets[i].state.syncPeriod = 0;\r
+               }\r
        }\r
        scsiDev.minSyncPeriod = 0;\r
 \r
@@ -659,16 +662,7 @@ static void process_SelectionPhase()
                selStatus = scsiDev.selFlag;\r
        }\r
 \r
-       int tgtIndex;\r
-       TargetState* target = NULL;\r
-       for (tgtIndex = 0; tgtIndex < S2S_MAX_TARGETS; ++tgtIndex)\r
-       {\r
-               if (scsiDev.targets[tgtIndex].targetId == (selStatus & 7))\r
-               {\r
-                       target = &scsiDev.targets[tgtIndex];\r
-                       break;\r
-               }\r
-       }\r
+       S2S_Target* target = s2s_DeviceFindByScsiId(selStatus & 7);\r
        if ((target != NULL) && (selStatus & 0x40))\r
        {\r
                // We've been selected!\r
@@ -694,7 +688,7 @@ static void process_SelectionPhase()
                // controllers don't generate parity bits.\r
                if (!scsiDev.atnFlag)\r
                {\r
-                       target->unitAttention = 0;\r
+                       target->state.unitAttention = 0;\r
                        scsiDev.compatMode = COMPAT_SCSI1;\r
                }\r
                else if (!(scsiDev.boardCfg.flags & S2S_CFG_ENABLE_SCSI2))\r
@@ -788,15 +782,15 @@ static void process_MessageOut()
 \r
                scsiDiskReset();\r
 \r
-               scsiDev.target->unitAttention = SCSI_BUS_RESET;\r
+               scsiDev.target->state.unitAttention = SCSI_BUS_RESET;\r
 \r
                // ANY initiator can reset the reservation state via this message.\r
-               scsiDev.target->reservedId = -1;\r
-               scsiDev.target->reserverId = -1;\r
+               scsiDev.target->state.reservedId = -1;\r
+               scsiDev.target->state.reserverId = -1;\r
 \r
                // Cancel any sync negotiation\r
-               scsiDev.target->syncOffset = 0;\r
-               scsiDev.target->syncPeriod = 0;\r
+               scsiDev.target->state.syncOffset = 0;\r
+               scsiDev.target->state.syncPeriod = 0;\r
 \r
                enter_BusFree();\r
        }\r
@@ -823,8 +817,8 @@ static void process_MessageOut()
 \r
                if (wasNeedSyncNegotiationAck)\r
                {\r
-                       scsiDev.target->syncOffset = 0;\r
-                       scsiDev.target->syncPeriod = 0;\r
+                       scsiDev.target->state.syncOffset = 0;\r
+                       scsiDev.target->state.syncPeriod = 0;\r
                }\r
        }\r
        else if (scsiDev.msgOut == 0x08)\r
@@ -839,8 +833,8 @@ static void process_MessageOut()
 \r
                if (wasNeedSyncNegotiationAck)\r
                {\r
-                       scsiDev.target->syncOffset = 0;\r
-                       scsiDev.target->syncPeriod = 0;\r
+                       scsiDev.target->state.syncOffset = 0;\r
+                       scsiDev.target->state.syncPeriod = 0;\r
                }\r
        }\r
        else if (scsiDev.msgOut & 0x80) // 0x80 -> 0xFF\r
@@ -890,13 +884,13 @@ static void process_MessageOut()
                        scsiWrite(WDTR, sizeof(WDTR));\r
 \r
                        // SDTR becomes invalidated.\r
-                       scsiDev.target->syncOffset = 0;\r
-                       scsiDev.target->syncPeriod = 0;\r
+                       scsiDev.target->state.syncOffset = 0;\r
+                       scsiDev.target->state.syncPeriod = 0;\r
                }\r
                else if (extmsg[0] == 1 && msgLen == 3) // Synchronous data request\r
                {\r
-                       int oldPeriod = scsiDev.target->syncPeriod;\r
-                       int oldOffset = scsiDev.target->syncOffset;\r
+                       int oldPeriod = scsiDev.target->state.syncPeriod;\r
+                       int oldOffset = scsiDev.target->state.syncOffset;\r
 \r
                        int transferPeriod = extmsg[1];\r
                        int offset = extmsg[2];\r
@@ -918,10 +912,10 @@ static void process_MessageOut()
                                ((scsiDev.boardCfg.scsiSpeed != S2S_CFG_SPEED_NoLimit) &&\r
                                        (scsiDev.boardCfg.scsiSpeed <= S2S_CFG_SPEED_ASYNC_50)))\r
                        {\r
-                               scsiDev.target->syncOffset = 0;\r
-                               scsiDev.target->syncPeriod = 0;\r
+                               scsiDev.target->state.syncOffset = 0;\r
+                               scsiDev.target->state.syncPeriod = 0;\r
                        } else {\r
-                               scsiDev.target->syncOffset = offset <= 15 ? offset : 15;\r
+                               scsiDev.target->state.syncOffset = offset <= 15 ? offset : 15;\r
                                // FAST20 / 50ns / 20MHz is disabled for now due to\r
                                // data corruption while reading data. We can count the\r
                                // ACK's correctly, but can't save the data to a register\r
@@ -929,39 +923,39 @@ static void process_MessageOut()
                                if ((scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_TURBO) &&\r
                                        (transferPeriod <= 16))\r
                                {\r
-                                       scsiDev.target->syncPeriod = 16; // 15.6MB/s\r
+                                       scsiDev.target->state.syncPeriod = 16; // 15.6MB/s\r
                                }\r
                                else if (scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_TURBO)\r
                                {\r
-                                       scsiDev.target->syncPeriod = transferPeriod;\r
+                                       scsiDev.target->state.syncPeriod = transferPeriod;\r
                                }\r
                                else if (transferPeriod <= 25 &&\r
                                        ((scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_NoLimit) ||\r
                                                (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_SYNC_10)))\r
                                {\r
-                                       scsiDev.target->syncPeriod = 25; // 100ns, 10MB/s\r
+                                       scsiDev.target->state.syncPeriod = 25; // 100ns, 10MB/s\r
 \r
                                } else if (transferPeriod < 50 &&\r
                                        ((scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_NoLimit) ||\r
                                                (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_SYNC_10)))\r
                                {\r
-                                       scsiDev.target->syncPeriod = transferPeriod;\r
+                                       scsiDev.target->state.syncPeriod = transferPeriod;\r
                                } else if (transferPeriod >= 50)\r
                                {\r
-                                       scsiDev.target->syncPeriod = transferPeriod;\r
+                                       scsiDev.target->state.syncPeriod = transferPeriod;\r
                                } else {\r
-                                       scsiDev.target->syncPeriod = 50;\r
+                                       scsiDev.target->state.syncPeriod = 50;\r
                                }\r
                        }\r
 \r
                        if (transferPeriod != oldPeriod ||\r
-                               scsiDev.target->syncPeriod != oldPeriod ||\r
+                               scsiDev.target->state.syncPeriod != oldPeriod ||\r
                                offset != oldOffset ||\r
-                               scsiDev.target->syncOffset != oldOffset ||\r
+                               scsiDev.target->state.syncOffset != oldOffset ||\r
                                !wasNeedSyncNegotiationAck) // Don't get into infinite loops negotiating.\r
                        {\r
                                scsiEnterPhase(MESSAGE_IN);\r
-                               uint8_t SDTR[] = {0x01, 0x03, 0x01, scsiDev.target->syncPeriod, scsiDev.target->syncOffset};\r
+                               uint8_t SDTR[] = {0x01, 0x03, 0x01, scsiDev.target->state.syncPeriod, scsiDev.target->state.syncOffset};\r
                                scsiWrite(SDTR, sizeof(SDTR));\r
                                scsiDev.needSyncNegotiationAck = 1; // Check if this message is rejected.\r
                                scsiDev.sdUnderrunCount = 0;  // reset counter, may work now.\r
@@ -1133,145 +1127,34 @@ void scsiInit()
        scsiDev.hostSpeedKBs = 0;\r
        scsiDev.hostSpeedMeasured = 0;\r
 \r
-       int i;\r
-       for (i = 0; i < S2S_MAX_TARGETS; ++i)\r
+       int deviceCount;\r
+       S2S_Device* devices = s2s_GetDevices(&deviceCount);\r
+       for (int deviceIdx = 0; deviceIdx < deviceCount; ++deviceIdx)\r
        {\r
-               const S2S_TargetCfg* cfg = s2s_getConfigByIndex(i);\r
-               if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))\r
-               {\r
-                       scsiDev.targets[i].targetId = cfg->scsiId & S2S_CFG_TARGET_ID_BITS;\r
-                       scsiDev.targets[i].cfg = cfg;\r
+               int targetCount;\r
+               S2S_Target* targets = devices[deviceIdx].getTargets(devices + deviceIdx, &targetCount);\r
 \r
-                       scsiDev.targets[i].liveCfg.bytesPerSector = cfg->bytesPerSector;\r
-               }\r
-               else\r
+               for (int i = 0; i < targetCount; ++i)\r
                {\r
-                       scsiDev.targets[i].targetId = 0xff;\r
-                       scsiDev.targets[i].cfg = NULL;\r
-               }\r
-               scsiDev.targets[i].reservedId = -1;\r
-               scsiDev.targets[i].reserverId = -1;\r
-               if (firstInit)\r
-               {\r
-                       scsiDev.targets[i].unitAttention = POWER_ON_RESET;\r
-               }\r
-               else\r
-               {\r
-                       scsiDev.targets[i].unitAttention = PARAMETERS_CHANGED;\r
-               }\r
-               scsiDev.targets[i].sense.code = NO_SENSE;\r
-               scsiDev.targets[i].sense.asc = NO_ADDITIONAL_SENSE_INFORMATION;\r
-\r
-               scsiDev.targets[i].syncOffset = 0;\r
-               scsiDev.targets[i].syncPeriod = 0;\r
-       }\r
-       firstInit = 0;\r
-}\r
-\r
-/* TODO REENABLE\r
-void scsiDisconnect()\r
-{\r
-       scsiEnterPhase(MESSAGE_IN);\r
-       scsiWriteByte(0x02); // save data pointer\r
-       scsiWriteByte(0x04); // disconnect msg.\r
-\r
-       // For now, the caller is responsible for tracking the disconnected\r
-       // state, and calling scsiReconnect.\r
-       // Ideally the client would exit their loop and we'd implement this\r
-       // as part of scsiPoll\r
-       int phase = scsiDev.phase;\r
-       enter_BusFree();\r
-       scsiDev.phase = phase;\r
-}\r
-*/\r
-\r
-/* TODO REENABLE\r
-int scsiReconnect()\r
-{\r
-       int reconnected = 0;\r
-\r
-       int sel = SCSI_ReadFilt(SCSI_Filt_SEL);\r
-       int bsy = SCSI_ReadFilt(SCSI_Filt_BSY);\r
-       if (!sel && !bsy)\r
-       {\r
-               s2s_delay_us(1);\r
-               sel = SCSI_ReadFilt(SCSI_Filt_SEL);\r
-               bsy = SCSI_ReadFilt(SCSI_Filt_BSY);\r
-       }\r
-\r
-       if (!sel && !bsy)\r
-       {\r
-               // Arbitrate.\r
-               s2s_ledOn();\r
-               uint8_t scsiIdMask = 1 << scsiDev.target->targetId;\r
-               SCSI_Out_Bits_Write(scsiIdMask);\r
-               SCSI_Out_Ctl_Write(1); // Write bits manually.\r
-               SCSI_SetPin(SCSI_Out_BSY);\r
-\r
-               s2s_delay_us(3); // arbitrate delay. 2.4us.\r
-\r
-               uint8_t dbx = scsiReadDBxPins();\r
-               sel = SCSI_ReadFilt(SCSI_Filt_SEL);\r
-               if (sel || ((dbx ^ scsiIdMask) > scsiIdMask))\r
-               {\r
-                       // Lost arbitration.\r
-                       SCSI_Out_Ctl_Write(0);\r
-                       SCSI_ClearPin(SCSI_Out_BSY);\r
-                       s2s_ledOff();\r
-               }\r
-               else\r
-               {\r
-                       // Won arbitration\r
-                       SCSI_SetPin(SCSI_Out_SEL);\r
-                       s2s_delay_us(1); // Bus clear + Bus settle.\r
-\r
-                       // Reselection phase\r
-                       SCSI_CTL_PHASE_Write(__scsiphase_io);\r
-                       SCSI_Out_Bits_Write(scsiIdMask | (1 << scsiDev.initiatorId));\r
-                       scsiDeskewDelay(); // 2 deskew delays\r
-                       scsiDeskewDelay(); // 2 deskew delays\r
-                       SCSI_ClearPin(SCSI_Out_BSY);\r
-                       s2s_delay_us(1);  // Bus Settle Delay\r
-\r
-                       uint32_t waitStart_ms = getTime_ms();\r
-                       bsy = SCSI_ReadFilt(SCSI_Filt_BSY);\r
-                       // Wait for initiator.\r
-                       while (\r
-                               !bsy &&\r
-                               !scsiDev.resetFlag &&\r
-                               (elapsedTime_ms(waitStart_ms) < 250))\r
-                       {\r
-                               bsy = SCSI_ReadFilt(SCSI_Filt_BSY);\r
-                       }\r
-\r
-                       if (bsy)\r
+                       S2S_TargetState* state = &(targets[i].state);\r
+                       state->reservedId = -1;\r
+                       state->reserverId = -1;\r
+                       if (firstInit)\r
                        {\r
-                               SCSI_SetPin(SCSI_Out_BSY);\r
-                               scsiDeskewDelay(); // 2 deskew delays\r
-                               scsiDeskewDelay(); // 2 deskew delays\r
-                               SCSI_ClearPin(SCSI_Out_SEL);\r
-\r
-                               // Prepare for the initial IDENTIFY message.\r
-                               SCSI_Out_Ctl_Write(0);\r
-                               scsiEnterPhase(MESSAGE_IN);\r
-\r
-                               // Send identify command\r
-                               scsiWriteByte(0x80);\r
-\r
-                               scsiEnterPhase(scsiDev.phase);\r
-                               reconnected = 1;\r
+                               state->unitAttention = POWER_ON_RESET;\r
                        }\r
                        else\r
                        {\r
-                               // reselect timeout.\r
-                               SCSI_Out_Ctl_Write(0);\r
-                               SCSI_ClearPin(SCSI_Out_SEL);\r
-                               SCSI_CTL_PHASE_Write(0);\r
-                               s2s_ledOff();\r
+                               state->unitAttention = PARAMETERS_CHANGED;\r
                        }\r
+                       state->sense.code = NO_SENSE;\r
+                       state->sense.asc = NO_ADDITIONAL_SENSE_INFORMATION;\r
+\r
+                       state->syncOffset = 0;\r
+                       state->syncPeriod = 0;\r
                }\r
        }\r
-       return reconnected;\r
+       firstInit = 0;\r
 }\r
-*/\r
+\r
 \r
index 64353ada8d845688ec080251ecc81294750e9d7c..ccbba855bc935e05792d562d057bab9284db9af0 100755 (executable)
@@ -17,8 +17,8 @@
 #ifndef SCSI_H
 #define SCSI_H
 
+#include "device.h"
 #include "geometry.h"
-#include "sense.h"
 
 #include <stdint.h>
 
@@ -75,33 +75,6 @@ typedef enum
 #define MAX_SECTOR_SIZE 8192
 #define MIN_SECTOR_SIZE 64
 
-// Shadow parameters, possibly not saved to flash yet.
-// Set via Mode Select
-typedef struct
-{
-       uint16_t bytesPerSector;
-} LiveCfg;
-
-typedef struct
-{
-       uint8_t targetId;
-
-       const S2S_TargetCfg* cfg;
-
-       LiveCfg liveCfg;
-
-       ScsiSense sense;
-
-       uint16_t unitAttention; // Set to the sense qualifier key to be returned.
-
-       // Only let the reserved initiator talk to us.
-       // A 3rd party may be sending the RESERVE/RELEASE commands
-       int reservedId; // 0 -> 7 if reserved. -1 if not reserved.
-       int reserverId; // 0 -> 7 if reserved. -1 if not reserved.
-
-       uint8_t syncOffset;
-       uint8_t syncPeriod;
-} TargetState;
 
 typedef struct
 {
@@ -110,10 +83,8 @@ typedef struct
        // 65536 bytes is the DMA limit
        uint8_t data[MAX_SECTOR_SIZE * 8];
 
-       TargetState targets[S2S_MAX_TARGETS];
-       TargetState* target;
-       S2S_BoardCfg boardCfg;
-
+       S2S_Target* target;
+       S2S_BoardCfg boardCfg; // TODO remove
 
        // Set to true (1) if the ATN flag was set, and we need to
        // enter the MESSAGE_OUT phase.
index 8da0a098e83b4f50f5dd21d41f8b5fb29f980eeb..887b3d088079741c69d093a9e7f93af37a6b6ad5 100755 (executable)
@@ -576,17 +576,18 @@ uint32_t scsiEnterPhaseImmediate(int newPhase)
        while (likely(!scsiDev.resetFlag) && scsiStatusACK()) {}\r
 \r
        int oldPhase = *SCSI_CTRL_PHASE;\r
+       uint8_t syncOffset = scsiDev.target->state.syncOffset;\r
+       uint8_t syncPeriod = scsiDev.target->state.syncPeriod;\r
 \r
        if (newPhase != oldPhase)\r
        {\r
-               if ((newPhase == DATA_IN || newPhase == DATA_OUT) &&\r
-                       scsiDev.target->syncOffset)\r
+               if ((newPhase == DATA_IN || newPhase == DATA_OUT) && syncOffset)\r
                {\r
-                       if (scsiDev.target->syncPeriod < 23)\r
+                       if (syncPeriod < 23)\r
                        {\r
                                scsiSetTiming(SCSI_FAST20_ASSERT, SCSI_FAST20_DESKEW, SCSI_FAST20_HOLD, 1);\r
                        }\r
-                       else if (scsiDev.target->syncPeriod <= 25)\r
+                       else if (syncPeriod <= 25)\r
                        {\r
                                if (newPhase == DATA_IN)\r
                                {\r
@@ -602,26 +603,25 @@ uint32_t scsiEnterPhaseImmediate(int newPhase)
                                // Amiga A3000 OS3.9 sets period to 35 and fails with\r
                                // glitch == 1.\r
                                int glitch =\r
-                                       scsiDev.target->syncPeriod < 35 ? 1 :\r
-                                               (scsiDev.target->syncPeriod < 45 ? 2 : 5);\r
-                               int deskew = syncDeskew(scsiDev.target->syncPeriod);\r
+                                       syncPeriod < 35 ? 1 : (syncPeriod < 45 ? 2 : 5);\r
+                               int deskew = syncDeskew(syncPeriod);\r
                                int assertion;\r
                                if (newPhase == DATA_IN)\r
                                {\r
-                                       assertion = syncAssertionWrite(scsiDev.target->syncPeriod, deskew);\r
+                                       assertion = syncAssertionWrite(syncPeriod, deskew);\r
                                }\r
                                else\r
                                {\r
-                                       assertion = syncAssertionRead(scsiDev.target->syncPeriod);\r
+                                       assertion = syncAssertionRead(syncPeriod);\r
                                }\r
                                scsiSetTiming(\r
                                        assertion,\r
                                        deskew,\r
-                                       syncHold(scsiDev.target->syncPeriod),\r
+                                       syncHold(syncPeriod),\r
                                        glitch);\r
                        }\r
 \r
-                       *SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;\r
+                       *SCSI_CTRL_SYNC_OFFSET = syncOffset;\r
                }\r
                else if (newPhase >= 0)\r
                {\r
@@ -681,13 +681,13 @@ uint32_t scsiEnterPhaseImmediate(int newPhase)
 // theoretical speed / 2\r
 uint32_t s2s_getScsiRateKBs()\r
 {\r
-       if (scsiDev.target->syncOffset)\r
+       if (scsiDev.target->state.syncOffset)\r
        {\r
-               if (scsiDev.target->syncPeriod < 23)\r
+               if (scsiDev.target->state.syncPeriod < 23)\r
                {\r
                        return 20 / 2;\r
                }\r
-               else if (scsiDev.target->syncPeriod <= 25)\r
+               else if (scsiDev.target->state.syncPeriod <= 25)\r
                {\r
                        return 10 / 2;\r
                }\r
@@ -695,7 +695,7 @@ uint32_t s2s_getScsiRateKBs()
                {\r
                        // 1000000000 / (scsiDev.target->syncPeriod * 4) bytes per second\r
                        // (1000000000 / (scsiDev.target->syncPeriod * 4)) / 1000  kB/s\r
-                       return (1000000 / (scsiDev.target->syncPeriod * 4)) / 2;\r
+                       return (1000000 / (scsiDev.target->state.syncPeriod * 4)) / 2;\r
                }\r
        }\r
        else\r
index bc400cbc75e403f27649d68e291f0378ce6efab8..7f4b7e8b195588360a7fe30835037f49781516b3 100755 (executable)
 \r
 #include <string.h>\r
 \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
+\r
 // Global\r
-SdDevice sdDev;\r
+SdCard sdCard S2S_DMA_ALIGN = {\r
+               {\r
+                       sd_getBoardConfig,\r
+                       //sd_findByScsiId,\r
+                       sd_getTargets,\r
+                       sd_getCapacity\r
+               }\r
+};\r
+\r
+S2S_Device* sdDevice = &(sdCard.dev);\r
 \r
 static int sdCmdActive = 0;\r
 \r
@@ -73,8 +87,8 @@ void sdReadDMA(uint32_t lba, uint32_t sectors, uint8_t* outputBuffer)
                scsiDiskReset();\r
 \r
                scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = HARDWARE_ERROR;\r
-               scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;\r
+               scsiDev.target->state.sense.code = HARDWARE_ERROR;\r
+               scsiDev.target->state.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;\r
                scsiDev.phase = STATUS;\r
        }\r
        else\r
@@ -127,10 +141,10 @@ void sdTmpWrite(uint8_t* data, uint32_t lba, int sectors)
 \r
 static void sdClear()\r
 {\r
-       sdDev.version = 0;\r
-       sdDev.capacity = 0;\r
-       memset(sdDev.csd, 0, sizeof(sdDev.csd));\r
-       memset(sdDev.cid, 0, sizeof(sdDev.cid));\r
+       sdCard.version = 0;\r
+       sdCard.capacity = 0;\r
+       memset(sdCard.csd, 0, sizeof(sdCard.csd));\r
+       memset(sdCard.cid, 0, sizeof(sdCard.cid));\r
 }\r
 \r
 static int sdDoInit()\r
@@ -143,9 +157,9 @@ static int sdDoInit()
        int8_t error = BSP_SD_Init();\r
        if (error == MSD_OK)\r
        {\r
-               memcpy(sdDev.csd, &SDCardInfo.SD_csd, sizeof(sdDev.csd));\r
-               memcpy(sdDev.cid, &SDCardInfo.SD_cid, sizeof(sdDev.cid));\r
-               sdDev.capacity = SDCardInfo.CardCapacity / SD_SECTOR_SIZE;\r
+               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
                result = 1;\r
 \r
@@ -181,7 +195,7 @@ static int sdDoInit()
 //bad:\r
        blockDev.state &= ~(DISK_PRESENT | DISK_INITIALISED);\r
 \r
-       sdDev.capacity = 0;\r
+       sdCard.capacity = 0;\r
 \r
 out:\r
        s2s_ledOff();\r
@@ -256,13 +270,13 @@ int sdInit()
                }\r
                else if (!cs && (blockDev.state & DISK_PRESENT))\r
                {\r
-                       sdDev.capacity = 0;\r
+                       sdCard.capacity = 0;\r
                        blockDev.state &= ~DISK_PRESENT;\r
                        blockDev.state &= ~DISK_INITIALISED;\r
                        int i;\r
                        for (i = 0; i < S2S_MAX_TARGETS; ++i)\r
                        {\r
-                               scsiDev.targets[i].unitAttention = PARAMETERS_CHANGED;\r
+                               sdCard.targets[i].state.unitAttention = PARAMETERS_CHANGED;\r
                        }\r
 \r
                        HAL_SD_DeInit(&hsd);\r
@@ -273,3 +287,43 @@ int sdInit()
        return result;\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
+       {\r
+               int cfgSectors = (S2S_CFG_SIZE + 511) / 512;\r
+               BSP_SD_ReadBlocks_DMA(\r
+                       (uint32_t*) &(sdCardDevice->boardCfg[0]),\r
+                       (sdCardDevice->capacity - cfgSectors) * 512ll,\r
+                       512,\r
+                       cfgSectors);\r
+\r
+               S2S_BoardCfg* cfg = (S2S_BoardCfg*) &(sdCardDevice->boardCfg[0]);\r
+               if (memcmp(cfg->magic, "BCFG", 4))\r
+               {\r
+                       return NULL;\r
+               }\r
+               else\r
+               {\r
+                       return cfg;\r
+               }\r
+       }\r
+\r
+       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
+       *count = S2S_MAX_TARGETS;\r
+       return sdCardDevice->targets;\r
+}\r
+\r
+static uint32_t sd_getCapacity(S2S_Device* dev)\r
+{\r
+       SdCard* sdCardDevice = (SdCard*)dev;\r
+       return sdCardDevice->capacity;\r
+}\r
index b82f11920835d690a20b0fc408587cc742bc18f0..3a3fd556260de61b659af7da3ec72bdc52a17aeb 100755 (executable)
 #define S2S_SD_H
 
 #include <stdint.h>
+#include "bsp.h"
+#include "device.h"
 
 #define SD_SECTOR_SIZE 512
 
 typedef struct
 {
+       S2S_Device dev;
+
+       uint8_t boardCfg[S2S_CFG_SIZE] S2S_DMA_ALIGN;
+
+       S2S_Target targets[S2S_MAX_TARGETS];
+
        int version; // SDHC = version 2.
        uint32_t capacity; // in 512 byte blocks
 
        uint8_t csd[16]; // Unparsed CSD
        uint8_t cid[16]; // Unparsed CID
-} SdDevice;
+} SdCard;
+
+extern SdCard sdCard; // TODO move to .c file
 
-extern SdDevice sdDev;
+extern S2S_Device* sdDevice;
 
 int sdInit(void);
 
index 8fb6aa89e9ef917c2bb4974826ed9da449930ac5..b9666ad9edf5f534b79d1189c9af83be11fcb517 100755 (executable)
@@ -16,8 +16,6 @@
 //     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
 
 
-#include "usbd_msc_storage_sd.h"
-#include "stm32f2xx.h"
 #include "../bsp_driver_sd.h"
 #include "../bsp.h"
 #include "../disk.h"
 #include "../config.h"
 #include "../geometry.h"
 #include "../inquiry.h"
-#include "usb_device.h"
 
+#include "usbd_msc_storage_sd.h"
+#include "stm32f2xx.h"
+#include "usb_device.h"
 
 
 static int8_t s2s_usbd_storage_Init(uint8_t lun);
@@ -69,24 +69,32 @@ USBD_StorageTypeDef USBD_MSC_SD_fops =
        s2s_usbd_storage_Inquiry
 };
 
-static const S2S_TargetCfg* getUsbConfig(uint8_t lun) {
+static const S2S_Target* getUsbTarget(uint8_t lun) {
        int count = 0;
-       for (int i = 0; i < S2S_MAX_TARGETS; ++i)
+       int deviceCount;
+       S2S_Device* devices = s2s_GetDevices(&deviceCount);
+       for (int deviceIdx = 0; deviceIdx < deviceCount; ++deviceIdx)
        {
-               const S2S_TargetCfg* cfg = s2s_getConfigByIndex(i);
-               if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))
+               int targetCount;
+               S2S_Target* targets = devices[deviceIdx].getTargets(devices + deviceIdx, &targetCount);
+               for (int targetIdx = 0; targetIdx < targetCount; ++targetIdx)
                {
-                       if (count == lun)
-                       {
-                               return cfg;
-                       }
-                       else
+                       S2S_Target* target = targets + targetIdx;
+                       if (target && (target->cfg->scsiId & S2S_CFG_TARGET_ENABLED))
                        {
-                               count++;
+                               if (count == lun)
+                               {
+                                       return target;
+                               }
+                               else
+                               {
+                                       count++;
+                               }
                        }
                }
        }
-       return s2s_getConfigByIndex(0); // Fallback, try not to crash
+       int dummy;
+       return devices[0].getTargets(devices, &dummy); // Fallback, try not to crash
 }
 
 int8_t s2s_usbd_storage_Init(uint8_t lun)
@@ -96,30 +104,31 @@ int8_t s2s_usbd_storage_Init(uint8_t lun)
 
 int8_t s2s_usbd_storage_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size)
 {
-       const S2S_TargetCfg* cfg = getUsbConfig(lun);
+       const S2S_Target* target = getUsbTarget(lun);
 
        uint32_t capacity = getScsiCapacity(
-               cfg->sdSectorStart,
-               cfg->bytesPerSector,
-               cfg->scsiSectors);
+               target->device,
+               target->cfg->sdSectorStart,
+               target->state.bytesPerSector,
+               target->cfg->scsiSectors);
 
        *block_num  = capacity;
-       *block_size = cfg->bytesPerSector;
+       *block_size = target->state.bytesPerSector;
        return (0);
 }
 
 uint32_t s2s_usbd_storage_Inquiry (uint8_t lun, uint8_t* buf, uint8_t maxlen)
 {
-       const S2S_TargetCfg* cfg = getUsbConfig(lun);
+       const S2S_Target* target = getUsbTarget(lun);
 
-       return s2s_getStandardInquiry(cfg, buf, maxlen);
+       return s2s_getStandardInquiry(target->cfg, buf, maxlen);
 }
 
 int8_t s2s_usbd_storage_IsReady (uint8_t lun)
 {
-       const S2S_TargetCfg* cfg = getUsbConfig(lun);
+       const S2S_Target* target = getUsbTarget(lun);
        return (
-                       cfg &&
+                       target &&
                        (blockDev.state & DISK_PRESENT) &&
                        (blockDev.state & DISK_INITIALISED)
                        ) ? 0 : 1; // inverse logic
@@ -137,24 +146,24 @@ int8_t s2s_usbd_storage_Read (uint8_t lun,
                uint16_t blk_len)
 {
        s2s_ledOn();
-       const S2S_TargetCfg* cfg = getUsbConfig(lun);
+       const S2S_Target* target = getUsbTarget(lun);
 
-       if (cfg->bytesPerSector == 512)
+       if (target->state.bytesPerSector == 512)
        {
                BSP_SD_ReadBlocks_DMA(
                        (uint32_t*) buf,
-                       (cfg->sdSectorStart + blk_addr) * 512ll,
+                       (target->cfg->sdSectorStart + blk_addr) * 512ll,
                        512,
                        blk_len);
        }
        else
        {
-               int sdPerScsi = SDSectorsPerSCSISector(cfg->bytesPerSector);
-               int sdSectorNum =  cfg->sdSectorStart + (blk_addr * sdPerScsi);
+               int sdPerScsi = SDSectorsPerSCSISector(target->state.bytesPerSector);
+               int sdSectorNum =  target->cfg->sdSectorStart + (blk_addr * sdPerScsi);
 
                for (int blk = 0; blk < blk_len; ++blk)
                {
-                       for (int i = 0; i < SDSectorsPerSCSISector(cfg->bytesPerSector); ++i)
+                       for (int i = 0; i < SDSectorsPerSCSISector(target->state.bytesPerSector); ++i)
                        {
                                uint8_t partial[512] S2S_DMA_ALIGN;
                                BSP_SD_ReadBlocks_DMA(
@@ -164,16 +173,14 @@ int8_t s2s_usbd_storage_Read (uint8_t lun,
                                        1);
                                sdSectorNum++;
 
-                               int validBytes = cfg->bytesPerSector % SD_SECTOR_SIZE;
+                               int validBytes = target->state.bytesPerSector % SD_SECTOR_SIZE;
                                if (validBytes == 0) validBytes = SD_SECTOR_SIZE;
 
                                memcpy(buf, partial, validBytes);
 
                                buf += validBytes;
                        }
-
                }
-
        }
        s2s_ledOff();
        return 0;
@@ -185,24 +192,24 @@ int8_t s2s_usbd_storage_Write (uint8_t lun,
                uint16_t blk_len)
 {
        s2s_ledOn();
-       const S2S_TargetCfg* cfg = getUsbConfig(lun);
+       const S2S_Target* target = getUsbTarget(lun);
 
-       if (cfg->bytesPerSector == 512)
+       if (target->state.bytesPerSector == 512)
        {
                BSP_SD_WriteBlocks_DMA(
                        (uint32_t*) buf,
-                       (cfg->sdSectorStart + blk_addr) * 512ll,
+                       (target->cfg->sdSectorStart + blk_addr) * 512ll,
                        512,
                        blk_len);
        }
        else
        {
-               int sdPerScsi = SDSectorsPerSCSISector(cfg->bytesPerSector);
-               int sdSectorNum =  cfg->sdSectorStart + (blk_addr * sdPerScsi);
+               int sdPerScsi = SDSectorsPerSCSISector(target->state.bytesPerSector);
+               int sdSectorNum =  target->cfg->sdSectorStart + (blk_addr * sdPerScsi);
 
                for (int blk = 0; blk < blk_len; ++blk)
                {
-                       for (int i = 0; i < SDSectorsPerSCSISector(cfg->bytesPerSector); ++i)
+                       for (int i = 0; i < SDSectorsPerSCSISector(target->state.bytesPerSector); ++i)
                        {
                                uint8_t partial[512] S2S_DMA_ALIGN;
                                memcpy(partial, buf, 512);
@@ -214,7 +221,7 @@ int8_t s2s_usbd_storage_Write (uint8_t lun,
                                        1);
                                sdSectorNum++;
 
-                               int validBytes = cfg->bytesPerSector % SD_SECTOR_SIZE;
+                               int validBytes = target->state.bytesPerSector % SD_SECTOR_SIZE;
                                if (validBytes == 0) validBytes = SD_SECTOR_SIZE;
 
                                buf += validBytes;
@@ -231,12 +238,19 @@ int8_t s2s_usbd_storage_Write (uint8_t lun,
 int8_t s2s_usbd_storage_GetMaxLun (void)
 {
        int count = 0;
-       for (int i = 0; i < S2S_MAX_TARGETS; ++i)
+       int deviceCount;
+       S2S_Device* devices = s2s_GetDevices(&deviceCount);
+       for (int deviceIdx = 0; deviceIdx < deviceCount; ++deviceIdx)
        {
-               const S2S_TargetCfg* cfg = s2s_getConfigByIndex(i);
-               if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))
+               int targetCount;
+               S2S_Target* targets = devices[deviceIdx].getTargets(devices + deviceIdx, &targetCount);
+               for (int targetIdx = 0; targetIdx < targetCount; ++targetIdx)
                {
-                       count++;
+                       S2S_Target* target = targets + targetIdx;
+                       if (target && (target->cfg->scsiId & S2S_CFG_TARGET_ENABLED))
+                       {
+                               count++;
+                       }
                }
        }
        return count - 1 < 0 ? 0 : count - 1;