// 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
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
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
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
likely(scsiDev.phase == DATA_IN) &&\r
likely(!scsiDev.resetFlag))\r
{\r
-#if 0\r
- _WFI();\r
-#endif\r
}\r
\r
\r
\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
// 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
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
\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