Fix terrible performance
[SCSI2SD-V6.git] / src / firmware / disk.c
index 886bfe2..2e69d48 100755 (executable)
 //     You should have received a copy of the GNU General Public License\r
 //     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.\r
 \r
+#include "stm32f2xx.h"\r
+\r
 #include "scsi.h"\r
 #include "scsiPhy.h"\r
 #include "config.h"\r
-#include "debug.h"\r
 #include "disk.h"\r
 #include "sd.h"\r
 #include "time.h"\r
@@ -35,12 +36,7 @@ static int doSdInit()
        int result = 0;\r
        if (blockDev.state & DISK_PRESENT)\r
        {\r
-               result = sdInit();\r
-\r
-               if (result)\r
-               {\r
-                       blockDev.state = blockDev.state | DISK_INITIALISED;\r
-               }\r
+               blockDev.state = blockDev.state | DISK_INITIALISED;\r
        }\r
        return result;\r
 }\r
@@ -552,63 +548,41 @@ void scsiDiskPoll()
                int prep = 0;\r
                int i = 0;\r
                int scsiActive = 0;\r
-               // int sdActive = 0;\r
+               int sdActive = 0;\r
                while ((i < totalSDSectors) &&\r
                        likely(scsiDev.phase == DATA_IN) &&\r
                        likely(!scsiDev.resetFlag))\r
                {\r
-                       // Wait for the next DMA interrupt. It's beneficial to halt the\r
-                       // processor to give the DMA controller more memory bandwidth to\r
-                       // work with.\r
-#if 0\r
-                       int scsiBusy = 1;\r
-                       int sdBusy = 1;\r
-                       while (scsiBusy && sdBusy)\r
-                       {\r
-                               uint8_t intr = CyEnterCriticalSection();\r
-                               scsiBusy = scsiDMABusy();\r
-                               sdBusy = sdDMABusy();\r
-                               if (scsiBusy && sdBusy)\r
-                               {\r
-                                       __WFI();\r
-                               }\r
-                               CyExitCriticalSection(intr);\r
-                       }\r
-#endif\r
-\r
-#if 0\r
-                       if (sdActive && !sdBusy && sdReadSectorDMAPoll())\r
+                       if (sdActive && sdReadDMAPoll())\r
                        {\r
+                               prep += sdActive;\r
                                sdActive = 0;\r
-                               prep++;\r
                        }\r
 \r
-                       // Usually SD is slower than the SCSI interface.\r
-                       // Prioritise starting the read of the next sector over starting a\r
-                       // SCSI transfer for the last sector\r
-                       // ie. NO "else" HERE.\r
                        if (!sdActive &&\r
                                (prep - i < buffers) &&\r
                                (prep < totalSDSectors))\r
                        {\r
                                // Start an SD transfer if we have space.\r
-                               if (transfer.multiBlock)\r
+                               uint32_t startBuffer = prep % buffers;\r
+                               uint32_t sectors = totalSDSectors - prep;\r
+#if 0\r
+                               if (!scsiActive && prep == i)\r
                                {\r
-                                       sdReadMultiSectorDMA(&scsiDev.data[SD_SECTOR_SIZE * (prep % buffers)]);\r
+                                       sectors = 1; // We need to get some data to send ASAP !\r
                                }\r
                                else\r
+#endif\r
                                {\r
-                                       sdReadSingleSectorDMA(sdLBA + prep, &scsiDev.data[SD_SECTOR_SIZE * (prep % buffers)]);\r
+                                       uint32_t freeBuffers = buffers - (prep - i);\r
+                                       uint32_t contiguousBuffers = buffers - startBuffer;\r
+                                       freeBuffers = freeBuffers < contiguousBuffers\r
+                                               ? freeBuffers : contiguousBuffers;\r
+                                       sectors = sectors < freeBuffers ? sectors : freeBuffers;\r
                                }\r
-                               sdActive = 1;\r
-                       }\r
-#endif\r
-                       if ((prep - i < buffers) &&\r
-                               (prep < totalSDSectors))\r
-                       {\r
-                               // TODO MM Blocking reads are bad mmkay\r
-                               sdTmpRead(&scsiDev.data[SD_SECTOR_SIZE * (prep % buffers)], sdLBA + prep, 1);\r
-                               prep++;\r
+                               sdReadDMA(sdLBA + prep, sectors, &scsiDev.data[SD_SECTOR_SIZE * startBuffer]);\r
+\r
+                               sdActive = sectors;\r
                        }\r
 \r
                        if (scsiActive && scsiPhyComplete() && scsiWriteDMAPoll())\r
@@ -628,7 +602,6 @@ void scsiDiskPoll()
                                scsiWriteDMA(&scsiDev.data[SD_SECTOR_SIZE * (i % buffers)], dmaBytes);\r
                                scsiActive = 1;\r
                        }\r
