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 ); 
ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff); ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9); ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff); ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 ); 
static void post_fep_init(unsigned int crd){ /* Begin post_fep_init */	int i;	unsigned char *memaddr;	struct global_data *gd;	struct board_info *bd;	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) { /* 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)).  		------------------------------------------------------------------------ */ 		/* PCI cards are already remapped at this point ISA are not */		bd->numports = readw(bd->re_map_membase + XEMPORTS);		epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports");		nbdevs += (bd->numports);	} else {		/* Fix up the mappings for ISA/EISA etc */		/* FIXME: 64K - can we be smarter ? */		bd->re_map_membase = ioremap(bd->membase, 0x10000);	}	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 = bd->re_map_membase;	/* -----------------------------------------------------------------		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 = (struct board_chan *)(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 = (struct global_data *)(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) && (readw(memaddr + XEPORTS) < 3))		shrinkmem = 1;	if (bd->type < PCIXEM)		if (!request_region((int)bd->port, 4, board_desc[bd->type]))			return;			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 */		unsigned long flags;		ch->brdchan        = bc;		ch->mailbox        = gd; 		INIT_WORK(&ch->tqueue, do_softint, ch);		ch->board          = &boards[crd];		spin_lock_irqsave(&epca_lock, flags);		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        = NULL;		if (shrinkmem) {			fepcmd(ch, SETBUFFER, 32, 0, 0, 0);			shrinkmem = 0;		}		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);		writew(100, &bc->edelay);		writeb(1, &bc->idata);			ch->startc  = readb(&bc->startc);		ch->stopc   = readb(&bc->stopc);		ch->startca = readb(&bc->startca);		ch->stopca  = readb(&bc->stopca);			ch->fepcflag = 0;		ch->fepiflag = 0;		ch->fepoflag = 0;		ch->fepstartc = 0;		ch->fepstopc = 0;		ch->fepstartca = 0;		ch->fepstopca = 0;			ch->close_delay = 50;		ch->count = 0;		ch->blocked_open = 0;		init_waitqueue_head(&ch->open_wait);		init_waitqueue_head(&ch->close_wait);		spin_unlock_irqrestore(&epca_lock, flags);		ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL);		if (!ch->tmp_buf) {			printk(KERN_ERR "POST FEP INIT : kmalloc failed for port 0x%x\n",i);			release_region((int)bd->port, 4);			while(i-- > 0)				kfree((ch--)->tmp_buf);			return;		} else			memset((void *)ch->tmp_buf,0,ch->txbufsize);	} /* End for each port */	printk(KERN_INFO 	        "Digi PC/Xx Driver V%s:  %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", 	        VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports);	memwinoff(bd, 0);} /* End post_fep_init */
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/bc9a5154a24d16d41cc79dbf1442de34454bc7db/epca.c/buggy/drivers/char/epca.c