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

📄 nwatadrv.c

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

	      (void) ataCmd (ctrl, drive, ATA_CMD_RECALIB, 0, 0);

	      /* find out supported capabilities of the drive */

	      pDrive->multiSecs = pParam->multiSecs & 0x00ff;
	      pDrive->okMulti = (pDrive->multiSecs) ? TRUE : FALSE;
	      pDrive->okIordy = (pParam->capabilities & 0x0800) ? TRUE : FALSE;
	      pDrive->okLba   = (pParam->capabilities & 0x0200) ? TRUE : FALSE;
	      pDrive->okDma   = (pParam->capabilities & 0x0100) ? TRUE : FALSE;

	      /* find out supported max PIO mode */

	      pDrive->pioMode = (pParam->pioMode >> 8) & 0x03;	/* PIO 0,1,2 */
	      if (pDrive->pioMode > 2)
	        pDrive->pioMode = 0;

	      if ((pDrive->okIordy) && (pParam->valid & 0x02))	/* PIO 3,4 */
		    {
		      if (pParam->advancedPio & 0x01)
		        pDrive->pioMode = 3;
		      if (pParam->advancedPio & 0x02)
		        pDrive->pioMode = 4;
		    }

	      /* find out supported max DMA mode */

		    if (pParam->multiDma & 0x04)
		      pDrive->multiDmaMode = 2;
		    else if (pParam->multiDma & 0x02)
		      pDrive->multiDmaMode = 1;
		    else if (pParam->multiDma & 0x01)
		      pDrive->multiDmaMode = 0;
        else pDrive->multiDmaMode = -1;
  
        /* Is Ultra DMA supported */
        
        if (pParam->valid & 0x04)
        {
          if (pParam->ultraDma & 0x40)
		        pDrive->ultraDmaMode = 6;
		      else if (pParam->ultraDma & 0x20)
		        pDrive->ultraDmaMode = 5;
		      else if (pParam->ultraDma & 0x10)
		        pDrive->ultraDmaMode = 4;
		      else if (pParam->ultraDma & 0x08)
		        pDrive->ultraDmaMode = 3;
		      else if (pParam->ultraDma & 0x04)
		        pDrive->ultraDmaMode = 2;
		      else if (pParam->ultraDma & 0x02)
		        pDrive->ultraDmaMode = 1;
		      else if (pParam->ultraDma & 0x01)
		        pDrive->ultraDmaMode = 0;
        }
        else
           pDrive->ultraDmaMode = -1;

        if (pDrive->ultraDmaMode == -1 &&
            pDrive->multiDmaMode == -1)
            pDrive->okDma = FALSE;
        else
            pDrive->okDma = TRUE;
		
	      /* find out transfer mode to use */
      
	      pDrive->rwBits = configType & ATA_BITS_MASK;
	      pDrive->rwPio  = configType & ATA_PIO_MASK;
	      pDrive->rwDma  = configType & ATA_DMA_MASK;
	      pDrive->rwMode = ATA_PIO_DEF_W;
        /*added by youyan 2005-11-19 11:07*/
        pDrive->status = ATA_ACTIVE_MODE; /*active mode*/
        /*end of added by youyan 2005-11-19 11:07*/
      
