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

📄 epca.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
			value is smaller will be the amount actually written. 			bytesAvailable will then take on this newly calculated value.		---------------------------------------------------------------------- */		bytesAvailable = MIN(dataLen, bytesAvailable);		/* First we read the data in from the file system into a temp buffer */		memoff(ch);		restore_flags(flags);		if (bytesAvailable) 		{ /* Begin bytesAvailable */			/* Can the user buffer be accessed at the moment ? */			if (verify_area(VERIFY_READ, (char*)buf, bytesAvailable))				bytesAvailable = 0; /* Can't do; try again later */			else  /* Evidently it can, began transmission */			{ /* Begin if area verified */				/* ---------------------------------------------------------------					The below function reads data from user memory.  This routine					can not be used in an interrupt routine. (Because it may 					generate a page fault)  It can only be called while we can the					user context is accessible. 					The prototype is :					inline void copy_from_user(void * to, const void * from,					                          unsigned long count);					You must include <asm/segment.h>					I also think (Check hackers guide) that optimization must					be turned ON.  (Which sounds strange to me...)						Remember copy_from_user WILL generate a page fault if the					user memory being accessed has been swapped out.  This can					cause this routine to temporarily sleep while this page					fault is occuring.								----------------------------------------------------------------- */				copy_from_user(ch->tmp_buf, buf, bytesAvailable);			} /* End if area verified */		} /* End bytesAvailable */		/* ------------------------------------------------------------------ 			Set buf to this address for the moment.  tmp_buf was allocated in			post_fep_init.		--------------------------------------------------------------------- */		buf = ch->tmp_buf;	} /* End from_user */	/* All data is now local */	amountCopied = 0;	save_flags(flags);	cli();	globalwinon(ch);	head = bc->tin & (size - 1);	tail = bc->tout;	if (tail != bc->tout)		tail = 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;	} /* End head has not wrapped */	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);	bc->tin = head;	if ((ch->statusflags & LOWWAIT) == 0) 	{		ch->statusflags |= LOWWAIT;		bc->ilow = 1;	}	memoff(ch);	restore_flags(flags);	return(amountCopied);} /* End pc_write *//* ------------------ Begin pc_put_char  ------------------------- */static void pc_put_char(struct tty_struct *tty, unsigned char c){ /* Begin pc_put_char */   	pc_write(tty, 0, &c, 1);	return;} /* End pc_put_char *//* ------------------ Begin pc_write_room  ------------------------- */static int pc_write_room(struct tty_struct *tty){ /* Begin pc_write_room */	int remain;	struct channel *ch;	unsigned long flags;	unsigned int head, tail;	volatile struct board_chan *bc;	remain = 0;	/* ---------------------------------------------------------		verifyChannel returns the channel from the tty struct		if it is valid.  This serves as a sanity check.	------------------------------------------------------------- */	if ((ch = verifyChannel(tty)) != NULL) 	{		save_flags(flags);		cli();		globalwinon(ch);		bc   = ch->brdchan;		head = bc->tin & (ch->txbufsize - 1);		tail = bc->tout;		if (tail != bc->tout)			tail = bc->tout;		/* Wrap tail if necessary */		tail &= (ch->txbufsize - 1);		if ((remain = tail - head - 1) < 0 )			remain += ch->txbufsize;		if (remain && (ch->statusflags & LOWWAIT) == 0) 		{			ch->statusflags |= LOWWAIT;			bc->ilow = 1;		}		memoff(ch);		restore_flags(flags);	}	/* Return how much room is left on card */	return remain;} /* End pc_write_room *//* ------------------ Begin pc_chars_in_buffer  ---------------------- */static int pc_chars_in_buffer(struct tty_struct *tty){ /* Begin pc_chars_in_buffer */	int chars;	unsigned int ctail, head, tail;	int remain;	unsigned long flags;	struct channel *ch;	volatile struct board_chan *bc;	/* ---------------------------------------------------------		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);	save_flags(flags);	cli();	globalwinon(ch);	bc = ch->brdchan;	tail = bc->tout;	head = bc->tin;	ctail = ch->mailbox->cout;	if (tail == head && ch->mailbox->cin == ctail && bc->tbusy == 0)		chars = 0;	else 	{ /* Begin if some space on the card has been used */		head = bc->tin & (ch->txbufsize - 1);		tail &= (ch->txbufsize - 1);		/*  --------------------------------------------------------------			The logic here is basically opposite of the above pc_write_room			here we are finding the amount of bytes in the buffer filled.			Not the amount of bytes empty.		------------------------------------------------------------------- */		if ((remain = tail - head - 1) < 0 )			remain += ch->txbufsize;		chars = (int)(ch->txbufsize - remain);		/* -------------------------------------------------------------  			Make it possible to wakeup anything waiting for output			in tty_ioctl.c, etc.			If not already set.  Setup an event to indicate when the			transmit buffer empties 		----------------------------------------------------------------- */		if (!(ch->statusflags & EMPTYWAIT))			setup_empty_event(tty,ch);	} /* End if some space on the card has been used */	memoff(ch);	restore_flags(flags);	/* Return number of characters residing on card. */	return(chars);} /* End pc_chars_in_buffer *//* ------------------ Begin pc_flush_buffer  ---------------------- */static void pc_flush_buffer(struct tty_struct *tty){ /* Begin pc_flush_buffer */	unsigned int tail;	unsigned long flags;	struct channel *ch;	volatile struct board_chan *bc;	/* ---------------------------------------------------------		verifyChannel returns the channel from the tty struct		if it is valid.  This serves as a sanity check.	------------------------------------------------------------- */	if ((ch = verifyChannel(tty)) == NULL)		return;	save_flags(flags);	cli();	globalwinon(ch);	bc   = ch->brdchan;	tail = bc->tout;	/* Have FEP move tout pointer; effectively flushing transmit buffer */	fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0);	memoff(ch);	restore_flags(flags);	wake_up_interruptible(&tty->write_wait);	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)		(tty->ldisc.write_wakeup)(tty);} /* End pc_flush_buffer *//* ------------------ Begin pc_flush_chars  ---------------------- */static void pc_flush_chars(struct tty_struct *tty){ /* Begin pc_flush_chars */	struct channel * ch;	/* ---------------------------------------------------------		verifyChannel returns the channel from the tty struct		if it is valid.  This serves as a sanity check.	------------------------------------------------------------- */	if ((ch = verifyChannel(tty)) != NULL) 	{		unsigned long flags;		save_flags(flags);		cli();		/* ----------------------------------------------------------------			If not already set and the transmitter is busy setup an event			to indicate when the transmit empties.		------------------------------------------------------------------- */		if ((ch->statusflags & TXBUSY) && !(ch->statusflags & EMPTYWAIT))			setup_empty_event(tty,ch);		restore_flags(flags);	}} /* End pc_flush_chars *//* ------------------ Begin block_til_ready  ---------------------- */static int block_til_ready(struct tty_struct *tty,                            struct file *filp, struct channel *ch){ /* Begin block_til_ready */	DECLARE_WAITQUEUE(wait,current);	int	retval, do_clocal = 0;	unsigned long flags;	if (tty_hung_up_p(filp))	{		if (ch->asyncflags & ASYNC_HUP_NOTIFY)			retval = -EAGAIN;		else			retval = -ERESTARTSYS;			return(retval);	}	/* ----------------------------------------------------------------- 		If the device is in the middle of being closed, then block		until it's done, and then try again.	-------------------------------------------------------------------- */	if (ch->asyncflags & ASYNC_CLOSING) 	{		interruptible_sleep_on(&ch->close_wait);		if (ch->asyncflags & ASYNC_HUP_NOTIFY)			return -EAGAIN;		else			return -ERESTARTSYS;	}	/* ----------------------------------------------------------------- 	   If this is a callout device, then just make sure the normal	   device isn't being used.	-------------------------------------------------------------------- */	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) 	{ /* A cud device has been opened */		if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)			return -EBUSY;		if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&		    (ch->asyncflags & ASYNC_SESSION_LOCKOUT) &&		    (ch->session != current->session))		    return -EBUSY;		if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&		    (ch->asyncflags & ASYNC_PGRP_LOCKOUT) &&		    (ch->pgrp != current->pgrp))		    return -EBUSY; 		ch->asyncflags |= ASYNC_CALLOUT_ACTIVE;		return 0;	} /* End a cud device has been opened */	if (filp->f_flags & O_NONBLOCK) 	{		/* ----------------------------------------------------------------- 	  	 If non-blocking mode is set, then make the check up front	  	 and then exit.		-------------------------------------------------------------------- */		if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE)			return -EBUSY;		ch->asyncflags |= ASYNC_NORMAL_ACTIVE;		return 0;	}	if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE) 	{		if (ch->normal_termios.c_cflag & CLOCAL)			do_clocal = 1;	}	else 	{		if (tty->termios->c_cflag & CLOCAL)			do_clocal = 1;	}	   /* Block waiting for the carrier detect and the line to become free */		retval = 0;	add_wait_queue(&ch->open_wait, &wait);	save_flags(flags);	cli();

⌨️ 快捷键说明

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