diff options
author | Alan Cox <alan@redhat.com> | 2008-10-13 05:42:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 12:51:43 -0400 |
commit | bf970ee46e0fb363c8df4393229121d54330a98e (patch) | |
tree | 3beb09c369b3459e70689b5f9a35caacf063f116 /drivers | |
parent | 73ec06fc5f5c8e1097a7a4a4ab2d7c6c3a007e81 (diff) |
tty: extract the pty init time special cases
The majority of the remaining init_dev code is pty special cases. We
refactor this code into the driver->install method.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/pty.c | 126 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 198 |
2 files changed, 182 insertions, 142 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index c98450023030..c5a192dd00db 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -227,7 +227,58 @@ static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios | |||
227 | tty->termios->c_cflag |= (CS8 | CREAD); | 227 | tty->termios->c_cflag |= (CS8 | CREAD); |
228 | } | 228 | } |
229 | 229 | ||
230 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
231 | { | ||
232 | struct tty_struct *o_tty; | ||
233 | int idx = tty->index; | ||
234 | int retval; | ||
235 | |||
236 | o_tty = alloc_tty_struct(); | ||
237 | if (!o_tty) | ||
238 | return -ENOMEM; | ||
239 | if (!try_module_get(driver->other->owner)) { | ||
240 | /* This cannot in fact currently happen */ | ||
241 | free_tty_struct(o_tty); | ||
242 | return -ENOMEM; | ||
243 | } | ||
244 | initialize_tty_struct(o_tty, driver->other, idx); | ||
245 | |||
246 | /* We always use new tty termios data so we can do this | ||
247 | the easy way .. */ | ||
248 | retval = tty_init_termios(tty); | ||
249 | if (retval) | ||
250 | goto free_mem_out; | ||
251 | |||
252 | retval = tty_init_termios(o_tty); | ||
253 | if (retval) { | ||
254 | tty_free_termios(tty); | ||
255 | goto free_mem_out; | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * Everything allocated ... set up the o_tty structure. | ||
260 | */ | ||
261 | driver->other->ttys[idx] = o_tty; | ||
262 | tty_driver_kref_get(driver->other); | ||
263 | if (driver->subtype == PTY_TYPE_MASTER) | ||
264 | o_tty->count++; | ||
265 | /* Establish the links in both directions */ | ||
266 | tty->link = o_tty; | ||
267 | o_tty->link = tty; | ||
268 | |||
269 | tty_driver_kref_get(driver); | ||
270 | tty->count++; | ||
271 | driver->ttys[idx] = tty; | ||
272 | return 0; | ||
273 | free_mem_out: | ||
274 | module_put(o_tty->driver->owner); | ||
275 | free_tty_struct(o_tty); | ||
276 | return -ENOMEM; | ||
277 | } | ||
278 | |||
279 | |||
230 | static const struct tty_operations pty_ops = { | 280 | static const struct tty_operations pty_ops = { |
281 | .install = pty_install, | ||
231 | .open = pty_open, | 282 | .open = pty_open, |
232 | .close = pty_close, | 283 | .close = pty_close, |
233 | .write = pty_write, | 284 | .write = pty_write, |
@@ -332,6 +383,7 @@ static inline void legacy_pty_init(void) { } | |||
332 | int pty_limit = NR_UNIX98_PTY_DEFAULT; | 383 | int pty_limit = NR_UNIX98_PTY_DEFAULT; |
333 | static int pty_limit_min = 0; | 384 | static int pty_limit_min = 0; |
334 | static int pty_limit_max = NR_UNIX98_PTY_MAX; | 385 | static int pty_limit_max = NR_UNIX98_PTY_MAX; |
386 | static int pty_count = 0; | ||
335 | 387 | ||
336 | static struct cdev ptmx_cdev; | 388 | static struct cdev ptmx_cdev; |
337 | 389 | ||
@@ -351,6 +403,7 @@ static struct ctl_table pty_table[] = { | |||
351 | .procname = "nr", | 403 | .procname = "nr", |
352 | .maxlen = sizeof(int), | 404 | .maxlen = sizeof(int), |
353 | .mode = 0444, | 405 | .mode = 0444, |
406 | .data = &pty_count, | ||
354 | .proc_handler = &proc_dointvec, | 407 | .proc_handler = &proc_dointvec, |
355 | }, { | 408 | }, { |
356 | .ctl_name = 0 | 409 | .ctl_name = 0 |
@@ -426,7 +479,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, int idx) | |||
426 | return tty; | 479 | return tty; |
427 | } | 480 | } |
428 | 481 | ||
429 | static void pty_shutdown(struct tty_struct *tty) | 482 | static void pty_unix98_shutdown(struct tty_struct *tty) |
430 | { | 483 | { |
431 | /* We have our own method as we don't use the tty index */ | 484 | /* We have our own method as we don't use the tty index */ |
432 | kfree(tty->termios); | 485 | kfree(tty->termios); |
@@ -436,19 +489,71 @@ static void pty_shutdown(struct tty_struct *tty) | |||
436 | /* We have no need to install and remove our tty objects as devpts does all | 489 | /* We have no need to install and remove our tty objects as devpts does all |
437 | the work for us */ | 490 | the work for us */ |
438 | 491 | ||
439 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | 492 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) |
440 | { | 493 | { |
494 | struct tty_struct *o_tty; | ||
495 | int idx = tty->index; | ||
496 | |||
497 | o_tty = alloc_tty_struct(); | ||
498 | if (!o_tty) | ||
499 | return -ENOMEM; | ||
500 | if (!try_module_get(driver->other->owner)) { | ||
501 | /* This cannot in fact currently happen */ | ||
502 | free_tty_struct(o_tty); | ||
503 | return -ENOMEM; | ||
504 | } | ||
505 | initialize_tty_struct(o_tty, driver->other, idx); | ||
506 | |||
507 | tty->termios = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
508 | if (tty->termios == NULL) | ||
509 | goto free_mem_out; | ||
510 | *tty->termios = driver->init_termios; | ||
511 | tty->termios_locked = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
512 | if (tty->termios_locked == NULL) | ||
513 | goto free_mem_out; | ||
514 | o_tty->termios = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
515 | if (o_tty->termios == NULL) | ||
516 | goto free_mem_out; | ||
517 | *o_tty->termios = driver->other->init_termios; | ||
518 | o_tty->termios_locked = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
519 | if (o_tty->termios_locked == NULL) | ||
520 | goto free_mem_out; | ||
521 | |||
522 | tty_driver_kref_get(driver->other); | ||
523 | if (driver->subtype == PTY_TYPE_MASTER) | ||
524 | o_tty->count++; | ||
525 | /* Establish the links in both directions */ | ||
526 | tty->link = o_tty; | ||
527 | o_tty->link = tty; | ||
528 | /* | ||
529 | * All structures have been allocated, so now we install them. | ||
530 | * Failures after this point use release_tty to clean up, so | ||
531 | * there's no need to null out the local pointers. | ||
532 | */ | ||
533 | tty_driver_kref_get(driver); | ||
534 | tty->count++; | ||
535 | pty_count++; | ||
441 | return 0; | 536 | return 0; |
537 | free_mem_out: | ||
538 | kfree(o_tty->termios); | ||
539 | module_put(o_tty->driver->owner); | ||
540 | free_tty_struct(o_tty); | ||
541 | kfree(tty->termios_locked); | ||
542 | kfree(tty->termios); | ||
543 | free_tty_struct(tty); | ||
544 | module_put(driver->owner); | ||
545 | return -ENOMEM; | ||
442 | } | 546 | } |
443 | 547 | ||
444 | static void pty_remove(struct tty_driver *driver, struct tty_struct *tty) | 548 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) |
445 | { | 549 | { |
550 | pty_count--; | ||
446 | } | 551 | } |
447 | 552 | ||
448 | static const struct tty_operations ptm_unix98_ops = { | 553 | static const struct tty_operations ptm_unix98_ops = { |
449 | .lookup = ptm_unix98_lookup, | 554 | .lookup = ptm_unix98_lookup, |
450 | .install = pty_install, | 555 | .install = pty_unix98_install, |
451 | .remove = pty_remove, | 556 | .remove = pty_unix98_remove, |
452 | .open = pty_open, | 557 | .open = pty_open, |
453 | .close = pty_close, | 558 | .close = pty_close, |
454 | .write = pty_write, | 559 | .write = pty_write, |
@@ -458,13 +563,13 @@ static const struct tty_operations ptm_unix98_ops = { | |||
458 | .unthrottle = pty_unthrottle, | 563 | .unthrottle = pty_unthrottle, |
459 | .set_termios = pty_set_termios, | 564 | .set_termios = pty_set_termios, |
460 | .ioctl = pty_unix98_ioctl, | 565 | .ioctl = pty_unix98_ioctl, |
461 | .shutdown = pty_shutdown | 566 | .shutdown = pty_unix98_shutdown |
462 | }; | 567 | }; |
463 | 568 | ||
464 | static const struct tty_operations pty_unix98_ops = { | 569 | static const struct tty_operations pty_unix98_ops = { |
465 | .lookup = pts_unix98_lookup, | 570 | .lookup = pts_unix98_lookup, |
466 | .install = pty_install, | 571 | .install = pty_unix98_install, |
467 | .remove = pty_remove, | 572 | .remove = pty_unix98_remove, |
468 | .open = pty_open, | 573 | .open = pty_open, |
469 | .close = pty_close, | 574 | .close = pty_close, |
470 | .write = pty_write, | 575 | .write = pty_write, |
@@ -473,6 +578,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
473 | .chars_in_buffer = pty_chars_in_buffer, | 578 | .chars_in_buffer = pty_chars_in_buffer, |
474 | .unthrottle = pty_unthrottle, | 579 | .unthrottle = pty_unthrottle, |
475 | .set_termios = pty_set_termios, | 580 | .set_termios = pty_set_termios, |
581 | .shutdown = pty_unix98_shutdown | ||
476 | }; | 582 | }; |
477 | 583 | ||
478 | /** | 584 | /** |
@@ -589,10 +695,6 @@ static void __init unix98_pty_init(void) | |||
589 | if (tty_register_driver(pts_driver)) | 695 | if (tty_register_driver(pts_driver)) |
590 | panic("Couldn't register Unix98 pts driver"); | 696 | panic("Couldn't register Unix98 pts driver"); |
591 | 697 | ||
592 | /* FIXME: WTF */ | ||
593 | #if 0 | ||
594 | pty_table[1].data = &ptm_driver->refcount; | ||
595 | #endif | ||
596 | register_sysctl_table(pty_root_table); | 698 | register_sysctl_table(pty_root_table); |
597 | 699 | ||
598 | /* Now create the /dev/ptmx special device */ | 700 | /* Now create the /dev/ptmx special device */ |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index b0ad4880c3a8..e881e9ed08de 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -136,8 +136,6 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ | |||
136 | DEFINE_MUTEX(tty_mutex); | 136 | DEFINE_MUTEX(tty_mutex); |
137 | EXPORT_SYMBOL(tty_mutex); | 137 | EXPORT_SYMBOL(tty_mutex); |
138 | 138 | ||
139 | static void initialize_tty_struct(struct tty_struct *tty); | ||
140 | |||
141 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 139 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
142 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); | 140 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
143 | ssize_t redirected_tty_write(struct file *, const char __user *, | 141 | ssize_t redirected_tty_write(struct file *, const char __user *, |
@@ -166,7 +164,7 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | |||
166 | * Locking: none | 164 | * Locking: none |
167 | */ | 165 | */ |
168 | 166 | ||
169 | static struct tty_struct *alloc_tty_struct(void) | 167 | struct tty_struct *alloc_tty_struct(void) |
170 | { | 168 | { |
171 | return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); | 169 | return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); |
172 | } | 170 | } |
@@ -180,7 +178,7 @@ static struct tty_struct *alloc_tty_struct(void) | |||
180 | * Locking: none. Must be called after tty is definitely unused | 178 | * Locking: none. Must be called after tty is definitely unused |
181 | */ | 179 | */ |
182 | 180 | ||
183 | static inline void free_tty_struct(struct tty_struct *tty) | 181 | void free_tty_struct(struct tty_struct *tty) |
184 | { | 182 | { |
185 | kfree(tty->write_buf); | 183 | kfree(tty->write_buf); |
186 | tty_buffer_free_all(tty); | 184 | tty_buffer_free_all(tty); |
@@ -1227,22 +1225,70 @@ struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, int idx) | |||
1227 | } | 1225 | } |
1228 | 1226 | ||
1229 | /** | 1227 | /** |
1228 | * tty_init_termios - helper for termios setup | ||
1229 | * @tty: the tty to set up | ||
1230 | * | ||
1231 | * Initialise the termios structures for this tty. Thus runs under | ||
1232 | * the tty_mutex currently so we can be relaxed about ordering. | ||
1233 | */ | ||
1234 | |||
1235 | int tty_init_termios(struct tty_struct *tty) | ||
1236 | { | ||
1237 | struct ktermios *tp, *ltp; | ||
1238 | int idx = tty->index; | ||
1239 | |||
1240 | tp = tty->driver->termios[idx]; | ||
1241 | ltp = tty->driver->termios_locked[idx]; | ||
1242 | if (tp == NULL) { | ||
1243 | WARN_ON(ltp != NULL); | ||
1244 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1245 | ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1246 | if (tp == NULL || ltp == NULL) { | ||
1247 | kfree(tp); | ||
1248 | kfree(ltp); | ||
1249 | return -ENOMEM; | ||
1250 | } | ||
1251 | memcpy(tp, &tty->driver->init_termios, | ||
1252 | sizeof(struct ktermios)); | ||
1253 | tty->driver->termios[idx] = tp; | ||
1254 | tty->driver->termios_locked[idx] = ltp; | ||
1255 | } | ||
1256 | tty->termios = tp; | ||
1257 | tty->termios_locked = ltp; | ||
1258 | |||
1259 | /* Compatibility until drivers always set this */ | ||
1260 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1261 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1262 | return 0; | ||
1263 | } | ||
1264 | |||
1265 | /** | ||
1230 | * tty_driver_install_tty() - install a tty entry in the driver | 1266 | * tty_driver_install_tty() - install a tty entry in the driver |
1231 | * @driver: the driver for the tty | 1267 | * @driver: the driver for the tty |
1232 | * @tty: the tty | 1268 | * @tty: the tty |
1233 | * | 1269 | * |
1234 | * Install a tty object into the driver tables. The tty->index field | 1270 | * Install a tty object into the driver tables. The tty->index field |
1235 | * will be set by the time this is called. | 1271 | * will be set by the time this is called. This method is responsible |
1272 | * for ensuring any need additional structures are allocated and | ||
1273 | * configured. | ||
1236 | * | 1274 | * |
1237 | * Locking: tty_mutex for now | 1275 | * Locking: tty_mutex for now |
1238 | */ | 1276 | */ |
1239 | static int tty_driver_install_tty(struct tty_driver *driver, | 1277 | static int tty_driver_install_tty(struct tty_driver *driver, |
1240 | struct tty_struct *tty) | 1278 | struct tty_struct *tty) |
1241 | { | 1279 | { |
1280 | int idx = tty->index; | ||
1281 | |||
1242 | if (driver->ops->install) | 1282 | if (driver->ops->install) |
1243 | return driver->ops->install(driver, tty); | 1283 | return driver->ops->install(driver, tty); |
1244 | driver->ttys[tty->index] = tty; | 1284 | |
1245 | return 0; | 1285 | if (tty_init_termios(tty) == 0) { |
1286 | tty_driver_kref_get(driver); | ||
1287 | tty->count++; | ||
1288 | driver->ttys[idx] = tty; | ||
1289 | return 0; | ||
1290 | } | ||
1291 | return -ENOMEM; | ||
1246 | } | 1292 | } |
1247 | 1293 | ||
1248 | /** | 1294 | /** |
@@ -1327,9 +1373,7 @@ static int tty_reopen(struct tty_struct *tty) | |||
1327 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | 1373 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, |
1328 | int first_ok) | 1374 | int first_ok) |
1329 | { | 1375 | { |
1330 | struct tty_struct *tty, *o_tty; | 1376 | struct tty_struct *tty; |
1331 | struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; | ||
1332 | struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | ||
1333 | int retval; | 1377 | int retval; |
1334 | 1378 | ||
1335 | /* check whether we're reopening an existing tty */ | 1379 | /* check whether we're reopening an existing tty */ |
@@ -1361,118 +1405,17 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1361 | if (!try_module_get(driver->owner)) | 1405 | if (!try_module_get(driver->owner)) |
1362 | return ERR_PTR(-ENODEV); | 1406 | return ERR_PTR(-ENODEV); |
1363 | 1407 | ||
1364 | o_tty = NULL; | ||
1365 | tp = o_tp = NULL; | ||
1366 | ltp = o_ltp = NULL; | ||
1367 | |||
1368 | tty = alloc_tty_struct(); | 1408 | tty = alloc_tty_struct(); |
1369 | if (!tty) | 1409 | if (!tty) |
1370 | goto fail_no_mem; | 1410 | goto fail_no_mem; |
1371 | initialize_tty_struct(tty); | 1411 | initialize_tty_struct(tty, driver, idx); |
1372 | tty->driver = driver; | ||
1373 | tty->ops = driver->ops; | ||
1374 | tty->index = idx; | ||
1375 | tty_line_name(driver, idx, tty->name); | ||
1376 | |||
1377 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | ||
1378 | tp_loc = &tty->termios; | ||
1379 | ltp_loc = &tty->termios_locked; | ||
1380 | } else { | ||
1381 | tp_loc = &driver->termios[idx]; | ||
1382 | ltp_loc = &driver->termios_locked[idx]; | ||
1383 | } | ||
1384 | |||
1385 | if (!*tp_loc) { | ||
1386 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1387 | if (!tp) | ||
1388 | goto free_mem_out; | ||
1389 | *tp = driver->init_termios; | ||
1390 | } | ||
1391 | |||
1392 | if (!*ltp_loc) { | ||
1393 | ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1394 | if (!ltp) | ||
1395 | goto free_mem_out; | ||
1396 | } | ||
1397 | |||
1398 | if (driver->type == TTY_DRIVER_TYPE_PTY) { | ||
1399 | o_tty = alloc_tty_struct(); | ||
1400 | if (!o_tty) | ||
1401 | goto free_mem_out; | ||
1402 | if (!try_module_get(driver->other->owner)) { | ||
1403 | /* This cannot in fact currently happen */ | ||
1404 | free_tty_struct(o_tty); | ||
1405 | o_tty = NULL; | ||
1406 | goto free_mem_out; | ||
1407 | } | ||
1408 | initialize_tty_struct(o_tty); | ||
1409 | o_tty->driver = driver->other; | ||
1410 | o_tty->ops = driver->ops; | ||
1411 | o_tty->index = idx; | ||
1412 | tty_line_name(driver->other, idx, o_tty->name); | ||
1413 | |||
1414 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | ||
1415 | o_tp_loc = &o_tty->termios; | ||
1416 | o_ltp_loc = &o_tty->termios_locked; | ||
1417 | } else { | ||
1418 | o_tp_loc = &driver->other->termios[idx]; | ||
1419 | o_ltp_loc = &driver->other->termios_locked[idx]; | ||
1420 | } | ||
1421 | |||
1422 | if (!*o_tp_loc) { | ||
1423 | o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1424 | if (!o_tp) | ||
1425 | goto free_mem_out; | ||
1426 | *o_tp = driver->other->init_termios; | ||
1427 | } | ||
1428 | |||
1429 | if (!*o_ltp_loc) { | ||
1430 | o_ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1431 | if (!o_ltp) | ||
1432 | goto free_mem_out; | ||
1433 | } | ||
1434 | |||
1435 | /* | ||
1436 | * Everything allocated ... set up the o_tty structure. | ||
1437 | */ | ||
1438 | if (!(driver->other->flags & TTY_DRIVER_DEVPTS_MEM)) | ||
1439 | driver->other->ttys[idx] = o_tty; | ||
1440 | if (!*o_tp_loc) | ||
1441 | *o_tp_loc = o_tp; | ||
1442 | if (!*o_ltp_loc) | ||
1443 | *o_ltp_loc = o_ltp; | ||
1444 | o_tty->termios = *o_tp_loc; | ||
1445 | o_tty->termios_locked = *o_ltp_loc; | ||
1446 | tty_driver_kref_get(driver->other); | ||
1447 | if (driver->subtype == PTY_TYPE_MASTER) | ||
1448 | o_tty->count++; | ||
1449 | |||
1450 | /* Establish the links in both directions */ | ||
1451 | tty->link = o_tty; | ||
1452 | o_tty->link = tty; | ||
1453 | } | ||
1454 | |||
1455 | /* | ||
1456 | * All structures have been allocated, so now we install them. | ||
1457 | * Failures after this point use release_tty to clean up, so | ||
1458 | * there's no need to null out the local pointers. | ||
1459 | */ | ||
1460 | |||
1461 | if (!*tp_loc) | ||
1462 | *tp_loc = tp; | ||
1463 | if (!*ltp_loc) | ||
1464 | *ltp_loc = ltp; | ||
1465 | tty->termios = *tp_loc; | ||
1466 | tty->termios_locked = *ltp_loc; | ||
1467 | /* Compatibility until drivers always set this */ | ||
1468 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1469 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1470 | tty_driver_kref_get(driver); | ||
1471 | tty->count++; | ||
1472 | 1412 | ||
1473 | retval = tty_driver_install_tty(driver, tty); | 1413 | retval = tty_driver_install_tty(driver, tty); |
1474 | if (retval < 0) | 1414 | if (retval < 0) { |
1475 | goto release_mem_out; | 1415 | free_tty_struct(tty); |
1416 | module_put(driver->owner); | ||
1417 | return ERR_PTR(retval); | ||
1418 | } | ||
1476 | 1419 | ||
1477 | /* | 1420 | /* |
1478 | * Structures all installed ... call the ldisc open routines. | 1421 | * Structures all installed ... call the ldisc open routines. |
@@ -1480,22 +1423,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1480 | * to decrement the use counts, as release_tty doesn't care. | 1423 | * to decrement the use counts, as release_tty doesn't care. |
1481 | */ | 1424 | */ |
1482 | 1425 | ||
1483 | retval = tty_ldisc_setup(tty, o_tty); | 1426 | retval = tty_ldisc_setup(tty, tty->link); |
1484 | if (retval) | 1427 | if (retval) |
1485 | goto release_mem_out; | 1428 | goto release_mem_out; |
1486 | return tty; | 1429 | return tty; |
1487 | 1430 | ||
1488 | /* Release locally allocated memory ... nothing placed in slots */ | ||
1489 | free_mem_out: | ||
1490 | kfree(o_tp); | ||
1491 | if (o_tty) { | ||
1492 | module_put(o_tty->driver->owner); | ||
1493 | free_tty_struct(o_tty); | ||
1494 | } | ||
1495 | kfree(ltp); | ||
1496 | kfree(tp); | ||
1497 | free_tty_struct(tty); | ||
1498 | |||
1499 | fail_no_mem: | 1431 | fail_no_mem: |
1500 | module_put(driver->owner); | 1432 | module_put(driver->owner); |
1501 | return ERR_PTR(-ENOMEM); | 1433 | return ERR_PTR(-ENOMEM); |
@@ -2852,7 +2784,8 @@ EXPORT_SYMBOL(do_SAK); | |||
2852 | * Locking: none - tty in question must not be exposed at this point | 2784 | * Locking: none - tty in question must not be exposed at this point |
2853 | */ | 2785 | */ |
2854 | 2786 | ||
2855 | static void initialize_tty_struct(struct tty_struct *tty) | 2787 | void initialize_tty_struct(struct tty_struct *tty, |
2788 | struct tty_driver *driver, int idx) | ||
2856 | { | 2789 | { |
2857 | memset(tty, 0, sizeof(struct tty_struct)); | 2790 | memset(tty, 0, sizeof(struct tty_struct)); |
2858 | kref_init(&tty->kref); | 2791 | kref_init(&tty->kref); |
@@ -2873,6 +2806,11 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
2873 | spin_lock_init(&tty->ctrl_lock); | 2806 | spin_lock_init(&tty->ctrl_lock); |
2874 | INIT_LIST_HEAD(&tty->tty_files); | 2807 | INIT_LIST_HEAD(&tty->tty_files); |
2875 | INIT_WORK(&tty->SAK_work, do_SAK_work); | 2808 | INIT_WORK(&tty->SAK_work, do_SAK_work); |
2809 | |||
2810 | tty->driver = driver; | ||
2811 | tty->ops = driver->ops; | ||
2812 | tty->index = idx; | ||
2813 | tty_line_name(driver, idx, tty->name); | ||
2876 | } | 2814 | } |
2877 | 2815 | ||
2878 | /** | 2816 | /** |