ip2main.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,945 行 · 第 1/5 页

C
1,945
字号
/******************************************************************************//* Function:   ip2_close()                                                    *//* Parameters: Pointer to tty structure                                       *//*             Pointer to file structure                                      *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//*                                                                            *//*                                                                            *//******************************************************************************/static voidip2_close( PTTY tty, struct file *pFile ){	i2ChanStrPtr  pCh = tty->driver_data;	if ( !pCh ) {		return;	}	ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );#ifdef IP2DEBUG_OPEN	printk(KERN_DEBUG "IP2:close %s:\n",tty->name);#endif	if ( tty_hung_up_p ( pFile ) ) {		ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );		return;	}	if ( tty->count > 1 ) { /* not the last close */		ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );		return;	}	pCh->flags |= ASYNC_CLOSING;	// last close actually	tty->closing = 1;	if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {		/*		 * Before we drop DTR, make sure the transmitter has completely drained.		 * This uses an timeout, after which the close		 * completes.		 */		ip2_wait_until_sent(tty, pCh->ClosingWaitTime );	}	/*	 * At this point we stop accepting input. Here we flush the channel	 * input buffer which will allow the board to send up more data. Any	 * additional input is tossed at interrupt/poll time.	 */	i2InputFlush( pCh );	/* disable DSS reporting */	i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,				CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);	if ( !tty || (tty->termios->c_cflag & HUPCL) ) {		i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);		pCh->dataSetOut &= ~(I2_DTR | I2_RTS);		i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));	}	serviceOutgoingFifo ( pCh->pMyBord );	if ( tty->driver->flush_buffer ) 		tty->driver->flush_buffer(tty);	if ( tty->ldisc.flush_buffer )  		tty->ldisc.flush_buffer(tty);	tty->closing = 0;		pCh->pTTY = NULL;	if (pCh->wopen) {		if (pCh->ClosingDelay) {			msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));		}		wake_up_interruptible(&pCh->open_wait);	}	pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);	wake_up_interruptible(&pCh->close_wait);#ifdef IP2DEBUG_OPEN	DBG_CNT("ip2_close: after wakeups--");#endif	ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );	return;}/******************************************************************************//* Function:   ip2_hangup()                                                   *//* Parameters: Pointer to tty structure                                       *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//*                                                                            *//*                                                                            *//******************************************************************************/static voidip2_hangup ( PTTY tty ){	i2ChanStrPtr  pCh = tty->driver_data;	if( !pCh ) {		return;	}	ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );	ip2_flush_buffer(tty);	/* disable DSS reporting */	i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);	i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);	if ( (tty->termios->c_cflag & HUPCL) ) {		i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);		pCh->dataSetOut &= ~(I2_DTR | I2_RTS);		i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));	}	i2QueueCommands(PTYPE_INLINE, pCh, 1, 3, 				CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);	serviceOutgoingFifo ( pCh->pMyBord );	wake_up_interruptible ( &pCh->delta_msr_wait );	pCh->flags &= ~ASYNC_NORMAL_ACTIVE;	pCh->pTTY = NULL;	wake_up_interruptible ( &pCh->open_wait );	ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );}/******************************************************************************//******************************************************************************//* Device Output Section                                                      *//******************************************************************************//******************************************************************************//******************************************************************************//* Function:   ip2_write()                                                    *//* Parameters: Pointer to tty structure                                       *//*             Flag denoting data is in user (1) or kernel (0) space          *//*             Pointer to data                                                *//*             Number of bytes to write                                       *//* Returns:    Number of bytes actually written                               *//*                                                                            *//* Description: (MANDATORY)                                                   *//*                                                                            *//*                                                                            *//******************************************************************************/static intip2_write( PTTY tty, const unsigned char *pData, int count){	i2ChanStrPtr  pCh = tty->driver_data;	int bytesSent = 0;	unsigned long flags;	ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );	/* Flush out any buffered data left over from ip2_putchar() calls. */	ip2_flush_chars( tty );	/* This is the actual move bit. Make sure it does what we need!!!!! */	WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);	bytesSent = i2Output( pCh, pData, count, 0 );	WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);	ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );	return bytesSent > 0 ? bytesSent : 0;}/******************************************************************************//* Function:   ip2_putchar()                                                  *//* Parameters: Pointer to tty structure                                       *//*             Character to write                                             *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//*                                                                            *//*                                                                            *//******************************************************************************/static voidip2_putchar( PTTY tty, unsigned char ch ){	i2ChanStrPtr  pCh = tty->driver_data;	unsigned long flags;//	ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );	WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);	pCh->Pbuf[pCh->Pbuf_stuff++] = ch;	if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {		WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);		ip2_flush_chars( tty );	} else		WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);//	ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );}/******************************************************************************//* Function:   ip2_flush_chars()                                              *//* Parameters: Pointer to tty structure                                       *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//*                                                                            *//******************************************************************************/static voidip2_flush_chars( PTTY tty ){	int   strip;	i2ChanStrPtr  pCh = tty->driver_data;	unsigned long flags;	WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);	if ( pCh->Pbuf_stuff ) {//		ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );		//		// We may need to restart i2Output if it does not fullfill this request		//		strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 );		if ( strip != pCh->Pbuf_stuff ) {			memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );		}		pCh->Pbuf_stuff -= strip;	}	WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);}/******************************************************************************//* Function:   ip2_write_room()                                               *//* Parameters: Pointer to tty structure                                       *//* Returns:    Number of bytes that the driver can accept                     *//*                                                                            *//* Description:                                                               *//*                                                                            *//******************************************************************************/static intip2_write_room ( PTTY tty ){	int bytesFree;	i2ChanStrPtr  pCh = tty->driver_data;	unsigned long flags;	READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);	bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;	READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);	ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );	return ((bytesFree > 0) ? bytesFree : 0);}/******************************************************************************//* Function:   ip2_chars_in_buf()                                             *//* Parameters: Pointer to tty structure                                       *//* Returns:    Number of bytes queued for transmission                        *//*                                                                            *//* Description:                                                               *//*                                                                            *//*                                                                            *//******************************************************************************/static intip2_chars_in_buf ( PTTY tty ){	i2ChanStrPtr  pCh = tty->driver_data;	int rc;	unsigned long flags;	ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );#ifdef IP2DEBUG_WRITE	printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",				 pCh->Obuf_char_count + pCh->Pbuf_stuff,				 pCh->Obuf_char_count, pCh->Pbuf_stuff );#endif	READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);	rc =  pCh->Obuf_char_count;	READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);	READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);	rc +=  pCh->Pbuf_stuff;	READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);	return rc;}/******************************************************************************//* Function:   ip2_flush_buffer()                                             *//* Parameters: Pointer to tty structure                                       *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//*                                                                            *//*                                                                            *//******************************************************************************/static voidip2_flush_buffer( PTTY tty ){	i2ChanStrPtr  pCh = tty->driver_data;	unsigned long flags;	ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );#ifdef IP2DEBUG_WRITE	printk (KERN_DEBUG "IP2: flush buffer\n" );#endif	WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);	pCh->Pbuf_stuff = 0;	WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);	i2FlushOutput( pCh );	ip2_owake(tty);	ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );}/******************************************************************************//* Function:   ip2_wait_until_sent()                                          *//* Parameters: Pointer to tty structure                                       *//*             Timeout for wait.                                              *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//* This function is used in place of the normal tty_wait_until_sent, which    *//* only waits for the driver buffers to be empty (or rather, those buffers    *//* reported by chars_in_buffer) which doesn't work for IP2 due to the         *//* indeterminate number of bytes buffered on the board.                       *//******************************************************************************/static voidip2_wait_until_sent ( PTTY tty, int timeout ){	int i = jiffies;	i2ChanStrPtr  pCh = tty->driver_data;	tty_wait_until_sent(tty, timeout );	if ( (i = timeout - (jiffies -i)) > 0)		i2DrainOutput( pCh, i );}/******************************************************************************//******************************************************************************//* Device Input Section                                                       *//******************************************************************************//******************************************************************************//******************************************************************************//* Function:   ip2_throttle()                                                 *//* Parameters: Pointer to tty structure                                       *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//*                                                                            *//*                                                                            *//******************************************************************************/static voidip2_throttle ( PTTY tty ){	i2ChanStrPtr  pCh = tty->driver_data;#ifdef IP2DEBUG_READ	printk (KERN_DEBUG "IP2: throttle\n" );#endif	/*	 * Signal the poll/interrupt handlers not to forward incoming data to	 * the line discipline. This will cause the buffers to fill up in the	 * library and thus cause the library routines to send the flow control	 * stuff.	 */	pCh->throttled = 1;}/******************************************************************************//* Function:   ip2_unthrottle()                                               *//* Parameters: Pointer to tty structure                                       *//* Returns:    Nothing                                                        *//*                                                                            *//* Description:                                                               *//*                                                              

⌨️ 快捷键说明

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