Exemplo n.º 1
0
/**
 * n_hdlc_tty_ioctl - process IOCTL system call for the tty device.
 * @tty - pointer to tty instance data
 * @file - pointer to open file object for device
 * @cmd - IOCTL command code
 * @arg - argument for IOCTL call (cmd dependent)
 *
 * Returns command dependent result.
 */
static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
			    unsigned int cmd, unsigned long arg)
{
	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
	int error = 0;
	int count;
	unsigned long flags;
	struct n_hdlc_buf *buf = NULL;

	if (debuglevel >= DEBUG_LEVEL_INFO)	
		printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
			__FILE__,__LINE__,cmd);
		
	/* Verify the status of the device */
	if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC)
		return -EBADF;

	switch (cmd) {
	case FIONREAD:
		/* report count of read data available */
		/* in next available frame (if any) */
		spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
		buf = list_first_entry_or_null(&n_hdlc->rx_buf_list.list,
						struct n_hdlc_buf, list_item);
		if (buf)
			count = buf->count;
		else
			count = 0;
		spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
		error = put_user(count, (int __user *)arg);
		break;

	case TIOCOUTQ:
		/* get the pending tx byte count in the driver */
		count = tty_chars_in_buffer(tty);
		/* add size of next output frame in queue */
		spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
		buf = list_first_entry_or_null(&n_hdlc->tx_buf_list.list,
						struct n_hdlc_buf, list_item);
		if (buf)
			count += buf->count;
		spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
		error = put_user(count, (int __user *)arg);
		break;

	case TCFLSH:
		switch (arg) {
		case TCIOFLUSH:
		case TCOFLUSH:
			flush_tx_queue(tty);
		}
		/* fall through to default */

	default:
		error = n_tty_ioctl_helper(tty, file, cmd, arg);
		break;
	}
	return error;
	
}	/* end of n_hdlc_tty_ioctl() */
Exemplo n.º 2
0
static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
							poll_table *wait)
{
	unsigned int mask = 0;

	poll_wait(file, &tty->read_wait, wait);
	poll_wait(file, &tty->write_wait, wait);
	if (input_available_p(tty, TIME_CHAR(tty) ? 0 : MIN_CHAR(tty)))
		mask |= POLLIN | POLLRDNORM;
	if (tty->packet && tty->link->ctrl_status)
		mask |= POLLPRI | POLLIN | POLLRDNORM;
	if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
		mask |= POLLHUP;
	if (tty_hung_up_p(file))
		mask |= POLLHUP;
	if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
		if (MIN_CHAR(tty) && !TIME_CHAR(tty))
			tty->minimum_to_wake = MIN_CHAR(tty);
		else
			tty->minimum_to_wake = 1;
	}
	if (tty->ops->write && !tty_is_writelocked(tty) &&
			tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
			tty_write_room(tty) > 0)
		mask |= POLLOUT | POLLWRNORM;
	return mask;
}
Exemplo n.º 3
0
static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
			    unsigned int cmd, unsigned long arg)
{
	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
	int error = 0;
	int count;
	unsigned long flags;
	
	if (debuglevel >= DEBUG_LEVEL_INFO)	
		printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
			__FILE__,__LINE__,cmd);
		
	
	if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC)
		return -EBADF;

	switch (cmd) {
	case FIONREAD:
		
		
		spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
		if (n_hdlc->rx_buf_list.head)
			count = n_hdlc->rx_buf_list.head->count;
		else
			count = 0;
		spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
		error = put_user(count, (int __user *)arg);
		break;

	case TIOCOUTQ:
		
		count = tty_chars_in_buffer(tty);
		
		spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
		if (n_hdlc->tx_buf_list.head)
			count += n_hdlc->tx_buf_list.head->count;
		spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
		error = put_user(count, (int __user *)arg);
		break;

	case TCFLSH:
		switch (arg) {
		case TCIOFLUSH:
		case TCOFLUSH:
			flush_tx_queue(tty);
		}
		

	default:
		error = n_tty_ioctl_helper(tty, file, cmd, arg);
		break;
	}
	return error;
	
}	
Exemplo n.º 4
0
/**
 * Prototype    : ps_change_uart_baud_rate
 * Description  : change arm platform uart baud rate to secend
 *                baud rate for high baud rate when download patch
 * input        : ps_core_d
 * output       : no
 * Calls        :
 * Called By    :
 *
 *   History        :
 *   1.Date         : 2012/11/05
 *     Author       : wx144390
 *     Modification : Created function
 *
 */
