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

📄 m5200atadrv.c

📁 vxworks硬盘DMA驱动,VXWORKS 6.0以前版本不支持ATA硬盘的DMA传输方式,只支持PIO模式,假如该驱动后,可能会极大提高传输速度,快下吧!
💻 C
📖 第 1 页 / 共 5 页
字号:
    return (NULL);    if ((pDev = (ATA_DEV *)malloc(sizeof (ATA_DEV))) == NULL)    return (NULL);    pBlkdev = &pDev->blkDev;    if ((pDrive->state == ATA_DEV_OK) || (pDrive->state == ATA_DEV_MED_CH))        {        pDrive->state = ATA_DEV_MED_CH;        if (pDrive->type == ATA_TYPE_ATA)            {        /*         * 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)))            {        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;        }        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;    case FIOSYNC:        (void)ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_FLUSH_CACHE, 0, 0);        status = OK;        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*/

⌨️ 快捷键说明

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