コード例 #1
0
static int tiocgdev(unsigned fd, unsigned cmd,  unsigned int __user *ptr) 
{ 

	struct file *file = fget(fd);
	struct tty_struct *real_tty;

	if (!file)
		return -EBADF;
	if (file->f_op->ioctl != tty_ioctl)
		return -EINVAL; 
	real_tty = (struct tty_struct *)file->private_data;
	if (!real_tty) 	
		return -EINVAL; 
	return put_user(new_encode_dev(tty_devnum(real_tty)), ptr); 
} 
コード例 #2
0
static int rin_open(struct tty_struct *tty)
{
	struct rin_st *sl;
	int err;
	static int realloc_count = 0;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (tty->ops->write == NULL)
		return -EOPNOTSUPP;

	/* RTnetlink lock is misused here to serialize concurrent
	   opens of rin channels. There are better ways, but it is
	   the simplest one.
	 */
	rtnl_lock();

	/* Collect hanged up channels. */
	rin_sync();

	sl = tty->disc_data;

	err = -EEXIST;
	/* First make sure we're not already connected. */
	if (sl && sl->magic == RIN_MAGIC)
		goto err_exit;

	/* OK.  Find a free RIN channel to use. */
	err = -ENFILE;
	if(rindrv_count==0)
	{
		sl = rin_alloc(tty_devnum(tty));
		if(DEBUG) printk("%s - line : %d, sl->dev = %x\n", __FUNCTION__, __LINE__, (unsigned int)sl->dev);
	}
	else if(rindrv_count>0)
	{
		if(realloc_count<rindrv_count)
		{
			sl = netdev_priv(rin_devs[realloc_count]);
			if(DEBUG) printk("%s - line : %d, realloc sl->dev = %x\n", __FUNCTION__, __LINE__, (unsigned int)sl->dev);
			realloc_count ++;
			err = 0;

		}
	}
	else
	{
		if(DEBUG) printk("%s - line : %d, error rindrv_count = %d\n", __FUNCTION__, __LINE__, rindrv_count);
		sl = NULL;
	}
	if (sl == NULL)
		goto err_exit;

	sl->tty = tty;
	tty->disc_data = sl;
	sl->line = tty_devnum(tty);
	sl->pid = current->pid;

	if(rindrv_count==0 && realloc_count == 0)
	{
		if (!test_bit(SLF_INUSE, &sl->flags)) {
			/* Perform the low-level RIN initialization. */
			err = rin_alloc_bufs(sl, RIN_MTU);
			if (err)
				goto err_free_chan;

			set_bit(SLF_INUSE, &sl->flags);

		err = register_netdevice(sl->dev);
		if (err)
			goto err_free_bufs;
		}
	}
	else if( rindrv_count == realloc_count)
	{
		rindrv_count = 0;
		realloc_count = 0;
		if(DEBUG) printk("%s - line : %d, realloc done!!\n", __FUNCTION__, __LINE__);
	}

	/* Done.  We have linked the TTY line to a channel. */
	rtnl_unlock();
	tty->receive_room = 65536;	/* We don't flow control */
	//ril_open must return 0, if succeed
	//return sl->dev->base_addr;
	return err;

err_free_bufs:
	rin_free_bufs(sl);

err_free_chan:
	sl->tty = NULL;
	tty->disc_data = NULL;
	clear_bit(SLF_INUSE, &sl->flags);

err_exit:
	rtnl_unlock();

	/* Count references from TTY module */
	return err;
}
コード例 #3
0
static int slcan_open(struct tty_struct *tty)
{
	struct slcan *sl;
	int err;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
	if (tty->ops->write == NULL)
		return -EOPNOTSUPP;
#endif

	/* RTnetlink lock is misused here to serialize concurrent
	   opens of slcan channels. There are better ways, but it is
	   the simplest one.
	 */
	rtnl_lock();

	/* Collect hanged up channels. */
	slc_sync();

	sl = (struct slcan *) tty->disc_data;

	err = -EEXIST;
	/* First make sure we're not already connected. */
	if (sl && sl->magic == SLCAN_MAGIC)
		goto err_exit;

	/* OK.  Find a free SLCAN channel to use. */
	err = -ENFILE;

	/* Look to see if the user has requested a specific channel
	 * to be used (encoded as '0' plus the interface number requested in
	 * the otherwise unused swtch termios variable )
	 * stty swtch 'channel' device
	 *  where 'channel' is '0' to maxdevs (0)
	 *  where device is the name of the serial device (/dev/ttyUSB0)
	 */
	if ((SWTC_CHAR(tty)>='0') && (SWTC_CHAR(tty)<'0'+maxdev)){
		sl = slc_alloc(tty_devnum(tty),SWTC_CHAR(tty));
	} else {
		/* OK.  Find a free SLCAN channel to use. */
		sl = slc_alloc(tty_devnum(tty),0);
	}

	if (sl == NULL)
		goto err_exit;

	sl->tty = tty;
	tty->disc_data = sl;
	sl->line = tty_devnum(tty);
	sl->pid = current->pid;

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
	/* FIXME: already done before we were called - seems this can go */
	if (tty->driver->flush_buffer)
		tty->driver->flush_buffer(tty);
#endif

	if (!test_bit(SLF_INUSE, &sl->flags)) {
		/* Perform the low-level SLCAN initialization. */
		sl->rcount   = 0;
		sl->xleft    = 0;

		set_bit(SLF_INUSE, &sl->flags);

		err = register_netdevice(sl->dev);
		if (err)
			goto err_free_chan;
	}

	/* Done.  We have linked the TTY line to a channel. */
	rtnl_unlock();

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
	tty->receive_room = 65536;	/* We don't flow control */
#endif

	return sl->dev->base_addr;

err_free_chan:
	sl->tty = NULL;
	tty->disc_data = NULL;
	clear_bit(SLF_INUSE, &sl->flags);

err_exit:
	rtnl_unlock();

	/* Count references from TTY module */
	return err;
}
コード例 #4
0
static int slcan_open(struct tty_struct *tty)
{
	struct slcan *sl;
	int err;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (tty->ops->write == NULL)
		return -EOPNOTSUPP;

	/* RTnetlink lock is misused here to serialize concurrent
	   opens of slcan channels. There are better ways, but it is
	   the simplest one.
	 */
	rtnl_lock();

	/* Collect hanged up channels. */
	slc_sync();

	sl = tty->disc_data;

	err = -EEXIST;
	/* First make sure we're not already connected. */
	if (sl && sl->magic == SLCAN_MAGIC)
		goto err_exit;

	/* OK.  Find a free SLCAN channel to use. */
	err = -ENFILE;
	sl = slc_alloc(tty_devnum(tty));
	if (sl == NULL)
		goto err_exit;

	sl->tty = tty;
	tty->disc_data = sl;
	sl->line = tty_devnum(tty);
	sl->pid = current->pid;

	if (!test_bit(SLF_INUSE, &sl->flags)) {
		/* Perform the low-level SLCAN initialization. */
		sl->rcount   = 0;
		sl->xleft    = 0;

		set_bit(SLF_INUSE, &sl->flags);

		err = register_netdevice(sl->dev);
		if (err)
			goto err_free_chan;
	}

	/* Done.  We have linked the TTY line to a channel. */
	rtnl_unlock();
	tty->receive_room = 65536;	/* We don't flow control */

	/* TTY layer expects 0 on success */
	return 0;

err_free_chan:
	sl->tty = NULL;
	tty->disc_data = NULL;
	clear_bit(SLF_INUSE, &sl->flags);

err_exit:
	rtnl_unlock();

	/* Count references from TTY module */
	return err;
}