struct board_chan *bc; 
struct board_chan __iomem *bc; 
static int pc_write(struct tty_struct * tty,                    const unsigned char *buf, int bytesAvailable){ /* Begin pc_write */	unsigned int head, tail;	int dataLen;	int size;	int amountCopied;	struct channel *ch;	unsigned long flags;	int remain;	struct board_chan *bc;	/* ----------------------------------------------------------------		pc_write is primarily called directly by the kernel routine		tty_write (Though it can also be called by put_char) found in		tty_io.c.  pc_write is passed a line discipline buffer where 		the data to be written out is stored.  The line discipline 		implementation itself is done at the kernel level and is not 		brought into the driver.  	------------------------------------------------------------------- */	/* ---------------------------------------------------------		verifyChannel returns the channel from the tty struct		if it is valid.  This serves as a sanity check.	------------------------------------------------------------- */	if ((ch = verifyChannel(tty)) == NULL)		return 0;	/* Make a pointer to the channel data structure found on the board. */	bc   = ch->brdchan;	size = ch->txbufsize;	amountCopied = 0;	spin_lock_irqsave(&epca_lock, flags);	globalwinon(ch);	head = readw(&bc->tin) & (size - 1);	tail = readw(&bc->tout);	if (tail != readw(&bc->tout))		tail = readw(&bc->tout);	tail &= (size - 1);	/*	If head >= tail, head has not wrapped around. */ 	if (head >= tail)  { /* Begin head has not wrapped */		/* ---------------------------------------------------------------			remain (much like dataLen above) represents the total amount of			space available on the card for data.  Here dataLen represents			the space existing between the head pointer and the end of 			buffer.  This is important because a memcpy cannot be told to			automatically wrap around when it hits the buffer end.		------------------------------------------------------------------ */ 		dataLen = size - head;		remain = size - (head - tail) - 1;	} else { /* Begin head has wrapped around */		remain = tail - head - 1;		dataLen = remain;	} /* End head has wrapped around */	/* -------------------------------------------------------------------			Check the space on the card.  If we have more data than 			space; reduce the amount of data to fit the space.	---------------------------------------------------------------------- */	bytesAvailable = min(remain, bytesAvailable);	txwinon(ch);	while (bytesAvailable > 0) 	{ /* Begin while there is data to copy onto card */		/* -----------------------------------------------------------------			If head is not wrapped, the below will make sure the first 			data copy fills to the end of card buffer.		------------------------------------------------------------------- */		dataLen = min(bytesAvailable, dataLen);		memcpy(ch->txptr + head, buf, dataLen);		buf += dataLen;		head += dataLen;		amountCopied += dataLen;		bytesAvailable -= dataLen;		if (head >= size) {			head = 0;			dataLen = tail;		}	} /* End while there is data to copy onto card */	ch->statusflags |= TXBUSY;	globalwinon(ch);	writew(head, &bc->tin);	if ((ch->statusflags & LOWWAIT) == 0)  {		ch->statusflags |= LOWWAIT;		writeb(1, &bc->ilow);	}	memoff(ch);	spin_unlock_irqrestore(&epca_lock, flags);	return(amountCopied);} /* End pc_write */
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/bc9a5154a24d16d41cc79dbf1442de34454bc7db/epca.c/buggy/drivers/char/epca.c