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 + -
显示快捷键?