📄 ip2main.c
字号:
(pCh->flags & ASYNC_CLOSING)?"True":"False"); printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");#endif#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_OPEN, 3, 2, (pCh->flags & ASYNC_CALLOUT_ACTIVE), (pCh->flags & ASYNC_CLOSING) );#endif /* check for signal */ if (signal_pending(current)) { rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS); break; } interruptible_sleep_on(&pCh->open_wait); } --pCh->wopen; //why count?#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_OPEN, 4, 0 );#endif if (rc != 0 ) { return rc; } pCh->flags |= ASYNC_NORMAL_ACTIVE;noblock: /* first open - Assign termios structure to port */ if ( tty->count == 1 ) { i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); if ( pCh->flags & ASYNC_SPLIT_TERMIOS ) { if ( tty->driver.subtype == SERIAL_TYPE_NORMAL ) { *tty->termios = pCh->NormalTermios; } else { *tty->termios = pCh->CalloutTermios; } } /* Now we must send the termios settings to the loadware */ set_params( pCh, NULL ); } /* override previous and never reset ??? */ pCh->session = current->session; pCh->pgrp = current->pgrp; /* * Now set any i2lib options. These may go away if the i2lib code ends * up rolled into the mainline. */ pCh->channelOptions |= CO_NBLOCK_WRITE;#ifdef IP2DEBUG_OPEN printk (KERN_DEBUG "IP2: open completed\n" );#endif serviceOutgoingFifo( pCh->pMyBord );#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );#endif return 0;}/******************************************************************************//* 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; }#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );#endif#ifdef IP2DEBUG_OPEN printk(KERN_DEBUG "IP2:close ttyF%02X:\n",MINOR(tty->device));#endif if ( tty_hung_up_p ( pFile ) ) { MOD_DEC_USE_COUNT;#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );#endif return; } if ( tty->count > 1 ) { /* not the last close */ MOD_DEC_USE_COUNT;#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );#endif return; } pCh->flags |= ASYNC_CLOSING; // last close actually /* * Save the termios structure, since this port may have separate termios * for callout and dialin. */ if (pCh->flags & ASYNC_NORMAL_ACTIVE) pCh->NormalTermios = *tty->termios; if (pCh->flags & ASYNC_CALLOUT_ACTIVE) pCh->CalloutTermios = *tty->termios; 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) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(pCh->ClosingDelay); } wake_up_interruptible(&pCh->open_wait); } pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&pCh->close_wait);#ifdef IP2DEBUG_OPEN DBG_CNT("ip2_close: after wakeups--");#endif MOD_DEC_USE_COUNT;#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );#endif return;}/******************************************************************************//* Function: ip2_hangup() *//* Parameters: Pointer to tty structure *//* Returns: Nothing *//* *//* Description: *//* *//* *//******************************************************************************/static voidip2_hangup ( PTTY tty ){ i2ChanStrPtr pCh = tty->driver_data;#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );#endif 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 || (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|ASYNC_CALLOUT_ACTIVE); pCh->pTTY = NULL; wake_up_interruptible ( &pCh->open_wait );#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );#endif}/******************************************************************************//******************************************************************************//* 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, int user, const unsigned char *pData, int count){ i2ChanStrPtr pCh = tty->driver_data; int bytesSent = 0; unsigned long flags;#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );#endif /* 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, user ); WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );#endif 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;#ifdef IP2DEBUG_TRACE// ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );#endif 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);#ifdef IP2DEBUG_TRACE// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );#endif}/******************************************************************************//* 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 ) {#ifdef IP2DEBUG_TRACE// ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );#endif // // 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);#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );#endif 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;#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );#endif#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;#ifdef IP2DEBUG_TRACE ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );#endif#ifdef IP2DEBUG_WRITE printk (KERN_DEBUG "IP2: flush buffer\n" );#endif WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); pCh->Pbuf_stuff = 0; WRITE_U
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -