be912166682115d36b51d6e670bb27cca326cc5a
[SCSI2SD-V6.git] / src / firmware / disk.c
1 // Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
2 // Copyright (C) 2014 Doug Brown <doug@downtowndougbrown.com>
3 //
4 // This file is part of SCSI2SD.
5 //
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.
10 //
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.
15 //
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/>.
18
19 #include "stm32f2xx.h"
20
21 #include "scsi.h"
22 #include "scsiPhy.h"
23 #include "config.h"
24 #include "disk.h"
25 #include "sd.h"
26 #include "time.h"
27
28 #include <string.h>
29
30 // Global
31 BlockDevice blockDev;
32 Transfer transfer;
33
34 static int doSdInit()
35 {
36 int result = 0;
37 if (blockDev.state & DISK_PRESENT)
38 {
39 blockDev.state = blockDev.state | DISK_INITIALISED;
40 }
41 return result;
42 }
43
44 // Callback once all data has been read in the data out phase.
45 static void doFormatUnitComplete(void)
46 {
47 // TODO start writing the initialisation pattern to the SD
48 // card
49 scsiDev.phase = STATUS;
50 }
51
52 static void doFormatUnitSkipData(int bytes)
53 {
54 // We may not have enough memory to store the initialisation pattern and
55 // defect list data. Since we're not making use of it yet anyway, just
56 // discard the bytes.
57 scsiEnterPhase(DATA_OUT);
58 int i;
59 for (i = 0; i < bytes; ++i)
60 {
61 scsiReadByte();
62 }
63 }
64
65 // Callback from the data out phase.
66 static void doFormatUnitPatternHeader(void)
67 {
68 int defectLength =
69 ((((uint16_t)scsiDev.data[2])) << 8) +
70 scsiDev.data[3];
71
72 int patternLength =
73 ((((uint16_t)scsiDev.data[4 + 2])) << 8) +
74 scsiDev.data[4 + 3];
75
76 doFormatUnitSkipData(defectLength + patternLength);
77 doFormatUnitComplete();
78 }
79
80 // Callback from the data out phase.
81 static void doFormatUnitHeader(void)
82 {
83 int IP = (scsiDev.data[1] & 0x08) ? 1 : 0;
84 int DSP = (scsiDev.data[1] & 0x04) ? 1 : 0;
85
86 if (! DSP) // disable save parameters
87 {
88 // Save the "MODE SELECT savable parameters"
89 s2s_configSave(
90 scsiDev.target->targetId,
91 scsiDev.target->liveCfg.bytesPerSector);
92 }
93
94 if (IP)
95 {
96 // We need to read the initialisation pattern header first.
97 scsiDev.dataLen += 4;
98 scsiDev.phase = DATA_OUT;
99 scsiDev.postDataOutHook = doFormatUnitPatternHeader;
100 }
101 else
102 {
103 // Read the defect list data
104 int defectLength =
105 ((((uint16_t)scsiDev.data[2])) << 8) +
106 scsiDev.data[3];
107 doFormatUnitSkipData(defectLength);
108 doFormatUnitComplete();
109 }
110 }
111
112 static void doReadCapacity()
113 {
114 uint32_t lba = (((uint32_t) scsiDev.cdb[2]) << 24) +
115 (((uint32_t) scsiDev.cdb[3]) << 16) +
116 (((uint32_t) scsiDev.cdb[4]) << 8) +
117 scsiDev.cdb[5];
118 int pmi = scsiDev.cdb[8] & 1;
119
120 uint32_t capacity = getScsiCapacity(
121 scsiDev.target->cfg->sdSectorStart,
122 scsiDev.target->liveCfg.bytesPerSector,
123 scsiDev.target->cfg->scsiSectors);
124
125 if (!pmi && lba)
126 {
127 // error.
128 // We don't do anything with the "partial medium indicator", and
129 // assume that delays are constant across each block. But the spec
130 // says we must return this error if pmi is specified incorrectly.
131 scsiDev.status = CHECK_CONDITION;
132 scsiDev.target->sense.code = ILLEGAL_REQUEST;
133 scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
134 scsiDev.phase = STATUS;
135 }
136 else if (capacity > 0)
137 {
138 uint32_t highestBlock = capacity - 1;
139
140 scsiDev.data[0] = highestBlock >> 24;
141 scsiDev.data[1] = highestBlock >> 16;
142 scsiDev.data[2] = highestBlock >> 8;
143 scsiDev.data[3] = highestBlock;
144
145 uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
146 scsiDev.data[4] = bytesPerSector >> 24;
147 scsiDev.data[5] = bytesPerSector >> 16;
148 scsiDev.data[6] = bytesPerSector >> 8;
149 scsiDev.data[7] = bytesPerSector;
150 scsiDev.dataLen = 8;
151 scsiDev.phase = DATA_IN;
152 }
153 else
154 {
155 scsiDev.status = CHECK_CONDITION;
156 scsiDev.target->sense.code = NOT_READY;
157 scsiDev.target->sense.asc = MEDIUM_NOT_PRESENT;
158 scsiDev.phase = STATUS;
159 }
160 }
161
162 static void doWrite(uint32_t lba, uint32_t blocks)
163 {
164 if (unlikely(scsiDev.target->cfg->deviceType == S2S_CFG_FLOPPY_14MB)) {
165 // Floppies are supposed to be slow. Some systems can't handle a floppy
166 // without an access time
167 s2s_delay_ms(10);
168 }
169
170 uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
171
172 if (unlikely(blockDev.state & DISK_WP) ||
173 unlikely(scsiDev.target->cfg->deviceType == S2S_CFG_OPTICAL))
174
175 {
176 scsiDev.status = CHECK_CONDITION;
177 scsiDev.target->sense.code = ILLEGAL_REQUEST;
178 scsiDev.target->sense.asc = WRITE_PROTECTED;
179 scsiDev.phase = STATUS;
180 }
181 else if (unlikely(((uint64_t) lba) + blocks >
182 getScsiCapacity(
183 scsiDev.target->cfg->sdSectorStart,
184 bytesPerSector,
185 scsiDev.target->cfg->scsiSectors
186 )
187 ))
188 {
189 scsiDev.status = CHECK_CONDITION;
190 scsiDev.target->sense.code = ILLEGAL_REQUEST;
191 scsiDev.target->sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
192 scsiDev.phase = STATUS;
193 }
194 else
195 {
196 transfer.lba = lba;
197 transfer.blocks = blocks;
198 transfer.currentBlock = 0;
199 scsiDev.phase = DATA_OUT;
200 scsiDev.dataLen = bytesPerSector;
201 scsiDev.dataPtr = bytesPerSector;
202
203 // No need for single-block writes atm. Overhead of the
204 // multi-block write is minimal.
205 transfer.multiBlock = 1;
206
207
208 // TODO uint32_t sdLBA =
209 // TODO SCSISector2SD(
210 // TODO scsiDev.target->cfg->sdSectorStart,
211 // TODO bytesPerSector,
212 // TODO lba);
213 // TODO uint32_t sdBlocks = blocks * SDSectorsPerSCSISector(bytesPerSector);
214 // TODO sdWriteMultiSectorPrep(sdLBA, sdBlocks);
215 }
216 }
217
218
219 static void doRead(uint32_t lba, uint32_t blocks)
220 {
221 if (unlikely(scsiDev.target->cfg->deviceType == S2S_CFG_FLOPPY_14MB)) {
222 // Floppies are supposed to be slow. Some systems can't handle a floppy
223 // without an access time
224 s2s_delay_ms(10);
225 }
226
227 uint32_t capacity = getScsiCapacity(
228 scsiDev.target->cfg->sdSectorStart,
229 scsiDev.target->liveCfg.bytesPerSector,
230 scsiDev.target->cfg->scsiSectors);
231 if (unlikely(((uint64_t) lba) + blocks > capacity))
232 {
233 scsiDev.status = CHECK_CONDITION;
234 scsiDev.target->sense.code = ILLEGAL_REQUEST;
235 scsiDev.target->sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
236 scsiDev.phase = STATUS;
237 }
238 else
239 {
240 transfer.lba = lba;
241 transfer.blocks = blocks;
242 transfer.currentBlock = 0;
243 scsiDev.phase = DATA_IN;
244 scsiDev.dataLen = 0; // No data yet
245
246 uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
247 uint32_t sdSectorPerSCSISector = SDSectorsPerSCSISector(bytesPerSector);
248 uint32_t sdSectors =
249 blocks * sdSectorPerSCSISector;
250
251 if ((
252 (sdSectors == 1) &&
253 !(scsiDev.boardCfg.flags & S2S_CFG_ENABLE_CACHE)
254 ) ||
255 unlikely(((uint64_t) lba) + blocks == capacity)
256 )
257 {
258 // We get errors on reading the last sector using a multi-sector
259 // read :-(
260 transfer.multiBlock = 0;
261 }
262 else
263 {
264 transfer.multiBlock = 1;
265
266 // uint32_t sdLBA =
267 // SCSISector2SD(
268 // scsiDev.target->cfg->sdSectorStart,
269 // bytesPerSector,
270 // lba);
271
272 // TODO sdReadMultiSectorPrep(sdLBA, sdSectors);
273 }
274 }
275 }
276
277 static void doSeek(uint32_t lba)
278 {
279 if (lba >=
280 getScsiCapacity(
281 scsiDev.target->cfg->sdSectorStart,
282 scsiDev.target->liveCfg.bytesPerSector,
283 scsiDev.target->cfg->scsiSectors)
284 )
285 {
286 scsiDev.status = CHECK_CONDITION;
287 scsiDev.target->sense.code = ILLEGAL_REQUEST;
288 scsiDev.target->sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
289 scsiDev.phase = STATUS;
290 }
291 }
292
293 static int doTestUnitReady()
294 {
295 int ready = 1;
296 if (likely(blockDev.state == (DISK_STARTED | DISK_PRESENT | DISK_INITIALISED)))
297 {
298 // nothing to do.
299 }
300 else if (unlikely(!(blockDev.state & DISK_STARTED)))
301 {
302 ready = 0;
303 scsiDev.status = CHECK_CONDITION;
304 scsiDev.target->sense.code = NOT_READY;
305 scsiDev.target->sense.asc = LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED;
306 scsiDev.phase = STATUS;
307 }
308 else if (unlikely(!(blockDev.state & DISK_PRESENT)))
309 {
310 ready = 0;
311 scsiDev.status = CHECK_CONDITION;
312 scsiDev.target->sense.code = NOT_READY;
313 scsiDev.target->sense.asc = MEDIUM_NOT_PRESENT;
314 scsiDev.phase = STATUS;
315 }
316 else if (unlikely(!(blockDev.state & DISK_INITIALISED)))
317 {
318 ready = 0;
319 scsiDev.status = CHECK_CONDITION;
320 scsiDev.target->sense.code = NOT_READY;
321 scsiDev.target->sense.asc = LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE;
322 scsiDev.phase = STATUS;
323 }
324 return ready;
325 }
326
327 // Handle direct-access scsi device commands
328 int scsiDiskCommand()
329 {
330 int commandHandled = 1;
331
332 uint8_t command = scsiDev.cdb[0];
333 if (unlikely(command == 0x1B))
334 {
335 // START STOP UNIT
336 // Enable or disable media access operations.
337 // Ignore load/eject requests. We can't do that.
338 //int immed = scsiDev.cdb[1] & 1;
339 int start = scsiDev.cdb[4] & 1;
340
341 if (start)
342 {
343 blockDev.state = blockDev.state | DISK_STARTED;
344 if (!(blockDev.state & DISK_INITIALISED))
345 {
346 doSdInit();
347 }
348 }
349 else
350 {
351 blockDev.state &= ~DISK_STARTED;
352 }
353 }
354 else if (unlikely(command == 0x00))
355 {
356 // TEST UNIT READY
357 doTestUnitReady();
358 }
359 else if (unlikely(!doTestUnitReady()))
360 {
361 // Status and sense codes already set by doTestUnitReady
362 }
363 else if (likely(command == 0x08))
364 {
365 // READ(6)
366 uint32_t lba =
367 (((uint32_t) scsiDev.cdb[1] & 0x1F) << 16) +
368 (((uint32_t) scsiDev.cdb[2]) << 8) +
369 scsiDev.cdb[3];
370 uint32_t blocks = scsiDev.cdb[4];
371 if (unlikely(blocks == 0)) blocks = 256;
372 doRead(lba, blocks);
373 }
374 else if (likely(command == 0x28))
375 {
376 // READ(10)
377 // Ignore all cache control bits - we don't support a memory cache.
378
379 uint32_t lba =
380 (((uint32_t) scsiDev.cdb[2]) << 24) +
381 (((uint32_t) scsiDev.cdb[3]) << 16) +
382 (((uint32_t) scsiDev.cdb[4]) << 8) +
383 scsiDev.cdb[5];
384 uint32_t blocks =
385 (((uint32_t) scsiDev.cdb[7]) << 8) +
386 scsiDev.cdb[8];
387
388 doRead(lba, blocks);
389 }
390 else if (likely(command == 0x0A))
391 {
392 // WRITE(6)
393 uint32_t lba =
394 (((uint32_t) scsiDev.cdb[1] & 0x1F) << 16) +
395 (((uint32_t) scsiDev.cdb[2]) << 8) +
396 scsiDev.cdb[3];
397 uint32_t blocks = scsiDev.cdb[4];
398 if (unlikely(blocks == 0)) blocks = 256;
399 doWrite(lba, blocks);
400 }
401 else if (likely(command == 0x2A) || // WRITE(10)
402 unlikely(command == 0x2E)) // WRITE AND VERIFY
403 {
404 // Ignore all cache control bits - we don't support a memory cache.
405 // Don't bother verifying either. The SD card likely stores ECC
406 // along with each flash row.
407
408 uint32_t lba =
409 (((uint32_t) scsiDev.cdb[2]) << 24) +
410 (((uint32_t) scsiDev.cdb[3]) << 16) +
411 (((uint32_t) scsiDev.cdb[4]) << 8) +
412 scsiDev.cdb[5];
413 uint32_t blocks =
414 (((uint32_t) scsiDev.cdb[7]) << 8) +
415 scsiDev.cdb[8];
416
417 doWrite(lba, blocks);
418 }
419 else if (unlikely(command == 0x04))
420 {
421 // FORMAT UNIT
422 // We don't really do any formatting, but we need to read the correct
423 // number of bytes in the DATA_OUT phase to make the SCSI host happy.
424
425 int fmtData = (scsiDev.cdb[1] & 0x10) ? 1 : 0;
426 if (fmtData)
427 {
428 // We need to read the parameter list, but we don't know how
429 // big it is yet. Start with the header.
430 scsiDev.dataLen = 4;
431 scsiDev.phase = DATA_OUT;
432 scsiDev.postDataOutHook = doFormatUnitHeader;
433 }
434 else
435 {
436 // No data to read, we're already finished!
437 }
438 }
439 else if (unlikely(command == 0x25))
440 {
441 // READ CAPACITY
442 doReadCapacity();
443 }
444 else if (unlikely(command == 0x0B))
445 {
446 // SEEK(6)
447 uint32_t lba =
448 (((uint32_t) scsiDev.cdb[1] & 0x1F) << 16) +
449 (((uint32_t) scsiDev.cdb[2]) << 8) +
450 scsiDev.cdb[3];
451
452 doSeek(lba);
453 }
454
455 else if (unlikely(command == 0x2B))
456 {
457 // SEEK(10)
458 uint32_t lba =
459 (((uint32_t) scsiDev.cdb[2]) << 24) +
460 (((uint32_t) scsiDev.cdb[3]) << 16) +
461 (((uint32_t) scsiDev.cdb[4]) << 8) +
462 scsiDev.cdb[5];
463
464 doSeek(lba);
465 }
466 else if (unlikely(command == 0x36))
467 {
468 // LOCK UNLOCK CACHE
469 // We don't have a cache to lock data into. do nothing.
470 }
471 else if (unlikely(command == 0x34))
472 {
473 // PRE-FETCH.
474 // We don't have a cache to pre-fetch into. do nothing.
475 }
476 else if (unlikely(command == 0x1E))
477 {
478 // PREVENT ALLOW MEDIUM REMOVAL
479 // Not much we can do to prevent the user removing the SD card.
480 // do nothing.
481 }
482 else if (unlikely(command == 0x01))
483 {
484 // REZERO UNIT
485 // Set the lun to a vendor-specific state. Ignore.
486 }
487 else if (unlikely(command == 0x35))
488 {
489 // SYNCHRONIZE CACHE
490 // We don't have a cache. do nothing.
491 }
492 else if (unlikely(command == 0x2F))
493 {
494 // VERIFY
495 // TODO: When they supply data to verify, we should read the data and
496 // verify it. If they don't supply any data, just say success.
497 if ((scsiDev.cdb[1] & 0x02) == 0)
498 {
499 // They are asking us to do a medium verification with no data
500 // comparison. Assume success, do nothing.
501 }
502 else
503 {
504 // TODO. This means they are supplying data to verify against.
505 // Technically we should probably grab the data and compare it.
506 scsiDev.status = CHECK_CONDITION;
507 scsiDev.target->sense.code = ILLEGAL_REQUEST;
508 scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
509 scsiDev.phase = STATUS;
510 }
511 }
512 else if (unlikely(command == 0x37))
513 {
514 // READ DEFECT DATA
515 scsiDev.status = CHECK_CONDITION;
516 scsiDev.target->sense.code = NO_SENSE;
517 scsiDev.target->sense.asc = DEFECT_LIST_NOT_FOUND;
518 scsiDev.phase = STATUS;
519
520 }
521 else
522 {
523 commandHandled = 0;
524 }
525
526 return commandHandled;
527 }
528
529 void scsiDiskPoll()
530 {
531 uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
532
533 if (scsiDev.phase == DATA_IN &&
534 transfer.currentBlock != transfer.blocks)
535 {
536 scsiEnterPhase(DATA_IN);
537
538 int totalSDSectors =
539 transfer.blocks * SDSectorsPerSCSISector(bytesPerSector);
540 uint32_t sdLBA =
541 SCSISector2SD(
542 scsiDev.target->cfg->sdSectorStart,
543 bytesPerSector,
544 transfer.lba);
545
546 const int sdPerScsi = SDSectorsPerSCSISector(bytesPerSector);
547 const int buffers = sizeof(scsiDev.data) / SD_SECTOR_SIZE;
548 int prep = 0;
549 int i = 0;
550 int scsiActive __attribute__((unused)) = 0; // unused if DMA disabled
551 int sdActive = 0;
552 while ((i < totalSDSectors) &&
553 likely(scsiDev.phase == DATA_IN) &&
554 likely(!scsiDev.resetFlag))
555 {
556 int completedDmaSectors;
557 if (sdActive && (completedDmaSectors = sdReadDMAPoll(sdActive)))
558 {
559 prep += completedDmaSectors;
560 sdActive -= completedDmaSectors;
561 } else if (sdActive > 1) {
562 if (scsiDev.data[SD_SECTOR_SIZE * (prep % buffers) + 511] != 0x33) {
563 prep += 1;
564 sdActive -= 1;
565 }
566 }
567
568 if (!sdActive &&
569 (prep - i < buffers) &&
570 (prep < totalSDSectors))
571 {
572 // Start an SD transfer if we have space.
573 uint32_t startBuffer = prep % buffers;
574 uint32_t sectors = totalSDSectors - prep;
575
576 uint32_t freeBuffers = buffers - (prep - i);
577
578 uint32_t contiguousBuffers = buffers - startBuffer;
579 freeBuffers = freeBuffers < contiguousBuffers
580 ? freeBuffers : contiguousBuffers;
581 sectors = sectors < freeBuffers ? sectors : freeBuffers;
582
583 if (sectors > 128) sectors = 128; // 65536 DMA limit !!
584
585 for (int dodgy = 0; dodgy < sectors; dodgy++)
586 {
587 scsiDev.data[SD_SECTOR_SIZE * (startBuffer + dodgy) + 511] = 0x33;
588 }
589
590 sdReadDMA(sdLBA + prep, sectors, &scsiDev.data[SD_SECTOR_SIZE * startBuffer]);
591
592 sdActive = sectors;
593 }
594
595 #ifdef SCSI_FSMC_DMA
596 if (scsiActive && scsiPhyComplete() && scsiWriteDMAPoll())
597 {
598 scsiActive = 0;
599 i++;
600 scsiPhyFifoFlip();
601 }
602 if (!scsiActive && ((prep - i) > 0))
603 {
604 int dmaBytes = SD_SECTOR_SIZE;
605 if ((i % sdPerScsi) == (sdPerScsi - 1))
606 {
607 dmaBytes = bytesPerSector % SD_SECTOR_SIZE;
608 if (dmaBytes == 0) dmaBytes = SD_SECTOR_SIZE;
609 }
610 scsiWriteDMA(&scsiDev.data[SD_SECTOR_SIZE * (i % buffers)], dmaBytes);
611 scsiActive = 1;
612 }
613 #else
614 if ((prep - i) > 0)
615 {
616 int dmaBytes = SD_SECTOR_SIZE;
617 if ((i % sdPerScsi) == (sdPerScsi - 1))
618 {
619 dmaBytes = bytesPerSector % SD_SECTOR_SIZE;
620 if (dmaBytes == 0) dmaBytes = SD_SECTOR_SIZE;
621 }
622 for (int k = 0; k < dmaBytes; ++k)
623 {
624 scsiPhyTx(scsiDev.data[SD_SECTOR_SIZE * (i % buffers) + k]);
625 }
626 i++;
627 while (!scsiPhyComplete() && !scsiDev.resetFlag) {}
628 scsiPhyFifoFlip();
629 }
630 #endif
631 }
632
633 // We've finished transferring the data to the FPGA, now wait until it's
634 // written to he SCSI bus.
635 while (!scsiPhyComplete() &&
636 likely(scsiDev.phase == DATA_IN) &&
637 likely(!scsiDev.resetFlag))
638 {
639 }
640
641
642 if (scsiDev.phase == DATA_IN)
643 {
644 scsiDev.phase = STATUS;
645 }
646 scsiDiskReset();
647 }
648 else if (scsiDev.phase == DATA_OUT &&
649 transfer.currentBlock != transfer.blocks)
650 {
651 scsiEnterPhase(DATA_OUT);
652
653 const int sdPerScsi = SDSectorsPerSCSISector(bytesPerSector);
654 int totalSDSectors = transfer.blocks * sdPerScsi;
655 uint32_t sdLBA =
656 SCSISector2SD(
657 scsiDev.target->cfg->sdSectorStart,
658 bytesPerSector,
659 transfer.lba);
660 // int buffers = sizeof(scsiDev.data) / SD_SECTOR_SIZE;
661 // int prep = 0;
662 int i = 0;
663 // int scsiDisconnected = 0;
664 int scsiComplete = 0;
665 // uint32_t lastActivityTime = s2s_getTime_ms();
666 // int scsiActive = 0;
667 // int sdActive = 0;
668
669 while ((i < totalSDSectors) &&
670 (likely(scsiDev.phase == DATA_OUT) || // scsiDisconnect keeps our phase.
671 scsiComplete) &&
672 likely(!scsiDev.resetFlag))
673 {
674 // Well, until we have some proper non-blocking SD code, we must
675 // do this in a half-duplex fashion. We need to write as much as
676 // possible in each SD card transaction.
677 uint32_t maxSectors = sizeof(scsiDev.data) / SD_SECTOR_SIZE;
678 uint32_t rem = totalSDSectors - i;
679 uint32_t sectors =
680 rem < maxSectors ? rem : maxSectors;
681 scsiRead(&scsiDev.data[0], sectors * SD_SECTOR_SIZE);
682 sdTmpWrite(&scsiDev.data[0], i + sdLBA, sectors);
683 i += sectors;
684 #if 0
685 // Wait for the next DMA interrupt. It's beneficial to halt the
686 // processor to give the DMA controller more memory bandwidth to
687 // work with.
688 int scsiBusy = 1;
689 int sdBusy = 1;
690 while (scsiBusy && sdBusy)
691 {
692 uint8_t intr = CyEnterCriticalSection();
693 scsiBusy = scsiDMABusy();
694 sdBusy = sdDMABusy();
695 if (scsiBusy && sdBusy)
696 {
697 __WFI();
698 }
699 CyExitCriticalSection(intr);
700 }
701
702 if (sdActive && !sdBusy && sdWriteSectorDMAPoll())
703 {
704 sdActive = 0;
705 i++;
706 }
707 if (!sdActive && ((prep - i) > 0))
708 {
709 // Start an SD transfer if we have space.
710 sdWriteMultiSectorDMA(&scsiDev.data[SD_SECTOR_SIZE * (i % buffers)]);
711 sdActive = 1;
712 }
713
714 uint32_t now = getTime_ms();
715
716 if (scsiActive && !scsiBusy && scsiReadDMAPoll())
717 {
718 scsiActive = 0;
719 ++prep;
720 lastActivityTime = now;
721 }
722 if (!scsiActive &&
723 ((prep - i) < buffers) &&
724 (prep < totalSDSectors) &&
725 likely(!scsiDisconnected))
726 {
727 int dmaBytes = SD_SECTOR_SIZE;
728 if ((prep % sdPerScsi) == (sdPerScsi - 1))
729 {
730 dmaBytes = bytesPerSector % SD_SECTOR_SIZE;
731 if (dmaBytes == 0) dmaBytes = SD_SECTOR_SIZE;
732 }
733 scsiReadDMA(&scsiDev.data[SD_SECTOR_SIZE * (prep % buffers)], dmaBytes);
734 scsiActive = 1;
735 }
736 else if (
737 (scsiDev.boardCfg.flags & CONFIG_ENABLE_DISCONNECT) &&
738 (scsiActive == 0) &&
739 likely(!scsiDisconnected) &&
740 unlikely(scsiDev.discPriv) &&
741 unlikely(diffTime_ms(lastActivityTime, now) >= 20) &&
742 likely(scsiDev.phase == DATA_OUT))
743 {
744 // We're transferring over the SCSI bus faster than the SD card
745 // can write. There is no more buffer space once we've finished
746 // this SCSI transfer.
747 // The NCR 53C700 interface chips have a 250ms "byte-to-byte"
748 // timeout buffer. SD card writes are supposed to complete
749 // within 200ms, but sometimes they don't.
750 // The NCR 53C700 series is used on HP 9000 workstations.
751 scsiDisconnect();
752 scsiDisconnected = 1;
753 lastActivityTime = getTime_ms();
754 }
755 else if (unlikely(scsiDisconnected) &&
756 (
757 (prep == i) || // Buffers empty.
758 // Send some messages every 100ms so we don't timeout.
759 // At a minimum, a reselection involves an IDENTIFY message.
760 unlikely(diffTime_ms(lastActivityTime, now) >= 100)
761 ))
762 {
763 int reconnected = scsiReconnect();
764 if (reconnected)
765 {
766 scsiDisconnected = 0;
767 lastActivityTime = getTime_ms(); // Don't disconnect immediately.
768 }
769 else if (diffTime_ms(lastActivityTime, getTime_ms()) >= 10000)
770 {
771 // Give up after 10 seconds of trying to reconnect.
772 scsiDev.resetFlag = 1;
773 }
774 }
775 else if (
776 likely(!scsiComplete) &&
777 (sdActive == 1) &&
778 (prep == totalSDSectors) && // All scsi data read and buffered
779 likely(!scsiDev.discPriv) && // Prefer disconnect where possible.
780 unlikely(diffTime_ms(lastActivityTime, now) >= 150) &&
781
782 likely(scsiDev.phase == DATA_OUT) &&
783 !(scsiDev.cdb[scsiDev.cdbLen - 1] & 0x01) // Not linked command
784 )
785 {
786 // We're transferring over the SCSI bus faster than the SD card
787 // can write. All data is buffered, and we're just waiting for
788 // the SD card to complete. The host won't let us disconnect.
789 // Some drivers set a 250ms timeout on transfers to complete.
790 // SD card writes are supposed to complete
791 // within 200ms, but sometimes they don'to.
792 // Just pretend we're finished.
793 scsiComplete = 1;
794
795 process_Status();
796 process_MessageIn(); // Will go to BUS_FREE state
797
798 // Try and prevent anyone else using the SCSI bus while we're not ready.
799 SCSI_SetPin(SCSI_Out_BSY);
800 }
801 #endif
802 }
803
804 #if 0
805 if (scsiComplete)
806 {
807 SCSI_ClearPin(SCSI_Out_BSY);
808 }
809 while (
810 !scsiDev.resetFlag &&
811 unlikely(scsiDisconnected) &&
812 (s2s_elapsedTime_ms(lastActivityTime) <= 10000))
813 {
814 scsiDisconnected = !scsiReconnect();
815 }
816 if (scsiDisconnected)
817 {
818 // Failed to reconnect
819 scsiDev.resetFlag = 1;
820 }
821 #endif
822
823 if (scsiDev.phase == DATA_OUT)
824 {
825 if (scsiDev.parityError &&
826 (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) &&
827 (scsiDev.compatMode >= COMPAT_SCSI2))
828 {
829 scsiDev.target->sense.code = ABORTED_COMMAND;
830 scsiDev.target->sense.asc = SCSI_PARITY_ERROR;
831 scsiDev.status = CHECK_CONDITION;;
832 }
833 scsiDev.phase = STATUS;
834 }
835 scsiDiskReset();
836 }
837 }
838
839 void scsiDiskReset()
840 {
841 scsiDev.dataPtr = 0;
842 scsiDev.savedDataPtr = 0;
843 scsiDev.dataLen = 0;
844 // transfer.lba = 0; // Needed in Request Sense to determine failure
845 transfer.blocks = 0;
846 transfer.currentBlock = 0;
847
848 // Cancel long running commands!
849 #if 0
850 if (
851 ((scsiDev.boardCfg.flags & S2S_CFG_ENABLE_CACHE) == 0) ||
852 (transfer.multiBlock == 0)
853 )
854 #endif
855 {
856 sdCompleteTransfer();
857 }
858
859 transfer.multiBlock = 0;
860 }
861
862 void scsiDiskInit()
863 {
864 scsiDiskReset();
865
866 // Don't require the host to send us a START STOP UNIT command
867 blockDev.state = DISK_STARTED;
868 }
869