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

📄 atadrv.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) && 		   (pCtrl->wdgOkay))	        ;            while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0)                   && (pCtrl->wdgOkay))	        ;	    wdCancel (pCtrl->wdgId);            if (!pCtrl->wdgOkay)	        {	        pCtrl->wdgOkay = TRUE;	        (void) ataInit (ctrl, 0);	        }	    break;	case ATA_STAT_BUSY:            while (ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY)		;	    break;	case ATA_STAT_DRQ:            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) == 0)	        ;	    break;	case ATA_STAT_SEEKCMPLT:            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_SEEKCMPLT) == 0)	        ;	    break;	}    ATA_DEBUG_MSG (3, "ataWait end:\n", 0, 0, 0, 0, 0, 0);    }/********************************************************************************* ataPiWait - wait the ATAPI drive ready** Wait the drive ready** RETURNS: OK, ERROR if the drive didn't become ready in certain period of time.*/LOCAL STATUS ataPiWait    (    int 	ctrl,    int 	request,    BOOL	reset    )    {    ATA_CTRL    *pCtrl	= &ataCtrl[ctrl];     ATA_DRIVE   *pDrive;    int		drive;    ATA_DEBUG_MSG (3, "ataPiWait: ctrl=%d  request=0x%x\n", ctrl, request,                   0, 0, 0, 0);    drive = (ATA_IO_BYTE_READ (pCtrl->sdh) >> 4) & 1;    pDrive = &pCtrl->drive[drive];    switch (request)	{	case ATA_STAT_READY:	    wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 		     (FUNCPTR)ataWdog, ctrl);            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) && 		   (pCtrl->wdgOkay))	        ;            while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0)                   && (pCtrl->wdgOkay))	        ;            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) &&		   (pCtrl->wdgOkay))                ;	    wdCancel (pCtrl->wdgId);            if (!pCtrl->wdgOkay)	        {	        pCtrl->wdgOkay = TRUE;                if (reset == TRUE)	            (void) pDrive->Reset (ctrl, drive);                return (ERROR);	        }	    break;	case ATA_STAT_ACCESS:	    wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 		     (FUNCPTR)ataWdog, ctrl);            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) && 		   (pCtrl->wdgOkay))	        ;            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) &&		   (pCtrl->wdgOkay))                ;	    wdCancel (pCtrl->wdgId);            if (!pCtrl->wdgOkay)	        {	        pCtrl->wdgOkay = TRUE;                if (reset == TRUE)	            (void) pDrive->Reset (ctrl, drive);                return (ERROR);	        }	    break;	case ATA_STAT_BUSY:            while (ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY)		;	    break;	case ATA_STAT_DRQ:            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) == 0)	        ;	    break;	case ATA_STAT_SEEKCMPLT:            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_SEEKCMPLT)                    == 0)	        ;	    break;	}    ATA_DEBUG_MSG (3, "ataPiWait end:\n", 0, 0, 0, 0, 0, 0);    return (OK);    } /* ataPiWait *//********************************************************************************* ataInit - init a ATA/IDE disk controller** This routine initializes a ATA/IDE disk controller.** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS ataInit    (    int ctrl,    int dev    )    {    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];    int      ix;    ATA_DEBUG_MSG (2, "ataInit: ctrl=%d\n", ctrl, 0, 0, 0, 0, 0);    ATA_IO_BYTE_WRITE (pCtrl->dControl,                       ATA_CTL_4BIT | ATA_CTL_RST);    for (ix = 0; ix < 100; ix++)        sysDelay ();    ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT);    for (ix = 0; ix < 100; ix++)        sysDelay ();    pCtrl->wdgOkay = TRUE;    /* start the ata  watchdog */    wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),	     (FUNCPTR)ataWdog, ctrl);    while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) &&           (pCtrl->wdgOkay))	;    ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT);    for (ix = 0; ix < 100; ix++)         sysDelay ();    while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0) &&	   (pCtrl->wdgOkay))	;    wdCancel (pCtrl->wdgId);    if (!pCtrl->wdgOkay)        {	ATA_DEBUG_MSG (1, "ataInit error:\n", 0, 0, 0, 0, 0, 0);        pCtrl->wdgOkay = TRUE;        return (ERROR);        }    ATA_DEBUG_MSG (3, "ataInit Calling sysAtaInit (if present):\n",                   0, 0, 0, 0, 0, 0);    /* Call out to bsp specific setup routine */    SYS_ATA_INIT_RTN (ctrl);    ATA_DEBUG_MSG (3, "ataInit sysAtaInit returned\n", 0, 0, 0, 0, 0, 0);    /*     * The following allows recovery after an interrupt     * caused by drive software reset     */    semBInit(&pCtrl->syncSem, SEM_Q_FIFO, SEM_EMPTY);    ATA_DEBUG_MSG (2, "ataInit end\n", 0, 0, 0, 0, 0, 0);    return (OK);    }/********************************************************************************* ataCmd - issue non data command** Issue a non data command.  Non data commands have the same protocol.** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS ataCmd    (    int ctrl,    int drive,    int cmd,    int arg0,    int arg1    )    {    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];    ATA_TYPE *pType	= &ataTypes[ctrl][drive];    BOOL     retry	= TRUE;    int      retryCount	= 0;    int      semStatus;    ATA_DEBUG_MSG (2, "ataCmd%d/%d: cmd=0x%x\n", ctrl, drive, cmd, arg0, arg1, 0);    while (retry)	{        ataWait (ctrl, ATA_STAT_READY);	switch (cmd)	    {	    case ATA_CMD_DIAGNOSE:        	ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));		break;	    case ATA_CMD_INITP:		ATA_IO_BYTE_WRITE (pCtrl->cylLo, pType->cylinders);		ATA_IO_BYTE_WRITE (pCtrl->cylHi, pType->cylinders >> 8);		ATA_IO_BYTE_WRITE (pCtrl->seccnt, pType->sectors);		ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) | 			    ((pType->heads - 1) & 0x0f));		break;	    case ATA_CMD_RECALIB:		ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));		break;	    case ATA_CMD_SEEK:		ATA_IO_BYTE_WRITE (pCtrl->cylLo, arg0);		ATA_IO_BYTE_WRITE (pCtrl->cylHi, arg0>>8);		ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) |			    (arg1 & 0xf));		break;	    case ATA_CMD_SET_FEATURE:        	ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg1);        	ATA_IO_BYTE_WRITE (pCtrl->feature, arg0);        	ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));		break;	    case ATA_CMD_SET_MULTI:        	ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg0);        	ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));		break;	    }        ATA_IO_BYTE_WRITE (pCtrl->command, cmd);        semStatus = semTake (&pCtrl->syncSem, 			     sysClkRateGet() * pCtrl->semTimeout);        if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))	    {            ATA_DEBUG_MSG (1, "ataCmd err: status=0x%x semStatus=%d err=0x%x\n",                           pCtrl->intStatus, semStatus,                           ATA_IO_BYTE_READ (pCtrl->error), 0, 0, 0);	    if (++retryCount > ataRetry)	        return (ERROR);	    }	else	    retry = FALSE;	}	switch (cmd)	    {	    case ATA_CMD_SEEK:		ataWait (ctrl, ATA_STAT_SEEKCMPLT);		break;	    }    ATA_DEBUG_MSG (2, "ataCmd end - ctrl %d, drive %d: Ok\n", ctrl, drive, 0, 0, 0, 0);    return (OK);    }/********************************************************************************* ataPread - Read drive parameters** Read drive parameters.** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS ataPread    (    int      ctrl,    int      drive,    void     *buffer    )    {    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];    BOOL     retry	= TRUE;    int      retryCount	= 0;    int      semStatus;    ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d\n", ctrl, drive, 0, 0, 0, 0);    while (retry)	{        ataWait (ctrl, ATA_STAT_READY);        ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));        ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READP);        semStatus = semTake (&pCtrl->syncSem, 			     sysClkRateGet() * pCtrl->semTimeout);        if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))	    {            ATA_DEBUG_MSG (1, "ataPread%d/%d - err: status=0x%x intStatus=0x%x "                          "error=0x%x semStatus=%d\n", ctrl, drive,                           ATA_IO_BYTE_READ (pCtrl->aStatus), pCtrl->intStatus,                           ATA_IO_BYTE_READ (pCtrl->error), semStatus);	    if (++retryCount > ataRetry)	        return (ERROR);	    }        else	    retry = FALSE;        }    ataWait (ctrl, ATA_STAT_DRQ);    ATA_IO_NWORD_READ_SWAP (pCtrl->data, (short *)buffer, 256);    ATA_DEBUG_MSG (2, "ataPread end:\n", 0, 0, 0, 0, 0, 0);    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);

⌨️ 快捷键说明

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