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

📄 nwatadrv.c

📁 ks8695的ide硬盘程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        return (ERROR);

    semTake (&pCtrl->muteSem, WAIT_FOREVER);

    switch (function)
	{
	case FIODISKFORMAT:
	    /*(void) errnoSet (S_ioLib_UNKNOWN_REQUEST);*/
	    break;

	default:
	    /*(void) errnoSet (S_ioLib_UNKNOWN_REQUEST);*/
	    break;
	}

    semGive (&pCtrl->muteSem);
    return (status);
    }

/*******************************************************************************
*
* ataBlkRW - read or write sectors to a ATA/IDE disk.
*
* Read or write sectors to a ATA/IDE disk.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/

LOCAL STATUS ataBlkRW(ATA_DEV *pDev,int startBlk,int nBlks,char *pBuf,int direction)
{
    ATA_CTRL *pCtrl	= &ataCtrl[pDev->ctrl];
    ATA_DRIVE *pDrive	= &pCtrl->drive[pDev->drive];
    BLK_DEV *pBlkdev	= &pDev->blkDev;
    int status		= ERROR;
    int retryRW0	= 0;
    int retryRW1	= 0;
    int retrySeek	= 0;
    int cylinder;
    int head;
    int sector;
    int nSecs;
    int ix;

    /* sanity check */

    if (!pCtrl->installed)
        return (ERROR);

    nSecs = ataLbaTotalSecs[pDev->ctrl][pDev->drive];//pBlkdev->bd_nBlocks;
//	printErr ("startBlk=%d nBlks=%d: nSecs=%d\n", startBlk, nBlks, nSecs);
    if ((startBlk + nBlks) > nSecs)
	{
//#ifdef	ATA_DEBUG
	printf("startBlk=%d nBlks=%d: 0 - %d\n", startBlk, nBlks, nSecs);
//#endif	/* ATA_DEBUG */
	return (ERROR);
	}

  startBlk += pDev->blkOffset;

  semTake (&pCtrl->muteSem, WAIT_FOREVER);

  for (ix = 0; ix < nBlks; ix += nSecs)
	{
	  if (pDrive->okLba)
	  {
	    head     = (startBlk & 0xff000000) >> 24;//modify from 0x0f000000 to 0xff000000 2005-6-22 16:25 by wb
	    cylinder = (startBlk & 0x00ffff00) >> 8;
	    sector   = (startBlk & 0x000000ff);
	  }
	  else
	  {
      cylinder = startBlk / (pBlkdev->bd_blksPerTrack * pBlkdev->bd_nHeads);
	    sector   = startBlk % (pBlkdev->bd_blksPerTrack * pBlkdev->bd_nHeads);
	    head     = sector / pBlkdev->bd_blksPerTrack;
	    sector   = sector % pBlkdev->bd_blksPerTrack + 1;
	  }
	  nSecs    = min (nBlks - ix, ATA_MAX_RW_SECTORS);
	  
	  retryRW1 = 3;
	  retryRW0 = 3;
	  while (ataRW(pDev->ctrl, pDev->drive, cylinder, head, sector, 
	       pBuf, nSecs, direction) != OK)
	  {
	    if (++retryRW0 > ataRetry)
		  {
	      (void)ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_RECALIB, 0,0);
        if (++retryRW1 > ataRetry)
		      goto done;
	      retrySeek = 0;
	      while (ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_SEEK, cylinder,head) != OK)
	      if (++retrySeek > ataRetry)
		      goto done;
	      retryRW0 = 0;
		  }
	  }
    startBlk += nSecs;
    pBuf += pBlkdev->bd_bytesPerBlk * nSecs;
	}
  status = OK;

done:
  if (status == ERROR)
    /*(void)errnoSet (S_ioLib_DEVICE_ERROR);*/
  semGive (&pCtrl->muteSem);
    return (status);
}

/*******************************************************************************
*
* ataIntr - ATA/IDE controller interrupt handler.
*
* RETURNS: N/A
*/

LOCAL void ataIntr(int ctrl)
    {
    ATA_CTRL *pCtrl;
	char atpStatus =0;
	unsigned int isr;
	KS8695P_REG_READ (REG_INT_STATUS, isr);
	/* if not ours, simply return */
    if ((isr & REG_INT_EXTI1) == 0)
       return ;
    //logMsg("go here intr wangb !\n",1,2,3,4,5,6);   
	/* disable interrupt first */
    KS8695P_REG_BIT_CLR (REG_INT_ENABLE, REG_INT_EXTI1);
	/* ACK */
	KS8695P_REG_WRITE(REG_INT_STATUS, REG_INT_EXTI1);
  pCtrl	= &ataCtrl[ctrl];
    //pCtrl->intCount++;
  //pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);
    
/*
	atpStatus = ATA_IO_BYTE_READ( busMasterRegs[ctrl] + BM_STATUS_REG);
	if (atpStatus & 0x4)
		ATA_IO_BYTE_WRITE(busMasterRegs[ctrl]+BM_STATUS_REG,atpStatus);	
*/
    semGive (&pCtrl->syncSem);
    KS8695P_REG_BIT_SET (REG_INT_ENABLE, REG_INT_EXTI1);
    }

