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); }
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; }
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; }
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; }