diff options
author | Jiri Slaby <jslaby@suse.cz> | 2012-06-04 07:35:29 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-13 20:30:14 -0400 |
commit | 5d249bc6a61e7a434c69e0d0becc77a803c8c5e8 (patch) | |
tree | 2491990795432373827e7a7f7280e31e3f10ef9c /drivers/tty/pty.c | |
parent | 7171604ae7b3bbc738b6a4b7cd0ee73eb0d551d9 (diff) |
PTY: merge pty_install implementations
There are currently two instances of code which handles PTY install.
One for the legacy BSD PTY's, one for unix98's PTY's. Both of them are
very similar and differ only in termios allocation and handling.
Since we will need to allocate a tty_port at that place, this would
require editing two places with the same pattern. Instead, let us move
the implementation to one common place and call it from both places.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/pty.c')
-rw-r--r-- | drivers/tty/pty.c | 110 |
1 files changed, 45 insertions, 65 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 4bcaf896fac4..881888f0a445 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -282,39 +282,53 @@ done: | |||
282 | return 0; | 282 | return 0; |
283 | } | 283 | } |
284 | 284 | ||
285 | /* Traditional BSD devices */ | 285 | static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, |
286 | #ifdef CONFIG_LEGACY_PTYS | 286 | bool legacy) |
287 | |||
288 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
289 | { | 287 | { |
290 | struct tty_struct *o_tty; | 288 | struct tty_struct *o_tty; |
291 | int idx = tty->index; | 289 | int idx = tty->index; |
292 | int retval; | 290 | int retval = -ENOMEM; |
293 | 291 | ||
294 | o_tty = alloc_tty_struct(); | 292 | o_tty = alloc_tty_struct(); |
295 | if (!o_tty) | 293 | if (!o_tty) |
296 | return -ENOMEM; | 294 | goto err; |
297 | if (!try_module_get(driver->other->owner)) { | 295 | if (!try_module_get(driver->other->owner)) { |
298 | /* This cannot in fact currently happen */ | 296 | /* This cannot in fact currently happen */ |
299 | retval = -ENOMEM; | ||
300 | goto err_free_tty; | 297 | goto err_free_tty; |
301 | } | 298 | } |
302 | initialize_tty_struct(o_tty, driver->other, idx); | 299 | initialize_tty_struct(o_tty, driver->other, idx); |
303 | 300 | ||
304 | /* We always use new tty termios data so we can do this | 301 | if (legacy) { |
305 | the easy way .. */ | 302 | /* We always use new tty termios data so we can do this |
306 | retval = tty_init_termios(tty); | 303 | the easy way .. */ |
307 | if (retval) | 304 | retval = tty_init_termios(tty); |
308 | goto err_deinit_tty; | 305 | if (retval) |
309 | 306 | goto err_deinit_tty; | |
310 | retval = tty_init_termios(o_tty); | 307 | |
311 | if (retval) | 308 | retval = tty_init_termios(o_tty); |
312 | goto err_free_termios; | 309 | if (retval) |
310 | goto err_free_termios; | ||
311 | |||
312 | driver->other->ttys[idx] = o_tty; | ||
313 | driver->ttys[idx] = tty; | ||
314 | } else { | ||
315 | tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
316 | if (tty->termios == NULL) | ||
317 | goto err_deinit_tty; | ||
318 | *tty->termios = driver->init_termios; | ||
319 | tty->termios_locked = tty->termios + 1; | ||
320 | |||
321 | o_tty->termios = kzalloc(sizeof(struct ktermios[2]), | ||
322 | GFP_KERNEL); | ||
323 | if (o_tty->termios == NULL) | ||
324 | goto err_free_termios; | ||
325 | *o_tty->termios = driver->other->init_termios; | ||
326 | o_tty->termios_locked = o_tty->termios + 1; | ||
327 | } | ||
313 | 328 | ||
314 | /* | 329 | /* |
315 | * Everything allocated ... set up the o_tty structure. | 330 | * Everything allocated ... set up the o_tty structure. |
316 | */ | 331 | */ |
317 | driver->other->ttys[idx] = o_tty; | ||
318 | tty_driver_kref_get(driver->other); | 332 | tty_driver_kref_get(driver->other); |
319 | if (driver->subtype == PTY_TYPE_MASTER) | 333 | if (driver->subtype == PTY_TYPE_MASTER) |
320 | o_tty->count++; | 334 | o_tty->count++; |
@@ -324,18 +338,29 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
324 | 338 | ||
325 | tty_driver_kref_get(driver); | 339 | tty_driver_kref_get(driver); |
326 | tty->count++; | 340 | tty->count++; |
327 | driver->ttys[idx] = tty; | ||
328 | return 0; | 341 | return 0; |
329 | err_free_termios: | 342 | err_free_termios: |
330 | tty_free_termios(tty); | 343 | if (legacy) |
344 | tty_free_termios(tty); | ||
345 | else | ||
346 | kfree(tty->termios); | ||
331 | err_deinit_tty: | 347 | err_deinit_tty: |
332 | deinitialize_tty_struct(o_tty); | 348 | deinitialize_tty_struct(o_tty); |
333 | module_put(o_tty->driver->owner); | 349 | module_put(o_tty->driver->owner); |
334 | err_free_tty: | 350 | err_free_tty: |
335 | free_tty_struct(o_tty); | 351 | free_tty_struct(o_tty); |
352 | err: | ||
336 | return retval; | 353 | return retval; |
337 | } | 354 | } |
338 | 355 | ||
356 | /* Traditional BSD devices */ | ||
357 | #ifdef CONFIG_LEGACY_PTYS | ||
358 | |||
359 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
360 | { | ||
361 | return pty_common_install(driver, tty, true); | ||
362 | } | ||
363 | |||
339 | static int pty_bsd_ioctl(struct tty_struct *tty, | 364 | static int pty_bsd_ioctl(struct tty_struct *tty, |
340 | unsigned int cmd, unsigned long arg) | 365 | unsigned int cmd, unsigned long arg) |
341 | { | 366 | { |
@@ -509,52 +534,7 @@ static void pty_unix98_shutdown(struct tty_struct *tty) | |||
509 | 534 | ||
510 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | 535 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) |
511 | { | 536 | { |
512 | struct tty_struct *o_tty; | 537 | return pty_common_install(driver, tty, false); |
513 | int idx = tty->index; | ||
514 | |||
515 | o_tty = alloc_tty_struct(); | ||
516 | if (!o_tty) | ||
517 | return -ENOMEM; | ||
518 | if (!try_module_get(driver->other->owner)) { | ||
519 | /* This cannot in fact currently happen */ | ||
520 | goto err_free_tty; | ||
521 | } | ||
522 | initialize_tty_struct(o_tty, driver->other, idx); | ||
523 | |||
524 | tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
525 | if (tty->termios == NULL) | ||
526 | goto err_free_mem; | ||
527 | *tty->termios = driver->init_termios; | ||
528 | tty->termios_locked = tty->termios + 1; | ||
529 | |||
530 | o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
531 | if (o_tty->termios == NULL) | ||
532 | goto err_free_mem; | ||
533 | *o_tty->termios = driver->other->init_termios; | ||
534 | o_tty->termios_locked = o_tty->termios + 1; | ||
535 | |||
536 | tty_driver_kref_get(driver->other); | ||
537 | if (driver->subtype == PTY_TYPE_MASTER) | ||
538 | o_tty->count++; | ||
539 | /* Establish the links in both directions */ | ||
540 | tty->link = o_tty; | ||
541 | o_tty->link = tty; | ||
542 | /* | ||
543 | * All structures have been allocated, so now we install them. | ||
544 | * Failures after this point use release_tty to clean up, so | ||
545 | * there's no need to null out the local pointers. | ||
546 | */ | ||
547 | tty_driver_kref_get(driver); | ||
548 | tty->count++; | ||
549 | return 0; | ||
550 | err_free_mem: | ||
551 | deinitialize_tty_struct(o_tty); | ||
552 | kfree(o_tty->termios); | ||
553 | kfree(tty->termios); | ||
554 | module_put(o_tty->driver->owner); | ||
555 | err_free_tty: | ||
556 | free_tty_struct(o_tty); | ||
557 | return -ENOMEM; | ||
558 | } | 538 | } |
559 | 539 | ||
560 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | 540 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) |