/* add by wangb 2005-11-2 14:43 */
		
		    switch (configType & ATA_MODE_MASK)
		    {
		      case ATA_PIO_0:
      		case ATA_PIO_1:
      		case ATA_PIO_2:
      		case ATA_PIO_3:
      		case ATA_PIO_4:
      		case ATA_PIO_DEF_0:
      		case ATA_PIO_DEF_1:
	          pDrive->rwMode = configType & ATA_MODE_MASK;
		        break;
      		case ATA_PIO_AUTO:
	          pDrive->rwMode = ATA_PIO_W_0 + pDrive->pioMode;
		        break;
        }

        if(pDrive->okDma)
       	switch (configType & ATA_DMA_MODE_MASK)
		    {
		      case ATA_DMA_MULTI_0:
            pDrive->rwDma = ATA_DMA_MULTI_W_0;
            break;
      		case ATA_DMA_MULTI_1:
            pDrive->rwDma = ATA_DMA_MULTI_W_1;
            break;
		      case ATA_DMA_MULTI_2:
            pDrive->rwDma = ATA_DMA_MULTI_W_2;
            break;
		      case ATA_DMA_ULTRA_0:
            pDrive->rwDma = ATA_DMA_ULTRA_W_0;
            break;
		      case ATA_DMA_ULTRA_1:
            pDrive->rwDma = ATA_DMA_ULTRA_W_1;
            break;
		      case ATA_DMA_ULTRA_2:
            pDrive->rwDma = ATA_DMA_ULTRA_W_2;
            break;
		      case ATA_DMA_ULTRA_3:
            pDrive->rwDma = ATA_DMA_ULTRA_W_3;
            break;
		      case ATA_DMA_ULTRA_4:
            pDrive->rwDma = ATA_DMA_ULTRA_W_4;
            break;
		      case ATA_DMA_ULTRA_5:
            pDrive->rwDma = ATA_DMA_ULTRA_W_5;
            break;
		      case ATA_DMA_AUTO:
#if 1
		        if (pDrive->ultraDmaMode != -1)
	            pDrive->rwDma = ATA_DMA_ULTRA_W_0 + pDrive->ultraDmaMode;
#endif
		        else if (pDrive->multiDmaMode != -1)
	            pDrive->rwDma = ATA_DMA_MULTI_W_0 + pDrive->multiDmaMode;
    		    break;
		      default:
            //
            // Turn off dma
            //
            
            pDrive->okDma = FALSE;   
		        break;
		    } //end switch
/* end by wangb 2005-11-2 14:44 */
	    /* set the transfer mode */
		    if (pDrive->okDma)
        {
        	//logMsg("go here okDma!\n",1,2,3,4,5,6);
	    	  ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_SET_RWMODE,pDrive->rwDma);
		    }
		    else
		    {
			    ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_SET_RWMODE,pDrive->rwMode);
			    if (pDrive->rwPio == ATA_PIO_MULTI)
			    {
		        if (pDrive->okMulti)
		          (void) ataCmd (ctrl, drive, ATA_CMD_SET_MULTI,pDrive->multiSecs, 0);
				    else
				      pDrive->rwPio = ATA_PIO_SINGLE;
			    }
  
		    }
      }/*end of for(driver....*/
	    pCtrl->installed = TRUE;

#ifdef  ATA_DEBUG
      printErr ("ataDrv Calling sysAtaInit (if present):\n");
#endif  /* ATA_DEBUG */
 
	/* Call system INIT routine to allow proper PIO mode setup */
      SYS_ATA_INIT_RTN (ctrl);
 
#ifdef  ATA_DEBUG
      printErr ("ataDrv sysAtaInit returned:\n");
#endif  /* ATA_DEBUG */

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

/*******************************************************************************
*
* ataDevCreate - create a device for a ATA/IDE disk
*
* This routine creates a device for a specified ATA/IDE disk.
*
* <drive> is a drive number for the hard drive; it must be 0 or 1.
*
* The <nBlocks> parameter specifies the size of the device in blocks.
* If <nBlocks> is zero, the whole disk is used.
*
* The <blkOffset> parameter specifies an offset, in blocks, from the start
* of the device to be used when writing or reading the hard disk.  This
* offset is added to the block numbers passed by the file system during
* disk accesses.  (VxWorks file systems always use block numbers beginning
* at zero for the start of a device.)
*
*
* RETURNS:
* A pointer to a block device structure (BLK_DEV) or NULL if memory cannot
* be allocated for the device structure.
*
* SEE ALSO: dosFsMkfs(), dosFsDevInit(), rt11FsDevInit(), rt11FsMkfs(),
* rawFsDevInit()
*/

