scsi.lst

来自「HIGH_SPEED_USB_To_ATA(IDE)Firmware相关代码(E」· LST 代码 · 共 1,388 行 · 第 1/5 页

LST
1,388
字号
C51 COMPILER V7.50   SCSI                                                                  11/07/2006 14:52:10 PAGE 1   


C51 COMPILER V7.50, COMPILATION OF MODULE SCSI
OBJECT MODULE PLACED IN scsi.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE scsi.c ROM(COMPACT) OPTIMIZE(9,SPEED) REGFILE(.\fx2_ata.ORC) BROWSE ORDER I
                    -NCDIR(c:\cypress\usb\target\inc) DEFINE(GPIF=0,FLASH=0,DEVICE_TYPE_IS_SCSI=1,DEVICE_TYPE_IS_IDE=1,VBUS_DETECT=1) DEBUG O
                    -BJECTEXTEND CODE

line level    source

   1          //-----------------------------------------------------------------------------
   2          //   File:      scsi.c
   3          //   Contents:   Functions to handle a scsi device.
   4          //
   5          // indent 3.  NO TABS!
   6          //
   7          // Description:
   8          //    SCSI devices differ from IDE device as follows:
   9          //    - SCSI devices may accept or return data according to the value of
  10          //       its byte count registers which may differ from the host request
  11          //       indicated in the CBW variable 'dataTransferlen'. 
  12          //
  13          //       If the host requests to write a greater amount than the byte count 
  14          //       registers indicate, the extra data is processed by throwing it on 
  15          //       the floor and reporting it as a residue.
  16          //
  17          //       If the host requests a read greater than what is indicated in the 
  18          //       byte count registers, and the last packet is a full packet, a short 
  19          //       packet is sent to terminate the transfer.
  20          //
  21          //    - generalSCSIInCommand() and generalSCSIOutCommand() are called from
  22          //       periph.c.  Their conditional compile flags are kept inside the function
  23          //       to maintain original code for periph.c.  All other functions in this
  24          //       module are specific for SCSI and are static to this file.  They are
  25          //       under one conditional compile flag.
  26          //
  27          //-----------------------------------------------------------------------------
  28          // $Archive: /USB/atapifx2/software/scsi.c $
  29          // $Date: 1/21/02 2:38p $
  30          // $Revision: 41 $
  31          //
  32          //-----------------------------------------------------------------------------
  33          //  Copyright (c) 1999 Cypress Semiconductor, Inc. All rights reserved
  34          //-----------------------------------------------------------------------------
  35          #include "fx2.h"
  36          #include "fx2regs.h"
  37          #include "scsi.h"
  38          #include "gpif.h"
  39          
  40          static BYTE scsiWrite(void);
  41          static BYTE scsiWriteUdma();
  42          static void prepareForATAPICommand();
  43          static bit inDataFromDriveUdma();
  44          
  45          
  46          // this bit determines if the current transfer is to be carried out using UDMA (1) or
  47          // PIO (0)
  48          bit useUdma;
  49          bit bShortPacketSent;
  50          BYTE udmaErrorCount;
  51          
  52          #define SENSE_LEN 18
  53          
C51 COMPILER V7.50   SCSI                                                                  11/07/2006 14:52:10 PAGE 2   

  54          //-----------------------------------------------------------------------------
  55          // Function:  generalSCSIInCommand()
  56          //
  57          // Input:   none
  58          // Output:  bit flag
  59          //          0 = success, 1 = failure
  60          //
  61          // Global data:
  62          //    CBW from EP2FIFOBUF.
  63          //
  64          // Description:
  65          //    Top level handler for scsi read.  The scsi command packet is 
  66          //    a 12-byte packet extracted from the CBW contained in EP2FIFOBUF 
  67          //    starting from byte 15.  If the command fails, the IN endpoint buffer
  68          //    is stalled and the transaction is failed.
  69          //
  70          //    If the command was processed successfully, data is extracted from the 
  71          //    drive till the byte count from the drive is exhausted.  If the byte count
  72          //    indicated by the drive is less than what is requested by the host, the IN
  73          //    endpoint is stalled, but the transaction is passed.  The remainder of bytes
  74          //    the host still expects is reported as a residue.
  75          //-----------------------------------------------------------------------------
  76          BYTE generalSCSIInCommand()
  77          {
  78   1      #if DEVICE_TYPE_IS_SCSI
  79   1      
  80   1         BYTE result = 0;
  81   1      
  82   1         // Clear the bit telling us if we need a STALL to terminat the IRP on the host side   
  83   1         bShortPacketSent = 0;
  84   1      
  85   1         // if the drive is configured for udma then use udma depending on the
  86   1         // scsi command
  87   1         if (udmaMode)
  88   1         {
  89   2            switch(EP2FIFOBUF[0xf])
  90   2            {
  91   3               case 0x28:
  92   3               case 0xA8:
  93   3                  useUdma = 1;     
  94   3                  break;
  95   3               default:
  96   3                  useUdma = 0;
  97   3                  break;
  98   3            }
  99   2         }
 100   1      
 101   1         result = sendSCSICommand(EP2FIFOBUF + CBW_DATA_START);
 102   1      
 103   1         // relinquish control of the bulk buffer occupied by the CBW
 104   1         EP2BCL = 0x80; 
 105   1         
 106   1         // Need to modify this code so that we know if we sent a short packet to terminate the xfer.
 107   1         // Although the STALL is required, the ScanLogic driver and Mac driver will not properly handle it.
 108   1         
 109   1         if(result != USBS_PASSED)
 110   1            {
 111   2            failedIn();    // stalls EP8 
 112   2            return(USBS_FAILED);
 113   2            }
 114   1      
 115   1         // no need to do the data xfer phase if the host isn't expecting any data.
C51 COMPILER V7.50   SCSI                                                                  11/07/2006 14:52:10 PAGE 3   

 116   1         if (!dataTransferLenLSW && !dataTransferLenMSW)
 117   1            {
 118   2            // Make sure the status is correct
 119   2            while (readATAPI_STATUS_REG() & ATAPI_STATUS_BUSY_BIT)
 120   2               ;
 121   2      
 122   2            if (readATAPI_STATUS_REG() & ATAPI_STATUS_DRQ_BIT)
 123   2               return(USBS_PHASE_ERROR);       // USBS_PHASE_ERROR -- Hn < Di (case 2)
 124   2            else
 125   2               return(USBS_PASSED);
 126   2            }
 127   1      
 128   1         //////////////////////////////////////////////////////////////////
 129   1         // Start of data xfer phase
 130   1         //////////////////////////////////////////////////////////////////
 131   1         if (useUdma) 
 132   1         {
 133   2            result = inDataFromDriveUdma();
 134   2         }
 135   1         else
 136   1         {
 137   2            result = inDataFromDrive();
 138   2         }
 139   1      
 140   1         if (dataTransferLen)    
 141   1            {
 142   2            // Case H(i) > D(i) or H(i) > D(n)
 143   2            // "terminate the transfer with a short packet, then STALL the IN endpoint"
 144   2            failedIn();       // only stalls EP8, does not return error
 145   2           
 146   2            // Pass the result to the next layer up.
 147   2            return(result);  
 148   2            }
 149   1      
 150   1         else
 151   1            return(result);       // No residue, just return status
 152   1      
 153   1      #else
                 return(0);
              #endif
 156   1      }   
 157          
 158          
 159          //-----------------------------------------------------------------------------
 160          // Function:  generalSCSIOutCommand()
 161          //
 162          // Input:   none
 163          // Output:  bit flag
 164          //          0 = success, 1 = failure
 165          //
 166          // Global data:
 167          //    CBW from EP2FIFOBUF.
 168          //
 169          // Local data:
 170          //    cmd      - command op code from CBW
 171          //    result   - return status
 172          //
 173          // Description:
 174          //    The scsi command packet is a 12-byte packet extracted from the CBW 
 175          //    contained in EP2FIFOBUF starting from byte 15.  If the command fails, 
 176          //    the OUT endpoint buffer is stalled and the transaction is failed.
 177          //
C51 COMPILER V7.50   SCSI                                                                  11/07/2006 14:52:10 PAGE 4   

 178          //    If the command is successful, data is sent to the drive.
 179          //    When the write encounters an error, the endpoint is stalled and the
 180          //    transaction is failed.
 181          //
 182          //-----------------------------------------------------------------------------
 183          BYTE generalSCSIOutCommand()
 184          {
 185   1      #if DEVICE_TYPE_IS_SCSI
 186   1         // Init local vars.
 187   1      
 188   1         BYTE result = USBS_FAILED;
 189   1      
 190   1         useUdma = 0;
 191   1      
 192   1         // if the drive is configured for udma then use udma depending on the
 193   1         // scsi command
 194   1         if (udmaMode)
 195   1         {
 196   2            switch(EP2FIFOBUF[0xf])
 197   2            {
 198   3               case 0x2A:
 199   3               case 0xAA:
 200   3                  useUdma = 1;   //syk
 201   3                  break;
 202   3               default:
 203   3                  useUdma = 0;
 204   3                  break;
 205   3            }
 206   2         }
 207   1      
 208   1         result = sendSCSICommand(EP2FIFOBUF + CBW_DATA_START);
 209   1      
 210   1         // relinquish control of the bulk buffer occupied by the CBW
 211   1         EP2BCL = 0x80;     
 212   1      
 213   1         // If the command failed, stall the endpoint and get out
 214   1         if (result != USBS_PASSED)
 215   1         {
 216   2            // If the transfer still contains data, and the xfer has not been terminated by a short packet
 217   2            // then we must stop the transfer with a STALL.
 218   2            if (dataTransferLen > 0)
 219   2            {
 220   3               // We may want to stall the endpoint here, but we must be careful to make sure that 
 221   3               // we don't set the stall bit when the xfer has completed!
 222   3                stallEP2OUT();
 223   3            }
 224   2            return(USBS_FAILED);
 225   2         }
 226   1      
 227   1         if (!dataTransferLen)
 228   1            return(result);
 229   1      
 230   1         if (useUdma)
 231   1         {
 232   2            result = scsiWriteUdma();
 233   2         }
 234   1         else
 235   1         {
 236   2            result = scsiWrite();
 237   2         }
 238   1      
 239   1         return(result);
C51 COMPILER V7.50   SCSI                                                                  11/07/2006 14:52:10 PAGE 5   

 240   1      #endif
 241   1      
 242   1      #if DEVICE_TYPE_IS_IDE
 243   1         return(0);
 244   1      #endif
 245   1      }
 246          
 247          
 248          
 249          #define SENSE_LEN 18
 250          const char code testUnitReady[12] = { 0x00, 0x00, 0x00, 0x00, 00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
             -};
 251          const char code requestSense[12] = {  0x03, 0x00, 0x00, 0x00, SENSE_LEN, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0
             -0, 0x00};
 252          // Send a TestUnitReady command to the device.
 253          // If the device fails the testUnitReady command, return the sense code, else return 0
 254          BYTE SCSITestUnitReady()
 255          {
 256   1      
 257   1         bit result = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?