⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ata.c

📁 Cirrus Logic EP7312处理器部分控制程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
// Function Name: ATAExecuteDeviceDiagnostic
//	
// Function Description: Function implements the ATA Execute Device
//                       Diagnostic command. Returns the device  
//                       diagnostic code.
//
//*******************************************************************
unsigned char ATAExecuteDeviceDiagnostic(void)
{
   unsigned char ucReturnValue;

   //
   // Wait for the BSY and DRQ bits in the Status register to be low.
   //
   while(ATAReadCommandRegister(STATUSREGISTER) & (ATABSY | ATADRQ));

   //
   // Write the execute device diagnostic command into the 
   // Command register.
   //
   ATAWriteCommandRegister(COMMANDREGISTER, 0x90);

   //
   // Wait for the command to complete.
   // 
   while(ATAReadCommandRegister(STATUSREGISTER) & (ATABSY | ATADRQ));

   //
   // Read and return the diagnostic code out.
   //
   ucReturnValue = ATAReadCommandRegister(ERRORREGISTER);

   return(ucReturnValue);
}

//*******************************************************************
//
// Function Name: ATAIdentifyPacketDevice	
//
// Function Description: Function retruns a 256 word chunk of data 
//			 about the device.
//
//*******************************************************************
int ATAIdentifyPacketDevice(unsigned short * RV)
{
   unsigned long returncount;

   //
   // Wait for the BSY and DRQ bits in the Status register to be low.
   //
   while(ATAReadCommandRegister(STATUSREGISTER) & (ATABSY | ATADRQ));

   //
   // Write the identify packet device command into the Command register.
   //
   ATAWriteCommandRegister(COMMANDREGISTER, 0xa1);

   //
   // Wait for the command to complete.
   //
   while(ATAReadCommandRegister(STATUSREGISTER) & (ATABSY));

   //
   // Read and return the data.
   //
   returncount = ATAReadDataRegister(RV,256);

   return(returncount);
}

