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

📄 atadrv.c

📁 MPC5200 BSP 支持ATA,USB, I2C,扩展网口
💻 C
📖 第 1 页 / 共 5 页
字号:
** 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 (1, "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 (3, "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.*/STATUS ataPread    (    int      ctrl,    int      drive,    void     *buffer    )    {    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];    BOOL     retry	= TRUE;    int      retryCount	= 0;    int      semStatus;    ATA_DEBUG_MSG (3, "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 (3, "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;    volatile int i=0;    ATA_DEBUG_MSG (3, "ataRW: ctrl=%d drive=%d c=%d h=%d s=%d buf=0x%x ",                   ctrl, drive, cylinder, head, sector, (int)buffer);    ATA_DEBUG_MSG (3, "n=%d dir=%d\n", nSecs, direction, 0, 0, 0, 0);retryRW:    ataWait (ctrl, ATA_STAT_READY);		for (i = 0;i < 20*4;i++) {};			/* Wait for BSY=0 & DRQ=0 */		while ( (ATA_IO_BYTE_READ (pCtrl->aStatus) & (ATA_STAT_BUSY | ATA_STAT_DRQ))             != 0 )        ;    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);				for (i = 0;i < 20*4;i++) {};			/* Wait for BSY=0 & DRQ=0 */		while ( (ATA_IO_BYTE_READ (pCtrl->aStatus) & (ATA_STAT_BUSY | ATA_STAT_DRQ))             != 0 )        ;            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;				for (i = 0;i < 20*4;i++) {};			/* Wait for BSY=0 & DRQ=0 */		while ( (ATA_IO_BYTE_READ (pCtrl->aStatus) & (ATA_STAT_BUSY | ATA_STAT_DRQ))             != 0 )        ;    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, pBuf, nWords);	    		else	        		ATA_IO_NLONG_WRITE (pCtrl->data, (long *)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, pBuf, nWords);	    		else	        	ATA_IO_NLONG_READ (pCtrl->data, (long *)pBuf, nWords >> 1);	    		pBuf     += nWords;	    		nSectors -= block;	    }		}    ATA_DEBUG_MSG (3, "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;		ATA_DEBUG_MSG (3, "Enter into ataDevIdentify\n", 0, 0, 0, 0, 0, 0);    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 (3, "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

⌨️ 快捷键说明

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