summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
authorDaeseok Youn <daeseok.youn@gmail.com>2014-06-02 14:08:24 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-19 15:21:47 -0700
commit72d0f6fc63fa42ef3b956b2f02f3a10dca1225fe (patch)
treee5f6e5713abed5d3c86ba3e80eabb48908c8c038 /drivers/staging
parent551a9d73942b0ffa6cb9fe3bb35936dcc7172281 (diff)
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 <daeseok.youn@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/dgap/dgap.c44
1 files 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;
}
/*