scsi.lst

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

LST
1,388
字号
 258   1         //char count;
 259   1          
 260   1         if (!scsi)
 261   1            return(result);
 262   1      
 263   1      #if DEVICE_TYPE_IS_SCSI
 264   1         useUdma = 0;
 265   1         result = sendSCSICommand((char xdata *) testUnitReady);
 266   1         if (result != USBS_PASSED)
 267   1         {
 268   2            result = sendSCSICommand((char xdata *) requestSense);
 269   2            if (result != USBS_PASSED)
 270   2               {
 271   3               }
 272   2      
 273   2            //result = waitForIntrq();
 274   2      
 275   2            readPIO16toXdata(ATAPI_DATA_REG, halfKBuffer, SENSE_LEN, LISTEN_TO_DRIVE_LEN);
 276   2            return(halfKBuffer[12]);
 277   2          }
 278   1      #endif
 279   1      }   
 280          
 281          
 282          // Read the Inquiry info into our internal data structures.
 283          // NOT prompted by the host.
 284          #define INQUIRY_LEN 0x2c
 285          const char code inquiryCommand[12] = { 0x12, 0x00, 0x00, 0x00, INQUIRY_LEN, 0x00, 0x00, 0x00, 0x00, 0x00, 
             -0x00, 0x00};
 286          void SCSIInquiryToATAPI()
 287          {
 288   1      #if DEVICE_TYPE_IS_SCSI
 289   1      
 290   1          bit result;
 291   1      
 292   1          useUdma = 0;
 293   1          result = sendSCSICommand((char xdata *) inquiryCommand);
 294   1          if (result != USBS_PASSED)
 295   1          {
 296   2              failedIn();    //This is an internal command, just leave if it fails.
 297   2              return;
 298   2          }
C51 COMPILER V7.50   SCSI                                                                  11/07/2006 14:52:10 PAGE 6   

 299   1      
 300   1           result = waitForIntrq();
 301   1      
 302   1           readPIO16toXdata(ATAPI_DATA_REG, halfKBuffer, INQUIRY_LEN, LISTEN_TO_DRIVE_LEN);
 303   1        
 304   1      
 305   1         if (halfKBuffer[SCSI_INQUIRY_DEVICE_CLASS] == 5)
 306   1         {
 307   2            intrfcSubClass = USB_MS_CD_ROM_SUBCLASS;  
 308   2         }
 309   1      #endif
 310   1      }   
 311          
 312          
 313          WORD getDriveDataLen()
 314          {
 315   1          WORD driveDataLen;
 316   1      
 317   1      
 318   1          driveDataLen = readPIO8(ATAPI_BYTE_COUNT_MSB) << 8;
 319   1          driveDataLen += readPIO8(ATAPI_BYTE_COUNT_LSB);
 320   1          return(driveDataLen);
 321   1      }
 322           
 323          
 324          
 325          ///////////////////////////////////////////////////////////////////////////////
 326          #if DEVICE_TYPE_IS_SCSI
 327          ///////////////////////////////////////////////////////////////////////////////
 328          
 329          //-----------------------------------------------------------------------------
 330          // Function:  scsiWrite()
 331          //
 332          // Input:   none
 333          // Output:  bit flag
 334          //          0 = success, 1 = failure
 335          //
 336          // Global data:
 337          //    dataTransferLen   - Amount of data requested by the host.  Counts down.
 338          //    EP2CS             - Endpoint buffer status byte.
 339          //    EP2BCL            - Endpoint LSB byte count register.
 340          //
 341          // Local data:
 342          //    wDriveDataLen     - Amount of data drive will accept.
 343          //    wAmountToWrite    - Amount of data to write to the drive.  This is typically
 344          //                         a portion wDriveDataLen, and is qualified by the packet lenght.
 345          //    wAmountSent       - Amount of data sent to the drive.  Counts up to ensure we don't
 346          //                         exceed the packet size.
 347          //    driveStatus       - Drive status from last action.  
 348          //    bDone             - loop control flag     
 349          //
 350          // Description:
 351          //    This function handles the special case of scsi MODE PAGE write (MODE SELECT command).
 352          //    The drive byte count and the DRQ bit are used to determine how much data to send.
 353          //    Typically, the host requests to send data that is much larger than what the
 354          //    drive wants to accept.  
 355          //
 356          //    The drive may want to receive data in chunks less than a packet size, and the 
 357          //    total number of bytes to satisfy the command may be less or greater than
 358          //    a packet length.  Drive data request is processed as follows:
 359          //    
 360          //    (1) Total number of bytes is less than a packet, and drive wants to receive it in
