📄 hpcfsdrv.c
字号:
/* hpcFsDrv.c - virtual generic file I/O driver for HPC *//* Copyright 1996-1998 Wind River Systems, Inc.; Copyright 2000 Intel Corp. *//*modification history--------------------01a,29Jun00,jdg written, based on wdbTsfsDrv.c*//*DESCRIPTIONThis library provides a virtual file I/O driver for use with the HPC fileserver. I/O is performed on this virtual I/O device exactly as it would beon any device referencing a VxWorks file system. File operations, such asread() and write(), move data over HPC. The operations are then executed on the host file system. Because file operations are actually performed on the host file system by the HPC file server, the file system presented by this virtual I/O device is known as the HPC file system or HPCFS.The driver is installed with hpcfsDrv(), creating a device typicallycalled '/hpc'. See the manual page for hpcfsDrv() for more informationabout using this function. The initialization is done automatically,enabling access to HPCFS, when INCLUDE_HPCFS is defined.The file server also must be started on the host.TSFS SOCKETSHPCFS provides all of the functionality of other VxWorks file systems.For details, see the .pG "I/O System and Local File Systems."HPCFS does not at this time provide access to TCP sockets.DIRECTORIESAll directory functions, such as mkdir(), rmdir(), opendir(), readdir(),closedir(), and rewinddir() are supported by HPCFS, regardless ofwhether the file server providing HPCFS is being run on a UNIX or Windows host.While it is possible to open and close directories using open() and close(),it is not possible to read from a directory using read(). Instead, readdir() must be used. It is also not possible to write to an open directory, and opening a directory for anything other than read-only results in an error, with 'errno' set to 'EISDIR'. Calling read() on a directory returns 'ERROR' with 'errno' set to 'EISDIR'.OPEN FLAGSWhen the file server that is providing the HPCFS is running on a Windowshost, the default file-translation mode is binary translation. If texttranslation is required, then HPCFS_O_TEXT can be included in the modeargument to open(). For example:.CS fd = open ("/tgtsvr/foo", O_CREAT | O_RDWR | HPCFS_O_TEXT, 0777).CEIf the file server providing HPCFS services is running on a UNIX host, HPCFS_O_TEXT is ignored.IOCTL SUPPORTHPCFS supports the following ioctl() functions for controlling filesand sockets. Details about each function can be found in the documentation listed below..iP 'FIOSEEK'.iP 'FIOWHERE'.iP 'FIOMKDIR'Create a directory. The path, in this case '/tgtsvr/tmp', must be anabsolute path prefixed with the device name. To create the directory '/tmp' on the root of the TSFS file system use the following:.CS status = ioctl (fd, FIOMKDIR, "/tgtsvr/tmp").CE.iP 'FIORMDIR'Remove a directory. The path, in this case '/tgtsvr/foo', must be an absolute path prefixed with the device name. To remove the directory '/foo' from the root of the TSFS file system, use the following:.CS status = ioctl (fd, FIORMDIR, "/tgtsvr/foo").CE.iP 'FIORENAME'Rename the file or directory represented by 'fd' to the name in the stringpointed to by 'arg'. The path indicated by 'arg' may be prefixed with thedevice name or not. Using this ioctl() function with the path '/foo/goo'produces the same outcome as the path '/tgtsvr/foo/goo'. The path is notmodified to account for the current working directory, and therefore mustbe an absolute path..CS char *arg = "/tgtsvr/foo/goo"; status = ioctl (fd, FIORENAME, arg);.CEERROR CODESThe routines in this library return the VxWorks error codes that most closely match the errnos generated by the corresponding host function.If an 'errno' generatedon the host has no reasonable VxWorks counterpart, the host 'errno' ispassed to the target calling routine unchanged.SEE ALSO:.I "VxWorks Programmer's Guide: I/O System, Local File Systems"INTERNALopendir(), closedir(), readdir() and rewinddir() are supported whenthe file server is running on a Unix host. All of these, with the exception ofrewinddir() are supported on Win32. Win32 provides directory listings withan iterator model (findfirst(), findnext(), findclose()). There is noway to back up this iterator, like rewinddir does.@@ need to fix wdb.hThere are times when the host must return an error code that is not defined on the target. These error codes are defined in wdb.h. Eachtime the errno is set in this function, it is first mapped from theportable error codes defined in wdb.h to a vxWorks' error code. Common,usually Posix, errnos are passed through this mapping unchanged. Ifan errno generated on the host is not understood by the mapping routines,then it is passed through unchanged. This may give the user useful information about what has happened when vxWorks doesn't have an equivalent errno. Many of the errnos mapped are the Win32 socket andnetworking errnos, which have vxWorks counterparts, but are very differentfrom unix and vxWorks definitions.The ioctl command FIORENAME does not work ideally. It should modify the pathit is handed to account for the current working directory. Doing this howeverrequires that this wdb-virtual-io driver call into ioLib, something that hasbeen avoided so far. This creates a problem with rename() that is not seenin dosFsLib. The rename function, in ioLib, does not patch up the path namewith the current working directory, letting the ioctl in dosFsLib do itinstead. When the current working directory is '/tgtsvr/foo/goo', and it contains the file 'file1', and the tsfsRoot is '/folk/blimpy', calling 'rename ("file1", "file-renamed") results in /folk/blimpy/foo/goo/file1being renamed to /folk/blimpy/file-renamed. Notice the /foo/goo workingdirectory was ignored. By the way, passFsLib has the same problem.*/#include "vxWorks.h"#include "ioLib.h"#include "iosLib.h"#include "tyLib.h"#include "stdlib.h"#include "stdio.h"#include "intLib.h"#include "string.h"#include "sys/stat.h"#include "dirent.h"#include "hpcIf.h"#include "hpcFsRpc.h"#include "hpcFsFunc.h"#include "hpcFs.h"typedef struct{ DEV_HDR devHdr; /* device header */} HPCFS_DEV;typedef struct{ int channel; int mode; int perm;} HPCFS_CHANNEL_DESC;static int hpcfsDrvNum = 0; /* drvnum for this driver */static HPCFS_DEV hpcfsDev; /* virtual I/O device */static int hpcfsHpcChanNum = -1; /* HPC channel being used */static SEM_ID hpcfsAccess; /* Semaphore used to access HPC chan *//* globals *//* forward declarations */static int hpcfsCreate (HPCFS_DEV *pDev, char *name, int mode);static int hpcfsOpen (HPCFS_DEV *pDev, char *name, int mode, int perm);static int hpcfsDelete (HPCFS_DEV *pDev, char *name);static STATUS hpcfsClose (HPCFS_CHANNEL_DESC *pChannelDesc);static int hpcfsRead (HPCFS_CHANNEL_DESC *pChannelDesc, char *buf, int maxBytes);static int hpcfsWrite (HPCFS_CHANNEL_DESC *pChannelDesc, char *buf, int maxBytes);static STATUS hpcfsIoctl (HPCFS_CHANNEL_DESC *pChannelDesc, int request, int arg);static int hpcfsErrnoMap (int hostErrno);/*static void hpcfsRcvChars(unsigned char *buff, unsigned int len, void *data);static unsigned int hpcfsTxChars(unsigned char **buf, void *data);*/#if 0/********************************************************************************* hpcfsTxInit - initialize txDesc structure** This routine initializes the txDesc structure, which is used to pass* data into the tx callback from HPC.** NOMANUAL*/static void hpcfsTxInit(){ txDesc.txSem = semBCreate(SEM_Q_FIFO, SEM_FULL); txDesc.buf1 = NULL; txDesc.buf2 = NULL;}/********************************************************************************* hpcfsTxSend - send data to HPC channel via callback** This routine sends one or two buffers of data to the HPC channel via* the callback.** Note that the buffers given to this routine may NOT be reused when this call* completes. The data is actually sent an arbitrary amount of time afterwards.** NOMANUAL*/void hpcfsTxSend( char *buf1, int size1, char *buf2, int size2){ semTake(txDesc.txSem, WAIT_FOREVER); /* now we own txDesc */ if (size1 <= 0) txDesc.buf1 = NULL; else txDesc.buf1 = buf1; if (size2 <= 0) txDesc.buf2 = NULL; else txDesc.buf2 = buf2; txDesc.size1 = size1; txDesc.size2 = size2; hpcStartio(hpcfsHpcChanNum);}/********************************************************************************* hpcfsTxChars - HPC callback to get TX characters** This is a callback routine called from within HPC to return characters* which should be transmitted. It gets these characters from the txDesc* structure.** NOMANUAL*/static unsigned int hpcfsTxChars( unsigned char **buf, void *data){ if (txDesc.buf1) { *buf = txDesc.buf1; txDesc.buf1 = NULL; if (txDesc.buf2 == NULL) return (unsigned int)txDesc.size1 | HPC_IB_BIT; else return (unsigned int)txDesc.size1; } if (txDesc.buf2) { *buf = txDesc.buf2; txDesc.buf2 = NULL; return (unsigned int)txDesc.size2 | HPC_IB_BIT; } /* We're finished, so release semaphore */ semGive(txDesc.txSem); return 0;}#endif/********************************************************************************* hpcfsDrv - initialize the HPCFS device driver** This routine initializes an HPC channel and creates an HPCFS device* with the specified name.** This routine should be called exactly once, before any reads, writes, or* opens. Normally, it is called by usrRoot() in usrConfig.c,* and the device name created is '/hpcfs'.** After this routine has been called, individual virtual I/O channels* can be opened by appending the host file name to the virtual I/O* device name. For example, to get a file descriptor for the host* file '/etc/passwd', call open() as follows:* .CS* fd = open ("/tgtsvr/etc/passwd", O_RDWR, 0)* .CE** RETURNS: OK, or ERROR if the driver can not be installed.*/STATUS hpcfsDrv ( char * name, /* root name in i/o system */ int hpcChanNum /* HPC Channel number */ ){ HPC_ERROR_CODE hpcError; /* check if driver is already installed */ if (hpcfsDrvNum > 0) return (OK); /* Open HPC channel */ hpcError = hpcOpenW32(hpcChanNum); if (hpcError != HPC_OK) return (ERROR); hpcFuncInit(hpcChanNum); hpcfsAccess = semBCreate(SEM_Q_FIFO, SEM_FULL); hpcfsDrvNum = iosDrvInstall( hpcfsCreate, hpcfsDelete, hpcfsOpen, hpcfsClose, hpcfsRead, hpcfsWrite, hpcfsIoctl ); if (hpcfsDrvNum <= 0) return (ERROR); hpcfsHpcChanNum = hpcChanNum; /* Add the device to the I/O systems device list */ return (iosDevAdd (&hpcfsDev.devHdr, name, hpcfsDrvNum));}/********************************************************************************* hpcfsCreate - open a virtual I/O channel** RETURNS: hpcfsDev handle*/static int hpcfsCreate ( HPCFS_DEV * pDev, /* I/O system device entry */ char * name, /* name of file to open */ int mode /* VxWorks open mode */ ) { return hpcfsOpen (pDev, name, mode | O_CREAT | O_TRUNC, 0666); } /********************************************************************************* hpcfsOpen - open a virtual I/O channel** This routine issues a request to the file server to open a file and then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -