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

📄 atadrv.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    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;	    }        else if (pDrive->type == ATA_TYPE_ATAPI)            {            pBlkdev->bd_nBlocks         = 100;            pBlkdev->bd_bytesPerBlk     = 2048;            pBlkdev->bd_blksPerTrack    = pBlkdev->bd_nBlocks;            pBlkdev->bd_nHeads          = 1;            if (pParam->config & CONFIG_REMOVABLE)                pBlkdev->bd_removable   = TRUE;            else                pBlkdev->bd_removable   = FALSE;            pBlkdev->bd_retry           = 1;            pBlkdev->bd_mode            = O_RDONLY;            pBlkdev->bd_readyChanged    = TRUE;            pBlkdev->bd_blkRd           = ataPiBlkRd;            pBlkdev->bd_blkWrt          = ataStub;            pBlkdev->bd_ioctl           = ataPiIoctl;            pBlkdev->bd_reset           = ataPiReset;            pBlkdev->bd_statusChk       = ataPiStatusChk;	    pDev->ctrl		        = ctrl;	    pDev->drive		        = drive;	    pDev->blkOffset	        = blkOffset;            pDev->nBlocks               = nBlocks;	    }        ataDriveInit (ctrl, drive);        pDrive->state = ATA_DEV_OK;	}    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_DRIVE *pDrive	= &pCtrl->drive[drive];    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);    /*     * 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)         &&	(ataForceCHSonLBA != TRUE)		    &&	(ataLbaTotalSecs[ctrl][drive] > 	(pType->cylinders * pType->heads * pType->sectors)))   	{	pBlkdev->bd_nBlocks = ataLbaTotalSecs[ctrl][drive];	}    else /* just use CHS value */	{        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, 0);    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)        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);	}    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;    ATA_TYPE  *pType	= &ataTypes[pDev->ctrl][pDev->drive];    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 = pBlkdev->bd_nBlocks;    if ((startBlk + nBlks) > nSecs)	{	ATA_DEBUG_MSG (1, "startBlk=%d nBlks=%d: 0 - %d\n", startBlk, nBlks,                        nSecs, 0, 0, 0);	return (ERROR);	}    startBlk += pDev->blkOffset;    semTake (&pCtrl->muteSem, WAIT_FOREVER);    for (ix = 0; ix < nBlks; ix += nSecs)	{	if (pDrive->okLba)	    {	    head     = (startBlk & 0x0f000000) >> 24;	    cylinder = (startBlk & 0x00ffff00) >> 8;	    sector   = (startBlk & 0x000000ff);	    }	else	    {	    cylinder = startBlk / (pType->sectors * pType->heads);	    sector   = startBlk % (pType->sectors * pType->heads);	    head     = sector / pType->sectors;	    sector   = sector % pType->sectors + 1;	    }	nSecs    = min (nBlks - ix, ATA_MAX_RW_SECTORS);	retryRW1 = 0;	retryRW0 = 0;	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	= &ataCtrl[ctrl];    pCtrl->intCount++;    pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);    semGive (&pCtrl->syncSem);    }/********************************************************************************* 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 ATA/ATAPI 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    )    {    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];    ATA_DEBUG_MSG (3, "ataWait: ctrl=%d  request=0x%x\n", ctrl, request,                  0, 0, 0, 0);    switch (request)	{	case ATA_STAT_READY:	    wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 		     (FUNCPTR)ataWdog, ctrl);

⌨️ 快捷键说明

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