1 // Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
2 // Copyright (C) 2014 Doug Brown <doug@downtowndougbrown.com>
4 // This file is part of SCSI2SD.
6 // SCSI2SD is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
11 // SCSI2SD is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
20 #include "stm32f2xx.h"
23 #include "stm32f4xx.h"
28 // For SD write direct routines
30 #include "bsp_driver_sd.h"
50 if (blockDev
.state
& DISK_PRESENT
)
52 blockDev
.state
= blockDev
.state
| DISK_INITIALISED
;
57 // Callback once all data has been read in the data out phase.
58 static void doFormatUnitComplete(void)
60 // TODO start writing the initialisation pattern to the SD
62 scsiDev
.phase
= STATUS
;
65 static void doFormatUnitSkipData(int bytes
)
67 // We may not have enough memory to store the initialisation pattern and
68 // defect list data. Since we're not making use of it yet anyway, just
70 scsiEnterPhase(DATA_OUT
);
72 for (i
= 0; i
< bytes
; ++i
)
78 // Callback from the data out phase.
79 static void doFormatUnitPatternHeader(void)
82 ((((uint16_t)scsiDev
.data
[2])) << 8) +
86 ((((uint16_t)scsiDev
.data
[4 + 2])) << 8) +
89 doFormatUnitSkipData(defectLength
+ patternLength
);
90 doFormatUnitComplete();
93 // Callback from the data out phase.
94 static void doFormatUnitHeader(void)
96 int IP
= (scsiDev
.data
[1] & 0x08) ? 1 : 0;
97 int DSP
= (scsiDev
.data
[1] & 0x04) ? 1 : 0;
99 if (! DSP
) // disable save parameters
101 // Save the "MODE SELECT savable parameters"
103 scsiDev
.target
->targetId
,
104 scsiDev
.target
->liveCfg
.bytesPerSector
);
109 // We need to read the initialisation pattern header first.
110 scsiDev
.dataLen
+= 4;
111 scsiDev
.phase
= DATA_OUT
;
112 scsiDev
.postDataOutHook
= doFormatUnitPatternHeader
;
116 // Read the defect list data
118 ((((uint16_t)scsiDev
.data
[2])) << 8) +
120 doFormatUnitSkipData(defectLength
);
121 doFormatUnitComplete();
125 static void doReadCapacity()
127 uint32_t lba
= (((uint32_t) scsiDev
.cdb
[2]) << 24) +
128 (((uint32_t) scsiDev
.cdb
[3]) << 16) +
129 (((uint32_t) scsiDev
.cdb
[4]) << 8) +
131 int pmi
= scsiDev
.cdb
[8] & 1;
133 uint32_t capacity
= getScsiCapacity(
134 scsiDev
.target
->cfg
->sdSectorStart
,
135 scsiDev
.target
->liveCfg
.bytesPerSector
,
136 scsiDev
.target
->cfg
->scsiSectors
);
141 // We don't do anything with the "partial medium indicator", and
142 // assume that delays are constant across each block. But the spec
143 // says we must return this error if pmi is specified incorrectly.
144 scsiDev
.status
= CHECK_CONDITION
;
145 scsiDev
.target
->sense
.code
= ILLEGAL_REQUEST
;
146 scsiDev
.target
->sense
.asc
= INVALID_FIELD_IN_CDB
;
147 scsiDev
.phase
= STATUS
;
149 else if (capacity
> 0)
151 uint32_t highestBlock
= capacity
- 1;
153 scsiDev
.data
[0] = highestBlock
>> 24;
154 scsiDev
.data
[1] = highestBlock
>> 16;
155 scsiDev
.data
[2] = highestBlock
>> 8;
156 scsiDev
.data
[3] = highestBlock
;
158 uint32_t bytesPerSector
= scsiDev
.target
->liveCfg
.bytesPerSector
;
159 scsiDev
.data
[4] = bytesPerSector
>> 24;
160 scsiDev
.data
[5] = bytesPerSector
>> 16;
161 scsiDev
.data
[6] = bytesPerSector
>> 8;
162 scsiDev
.data
[7] = bytesPerSector
;
164 scsiDev
.phase
= DATA_IN
;
168 scsiDev
.status
= CHECK_CONDITION
;
169 scsiDev
.target
->sense
.code
= NOT_READY
;
170 scsiDev
.target
->sense
.asc
= MEDIUM_NOT_PRESENT
;
171 scsiDev
.phase
= STATUS
;
175 static void doWrite(uint32_t lba
, uint32_t blocks
)
177 if (unlikely(scsiDev
.target
->cfg
->deviceType
== S2S_CFG_FLOPPY_14MB
)) {
178 // Floppies are supposed to be slow. Some systems can't handle a floppy
179 // without an access time
183 uint32_t bytesPerSector
= scsiDev
.target
->liveCfg
.bytesPerSector
;
185 if (unlikely(blockDev
.state
& DISK_WP
) ||
186 unlikely(scsiDev
.target
->cfg
->deviceType
== S2S_CFG_OPTICAL
))
189 scsiDev
.status
= CHECK_CONDITION
;
190 scsiDev
.target
->sense
.code
= ILLEGAL_REQUEST
;
191 scsiDev
.target
->sense
.asc
= WRITE_PROTECTED
;
192 scsiDev
.phase
= STATUS
;
194 else if (unlikely(((uint64_t) lba
) + blocks
>
196 scsiDev
.target
->cfg
->sdSectorStart
,
198 scsiDev
.target
->cfg
->scsiSectors
202 scsiDev
.status
= CHECK_CONDITION
;
203 scsiDev
.target
->sense
.code
= ILLEGAL_REQUEST
;
204 scsiDev
.target
->sense
.asc
= LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE
;
205 scsiDev
.phase
= STATUS
;
210 transfer
.blocks
= blocks
;
211 transfer
.currentBlock
= 0;
212 scsiDev
.phase
= DATA_OUT
;
213 scsiDev
.dataLen
= bytesPerSector
;
214 scsiDev
.dataPtr
= bytesPerSector
;
216 // No need for single-block writes atm. Overhead of the
217 // multi-block write is minimal.
218 transfer
.multiBlock
= 1;
221 // TODO uint32_t sdLBA =
222 // TODO SCSISector2SD(
223 // TODO scsiDev.target->cfg->sdSectorStart,
224 // TODO bytesPerSector,
226 // TODO uint32_t sdBlocks = blocks * SDSectorsPerSCSISector(bytesPerSector);
227 // TODO sdWriteMultiSectorPrep(sdLBA, sdBlocks);
232 static void doRead(uint32_t lba
, uint32_t blocks
)
234 if (unlikely(scsiDev
.target
->cfg
->deviceType
== S2S_CFG_FLOPPY_14MB
)) {
235 // Floppies are supposed to be slow. Some systems can't handle a floppy
236 // without an access time
240 uint32_t capacity
= getScsiCapacity(
241 scsiDev
.target
->cfg
->sdSectorStart
,
242 scsiDev
.target
->liveCfg
.bytesPerSector
,
243 scsiDev
.target
->cfg
->scsiSectors
);
244 if (unlikely(((uint64_t) lba
) + blocks
> capacity
))
246 scsiDev
.status
= CHECK_CONDITION
;
247 scsiDev
.target
->sense
.code
= ILLEGAL_REQUEST
;
248 scsiDev
.target
->sense
.asc
= LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE
;
249 scsiDev
.phase
= STATUS
;
254 transfer
.blocks
= blocks
;
255 transfer
.currentBlock
= 0;
256 scsiDev
.phase
= DATA_IN
;
257 scsiDev
.dataLen
= 0; // No data yet
259 uint32_t bytesPerSector
= scsiDev
.target
->liveCfg
.bytesPerSector
;
260 uint32_t sdSectorPerSCSISector
= SDSectorsPerSCSISector(bytesPerSector
);
262 blocks
* sdSectorPerSCSISector
;
266 !(scsiDev
.boardCfg
.flags
& S2S_CFG_ENABLE_CACHE
)
268 unlikely(((uint64_t) lba
) + blocks
== capacity
)
271 // We get errors on reading the last sector using a multi-sector
273 transfer
.multiBlock
= 0;
277 transfer
.multiBlock
= 1;
281 // scsiDev.target->cfg->sdSectorStart,
285 // TODO sdReadMultiSectorPrep(sdLBA, sdSectors);
290 static void doSeek(uint32_t lba
)
294 scsiDev
.target
->cfg
->sdSectorStart
,
295 scsiDev
.target
->liveCfg
.bytesPerSector
,
296 scsiDev
.target
->cfg
->scsiSectors
)
299 scsiDev
.status
= CHECK_CONDITION
;
300 scsiDev
.target
->sense
.code
= ILLEGAL_REQUEST
;
301 scsiDev
.target
->sense
.asc
= LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE
;
302 scsiDev
.phase
= STATUS
;
310 static int doTestUnitReady()
313 if (likely(blockDev
.state
== (DISK_STARTED
| DISK_PRESENT
| DISK_INITIALISED
)))
317 else if (unlikely(!(blockDev
.state
& DISK_STARTED
)))
320 scsiDev
.status
= CHECK_CONDITION
;
321 scsiDev
.target
->sense
.code
= NOT_READY
;
322 scsiDev
.target
->sense
.asc
= LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED
;
323 scsiDev
.phase
= STATUS
;
325 else if (unlikely(!(blockDev
.state
& DISK_PRESENT
)))
328 scsiDev
.status
= CHECK_CONDITION
;
329 scsiDev
.target
->sense
.code
= NOT_READY
;
330 scsiDev
.target
->sense
.asc
= MEDIUM_NOT_PRESENT
;
331 scsiDev
.phase
= STATUS
;
333 else if (unlikely(!(blockDev
.state
& DISK_INITIALISED
)))
336 scsiDev
.status
= CHECK_CONDITION
;
337 scsiDev
.target
->sense
.code
= NOT_READY
;
338 scsiDev
.target
->sense
.asc
= LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE
;
339 scsiDev
.phase
= STATUS
;
344 // Handle direct-access scsi device commands
345 int scsiDiskCommand()
347 int commandHandled
= 1;
349 uint8_t command
= scsiDev
.cdb
[0];
350 if (unlikely(command
== 0x1B))
353 // Enable or disable media access operations.
354 //int immed = scsiDev.cdb[1] & 1;
355 int start
= scsiDev
.cdb
[4] & 1;
356 int loadEject
= scsiDev
.cdb
[4] & 2;
360 // Ignore load/eject requests. We can't do that.
364 blockDev
.state
= blockDev
.state
| DISK_STARTED
;
365 if (!(blockDev
.state
& DISK_INITIALISED
))
372 blockDev
.state
&= ~DISK_STARTED
;
375 else if (unlikely(command
== 0x00))
380 else if (unlikely(!doTestUnitReady()))
382 // Status and sense codes already set by doTestUnitReady
384 else if (likely(command
== 0x08))
388 (((uint32_t) scsiDev
.cdb
[1] & 0x1F) << 16) +
389 (((uint32_t) scsiDev
.cdb
[2]) << 8) +
391 uint32_t blocks
= scsiDev
.cdb
[4];
392 if (unlikely(blocks
== 0)) blocks
= 256;
395 else if (likely(command
== 0x28))
398 // Ignore all cache control bits - we don't support a memory cache.
401 (((uint32_t) scsiDev
.cdb
[2]) << 24) +
402 (((uint32_t) scsiDev
.cdb
[3]) << 16) +
403 (((uint32_t) scsiDev
.cdb
[4]) << 8) +
406 (((uint32_t) scsiDev
.cdb
[7]) << 8) +
411 else if (likely(command
== 0x0A))
415 (((uint32_t) scsiDev
.cdb
[1] & 0x1F) << 16) +
416 (((uint32_t) scsiDev
.cdb
[2]) << 8) +
418 uint32_t blocks
= scsiDev
.cdb
[4];
419 if (unlikely(blocks
== 0)) blocks
= 256;
420 doWrite(lba
, blocks
);
422 else if (likely(command
== 0x2A) || // WRITE(10)
423 unlikely(command
== 0x2E)) // WRITE AND VERIFY
425 // Ignore all cache control bits - we don't support a memory cache.
426 // Don't bother verifying either. The SD card likely stores ECC
427 // along with each flash row.
430 (((uint32_t) scsiDev
.cdb
[2]) << 24) +
431 (((uint32_t) scsiDev
.cdb
[3]) << 16) +
432 (((uint32_t) scsiDev
.cdb
[4]) << 8) +
435 (((uint32_t) scsiDev
.cdb
[7]) << 8) +
438 doWrite(lba
, blocks
);
440 else if (unlikely(command
== 0x04))
443 // We don't really do any formatting, but we need to read the correct
444 // number of bytes in the DATA_OUT phase to make the SCSI host happy.
446 int fmtData
= (scsiDev
.cdb
[1] & 0x10) ? 1 : 0;
449 // We need to read the parameter list, but we don't know how
450 // big it is yet. Start with the header.
452 scsiDev
.phase
= DATA_OUT
;
453 scsiDev
.postDataOutHook
= doFormatUnitHeader
;
457 // No data to read, we're already finished!
460 else if (unlikely(command
== 0x25))
465 else if (unlikely(command
== 0x0B))
469 (((uint32_t) scsiDev
.cdb
[1] & 0x1F) << 16) +
470 (((uint32_t) scsiDev
.cdb
[2]) << 8) +
476 else if (unlikely(command
== 0x2B))
480 (((uint32_t) scsiDev
.cdb
[2]) << 24) +
481 (((uint32_t) scsiDev
.cdb
[3]) << 16) +
482 (((uint32_t) scsiDev
.cdb
[4]) << 8) +
487 else if (unlikely(command
== 0x36))
490 // We don't have a cache to lock data into. do nothing.
492 else if (unlikely(command
== 0x34))
495 // We don't have a cache to pre-fetch into. do nothing.
497 else if (unlikely(command
== 0x1E))
499 // PREVENT ALLOW MEDIUM REMOVAL
500 // Not much we can do to prevent the user removing the SD card.
503 else if (unlikely(command
== 0x01))
506 // Set the lun to a vendor-specific state. Ignore.
508 else if (unlikely(command
== 0x35))
511 // We don't have a cache. do nothing.
513 else if (unlikely(command
== 0x2F))
516 // TODO: When they supply data to verify, we should read the data and
517 // verify it. If they don't supply any data, just say success.
518 if ((scsiDev
.cdb
[1] & 0x02) == 0)
520 // They are asking us to do a medium verification with no data
521 // comparison. Assume success, do nothing.
525 // TODO. This means they are supplying data to verify against.
526 // Technically we should probably grab the data and compare it.
527 scsiDev
.status
= CHECK_CONDITION
;
528 scsiDev
.target
->sense
.code
= ILLEGAL_REQUEST
;
529 scsiDev
.target
->sense
.asc
= INVALID_FIELD_IN_CDB
;
530 scsiDev
.phase
= STATUS
;
533 else if (unlikely(command
== 0x37))
536 uint32_t allocLength
= (((uint16_t)scsiDev
.cdb
[7]) << 8) |
540 scsiDev
.data
[1] = scsiDev
.cdb
[1];
545 if (scsiDev
.dataLen
> allocLength
)
547 scsiDev
.dataLen
= allocLength
;
550 scsiDev
.phase
= DATA_IN
;
557 return commandHandled
;
562 uint32_t bytesPerSector
= scsiDev
.target
->liveCfg
.bytesPerSector
;
564 if (scsiDev
.phase
== DATA_IN
&&
565 transfer
.currentBlock
!= transfer
.blocks
)
567 // Take responsibility for waiting for the phase delays
568 uint32_t phaseChangeDelayUs
= scsiEnterPhaseImmediate(DATA_IN
);
571 transfer
.blocks
* SDSectorsPerSCSISector(bytesPerSector
);
574 scsiDev
.target
->cfg
->sdSectorStart
,
578 const int sdPerScsi
= SDSectorsPerSCSISector(bytesPerSector
);
579 const int buffers
= sizeof(scsiDev
.data
) / SD_SECTOR_SIZE
;
582 int scsiActive
__attribute__((unused
)) = 0; // unused if DMA disabled
585 // It's highly unlikely that someone is going to use huge transfers
586 // per scsi command, but if they do it'll be slower than usual.
587 uint32_t totalScsiBytes
= transfer
.blocks
* bytesPerSector
;
588 int useSlowDataCount
= totalScsiBytes
>= SCSI_XFER_MAX
;
589 if (!useSlowDataCount
)
591 scsiSetDataCount(totalScsiBytes
);
594 while ((i
< totalSDSectors
) &&
595 likely(scsiDev
.phase
== DATA_IN
) &&
596 likely(!scsiDev
.resetFlag
))
598 int completedDmaSectors
;
599 if (sdActive
&& (completedDmaSectors
= sdReadDMAPoll(sdActive
)))
601 prep
+= completedDmaSectors
;
602 sdActive
-= completedDmaSectors
;
603 } else if (sdActive
> 1)
605 if ((scsiDev
.data
[SD_SECTOR_SIZE
* (prep
% buffers
) + 510] != 0xAA) ||
606 (scsiDev
.data
[SD_SECTOR_SIZE
* (prep
% buffers
) + 511] != 0x33))
614 (prep
- i
< buffers
) &&
615 (prep
< totalSDSectors
) &&
616 ((totalSDSectors
- prep
) >= sdPerScsi
) &&
617 (likely(!useSlowDataCount
) || scsiPhyComplete()) &&
618 (HAL_SD_GetState(&hsd
) != HAL_SD_STATE_BUSY
)) // rx complete but IRQ not fired yet.
620 // Start an SD transfer if we have space.
621 uint32_t startBuffer
= prep
% buffers
;
622 uint32_t sectors
= totalSDSectors
- prep
;
623 uint32_t freeBuffers
= buffers
- (prep
- i
);
625 uint32_t contiguousBuffers
= buffers
- startBuffer
;
626 freeBuffers
= freeBuffers
< contiguousBuffers
627 ? freeBuffers
: contiguousBuffers
;
628 sectors
= sectors
< freeBuffers
? sectors
: freeBuffers
;
630 if (sectors
> 128) sectors
= 128; // 65536 DMA limit !!
632 // Round-down when we have odd sector sizes.
635 sectors
= (sectors
/ sdPerScsi
) * sdPerScsi
;
638 for (int dodgy
= 0; dodgy
< sectors
; dodgy
++)
640 scsiDev
.data
[SD_SECTOR_SIZE
* (startBuffer
+ dodgy
) + 510] = 0xAA;
641 scsiDev
.data
[SD_SECTOR_SIZE
* (startBuffer
+ dodgy
) + 511] = 0x33;
644 sdReadDMA(sdLBA
+ prep
, sectors
, &scsiDev
.data
[SD_SECTOR_SIZE
* startBuffer
]);
648 if (useSlowDataCount
)
650 scsiSetDataCount((sectors
/ sdPerScsi
) * bytesPerSector
);
653 // Wait now that the SD card is busy
654 // Chances are we've probably already waited sufficient time,
655 // but it's hard to measure microseconds cheaply. So just wait
656 // extra just-in-case. Hopefully it's in parallel with dma.
657 if (phaseChangeDelayUs
> 0)
659 s2s_delay_us(phaseChangeDelayUs
);
660 phaseChangeDelayUs
= 0;
664 if (((prep
- i
) > 0) &&
667 int dmaBytes
= SD_SECTOR_SIZE
;
668 if ((i
% sdPerScsi
) == (sdPerScsi
- 1))
670 dmaBytes
= bytesPerSector
% SD_SECTOR_SIZE
;
671 if (dmaBytes
== 0) dmaBytes
= SD_SECTOR_SIZE
;
674 uint8_t* scsiDmaData
= &(scsiDev
.data
[SD_SECTOR_SIZE
* (i
% buffers
)]);
675 scsiWritePIO(scsiDmaData
, dmaBytes
);
681 if (phaseChangeDelayUs
> 0 && !scsiDev
.resetFlag
) // zero bytes ?
683 s2s_delay_us(phaseChangeDelayUs
);
684 phaseChangeDelayUs
= 0;
687 if (scsiDev
.resetFlag
)
693 // Wait for the SD transfer to complete before we disable IRQs.
694 // (Otherwise some cards will cause an error if we don't sent the
695 // stop transfer command via the DMA complete handler in time)
696 while (HAL_SD_GetState(&hsd
) == HAL_SD_STATE_BUSY
)
698 // Wait while keeping BSY.
702 HAL_SD_CardStateTypeDef cardState
= HAL_SD_GetCardState(&hsd
);
703 while (cardState
== HAL_SD_CARD_PROGRAMMING
|| cardState
== HAL_SD_CARD_SENDING
)
705 cardState
= HAL_SD_GetCardState(&hsd
);
708 // We've finished transferring the data to the FPGA, now wait until it's
709 // written to he SCSI bus.
710 while (!scsiPhyComplete() &&
711 likely(scsiDev
.phase
== DATA_IN
) &&
712 likely(!scsiDev
.resetFlag
))
715 if (!scsiPhyComplete() && likely(!scsiDev
.resetFlag
))
722 if (scsiDev
.phase
== DATA_IN
)
724 scsiDev
.phase
= STATUS
;
728 else if (scsiDev
.phase
== DATA_OUT
&&
729 transfer
.currentBlock
!= transfer
.blocks
)
731 scsiEnterPhase(DATA_OUT
);
733 const int sdPerScsi
= SDSectorsPerSCSISector(bytesPerSector
);
734 int totalSDSectors
= transfer
.blocks
* sdPerScsi
;
737 scsiDev
.target
->cfg
->sdSectorStart
,
742 int disconnected
= 0;
745 int enableParity
= scsiDev
.boardCfg
.flags
& S2S_CFG_ENABLE_PARITY
;
747 uint32_t maxSectors
= sizeof(scsiDev
.data
) / SD_SECTOR_SIZE
;
749 static_assert(SCSI_XFER_MAX
>= sizeof(scsiDev
.data
), "Assumes SCSI_XFER_MAX >= sizeof(scsiDev.data)");
751 // Start reading and filling fifos as soon as possible.
752 // It's highly unlikely that someone is going to use huge transfers
753 // per scsi command, but if they do it'll be slower than usual.
754 // Note: Happens in Macintosh FWB HDD Toolkit benchmarks which default
756 uint32_t totalTransferBytes
= transfer
.blocks
* bytesPerSector
;
757 int useSlowDataCount
= totalTransferBytes
>= SCSI_XFER_MAX
;
758 if (!useSlowDataCount
)
760 DWT
->CYCCNT
= 0; // Start counting cycles
761 scsiSetDataCount(totalTransferBytes
);
764 int lastWriteSize
= 0;
766 while ((i
< totalSDSectors
) &&
767 likely(scsiDev
.phase
== DATA_OUT
) &&
768 likely(!scsiDev
.resetFlag
))
769 // KEEP GOING to ensure FIFOs are in a good state.
770 // likely(!parityError || !enableParity))
772 if (bytesPerSector
== SD_SECTOR_SIZE
)
774 uint32_t maxXferSectors
= SCSI_XFER_MAX
/ SD_SECTOR_SIZE
;
775 uint32_t rem
= totalSDSectors
- i
;
776 uint32_t sectors
= rem
< maxXferSectors
? rem
: maxXferSectors
;
778 uint32_t totalBytes
= sectors
* SD_SECTOR_SIZE
;
780 if (useSlowDataCount
)
782 scsiSetDataCount(totalBytes
);
785 lastWriteSize
= sectors
;
786 HAL_SD_WriteBlocks_DMA(&hsd
, i
+ sdLBA
, sectors
);
790 uint32_t dmaFinishTime
= 0;
791 while (j
< sectors
&& !scsiDev
.resetFlag
)
794 HAL_SD_GetState(&hsd
) != HAL_SD_STATE_BUSY
&&
800 if (!sdActive
&& ((prep
- j
) > 0))
802 // Start an SD transfer if we have space.
803 HAL_SD_WriteBlocks_Data(&hsd
, &scsiDev
.data
[SD_SECTOR_SIZE
* (j
% maxSectors
)]);
808 if (((prep
- j
) < maxSectors
) &&
813 &scsiDev
.data
[(prep
% maxSectors
) * SD_SECTOR_SIZE
],
819 dmaFinishTime
= s2s_getTime_ms();
823 if (i
+ prep
>= totalSDSectors
&&
825 (!parityError
|| !enableParity
) &&
826 s2s_elapsedTime_ms(dmaFinishTime
) >= 180)
828 // We're transferring over the SCSI bus faster than the SD card
829 // can write. All data is buffered, and we're just waiting for
830 // the SD card to complete. The host won't let us disconnect.
831 // Some drivers set a 250ms timeout on transfers to complete.
832 // SD card writes are supposed to complete
833 // within 200ms, but sometimes they don't.
834 // Just pretend we're finished.
836 clearBSY
= process_MessageIn(0); // Will go to BUS_FREE state but keep BSY asserted.
841 if (scsiDev
.resetFlag
)
847 while (HAL_SD_GetState(&hsd
) == HAL_SD_STATE_BUSY
) {} // Waits for DMA to complete
848 if (lastWriteSize
> 1)
850 SDMMC_CmdStopTransfer(hsd
.Instance
);
855 s2s_elapsedTime_ms(dmaFinishTime
) < 180)
857 // Wait while the SD card is writing buffer to flash
858 // The card may remain in the RECEIVING state (even though it's programming) if
859 // it has buffer space to receive more data available.
863 i
+ sectors
>= totalSDSectors
&&
864 (!parityError
|| !enableParity
))
866 // We're transferring over the SCSI bus faster than the SD card
867 // can write. All data is buffered, and we're just waiting for
868 // the SD card to complete. The host won't let us disconnect.
869 // Some drivers set a 250ms timeout on transfers to complete.
870 // SD card writes are supposed to complete
871 // within 200ms, but sometimes they don't.
872 // Just pretend we're finished.
874 clearBSY
= process_MessageIn(0); // Will go to BUS_FREE state but keep BSY asserted.
877 // Wait while the SD card is writing buffer to flash
878 // The card may remain in the RECEIVING state (even though it's programming) if
879 // it has buffer space to receive more data available.
880 while (sdIsBusy()) {}
881 HAL_SD_CardStateTypeDef cardState
= HAL_SD_GetCardState(&hsd
);
882 while (cardState
== HAL_SD_CARD_PROGRAMMING
|| cardState
== HAL_SD_CARD_RECEIVING
)
884 // Wait while the SD card is writing buffer to flash
885 // The card may remain in the RECEIVING state (even though it's programming) if
886 // it has buffer space to receive more data available.
887 cardState
= HAL_SD_GetCardState(&hsd
);
894 // Well, until we have some proper non-blocking SD code, we must
895 // do this in a half-duplex fashion. We need to write as much as
896 // possible in each SD card transaction.
897 // use sg_dd from sg_utils3 tools to test.
899 uint32_t rem
= totalSDSectors
- i
;
901 if (rem
<= maxSectors
)
907 sectors
= maxSectors
;
908 while (sectors
% sdPerScsi
) sectors
--;
912 if (useSlowDataCount
)
914 scsiSetDataCount((sectors
/ sdPerScsi
) * bytesPerSector
);
917 for (int scsiSector
= i
; scsiSector
< i
+ sectors
; ++scsiSector
)
919 int dmaBytes
= SD_SECTOR_SIZE
;
920 if ((scsiSector
% sdPerScsi
) == (sdPerScsi
- 1))
922 dmaBytes
= bytesPerSector
% SD_SECTOR_SIZE
;
923 if (dmaBytes
== 0) dmaBytes
= SD_SECTOR_SIZE
;
926 scsiReadPIO(&scsiDev
.data
[SD_SECTOR_SIZE
* (scsiSector
- i
)], dmaBytes
, &parityError
);
928 if (!parityError
|| !enableParity
)
930 BSP_SD_WriteBlocks_DMA(&scsiDev
.data
[0], i
+ sdLBA
, sectors
);
936 // Should already be complete here as we've ready the FIFOs
937 // by now. Check anyway.
939 while (!scsiPhyComplete() && likely(!scsiDev
.resetFlag
))
950 if (scsiDev
.phase
== DATA_OUT
)
953 (scsiDev
.boardCfg
.flags
& S2S_CFG_ENABLE_PARITY
))
955 scsiDev
.target
->sense
.code
= ABORTED_COMMAND
;
956 scsiDev
.target
->sense
.asc
= SCSI_PARITY_ERROR
;
957 scsiDev
.status
= CHECK_CONDITION
;;
959 scsiDev
.phase
= STATUS
;
968 scsiDev
.savedDataPtr
= 0;
970 // transfer.lba = 0; // Needed in Request Sense to determine failure
972 transfer
.currentBlock
= 0;
974 // Cancel long running commands!
977 ((scsiDev
.boardCfg
.flags
& S2S_CFG_ENABLE_CACHE
) == 0) ||
978 (transfer
.multiBlock
== 0)
982 sdCompleteTransfer();
985 transfer
.multiBlock
= 0;
992 // Don't require the host to send us a START STOP UNIT command
993 blockDev
.state
= DISK_STARTED
;