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

📄 atadrv.c

📁 用于EQUATOR处理器上的FAT32文件系统(vxWorks5.5)
💻 C
📖 第 1 页 / 共 5 页
字号:



	    pBuf     += nWords;
	    nSectors -= block;
	    }
	}

#ifdef	ATA_DEBUG
    printErr ("ataRW: end\n");
#endif	/* ATA_DEBUG */

    return (OK);

errorRW:
#ifdef	ATA_DEBUG
    {
    int error	= ATA_IO_BYTE_READ (pCtrl->error);
    int status	= ATA_IO_BYTE_READ (pCtrl->aStatus);
	int ideStatus = sysInByte( busMasterRegs[ctrl] + BM_STATUS_REG);
    printf ("ataRW err: stat=0x%x 0x%x semStatus=%d error=0x%x errorno 0x%x,ideStatus 0x%x\n",
	      pCtrl->intStatus, status, semStatus, error,errno,ideStatus);
    printf("sysClkRateGet=%d timeout=%d\n",sysClkRateGet(),sysClkRateGet() * pCtrl->semTimeout);
    
    }
#endif	/* ATA_DEBUG */
    if (++retryCount < ataRetry)
	goto retryRW;
    return (ERROR);
    }

/*******************************************************************************
*
* ataDmaRW - read/write a number of sectors on the current track
*
* Read/write a number of sectors on the current track
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/
//efine ATA_PERFORMANCE
LOCAL STATUS ataDmaRW
    (
    int ctrl,
    int drive,
    int cylinder,
    int head,
    int sector,
    void *buffer,
    int nSecs,
    int direction
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
    ATA_DRIVE *pDrive	= &pCtrl->drive[drive];
    ATA_TYPE *pType	= &ataTypes[ctrl][drive];
    int retryCount	= 0;
    int semStatus;
//    struct timespec wait200ns;
    int i;
    unsigned char tmp;
    STATUS status;

#ifdef ATA_PERFORMANCE
    int startTick,endTick;   
#endif

//    wait200ns.tv_sec = 0;
//    wait200ns.tv_nsec = 200;

#ifdef	ATA_DEBUG
    printErr ("ataDmaRW: ctrl=%d drive=%d c=%d h=%d s=%d buf=0x%x n=%d dir=%d\n",
              ctrl, drive, cylinder, head, sector, 
	      (int)buffer, nSecs, direction);
#endif	/* ATA_DEBUG */

retryDmaRW:

    status = ataDmaSetupXfer(ctrl,direction,buffer,nSecs*pType->bytes);
    
    if (status != OK)
     return status;

    ataWait(ctrl, ATA_STAT_READY);
    
    ATA_IO_BYTE_WRITE (pCtrl->sdh,
                           (drive << 4));
 

//    ataWait (ctrl, ATA_STAT_READY);

    ATA_IO_BYTE_WRITE (pCtrl->seccnt, nSecs);
  
    ATA_IO_BYTE_WRITE (pCtrl->sector, sector);
   
    ATA_IO_BYTE_WRITE (pCtrl->cylLo, cylinder);
   
    ATA_IO_BYTE_WRITE (pCtrl->cylHi, cylinder>>8);
      
    if (pDrive->okLba)
        ATA_IO_BYTE_WRITE (pCtrl->sdh,
                           ATA_SDH_LBA | (drive << 4) | (head & 0xf));
    else
        ATA_IO_BYTE_WRITE (pCtrl->sdh,
                           ATA_SDH_IBM | (drive << 4) | (head & 0xf));

    if (direction == O_WRONLY)
	{

#ifdef ATA_PERFORMANCE
        startTick = hmpv_read_fcnt();
#endif

	    ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_DMA_WRITE);


//        ataWait (ctrl, ATA_STAT_DRQ);
        enableChan(ctrl);

  
        semStatus = semTake (&pCtrl->syncSem, 
				             sysClkRateGet() * pCtrl->semTimeout);
    	if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
	       goto errorDmaRW;



         for (i=0;i<1000;i++)
          {

  //          nanosleep(&wait200ns,NULL);
            tmp = sysInByte( busMasterRegs[ctrl] + BM_STATUS_REG);
            if (tmp & 0x4) {
              break;
            }

          taskDelay(0);
            
          }

#ifdef ATA_PERFORMANCE
        endTick = hmpv_read_fcnt();
#endif

 //       disableChan();
 //       clearChan();

  
 //       ATA_IO_BYTE_READ (pCtrl->status);

        
	  
            
	}
    else
	{

#ifdef ATA_PERFORMANCE
        startTick = hmpv_read_fcnt();
#endif

        ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_DMA_READ);

//        ataWait(ctrl,ATA_STAT_DRQ);

        enableChan(ctrl);   
	 
        semStatus = semTake (&pCtrl->syncSem, 
                              sysClkRateGet() * pCtrl->semTimeout);

 
    	 if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR)) {
         disableChan(ctrl);
         clearChan(ctrl);
         tmp = ATA_IO_BYTE_READ (pCtrl->status);
	        goto errorDmaRW;
         }
 

         //
         // Wait for DMA Master to finsh
         //
           
         for (i=0;i<1000;i++)
          {
        //    nanosleep(&wait200ns,NULL);

            tmp = sysInByte( busMasterRegs[ctrl] + BM_STATUS_REG);
            if (tmp & 0x4) {
              break;
            }

            taskDelay(0);
            
          }

#ifdef ATA_PERFORMANCE
         endTick = hmpv_read_fcnt();
#endif

//         disableChan();
//         clearChan();
//         tmp = ATA_IO_BYTE_READ (pCtrl->status);


     
	    
	}

#ifdef	ATA_DEBUG
    printErr ("ataDmaRW: end\n");
    if (direction == O_WRONLY )
      printf("Wrote %d bytes\n",nSecs*pType->bytes);
    else
      printf("Read %d bytes.\n",nSecs*pType->bytes);
#endif	/* ATA_DEBUG */

#ifdef ATA_PERFORMANCE
     {
     float count,MBps;
     if (endTick > startTick)
      count = endTick - startTick;
     else
      count = 0xFFFFFFF - startTick + endTick;

     MBps = nSecs*pType->bytes/(count/CPU_MHZ);

     if (direction == O_WRONLY )
        printf("Wrote %d bytes. MBps %f\n",nSecs*pType->bytes,MBps);
     else
       printf("Read %d bytes. MBps %f\n",nSecs*pType->bytes,MBps);
     } 
#endif

    return (OK);

errorDmaRW:
#ifdef ATA_DEBUG
    {
    int error	= ATA_IO_BYTE_READ (pCtrl->error);
    int status	= ATA_IO_BYTE_READ (pCtrl->aStatus);
    printErr ("ataDmaRW err: stat=0x%x 0x%x semStatus=%d error=0x%x errorno 0x%x\n",
	      pCtrl->intStatus, status, semStatus, error,errno);
    printErr("sysClkRateGet=%d timeout=%d\n",sysClkRateGet(),sysClkRateGet() * pCtrl->semTimeout);
    
    }
#endif	/* ATA_DEBUG */

    if (++retryCount < ataRetry)
      goto retryDmaRW;
    return (ERROR);
    }



static  PRD_ENTRY prdTable[2][MAX_PRD_ENTRIES];
//***********************************************************
//
// ataDmaSetupXfer() -- set up 1, 2 or 3 PRD
//
//*********************************************************** 
static STATUS ataDmaSetupXfer(int ctrl, int dir, char *addr, int count)

{
   PPRD_ENTRY prdEntry;
   int numBytes;

   
   // disable/stop the dma channel, clear interrupt and error bits

   disableChan(ctrl);
   clearChan(ctrl);


   if (count/MAX_TRANSFER + 2 > MAX_PRD_ENTRIES) {
    printf("ERROR: too many dma bytes 0x%x, expand table!!!!!\n",count);
    return ERROR;
   }

   prdEntry = &prdTable[ctrl][0];

   //
   // build prd table
   // each entry cannot cross a 64Kbyte bountry so...
   //

#if 0
   while (TRUE) {

      prdEntry->address = addr;


      if (count <= MAX_TRANSFER) {
         prdEntry->bits.count = count;
         prdEntry->bits.EOT = 1;
         break;
      } else  {
         prdEntry->bits.count = MAX_TRANSFER;
         prdEntry->bits.EOT = 0;
      }
      count -= MAX_TRANSFER;         
      addr  += MAX_TRANSFER;

      prdEntry++;
   }

#endif

   while (TRUE) {


      prdEntry->address = addr;

      numBytes = 0x10000 - ((int)addr & 0xFFFF);

      if (numBytes > count) {
         prdEntry->bits.count = count;
         prdEntry->bits.EOT = 1;
         break;
      } else  {
         prdEntry->bits.count = numBytes;
         prdEntry->bits.EOT = 0;
      }
      count -= numBytes;         
      addr  += numBytes;

      prdEntry++;
   }
   // set the prd list address

   sysOutLong(busMasterRegs[ctrl] + BM_PRD_ADDR,(ULONG)&prdTable[ctrl][0]);
 
    

   // set the read/write control:

   if ( dir ==  O_WRONLY)
      rwControl[ctrl] = BM_CR_MASK_WRITE;     // ATA Write DMA
   else 
      rwControl[ctrl] = BM_CR_MASK_READ;    // ATA Read DMA
 
   return OK; 
}

