scsi.lst
来自「HIGH_SPEED_USB_To_ATA(IDE)Firmware相关代码(E」· LST 代码 · 共 1,388 行 · 第 1/5 页
LST
1,388 行
523 1
524 1 // Send the "ATAPI packet" command
525 1 writePIO8(ATAPI_COMMAND_REG, ATAPI_COMMAND_ATAPI_PACKET);
526 1
527 1 // Wait for the register block to be non-busy and to request data
528 1 do
529 1 driveStatus = readPIO8(ATAPI_STATUS_REG);
530 1 while( driveStatus & ATAPI_STATUS_BUSY_BIT);
531 1
532 1 if(driveStatus & ATAPI_STATUS_ERROR_BIT)
533 1 return(USBS_FAILED);
534 1
535 1 // Write 6 words of command
536 1 {
537 2 BYTE i;
538 2 WORD cmd_data;
539 2
540 2 for(i=0; i<12; i+=2)
541 2 {
542 3 cmd_data = (BYTE) (cmdbuf[i+1]);
C51 COMPILER V7.50 SCSI 11/07/2006 14:52:10 PAGE 10
543 3 cmd_data = (cmd_data << 8) | (BYTE) (cmdbuf[i]);
544 3 writePIO8(ATAPI_DATA_REG, cmd_data);
545 3 }
546 2 }
547 1
548 1 if (useUdma)
549 1 return(USBS_PASSED);
550 1
551 1 {
552 2 // Wait for the register block to be non-busy
553 2 for (driveStatus=ATAPI_STATUS_BUSY_BIT; driveStatus & ATAPI_STATUS_BUSY_BIT; )
554 2 {
555 3 // Read the alt status register so we don't trigger any events
556 3 driveStatus = readPIO8(ATAPI_ALT_STATUS_REG);
557 3 }
558 2 }
559 1
560 1 if (readATAPI_STATUS_REG() & ATAPI_STATUS_ERROR_BIT) // Reading the status reg clears the interrupt
561 1 return(USBS_FAILED);
562 1 else
563 1 return(USBS_PASSED);
564 1 }
565
566
567
568 static void prepareForATAPICommand()
569 {
570 1
571 1
572 1 // Select ATAPI device
573 1 writePIO8(ATAPI_DRIVESEL_REG, 0xa0);
574 1
575 1 // Make sure the device is ready for the packet
576 1 while(readATAPI_STATUS_REG() & ATAPI_STATUS_BUSY_BIT)
577 1 ;
578 1
579 1 // configure the transfer mode (PIO or UDMA) using the feature register
580 1 if (useUdma)
581 1 {
582 2 writePIO8(ATAPI_FEATURE_REG, 0x01);
583 2 }
584 1 else
585 1 {
586 2 // This disables disconnect/reconnect, synchronous, overlapped and DMA features.
587 2 writePIO8(ATAPI_FEATURE_REG, 0x00);
588 2 }
589 1
590 1 // Set "max byte count"
591 1 writePIO8(ATAPI_BYTE_COUNT_LSB, 0xff);
592 1 writePIO8(ATAPI_BYTE_COUNT_MSB, 0xff);
593 1
594 1 }
595
596
597
598 //-----------------------------------------------------------------------------
599 // Function: inDataFromDrive()
600 //
601 // Input: none
602 // Output: bit flag
603 // 0 = success, 1 = failure
604 //
C51 COMPILER V7.50 SCSI 11/07/2006 14:52:10 PAGE 11
605 // Global data:
606 //
607 // Local data:
608 //
609 // Description:
610 // Read from the drive until the drive is empty or the buffer is full.
611 // This breaks up the 16 bit length read into wPacketSize. driveDataLen is
612 // the amount of data available from the drive. If the last read results in
613 // a short packet, but the drive has more data to give, don't release the packet.
614 // until either the drive has finished or the packet is full.
615 //
616 // Phase error note: In the Hi<>Do case, we will send garbage to the host before
617 // reporting the phase error. In the Hi<Di case we return Di and report phase error.
618 //-----------------------------------------------------------------------------
619 static BYTE inDataFromDrive()
620 {
621 1
622 1 BYTE driveStatus;
623 1 WORD wDriveDataLen = 0;
624 1 WORD wReadLen = 0; // Amount of data in the current transaction w/ the drive
625 1 WORD wInSize = 0; // Tracks the amount of data in the current IN packet
626 1 bit bDone = 0;
627 1 bit cReturnStatus = USBS_FAILED;
628 1
629 1 // Clear the interrupt bit
630 1 CLEAR_INTRQ;
631 1
632 1 // See if drive is finished processing command and
633 1 // is ready for data.
634 1 do
635 1 {
636 2 driveStatus = readPIO8(ATAPI_STATUS_REG);
637 2 }
638 1 while( driveStatus & ATAPI_STATUS_BUSY_BIT ); // DO-WHILE!!!
639 1
640 1 // If the drive doesn't have data for us, take off!
641 1 if(!(driveStatus & ATAPI_STATUS_DRQ_BIT) )
642 1 return (USBS_PASSED);
643 1
644 1 while( (!(driveStatus & ATAPI_STATUS_ERROR_BIT)) && (!bDone) && dataTransferLen)
645 1 {
646 2 // Get the amount of data the drive is willing to accept
647 2 if(!wDriveDataLen)
648 2 wDriveDataLen = getDriveDataLen();
649 2
650 2 // Wait for an available buffer.
651 2 waitForInBuffer();
652 2
653 2 while( (wInSize < wPacketSize) && (!bDone) && dataTransferLen)
654 2 {
655 3 // Get data from drive to endpoint.
656 3 wReadLen = min(wPacketSize-wInSize, wDriveDataLen);
657 3 wReadLen = min(dataTransferLen, wReadLen); // added to cover Hi<Di case
658 3 readPIO16(ATAPI_DATA_REG, wReadLen+1); // add 1 in case readLen is odd
659 3
660 3 // Adjust counts.
661 3 wDriveDataLen -= wReadLen;
662 3 dataTransferLen -= wReadLen;
663 3 wInSize += wReadLen;
664 3
665 3 // Wait for the register block to be non-busy
666 3 while(readATAPI_STATUS_REG() & ATAPI_STATUS_BUSY_BIT)
C51 COMPILER V7.50 SCSI 11/07/2006 14:52:10 PAGE 12
667 3 ;
668 3
669 3 // Don't trust the first result after the busy bit goes away. Read it again.
670 3 // The DELL-07 CDRW has occasional problems if this is not done.
671 3 driveStatus = readATAPI_STATUS_REG();
672 3
673 3 // Check if we're done or the drive still has data to transfer.
674 3 if(driveStatus & ATAPI_STATUS_ERROR_BIT)
675 3 {
676 4 bDone = 1;
677 4 cReturnStatus = USBS_FAILED;
678 4 }
679 3
680 3 else if(!(driveStatus & ATAPI_STATUS_DRQ_BIT) )
681 3 {
682 4 bDone=1; // No more data
683 4 cReturnStatus = USBS_PASSED;
684 4 }
685 3
686 3 else
687 3 if(!wDriveDataLen)
688 3 wDriveDataLen = getDriveDataLen();
689 3 }
690 2
691 2 // We either have a full packet or we're at the last packet.
692 2 // Release the buffer to the SIE and re-init packet byte count.
693 2
694 2 EP8BCH = MSB(wInSize);
695 2 EP8BCL = LSB(wInSize);
696 2 if (wInSize < wPacketSize)
697 2 bShortPacketSent = 1;
698 2 wInSize = 0;
699 2 }
700 1
701 1 // If the device still says it has data ready for us, we're either in case
702 1 // 7 (Hi<Di) or 8 (Hi <> Do). Both are phase error cases.
703 1 if ((readATAPI_STATUS_REG() & ATAPI_STATUS_DRQ_BIT) || wDriveDataLen)
704 1 return (USBS_PHASE_ERROR);
705 1
706 1 return(cReturnStatus);
707 1 }
708
709 static bit inDataFromDriveUdma()
710 {
711 1 BYTE driveStatus;
712 1 BYTE error;
713 1
714 1 initUdmaRead();
715 1
716 1 readUDMA((dataTransferLen + 1) >> 1);
717 1
718 1 // If there's anything in the transfer count it's an error
719 1 // This code doesn't handle partial transfers. Any failure kills the entire xfer.
720 1 if (! (GPIFTCMSW || GPIFTCLSW))
721 1 {
722 2 dataTransferLen = 0;
723 2 }
724 1
725 1 // switch the EP back to manual mode
726 1 EP8FIFOCFG = 0x05;
727 1
728 1 driveStatus = readATAPI_STATUS_REG();
C51 COMPILER V7.50 SCSI 11/07/2006 14:52:10 PAGE 13
729 1
730 1 // Check if stall is needed
731 1 if (dataTransferLenLSW & (wPacketSize - 1))
732 1 bShortPacketSent = 1;
733 1
734 1 if (driveStatus & ATAPI_STATUS_ERROR_BIT)
735 1 {
736 2 error = readPIO8(ATAPI_ERROR_REG);
737 2
738 2 // Upper 4 bits of error contain sense key. 4 is the sense key for parity error
739 2 if ((error & 0xf0) == 0x40)
740 2 {
741 3 // Allow up to a 10/1 error ratio. If it gets above that, slow down or stop using UDMA.
742 3 udmaErrorCount += 10;
743 3 if (udmaErrorCount >= 20)
744 3 {
745 4 if (udmaMode == TRANSFER_MODE_UDMA4)
746 4 {
747 5 udmaMode = TRANSFER_MODE_UDMA2;
748 5 configureATATransferMode(udmaMode);
749 5 }
750 4 else
751 4 {
752 5 udmaMode = 0;
753 5 configureATATransferMode(PIO_MODE4);
754 5 }
755 4 udmaErrorCount = 0;
756 4 }
757 3 }
758 2 return(USBS_FAILED);
759 2 }
760 1 else if (driveStatus & ATAPI_STATUS_DRQ_BIT)
761 1 return(USBS_PHASE_ERROR);
762 1 else
763 1 {
764 2 if (udmaErrorCount)
765 2 udmaErrorCount--;
766 2
767 2 return(USBS_PASSED);
768 2 }
769 1 }
770
771
772 // Note: This routine will never STALL the out pipe.
773 // If dataTransferLen remains above 0, it will get stuck rather than stall.
774 static BYTE scsiWriteUdma()
775 {
776 1 BYTE driveStatus;
777 1
778 1 writeUDMA((dataTransferLen+1) >> 1);
779 1
780 1 // If there's anything in the transfer count it's an error
781 1 // This code doesn't handle partial transfers. Any failure kills the entire xfer.
782 1 if (! (GPIFTCMSW || GPIFTCLSW))
783 1 {
784 2 dataTransferLen = 0;
785 2 }
786 1
787 1 // Check status to clear interrupt.
788 1 driveStatus = readATAPI_STATUS_REG();
789 1 if (driveStatus & ATAPI_STATUS_ERROR_BIT)
790 1 return(USBS_FAILED);
C51 COMPILER V7.50 SCSI 11/07/2006 14:52:10 PAGE 14
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?