BLK_DEV *ataDevCreate
    (
    int ctrl,
    int drive,
    int nBlocks,
    int blkOffset
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
    ATA_TYPE *pType	= &ataTypes[ctrl][drive];
    ATA_DRIVE *pDrive	= &pCtrl->drive[drive];
    ATA_DEV *pDev;
    BLK_DEV *pBlkdev;
    int	    maxBlks;



    if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||
        !ataDrvInstalled || !pCtrl->installed)
	return (NULL);

    if ((pDev = (ATA_DEV *)malloc(sizeof (ATA_DEV))) == NULL)
	return (NULL);

    pBlkdev = &pDev->blkDev;


    /* 
     * if LBA is supported and ataLbaTotalSecs is not zero
     * and ataLbaTotalSecs is greater than the product of
     * CHS, then we should use the LBA value.
     */

    if ((pDrive->okLba == TRUE)                     && 
   	(ataLbaTotalSecs[ctrl][drive] != 0)         &&
	(ataLbaTotalSecs[ctrl][drive] > 
	(pType->cylinders * pType->heads * pType->sectors)))   
	{
	maxBlks = (ataLbaTotalSecs[ctrl][drive]) - blkOffset;
	}
    else /* just use CHS */
	{
        maxBlks = ((pType->cylinders * pType->heads * pType->sectors) 
			- blkOffset);
	}

    if (nBlocks == 0)
	nBlocks = maxBlks;
    
    if (nBlocks > maxBlks)
	nBlocks = maxBlks;

    pBlkdev->bd_nBlocks		= nBlocks;
    pBlkdev->bd_bytesPerBlk	= pType->bytes;
    pBlkdev->bd_blksPerTrack	= pType->sectors;
    pBlkdev->bd_nHeads		= pType->heads;
    pBlkdev->bd_removable	= TRUE;
    pBlkdev->bd_retry		= 1;
    pBlkdev->bd_mode		= O_RDWR;
    pBlkdev->bd_readyChanged	= TRUE;
    pBlkdev->bd_blkRd		= ataBlkRd;
    pBlkdev->bd_blkWrt		= ataBlkWrt;
    pBlkdev->bd_ioctl		= ataIoctl;
    pBlkdev->bd_reset		= ataReset;
    pBlkdev->bd_statusChk	= ataStatus;
    pBlkdev->bd_reset		= NULL;
    pBlkdev->bd_statusChk	= NULL;
    pDev->ctrl			= ctrl;
    pDev->drive			= drive;
    pDev->blkOffset		= blkOffset;

    return (&pDev->blkDev);
    }

/*******************************************************************************
*
* ataRawio - do raw I/O access
*
* This routine is called to perform raw I/O access.
*
* <drive> is a drive number for the hard drive: it must be 0 or 1.
*
* The <pAtaRaw> is a pointer to the structure ATA_RAW which is defined in 
* ataDrv.h.
*
* RETURNS:
* OK, or ERROR if the parameters are not valid.
*
*/

