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

📄 fdcdrv.c

📁 WINDRIVER MCP750 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
/* fdcDrv.c - Floppy Disk Controller (FDC) Input/Output Driver Module *//* Copyright 1984-2001 Wind River Systems, Inc. *//* Copyright 1996,1997,1998 Motorola, Inc., All Rights Reserved *//*modification history--------------------01c,16sep01,dat  Use of WRS_ASM macro01b,15apr98,dat  added INCLUDE_FD, using macros FD_BASE_ADDR and		 FD_DMA_CHAN to match old API for fdDrv().01a,12dec97,rbb  created by Motorola.*//*DESCRIPTIONThis is the I/O driver for a standard PS2 floppy device controller (FDC).This driver is normally included as a source file, and expects the macroINCLUDE_FD to be defined if any code is to be compiled.USER CALLABLE ROUTINESMost of the routines in this driver are accessible only through the I/Osystem.  Two routines, however, must be called directly: fdDrv() toinitialize the driver, and fdDevCreate() to create devices.Before using the driver, it must be initialized by calling the fdDrv().The macros FD_BASE_ADDR and FD_DMA_CHAN are needed to provide the baseaddress of the floppy disk controller device and the DMA channel numberto be used. (This is to maintain compatibility with the existing API forfdDrv() )..CSSTATUS fdDrv    (    UINT intVector,		// interrupt vector    UINT intLevel		// interrupt level    ).CEThis routine initializes the floppy disk controller driver, sets upinterrupt vectors, and performs hardware initialization of the floppydisk controller chip.This routine should be called exactly once, before any reads, writes,or calls to fdDevCreate().  Normally, it is called from usrRoot() inusrConfig.c.CREATING DISK DEVICESBefore a disk device can be used, it must be created.  This is donewith the fdDevCreate() call.  Each floppy disk drive to be used mayhave one or more devices associated with it, by calling this routine.The way the device is created with this call determines the floppydiskette type, and whether it covers the whole disk or just part ofit.fdDevCreate() - create a device for a floppy disk.CSBLK_DEV *fdDevCreate    (    UINT driveNumber,		// drive number (0 to 3)    UINT fdType,		// type of floppy disk (table index)    UINT nBlocks,		// device size in blocks (0 = whole disk)    UINT blkOffset 		// offset from start of device    ).CEThis routine creates a device for a specified floppy disk.The driveNumber parameter is the drive number of the floppy disk; validvalues are 0 to 3.The fdType parameter specifies the type of diskette, which is describedin the structure table fdcTypes[] in fdcDrv.c.  fdcType is an indexinto the table.  Currently the table contains two diskette types: - An fdcType of 0 indicates the first entry in the table (3.5" 2HD, 1.44MB); - An fdcType of 1 indicates the second entry in the table (3.5" 2HD, 720KB);Members of the fdcTypes[] structure are:   UINT numberofheads;		// number of heads (sides)   UINT numberoftracks;		// number of tracks   UINT sectorstrack;		// sectors (blocks) per track   UINT sectorsize;		// sector (block) size in bytes   UINT ratestep;		// step rate   UINT ratedata;		// data rate   UINT gaprw;			// read/write sector gap   UINT gapformat;		// format gapThe nBlocks parameter specifies the size of the device, in blocks.  IfnBlocks is zero, the whole disk is used.The blkOffset parameter specifies an offset, in blocks, from the startof the device to be used when writing or reading the floppy disk.  Thisoffset is added to the block numbers passed by the file system duringdisk accesses.  (VxWorks file systems always use block numbers beginningat zero for the start of a device.)  Normally, blkOffset is 0.For instance, to create a rawFs compatible device, covering the wholedisk (3.5" 2HD, 1.44MB) on drive 0, the proper call would be:.CS    fdDevCreate (0, 0, 0, 0);.CEIOCTLThis driver responds to all the same ioctl codes as a normal blockdevice driver.  To format a disk use FIODISKFORMAT.CAVEATSNo mechanism exists for detecting the change of media.  The driverdoes not support the concurrent operation of multiple drives.  Thisis due to the fact that all drives share the same DMA channel.*//* * includes * * include file paths are dependent on makefile */#include "vxWorks.h"	/* vxWorks generics */#include "taskLib.h"	/* taskLib functions */#include "ioLib.h"	/* input/output generics */#include "blkIo.h"	/* block input/output specifics */#include "semLib.h"	/* semaphore operations */#include "cacheLib.h"	/* cache control */#include "intLib.h"	/* interrupt control */#include "errnoLib.h"	/* error number */#include "string.h"#include "fdc.h"	/* floppy disk controller (FDC) */#include "fdcDrv.h"	/* floppy disk controller (FDC) driver header */#include "i8237.h"	/* i8237 DMA controller device */#ifdef INCLUDE_FD	/* do nothing, if not defined *//* defines */#ifndef EIEIO_SYNC# define EIEIO_SYNC  _WRS_ASM(" eieio; sync")#endif  /* EIEIO_SYNC *//* typedefs *//* globals */LOCAL UINT fdcDrvInitFlag = 0;		/* driver initialization flag */LOCAL UINT fdcDrvBaseAddress = 0;	/* base address of FDC */LOCAL UINT fdcDrvIntVector = (UINT)-1;	/* interrupt vector number */LOCAL UINT fdcDrvIntLevel = (UINT)-1;	/* interrupt level number */LOCAL UINT fdcDrvDmaChannel = (UINT)-1;	/* DMA channel number */LOCAL SEM_ID fdcDrvSemId;		/* driver ownership semaphore */LOCAL FDC_IARGS fdcDrvIArgs;		/* interrupt handler arguments */LOCAL UINT fdcDrvIntCount[FDC_NDRIVES] = { 0 };/* locals */LOCAL FDC_TYPE fdcTypes[] = {   { 2, 80, 18, 512, 0, 500, 0x1B, 0x6C },	/* 1.44MB */   { 2, 80,  9, 512, 0, 250, 0x2A, 0x50 }	/* 720KB */};#define FDC_TYPES_TABLESIZE	(sizeof(fdcTypes)/sizeof(FDC_TYPE))/* forward declarations */extern STATUS fdDrv();extern BLK_DEV *fdDevCreate();LOCAL STATUS fdcIoctl();LOCAL STATUS fdcRead();LOCAL STATUS fdcWrite();LOCAL STATUS fdcStatusChk();LOCAL UINT fdcCheck();		/* check state */LOCAL UINT fdcClearReset();	/* clear reset state */LOCAL void fdcDelay();		/* delay (sleep) in milli-seconds */LOCAL UINT fdcDrvMain();	/* fdc driver main entry point */LOCAL UINT fdcFormat();		/* format track/disk */LOCAL UCHAR fdcDRCode();	/* return data-rate code */LOCAL UINT fdcInit();		/* initialize operating parameters */LOCAL void fdcInt();		/* interrupt handler */LOCAL void fdcSetAES();	/* setup additional error status information */LOCAL UINT fdc_clsn();		/* calculate logical sector number */LOCAL void fdcCP();		/* calculate position */LOCAL UINT fdcRxd();		/* receive byte from data FIFO */LOCAL UINT fdcRxdEp();		/* receive data from FIFO, execution phase */LOCAL UINT fdcSeek();		/* seek to track */LOCAL void fdcStat();	/* retrieve command execution status (results) */LOCAL UINT fdcTxd(FDC *, UCHAR);	/* transmit (send) byte to data FIFO */LOCAL UINT fdcTxdEp();		/* transmit data to FIFO, execution phase */LOCAL void fdcExeCmd();		/* execute command */LOCAL UINT fdcXfer();		/* read/write transfer */LOCAL UINT fdcXfrcheck();	/* sanity check on block size/number of blocks/sector size parameters */LOCAL UINT fdcSCode();		/* return sector code *//* externals */extern void bzero();		/* zero or clear memory routine */extern void *calloc();		/* memory allocate and clear */extern void *memalign();	/* aligned memory allocate */extern int sysClkRateGet();	/* system clock rate */extern void isaDmaInit();	/* initialize DMA (global configuration) */extern void isaDmaStart();	/* initialize DMA channel for transfer */extern void isaDmaStop();	/* disable DMA channel */extern UINT isaDmaStatus();	/* query DMA channel for transfer status *//********************************************************************************* fdDrv - initialize the floppy disk driver* * This function's purpose is to the initialize the floppy disk* controller device for operation.** The macros FD_BASE_ADDR and FD_DMA_CHAN must be defined for this driver* to compile correctly.** RETURNS: OK, or ERROR if driver initialization fails*/STATUS fdDrv    (    register UINT interruptVector,	/* interrupt vector */    register UINT interruptLevel	/* interrupt level */    )    {    register UINT baseAddress = FD_BASE_ADDR;	/* base address of FDC */    register UINT dmaChannel = FD_DMA_CHAN; 	/* DMA channel number */    /* initialize driver, if initialized, return ERROR */    if (fdcDrvInitFlag) 	{        return (ERROR);   	}    /* make some sanity of the desired mode */    if (interruptVector != (UINT)-1) 	{        if (dmaChannel == (UINT)-1) 	    {   	    return (ERROR);      	    }   	}    /* create semaphore to interlock access to the FDC */    if ((fdcDrvSemId = semBCreate(SEM_Q_PRIORITY, SEM_FULL)) == (SEM_ID)NULL) 	{        return (ERROR);   	}    /* connect/enable interrupt handler */    if (interruptVector != (UINT)-1) 	{        intConnect( (VOIDFUNCPTR *)interruptVector,		    (VOIDFUNCPTR)fdcInt,		    (int)((FDC_IARGS *)&fdcDrvIArgs) );        intEnable(interruptVector);	}    /*     * initialize the base address of FDC variable, user may override     * if the value is not zero     */    if (!fdcDrvBaseAddress) 	{        fdcDrvBaseAddress = baseAddress;	}     /*     * initialize the DMA channel number for this FDC     * initialize the interrupt vector/level     */    fdcDrvDmaChannel = dmaChannel;    fdcDrvIntVector = interruptVector;    fdcDrvIntLevel = interruptLevel;    /* set the driver initialization flag to a true state */    fdcDrvInitFlag = (UINT)-1;	    return (OK);    }/********************************************************************************* fdDevCreate - create a device for a floppy disk* * This function's purpose is to create a device for a specified* floppy disk.** RETURNS: pointer to BLK_DEV structure*/BLK_DEV * fdDevCreate    (    register UINT driveNumber,	/* drive number (0 to 3) */    register UINT fdType,	/* type of floppy disk (table index) */    register UINT nBlocks,	/* device size in blocks (0 = whole disk) */    register UINT blkOffset 	/* offset from start of device */    )    {    register FDC_DEV *pDev;		/* device descriptor pointer */    register UINT dmaBufferAddress;	/* DMA buffer address */    register UINT realBlocks;		/* real number of blocks */    /* do not create device if the driver has not been initialized */    if (!fdcDrvInitFlag) 	{        return ((BLK_DEV *)NULL);	}    /* validate floppy disk drive number */    if (driveNumber > (FDC_NDRIVES - 1)) 	{        return ((BLK_DEV *)NULL);        }    /* validate floppy device/disk type */    if (fdType >= FDC_TYPES_TABLESIZE) 	{        return ((BLK_DEV *)NULL);        }    /* allocate memory for device descriptor */    pDev = calloc(1, sizeof(FDC_DEV));    if (pDev == (FDC_DEV *)NULL) 	{        return ((BLK_DEV *)NULL);        }       /* allocate DMA buffer */    dmaBufferAddress = (UINT)memalign(FDC_DMAALIGN, FDC_DMAALIGN);    if (dmaBufferAddress == (UINT)NULL) 	{        return ((BLK_DEV *)NULL);        }    pDev->dmaBuffer = dmaBufferAddress;    /* create interrupt level to task level semaphore */    if ((pDev->intSemId = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == (SEM_ID)NULL) 	{      	return ((BLK_DEV *)NULL);   	}    /* initialize device specific data structures */    pDev->driveNumber = driveNumber;    pDev->fdcType = fdcTypes[fdType];    /*     * initialize block information, perfrom some sanity     * checks on the blkOffset and nBlocks arguments     */    pDev->blockSize = pDev->fdcType.sectorsize;    pDev->blockOffset = blkOffset;    realBlocks = pDev->fdcType.numberofheads *                 pDev->fdcType.numberoftracks * 		 pDev->fdcType.sectorstrack;    if ((nBlocks > realBlocks) ||        (blkOffset >= realBlocks) ||        ((blkOffset + nBlocks) > realBlocks)) 	{      	return ((BLK_DEV *)NULL);   	}    if (!nBlocks) 	{        pDev->blockTotal = realBlocks - blkOffset;   	}     else 	{        pDev->blockTotal = nBlocks;   	}    /* initialize device block descriptor */    pDev->fdcBlockDev.bd_blkRd = fdcRead;    pDev->fdcBlockDev.bd_blkWrt = fdcWrite;    pDev->fdcBlockDev.bd_ioctl = fdcIoctl;    pDev->fdcBlockDev.bd_reset = NULL;    pDev->fdcBlockDev.bd_statusChk = fdcStatusChk;    pDev->fdcBlockDev.bd_removable = TRUE;    pDev->fdcBlockDev.bd_nBlocks = realBlocks;    pDev->fdcBlockDev.bd_bytesPerBlk = pDev->fdcType.sectorsize;    pDev->fdcBlockDev.bd_blksPerTrack = pDev->fdcType.sectorstrack;    pDev->fdcBlockDev.bd_nHeads = pDev->fdcType.numberofheads;    pDev->fdcBlockDev.bd_retry = 0;    pDev->fdcBlockDev.bd_mode = O_RDWR;    pDev->fdcBlockDev.bd_readyChanged = TRUE;    /* initialize the system clock rate */    pDev->sysClkRate = sysClkRateGet();    return ((BLK_DEV *)pDev);    }/********************************************************************************* fdcRead - fdc read blocks** This function's purpose is to read the specified number of* blocks from the specified device.** RETURNS: OK, or ERROR if the read failed*/LOCAL STATUS fdcRead    (    register FDC_DEV *pDev,		/* pointer to device descriptor */    register UINT startBlk,		/* starting block to read */    register UINT numBlks,		/* number of blocks to read */    register char *pBuf 		/* pointer to buffer to receive 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_READOP;    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));    }/********************************************************************************* fdcWrite - fdc write blocks* * This function's purpose is to write the specified number of* blocks to the specified device.** RETURNS: OK, or ERROR if the write failed*/LOCAL STATUS fdcWrite

⌨️ 快捷键说明

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