//*****************************************************************
//
// Function Name: ATASimpleRegPacket
//
// Function Description:                        
//
//******************************************************************
unsigned int ATASimpleRegPacket(int dev, unsigned int uiCommandPacketByteCount,		
 		           unsigned short cfp[6], unsigned int uiTransferDir,				
                       unsigned int uiDataPacketByteCount, 
                       unsigned short * data_pointer )
{
   
   unsigned long ulCount = 0;					
   unsigned long ulTotalTransfered = 0;

   unsigned short usWordCount = 0;
   unsigned short usByteCount = 0;
   unsigned char ucDevCtrl = 0;
   unsigned char ucDevHead = 0;
   unsigned char ucCylLow = 0;
   unsigned char ucCylHigh = 0;
   unsigned char ucFrReg = 0;
   unsigned char ucScReg = 0;
   unsigned char ucSnReg = 0;
   unsigned char ucStatus = 0;
   unsigned char ucReason = 0;
   unsigned char ucLowCyl = 0;
   unsigned char ucHighCyl = 0;
   
   ucDevCtrl = CB_DC_HD15 | CB_DC_NIEN;
   ucDevHead = dev ? CB_DH_DEV1 : CB_DH_DEV0 ;
   ucCylLow = uiDataPacketByteCount & 0x00ff;
   ucCylHigh = ( uiDataPacketByteCount & 0xff00 ) >> 8;
   ucFrReg = reg_atapi_reg_fr;
   ucScReg = reg_atapi_reg_sc;
   ucSnReg = reg_atapi_reg_sn;
   reg_atapi_reg_fr = 0;
   reg_atapi_reg_sc = 0;
   reg_atapi_reg_sn = 0;
   reg_atapi_reg_dh = 0;

   reg_cmd_info.cmd = 0;
   reg_cmd_info.fr1 = 0;
   reg_cmd_info.sc1 = 0;
   reg_cmd_info.sn1 = 0;
   reg_cmd_info.cl1 = 0;
   reg_cmd_info.ch1 = 0;
   reg_cmd_info.dh1 = 0;
   reg_cmd_info.dc1 = 0;
   reg_cmd_info.ec  = 0;
   reg_cmd_info.to  = 0;
   reg_cmd_info.st2 = 0;
   reg_cmd_info.as2 = 0;
   reg_cmd_info.er2 = 0;
   reg_cmd_info.sc2 = 0;
   reg_cmd_info.sn2 = 0;
   reg_cmd_info.cl2 = 0;
   reg_cmd_info.ch2 = 0;
   reg_cmd_info.dh2 = 0;
   reg_cmd_info.totalBytesXfer = 0L;
   reg_cmd_info.failbits = 0;
   reg_cmd_info.drqPackets = 0L;
   reg_cmd_info.cmd = CMD_PACKET;
   reg_cmd_info.fr1 = ucFrReg;
   reg_cmd_info.sc1 = ucScReg;
   reg_cmd_info.sn1 = ucSnReg;
   reg_cmd_info.cl1 = ucCylLow;
   reg_cmd_info.ch1 = ucCylHigh;
   reg_cmd_info.dh1 = ucDevHead;
   reg_cmd_info.dc1 = ucDevCtrl;

   //
   // Set up all the registers except the command register.
   //

   while (1)
   {
      ucStatus = ATAReadCommandRegister( STATUSREGISTER );

      //
      // Wait for BSY=0 & DRQ=0
      //
	if (!(ucStatus & (ATABSY | ATADRQ)))     	
		break;
   }

  
   ATAWriteControlRegister( DEVICECONTROLREGISTER, ucDevCtrl );
   ATAWriteCommandRegister( FEATURESREGISTER, ucFrReg );
   ATAWriteCommandRegister( SECTORCOUNTREGISTER, ucScReg );
   ATAWriteCommandRegister( SECTORNUMBERREGISTER, ucSnReg );
   ATAWriteCommandRegister( CYLINDERLOWREGISTER, ucCylLow );
   ATAWriteCommandRegister( CYLINDERHIGHREGISTER, ucCylHigh );
   ATAWriteCommandRegister( DEVICEHEADREGISTER, ucDevHead );

   //
   // Start the command by setting the Command register.  The drive
   // should immediately set BUSY status. Write 0xA0 ATA command
   //
   ATAWriteCommandRegister( COMMANDREGISTER, CMD_PACKET );

   //
   // Command packet transfer...
   // Check for protocol failures,
   // the device should have BSY=1 now but any number of
   // strange things can happen on ATAPI devices:
   // 1) the device may not set BSY=1 or DRQ=1 for awhile.
   // 2) the device may go directly to DRQ=1 status,
   // 3) the device may reject the command (maybe it is
   //    not really an ATAPI device or has some error).
   //

  while ( 1 )
   {
      ucStatus = ATAReadCommandRegister( STATUSREGISTER );
      
      //
      // BSY = 1, that's ok
      //
      if ( ucStatus & ATABSY )
         break; 

      //
      // BSY = 0
      //
      else
      {

         //
         // DRQ = 1, that's Ok
         //
         if ( ucStatus & ATADRQ )
            break;

         //
         // ERR = 1, error, this is Ok
         //               
         if ( ucStatus & ATAERR )
         {   
		reg_cmd_info.ec = 77;
		break;
	   }

         //
         // This is not Ok
         //
         reg_cmd_info.failbits |= FAILBIT0;
      }
   }

   while ( 1 )
   {
	ucReason = ATAReadCommandRegister( SECTORCOUNTREGISTER );

      //
      // CoD = 1, I/O = 1
      //
	if ((ucReason & (CB_SC_P_IO | CB_SC_P_CD)) == CB_SC_P_CD)
		break;
   }
   
   //
   // Command packet transfer...
   // Poll Alternate Status for BSY=0.
   //

   while ( 1 )
   {
      //
      // Poll for not busy, was ASTAT
      //
      ucStatus = ATAReadCommandRegister( STATUSREGISTER ); 
      if ( ( ucStatus & ATABSY ) == 0 )
         break;
   }

   //
   // Command packet transfer...
   // If no error, transfer the command packet.
   //

   if ( reg_cmd_info.ec == 0 )
   {
      //
      // Command packet transfer...
      // Read the primary status register and the other ATAPI registers.
      //
      ucStatus = ATAReadCommandRegister( STATUSREGISTER );
      ucReason = ATAReadCommandRegister( SECTORCOUNTREGISTER );
      ucLowCyl = ATAReadCommandRegister( CYLINDERLOWREGISTER );
      ucHighCyl = ATAReadCommandRegister( CYLINDERHIGHREGISTER );

      //
      // Command packet transfer...
      // check status: must have BSY=0, DRQ=1 now
      //
      if ( ( ucStatus & ( ATABSY | ATADRQ ) ) != ATADRQ )
      {
         reg_cmd_info.ec = 52;

         //
         // command done
         //
         uiTransferDir = -1;
      }
      else
      {
       ulCount = ATAWriteDataRegister( cfp, uiCommandPacketByteCount >> 1 );
      }
   }

   while ( 1 )
   {
	ucStatus = ATAReadCommandRegister( STATUSREGISTER );

      //
      //wait for BSY to clear
      //
	if (!(ucStatus & ATABSY))			
		break;
   }

   ucStatus = ATAReadCommandRegister( STATUSREGISTER );

   //
   // If data transfer
   //
   if (ucStatus & ATADRQ)				
   {
      //
      // Data transfer loop
      //
	while (1)
	{
         ucReason = ATAReadCommandRegister( SECTORCOUNTREGISTER );
           
            //
            // Device has set amount to transfer in these registers
            // 	
            ucLowCyl = ATAReadCommandRegister( CYLINDERLOWREGISTER );
      	ucHighCyl = ATAReadCommandRegister( CYLINDERHIGHREGISTER );

         //
	   // write to memory buffer here and increment memory pointer by byte count
         //
	   usByteCount = (ucHighCyl << 8) | ucLowCyl; 
	   usWordCount = (usByteCount >> 1) + (usByteCount & 0x0001);
	   ulCount = ATAReadDataRegister(data_pointer,usWordCount);
	   ulTotalTransfered += ulCount;
		
	   ucStatus = ATAReadCommandRegister( STATUSREGISTER );
	   if(!(ucStatus & (ATABSY | ATADRQ)))
	   {
		break;
	   }
	} 
   }
   
   //
   // Set IO, CD, DRY; Clear BSY, DRQ
   //
   while ( 1 )
   {
	ucStatus = ATAReadCommandRegister( STATUSREGISTER );
	ucReason = ATAReadCommandRegister( SECTORCOUNTREGISTER );
	if (ucStatus & ATABSY)
	{
	}
	else
	{
         //
         // DRDY = 1 and DRQ = 0
         //
	   if ((ucStatus & (ATADRDY | ATADRQ)) == ATADRDY)

            //
            // IO = 1, and CD = 1
            //
	      if (ucReason & (CB_SC_P_IO | CB_SC_P_CD) == (CB_SC_P_IO | CB_SC_P_CD))
		   break;
	}
   }

   ucStatus = ATAReadCommandRegister( STATUSREGISTER );
   if ( reg_cmd_info.ec )
      return 1;
   else
   return 0;
}

⌨️ 快捷键说明

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