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

📄 m5200atadrv.c

📁 vxworks硬盘DMA驱动,VXWORKS 6.0以前版本不支持ATA硬盘的DMA传输方式,只支持PIO模式,假如该驱动后,可能会极大提高传输速度,快下吧!
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Identify device presence and its type */    if (ataDevIdentify (ctrl, drive) != OK)        goto driveInitExit;    /* Set Reset function according to device type */    if (pDrive->type == ATA_TYPE_ATA)        pDrive->Reset = ataInit;    else if (pDrive->type == ATA_TYPE_ATAPI)        pDrive->Reset = ataPiInit;    if (pDrive->type == ATA_TYPE_ATA)        {        if (ataPread (ctrl, drive, (char *)pParam) == OK)            {        if ((pCtrl->ctrlType == ATA_PCMCIA) ||        ((pCtrl->ctrlType != ATA_PCMCIA) && (drive == 0)))        {                if (ataCmd (ctrl, drive, ATA_CMD_DIAGNOSE, 0, 0) != OK)            {                semGive (&pCtrl->muteSem);                return (ERROR);            }        }            /* find out geometry */            if ((configType & ATA_GEO_MASK) == ATA_GEO_FORCE)                {                (void) ataCmd (ctrl, drive, ATA_CMD_INITP, 0, 0);                (void) ataPread (ctrl, drive, (char *)pParam);                }            else if ((configType & ATA_GEO_MASK) == ATA_GEO_PHYSICAL)                {                pType->cylinders = pParam->cylinders - 1;                pType->heads     = pParam->heads;                pType->sectors   = pParam->sectors;                }            else if ((configType & ATA_GEO_MASK) == ATA_GEO_CURRENT)                {                if ((pParam->currentCylinders != 0) &&                    (pParam->currentHeads != 0) &&                    (pParam->currentSectors != 0))                    {                    pType->cylinders = pParam->currentCylinders - 1;                    pType->heads     = pParam->currentHeads;                    pType->sectors   = pParam->currentSectors;                    }                else                    {                    pType->cylinders = pParam->cylinders - 1;                    pType->heads     = pParam->heads;                    pType->sectors   = pParam->sectors;                    }                }            /*             * Not all modern hard drives report a true capacity value             * in their IDENTIFY DEVICE CHS fields.             * For example, a Western Digital 20 Gb drive reports             * its CHS as 16383 cylinders, 16 heads, and 63 spt.             * This is about 8.4GB, but the LBA sectors is reported             * as 0x02607780, which is closer to 20Gb, the true capacity             * of the drive.  The reason for this is PC BIOS can have a             * 8.4GB limitation, and drive manufacturers have broken the             * ATA specification to be compatable.  Negative competition.             * Note that the ATA specifications original limit is             * about 136.9 Gb, however when combinined with a PC BIOS             * interface, a 8.4 Gb limit is produced.             * VxWorks does not have such limitations being a true 32bit OS,             * but since the drive manufactures are not honoring the CHS             * values, we have to allow for devices that demand "pure" LBA             * and present incorrect CHS.             * If the drive supports Logical Block Addresses (LBA)             * then we need to check the field located at 16bit words 60 & 61,             * "Total number of user addressable sectors (LBA mode only)".             * If this value is greater than the CHS fields report,             * then 60-61 holds the true size of the disk and that             * will be reported to the block device interface.             * Note that the CHS values are still left as the disk reported.             * This is tracked at WRS as SPR#22830             */            if (pParam->capabilities & 0x0200)  /* if (drive supports LBA) */                {                ataLbaTotalSecs[ctrl][drive] =  (UINT32)            ((((UINT32) ((pParam->sectors0) & 0x0000ffff)) <<  0) |             (((UINT32) ((pParam->sectors1) & 0x0000ffff)) << 16));                ATA_DEBUG_MSG (1, "ID_DRIVE reports LBA (60-61) as 0x%08lx\n",                               ataLbaTotalSecs[ctrl][drive], 0, 0, 0, 0, 0);                }            /*             * reinitialize the controller with parameters read from the             * controller.             */            (void) ataCmd (ctrl, drive, ATA_CMD_INITP, 0, 0);            /* recalibrate (this command !!! is absent in ATA-4) */            (void) ataCmd (ctrl, drive, ATA_CMD_RECALIB, 0, 0);            }        else            {            pDrive->state = ATA_DEV_PREAD_F;            goto driveInitExit;            }        }    else if (pDrive->type == ATA_TYPE_ATAPI)        {        /* Although ATAPI device parameters have been read by ataDevIdentify(),         * execute ATAPI Identify Device command to allow ATA commands         * acceptance by an ATAPI device after Diagnostic or Reset commands.         */        if (ataPiPread (ctrl, drive, pParam) != OK)            {            pDrive->state = ATA_DEV_PREAD_F;            goto driveInitExit;            }        }    /* find out supported capabilities of the drive */    pDrive->multiSecs = pParam->multiSecs & 0x00ff;    pDrive->okMulti   = (pDrive->multiSecs != 0) ? 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 ((pDrive->okDma) && (pParam->valid & 0x02))        {        pDrive->singleDmaMode = (pParam->dmaMode >> 8) & 0x03;        if (pDrive->singleDmaMode >= 2)            pDrive->singleDmaMode = 0;        pDrive->multiDmaMode  = 0;        if (pParam->singleDma & 0x04)            pDrive->singleDmaMode = 2;        else if (pParam->singleDma & 0x02)            pDrive->singleDmaMode = 1;        else if (pParam->singleDma & 0x01)            pDrive->singleDmaMode = 0;        if (pParam->multiDma & 0x04)            pDrive->multiDmaMode = 2;        else if (pParam->multiDma & 0x02)            pDrive->multiDmaMode = 1;        else if (pParam->multiDma & 0x01)            pDrive->multiDmaMode = 0;        }    /* 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;    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;        case ATA_DMA_0:        case ATA_DMA_1:        case ATA_DMA_2:            if (pDrive->okDma)                {                if (pDrive->rwDma == ATA_DMA_SINGLE)                    pDrive->rwMode |= ATA_DMA_SINGLE_0;                if (pDrive->rwDma == ATA_DMA_MULTI)                    pDrive->rwMode |= ATA_DMA_MULTI_0;                }            break;        case ATA_DMA_AUTO:            if (pDrive->okDma)                {                if (pDrive->rwDma == ATA_DMA_SINGLE)                    pDrive->rwMode = ATA_DMA_SINGLE_0 +                                     pDrive->singleDmaMode;                if (pDrive->rwDma == ATA_DMA_MULTI)                    pDrive->rwMode = ATA_DMA_MULTI_0 +                                     pDrive->multiDmaMode;                }            break;        default:            break;        }    /* Set the transfer mode */    (void) ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_SET_RWMODE,                   pDrive->rwMode);    /* Disable reverting to power on defaults */    (void) ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_DISABLE_REVE, 0);    /* Set multiple mode (multisector read/write) */    if ((pDrive->rwPio == ATA_PIO_MULTI) && (pDrive->type == ATA_TYPE_ATA))        {        if (pDrive->okMulti)            (void) ataCmd (ctrl, drive, ATA_CMD_SET_MULTI,                           pDrive->multiSecs, 0);        else            pDrive->rwPio = ATA_PIO_SINGLE;        }    pDrive->state = ATA_DEV_OK;driveInitExit:    semGive (&pCtrl->muteSem);    if (pDrive->state != ATA_DEV_OK)        {        ATA_DEBUG_MSG (1, "ataDriveInit%d/%d: ERROR: state=%d dev=0x%x "                       "status=0x%x error=0x%x\n", ctrl, drive, pDrive->state,                       ATA_IO_BYTE_READ (pCtrl->sdh),                       ATA_IO_BYTE_READ (pCtrl->status),                       ATA_IO_BYTE_READ (pCtrl->error));        return (ERROR);        }    return (OK);    } /* ataDriveInit *//********************************************************************************* ataDrv - initialize the ATA driver** This routine initializes the ATA/IDE/ATAPI CDROM driver, sets up interrupt* vectors, and performs hardware initialization of the ATA/IDE chip.** This routine must be called exactly once, before any reads, writes,* or calls to ataDevCreate().  Normally, it is called by usrRoot()* in usrConfig.c.** RETURNS: OK, or ERROR if initialization fails.** SEE ALSO: ataDevCreate()*/STATUS ataDrv    (    int  ctrl,          /* controller no. */    int  drives,        /* number of drives */    int  vector,        /* interrupt vector */    int  level,         /* interrupt level */    int  configType,        /* configuration type */    int  semTimeout,        /* timeout seconds for sync semaphore */    int  wdgTimeout     /* timeout seconds for watch dog */    )    {    ATA_CTRL        *pCtrl  = &ataCtrl[ctrl];    ATA_RESOURCE    *pAta   = &ataResources[ctrl];    PCCARD_RESOURCE *pResource  = &pAta->resource;    ATA_DRIVE       *pDrive;    ATA_PARAM       *pParam;    ATA_TYPE        *pType;    int             drive;    int             ix;    if ((ctrl >= ATA_MAX_CTRLS) || (drives > ATA_MAX_DRIVES))    return (ERROR);    if (!ataDrvInstalled)    {    for (ix = 0; ix < ATA_MAX_CTRLS; ix++)            ataCtrl[ix].wdgId = wdCreate ();        ataDrvInstalled = TRUE;    }    if (!pCtrl->installed)    {    if (semTimeout == 0)        pCtrl->semTimeout = ATA_SEM_TIMEOUT_DEF;    else        pCtrl->semTimeout = semTimeout;    if (wdgTimeout == 0)        pCtrl->wdgTimeout = ATA_WDG_TIMEOUT_DEF;    else        pCtrl->wdgTimeout = wdgTimeout;        semBInit (&pCtrl->syncSem, SEM_Q_FIFO, SEM_EMPTY);        semMInit (&pCtrl->muteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE |              SEM_INVERSION_SAFE);    pCtrl->data = ATA_DATA  (pResource->ioStart[0]);    pCtrl->error    = ATA_ERROR (pResource->ioStart[0]);    pCtrl->feature  = ATA_FEATURE   (pResource->ioStart[0]);    pCtrl->seccnt   = ATA_SECCNT    (pResource->ioStart[0]);    pCtrl->sector   = ATA_SECTOR    (pResource->ioStart[0]);    pCtrl->cylLo    = ATA_CYL_LO    (pResource->ioStart[0]);    pCtrl->cylHi    = ATA_CYL_HI    (pResource->ioStart[0]);    pCtrl->sdh  = ATA_SDH   (pResource->ioStart[0]);    pCtrl->command  = ATA_COMMAND   (pResource->ioStart[0]);    pCtrl->status   = ATA_STATUS    (pResource->ioStart[0]);    pCtrl->aStatus  = ATA_A_STATUS  (pResource->ioStart[1]);    pCtrl->dControl = ATA_D_CONTROL (pResource->ioStart[1]);    pCtrl->dAddress = ATA_D_ADDRESS (pResource->ioStart[1]);        (void) intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (vector),                   (VOIDFUNCPTR)ataIntr, ctrl);        sysIntEnablePIC (level);    /* unmask the interrupt level */    pCtrl->intLevel = level;    pCtrl->wdgOkay  = TRUE;    pCtrl->configType = configType;    semTake (&pCtrl->muteSem, WAIT_FOREVER);    pCtrl->installed = TRUE;        for (drive = 0; drive < drives; drive++)        {        pType  = &ataTypes[ctrl][drive];        pDrive = &pCtrl->drive[drive];        pParam = &pDrive->param;            pDrive->state   = ATA_DEV_INIT;            pDrive->type    = ATA_TYPE_INIT;            pDrive->diagCode    = 0;            pDrive->Reset   = ataInit;            ataDriveInit (ctrl, drive);            }        ATA_DEBUG_MSG (1, "ataDrv Calling sysAtaInit (if present):\n",                      0, 0, 0, 0, 0, 0);    /* Call system INIT routine to allow proper PIO mode setup */        SYS_ATA_INIT_RTN (ctrl);        ATA_DEBUG_MSG (1, "ataDrv sysAtaInit returned:\n",                      0, 0, 0, 0, 0, 0);    semGive (&pCtrl->muteSem);    }    return (OK);    }/********************************************************************************* ataDevCreate - create a device for a ATA/IDE disk** This routine creates a device for a specified ATA/IDE or ATAPI CDROM disk.** <ctrl> is a controller number for the ATA controller; the primary controller* is 0.  The maximum is specified via ATA_MAX_CTRLS.** <drive> is the drive number for the ATA hard drive; the master drive* is 0.  The maximum is specified via ATA_MAX_DRIVES.** 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(), rawFsDevInit()*/BLK_DEV *ataDevCreate    (    int ctrl,     /* ATA controller number, 0 is the primary controller */    int drive,    /* ATA drive number, 0 is the master drive */    int nBlocks,  /* number of blocks on device, 0 = use entire disc */    int blkOffset /* offset BLK_DEV nBlocks from the start of the drive */    )    {    ATA_CTRL  *pCtrl    = &ataCtrl[ctrl];    ATA_TYPE  *pType    = &ataTypes[ctrl][drive];    ATA_DRIVE *pDrive   = &pCtrl->drive[drive];    ATA_PARAM *pParam   = &pDrive->param; /* move * */    ATA_DEV   *pDev;    BLK_DEV   *pBlkdev;    int       maxBlks;    if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||        !ataDrvInstalled || !pCtrl->installed)

⌨️ 快捷键说明

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