From 72d0f6fc63fa42ef3b956b2f02f3a10dca1225fe Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Mon, 2 Jun 2014 14:08:24 +0900 Subject: [PATCH] staging: dgap: unwind on error in dgap_tty_register_ports() - The dgap_tty_register_ports() needs to handle if the tty_port_register_device() fails. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 44 +++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 8580f4bd229f..3e716feea5f6 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -4143,6 +4143,7 @@ static int dgap_tty_register_ports(struct board_t *brd) { struct channel_t *ch; int i; + int ret; brd->serial_ports = kcalloc(brd->nasync, sizeof(*brd->serial_ports), GFP_KERNEL); @@ -4152,8 +4153,8 @@ static int dgap_tty_register_ports(struct board_t *brd) brd->printer_ports = kcalloc(brd->nasync, sizeof(*brd->printer_ports), GFP_KERNEL); if (!brd->printer_ports) { - kfree(brd->serial_ports); - return -ENOMEM; + ret = -ENOMEM; + goto free_serial_ports; } for (i = 0; i < brd->nasync; i++) { @@ -4170,6 +4171,11 @@ static int dgap_tty_register_ports(struct board_t *brd) brd->serial_driver, brd->firstminor + i, NULL); + if (IS_ERR(classp)) { + ret = PTR_ERR(classp); + goto unregister_ttys; + } + dgap_create_tty_sysfs(&ch->ch_tun, classp); ch->ch_tun.un_sysfs = classp; @@ -4177,12 +4183,46 @@ static int dgap_tty_register_ports(struct board_t *brd) brd->print_driver, brd->firstminor + i, NULL); + if (IS_ERR(classp)) { + ret = PTR_ERR(classp); + goto unregister_ttys; + } + dgap_create_tty_sysfs(&ch->ch_pun, classp); ch->ch_pun.un_sysfs = classp; } dgap_create_ports_sysfiles(brd); return 0; + +unregister_ttys: + while (i >= 0) { + ch = brd->channels[i]; + if (ch->ch_tun.un_sysfs) { + dgap_remove_tty_sysfs(ch->ch_tun.un_sysfs); + tty_unregister_device(brd->serial_driver, i); + } + + if (ch->ch_pun.un_sysfs) { + dgap_remove_tty_sysfs(ch->ch_pun.un_sysfs); + tty_unregister_device(brd->print_driver, i); + } + i--; + } + + for (i = 0; i < brd->nasync; i++) { + tty_port_destroy(&brd->serial_ports[i]); + tty_port_destroy(&brd->printer_ports[i]); + } + + kfree(brd->printer_ports); + brd->printer_ports = NULL; + +free_serial_ports: + kfree(brd->serial_ports); + brd->serial_ports = NULL; + + return ret; } /* -- 2.34.1