STATUS ataRawio
    (
    int ctrl,
    int drive,
    ATA_RAW *pAtaRaw
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
    ATA_TYPE *pType	= &ataTypes[ctrl][drive];
    ATA_DEV ataDev;
    BLK_DEV *pBlkdev	= &ataDev.blkDev;
    UINT startBlk;

    if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||
        !ataDrvInstalled || !pCtrl->installed)
	return (ERROR);

    if ((pAtaRaw->cylinder	>= pType->cylinders)	||
        (pAtaRaw->head		>= pType->heads)	||
        (pAtaRaw->sector	>  pType->sectors)	||
        (pAtaRaw->sector	== 0))
	return (ERROR);

    pBlkdev->bd_nBlocks		= pType->cylinders * pType->heads * 
				  pType->sectors;
    pBlkdev->bd_bytesPerBlk	= pType->bytes;
    pBlkdev->bd_blksPerTrack	= pType->sectors;
    pBlkdev->bd_nHeads		= pType->heads;
    pBlkdev->bd_removable	= FALSE;
    pBlkdev->bd_retry		= 1;
    pBlkdev->bd_mode		= O_RDWR;
    pBlkdev->bd_readyChanged	= TRUE;
    pBlkdev->bd_blkRd		= ataBlkRd;
    pBlkdev->bd_blkWrt		= ataBlkWrt;
    pBlkdev->bd_ioctl		= ataIoctl;
    pBlkdev->bd_reset		= ataReset;
    pBlkdev->bd_statusChk	= ataStatus;

    ataDev.ctrl			= ctrl;
    ataDev.drive		= drive;
    ataDev.blkOffset		= 0;

    startBlk = pAtaRaw->cylinder * (pType->sectors * pType->heads) +
	       pAtaRaw->head * pType->sectors + pAtaRaw->sector - 1;

    return (ataBlkRW (&ataDev, startBlk, pAtaRaw->nSecs, pAtaRaw->pBuf,
		     pAtaRaw->direction));
    }

/*******************************************************************************
*
* ataBlkRd - read one or more blocks from a ATA/IDE disk
*
* This routine reads one or more blocks from the specified device,
* starting with the specified block number.
*
* If any block offset was specified during ataDevCreate(), it is added
* to <startBlk> before the transfer takes place.
*
* RETURNS: OK, ERROR if the read command didn't succeed.
*/

LOCAL STATUS ataBlkRd
    (
    ATA_DEV *pDev,
    int startBlk,
    int nBlks,
    char *pBuf
    )
    {
    return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_RDONLY));
    }

/*******************************************************************************
*
* ataBlkWrt - write one or more blocks to a ATA/IDE disk
*
* This routine writes one or more blocks to the specified device,
* starting with the specified block number.
*
* If any block offset was specified during ataDevCreate(), it is added
* to <startBlk> before the transfer takes place.
*
* RETURNS: OK, ERROR if the write command didn't succeed.
*/

LOCAL STATUS ataBlkWrt
    (
    ATA_DEV *pDev,
    int startBlk,
    int nBlks,
    char *pBuf
    )
    {
    return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_WRONLY));
    }

/*******************************************************************************
*
* ataReset - reset a ATA/IDE disk controller
*
* This routine resets a ATA/IDE disk controller.
*
* RETURNS: OK, always.
*/

LOCAL STATUS ataReset
    (
    ATA_DEV *pDev
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[pDev->ctrl];
    
    if (!pCtrl->installed)
	return (ERROR);

    semTake (&pCtrl->muteSem, WAIT_FOREVER);

    (void) ataInit (pDev->ctrl);

    semGive (&pCtrl->muteSem);

    return (OK);
    }

/*******************************************************************************
*
* ataStatus - check status of a ATA/IDE disk controller
*
* This routine check status of a ATA/IDE disk controller.
*
* RETURNS: OK, ERROR if the card is removed.
*/

LOCAL STATUS ataStatus
    (
    ATA_DEV *pDev
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[pDev->ctrl];
    BLK_DEV *pBlkdev	= &pDev->blkDev;
    
    if (!pCtrl->installed)
	return (ERROR);

    if (pCtrl->changed)
	{
	pBlkdev->bd_readyChanged = TRUE;
	pCtrl->changed		 = FALSE;
	}

    return (OK);
    }

/*******************************************************************************
*
* ataIoctl - do device specific control function
*
* This routine is called when the file system cannot handle an ioctl()
* function.
*
* RETURNS:  OK or ERROR.
*/

LOCAL STATUS ataIoctl
    (
    ATA_DEV *pDev,
    int function,
    int arg
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[pDev->ctrl];
    FAST int status	= ERROR;

    if (!pCtrl->installed)

⌨️ 快捷键说明

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