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

📄 fdcdrv.c

📁 WINDRIVER MCP750 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
    (    register FDC_DEV *pDev,		/* pointer to device descriptor */    register UINT startBlk,		/* starting block to write */    register UINT numBlks,		/* number of blocks to write */    register char *pBuf 		/* pointer to buffer of send data */    )    {    register UINT localStatus;	/* local status variable */    FDC_CMDPCKT fdcCmdPacket;	/* command packet */    /*     * verify the request against the logical block parameters (all     * or nothing)     */    if ((startBlk + pDev->blockOffset + numBlks) > pDev->blockTotal) 	{        return (ERROR);	}    /* check for a NOP request */    if (!numBlks) 	{        errno = S_ioLib_DEVICE_ERROR;        return (ERROR);	}    /* build command packet */    fdcCmdPacket.command = FDC_WRITOP;    fdcCmdPacket.status = 0;    fdcCmdPacket.memaddr = (UINT)pBuf;    fdcCmdPacket.blcknum = startBlk + pDev->blockOffset;    fdcCmdPacket.nblcks = numBlks;    fdcCmdPacket.tdflg = 0;    fdcCmdPacket.aescount = 0;    /* take ownership, call driver, release ownership */    semTake(fdcDrvSemId, WAIT_FOREVER);    localStatus = fdcDrvMain(pDev, (FDC_CMDPCKT *)&fdcCmdPacket);    semGive(fdcDrvSemId);    return ((localStatus ? ERROR : OK));    }/********************************************************************************* fdcIoctl - fdc i/o control** This function's purpose is to perform the specified I/O control* operation.** RETURNS: OK, or ERROR if ioctl request failed*/LOCAL STATUS fdcIoctl    (    register FDC_DEV *pDev,	/* pointer to device descriptor */    register int funcCode,	/* ioctl() function code */    register int arg 		/* function-specific argument */    )    {    register UINT localStatus;	/* local status variable */    FDC_CMDPCKT fdcCmdPacket;	/* command packet */    switch (funcCode) 	{        case FIODISKFORMAT:	    /* build command packet */	    fdcCmdPacket.command = FDC_FRMTOP;	    fdcCmdPacket.status = 0;	    fdcCmdPacket.memaddr = 0;	    fdcCmdPacket.blcknum = 0;	    fdcCmdPacket.nblcks = 0;	    fdcCmdPacket.tdflg = 'D';	    fdcCmdPacket.aescount = 0;	    /* take ownership, call driver, release ownership */	    semTake(fdcDrvSemId, WAIT_FOREVER);	    localStatus = fdcDrvMain(pDev, (FDC_CMDPCKT *)&fdcCmdPacket);	    semGive(fdcDrvSemId);	    break;        default:	    errno = S_ioLib_UNKNOWN_REQUEST;	    localStatus = ERROR;	    break;	}    return ((localStatus ? ERROR : OK));    }/********************************************************************************* fdcStatusChk - fdc status check** This function's purpose is to perform a status check on the* specified device.  The status check basically checks to see* if the disk has been changed.** RETURNS: OK, or ERROR if check fails*/LOCAL STATUS fdcStatusChk    (    register FDC_DEV *pDev		/* pointer to device descriptor */    )    {    register STATUS lstatus;	/* local error status */    register FDC *pFdc;		/* FDC registers pointer */    FDC_CMDPCKT fdcCmdPacket;	/* command packet */    FDC_CRDATA fdc_crdata;    /*     * initialize pointer to FDC registers     * initialize local error status variable     */    pFdc = (FDC *)fdcDrvBaseAddress;    lstatus = OK;    /* take ownership */    semTake(fdcDrvSemId, WAIT_FOREVER);    /* motor on */    pFdc->dor |= (pDev->driveNumber | (0x10 << pDev->driveNumber));    EIEIO_SYNC;    /*     * query the digital input register for a disk change status, if     * a disk change has occurred, set the "ready change" flag     */    if (pFdc->dir_ccr & FDC_DIR_PS2_DSKCHG) 	{           /* set the "ready change" flag */        pDev->fdcBlockDev.bd_readyChanged = TRUE;        /* build command packet */        fdcCmdPacket.command = FDC_CHCKOP;        fdcCmdPacket.status = 0;        fdcCmdPacket.memaddr = 0;        fdcCmdPacket.blcknum = 0;        fdcCmdPacket.nblcks = 0;        fdcCmdPacket.tdflg = 0;        fdcCmdPacket.aescount = 0;        /* initialize interrupt handler arguments data structure */        fdcDrvIArgs.pDev = pDev;        fdcDrvIArgs.pCmd = (FDC_CMDPCKT *)&fdcCmdPacket;        fdcDrvIArgs.pFdc = pFdc;        fdcDrvIArgs.cr_data_p = (FDC_CRDATA *)&fdc_crdata;        /* check state (take to known state) */        if (fdcCheck(pDev, (FDC_DEV *)&fdcCmdPacket, pFdc, fdc_crdata, 1)) 	    {	    lstatus = ERROR;            }   	}    /* motor off */    pFdc->dor &= (FDC_DOR_DMAEN|FDC_DOR_RESET);    /* release ownership */    semGive(fdcDrvSemId);    return (lstatus);    }/********************************************************************************* fdcDrvMain - fdc driver main entry point** This function's purpose is the main entry point into the FDC* Floppy Disk I/O driver.* * RETURNS: 0 if OK, non-zero for error condition which means the status*  word in the command packet is set.*/LOCAL UINT fdcDrvMain    (    register FDC_DEV *pDev,	/* device descriptor pointer */    register FDC_CMDPCKT *pCmd 	/* command packet pointer */    )    {    register UINT lstatus;	/* local error status */    FDC_CRDATA fdc_crdata;    /* setup local error status (error condition) */    lstatus = (UINT)-1;    /* initialize interrupt handler arguments data structure */    fdcDrvIArgs.pDev = pDev;    fdcDrvIArgs.pCmd = pCmd;    fdcDrvIArgs.pFdc = (FDC *)fdcDrvBaseAddress;    fdcDrvIArgs.cr_data_p = (FDC_CRDATA *)&fdc_crdata;    /* perform the requested action */    switch (pCmd->command) 	{        case FDC_READOP:        case FDC_WRITOP:	    /*	     * sanity check of block size/number of blocks/physical	     * sector size	     */	    if ((pCmd->command == FDC_READOP) || (pCmd->command == FDC_WRITOP)) 		{	        if (fdcXfrcheck(pDev, pCmd, 0)) 		    {	            break;	    	    }	 	}	    if (!(fdcXfer(pDev, pCmd, (FDC *)fdcDrvBaseAddress, fdc_crdata))) 		{	        lstatus = 0;	 	}	    break;	case FDC_FRMTOP:	    if (!(fdcFormat(pDev, pCmd, (FDC *)fdcDrvBaseAddress, fdc_crdata)))		{	    	lstatus = 0;	 	}	    break;	}    if (lstatus) 	errno = S_ioLib_DEVICE_ERROR;    return (lstatus);    }/********************************************************************************* fdcXfer - read/write transfer** This function's purpose is to perform the specified data* transfers with the specified device.  The data requests* are blocked to a track size, only a one track can be* read/written at a time.** RETURNS: 0 if OK, non-zero for error condition which means the status*  word in the command packet is set.*/LOCAL UINT fdcXfer    (    register FDC_DEV *pDev,		/* device descriptor pointer */    register FDC_CMDPCKT *pCmd,		/* command packet pointer */    register FDC *pFdc,			/* FDC registers pointer */    register FDC_CRDATA *cr_data_p 	/* command/result data pointer */    )    {    register UINT bufadd;		/* starting address of data transfer */    register UINT t_count, m_count;	/* data count variables */    register UINT d_count, x_count;	/* data count variables */    register UINT l_count;		/* loop count variable */    register UINT lstatus;		/* local status flag */    register UCHAR statusx;		/* status register copy */    register UINT e_sector;		/* ending sector numbner */    register UCHAR *pd_p;		/* phase data pointer */    struct fdc_pos pos;    /* setup the return status */    lstatus = 0;    /*     * calculate starting logical sector number of data     * transfer, this is only done once     */    pos.lsector =        fdc_clsn( pCmd->blcknum, pDev->fdcType.sectorsize,	          pDev->blockSize, pDev->fdcType.sectorstrack, 1 );    /*     * calculate the number of bytes in a track, this is the     * maximum number of bytes that can be transferred at one     * given time     *     * calculate the number of bytes that the user specified     */    t_count = pDev->fdcType.sectorsize * pDev->fdcType.sectorstrack;    m_count = pCmd->nblcks * pDev->blockSize;    /* check the sanity of number of blocks requested */    if (((pos.lsector * pDev->fdcType.sectorsize) + m_count) >        (t_count * pDev->fdcType.numberofheads * pDev->fdcType.numberoftracks)) 	{        pCmd->status = FDC_ERROR_ILLDREQ;        return ((UINT)-1);   	}    /* check state (take to known state) */    if (fdcCheck(pDev, pCmd, pFdc, cr_data_p, 0)) 	{        lstatus = (UINT)-1;        m_count = 0;	}    /*     * setup starting address of data transfer     * read/write data tracks loop     */    bufadd = pCmd->memaddr;    for (l_count = 0; m_count; l_count++) 	{         	/* calculate floppy disk address from logical sector number */      	fdcCP( pDev->fdcType.numberofheads,	     pDev->fdcType.sectorstrack,	     (struct fdc_pos *)&pos );      	/*         * seek to track for initial data transfer         *         * if the seek to track call fails, post error status and         * terminate for loop         */      	if (l_count == 0) 	    {	    if (fdcSeek(pDev, pCmd, pFdc, cr_data_p, pos.headno, pos.cylndrno)) 		{	        lstatus = (UINT)-1;	        break;	 	}      	    }      	/*         * calculate the size (number of bytes) for this transfer         * calculate the ending sector number for this transfer         */      	if (pos.sectorno > 1) 	    {	    d_count = 		((pDev->fdcType.sectorstrack - 		 (pos.sectorno - 1)) * pDev->fdcType.sectorsize);	    if (d_count >= m_count) 		{	    	d_count = m_count;	    	e_sector = 		    ((d_count / pDev->fdcType.sectorsize) - 1) + pos.sectorno;	 	} 	    else 		{	        e_sector = pDev->fdcType.sectorstrack;	 	}      	    } 	else 	    {	    if (m_count >= t_count) 		{	        d_count = t_count;	 	} 	    else 		{	        d_count = m_count;		}	   e_sector = d_count / pDev->fdcType.sectorsize;      	   }      	/* setup the "read-data" or "write-data" command structure */      	pd_p = (UCHAR *)&cr_data_p->c_data.c_justdata.databytes[0];      	bzero((UCHAR *)cr_data_p, sizeof(FDC_CRDATA));      	pd_p[0] = FDC_CP_MFM | 		  ((pCmd->command == FDC_READOP) ? 		   FDC_CS_READDATA : FDC_CS_WRITEDATA);              pd_p[1] = pDev->driveNumber | (pos.headno ? FDC_ST0_HDS : 0);        pd_p[2] = pos.cylndrno;        pd_p[3] = pos.headno;        pd_p[4] = pos.sectorno;        pd_p[5] = fdcSCode(pDev->fdcType.sectorsize);        pd_p[6] = (UCHAR)e_sector;        pd_p[7] = (UCHAR)pDev->fdcType.gaprw;        pd_p[8] = 0xFF;        /* setup/start DMA controller */        if (fdcDrvDmaChannel != (UINT)-1) 	    {	    /* copy caller's buffer to internal buffer */	    if (pCmd->command == FDC_WRITOP) 		{	        memcpy((void *) pDev->dmaBuffer, (void *) bufadd, d_count);	        cacheFlush(DATA_CACHE, (void *)pDev->dmaBuffer, d_count);	 	}	    /* initialize DMA controller for DMA data transfer */	    isaDmaStart( fdcDrvDmaChannel,		         I8237_MODE_TM_DEMAND,		         ((pCmd->command == FDC_READOP) ? 			  I8237_MODE_TT_WRITE : I8237_MODE_TT_READ),		         pDev->dmaBuffer, d_count );	    }	/* issue the "read-data" or the "write-data" command */      	fdcExeCmd(pFdc, pd_p, sizeof(cr_data_p->c_data.c_readdata));      	/* wait for interrupt, or poll for completion */      	if (fdcDrvIntVector != (UINT)-1) 	    {	    if (semTake(pDev->intSemId, pDev->sysClkRate * 2) == ERROR) 		{	        pFdc->fifo = 0x00;	        EIEIO_SYNC;	        isaDmaStop(fdcDrvDmaChannel);	        x_count = 0;	 	} 	    else 		{	        x_count = d_count;	 	}      	    } 	else 	    {	    /* poll DMA controller for completion (terminal count) */	    if (fdcDrvDmaChannel != (UINT)-1) 		{	        for (x_count = 0;; x_count++) 		    {			/* sleep for a bit (10ms) */	       		fdcDelay(10);			/* retrieve DMA controller status */	       		if ((statusx = 				(UCHAR)isaDmaStatus(fdcDrvDmaChannel)) == 1) 			    {		  	    x_count = d_count;		  	    break;	       		    } 			else 			    {		  	    if (x_count >= (2000/10)) 				{		     		pFdc->fifo = 0x00;		     		EIEIO_SYNC;

⌨️ 快捷键说明

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