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

📄 fdcdrv.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 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_FDC */

⌨️ 快捷键说明

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