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

📄 ip2main.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/***   (c) 1999 by Computone Corporation***********************************************************************************   PACKAGE:     Linux tty Device Driver for IntelliPort family of multiport*                serial I/O controllers.**   DESCRIPTION: Mainline code for the device driver********************************************************************************/// ToDo://// Done://// 1.2.9// Four box EX was barfing on >128k kmalloc, made structure smaller by// reducing output buffer size//// 1.2.8// Device file system support (MHW)//// 1.2.7 // Fixed// Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules//// 1.2.6//Fixes DCD problems//	DCD was not reported when CLOCAL was set on call to TIOCMGET////Enhancements://	TIOCMGET requests and waits for status return//	No DSS interrupts enabled except for DCD when needed//// For internal use only////#define IP2DEBUG_INIT//#define IP2DEBUG_OPEN//#define IP2DEBUG_WRITE//#define IP2DEBUG_READ//#define IP2DEBUG_IOCTL//#define IP2DEBUG_IPL//#define IP2DEBUG_TRACE//#define DEBUG_FIFO/************//* Includes *//************/#include <linux/config.h>// Uncomment the following if you want it compiled with modversions#ifdef MODULE#	if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)#		define MODVERSIONS#	endif#	ifdef MODVERSIONS#		include <linux/modversions.h>#	endif#endif#include <linux/version.h>#include <linux/ctype.h>#include <linux/string.h>#include <linux/fcntl.h>#include <linux/errno.h>#include <linux/module.h>#include <linux/signal.h>#include <linux/sched.h>#ifdef	CONFIG_DEVFS_FS#include <linux/devfs_fs_kernel.h>#endif#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/mm.h>#include <linux/malloc.h>#include <linux/major.h>#include <linux/wait.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/termios.h>#include <linux/tty_driver.h>#include <linux/serial.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/cdk.h>#include <linux/comstats.h>#include <linux/delay.h>#include <asm/system.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/bitops.h>#ifndef KERNEL_VERSION#define KERNEL_VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)#	include <linux/vmalloc.h>#	include <linux/init.h>#	include <asm/serial.h>#else#	include <linux/bios32.h>#endif// These VERSION switches maybe inexact because I simply don't know// when the various features appeared in the 2.1.XX kernels.// They are good enough for 2.0 vs 2.2 and if you are fooling with// the 2.1.XX stuff then it would be trivial for you to fix.// Most of these macros were stolen from some other drivers// so blame them.#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,4)#	include <asm/segment.h>#	define GET_USER(error,value,addr) error = get_user(value,addr)#	define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0#	define PUT_USER(error,value,addr) error = put_user(value,addr)#	define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0#	if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,5)#		include <asm/uaccess.h>#		define		pcibios_strerror(status)	\					printk( KERN_ERR "IP2: PCI error 0x%x \n", status );#	endif#else  /* 2.0.x and 2.1.x before 2.1.4 */#	define		proc_register_dynamic(a,b) proc_register(a,b) #	define GET_USER(error,value,addr)					  \	do {									  \		error = verify_area (VERIFY_READ, (void *) addr, sizeof (value)); \		if (error == 0)							  \			value = get_user(addr);					  \	} while (0)#	define COPY_FROM_USER(error,dest,src,size)				  \	do {									  \		error = verify_area (VERIFY_READ, (void *) src, size);		  \		if (error == 0)							  \			memcpy_fromfs (dest, src, size);			  \	} while (0)#	define PUT_USER(error,value,addr)					   \	do {									   \		error = verify_area (VERIFY_WRITE, (void *) addr, sizeof (value)); \		if (error == 0)							   \			put_user (value, addr);					   \	} while (0)#	define COPY_TO_USER(error,dest,src,size)				  \	do {									  \		error = verify_area (VERIFY_WRITE, (void *) dest, size);		  \		if (error == 0)							  \			memcpy_tofs (dest, src, size);				  \	} while (0)#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)#define __init#define __initfunc(a) a#define __initdata#define ioremap(a,b) vremap((a),(b))#define iounmap(a) vfree((a))#define SERIAL_TYPE_NORMAL	1#define SERIAL_TYPE_CALLOUT	2#define schedule_timeout(a){current->timeout = jiffies + (a); schedule();}#define signal_pending(a) ((a)->signal & ~(a)->blocked)#define in_interrupt()	intr_count#endif#include "./ip2/ip2types.h"#include "./ip2/ip2trace.h"#include "./ip2/ip2ioctl.h"#include "./ip2/ip2.h"#include "./ip2/i2ellis.h"#include "./ip2/i2lib.h"/***************** * /proc/ip2mem  * *****************/#include <linux/proc_fs.h>static int ip2_read_procmem(char *, char **, off_t, int);int ip2_read_proc(char *, char **, off_t, int, int *, void * );/********************//* Type Definitions *//********************//*************//* Constants *//*************//* String constants to identify ourselves */static char *pcName    = "Computone IntelliPort Plus multiport driver";static char *pcVersion = "1.2.9";/* String constants for port names */static char *pcDriver_name   = "ip2";#ifdef	CONFIG_DEVFS_FSstatic char *pcTty    		 = "ttf/%d";static char *pcCallout		 = "cuf/%d";#elsestatic char *pcTty    		 = "ttyF";static char *pcCallout		 = "cuf";#endifstatic char *pcIpl    		 = "ip2ipl";/* Serial subtype definitions */#define SERIAL_TYPE_NORMAL    1#define SERIAL_TYPE_CALLOUT   2// cheezy kludge or genius - you decide?int ip2_loadmain(int *, int *, unsigned char *, int);static unsigned char *Fip_firmware;static int Fip_firmware_size;/***********************//* Function Prototypes *//***********************//* Global module entry functions */#ifdef MODULEint init_module(void);void cleanup_module(void);#endifint old_ip2_init(void);/* Private (static) functions */static int  ip2_open(PTTY, struct file *);static void ip2_close(PTTY, struct file *);static int  ip2_write(PTTY, int, const unsigned char *, int);static void ip2_putchar(PTTY, unsigned char);static void ip2_flush_chars(PTTY);static int  ip2_write_room(PTTY);static int  ip2_chars_in_buf(PTTY);static void ip2_flush_buffer(PTTY);static int  ip2_ioctl(PTTY, struct file *, UINT, ULONG);static void ip2_set_termios(PTTY, struct termios *);static void ip2_set_line_discipline(PTTY);static void ip2_throttle(PTTY);static void ip2_unthrottle(PTTY);static void ip2_stop(PTTY);static void ip2_start(PTTY);static void ip2_hangup(PTTY);static void set_irq(int, int);static void ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs);static void ip2_poll(unsigned long arg);static inline void service_all_boards(void);static inline void do_input(i2ChanStrPtr pCh);static inline void do_status(i2ChanStrPtr pCh);static void ip2_wait_until_sent(PTTY,int);static void set_params (i2ChanStrPtr, struct termios *);static int set_modem_info(i2ChanStrPtr, unsigned int, unsigned int *);static int get_serial_info(i2ChanStrPtr, struct serial_struct *);static int set_serial_info(i2ChanStrPtr, struct serial_struct *);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)static int     ip2_ipl_read(struct inode *, char *, size_t , loff_t *);#elsestatic ssize_t ip2_ipl_read(struct file *, char *, size_t, loff_t *) ;#endifstatic ssize_t ip2_ipl_write(struct file *, const char *, size_t, loff_t *);static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG);static int ip2_ipl_open(struct inode *, struct file *);void ip2trace(unsigned short,unsigned char,unsigned char,unsigned long,...);static int DumpTraceBuffer(char *, int);static int DumpFifoBuffer( char *, int);static void ip2_init_board(int);static unsigned short find_eisa_board(int);/***************//* Static Data *//***************/static struct tty_driver ip2_tty_driver;static struct tty_driver ip2_callout_driver;static int ref_count;/* Here, then is a table of board pointers which the interrupt routine should * scan through to determine who it must service. */static unsigned short i2nBoards; // Number of boards herestatic i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];static i2ChanStrPtr  DevTable[IP2_MAX_PORTS];//DevTableMem just used to save addresses for kfreestatic void  *DevTableMem[IP2_MAX_BOARDS];static struct tty_struct * TtyTable[IP2_MAX_PORTS];static struct termios    * Termios[IP2_MAX_PORTS];static struct termios    * TermiosLocked[IP2_MAX_PORTS];/* This is the driver descriptor for the ip2ipl device, which is used to * download the loadware to the boards. */static struct file_operations ip2_ipl = {	owner:		THIS_MODULE,	read:		ip2_ipl_read,	write:		ip2_ipl_write,	ioctl:		ip2_ipl_ioctl,	open:		ip2_ipl_open,}; static long irq_counter;static long bh_counter;// Use immediate queue to service interrupts//#define USE_IQI	// PCI&2.2 needs work//#define USE_IQ	// PCI&2.2 needs work/* The timer_list entry for our poll routine. If interrupt operation is not * selected, the board is serviced periodically to see if anything needs doing. */#define  POLL_TIMEOUT   (jiffies + 1)static struct timer_list PollTimer = { function: ip2_poll };static char  TimerOn;#ifdef IP2DEBUG_TRACE/* Trace (debug) buffer data */#define TRACEMAX  1000static unsigned long tracebuf[TRACEMAX];static int tracestuff;static int tracestrip;static int tracewrap;#endif/**********//* Macros *//**********/#if defined(MODULE) && defined(IP2DEBUG_OPEN)#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \		    kdevname(tty->device),(pCh->flags),ref_count, \		    tty->count,/*GET_USE_COUNT(module)*/0,s)#else#define DBG_CNT(s)#endif#define MIN(a,b)	( ( (a) < (b) ) ? (a) : (b) )#define MAX(a,b)	( ( (a) > (b) ) ? (a) : (b) )/********//* Code *//********/#include "./ip2/i2ellis.c"    /* Extremely low-level interface services */#include "./ip2/i2cmd.c"      /* Standard loadware command definitions */#include "./ip2/i2lib.c"      /* High level interface services *//* Configuration area for modprobe */#ifdef MODULE#	if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)		MODULE_AUTHOR("Doug McNash");		MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");#	endif	/* LINUX_VERSION */#endif	/* MODULE */static int poll_only;static int Eisa_irq;static int Eisa_slot;static int iindx;static char rirqs[IP2_MAX_BOARDS];static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};/******************************************************************************//* Initialisation Section                                                     *//******************************************************************************/int ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) {	int i;	/* process command line arguments to modprobe or insmod i.e. iop & irqp */	/* otherwise ip2config is initialized by what's in ip2/ip2.h */	/* command line trumps initialization in ip2.h */	/* first two args are null if builtin to kernel */	if ((irqp != NULL) || (iop != NULL)) {		for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {			if (irqp && irqp[i]) {				ip2config.irq[i] = irqp[i];			}			if (iop && iop[i]) {				ip2config.addr[i] = iop[i];			}		}	}	Fip_firmware = firmware;	Fip_firmware_size = firmsize;	return old_ip2_init();}

⌨️ 快捷键说明

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