ide.lst

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

LST
1,377
字号
 252   3               // Page 0x3F, All Pages, is also responded to, I just return the single page 5 though.
 253   3               // I do this because page 5 is the only page with significant information anyway, and
 254   3               // this simplification reduces the code by eliminating the need to return a number of
 255   3               // additional pages (which would change if additional pages are later supported).
 256   3               // The supported pages are (see INF-8070_1_3.pdf p37 Table 25):
 257   3               //   case 0x01:                          // Read-Write Error Recovery Page
 258   3               //   case 0x08:                          // Caching Page
 259   3               //   case 0x05:                          // Flexible Disk Page: needed to boot from USB
 260   3               //   case 0x1B:                          // Removable Block Access Capabilities Page
 261   3               //   case 0x3F:                          // All Pages
 262   3               
 263   3               EP8FIFOBUF[0] = 0x00;
 264   3               mymemmovexx(EP8FIFOBUF+1, EP8FIFOBUF, 18-1); // clear buffer - 18 bytes in all responses
 265   3               
 266   3               EP8FIFOBUF[1] = 0x12; // Mode Data length (LSB) in Mode Parameter Header is 
 267   3                                     // 8(MPH) + 12(1 page) - 2(offset of 2 byte length field itself)           
 268   3               
 269   3               EP8FIFOBUF[8+0] = pagenum;         // fill out the page num - fields are all 0x0
 270   3               EP8FIFOBUF[8+1] = 0x0A;            // set individual Page Length
 271   3         
 272   3               if((pagenum == 0x05) || (pagenum == 0x3F))
 273   3               {  // Note: a request for All Pages just returns the single page 5 here
 274   4                  EP8FIFOBUF[8+0] = 0x05;            
 275   4                  if(EZUSB_HIGHSPEED())
 276   4                  {
 277   5                     EP8FIFOBUF[8+2] = 0xFF;         // HS Transfer Rate (MSB) (field limited to 65Mb/Sec)
 278   5                     EP8FIFOBUF[8+3] = 0xFF;         // HS Transfer Rate (LSB)
 279   5                  }
 280   4                  else
 281   4                  {
 282   5                     EP8FIFOBUF[8+2] = 0x2E;         // FS Transfer Rate (MSB) (12Mb/Sec) 
 283   5                     EP8FIFOBUF[8+3] = 0xE0;         // FS Transfer Rate (LSB)
 284   5                  }
 285   4                  EP8FIFOBUF[8+4] = NumHeads;        // #Heads
 286   4                  EP8FIFOBUF[8+5] = NumSectPerTrack; // #SectorsPerTrack
 287   4                  EP8FIFOBUF[8+6] = (ATA_SECTOR_SIZE >>  8) & 0xff; // Data Bytes per sector (truncated)
 288   4                  EP8FIFOBUF[8+7] = (ATA_SECTOR_SIZE >>  0) & 0xff; // Data Bytes per sector
 289   4                  EP8FIFOBUF[8+8] = NumCylindersMSB; // #Cyl MSB
 290   4                  EP8FIFOBUF[8+9] = NumCylindersLSB; // #Cyl LSB
 291   4               }
 292   3               else if(pagenum == 0x1B)
 293   3               {
 294   4                  EP8FIFOBUF[8+3] = 0x01;            // set TLUN = 1 for page 0x1B
 295   4               }
C51 COMPILER V7.50   IDE                                                                   11/07/2006 14:52:09 PAGE 6   

 296   3         
 297   3               packetLen = min(0x12, dataTransferLen);
 298   3               if (packetLen)
 299   3               {
 300   4                  EP8BCH = MSB(packetLen);
 301   4                  EP8BCL = LSB(packetLen);
 302   4               
 303   4                  dataTransferLen -= packetLen;
 304   4               }
 305   3               sensePtr = senseOk;
 306   3               return(USBS_PASSED);
 307   3            } // end case
 308   2      
 309   2            case MODE_SELECT_06:
 310   2            case MODE_SENSE_06:
 311   2            case STOP_START_UNIT:
 312   2            default:
 313   2            {
 314   3               // relinquish control of the bulk buffer occupied by the CBW
 315   3               EP2BCL = 0x80;     
 316   3               
 317   3               sensePtr = senseInvalidFieldInCDB;
 318   3               failedIn();
 319   3               return(USBS_FAILED);
 320   3            }
 321   2         }
 322   1      }   
 323          
 324          bit generalIDEOutCommand()
 325          {
 326   1         BYTE cmd;
 327   1         
 328   1         cmd = EP2FIFOBUF[0xf];  
 329   1         
 330   1         switch (cmd)
 331   1         {
 332   2            case WRITE_10:
 333   2               sensePtr = senseOk;
 334   2               checkForMedia();
 335   2               if (sensePtr == senseOk)
 336   2                  return(ideWriteCommand());
 337   2               else
 338   2               {
 339   3                  // relinquish control of the bulk buffer occupied by the CBW
 340   3                  EP2BCL = 0x80;
 341   3                  if (dataTransferLen)
 342   3                     stallEP2OUT();
 343   3      
 344   3                  return(USBS_FAILED);
 345   3               }
 346   2                      
 347   2            default:
 348   2               // relinquish control of the bulk buffer occupied by the CBW
 349   2               EP2BCL = 0x80;     
 350   2               
 351   2               if (dataTransferLen)
 352   2                  stallEP2OUT();
 353   2               
 354   2               return(USBS_FAILED);
 355   2               break;
 356   2         }
 357   1      }   
C51 COMPILER V7.50   IDE                                                                   11/07/2006 14:52:09 PAGE 7   

 358          
 359          
 360          
 361          void waitForInBuffer()
 362          {
 363   1         while((EP8CS & bmEPFULL));   // Wait for an available buffer from the host
 364   1      
 365   1         return;
 366   1      }   
 367          
 368          
 369          static bit ideReadCommand(bit verify)
 370          {   
 371   1         BYTE driveStatus;
 372   1         WORD sectorcount; 
 373   1         BYTE i; 
 374   1         WORD wordCtr;
 375   1      
 376   1         writePIO8(ATA_DRIVESEL_REG, 0xe0);
 377   1         if (waitForBusyBit() == USBS_FAILED)
 378   1         {
 379   2            // Oddly enough, an error bit is okay here.  It means that the LAST command failed, not this one.
 380   2            // A new command is required to clear many error conditions.
 381   2         }
 382   1              
 383   1         ((BYTE *) &dwLBA)[0] = EP2FIFOBUF[CBW_DATA_START+2];
 384   1         ((BYTE *) &dwLBA)[1] = EP2FIFOBUF[CBW_DATA_START+3];
 385   1         ((BYTE *) &dwLBA)[2] = EP2FIFOBUF[CBW_DATA_START+4];
 386   1         ((BYTE *) &dwLBA)[3] = EP2FIFOBUF[CBW_DATA_START+5];
 387   1      
 388   1         // relinquish control of the bulk buffer occupied by the CBW
 389   1         EP2BCL = 0x80;  
 390   1      
 391   1         // This loop breaks up the 32 bit length into 8 bits * sectors.
 392   1         // For example, a read of 0x10000 turns into 0x80 sectors.
 393   1         while (dataTransferLen)
 394   1         {
 395   2            dwLBAtoLBARegs();
 396   2      
 397   2            // First stuff the length register (number of sectors to read)
 398   2            if (dataTransferLenMSW & 0xfffe)
 399   2            {
 400   3               writePIO8(ATA_SECTOR_COUNT_REG, 1);     // if (bExtAddrSupport) we need to stuff the MSB
 401   3               writePIO8(ATA_SECTOR_COUNT_REG, 0);     // 0 means 256 blocks of 512 bytes -- Max drive xfer, max
             - TC
 402   3               sectorcount = 0x100;
 403   3            }
 404   2            else
 405   2            {
 406   3               sectorcount = (dataTransferLenLSW + ATA_SECTOR_SIZE-1)/ATA_SECTOR_SIZE + (dataTransferLenMSW & 1)
             - * 0x80;
 407   3               writePIO8(ATA_SECTOR_COUNT_REG, 0);      // for extended addressing
 408   3               writePIO8(ATA_SECTOR_COUNT_REG, sectorcount);       // divide len into blocks
 409   3            }
 410   2              
 411   2            dwLBA += sectorcount;
 412   2            
 413   2            if (!udmaMode || verify || (dataTransferLenLSW & 0x1ff))    // UDMA cannot handle sub-sector sized r
             -eads
 414   2            {
 415   3               // Execute the read command
 416   3               if (bExtAddrSupport)
C51 COMPILER V7.50   IDE                                                                   11/07/2006 14:52:09 PAGE 8   

 417   3                  {
 418   4                  if (verify)
 419   4                     writePIO8(ATA_COMMAND_REG, ATA_COMMAND_VERIFY_10_EXT);
 420   4                  else
 421   4                     writePIO8(ATA_COMMAND_REG, ATA_COMMAND_READ_10_EXT);
 422   4                  }
 423   3               else
 424   3                  {
 425   4                  if (verify)
 426   4                     writePIO8(ATA_COMMAND_REG, ATA_COMMAND_VERIFY_10);
 427   4                  else
 428   4                     writePIO8(ATA_COMMAND_REG, ATA_COMMAND_READ_10);
 429   4                  }
 430   3      
 431   3                 
 432   3               // The verify command reads from the drive, but doesn't transfer data
 433   3               // to us.
 434   3               if (verify)     
 435   3               {
 436   4                  if(waitForBusyBit() == USBS_FAILED)
 437   4                     return(USBS_FAILED);
 438   4                  else
 439   4                     continue;
 440   4               }
 441   3         
 442   3               // set up for GPIF transfer - wordwide
 443   3               //EP8GPIFTCH = MSB(wPacketSize >> 1);     
 444   3               //EP8GPIFTCL = LSB(wPacketSize >> 1);
 445   3               
 446   3               while (sectorcount--)
 447   3               {
 448   4                  // Wait for the drive to be non-busy and have either data or an error
 449   4                  while (1)
 450   4                  {
 451   5                     driveStatus = readATAPI_STATUS_REG();                             
 452   5                     if ((driveStatus & (ATAPI_STATUS_BUSY_BIT | ATAPI_STATUS_DRQ_BIT)) == ATAPI_STATUS_DRQ_BIT)
 453   5                        break;
 454   5                     if (driveStatus & (ATAPI_STATUS_BUSY_BIT | ATAPI_STATUS_ERROR_BIT) == ATAPI_STATUS_ERROR_BI
             -T)
 455   5                        break;
 456   5                  }
 457   4      
 458   4                  // If there's an error, the drive may still want to send us the data.
 459   4                  if (driveStatus & ATAPI_STATUS_ERROR_BIT)
 460   4                     {
 461   5                     readPIO8(ATAPI_ERROR_REG);
 462   5                     if (driveStatus & ATAPI_STATUS_DRQ_BIT)
 463   5                        for (wordCtr = 0; wordCtr < 0x100; wordCtr++)
 464   5                           readPIO8(ATAPI_DATA_REG);
 465   5                     failedIn();
 466   5                     return(USBS_FAILED);  
 467   5                     }
 468   4                  else
 469   4                  {
 470   5                     BYTE bLimit;
 471   5                     WORD wThisPacketSize;
 472   5      
 473   5                     if (wPacketSize == 0x40)
 474   5                        bLimit = 8;
 475   5                     else 
 476   5                        bLimit = 1;
 477   5                     for (i = 0; i < bLimit && dataTransferLen; i++)
C51 COMPILER V7.50   IDE                                                                   11/07/2006 14:52:09 PAGE 9   

 478   5                     {
 479   6                        waitForInBuffer();
 480   6      
 481   6                        wThisPacketSize = min(wPacketSize, dataTransferLen);
 482   6                        readPIO16(ATAPI_DATA_REG, wThisPacketSize+1);
 483   6                        while (!gpifIdle())     // Wait for xfer to complete
 484   6                           ;
 485   6                        EP8BCH = MSB(wThisPacketSize);
 486   6                        EP8BCL = LSB(wThisPacketSize);
 487   6                        dataTransferLen -= wThisPacketSize; 
 488   6                     }
 489   5                  }
 490   4               }//while (sectorcount--)
 491   3            }
 492   2            else  // transfer is udma mode
 493   2            {
 494   3               initUdmaRead();
 495   3               if (bExtAddrSupport)
 496   3                  writePIO8(ATAPI_COMMAND_REG, ATA_COMMAND_DMAREAD_RETRY_EXT);
 497   3               else
 498   3                  writePIO8(ATAPI_COMMAND_REG, ATA_COMMAND_DMAREAD_RETRY);
 499   3               readUDMA((DWORD) sectorcount << 8);     // Words = sectors * 256
 500   3               driveStatus = readATAPI_STATUS_REG();
 501   3               if (driveStatus & ATAPI_STATUS_ERROR_BIT) 
 502   3                  {
 503   4                  if (readPIO8(ATAPI_ERROR_REG) & ATAPI_ERROR_ICRC_BIT)
 504   4                     {
 505   5                     sensePtr = senseCRCError;
 506   5                     }
 507   4                  // No need to do failedIn() -- All data is already xferred.
 508   4                  return(USBS_FAILED);
 509   4                  }
 510   3      
 511   3               // Two choices -- Either we're limited to 0x100 sectors, or limited to dataTransferLen.
 512   3               // BUGBUG -- No capability here to report Hi > Di.
 513   3               if (sectorcount == 0x100)
 514   3                  dataTransferLenMSW -= 2;
 515   3               else

⌨️ 快捷键说明

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