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

📄 epca.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* ------------------------------------------------------------------		Setup entry points for the driver.  These are primarily called by 		the kernel in tty_io.c and n_tty.c	--------------------------------------------------------------------- */	pc_driver.open = pc_open;	pc_driver.close = pc_close;	pc_driver.write = pc_write;	pc_driver.write_room = pc_write_room;	pc_driver.flush_buffer = pc_flush_buffer;	pc_driver.chars_in_buffer = pc_chars_in_buffer;	pc_driver.flush_chars = pc_flush_chars;	pc_driver.put_char = pc_put_char;	pc_driver.ioctl = pc_ioctl;	pc_driver.set_termios = pc_set_termios;	pc_driver.stop = pc_stop;	pc_driver.start = pc_start;	pc_driver.throttle = pc_throttle;	pc_driver.unthrottle = pc_unthrottle;	pc_driver.hangup = pc_hangup;	pc_callout = pc_driver;	pc_callout.name = "cud";	pc_callout.major = DIGICU_MAJOR;	pc_callout.minor_start = 0;	pc_callout.init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;	pc_callout.subtype = SERIAL_TYPE_CALLOUT;	pc_info = pc_driver;	pc_info.name = "digi_ctl";	pc_info.major = DIGIINFOMAJOR;	pc_info.minor_start = 0;	pc_info.num = 1;	pc_info.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;	pc_info.subtype = SERIAL_TYPE_INFO;	save_flags(flags);	cli();	for (crd = 0; crd < num_cards; crd++) 	{ /* Begin for each card */		/*  ------------------------------------------------------------------			This is where the appropriate memory handlers for the hardware is			set.  Everything at runtime blindly jumps through these vectors.		---------------------------------------------------------------------- */		/* defined in epcaconfig.h */		bd = &boards[crd];		switch (bd->type)		{ /* Begin switch on bd->type {board type} */			case PCXEM:			case EISAXEM:				bd->memwinon     = pcxem_memwinon ;				bd->memwinoff    = pcxem_memwinoff ;				bd->globalwinon  = pcxem_globalwinon ;				bd->txwinon      = pcxem_txwinon ;				bd->rxwinon      = pcxem_rxwinon ;				bd->memoff       = pcxem_memoff ;				bd->assertgwinon = dummy_assertgwinon;				bd->assertmemoff = dummy_assertmemoff;				break;			case PCIXEM:			case PCIXRJ:			case PCIXR:				bd->memwinon     = dummy_memwinon;				bd->memwinoff    = dummy_memwinoff;				bd->globalwinon  = dummy_globalwinon;				bd->txwinon      = dummy_txwinon;				bd->rxwinon      = dummy_rxwinon;				bd->memoff       = dummy_memoff;				bd->assertgwinon = dummy_assertgwinon;				bd->assertmemoff = dummy_assertmemoff;				break;			case PCXE:			case PCXEVE:				bd->memwinon     = pcxe_memwinon;				bd->memwinoff    = pcxe_memwinoff;				bd->globalwinon  = pcxe_globalwinon;				bd->txwinon      = pcxe_txwinon;				bd->rxwinon      = pcxe_rxwinon;				bd->memoff       = pcxe_memoff;				bd->assertgwinon = dummy_assertgwinon;				bd->assertmemoff = dummy_assertmemoff;				break;			case PCXI:			case PC64XE:				bd->memwinon     = pcxi_memwinon;				bd->memwinoff    = pcxi_memwinoff;				bd->globalwinon  = pcxi_globalwinon;				bd->txwinon      = pcxi_txwinon;				bd->rxwinon      = pcxi_rxwinon;				bd->memoff       = pcxi_memoff;				bd->assertgwinon = pcxi_assertgwinon;				bd->assertmemoff = pcxi_assertmemoff;				break;			default:				break;		} /* End switch on bd->type */		/* ---------------------------------------------------------------			Some cards need a memory segment to be defined for use in 			transmit and receive windowing operations.  These boards			are listed in the below switch.  In the case of the XI the			amount of memory on the board is variable so the memory_seg			is also variable.  This code determines what they segment 			should be.		----------------------------------------------------------------- */		switch (bd->type)		{ /* Begin switch on bd->type {board type} */			case PCXE:			case PCXEVE:			case PC64XE:				bd->memory_seg = 0xf000;			break;			case PCXI:				board_id = inb((int)bd->port);				if ((board_id & 0x1) == 0x1) 				{ /* Begin its an XI card */ 					/* Is it a 64K board */					if ((board_id & 0x30) == 0) 						bd->memory_seg = 0xf000;					/* Is it a 128K board */					if ((board_id & 0x30) == 0x10) 						bd->memory_seg = 0xe000;					/* Is is a 256K board */						if ((board_id & 0x30) == 0x20) 						bd->memory_seg = 0xc000;					/* Is it a 512K board */					if ((board_id & 0x30) == 0x30) 						bd->memory_seg = 0x8000;				} /* End it is an XI card */				else				{					printk(KERN_ERR "<Error> - Board at 0x%x doesn't appear to be an XI\n",(int)bd->port);				}			break;		} /* End switch on bd->type */	} /* End for each card */	if (tty_register_driver(&pc_driver))		panic("Couldn't register Digi PC/ driver");	if (tty_register_driver(&pc_callout))		panic("Couldn't register Digi PC/ callout");	if (tty_register_driver(&pc_info))		panic("Couldn't register Digi PC/ info ");	/* -------------------------------------------------------------------	   Start up the poller to check for events on all enabled boards	---------------------------------------------------------------------- */	init_timer(&epca_timer);	epca_timer.function = epcapoll;	mod_timer(&epca_timer, jiffies + HZ/25);	restore_flags(flags);	return 0;} /* End pc_init *//* ------------------ Begin post_fep_init  ---------------------- */static void post_fep_init(unsigned int crd){ /* Begin post_fep_init */	int i;	unchar *memaddr;	volatile struct global_data *gd;	struct board_info *bd;	volatile struct board_chan *bc;	struct channel *ch; 	int shrinkmem = 0, lowwater ;  	/*  -------------------------------------------------------------		This call is made by the user via. the ioctl call DIGI_INIT.		It is responsible for setting up all the card specific stuff.	---------------------------------------------------------------- */	bd = &boards[crd];	/* -----------------------------------------------------------------		If this is a PCI board, get the port info.  Remember PCI cards		do not have entries into the epcaconfig.h file, so we can't get 		the number of ports from it.  Unfortunetly, this means that anyone		doing a DIGI_GETINFO before the board has booted will get an invalid		number of ports returned (It should return 0).  Calls to DIGI_GETINFO		after DIGI_INIT has been called will return the proper values. 	------------------------------------------------------------------- */	if (bd->type >= PCIXEM) /* If the board in question is PCI */	{ /* Begin get PCI number of ports */		/* --------------------------------------------------------------------			Below we use XEMPORTS as a memory offset regardless of which PCI			card it is.  This is because all of the supported PCI cards have			the same memory offset for the channel data.  This will have to be			changed if we ever develop a PCI/XE card.  NOTE : The FEP manual			states that the port offset is 0xC22 as opposed to 0xC02.  This is			only true for PC/XE, and PC/XI cards; not for the XEM, or CX series.			On the PCI cards the number of ports is determined by reading a 			ID PROM located in the box attached to the card.  The card can then			determine the index the id to determine the number of ports available.			(FYI - The id should be located at 0x1ac (And may use up to 4 bytes			if the box in question is a XEM or CX)).  		------------------------------------------------------------------------ */ 		bd->numports = (unsigned short)*(unsigned char *)bus_to_virt((unsigned long)                                                       (bd->re_map_membase + XEMPORTS));				epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports");		nbdevs += (bd->numports);	} /* End get PCI number of ports */	if (crd != 0)		card_ptr[crd] = card_ptr[crd-1] + boards[crd-1].numports;	else		card_ptr[crd] = &digi_channels[crd]; /* <- For card 0 only */	ch = card_ptr[crd];	epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range");	memaddr = (unchar *)bd->re_map_membase;	/* 	   The below command is necessary because newer kernels (2.1.x and	   up) do not have a 1:1 virtual to physical mapping.  The below	   call adjust for that.	*/	memaddr = (unsigned char *)bus_to_virt((unsigned long)memaddr);	/* -----------------------------------------------------------------		The below assignment will set bc to point at the BEGINING of		the cards channel structures.  For 1 card there will be between		8 and 64 of these structures.	-------------------------------------------------------------------- */	bc = (volatile struct board_chan *)((ulong)memaddr + CHANSTRUCT);	/* -------------------------------------------------------------------		The below assignment will set gd to point at the BEGINING of		global memory address 0xc00.  The first data in that global		memory actually starts at address 0xc1a.  The command in 		pointer begins at 0xd10.	---------------------------------------------------------------------- */	gd = (volatile struct global_data *)((ulong)memaddr + GLOBAL);	/* --------------------------------------------------------------------		XEPORTS (address 0xc22) points at the number of channels the		card supports. (For 64XE, XI, XEM, and XR use 0xc02)	----------------------------------------------------------------------- */	if (((bd->type == PCXEVE) | (bd->type == PCXE)) &&	    (*(ushort *)((ulong)memaddr + XEPORTS) < 3))		shrinkmem = 1;	if (bd->type < PCIXEM)		request_region((int)bd->port, 4, board_desc[bd->type]);	memwinon(bd, 0);	/*  --------------------------------------------------------------------		Remember ch is the main drivers channels structure, while bc is 	   the cards channel structure.	------------------------------------------------------------------------ */	/* For every port on the card do ..... */	for (i = 0; i < bd->numports; i++, ch++, bc++) 	{ /* Begin for each port */		ch->brdchan        = bc;		ch->mailbox        = gd; 		ch->tqueue.routine = do_softint;		ch->tqueue.data    = ch;		ch->board          = &boards[crd];		switch (bd->type)		{ /* Begin switch bd->type */			/* ----------------------------------------------------------------				Since some of the boards use different bitmaps for their				control signals we cannot hard code these values and retain				portability.  We virtualize this data here.			------------------------------------------------------------------- */			case EISAXEM:			case PCXEM:			case PCIXEM:			case PCIXRJ:			case PCIXR:				ch->m_rts = 0x02 ;				ch->m_dcd = 0x80 ; 				ch->m_dsr = 0x20 ;				ch->m_cts = 0x10 ;				ch->m_ri  = 0x40 ;				ch->m_dtr = 0x01 ;				break;			case PCXE:			case PCXEVE:			case PCXI:			case PC64XE:				ch->m_rts = 0x02 ;				ch->m_dcd = 0x08 ; 				ch->m_dsr = 0x10 ;				ch->m_cts = 0x20 ;				ch->m_ri  = 0x40 ;				ch->m_dtr = 0x80 ;				break;			} /* End switch bd->type */		if (boards[crd].altpin) 		{			ch->dsr = ch->m_dcd;			ch->dcd = ch->m_dsr;			ch->digiext.digi_flags |= DIGI_ALTPIN;		}		else 		{ 			ch->dcd = ch->m_dcd;			ch->dsr = ch->m_dsr;		}			ch->boardnum   = crd;		ch->channelnum = i;		ch->magic      = EPCA_MAGIC;		ch->tty        = 0;		if (shrinkmem) 		{			fepcmd(ch, SETBUFFER, 32, 0, 0, 0);			shrinkmem = 0;		}		switch (bd->type)		{ /* Begin switch bd->type */			case PCIXEM:			case PCIXRJ:			case PCIXR:				/* Cover all the 2MEG cards */				ch->txptr = memaddr + (((bc->tseg) << 4) & 0x1fffff);				ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x1fffff);				ch->txwin = FEPWIN | ((bc->tseg) >> 11);				ch->rxwin = FEPWIN | ((bc->rseg) >> 11);				break;			case PCXEM:			case EISAXEM:				/* Cover all the 32K windowed cards */				/* Mask equal to window size - 1 */				ch->txptr = memaddr + (((bc->tseg) << 4) & 0x7fff);				ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x7fff);				ch->txwin = FEPWIN | ((bc->tseg) >> 11);				ch->rxwin = FEPWIN | ((bc->rseg) >> 11);				break;			case PCXEVE:			case PCXE:				ch->txptr = memaddr + (((bc->tseg - bd->memory_seg) << 4) & 0x1fff);				ch->txwin = FEPWIN | ((bc->tseg - bd->memory_seg) >> 9);				ch->rxptr = memaddr + (((bc->rseg - bd->memory_seg) << 4) & 0x1fff);				ch->rxwin = FEPWIN | ((bc->rseg - bd->memory_seg) >>9 );				break;			case PCXI:			case PC64XE:				ch->txptr = memaddr + ((bc->tseg - bd->memory_seg) << 4);				ch->rxptr = memaddr + ((bc->rseg - bd->memory_seg) << 4);				ch->txwin = ch->rxwin = 0;				break;		} /* End switch bd->type */		ch->txbufhead = 0;		ch->txbufsize = bc->tmax + 1;			ch->rxbufhead = 0;		ch->rxbufsize = bc->rmax + 1;			lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2);		/* Set transmitter low water mark */		fepcmd(ch, STXLWATER, lowwater, 0, 10, 0);		/* Set receiver low water mark */		fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0);		/* Set receiver high water mark */		fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0);		bc->edelay = 100;		bc->idata = 1;			ch->startc  = bc->startc;		ch->stopc   = bc->stopc;		ch->startca = bc->startca;		ch->stopca  = bc->stopca;			ch->fepcflag = 0;		ch->fepiflag = 0;		ch->fepoflag = 0;		ch->fepstartc = 0;		ch->feps

⌨️ 快捷键说明

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