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

📄 par4chkd.c

📁 基于PC104的24位数据采集器的完整源码
💻 C
📖 第 1 页 / 共 5 页
字号:



#elif defined( SROS_WIN95 ) || defined( SROS_MSDOS )

// MSDOS Helper Function
SRLOCAL int Msdos_NameToAddress( char *ParPortName );

/* The rest of the functions are declared in par4chkd.h so they can 
   be called directly by the par4ch.c code instead of by the OS

         Msdos_DrvOpen
         Msdos_DrvRead
         Msdos_DrvIoctl
         Msdos_DrvClose
         Msdos_DrvGetLastError
*/





#elif defined( SROS_LINUX )

// Linux Helper Functions

SRLOCAL void Linux_GetParameters( void );
SRLOCAL void Linux_ResourceFree( int PortAddress, int DevMajor, char *PortName );

// Linux Functions called from the OS

int     Linux_DrvOpen(  struct inode *inode, struct file *filp );
close_t Linux_DrvClose( struct inode *inode, struct file *filp );
int     Linux_DrvIoctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg );

#if defined (LINUX_USE_OLD_READ)
rw_t    Linux_DrvRead(  struct inode *inode, struct file *filp, char *buf, count_t count );
#else
ssize_t Linux_DrvRead(  struct file *filp, char *buf, size_t count, loff_t *offset );
#endif // LINUX_USE_OLD_READ

void cleanup_module( void );
int     init_module( void );


#endif  // SROS_xxxxx











/* OS DEPENDENT HELPER FUNCTIONS AND MACROS:

In order to protect the rest of the code from having lots of
conditional sections, several helper functions and macros have been
defined.  The helper names are repeated once for each OS, but the
SROS_xxxxx define is used to select the one correct set to include at
compile time.

These helper functions include the in and out port I/O functions,
Atomic (ie non-interruptible) functions, and etc.  For example, under
WinNT and Linux, in and out are best called through macros provided
by the system, while under DOS inline assembler suffices.

*/


#if defined( SROS_WINNT )

// Lowest level PC I/O functions

SRLOCAL void OsPortIn( int port, unsigned char *value ) {

        *value = READ_PORT_UCHAR( (UCHAR *)port );

}
SRLOCAL void OsPortOut( int port, unsigned char value ) {

        WRITE_PORT_UCHAR( (UCHAR *)port, value );
}

// Functions to transfer data between user and kernel space

SRLOCAL unsigned long OsCopyToUser( void *UserBuff, const void *KernelBuff, unsigned long Nbytes ) {
        RtlCopyMemory( UserBuff, KernelBuff, Nbytes );
        return( Nbytes );
}
SRLOCAL unsigned long CopyFromUser( void *KernelBuff, const void *UserBuff, unsigned long Nbytes ) {
        RtlCopyMemory( KernelBuff, UserBuff, Nbytes );
        return( Nbytes );
}

// Misc functions

SRLOCAL void OsIrpFinish( IRP *Irp, long Status, unsigned long Info ) {
        Irp->IoStatus.Status      = (NTSTATUS)Status;
        Irp->IoStatus.Information = Info;
        IoCompleteRequest( Irp, IO_NO_INCREMENT );
}

SRLOCAL long OsSetReadParms( IRP *Irp, unsigned long *OutBufferSize, long **IOBuffer ) {
        
        IO_STACK_LOCATION *IrpStack;
        unsigned long      DevFlags;
        
        // Set up variables
        
        IrpStack        = IoGetCurrentIrpStackLocation( Irp );
        DevFlags        = IrpStack->DeviceObject->Flags;
        *OutBufferSize  = IrpStack->Parameters.Read.Length;

        
        // Get appropriate pointer for buffer
        
        if (DevFlags & DO_DIRECT_IO) {
                if (Irp->MdlAddress)
                        *IOBuffer = (long *)MmGetSystemAddressForMdl(Irp->MdlAddress);
                else
                        *IOBuffer = NULL;
                }

        else if (DevFlags & DO_BUFFERED_IO)
                *IOBuffer = (long *)Irp->AssociatedIrp.SystemBuffer;

        else // Must be NEITHER_IO
                
                *IOBuffer = (long *)Irp->UserBuffer;

        
        // Verify buffer pointer
        
        if ( (*OutBufferSize == 0) || (!(*IOBuffer)) )
             
                return( STATUS_INVALID_PARAMETER );
        else
                return( STATUS_SUCCESS );
}

SRLOCAL void OsSetIoctlCommand( IRP *Irp, unsigned long *Command ) {
        
        IO_STACK_LOCATION *IrpStack;
        
        IrpStack  = IoGetCurrentIrpStackLocation( Irp );
        *Command  = IrpStack->Parameters.DeviceIoControl.IoControlCode;
}

SRLOCAL long OsSetIoctlBuffers( IRP *Irp,
                        unsigned long Command,
                        int **InBuffer,
                        int **OutBuffer ) {

        // Assign buffers

        *InBuffer  = (int *)Irp->AssociatedIrp.SystemBuffer;
        *OutBuffer = (int *)Irp->AssociatedIrp.SystemBuffer;

        
        // Check that buffer exists since all commands pass (or get) data
        
            if ( !(*InBuffer) )
                    return( STATUS_INVALID_USER_BUFFER );


        // No filling needed for InBuffer since OS functions do that
                    
        return( STATUS_SUCCESS );
}

SRLOCAL void OsReturnIoctlBuffer( IRP *Irp,
                          unsigned long Command,
                          int *OutBuffer ) {
        
        // No filling needed for OutBuffer since OS functions do that
        
        return;
}

#define OsModuleUseCountInc
#define OsModuleUseCountDec

// Atomic operation functions

#define OsAtomicSet( pAtom, Value )  InterlockedExchange( (pAtom), (Value) )
#define OsAtomicInc( pAtom )         InterlockedIncrement( (pAtom) )
#define OsAtomicDec( pAtom )         InterlockedDecrement( (pAtom) )
#define OsAtomicAdd( pAtom, Amount ) InterlockedExchangeAdd( (pAtom), (Amount) )
#define OsAtomicSub( pAtom, Amount ) InterlockedExchangeAdd( (pAtom), -(Amount) )
#define OsAtomicRead( pAtom )        *(pAtom)



#elif defined( SROS_WIN95 ) || defined( SROS_MSDOS )

// Lowest level PC I/O functions

SRLOCAL void OsPortIn( int port, unsigned char *value) {

        unsigned char temp;
        
        _asm {

                mov     dx,WORD PTR port
                in      al,dx
                mov     BYTE PTR temp,al

                }

        *value = temp;

}
SRLOCAL void OsPortOut( int port, unsigned char value) {

        _asm {

                mov     dx,WORD PTR port
                mov     al,BYTE PTR value
                out     dx,al

                }

}

// Functions to transfer data between user and kernel space

SRLOCAL unsigned long OsCopyToUser( void *UserBuff, const void *KernelBuff, unsigned long Nbytes ) {

        int i;
        unsigned char *userptr;
        unsigned char *kernelptr;
        
        userptr   = (unsigned char *)UserBuff;
        kernelptr = (unsigned char *)KernelBuff;
        
        for ( i = 0 ; i < Nbytes ; i++ )
                *userptr++ = *kernelptr++;
        
        return( Nbytes );
}

SRLOCAL unsigned long OsCopyFromUser( void *KernelBuff, const void *UserBuff, unsigned long Nbytes ) {

        int i;
        unsigned char *userptr;
        unsigned char *kernelptr;
        
        userptr   = (unsigned char *)UserBuff;
        kernelptr = (unsigned char *)KernelBuff;
        for ( i = 0 ; i < Nbytes ; i++ )
                *userptr++ = *kernelptr++;
        
        return( Nbytes );
}

// Misc functions

SRLOCAL void OsIrpFinish( IRP *Irp, long Status, unsigned long Info ) {

        if (Irp)
                Irp->Nbytes = Info;

}

SRLOCAL long OsSetReadParms( IRP *Irp, unsigned long *OutBufferSize, long **IOBuffer ) {
        
        // Set parameters
        
        *OutBufferSize = Irp->Nbytes;
        *IOBuffer      = (long *)Irp->OutBuffer;

        
        // Verify buffer pointer
        
        if ( (*OutBufferSize == 0) || !(*IOBuffer) )
             
                return( STATUS_INVALID_PARAMETER );
        else
                return( STATUS_SUCCESS );
}

SRLOCAL void OsSetIoctlCommand( IRP *Irp, unsigned long *Command ) {
        *Command  = Irp->Command;
}

SRLOCAL long OsSetIoctlBuffers( IRP *Irp,
                        unsigned long Command,
                        int **InBuffer,
                        int **OutBuffer ) {

        // Assign buffers

        *InBuffer  = (int *)Irp->InBuffer;
        *OutBuffer = (int *)Irp->OutBuffer;

        
        // Check that a buffer exists since all commands pass (or get) data
        
            if ( !(*OutBuffer) && !(*InBuffer) )
                    return( STATUS_INVALID_USER_BUFFER );



        // No filling needed for InBuffer since "kernel" space is user space
                    
        return( STATUS_SUCCESS );
}

SRLOCAL void OsReturnIoctlBuffer( IRP *Irp,
                          unsigned long Command,
                          int *OutBuffer ) {
        
        // No filling needed for OutBuffer since "kernel" space is user space

        return;
}


#define OsModuleUseCountInc
#define OsModuleUseCountDec


// Atomic operation functions

#define OsAtomicSet( pAtom, Value )  *(pAtom) = (Value)
#define OsAtomicInc( pAtom )         *(pAtom) += 1
#define OsAtomicDec( pAtom )         *(pAtom) -= 1
#define OsAtomicAdd( pAtom, Amount ) *(pAtom) += (Amount)
#define OsAtomicSub( pAtom, Amount ) *(pAtom) -= (Amount)
#define OsAtomicRead( pAtom )        *(pAtom)



#elif defined( SROS_LINUX )

// Lowest level PC I/O functions

SRLOCAL void OsPortIn( int port, unsigned char *value) {

        *value = inb( port );
}
SRLOCAL void OsPortOut( int port, unsigned char value) {

        outb( value, port );
}

// Functions to transfer data between user and kernel space

SRLOCAL unsigned long OsCopyToUser( void *UserBuff, const void *KernelBuff, unsigned long Nbytes ) {
        unsigned long result;
        
        result = __copy_to_user( UserBuff, KernelBuff, Nbytes );
        
        return( result );
}        
SRLOCAL unsigned long OsCopyFromUser( void *KernelBuff, const void *UserBuff, unsigned long Nbytes ) {
        unsigned long result;
        
        result = __copy_from_user( KernelBuff, UserBuff, Nbytes );
        
        return( result );
}        

// Misc functions

SRLOCAL void OsIrpFinish( IRP *Irp, long Status, unsigned long Info ) {
        if (Irp)
                Irp->Nbytes = Info;
}

SRLOCAL long OsSetReadParms( IRP *Irp, unsigned long *OutBufferSize, long **IOBuffer ) {

        // Set parameters
        
        *OutBufferSize = Irp->Nbytes;
        *IOBuffer      = (long *)Irp->OutBuffer;

        
        // Verify buffer pointer
        
        if ( (*OutBufferSize == 0)   ||
             (!(*IOBuffer))          ||
             (!access_ok( VERIFY_WRITE, (void*)(*IOBuffer), *OutBufferSize)) )
             
                return( STATUS_INVALID_PARAMETER );

        else
                return( STATUS_SUCCESS );
}

SRLOCAL void OsSetIoctlCommand( IRP *Irp, unsigned long *Command ) {
        *Command  = Irp->Command;
}

SRLOCAL long OsSetIoctlBuffers( IRP *Irp,
                        unsigned long Command,
                        int **InBuffer,
                        int **OutBuffer ) {

        // BufferArea is defined at maximum size needed for any command

        static unsigned char BufferArea[sizeof(INIT4CHPARMS)];
        int ReadCopy, WriteCopy, Err;
        


        /* _IOC type is user-oriented, verify_area is kernel-oriented
         * so read/write are reversed.  VERIFY_WRITE handles R/W.
         * eg _IOC_READ means read from the device, so driver must write
         * to user space.
         */
        
        *InBuffer = *OutBuffer = (int *)BufferArea;
        
        // Check if driver must write to user space
        
        if ( _IOC_DIR(Command) & _IOC_READ )
                WriteCopy = 1;
        else
                WriteCopy = 0;

        
        // Check if driver must read from user space
        
        if ( _IOC_DIR(Command) & _IOC_WRITE )
                ReadCopy  = 1;
        else
                ReadCopy  = 0;


        

⌨️ 快捷键说明

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