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

📄 m5200atadrv.c

📁 vxworks硬盘DMA驱动,VXWORKS 6.0以前版本不支持ATA硬盘的DMA传输方式,只支持PIO模式,假如该驱动后,可能会极大提高传输速度,快下吧!
💻 C
📖 第 1 页 / 共 5 页
字号:
    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.*/LOCAL STATUS ataRW    (    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 block       = 1;    int nSectors;    int nWords;    int semStatus;    short *pBuf;    ATA_DEBUG_MSG (2, "ataRW: ctrl=%d drive=%d c=%d h=%d s=%d buf=0x%x ",                   ctrl, drive, cylinder, head, sector, (int)buffer);    ATA_DEBUG_MSG (2, "n=%d dir=%d\n", nSecs, direction, 0, 0, 0, 0);retryRW:    ataWait (ctrl, ATA_STAT_READY);    pBuf = (short *)buffer;    nSectors = nSecs;    ATA_IO_BYTE_WRITE (pCtrl->feature, pType->precomp);    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 (pDrive->rwPio == ATA_PIO_MULTI)    block = pDrive->multiSecs;    nWords = (pType->bytes * block) >> 1;    if (direction == O_WRONLY)    {        if (pDrive->rwPio == ATA_PIO_MULTI)        ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_WRITE_MULTI);    else        ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_WRITE);    while (nSectors > 0)        {        if ((pDrive->rwPio == ATA_PIO_MULTI) && (nSectors < block))        {        block = nSectors;        nWords = (pType->bytes * block) >> 1;        }            ataWait (ctrl, ATA_STAT_BUSY);            ataWait (ctrl, ATA_STAT_DRQ);        if (pDrive->rwBits == ATA_BITS_16)            ATA_IO_NWORD_WRITE (pCtrl->data, (void *)pBuf, nWords);        else            ATA_IO_NLONG_WRITE (pCtrl->data, (void *)pBuf, nWords >> 1);            semStatus = semTake (&pCtrl->syncSem,                 sysClkRateGet() * pCtrl->semTimeout);            if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))            goto errorRW;        pBuf     += nWords;        nSectors -= block;            }    }    else    {        if (pDrive->rwPio == ATA_PIO_MULTI)        ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READ_MULTI);    else        ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READ);    while (nSectors > 0)        {        if ((pDrive->rwPio == ATA_PIO_MULTI) && (nSectors < block))        {        block = nSectors;        nWords = (pType->bytes * block) >> 1;        }            semStatus = semTake (&pCtrl->syncSem,                 sysClkRateGet() * pCtrl->semTimeout);            if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))            goto errorRW;            ataWait (ctrl, ATA_STAT_BUSY); /* wait for slow disk */            ataWait (ctrl, ATA_STAT_DRQ);        if (pDrive->rwBits == ATA_BITS_16)            ATA_IO_NWORD_READ (pCtrl->data, (void *)pBuf, nWords);        else            ATA_IO_NLONG_READ (pCtrl->data, (void *)pBuf, nWords >> 1);        pBuf     += nWords;        nSectors -= block;        }    }    ATA_DEBUG_MSG (2, "ataRW: end\n", 0, 0, 0, 0, 0, 0);    return (OK);errorRW:    ATA_DEBUG_MSG (1, "ataRW err: stat=0x%x 0x%x semStatus=%d error=0x%x\n",               pCtrl->intStatus, ATA_IO_BYTE_READ (pCtrl->aStatus),                   semStatus, ATA_IO_BYTE_READ (pCtrl->error), 0, 0);    if (++retryCount < ataRetry)    goto retryRW;    return (ERROR);    }/******************************* ATAPI Devices *********************************//********************************************************************************* ataDevIdentify - identify device** This routine checks whether the device is connected to the controller, and if* so determines its type.  The routine set `type' field in the corresponding* ATA_DRIVE structure.* If device identification failed, the routine set `state' field in the* corresponding ATA_DRIVE structure to ATA_DEV_NONE.** RETURNS: TRUE if a device is present, FALSE otherwise*/LOCAL STATUS ataDevIdentify    (    int ctrl,    int dev    )    {    ATA_CTRL    *pCtrl  = &ataCtrl[ctrl];    ATA_DRIVE   *pDrive = &pCtrl->drive [dev];    ATA_PARAM   *pParam = &pDrive->param;    pDrive->type = ATA_TYPE_NONE;    /* Select device */    ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (dev << 4));    /* Wait for device selection */    ATA_WAIT_STATUS;    /* Clear semaphore: Selection of nonexistent device may rise an interrupt */    semTake (&pCtrl->syncSem, NO_WAIT);    ATA_IO_BYTE_WRITE (pCtrl->seccnt, 0xaa);    ATA_IO_BYTE_WRITE (pCtrl->sector, 0x55);    if (ATA_IO_BYTE_READ (pCtrl->seccnt) == 0xaa)        {        if (ataPiPread (ctrl, dev, pParam) == OK)            {            pDrive->type = ATA_TYPE_ATAPI;            }        else            if ( ((ATA_IO_BYTE_READ (ATAPI_STATUS) & (ATA_STAT_BUSY |           ATA_STAT_WRTFLT | ATA_STAT_DRQ | ATA_STAT_ERR)) ==                   ATA_STAT_ERR) &&                  (ATA_IO_BYTE_READ (ATAPI_ERROR) == ERR_ABRT) )                {                if (ataPiWait (ctrl, ATA_STAT_READY, FALSE) == OK)                    pDrive->type = ATA_TYPE_ATA;                }        }    if (pDrive->type != ATA_TYPE_NONE)        return (OK);    ATA_DEBUG_MSG (1, "ataDevIdentify%d/%d: ERROR: status=0x%x dev=0x%x "                   "error=0x%x\n", ctrl, dev, ATA_IO_BYTE_READ (pCtrl->status),                   ATA_IO_BYTE_READ (pCtrl->sdh),                   ATA_IO_BYTE_READ (pCtrl->error), 0);    /* Select present device */    ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (((~dev) & 0x1) << 4)); /* define macro for 0x1 */    pDrive->state = ATA_DEV_NONE;    return (ERROR);    } /* ataDevIdentify *//********************************************************************************* ataPiInit - init a ATAPI CD-ROM disk controller** This routine resets a ATAPI CD-ROM disk controller.** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS ataPiInit    (    int ctrl,    int drive    )    {    ATA_CTRL    *pCtrl = &ataCtrl[ctrl];    int     retryCount = 0;    int     i;    ATA_DEBUG_MSG (2, "ataPiInit%d/%d: \n", ctrl, drive, 0, 0, 0, 0);    while (TRUE) /* Forever */        {        ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (drive << 4));        ATA_WAIT_STATUS;        ATA_IO_BYTE_WRITE (ATAPI_COMMAND, ATA_PI_CMD_SRST);        for (i = 0; i < 5000; i++)  /* 2 ms */            {            ATA_WAIT_STATUS;            }        ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (drive << 4));        ATA_WAIT_STATUS;        pCtrl->wdgOkay = TRUE;        wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),                 (FUNCPTR)ataWdog, ctrl);        while ( (ATA_IO_BYTE_READ (ATAPI_STATUS) & (ATA_STAT_BUSY |                 ATA_STAT_READY | ATA_STAT_WRTFLT | ATA_STAT_DRQ |                 ATA_STAT_ECCCOR | ATA_STAT_ERR)) && (pCtrl->wdgOkay) )        ;        wdCancel (pCtrl->wdgId);        if (pCtrl->wdgOkay)            break;        pCtrl->wdgOkay = TRUE;        ATA_DEBUG_MSG (1, "ataPiInit%d/%d: ERROR: status=0x%x error=0x%x\n",                       ctrl, drive, ATA_IO_BYTE_READ(ATAPI_STATUS),                       ATA_IO_BYTE_READ(ATAPI_ERROR), 0, 0);    if (++retryCount == ataRetry)        return (ERROR);        }    /* The following allow to recover after accidental interrupt */    if (semTake (&pCtrl->syncSem, NO_WAIT) == OK)        {        ATA_DEBUG_MSG (2, "ataPiInit%d/%d: WARNING: interrupt cleared: "                       "status=0x%x dev=0x%x error=0x%x\n", ctrl, drive,                       ATA_IO_BYTE_READ(ATAPI_STATUS),                       ATA_IO_BYTE_READ(ATAPI_D_SELECT),                       ATA_IO_BYTE_READ(ATAPI_ERROR), 0);        }    else        {        ATA_DEBUG_MSG (2, "ataPiInit%d/%d: Ok: status=0x%x dev=0x%x error=0x%x"                       "\n", ctrl, drive, ATA_IO_BYTE_READ(ATAPI_STATUS),                       ATA_IO_BYTE_READ(ATAPI_D_SELECT),                       ATA_IO_BYTE_READ(ATAPI_ERROR), 0);        }    return (OK);    } /* ataPiInit *//********************************************************************************* ataPiPread - Read ATAPI drive parameters** This routine reads drive parameters.** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS ataPiPread    (    int     ctrl,    int     drive,    void        *buffer    )    {    ATA_CTRL    *pCtrl      = &ataCtrl[ctrl];    int     status;    int     error;    int     semStatus;    ATA_DEBUG_MSG (2, "ataPiPread%d/%d: \n", ctrl, drive, 0, 0, 0, 0);    ataPiWait (ctrl, ATA_STAT_ACCESS, TRUE);    /* Select device */    ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (drive << 4));    ATA_WAIT_STATUS;    if (ataPiWait (ctrl, ATA_STAT_ACCESS, TRUE) != OK)        {        ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (drive << 4));;        ATA_WAIT_STATUS;        }    /* ATAPI Identify Device Command */    ATA_IO_BYTE_WRITE (ATAPI_COMMAND, ATA_PI_CMD_IDENTD);    ATA_WAIT_STATUS;    /*     * Poll Status Register instead of wait for interrupt to avoid needless     * delay.     */    ataPiWait (ctrl, ATA_STAT_BUSY, FALSE);    semStatus = semTake (&pCtrl->syncSem, 1);    status = ATA_IO_BYTE_READ (ATAPI_STATUS);    if ( (status & ATA_STAT_ERR) || !(status & ATA_STAT_DRQ) ||         (semStatus != OK) )        {        error = ATA_IO_BYTE_READ (ATAPI_ERROR);        ATA_DEBUG_MSG (1, "ataPiPread%d/%d: ERROR: status=0x%x intStatus=0x%x "                      "error=0x%x semStatus=%d\n", ctrl, drive, status,                       pCtrl->intStatus, error, semStatus);        return (ERROR);        }    /* Receive parameter information from the drive */    ATA_IO_NWORD_READ_SWAP (ATAPI_DATA, (void *)buffer,                            sizeof(ATA_PARAM)/sizeof(short));    /* To prevent from reading status before it is valid */    ATA_IO_BYTE_READ (pCtrl->aStatus);    /* Wait for device to be ready !!! */    ataPiWait (ctrl, ATA_STAT_READY, TRUE);    ATA_DEBUG_MSG (2, "ataPiPread%d/%d:Ok: status=0x%x devReg=0x%x\n",                  ctrl, drive, ATA_IO_BYTE_READ (pCtrl->status),                  ATA_IO_BYTE_READ (pCtrl->sdh), 0, 0);    return (OK);    } /* ataPiPread *//********************************************************************************* atapiDMAInit - initialize the DMA engine** This routine initializes the DMA engine.** RETURN: OK, or ERROR*/LOCAL STATUS atapiDMAInit (void)    {    printErr("ATAPI (DMA Init.) ERROR: DMA transfer is not emplemented.\n");    return ERROR;    }/********************************************************************************* atapiDMATransfer - transfer a single data packet via DMA** This routine transfers a single data packet via DMA.** RETURN: OK, or ERROR** SEE ALSO: ataPiPIOTransfer()*/LOCAL STATUS atapiDMATransfer    (    ATA_DEV *pAtapiDev    )    {    pAtapiDev->errNum = 27;    return ERROR;    }/********************************************************************************* ataPiOverlapTransferLoop - loop for DRQ Interrupts with Overlapping** This routine loops for Data Request Interrupts until all data packets are* transferred.  It is invoked when ataPiPktCmd() executes an Overlapped command.* When Device executes an Overlapped command, it releases the ATA bus until the* device is ready to transfer a data or to present the completion st

⌨️ 快捷键说明

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