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

📄 idedrv.c

📁 ide接口驱动编程
💻 C
📖 第 1 页 / 共 2 页
字号:
	default:	    (void) errnoSet (S_ioLib_UNKNOWN_REQUEST);	}doneIoctl:    semGive (&ideMuteSem);    return (status);    }/********************************************************************************* ideBlkRW - read or write sectors to a IDE disk.** Read or write sectors to a IDE disk.** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS ideBlkRW    (    IDE_DEV *pIdeDev,    int startBlk,    int nBlks,    char *pBuf,    int direction    )    {    BLK_DEV *pBlkDev = &pIdeDev->blkDev;    int cylinder;    int head;    int sector;    int ix;    int nSecs;    int retryRW0 = 0;    int retryRW1 = 0;    int retrySeek = 0;    int status = ERROR;    IDE_TYPE *pType = &ideTypes[pIdeDev->drive];    /* sanity check */    nSecs =  pBlkDev->bd_nBlocks;    if ((startBlk + nBlks) > nSecs)	{        if (ideDebugErr)	    printErr ("startBlk=%d nBlks=%d: 0 - %d\n", startBlk, nBlks, nSecs);	return (ERROR);	}    startBlk += pIdeDev->blkOffset;    semTake (&ideMuteSem, WAIT_FOREVER);    for (ix = 0; ix < nBlks; ix += nSecs)	{	cylinder = startBlk / (pType->sectorsTrack * pType->heads);	sector   = startBlk % (pType->sectorsTrack * pType->heads);	head     = sector / pType->sectorsTrack;	sector   = sector % pType->sectorsTrack + 1;	nSecs    = min (nBlks - ix, pType->sectorsTrack - sector + 1);	retrySeek = 0;	while (ideSeek(pIdeDev->drive, cylinder, head) != OK)	    if (++retrySeek > ideRetry)		goto done;		retryRW1 = 0;	retryRW0 = 0;	while (ideRW (pIdeDev->drive, cylinder, head, sector, 	  pBuf, nSecs, direction) != OK)	    {	    if (++retryRW0 > ideRetry)		{	        (void) ideRecalib (pIdeDev->drive);	        if (++retryRW1 > ideRetry)		    goto done;	        retrySeek = 0;	        while (ideSeek(pIdeDev->drive, cylinder, head) != OK)	            if (++retrySeek > ideRetry)		        goto done;	        retryRW0 = 0;		}	    }        startBlk += nSecs;        pBuf += pBlkDev->bd_bytesPerBlk * nSecs;	}    status = OK;done:    if (status == ERROR)        (void)errnoSet (S_ioLib_DEVICE_ERROR);    semGive (&ideMuteSem);    return (status);    }/********************************************************************************* ideIntr - IDE controller interrupt handler.** RETURNS: N/A*/LOCAL void ideIntr    (    int ctrl    )    {    ideIntCount++;	/* XXX */    ideStatus = sysInByte (IDE_STATUS);    semGive (&ideSyncSem);    }/********************************************************************************* ideIntr - IDE controller watchdog handler.** RETURNS: N/A*/LOCAL void ideWdog    (    int ctrl    )    {    ideWaitForever = FALSE;    }/********************************************************************************* ideWait - wait the drive ready** Wait the drive ready** RETURNS: OK, ERROR if the drive didn't become ready in certain period of time.*/LOCAL void ideWait    (    int request    )    {    switch (request)	{	case STAT_READY:	    wdStart (ideWid, (sysClkRateGet() * ideWdSec), (FUNCPTR)ideInit, 0);            while (sysInByte (IDE_STATUS) & STAT_BUSY)	        ;            while ((sysInByte (IDE_STATUS) & STAT_READY) == 0)	        ;	    wdCancel (ideWid);	    break;	case STAT_DRQ:            while ((sysInByte (IDE_STATUS) & STAT_DRQ) == 0)	        ;	    break;	case STAT_SEEKCMPLT:            while ((sysInByte (IDE_STATUS) & STAT_SEEKCMPLT) == 0)	        ;	    break;	}    if (ideDebug)	printErr ("ideWait end: \n");    }/********************************************************************************* ideInit - init a IDE disk controller** This routine initializes a IDE disk controller.** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL void ideInit (void)    {    int ix;    sysOutByte (IDE_D_CONTROL, CTL_RST | CTL_IDS);    for (ix = 0; ix < 100; ix++)        sysDelay ();    sysOutByte (IDE_D_CONTROL, CTL_IDS);    for (ix = 0; ix < 100; ix++)        sysDelay ();    while ((sysInByte (IDE_STATUS) & STAT_BUSY) && (ideWaitForever))	;    sysOutByte (IDE_D_CONTROL, CTL_4BIT);    for (ix = 0; ix < 100; ix++)        sysDelay ();    while (((sysInByte (IDE_STATUS) & STAT_READY) == 0) && (ideWaitForever))	;    semBInit (&ideSyncSem, SEM_Q_FIFO, SEM_EMPTY);    if (ideDebug)	printErr ("ideInit end: \n");    }/********************************************************************************* ideDiagnose - diagnose the drive** Diagnose the drive** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS ideDiagnose (void)    {    int error;    int semStatus;    sysOutByte (IDE_SDH, SDH_IBM);    ideWait (STAT_READY);    sysOutByte (IDE_COMMAND, CMD_DIAGNOSE);    semStatus = semTake (&ideSyncSem, sysClkRateGet() * ideSemSec);    if (((error = sysInByte(IDE_ERROR)) != DIAG_OK) || (semStatus == ERROR))	{	if (ideDebugErr)	    printErr ("ideDiagnose: status=0x%x error=0x%x\n", 		      ideStatus, error);	return (ERROR);	}    ideWait (STAT_READY);    if (ideDebug)	printErr ("ideDiagnose end: \n");    return (OK);    }/********************************************************************************* idePinit - Initialize drive parameters** Initialize drive parameters.** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS idePinit    (    int drive    )    {    int status;    int error;    int semStatus;    int retryCount = 0;    IDE_TYPE *pType = &ideTypes[drive];retryPinit:    sysOutByte (IDE_CYL_LO, pType->cylinders);    sysOutByte (IDE_CYL_HI, pType->cylinders >> 8);    sysOutByte (IDE_SECCNT, pType->sectorsTrack);    sysOutByte (IDE_SDH, SDH_IBM | (drive << 4) | ((pType->heads & 0xf) - 1));    ideWait (STAT_READY);    sysOutByte (IDE_COMMAND, CMD_INITP);    semStatus = semTake (&ideSyncSem, sysClkRateGet() * ideSemSec);    if ((ideStatus & STAT_ERR) || (semStatus == ERROR))	{	error = sysInByte (IDE_ERROR);	status = sysInByte (IDE_STATUS);	ideInit ();	if (ideDebugErr)            printErr ("idePinit%d err: stat=0x%x 0x%x error=0x%x\n",	              drive, ideStatus, status, error);	if (++retryCount < ideRetry)	    goto retryPinit;	return (ERROR);	}    ideWait (STAT_READY);    if (ideDebug)	printErr ("idePinit%d end: \n", drive);    return (OK);    }/********************************************************************************* idePread - Read drive parameters** Read drive parameters.** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS idePread    (    int drive,    void *buffer    )    {    int status;    int error;    int semStatus;    int retryCount = 0;retryPread:    sysOutByte (IDE_SDH, SDH_IBM | (drive << 4));    ideWait (STAT_READY);    sysOutByte (IDE_COMMAND, CMD_READP);    semStatus = semTake (&ideSyncSem, sysClkRateGet() * ideSemSec);    if ((ideStatus & STAT_ERR) || (semStatus == ERROR))	{	error = sysInByte (IDE_ERROR);	status = sysInByte (IDE_STATUS);	ideInit ();	if (ideDebugErr)            printErr ("idePread%d err: stat=0x%x 0x%x error=0x%x\n",	              drive, ideStatus, status, error);	if (++retryCount < ideRetry)	    goto retryPread;	return (ERROR);	}    ideWait (STAT_DRQ);    sysInWordString (IDE_DATA, (short *)buffer, 256);    ideWait (STAT_READY);    if (ideDebug)	printErr ("idePread%d end: \n", drive);    return (OK);    }/********************************************************************************* ideRecalib - recalibrate the drive** Recalibrate the drive** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS ideRecalib    (    int drive    )    {    int status;    int error;    int semStatus;    int retryCount = 0;retryRecalib:    sysOutByte (IDE_SDH, SDH_IBM | (drive << 4));    ideWait (STAT_READY);    sysOutByte (IDE_COMMAND, CMD_RECALIB);    semStatus = semTake (&ideSyncSem, sysClkRateGet() * ideSemSec);    if ((ideStatus & STAT_ERR) || (semStatus == ERROR))	{	error = sysInByte (IDE_ERROR);	status = sysInByte (IDE_STATUS);	ideInit ();	if (ideDebugErr)	    printErr ("ideRecalib%d err: status=0x%x 0x%x error=0x%x\n",	              drive, ideStatus, status, error);	if (++retryCount < ideRetry)	    goto retryRecalib;	return (ERROR);	}        ideWait (STAT_READY);    if (ideDebug)	printErr ("ideRecalib%d end: \n", drive);    return (OK);    }/********************************************************************************* ideSeek - seek the drive heads to the specified cylinder** Seek the drive heads to the specified cylinder** RETURNS: OK, ERROR if the command didn't succeed.*/LOCAL STATUS ideSeek    (    int drive,    int cylinder,    int head    )    {    int status;    int error;    int semStatus;    int retryCount = 0;retrySeek:    sysOutByte (IDE_CYL_LO, cylinder);    sysOutByte (IDE_CYL_HI, cylinder>>8);    sysOutByte (IDE_SDH, SDH_IBM | (drive << 4) | (head & 0xf));    ideWait (STAT_READY);    sysOutByte (IDE_COMMAND, CMD_SEEK);    semStatus = semTake (&ideSyncSem, sysClkRateGet() * ideSemSec);    if ((ideStatus & STAT_ERR) || (semStatus == ERROR))	{	error = sysInByte (IDE_ERROR);	status = sysInByte (IDE_STATUS);	ideInit ();	if (ideDebugErr)	    printErr ("ideSeek%d err: c=%d h=%d status=0x%x 0x%x error=0x%x\n",		      drive, cylinder, head, ideStatus, status, error);	if (++retryCount < ideRetry)	    goto retrySeek;	return (ERROR);	}    ideWait (STAT_SEEKCMPLT);    ideWait (STAT_READY);    if (ideDebug)	printErr ("ideSeek%d end: c=%d h=%d\n", drive, cylinder, head);    return (OK);    }/********************************************************************************* ideRW - 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 ideRW    (    int drive,    int cylinder,    int head,    int sector,    void *buffer,    int nSecs,    int direction    )    {    int ix;    int status;    int error;    int semStatus;    int retryCount = 0;    short *pBuf = (short *)buffer;    IDE_TYPE *pType = &ideTypes[drive];    int nWords = pType->bytesSector >> 1;retryRW:    sysOutByte (IDE_PRECOMP, pType->precomp);    sysOutByte (IDE_SECCNT, nSecs);    sysOutByte (IDE_SECTOR, sector);    sysOutByte (IDE_CYL_LO, cylinder);    sysOutByte (IDE_CYL_HI, cylinder>>8);    sysOutByte (IDE_SDH, SDH_IBM | (drive << 4) | (head & 0xf));    ideWait (STAT_READY);    if (direction == O_WRONLY)	{	sysOutByte (IDE_COMMAND, CMD_WRITE);	for (ix = 0; ix < nSecs; ix++)	    {            ideWait (STAT_DRQ);	    sysOutWordString (IDE_DATA, pBuf, nWords);            semStatus = semTake (&ideSyncSem, sysClkRateGet() * ideSemSec);    	    if ((ideStatus & STAT_ERR) || (semStatus == ERROR))	        goto errorRW;	    pBuf += nWords;            }	}    else	{	sysOutByte (IDE_COMMAND, CMD_READ);	for (ix = 0; ix < nSecs; ix++)	    {            semStatus = semTake (&ideSyncSem, sysClkRateGet() * ideSemSec);    	    if ((ideStatus & STAT_ERR) || (semStatus == ERROR))	        goto errorRW;            ideWait (STAT_DRQ);	    sysInWordString (IDE_DATA, pBuf, nWords);	    pBuf += nWords;	    }	}    ideWait (STAT_READY);    if (ideDebug)	printErr ("ideRW%d end: c=%d h=%d s=%d buf=0x%x n=%d dir=%d\n",                  drive, cylinder, head, sector, (int)buffer, nSecs, direction);    return (OK);errorRW:    error = sysInByte (IDE_ERROR);    status = sysInByte (IDE_STATUS);    ideInit ();    if (ideDebugErr)	{        printErr ("ideRW%d err: c=%d h=%d s=%d buf=0x%x n=%d dir=%d ",                  drive, cylinder, head, sector, (int)buffer, nSecs, direction);        printErr ("stat=0x%x 0x%x error=0x%x\n", ideStatus, status, error);	}    if (++retryCount < ideRetry)	goto retryRW;    return (ERROR);    }/********************************************************************************* ideFormat - format the current track** format the current track; not supported.** RETURNS: ERROR always.*/LOCAL STATUS ideFormat    (    int drive,    int cylinder,    int head,    int interleave    )    {    return (ERROR);    }

⌨️ 快捷键说明

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