int32 ps_change_uart_baud_rate(int64 baud_rate, uint8 enable_flowctl)
{
    struct ps_plat_s *ps_plat_d = NULL;
    struct ps_core_s *ps_core_d;
    uint64 timeleft = 0;

    PS_PRINT_INFO("%s\n", __func__);

    ps_get_plat_reference(&ps_plat_d);
    if (unlikely(NULL == ps_plat_d))
    {
        PS_PRINT_ERR("ps_plat_d is NULL\n");
        return -EINVAL;
    }

    ps_core_d = ps_plat_d->core_data;
    if (likely(NULL != ps_core_d->tty))
    {
        tty_ldisc_flush(ps_core_d->tty);
        tty_driver_flush_buffer(ps_core_d->tty);
    }

    if (!IS_ERR_OR_NULL(ps_core_d->tty))
    {
        if (tty_chars_in_buffer(ps_core_d->tty))
        {
            PS_PRINT_INFO("uart tx buf is not empty\n");
        }
    }

    INIT_COMPLETION(ps_plat_d->ldisc_reconfiged);
    ps_plat_d->flow_cntrl    = enable_flowctl;
    ps_plat_d->baud_rate     = baud_rate;
    ps_plat_d->ldisc_install = TTY_LDISC_RECONFIG;

    PS_PRINT_INFO("ldisc_install = %d\n", TTY_LDISC_RECONFIG);
    sysfs_notify(g_sysfs_hi110x_bfgx, NULL, "install");

    timeleft = wait_for_completion_timeout(&ps_plat_d->ldisc_reconfiged, msecs_to_jiffies(HISI_LDISC_TIME));
    if (!timeleft)
    {
        PS_PRINT_ERR("hisi bfgx ldisc reconfig timeout\n");
        CHR_EXCEPTION(CHR_GNSS_DRV(CHR_GNSS_DRV_EVENT_PLAT, CHR_PLAT_DRV_ERROR_CFG_UART));

        return -EINVAL;
    }

    PS_PRINT_SUC("hisi bfgx ldisc reconfig succ\n");

    return 0;
}
Exemplo n.º 5
0
static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
		       unsigned int cmd, unsigned long arg)
{
	int retval;

	switch (cmd) {
	case TIOCOUTQ:
		return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
	case TIOCINQ:
		
		retval = tty->read_cnt;
		if (L_ICANON(tty))
			retval = inq_canon(tty);
		return put_user(retval, (unsigned int __user *) arg);
	default:
		return n_tty_ioctl_helper(tty, file, cmd, arg);
	}
}
Exemplo n.º 6
0
static void x25_asy_timeout(struct net_device *dev)
{
	struct x25_asy *sl = netdev_priv(dev);

	spin_lock(&sl->lock);
	if (netif_queue_stopped(dev)) {
		/* May be we must check transmitter timeout here ?
		 *      14 Oct 1994 Dmitry Gorodchanin.
		 */
		netdev_warn(dev, "transmit timed out, %s?\n",
			    (tty_chars_in_buffer(sl->tty) || sl->xleft) ?
			    "bad line quality" : "driver error");
		sl->xleft = 0;
		clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
		x25_asy_unlock(sl);
	}
	spin_unlock(&sl->lock);
}
Exemplo n.º 7
0
void tty_wait_until_sent(struct tty_struct *tty, long timeout)
{
	tty_debug_wait_until_sent(tty, "wait until sent, timeout=%ld\n", timeout);

	if (!timeout)
		timeout = MAX_SCHEDULE_TIMEOUT;

	timeout = wait_event_interruptible_timeout(tty->write_wait,
			!tty_chars_in_buffer(tty), timeout);
	if (timeout <= 0)
		return;

	if (timeout == MAX_SCHEDULE_TIMEOUT)
		timeout = 0;

	if (tty->ops->wait_until_sent)
		tty->ops->wait_until_sent(tty, timeout);
}
Exemplo n.º 8
0
void ps_uart_state_dump(struct tty_struct *tty)
{
    struct ps_core_s *ps_core_d = NULL;
    ps_get_core_reference(&ps_core_d);
    if (unlikely((NULL == ps_core_d) || (NULL == tty)))
    {
        PS_PRINT_ERR("ps_core_d ot tty is NULL\n");
        return;
    }

    PS_PRINT_INFO("===pre uart&tty state===\n");
    ps_uart_state_print(&g_uart_state_pre);
    PS_PRINT_INFO("===cur uart&tty state===\n");
    ps_uart_state_get(tty);
    ps_uart_state_print(&g_uart_state);
    PS_PRINT_INFO("chars in tty tx buf len=%x\n", tty_chars_in_buffer(ps_core_d->tty));

    return;
}
Exemplo n.º 9
0
void ps_uart_state_dump(struct tty_struct *tty)
{
    struct ps_core_s *ps_core_d = NULL;
    struct uart_state *state = NULL;

    ps_get_core_reference(&ps_core_d);
    if (unlikely((NULL == ps_core_d) || (NULL == tty)))
    {
        PS_PRINT_ERR("ps_core_d ot tty is NULL\n");
        return;
    }

    state = tty->driver_data;
    if (unlikely(NULL == state->uart_port))
    {
        PS_PRINT_ERR("uart_port is NULL\n");
        return;
    }

    PS_PRINT_INFO("===pre uart&tty state===\n");
    ps_uart_state_print(&g_uart_state_pre);
    PS_PRINT_INFO("===cur uart&tty state===\n");
    ps_uart_state_get(tty);
    ps_uart_state_print(&g_uart_state);
    PS_PRINT_INFO("chars in tty tx buf len=%x\n", tty_chars_in_buffer(ps_core_d->tty));
    PS_PRINT_INFO("uart port mctrl:0x%x\n", state->uart_port->mctrl);

    PS_PRINT_INFO("DR   :0x%x\n", readw(state->uart_port->membase + 0x00));
    PS_PRINT_INFO("FR   :0x%x\n", readw(state->uart_port->membase + 0x18));
    PS_PRINT_INFO("IBRD :0x%x\n", readw(state->uart_port->membase + 0x24));
    PS_PRINT_INFO("FBRD :0x%x\n", readw(state->uart_port->membase + 0x28));
    PS_PRINT_INFO("LCR_H:0x%x\n", readw(state->uart_port->membase + 0x2C));
    PS_PRINT_INFO("CR   :0x%x\n", readw(state->uart_port->membase + 0x30));
    PS_PRINT_INFO("IFLS :0x%x\n", readw(state->uart_port->membase + 0x34));
    PS_PRINT_INFO("IMSC :0x%x\n", readw(state->uart_port->membase + 0x38));
    PS_PRINT_INFO("RIS  :0x%x\n", readw(state->uart_port->membase + 0x3C));
    PS_PRINT_INFO("MIS  :0x%x\n", readw(state->uart_port->membase + 0x40));

    return;
}
Exemplo n.º 10
0
static void rin_nd_tx_timeout(struct net_device *dev)
{
	struct rin_st *sl = netdev_priv(dev);
#ifdef RIN_DEINSALA_DEBUG
    if(DEBUG) {
        printk(KERN_INFO "%s: rin_nd_tx_timeout: tty_chars_in_buffer(sl->tty): %d\n", sl->dev->name, tty_chars_in_buffer(sl->tty));
        printk(KERN_INFO "%s: rin_nd_tx_timeout: sl->xleft: %d\n", sl->dev->name, sl->xleft);
        printk(KERN_INFO "%s: rin_nd_tx_timeout: sl->rcount: %d\n", sl->dev->name, sl->rcount);
        printk(KERN_INFO "%s: rin_nd_tx_timeout: sl->mtu: %d\n", sl->dev->name, sl->mtu);
        printk(KERN_INFO "%s: rin_nd_tx_timeout: sl->buffsize: %d\n", sl->dev->name, sl->buffsize);
    }
#endif
	spin_lock(&sl->lock);

	if (netif_queue_stopped(dev)) {
		if (!netif_running(dev))
			goto out;

		/* May be we must check transmitter timeout here ?
		 *      14 Oct 1994 Dmitry Gorodchanin.
		 */
#ifdef RIN_CHECK_TRANSMIT
		if (time_before(jiffies, dev->trans_start + 20 * HZ))  {
			/* 20 sec timeout not reached */
			goto out;
		}
		if(DEBUG) printk(KERN_WARNING "%s: transmit timed out, %s?\n",
			dev->name,
			(tty_chars_in_buffer(sl->tty) || sl->xleft) ?
				"bad line quality" : "driver error");
		sl->xleft = 0;
		clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
		rin_unlock(sl);
#endif
	}
out:
	spin_unlock(&sl->lock);
}
Exemplo n.º 11
0
static void rin_receive_buf(struct tty_struct *tty, const unsigned char *cp,
							char *fp, int count)
{
	struct rin_st *sl = tty->disc_data;
	struct sk_buff *skb;

	if (!sl || sl->magic != RIN_MAGIC || !netif_running(sl->dev))
		return;


	skb = dev_alloc_skb(count);
	if (skb == NULL) {
		if(DEBUG) printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
        sl->rx_bytes += count;
		sl->rx_dropped++;
		return;
	}
	skb->dev = sl->dev;
	memcpy(skb_put(skb, count), cp, count);
	skb_reset_mac_header(skb);
	skb->protocol = htons(ETH_P_IP);

    spin_lock_bh(&sl->lock);
	sl->rx_bytes += count;
	netif_rx(skb);
	sl->rx_packets++;
    spin_unlock_bh(&sl->lock);

#ifdef RIN_DEINSALA_DEBUG
    if(DEBUG) {
        printk(KERN_INFO "%s: rin_receive_buf: netif_rx(skb) received packet of %d bytes from TTY\n", sl->dev->name, count);
        printk(KERN_INFO "%s: rin_receive_buf: tty_chars_in_buffer(sl->tty): %d\n", sl->dev->name, tty_chars_in_buffer(sl->tty));
        printk(KERN_INFO "%s: rin_receive_buf: sl->xleft: %d\n", sl->dev->name, sl->xleft);
        printk(KERN_INFO "%s: rin_receive_buf: sl->rcount: %d\n", sl->dev->name, sl->rcount);
        printk(KERN_INFO "%s: rin_receive_buf: sl->mtu: %d\n", sl->dev->name, sl->mtu);
        printk(KERN_INFO "%s: rin_receive_buf: sl->buffsize: %d\n", sl->dev->name, sl->buffsize);
    }
#endif
}
Exemplo n.º 12
0
/*
 * Called by the driver when there's room for more data.  If we have
 * more packets to send, we send them here.
 */
