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

📄 nec765fd.c

📁 VxWorks系统下软盘驱动器驱动的源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* nec765Fd.c - NEC 765 floppy disk device driver *//* Copyright 1989-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01i,01aug01,jkf  doubled sync semaphore timeout per T3 SPR#63543.01o,11jun01,jyo  SPR#65990, write protected media handling.01i,24feb98,hdn  added support for disk-change in fdStatusChk().01h,30aug95,hdn  added support for write-protected, unformatted, no-disk.01g,14jun95,hdn  removed function declarations defined in sysLib.h.01f,24jan95,jdi  doc cleanup.01e,25oct94,hdn  added fdRawio() to provide physical IO.		 swapped 1st and 2nd parameter of fdDevCreate().01d,03jun94,hdn  changed DESCRIPTION, 386 to 386/486.		 added an explanation of parameters for fdDevCreate().01c,22apr94,hdn  made two imported globals sysFdBuf, sysFdBufSize.01b,04nov93,hdn  cleaned up.01a,21sep93,hdn  written.*//*DESCRIPTIONThis is the driver for the NEC 765 Floppy Chip used on the PC 386/486.USER-CALLABLE ROUTINESMost of the routines in this driver are accessible only through the I/Osystem.  However, two routines must be called directly:  fdDrv() toinitialize the driver, and fdDevCreate() to create devices.Before the driver can be used, it must be initialized by calling fdDrv().This routine should be called exactly once, before any reads, writes, orcalls to fdDevCreate().  Normally, it is called from usrRoot() inusrConfig.c.The routine fdRawio() allows physical I/O access.  Its first argument is adrive number, 0 to 3; the second argument is a type of diskette; the thirdargument is a pointer to the FD_RAW structure, which is defined in nec765Fd.h.Interleaving is not supported when the driver formats.Two types of diskettes are currently supported:3.5" 2HD 1.44MB and 5.25" 2HD 1.2MB.  You can add additional diskettetypes to the `fdTypes[]' table in sysLib.c.The BLK_DEV bd_mode field will reflect the disk's write protect tab.INTERNALThe driver uses memory area at sysFdBuf(FD_DMA_BUF) size of sysFdBufSize(FD_DMA_BUF_SIZE) for DMA. Reasons are First of all, the DMA chip understand only 24 bits address. Secondly, a buffer should be in one page,the other word a buffer can not cross the 64k byte boundary. SEE ALSO:.pG "I/O System"*/#include "vxWorks.h"#include "taskLib.h"#include "blkIo.h"#include "ioLib.h"#include "iosLib.h"#include "memLib.h"#include "stdlib.h"#include "errnoLib.h"#include "stdio.h"#include "string.h"#include "private/semLibP.h"#include "intLib.h"#include "iv.h"#include "wdLib.h"#include "sysLib.h"#include "sys/fcntlcom.h"#include "drv/fdisk/nec765Fd.h"IMPORT int dmaSetup (int direction, void *pAddr, UINT nbytes, UINT chan);IMPORT FD_TYPE fdTypes[];IMPORT UINT sysFdBuf;IMPORT UINT sysFdBufSize;/* global */int  fdIntCount	= 0;		/* interrupt count */int  fdRetry	= 2;		/* max retry count */int  fdTimeout	= 10000;	/* max timeout count */int  fdSemSec	= 2;		/* semaphore timeout seconds */int  fdWdSec	= 4;		/* watchdog timeout seconds */SEMAPHORE  fdSyncSem;		/* binary semaphore for syncronization */SEMAPHORE  fdMuteSem;		/* mutex  semaphore for mutual-exclusion */WDOG_ID  fdWid;			/* watchdog to turn motor off *//* local */LOCAL char fdDORvalues[]	= {0x1c, 0x2d, 0x4e, 0x8f};LOCAL char fdAccess[]		= {0,0,0,0};	/* flag indicate first access */LOCAL BOOL fdDrvInstalled	= FALSE;	/* TRUE = facility installed */LOCAL int  fdCylinder		= 1;		/* last cylinder read/written *//* function prototypes */LOCAL STATUS fdBlkRd	(FD_DEV *pFdDev, int startBlk, int nBlks, char *pBuf);LOCAL STATUS fdBlkWrt	(FD_DEV *pFdDev, int startBlk, int nBlks, char *pBuf);LOCAL STATUS fdIoctl	(FD_DEV *pFdDev, int function, int arg);LOCAL STATUS fdReset	(FD_DEV *pFdDev);LOCAL STATUS fdStatusChk(FD_DEV *pFdDev);LOCAL STATUS fdBlkRW    (FD_DEV *pFdDev, int startBlk, int nBlks, char *pBuf,			 int direction);LOCAL void   fdIntr         (int ctrl);LOCAL STATUS fdCmdSend      (UCHAR *pCommand, int nBytes);LOCAL STATUS fdResultPhase  (UCHAR *pResults, BOOL immediate, int nBytes);LOCAL STATUS fdIntSense     (int seekEnd);LOCAL void   fdInit	    (void);LOCAL void   fdDriveRelease (void);LOCAL void   fdDriveSelect  (int fdType, int drive);LOCAL STATUS fdRecalib      (int drive);LOCAL STATUS fdSeek         (int drive, int cylinder, int head);LOCAL STATUS fdRW           (int fdType, int drive, int cylinder, int head,			     int sector, void *pBuf, int nSecs, int direction);LOCAL STATUS fdFormat       (int fdType, int drive, int cylinder, int head,    			     int interleave);LOCAL int    fdDriveIsWP    (int drive);/********************************************************************************* fdDrv - initialize the floppy disk driver** This routine initializes the floppy driver, sets up interrupt vectors,* and performs hardware initialization of the floppy chip.** This routine should be called exactly once, before any reads, writes,* or calls to fdDevCreate().  Normally, it is called by usrRoot()* in usrConfig.c.** RETURNS: OK.** SEE ALSO: fdDevCreate(), fdRawio()*/STATUS fdDrv    (    int vector,		/* interrupt vector */    int level		/* interrupt level */    )    {    if (!fdDrvInstalled)	{        semBInit (&fdSyncSem, SEM_Q_FIFO, SEM_EMPTY);        semMInit (&fdMuteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE |		  SEM_INVERSION_SAFE);        (void) intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (vector),		           (VOIDFUNCPTR)fdIntr, 0);        sysIntEnablePIC (level);	/* unmask the interrupt level */        fdWid = wdCreate ();        fdInit ();	fdDrvInstalled = TRUE;	}    return (OK);    }/********************************************************************************* fdDevCreate - create a device for a floppy disk** This routine creates a device for a specified floppy disk.** The <drive> parameter is the drive number of the floppy disk;* valid values are 0 to 3.** The <fdType> parameter specifies the type of diskette, which is described* in the structure table `fdTypes[]' in sysLib.c.  <fdType> is an index to* the table.  Currently the table contains two diskette types:* .iP "" 4* An <fdType> of 0 indicates the first entry in the table (3.5" 2HD, 1.44MB);* .iP* An <fdType> of 1 indicates the second entry in the table (5.25" 2HD, 1.2MB).* .LP* Members of the `fdTypes[]' structure are:* .CS*     int  sectors;       /@ no of sectors @/*     int  sectorsTrack;  /@ sectors per track @/*     int  heads;         /@ no of heads @/*     int  cylinders;     /@ no of cylinders @/*     int  secSize;       /@ bytes per sector, 128 << secSize @/*     char gap1;          /@ gap1 size for read, write @/*     char gap2;          /@ gap2 size for format @/*     char dataRate;      /@ data transfer rate @/*     char stepRate;      /@ stepping rate @/*     char headUnload;    /@ head unload time @/*     char headLoad;      /@ head load time @/*     char mfm;           /@ MFM bit for read, write, format @/*     char sk;            /@ SK bit for read @/*     char *name;         /@ name @/* .CE** The <nBlocks> parameter specifies the size of the device, in blocks.* If <nBlocks> is zero, the whole disk is used.** The <blkOffset> parameter specifies an offset, in blocks, from the start* of the device to be used when writing or reading the floppy disk.  This* offset is added to the block numbers passed by the file system during* disk accesses.  (VxWorks file systems always use block numbers beginning* at zero for the start of a device.)  Normally, <blkOffset> is 0.*** RETURNS:* A pointer to a block device structure (BLK_DEV) or NULL if memory cannot* be allocated for the device structure.** SEE ALSO: fdDrv(), fdRawio(), dosFsMkfs(), dosFsDevInit(), rt11FsDevInit(),* rt11FsMkfs(), rawFsDevInit()*/BLK_DEV *fdDevCreate    (    int drive,		/* driver number of floppy disk (0 - 3) */    int fdType,		/* type of floppy disk */    int nBlocks,	/* device size in blocks (0 = whole disk) */    int blkOffset	/* offset from start of device */    )    {    FD_DEV *pFdDev;    BLK_DEV *pBlkDev;    FD_TYPE *pType = &fdTypes[fdType];    if (!fdDrvInstalled)	return (NULL);    if (nBlocks == 0)	nBlocks = pType->sectors;    if ((UINT)drive >= FD_MAX_DRIVES)	return (NULL);    if ((pFdDev = (FD_DEV *)calloc(sizeof (FD_DEV), 1)) == NULL)	return (NULL);    pBlkDev = &pFdDev->blkDev;    pBlkDev->bd_nBlocks		= nBlocks;    pBlkDev->bd_bytesPerBlk	= 128 << pType->secSize;    pBlkDev->bd_blksPerTrack	= pType->sectorsTrack;    pBlkDev->bd_nHeads		= pType->heads;    pBlkDev->bd_removable	= TRUE;    pBlkDev->bd_retry		= 1;    pBlkDev->bd_readyChanged	= TRUE;    pBlkDev->bd_blkRd		= fdBlkRd;    pBlkDev->bd_blkWrt		= fdBlkWrt;    pBlkDev->bd_ioctl		= fdIoctl;    pBlkDev->bd_reset		= fdReset;    pBlkDev->bd_statusChk	= fdStatusChk;    pFdDev->fdType		= fdType;    pFdDev->drive		= drive;    pFdDev->blkOffset		= blkOffset;    /* SPR#65990, now check for the WP setting */    /* power up the drive */    sysOutByte (FD_REG_OUTPUT, fdDORvalues[drive]);     sysDelay ();    /* set the bd_mode per the WP tab */    pBlkDev->bd_mode		= (fdDriveIsWP(drive)) ? O_RDONLY : O_RDWR;    /* power down the device */    fdDriveRelease ();     sysDelay();    return (&pFdDev->blkDev);    }/********************************************************************************* fdRawio - provide raw I/O access** This routine is called when the raw I/O access is necessary.** The <drive> parameter is the drive number of the floppy disk;* valid values are 0 to 3.** The <fdType> parameter specifies the type of diskette, which is described* in the structure table `fdTypes[]' in sysLib.c.  <fdType> is an index to* the table.  Currently the table contains two diskette types:* .iP "" 4* An <fdType> of 0 indicates the first entry in the table (3.5" 2HD, 1.44MB);* .iP* An <fdType> of 1 indicates the second entry in the table (5.25" 2HD, 1.2MB).* .LP** The <pFdRaw> is a pointer to the structure FD_RAW, defined in nec765Fd.h** RETURNS:  OK or ERROR.** SEE ALSO: fdDrv(), fdDevCreate()*/STATUS fdRawio    (    int drive,		/* drive number of floppy disk (0 - 3) */    int fdType,		/* type of floppy disk */    FD_RAW *pFdRaw	/* pointer to FD_RAW structure */    )    {    FD_DEV fdDev;    BLK_DEV *pBlkDev	= &fdDev.blkDev;    FD_TYPE *pType	= &fdTypes[fdType];    UINT startBlk;    if (!fdDrvInstalled)	return (ERROR);    if ((UINT)drive >= FD_MAX_DRIVES)	return (ERROR);    if ((pFdRaw->cylinder	>= pType->cylinders)	||        (pFdRaw->head		>= pType->heads)	||        (pFdRaw->sector		>  pType->sectorsTrack)	||        (pFdRaw->sector		== 0))	return (ERROR);    pBlkDev->bd_nBlocks		= pType->sectors;    pBlkDev->bd_bytesPerBlk	= 128 << pType->secSize;    pBlkDev->bd_blksPerTrack	= pType->sectorsTrack;    pBlkDev->bd_nHeads		= pType->heads;    pBlkDev->bd_removable	= TRUE;    pBlkDev->bd_retry		= 1;    pBlkDev->bd_readyChanged	= TRUE;    pBlkDev->bd_blkRd		= fdBlkRd;    pBlkDev->bd_blkWrt		= fdBlkWrt;    pBlkDev->bd_ioctl		= fdIoctl;    pBlkDev->bd_reset		= fdReset;    pBlkDev->bd_statusChk	= fdStatusChk;    fdDev.drive			= drive;    fdDev.fdType		= fdType;    fdDev.blkOffset		= 0;    /* SPR#65990, now check for the WP setting */    /* power up the drive */    sysOutByte (FD_REG_OUTPUT, fdDORvalues[drive]);     sysDelay ();    /* set the bd_mode per the WP tab */    pBlkDev->bd_mode		= (fdDriveIsWP(drive)) ? O_RDONLY : O_RDWR;    startBlk = pFdRaw->cylinder * (pType->sectorsTrack * pType->heads) +	       pFdRaw->head * pType->sectorsTrack +	       pFdRaw->sector - 1;    return (fdBlkRW (&fdDev, startBlk, pFdRaw->nSecs, pFdRaw->pBuf,		     pFdRaw->direction));    }/********************************************************************************* fdBlkRd - read one or more blocks from a floppy disk** This routine reads one or more blocks from the specified device,* starting with the specified block number.** If any block offset was specified during fdDevCreate(), it is added* to <startBlk> before the transfer takes place.** RETURNS: OK, ERROR if the read command didn't succeed.*/LOCAL STATUS fdBlkRd    (    FD_DEV *pFdDev,    int startBlk,    int nBlks,    char *pBuf    )    {    return (fdBlkRW (pFdDev, startBlk, nBlks, pBuf, O_RDONLY));    }/********************************************************************************* fdBlkWrt - write one or more blocks to a floppy disk** This routine writes one or more blocks to the specified device,* starting with the specified block number.** If any block offset was specified during fdDevCreate(), it is added* to <startBlk> before the transfer takes place.** RETURNS: OK, ERROR if the write command didn't succeed.*/LOCAL STATUS fdBlkWrt    (    FD_DEV *pFdDev,    int startBlk,    int nBlks,    char *pBuf    )    {    return (fdBlkRW (pFdDev, startBlk, nBlks, pBuf, O_WRONLY));    }/********************************************************************************* fdReset - reset a floppy disk controller** This routine resets a floppy disk controller.** RETURNS: OK, always.*/

⌨️ 快捷键说明

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