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

📄 fdcdrv.c

📁 WINDRIVER MCP750 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
* fdcCP - calculate position* * This function's purpose is to calculate the position, in other* words, the physical sector number, the physical head number,* and the cylinder number.** RETURNS: N/A*/LOCAL void fdcCP    (    register UINT nheads,		/* number of heads */    register UINT sectrk,		/* sectors per track */    register struct fdc_pos *p	 	/* pointer to position template */    )    {    p->cylndrno = (USHORT)(p->lsector / (nheads * sectrk));    p->headno = (UCHAR)((p->lsector % (nheads * sectrk)) / sectrk);    p->sectorno = (UCHAR)(p->lsector % sectrk);    p->sectorno += 1;    }/********************************************************************************* fdcRxd - receive data from FIFO** This function's purpose is to retrieve one byte from the* data FIFO for command execution status (result phase data).** RETURNS: Data-Byte, or -1 on FIFO timeout.*/LOCAL UINT fdcRxd    (    register FDC *pFdc		/* FDC registers pointer */    )    {    register UCHAR rdata;	/* read data local variable */    register UINT acount;	/* access count variable */    /*     * poll MSR for data availability, if data is availabilty,     * read data FIFO and return with read data     */    for (acount = 0;;) 	{        rdata = pFdc->msr_dsr;        if ((rdata & (FDC_MSR_RQM|FDC_MSR_DIO|FDC_MSR_NONDMA)) ==	    (FDC_MSR_RQM|FDC_MSR_DIO)) 	    {	    rdata = pFdc->fifo;	    return (rdata);	    } 	else 	    {	    if (++acount > FDC_TIMEOUTCOUNT) 		{	        return ((UINT)-1);		}	    }	}    }/********************************************************************************* fdcTxd - transmit (send) byte to data FIFO**	This function's purpose is to send one byte to the*	data FIFO for command execution.** RETURNS: OK, or -1 on FIFO timeout*/LOCAL UINT fdcTxd    (    register FDC *pFdc,		/* FDC registers pointer */    register UCHAR wdata	/* write data */    )    {    register UCHAR rdata;	/* read data local variable */    register UINT acount;	/* access count variable */    /*     * poll MSR for data fifo availability, if data fifo is availabilty,     * write data FIFO and return     */    for (acount = 0;;) 	{        rdata = pFdc->msr_dsr;        if ((rdata & (FDC_MSR_RQM|FDC_MSR_DIO|FDC_MSR_NONDMA)) ==	    (FDC_MSR_RQM)) 	    {	    pFdc->fifo = wdata;	    break;	    }         else 	    {	    if (++acount > FDC_TIMEOUTCOUNT) 		{	        return ((UINT)-1);		}	    }	}    return (OK);    }/********************************************************************************* fdcStat - retrieve command execution status (results)** This function's purpose is to retrieve the command execution* status (results) bytes from the data FIFO.  The status bytes* are placed into the buffer as specified by the caller's* arguments.** RETURNS: N/A*/LOCAL void fdcStat    (    register FDC *pFdc,		/* FDC registers pointer */    register UCHAR *data_p,		/* data pointer */    register UINT data_s		/* data size in bytes */    )    {    register UINT rdata;		/* read data local variable */    for (; data_s; data_s--, data_p++) 	{        rdata = fdcRxd(pFdc);        if (rdata == (UINT)-1) 	    break;        *data_p = rdata;        }    }/******************************************************************************** fdcExeCmd - execute command** This function's purpose is to execute the specified command as* specified by the passed data (pointer and size arguments).** RETURNS: N/A*/LOCAL void fdcExeCmd    (    register FDC *pFdc,		/* FDC registers pointer */    register UCHAR *data_p,	/* data pointer */    register UINT data_s	/* data size in bytes */    )    {    register UINT rdata;		/* read data local variable */    for (; data_s; data_s--, data_p++) 	{        rdata = fdcTxd(pFdc, *data_p);        if (rdata == (UINT)-1) break;        }    }/********************************************************************************* fdcRxdEp - receive data from FIFO, execution phase* * This function's purpose is to retrieve all data from the* data FIFO for the command execution phase.  Only the* number of bytes as specified will be transferred to* the data buffer.** RETURNS: number of bytes read*/LOCAL UINT fdcRxdEp    (    register FDC *pFdc,		/* FDC registers pointer */    register UCHAR *data_p,	/* data pointer */    register UINT data_s	/* data size */    )    {    register UINT dcount;	/* local data count variable */    register UINT acount;	/* access count variable */    register UCHAR rdata;	/* read data local variable */    /*     * poll MSR for data availability, if data is availabilty,     * read data FIFO and write to caller's data buffer, exit     * if the the FIFO changes state (execution to result)     */    for (acount = 0, dcount = 0; dcount < data_s;) 	{        rdata = pFdc->msr_dsr;        EIEIO_SYNC;        if (rdata & FDC_MSR_RQM) 	    {	    if ((rdata & (FDC_MSR_NONDMA|FDC_MSR_DIO)) ==	        (FDC_MSR_NONDMA|FDC_MSR_DIO)) 		{	        rdata = pFdc->fifo;	        EIEIO_SYNC;	        *data_p++ = rdata;	        dcount++;	        acount = 0;		} 	    else 		{	        break;		}	    }         else 	    {	    if (++acount > FDC_TIMEOUTCOUNT) 		{	        pFdc->fifo = 0x00;	        break;		}	    }	}    return (dcount);    }/********************************************************************************* fdcTxdEp - transmit data to FIFO, execution phase** This function's purpose is to read all data from the data* caller's buffer and write it to the data FIFO.  This is for* the command execution phase only.  Only the number of bytes* as specified will be transferred to the data FIFO.* * RETURNS: number of bytes written.*/LOCAL UINT fdcTxdEp    (    register FDC *pFdc,		/* FDC registers pointer */    register UCHAR *data_p,	/* data pointer */    register UINT data_s	/* data size */    )    {    register UINT dcount;	/* local data count variable */    register UINT acount;	/* access count variable */    register UCHAR rdata;	/* read data local variable */    /*     * poll MSR for data availability, if data is availabilty,     * read caller's data buffer and write data to FIFO, exit     * if the the FIFO changes state (execution to result)     */    for (acount = 0, dcount = 0; dcount < data_s;) 	{        rdata = pFdc->msr_dsr;        EIEIO_SYNC;        if (rdata & FDC_MSR_RQM) 	    {	    if ((rdata & (FDC_MSR_NONDMA|FDC_MSR_DIO)) ==	        (FDC_MSR_NONDMA)) 		{	    pFdc->fifo = *data_p++;	    dcount++;	    EIEIO_SYNC;	    acount = 0;		} 	    else 		{	    break;		}	    } 	else 	    {	    if (++acount > FDC_TIMEOUTCOUNT) 		{	        pFdc->fifo = 0x00;	        break;		}	    }	}    return (dcount);    }/********************************************************************************* fdcDRCode - return data-rate code* *This function's purpose is to return the data-rate code.*This based upon the speed and sectors per track.** RETURNS: data-rate code*/LOCAL UCHAR fdcDRCode    (    register FDC_DEV *pDev		/* device descriptor pointer */    )    {    register UCHAR datarate;    switch (pDev->fdcType.ratedata) 	{        case 250:	    datarate = 0x02;	    break;        case 500:	    datarate = 0x00;	    break;        case 1000:	    datarate = 0x03;	    break;        default:	    datarate = 0x00;	    break;	}    return (datarate);    }/********************************************************************************* fdcSCode - return sector code** This function's purpose is to return the sector code based* upon the physical sector size.** RETURNS: sector code.*/LOCAL UINT fdcSCode    (    register UINT ssize		/* sector size */    )    {    register UINT multiple, npower;    multiple = ssize / 128;	/* divide by base code value */    for (npower = 0;; multiple >>= 1, npower++) 	{        if (multiple & 0x1) 	    {	    break;	    }	}    return (npower);    }/********************************************************************************* fdcSetAES - setup additional error status information** This function's purpose is to setup the additional error status* information packet in the mass storage i/o subsystem.  This* additional error status information is used by the upper layers* for display/reporting of errors.** RETURNS: N/A*/LOCAL void fdcSetAES    (    register FDC_CMDPCKT *pCmd,	/* command packet pointer */    register UCHAR *p,		/* status data pointer */    register UINT s		/* status data size (i.e., number of bytes) */    )    {    register UINT index;    pCmd->aescount = s;    for (index = 0; index < s; pCmd->aesdata[index++] = *p++);    }/********************************************************************************* fdcDelay - delay** This function's purpose is to delay (sleep) for the specified* number of milli-seconds.** RETURNS: N/A*/LOCAL void fdcDelay    (    register UINT msDelay	/* number of milli-seconds to delay */    )    {    register UINT msTicks;    msTicks = 1000 / sysClkRateGet();    if (msDelay % msTicks) msDelay += msTicks;    taskDelay(msDelay / msTicks);    }/********************************************************************************* fdcXfrcheck - sanity check on transfer request** This function's purpose is to make a sanity check on the transfer* request, this is done by examining the logical block size in* conjunction with the physical block size of the media and the number* of requested logical blocks.  If the block number denotes a* physical block number (not a file number), the block number is checked* for the modulus condition.** RETURNS: OK, or ERROR if sanity check failed*/LOCAL UINT fdcXfrcheck    (    register FDC_DEV *pDev,		/* device descriptor pointer */    register FDC_CMDPCKT *pCmd,	/* command packet pointer */    register UINT bvsf	/* block number verse file number flag, true = file */    )    {    if (!((pCmd->nblcks * pDev->blockSize) / pDev->fdcType.sectorsize)        || ((pCmd->nblcks * pDev->blockSize) % pDev->fdcType.sectorsize)) 	{        pCmd->status = FDC_ERROR_ILLDREQ;        return ((UINT) -1);	}    if (pDev->blockSize < pDev->fdcType.sectorsize) 	{	if (!bvsf) 	/* block or file number? */	    {	    if (pCmd->blcknum % (pDev->fdcType.sectorsize / pDev->blockSize)) 		{		pCmd->status = FDC_ERROR_ILLDREQ;		return ((UINT) -1);		}	    }	}    return (OK);    }/********************************************************************************* fdcInt - FDC interrupt handler** This function's purpose is handle/process the FDC interrupt* request.  The FDC's interrupt request line is active high, and* is edge triggered.  The interrupt request line is negated* when the result bytes are read from the FDC.  This interrupt* handler basically returns control to the task that is blocked* on the interrupt semaphore (taking ownership).** RETURNS: N/A*/LOCAL void fdcInt    (    register FDC_IARGS *pFdcIArgs    )    {    /* increment global interrupt counter */    fdcDrvIntCount[pFdcIArgs->pDev->driveNumber] += 1;    /* return to task level */    if (fdcDrvIntVector != (UINT)-1) 	{	semGive(pFdcIArgs->pDev->intSemId);	}    }#endif /* INCLUDE_FD */

⌨️ 快捷键说明

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