diff options
Diffstat (limited to 'drivers/char/tty_io.c')
| -rw-r--r-- | drivers/char/tty_io.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index a3afa0c387cd..ea18a129b0b5 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
| @@ -1184,6 +1184,7 @@ int tty_init_termios(struct tty_struct *tty) | |||
| 1184 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | 1184 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); |
| 1185 | return 0; | 1185 | return 0; |
| 1186 | } | 1186 | } |
| 1187 | EXPORT_SYMBOL_GPL(tty_init_termios); | ||
| 1187 | 1188 | ||
| 1188 | /** | 1189 | /** |
| 1189 | * tty_driver_install_tty() - install a tty entry in the driver | 1190 | * tty_driver_install_tty() - install a tty entry in the driver |
| @@ -1386,10 +1387,14 @@ EXPORT_SYMBOL(tty_shutdown); | |||
| 1386 | * tty_mutex - sometimes only | 1387 | * tty_mutex - sometimes only |
| 1387 | * takes the file list lock internally when working on the list | 1388 | * takes the file list lock internally when working on the list |
| 1388 | * of ttys that the driver keeps. | 1389 | * of ttys that the driver keeps. |
| 1390 | * | ||
| 1391 | * This method gets called from a work queue so that the driver private | ||
| 1392 | * shutdown ops can sleep (needed for USB at least) | ||
| 1389 | */ | 1393 | */ |
| 1390 | static void release_one_tty(struct kref *kref) | 1394 | static void release_one_tty(struct work_struct *work) |
| 1391 | { | 1395 | { |
| 1392 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | 1396 | struct tty_struct *tty = |
| 1397 | container_of(work, struct tty_struct, hangup_work); | ||
| 1393 | struct tty_driver *driver = tty->driver; | 1398 | struct tty_driver *driver = tty->driver; |
| 1394 | 1399 | ||
| 1395 | if (tty->ops->shutdown) | 1400 | if (tty->ops->shutdown) |
| @@ -1407,6 +1412,15 @@ static void release_one_tty(struct kref *kref) | |||
| 1407 | free_tty_struct(tty); | 1412 | free_tty_struct(tty); |
| 1408 | } | 1413 | } |
| 1409 | 1414 | ||
| 1415 | static void queue_release_one_tty(struct kref *kref) | ||
| 1416 | { | ||
| 1417 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | ||
| 1418 | /* The hangup queue is now free so we can reuse it rather than | ||
| 1419 | waste a chunk of memory for each port */ | ||
| 1420 | INIT_WORK(&tty->hangup_work, release_one_tty); | ||
| 1421 | schedule_work(&tty->hangup_work); | ||
| 1422 | } | ||
| 1423 | |||
| 1410 | /** | 1424 | /** |
| 1411 | * tty_kref_put - release a tty kref | 1425 | * tty_kref_put - release a tty kref |
| 1412 | * @tty: tty device | 1426 | * @tty: tty device |
| @@ -1418,7 +1432,7 @@ static void release_one_tty(struct kref *kref) | |||
| 1418 | void tty_kref_put(struct tty_struct *tty) | 1432 | void tty_kref_put(struct tty_struct *tty) |
| 1419 | { | 1433 | { |
| 1420 | if (tty) | 1434 | if (tty) |
| 1421 | kref_put(&tty->kref, release_one_tty); | 1435 | kref_put(&tty->kref, queue_release_one_tty); |
| 1422 | } | 1436 | } |
| 1423 | EXPORT_SYMBOL(tty_kref_put); | 1437 | EXPORT_SYMBOL(tty_kref_put); |
| 1424 | 1438 | ||
| @@ -2085,7 +2099,7 @@ static int tioccons(struct file *file) | |||
| 2085 | * the generic functionality existed. This piece of history is preserved | 2099 | * the generic functionality existed. This piece of history is preserved |
| 2086 | * in the expected tty API of posix OS's. | 2100 | * in the expected tty API of posix OS's. |
| 2087 | * | 2101 | * |
| 2088 | * Locking: none, the open fle handle ensures it won't go away. | 2102 | * Locking: none, the open file handle ensures it won't go away. |
| 2089 | */ | 2103 | */ |
| 2090 | 2104 | ||
| 2091 | static int fionbio(struct file *file, int __user *p) | 2105 | static int fionbio(struct file *file, int __user *p) |
| @@ -3056,11 +3070,22 @@ void __init console_init(void) | |||
| 3056 | } | 3070 | } |
| 3057 | } | 3071 | } |
| 3058 | 3072 | ||
| 3073 | static char *tty_devnode(struct device *dev, mode_t *mode) | ||
| 3074 | { | ||
| 3075 | if (!mode) | ||
| 3076 | return NULL; | ||
| 3077 | if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) || | ||
| 3078 | dev->devt == MKDEV(TTYAUX_MAJOR, 2)) | ||
| 3079 | *mode = 0666; | ||
| 3080 | return NULL; | ||
| 3081 | } | ||
| 3082 | |||
| 3059 | static int __init tty_class_init(void) | 3083 | static int __init tty_class_init(void) |
| 3060 | { | 3084 | { |
| 3061 | tty_class = class_create(THIS_MODULE, "tty"); | 3085 | tty_class = class_create(THIS_MODULE, "tty"); |
| 3062 | if (IS_ERR(tty_class)) | 3086 | if (IS_ERR(tty_class)) |
| 3063 | return PTR_ERR(tty_class); | 3087 | return PTR_ERR(tty_class); |
| 3088 | tty_class->devnode = tty_devnode; | ||
| 3064 | return 0; | 3089 | return 0; |
| 3065 | } | 3090 | } |
| 3066 | 3091 | ||