C51 COMPILER V7.50   SCSI                                                                  11/07/2006 14:52:10 PAGE 7   

 361          //    increments.  The rest of the packet must be processed out of the buffer in
 362          //    the size requested by the drive.  This transaction is governed by the
 363          //    DRQ bit in the status register.
 364          //
 365          //    (2) Total number of bytes is greater than a packet, but drive wants it
 366          //    in increments less than a packet lenght.  Full packet(s) are processed out
 367          //    of the buffer using logic from (1) until the drive is satisfied.  This 
 368          //    transaction is governed by the DRQ bit in the status register as well as the
 369          //    byte count from the drive.  Any data residue in the endpoint buffer is sent 
 370          //    to ATAPI_NULL_REGISTER.
 371          //
 372          //    If the host is determined to queue up packets to the buffer after the drive 
 373          //    byte count has been satisfied (DRQ=0), the data is processed out of the endpoint 
 374          //    buffer and discarded by setting the skip bit in the endpoint's byte count
 375          //    register.
 376          //
 377          //    The DRQ bit is valid.
 378          //
 379          //    If a write encounters an error, we return an error and let caller 
 380          //    stall the endpoint.
 381          //
 382          //-----------------------------------------------------------------------------
 383          static BYTE scsiWrite(void)
 384          {
 385   1      
 386   1         WORD wDriveDataLen = 0;
 387   1         BYTE driveStatus = 0;
 388   1         WORD wAmountToWrite = 0;
 389   1         WORD wAmountSent = 0;  
 390   1         bit bDone = 0;
 391   1         bit bShortPacketReceived = 0;
 392   1         BYTE cReturnStatus = USBS_PASSED;
 393   1         
 394   1      
 395   1         // See if drive is finished processing command and
 396   1         // is ready for data.
 397   1         while(readATAPI_STATUS_REG() & ATAPI_STATUS_BUSY_BIT)
 398   1            ;
 399   1      
 400   1         driveStatus = readATAPI_STATUS_REG();
 401   1      
 402   1         if (driveStatus & ATAPI_STATUS_DRQ_BIT)
 403   1         {
 404   2            while( (!(driveStatus & ATAPI_STATUS_ERROR_BIT)) && (!bDone) && dataTransferLen)
 405   2               {
 406   3                // Make sure the data is already in the endpoint buffer
 407   3               if(!(EP2CS & (bmEPEMPTY | bmEPSTALL))) 
 408   3                  {
 409   4                  if (EP2BC & (wPacketSize - 1))
 410   4                     bShortPacketReceived = 1;
 411   4      
 412   4                  EP2BCL = 00;         // Release the endpoint buffer to FIFO.
 413   4         
 414   4                  // Get the amount of data the drive is willing to accept
 415   4                  if(!wDriveDataLen)
 416   4                     wDriveDataLen = getDriveDataLen();
 417   4         
 418   4                  wAmountSent = 0; 
 419   4                  while( (wPacketSize > wAmountSent) && (!bDone) && dataTransferLen)
 420   4                     {
 421   5                     // wAmountToWrite is limited by two factors:
 422   5                     // -- wDriveDataLen -- The amount of data remaining in the drive's most recent request
C51 COMPILER V7.50   SCSI                                                                  11/07/2006 14:52:10 PAGE 8   

 423   5                     // -- wPacketSize-wAmountSent -- The amount of data remaining in our buffer
 424   5                     wAmountToWrite = min(wPacketSize-wAmountSent, wDriveDataLen);
 425   5                     wAmountToWrite = min(dataTransferLen, wAmountToWrite);
 426   5            
 427   5                     // Send the packet and adjust counts.  
 428   5                     writePIO16(ATAPI_DATA_REG, wAmountToWrite+1);
 429   5                     dataTransferLen -= wAmountToWrite;
 430   5                     wDriveDataLen -= wAmountToWrite;
 431   5                     wAmountSent += wAmountToWrite;
 432   5         
 433   5                     // Make sure the write is successful, otherwise get out. -- First wait for the busy bit to 
             -clear.
 434   5                     while(readATAPI_STATUS_REG() & ATAPI_STATUS_BUSY_BIT)
 435   5                        ;
 436   5         
 437   5                     // Don't trust the first result after the busy bit goes away.  Read it again.
 438   5                     // The DELL-07 CDRW has occasional problems if this is not done.
 439   5                     driveStatus = readATAPI_STATUS_REG();
 440   5                     
 441   5                     if(driveStatus & ATAPI_STATUS_ERROR_BIT)
 442   5                        {
 443   6                        cReturnStatus = USBS_FAILED;  
 444   6                        bDone = 1;                    
 445   6                        }
 446   5                     else
 447   5                        {
 448   6                        // Check if drive is finished with transaction.
 449   6                        if(!(driveStatus & ATAPI_STATUS_DRQ_BIT))
 450   6                           {
 451   7                           bDone=1;
 452   7                           cReturnStatus = USBS_PASSED;
 453   7                           }
 454   6                        else if(!wDriveDataLen)
 455   6                           wDriveDataLen = getDriveDataLen();
 456   6         
 457   6                        } // end else
 458   5                     } // end while(within current packet)
 459   4                  } // end if(data in endpoint buffer)
 460   3               } // end while(all data)
 461   2            } // end if (drive has data)
 462   1      
 463   1         // If the device still wants more data from the host at this point, it's a phase error (case 13)
 464   1         if ((readATAPI_STATUS_REG() & ATAPI_STATUS_DRQ_BIT) || wDriveDataLen)
 465   1            cReturnStatus = (USBS_PHASE_ERROR);   
 466   1      
 467   1         // If there is still data in our buffer there are several possibilities:
 468   1         // 1)  Data in our buffer.  No more data coming from the host.  Reset the endpoint.
 469   1         // 2)  Buffer full, more data expected from the host.  STALL.
 470   1         // 3)  Data still on the way from the host that will go beyond our buffer size.  STALL.
 471   1         // 4)  Data still on the way from the host that will fit within our buffer size.  Wait for the data, th
             -en reset the endpoint.
 472   1         //       There is no clean way to wait for the data that works with the current TCL scripts.  Just rese
             -t the endpoing.
 473   1         //
 474   1         if (dataTransferLen && !bShortPacketReceived)
 475   1            stallEP2OUT();
 476   1         // This is done in send_usbs()
 477   1         //   else if (!(EP2468STAT & bmEP2EMPTY))         // Discard residue in the buffer if needed.  This is 
             -required so that the FIFO will give the buffer back to us (if we DON'T stall)
 478   1         //                           // For example, case 11 with 250 bytes of data.
 479   1         //      ResetAndArmEp2();     
 480   1         return(cReturnStatus);
C51 COMPILER V7.50   SCSI                                                                  11/07/2006 14:52:10 PAGE 9   

 481   1      }
 482          
 483          
 484          //-----------------------------------------------------------------------------
 485          // Function:  sendSCSICommand()
 486          //
 487          // Input:   
 488          //    bit useInterrupt     
 489          //    char xdata *cmdbuf   - scsi command packet (EP2FIFOBUF + CBW_DATA_START)
 490          //
 491          // Output:  bit flag
 492          //          0 = success, 1 = failure
 493          //
 494          // Local data:
 495          //    WORD cmd_data - modified command data packet
 496          //
 497          // Description:
 498          //    The command packet is sent to the drive using 16-bit register writes to
 499          //    the drive's data register.  Data is modified to handle endian-ness before
 500          //    before it is sent to the drive.
 501          //
 502          //    ALERT!!!:  Sending the command packet to the drive using register writes was
 503          //       due to an assumption that we could not GPIF the middle of an endpoint's
 504          //       content.  From SSW, we can walk down an endpoint's content using GPIF
 505          //       as long as the transaction count is not exhausted.  For optimization,
 506          //       we may want to GPIF the start of the CBW (maybe send it to the null
 507          //       register where it won't cause grief), GPIF the scsi command packet
 508          //       to the drive then discard the rest of the CBW.  This would remove the
 509          //       need to process the command packet for endian-ness.
 510          //-----------------------------------------------------------------------------
 511          static bit sendSCSICommand(char xdata *cmdbuf)
 512          {
 513   1      
 514   1         BYTE driveStatus;
 515   1        
 516   1         prepareForATAPICommand();
 517   1         
 518   1         CLEAR_INTRQ;    // Clear the interrupt bit.
 519   1         
 520   1         // Make sure the device is ready for the packet
 521   1         while (readATAPI_STATUS_REG() & ATAPI_STATUS_BUSY_BIT)
 522   1            ;

⌨️ 快捷键说明

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