/* write_buf/write_cnt is protected by the atomic_write_lock mutex */
if (tty->write_cnt < chunk) {
- unsigned char *buf;
+ unsigned char *buf_chunk;
if (chunk < 1024)
chunk = 1024;
- buf = kmalloc(chunk, GFP_KERNEL);
- if (!buf) {
+ buf_chunk = kmalloc(chunk, GFP_KERNEL);
+ if (!buf_chunk) {
ret = -ENOMEM;
goto out;
}
kfree(tty->write_buf);
tty->write_cnt = chunk;
- tty->write_buf = buf;
+ tty->write_buf = buf_chunk;
}
/* Do the write .. */
* be held until the 'fast-open' is also done. Will change once we
* have refcounting in the driver and per driver locking
*/
-struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, int idx)
+struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
+ struct inode *inode, int idx)
{
struct tty_struct *tty;
if (driver->ops->lookup)
- return driver->ops->lookup(driver, idx);
+ return driver->ops->lookup(driver, inode, idx);
tty = driver->ttys[idx];
return tty;
int tty_init_termios(struct tty_struct *tty)
{
- struct ktermios *tp, *ltp;
+ struct ktermios *tp;
int idx = tty->index;
tp = tty->driver->termios[idx];
- ltp = tty->driver->termios_locked[idx];
if (tp == NULL) {
- WARN_ON(ltp != NULL);
- tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
- ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
- if (tp == NULL || ltp == NULL) {
- kfree(tp);
- kfree(ltp);
+ tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
+ if (tp == NULL)
return -ENOMEM;
- }
memcpy(tp, &tty->driver->init_termios,
sizeof(struct ktermios));
tty->driver->termios[idx] = tp;
- tty->driver->termios_locked[idx] = ltp;
}
tty->termios = tp;
- tty->termios_locked = ltp;
+ tty->termios_locked = tp + 1;
/* Compatibility until drivers always set this */
tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
struct tty_struct *tty;
int retval;
- /* check whether we're reopening an existing tty */
- tty = tty_driver_lookup_tty(driver, idx);
-
- if (IS_ERR(tty))
- return tty;
-
- if (tty) {
- retval = tty_reopen(tty);
- if (retval)
- return ERR_PTR(retval);
- return tty;
- }
-
/* Check if pty master is being opened multiple times */
if (driver->subtype == PTY_TYPE_MASTER &&
(driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok)
tp = tty->termios;
tty->driver->termios[idx] = NULL;
kfree(tp);
-
- tp = tty->termios_locked;
- tty->driver->termios_locked[idx] = NULL;
- kfree(tp);
}
}
EXPORT_SYMBOL(tty_free_termios);
int devpts;
int idx;
char buf[64];
+ struct inode *inode;
+ inode = filp->f_path.dentry->d_inode;
tty = (struct tty_struct *)filp->private_data;
- if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode,
- "tty_release_dev"))
+ if (tty_paranoia_check(tty, inode, "tty_release_dev"))
return;
check_tty_count(tty, "tty_release_dev");
idx, tty->name);
return;
}
- if (tty->termios_locked != tty->driver->termios_locked[idx]) {
- printk(KERN_DEBUG "tty_release_dev: driver.termios_locked[%d] not "
- "termios_locked for (%s)\n",
- idx, tty->name);
- return;
- }
}
#endif
idx, tty->name);
return;
}
- if (o_tty->termios_locked !=
- tty->driver->other->termios_locked[idx]) {
- printk(KERN_DEBUG "tty_release_dev: other->termios_locked["
- "%d] not o_termios_locked for (%s)\n",
- idx, tty->name);
- return;
- }
if (o_tty->link != tty) {
printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
return;
/* Make this pty number available for reallocation */
if (devpts)
- devpts_kill_index(idx);
+ devpts_kill_index(inode, idx);
}
/**
static int __tty_open(struct inode *inode, struct file *filp)
{
- struct tty_struct *tty;
+ struct tty_struct *tty = NULL;
int noctty, retval;
struct tty_driver *driver;
int index;
return -ENODEV;
}
got_driver:
- tty = tty_init_dev(driver, index, 0);
+ if (!tty) {
+ /* check whether we're reopening an existing tty */
+ tty = tty_driver_lookup_tty(driver, inode, index);
+
+ if (IS_ERR(tty))
+ return PTR_ERR(tty);
+ }
+
+ if (tty) {
+ retval = tty_reopen(tty);
+ if (retval)
+ tty = ERR_PTR(retval);
+ } else
+ tty = tty_init_dev(driver, index, 0);
+
mutex_unlock(&tty_mutex);
tty_driver_kref_put(driver);
if (IS_ERR(tty))
else
tty_line_name(driver, index, name);
- return device_create_drvdata(tty_class, device, dev, NULL, name);
+ return device_create(tty_class, device, dev, NULL, name);
}
EXPORT_SYMBOL(tty_register_device);
driver->termios[i] = NULL;
kfree(tp);
}
- tp = driver->termios_locked[i];
- if (tp) {
- driver->termios_locked[i] = NULL;
- kfree(tp);
- }
if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
tty_unregister_device(driver, i);
}
p = driver->ttys;
proc_tty_unregister_driver(driver);
driver->ttys = NULL;
- driver->termios = driver->termios_locked = NULL;
+ driver->termios = NULL;
kfree(p);
cdev_del(&driver->cdev);
}
void **p = NULL;
if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
- p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL);
+ p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
if (!p)
return -ENOMEM;
}
if (p) {
driver->ttys = (struct tty_struct **)p;
driver->termios = (struct ktermios **)(p + driver->num);
- driver->termios_locked = (struct ktermios **)
- (p + driver->num * 2);
} else {
driver->ttys = NULL;
driver->termios = NULL;
- driver->termios_locked = NULL;
}
cdev_init(&driver->cdev, &tty_fops);
if (error) {
unregister_chrdev_region(dev, driver->num);
driver->ttys = NULL;
- driver->termios = driver->termios_locked = NULL;
+ driver->termios = NULL;
kfree(p);
return error;
}
void proc_clear_tty(struct task_struct *p)
{
+ unsigned long flags;
struct tty_struct *tty;
- spin_lock_irq(&p->sighand->siglock);
+ spin_lock_irqsave(&p->sighand->siglock, flags);
tty = p->signal->tty;
p->signal->tty = NULL;
- spin_unlock_irq(&p->sighand->siglock);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
tty_kref_put(tty);
}