/*******************************************************************************
*
* ataWdog - ATA/IDE controller watchdog handler.
*
* RETURNS: N/A
*/

LOCAL void ataWdog
    (
    int ctrl
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];

    pCtrl->wdgOkay = FALSE;
    }

/*******************************************************************************
*
* ataWait - wait the drive ready
*
* Wait the drive ready
*
* RETURNS: OK, ERROR if the drive didn't become ready in certain period of time.
*/

LOCAL void ataWait(int ctrl,int request)
{
    unsigned char tempData =0;
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];

#ifdef	ATA_DEBUG
    printErr ("ataWait: ctrl=%d  request=0x%x\n", ctrl, request);
#endif	/* ATA_DEBUG */

    switch (request)
	{
	case ATA_STAT_READY:
	    wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 
		     (FUNCPTR)ataWdog, ctrl);
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) && 
		   (pCtrl->wdgOkay))
	        ;
	        tempData = ATA_IO_BYTE_READ (pCtrl->aStatus);
            while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0)
                   && (pCtrl->wdgOkay))
	        ;
	    wdCancel (pCtrl->wdgId);

            if (!pCtrl->wdgOkay)
	        {
	        pCtrl->wdgOkay = TRUE;
	        (void) ataInit (ctrl);
	        }
	    break;

	case ATA_STAT_BUSY:
            while (ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY)
		;
	    break;

	case ATA_STAT_DRQ:
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) == 0)
	        ;
	    break;

	case ATA_STAT_SEEKCMPLT:
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_SEEKCMPLT) == 0)
	        ;
	    break;
	}

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

/*******************************************************************************
*
* ataInit - init a ATA/IDE disk controller
*
* This routine initializes a ATA/IDE disk controller.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/

LOCAL STATUS ataInit
    (
    int ctrl
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
    int ix;

#ifdef	ATA_DEBUG
    printErr ("ataInit: ctrl=%d\n", ctrl);
#endif	/* ATA_DEBUG */

/*del by wangb 2005-11-2 14:57
    ATA_IO_BYTE_WRITE (pCtrl->dControl,
                       ATA_CTL_4BIT | ATA_CTL_RST | ATA_CTL_IDS);
    for (ix = 0; ix < 100; ix++)
        ideDelayFun ();

    ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT | ATA_CTL_IDS);
    for (ix = 0; ix < 100; ix++)
        ideDelayFun ();*/
/* add by wangb 2005-11-2 14:57 */        
    ATA_IO_BYTE_WRITE (pCtrl->dControl,
                       ATA_CTL_RST | ATA_CTL_IDS);

    for (ix = 0; ix < 100; ix++)
        ideDelayFun ();    
        
    ATA_IO_BYTE_WRITE (pCtrl->dControl,  ATA_CTL_IDS);
    for (ix = 0; ix < 100; ix++)
        ideDelayFun ();    
/* end by wangb 2005-11-2 14:57 */
    pCtrl->wdgOkay = TRUE;

    /* start the ata  watchdog */

    wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),
	     (FUNCPTR)ataWdog, ctrl);

    while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) &&
           (pCtrl->wdgOkay))
	;

//     ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT);
     ATA_IO_BYTE_WRITE (pCtrl->dControl, 0);
   for (ix = 0; ix < 100; ix++) 
        ideDelayFun ();

    while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0) &&
	   (pCtrl->wdgOkay))
	;

    wdCancel (pCtrl->wdgId);

    if (!pCtrl->wdgOkay)
        {
#ifdef	ATA_DEBUG
	printErr ("ataInit error:\n");
#endif	/* ATA_DEBUG */
        pCtrl->wdgOkay = TRUE;
        return (ERROR);
        }
#ifdef  ATA_DEBUG
        printErr ("ataInit Calling sysAtaInit (if present):\n");
#endif  /* ATA_DEBUG */

    /* Call out to bsp specific setup routine */
    SYS_ATA_INIT_RTN (ctrl);

#ifdef  ATA_DEBUG
        printErr ("ataInit sysAtaInit returned:\n");
#endif  /* ATA_DEBUG */

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

    return (OK);
    }