-\r
                }\r
 \r
                // We've finished transferring the data to the FPGA, now wait until it's\r
@@ -637,9 +610,6 @@ void scsiDiskPoll()
                        likely(scsiDev.phase == DATA_IN) &&\r
                        likely(!scsiDev.resetFlag))\r
                {\r
-#if 0\r
-               _WFI();\r
-#endif\r
                }\r
 \r
 \r
@@ -656,6 +626,11 @@ void scsiDiskPoll()
 \r
                const int sdPerScsi = SDSectorsPerSCSISector(bytesPerSector);\r
                int totalSDSectors = transfer.blocks * sdPerScsi;\r
+               uint32_t sdLBA =\r
+                       SCSISector2SD(\r
+                               scsiDev.target->cfg->sdSectorStart,\r
+                               bytesPerSector,\r
+                               transfer.lba);\r
                // int buffers = sizeof(scsiDev.data) / SD_SECTOR_SIZE;\r
                // int prep = 0;\r
                int i = 0;\r
@@ -674,10 +649,11 @@ void scsiDiskPoll()
                        // do this in a half-duplex fashion. We need to write as much as\r
                        // possible in each SD card transaction.\r
                        uint32_t maxSectors = sizeof(scsiDev.data) / SD_SECTOR_SIZE;\r
+                       uint32_t rem = totalSDSectors - i;\r
                        uint32_t sectors =\r
-                               totalSDSectors < maxSectors ? totalSDSectors : maxSectors;\r
+                               rem < maxSectors ? rem : maxSectors;\r
                        scsiRead(&scsiDev.data[0], sectors * SD_SECTOR_SIZE);\r
-                       sdTmpWrite(&scsiDev.data[0], i + transfer.lba, sectors);\r
+                       sdTmpWrite(&scsiDev.data[0], i + sdLBA, sectors);\r
                        i += sectors;\r
 #if 0\r
                        // Wait for the next DMA interrupt. It's beneficial to halt the\r
@@ -844,14 +820,14 @@ void scsiDiskReset()
        transfer.currentBlock = 0;\r
 \r
        // Cancel long running commands!\r
+#if 0\r
        if (\r
                ((scsiDev.boardCfg.flags & S2S_CFG_ENABLE_CACHE) == 0) ||\r
                        (transfer.multiBlock == 0)\r
                )\r
+#endif\r
        {\r
-#if 0\r
                sdCompleteTransfer();\r
-#endif\r
        }\r
 \r
        transfer.multiBlock = 0;\r
@@ -863,13 +839,5 @@ void scsiDiskInit()
 \r
        // Don't require the host to send us a START STOP UNIT command\r
        blockDev.state = DISK_STARTED;\r
-       // WP pin not available for micro-sd\r
-       // TODO read card WP register\r
-       #if 0\r
-       if (SD_WP_Read())\r
-       {\r
-               blockDev.state = blockDev.state | DISK_WP;\r
-       }\r
-       #endif\r
 }\r
 \r