static void rin_write_wakeup(struct tty_struct *tty)
{
	int actual;
	struct rin_st *sl = tty->disc_data;

	/* First make sure we're connected. */
	if (!sl || sl->magic != RIN_MAGIC || !netif_running(sl->dev))
        if(DEBUG) printk(KERN_INFO "rin_write_wakeup: not connected!!!");
		return;

	if (sl->xleft <= 0)  {
		/* Now serial buffer is almost free & we can start
		 * transmission of another packet */
		sl->tx_packets++;
		clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
#ifdef RIN_DEINSALA_DEBUG
        if(DEBUG) {
            printk(KERN_INFO "%s: rin_write_wakeup: tty_chars_in_buffer(sl->tty): %d\n", sl->dev->name, tty_chars_in_buffer(sl->tty));
            printk(KERN_INFO "%s: rin_write_wakeup: sl->xleft: %d\n", sl->dev->name, sl->xleft);
            printk(KERN_INFO "%s: rin_write_wakeup: sl->rcount: %d\n", sl->dev->name, sl->rcount);
            printk(KERN_INFO "%s: rin_write_wakeup: sl->mtu: %d\n", sl->dev->name, sl->mtu);
            printk(KERN_INFO "%s: rin_write_wakeup: sl->buffsize: %d\n", sl->dev->name, sl->buffsize);
            printk(KERN_INFO "%s: rin_write_wakeup: unlocking net queue\n", sl->dev->name);
        }
#endif
		rin_unlock(sl);
		return;
	}

	actual = tty->ops->write(tty, sl->xhead, sl->xleft);
#ifdef RIN_DEINSALA_DEBUG
    if(DEBUG) printk(KERN_INFO "%s: rin_write_wakeup: sent remaining %d bytes of packet to TTY\n", sl->dev->name, sl->xleft);
#endif
	sl->xleft -= actual;
	sl->xhead += actual;
#ifdef RIN_DEINSALA_DEBUG
    if(DEBUG) {
        printk(KERN_INFO "%s: rin_write_wakeup: tty_chars_in_buffer(sl->tty): %d\n", sl->dev->name, tty_chars_in_buffer(sl->tty));
        printk(KERN_INFO "%s: rin_write_wakeup: sl->xleft: %d\n", sl->dev->name, sl->xleft);
        printk(KERN_INFO "%s: rin_write_wakeup: sl->rcount: %d\n", sl->dev->name, sl->rcount);
        printk(KERN_INFO "%s: rin_write_wakeup: sl->mtu: %d\n", sl->dev->name, sl->mtu);
        printk(KERN_INFO "%s: rin_write_wakeup: sl->buffsize: %d\n", sl->dev->name, sl->buffsize);
    }
#endif
}
Exemplo n.º 13
0
/* Encapsulate one IP datagram and stuff into a TTY queue. */
static void rin_encaps(struct rin_st *sl, unsigned char *icp, int len)
{
	unsigned char *p;
	int actual;
    //WBT#196218
    int count = len;

	if (len > sl->mtu) {		/* Sigh, shouldn't occur BUT ... */
		if(DEBUG) printk(KERN_WARNING "%s: truncating oversized transmit packet!\n", sl->dev->name);
		sl->tx_dropped++;
		rin_unlock(sl);
		return;
	}

	p = icp;


	memcpy(sl->xbuff,p,len);
	/* Order of next two lines is *very* important.
	 * When we are sending a little amount of data,
	 * the transfer may be completed inside the ops->write()
	 * routine, because it's running with interrupts enabled.
	 * In this case we *never* got WRITE_WAKEUP event,
	 * if we did not request it before write operation.
	 *       14 Oct 1994  Dmitry Gorodchanin.
	 */
	set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
	actual = sl->tty->ops->write(sl->tty, sl->xbuff, len);
#ifdef RIN_DEINSALA_DEBUG
    if(DEBUG) printk(KERN_INFO "%s: rin_encaps: sent %d bytes of packet of %d bytes to TTY\n", sl->dev->name, actual, len);
#endif

#ifdef RIN_CHECK_TRANSMIT
	sl->dev->trans_start = jiffies;
#endif
	sl->xleft = count - actual;
#ifdef RIN_DEINSALA_DEBUG
    if(sl->xleft>0) {
        if(DEBUG) printk(KERN_INFO "%s: rin_encaps: remaining %d bytes\n", sl->dev->name, sl->xleft);
    }
#endif
	sl->xhead = sl->xbuff + actual;
#ifdef RIN_DEINSALA_DEBUG
    if(DEBUG) {
        printk(KERN_INFO "%s: rin_encaps: tty_chars_in_buffer(sl->tty): %d\n", sl->dev->name, tty_chars_in_buffer(sl->tty));
        printk(KERN_INFO "%s: rin_encaps: sl->xleft: %d\n", sl->dev->name, sl->xleft);
        printk(KERN_INFO "%s: rin_encaps: sl->rcount: %d\n", sl->dev->name, sl->rcount);
        printk(KERN_INFO "%s: rin_encaps: sl->mtu: %d\n", sl->dev->name, sl->mtu);
        printk(KERN_INFO "%s: rin_encaps: sl->buffsize: %d\n", sl->dev->name, sl->buffsize);
    }
#endif
}
Exemplo n.º 14
0
static void rin_receive_buf(struct tty_struct *tty, const unsigned char *cp,
							char *fp, int count)
{
	struct rin_st *sl = tty->disc_data;
	unsigned short rawip_size;
	unsigned short rawip_headsize = 2;
	int remain_count;
	int index=0;
	static int recv_count=0;
	static unsigned int start_time;
	static unsigned int end_time;
	
	
	remain_count = count;
	
	if (!sl || sl->magic != RIN_MAGIC || !netif_running(sl->dev))
		return;

	while(remain_count > 0) {
//		printk(KERN_INFO "rindrv.c : loop(%d), r_c(%d), m_d(%d), index(%d)\n",loop_count++, remain_count, is_need_more_data, index);
		//printk(KERN_INFO "rindrv.c : recv_rawip_size[%d], remain_rawip_size[%d], copyed_header_buff_data[%d]\n", recv_rawip_size, remain_rawip_size, copyed_header_buff_data);

		
		if(is_need_more_data && copyed_header_buff_data == 0 ) 
		{
			//if(recv_rawip_size+remain_rawip_size> sizeof(rawip_buffer)){
			//	printk(KERN_INFO "rindrv.c : [ERROR] %d + %d > 2610", recv_rawip_size, remain_rawip_size);
			//}
			memcpy(&rawip_buffer[recv_rawip_size],cp,remain_rawip_size);
			rin_receive_send_rawip(tty,rawip_buffer,fp,(recv_rawip_size+remain_rawip_size));
			remain_count = remain_count - remain_rawip_size;
			index = index+remain_rawip_size;
			is_need_more_data = 0;
		}
		else
		{
			if( copyed_header_buff_data == rawip_headsize)
			{
				rawip_size = get16(header_buff);
				rawip_headsize = 0;
			}
			else if ( copyed_header_buff_data == 1)
			{
				memcpy(&header_buff[1],&cp[index],1); //index ==0 
				rawip_headsize = 1;
  				rawip_size = get16(header_buff);
			}
			else
			{
				rawip_size = get16((char *)&cp[index]);
			}

			memset(header_buff, 0x0, 2);
			copyed_header_buff_data = 0;
			#ifdef CONFIG_LU6500
			if(rawip_size > 2600) {
			#else
			if(rawip_size > 1501) {
			#endif
				//printk(KERN_INFO "%s: rin_receive_buf: rawip size error : %d\n", sl->dev->name, rawip_size);
				return;
			}

			if( (rawip_size + rawip_headsize) <= remain_count) // 해당 packet안에 ip데이터 모두 있는 경우 
			{
				rin_receive_send_rawip(tty,&cp[index+rawip_headsize],fp,rawip_size);
			}
			else if (remain_count <= 2	)
			{
				//printk(KERN_INFO "rindrv.c : [error_case] remain_count %d \n", remain_count);				   
				memcpy(header_buff,&cp[index],remain_count);
                 		copyed_header_buff_data = remain_count;
				remain_count = 0;
				   
				return;
			}
			else // 마지막 데이터가 필요하여, 다음 packet을 수신해야 하는 경우 
			{
				rawip_headsize = 2;
 				is_need_more_data = 1;
				recv_rawip_size = remain_count - rawip_headsize;
				
				//if(recv_rawip_size > sizeof(rawip_buffer)){
				//  printk(KERN_INFO "rindrv.c :remain_count=%d, rawip_headsize=%d", remain_count, rawip_headsize);
				//  printk(KERN_INFO "rindrv.c : [ERROR] %d > 2610", recv_rawip_size);
				//}				
				memcpy(rawip_buffer,&cp[index+rawip_headsize],recv_rawip_size);
				remain_rawip_size = rawip_size - recv_rawip_size;

				return;
			}

			remain_count = remain_count - (rawip_size + rawip_headsize);	
			index = index + rawip_size + rawip_headsize;

			//printk(KERN_INFO "rindrv.c : loop bottom: remain_count[%d], index[%d],rawip_headsize[%d => 2]\n", remain_count, index,rawip_headsize);

			rawip_headsize = 2;

		}
	}	

	
	
}

static void rin_receive_send_rawip(struct tty_struct *tty, const unsigned char *cp,
							char *fp, int count)
{
struct rin_st *sl = tty->disc_data;
struct sk_buff *skb;

if (!sl || sl->magic != RIN_MAGIC || !netif_running(sl->dev))
	return;


skb = dev_alloc_skb(count);
if (skb == NULL) {
	if(DEBUG) printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
	sl->rx_bytes += count;
	sl->rx_dropped++;
	return;
}
skb->dev = sl->dev;
memcpy(skb_put(skb, count), cp, count);
skb_reset_mac_header(skb);
skb->protocol = htons(ETH_P_IP);

spin_lock_bh(&sl->lock);
sl->rx_bytes += count;
netif_rx(skb);
sl->rx_packets++;
spin_unlock_bh(&sl->lock);

#ifdef RIN_DEINSALA_DEBUG
if(DEBUG) {
	printk(KERN_INFO "%s: rin_receive_buf: netif_rx(skb) received packet of %d bytes from TTY\n", sl->dev->name, count);
	printk(KERN_INFO "%s: rin_receive_buf: tty_chars_in_buffer(sl->tty): %d\n", sl->dev->name, tty_chars_in_buffer(sl->tty));
	printk(KERN_INFO "%s: rin_receive_buf: sl->xleft: %d\n", sl->dev->name, sl->xleft);
	printk(KERN_INFO "%s: rin_receive_buf: sl->rcount: %d\n", sl->dev->name, sl->rcount);
	printk(KERN_INFO "%s: rin_receive_buf: sl->mtu: %d\n", sl->dev->name, sl->mtu);
	printk(KERN_INFO "%s: rin_receive_buf: sl->buffsize: %d\n", sl->dev->name, sl->buffsize);
}
#endif
}
#else
static void rin_receive_buf(struct tty_struct *tty, const unsigned char *cp,
							char *fp, int count)
{
	struct rin_st *sl = tty->disc_data;
	struct sk_buff *skb;

	if (!sl || sl->magic != RIN_MAGIC || !netif_running(sl->dev))
		return;


	skb = dev_alloc_skb(count);
	if (skb == NULL) {
		if(DEBUG) printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
        sl->rx_bytes += count;
		sl->rx_dropped++;
		return;
	}
	skb->dev = sl->dev;
	memcpy(skb_put(skb, count), cp, count);
	skb_reset_mac_header(skb);
	skb->protocol = htons(ETH_P_IP);

    spin_lock_bh(&sl->lock);
	sl->rx_bytes += count;
	netif_rx(skb);
	sl->rx_packets++;
    spin_unlock_bh(&sl->lock);

#ifdef RIN_DEINSALA_DEBUG
    if(DEBUG) {
        printk(KERN_INFO "%s: rin_receive_buf: netif_rx(skb) received packet of %d bytes from TTY\n", sl->dev->name, count);
        printk(KERN_INFO "%s: rin_receive_buf: tty_chars_in_buffer(sl->tty): %d\n", sl->dev->name, tty_chars_in_buffer(sl->tty));
        printk(KERN_INFO "%s: rin_receive_buf: sl->xleft: %d\n", sl->dev->name, sl->xleft);
        printk(KERN_INFO "%s: rin_receive_buf: sl->rcount: %d\n", sl->dev->name, sl->rcount);
        printk(KERN_INFO "%s: rin_receive_buf: sl->mtu: %d\n", sl->dev->name, sl->mtu);
        printk(KERN_INFO "%s: rin_receive_buf: sl->buffsize: %d\n", sl->dev->name, sl->buffsize);
    }
#endif
}
#endif
/************************************
 *  rin_open helper routines.
 ************************************/

/* Collect hanged up channels */
static void rin_sync(void)
{
	int i;
	struct net_device *dev;
	struct rin_st	  *sl;

	for (i = 0; i < rin_maxdev; i++) {
		dev = rin_devs[i];
		if (dev == NULL)
			break;

		sl = netdev_priv(dev);
		if (sl->tty || sl->leased)
			continue;
		if (dev->flags & IFF_UP)
			dev_close(dev);
	}
}