//***********************************************************
//
// ataDmaConfig() - configure/setup for Read/Write DMA
//
// The caller must call this function before attempting
// to use any ATA or ATAPI commands in PCI DMA mode.
//
//***********************************************************

int ataDmaConfig(int ctrl,UINT32 regAddr )

{
   // save the address of the bus master (SFF-8038) regs

   busMasterRegs[ctrl] = regAddr;

   sysOutByte(busMasterRegs[ctrl]+BM_STATUS_REG,BM_SR_MASK_DRV0 | BM_SR_MASK_INT);

   // the bus master must be setup now

 
   // read the BM status reg and save the upper 3 bits.

   statReg[ctrl] = sysInByte( busMasterRegs[ctrl] + BM_STATUS_REG );
   statReg[ctrl] = statReg[ctrl] & 0xe0;

   return 0;
}

static void ataPrintSpeed(char speed)
{
	printf("Configured drive for \n");
	switch(speed) {
		
    case ATA_DMA_ULTRA_W_0:
		printf("ultra DMA mode 0\n");
		break;
    case ATA_DMA_ULTRA_W_1:
		printf("ultra DMA mode 1\n");
		break;
    case ATA_DMA_ULTRA_W_2:
		printf("ultra DMA mode 2\n");
		break;
    case ATA_DMA_ULTRA_W_3:
		printf("ultra DMA mode 3\n");
		break;
    case ATA_DMA_ULTRA_W_4:
		printf("ultra DMA mode 4\n");
		break;
    case ATA_DMA_MULTI_W_0:
		printf("multiword DMA mode 0\n");
		break;
    case ATA_DMA_MULTI_W_1:
		printf("multiword DMA mode 1\n");
		break;
    case ATA_DMA_MULTI_W_2:
		printf("multiword DMA mode 2\n");
		break;
	case ATA_DMA_SINGLE_W_0:
		printf("singleword DMA mode 0\n");
		break;
    case ATA_DMA_SINGLE_W_1:
		printf("singleword DMA mode 1\n");
		break;
	case ATA_DMA_SINGLE_W_2:
		printf("singleword DMA mode 2\n");
		break;
    default:
		printf("unknown speed\n");
	}
}

extern STATUS usrFdiskPartRead();

STATUS
AtaMount(
   int     ctrl,	/* 0: primary address, 1: secondary address */
   int     drive,	/* drive number of hard disk (0 or 1) */
   char *  filename   /* mount point */
 )
{
  BLK_DEV *pBlkDev;
  CBIO_DEV_ID *pCbio, pCbioParts;
  char Devs[6];
  int i;

  /* create the device */
  if( !(pBlkDev=ataDevCreate( ctrl, drive, 0, 0)) ) 
    {
    printf( "Error creating device\n" );
    return ERROR;
    }

  /* creat cache for accessing the device */
  if ( (pCbio = dcacheDevCreate(pBlkDev, NULL, DISK_CACHE_SIZE, "master")) == NULL)
    {
    printf( "Error creating disk cache\n" );
    return ERROR;
    }


  /* create partition manager */
  if ( (pCbioParts = dpartDevCreate(pCbio, NUM_DISK_PARTITIONS, usrFdiskPartRead)) == NULL)
    {
    printf( "Error creating disk cache\n" );
    return ERROR;
    }
  
  for (i=0; i<NUM_DISK_PARTITIONS; i++)
    {
      //sprintf(&Devs[0], "%s%d:",filename, i);
      if (ctrl==0) sprintf(&Devs[0], "dev%d:", i);
      else sprintf(&Devs[0],"cf%d:",(2+i));
      printf("mounting %s\n",Devs);
      dosFsDevCreate(Devs, dpartPartGet(pCbioParts, i), NUM_DOSFS_FILES, NONE);
    }
}

⌨️ 快捷键说明

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