/*******************************************************************************
*
* ataCmd - issue non data command
*
* Issue a non data command.  Non data commands have the same protocol.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/

LOCAL STATUS ataCmd(int ctrl,int drive,int cmd,int arg0,int arg1)
{
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
    ATA_TYPE *pType	= &ataTypes[ctrl][drive];
    BOOL retry		= TRUE;
    int retryCount	= 0;
    int semStatus;

#ifdef	ATA_DEBUG
    printErr ("ataCmd: ctrl=%d drive=%d cmd=0x%x\n", ctrl, drive, cmd);
#endif	/* ATA_DEBUG */

    while (retry)
	{
        ataWait (ctrl, ATA_STAT_READY);
        ATA_IO_BYTE_WRITE (pCtrl->sdh,  (drive << 4));
        taskDelay(0);
        ataWait (ctrl, ATA_STAT_READY);

	switch (cmd)
	    {
	    case ATA_CMD_DIAGNOSE:
        	ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
		break;
	    case ATA_CMD_INITP:
		ATA_IO_BYTE_WRITE (pCtrl->cylLo, pType->cylinders);
		ATA_IO_BYTE_WRITE (pCtrl->cylHi, pType->cylinders >> 8);
		ATA_IO_BYTE_WRITE (pCtrl->seccnt, pType->sectors);
		ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) | 
			    ((pType->heads - 1) & 0x0f));
		break;
	    case ATA_CMD_RECALIB:
		ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
		break;
	    case ATA_CMD_SEEK:
		ATA_IO_BYTE_WRITE (pCtrl->cylLo, arg0);
		ATA_IO_BYTE_WRITE (pCtrl->cylHi, arg0>>8);
		ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) |
			    (arg1 & 0xf));
		break;
	    case ATA_CMD_SET_FEATURE:
        	ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg1);
        	ATA_IO_BYTE_WRITE (pCtrl->feature, arg0);
        	ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
		break;
	    case ATA_CMD_SET_MULTI:
        	ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg0);
        	ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
		break;
	    }

        ATA_IO_BYTE_WRITE (pCtrl->command, cmd);
        semStatus = semTake (&pCtrl->syncSem, 
			     sysClkRateGet() * pCtrl->semTimeout);
		pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);//add by wangb 2005-11-8 8:56
        if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
	    {
#ifdef	ATA_DEBUG
            int error = ATA_IO_BYTE_READ(pCtrl->error);
	    printErr ("ataCmd err: status=0x%x semStatus=%d err=0x%x\n", 
		      pCtrl->intStatus, semStatus, error);
#endif	/* ATA_DEBUG */
	    if (++retryCount > ataRetry)
	        return (ERROR);
	    }
	else
	    retry = FALSE;
	}

	switch (cmd)
	    {
	    case ATA_CMD_SEEK:
		ataWait (ctrl, ATA_STAT_SEEKCMPLT);
		break;
	    }

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

    return (OK);
    }

/*******************************************************************************
*
* ataPread - Read drive parameters
*
* Read drive parameters.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/

LOCAL STATUS ataPread(int ctrl,int drive,void *buffer)
{
  ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
  BOOL retry		= TRUE;
  int retryCount	= 0;
  int semStatus;

#ifdef	ATA_DEBUG
  printErr ("ataPread: ctrl=%d drive=%d\n", ctrl, drive);
	printErr ("drive << 4,0x%x\n",(drive<<4));
#endif	/* ATA_DEBUG */
/*by youyan 2005-11-21 10:32
  while (retry)
	{
	 
    ataWait(ctrl, ATA_STAT_READY); */
    ATA_IO_BYTE_WRITE (pCtrl->sdh, (drive << 4));
    ataWait (ctrl, ATA_STAT_READY);
    ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
    ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READP);
    semStatus = semTake (&pCtrl->syncSem,sysClkRateGet() * pCtrl->semTimeout);
		pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);//add by wangb 2005-11-8 8:56
    if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
    {
#ifdef	ATA_DEBUG
	    int error	= ATA_IO_BYTE_READ (pCtrl->error);
	    int status	= ATA_IO_BYTE_READ (pCtrl->aStatus);
      printErr ("ataPread err: stat=0x%x 0x%x semStatus=%d err=0x%x\n",
	              pCtrl->intStatus, status, semStatus, error);
#endif	/* ATA_DEBUG */
/*by youyan2005-11-21 10:32
	    if (++retryCount > ataRetry)
	    */
	      return (ERROR);
	  }
    else
	    retry = FALSE;
/*  }*/

  ataWait (ctrl, ATA_STAT_DRQ);

  ATA_IO_NWORD_READ_SWAP (pCtrl->data, (short *)buffer, 256);

#ifdef	ATA_DEBUG
  printErr ("ataPread end:\n");
#endif	/* ATA_DEBUG */
  return (OK);
}

/*******************************************************************************
*
* ataRW - 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.
*/

⌨️ 快捷键说明

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