Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d34138d0 authored by Alexey Khoroshilov's avatar Alexey Khoroshilov Committed by Greg Kroah-Hartman
Browse files

pcmcia: synclink_cs: fix error handling in mgslpc_probe()



mgslpc_probe() ignores errors in mgslpc_add_device() and
does not release all resource if mgslpc_config() failed.

The patch adds returned code to mgslpc_add_device()
and fixes the both issues.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: default avatarAlexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b95d788a
Loading
Loading
Loading
Loading
+41 −10
Original line number Diff line number Diff line
@@ -397,7 +397,7 @@ static int adapter_test(MGSLPC_INFO *info);

static int claim_resources(MGSLPC_INFO *info);
static void release_resources(MGSLPC_INFO *info);
static void mgslpc_add_device(MGSLPC_INFO *info);
static int mgslpc_add_device(MGSLPC_INFO *info);
static void mgslpc_remove_device(MGSLPC_INFO *info);

static bool rx_get_frame(MGSLPC_INFO *info, struct tty_struct *tty);
@@ -549,14 +549,21 @@ static int mgslpc_probe(struct pcmcia_device *link)
    /* Initialize the struct pcmcia_device structure */

    ret = mgslpc_config(link);
    if (ret) {
	    tty_port_destroy(&info->port);
	    return ret;
    }
    if (ret != 0)
	    goto failed;

    mgslpc_add_device(info);
    ret = mgslpc_add_device(info);
    if (ret != 0)
	    goto failed_release;

    return 0;

failed_release:
    mgslpc_release((u_long)link);
failed:
    tty_port_destroy(&info->port);
    kfree(info);
    return ret;
}

/* Card has been inserted.
@@ -2706,8 +2713,12 @@ static void release_resources(MGSLPC_INFO *info)
 *
 * Arguments:		info	pointer to device instance data
 */
static void mgslpc_add_device(MGSLPC_INFO *info)
static int mgslpc_add_device(MGSLPC_INFO *info)
{
	MGSLPC_INFO *current_dev = NULL;
	struct device *tty_dev;
	int ret;

	info->next_device = NULL;
	info->line = mgslpc_device_count;
	sprintf(info->device_name,"ttySLP%d",info->line);
@@ -2722,7 +2733,7 @@ static void mgslpc_add_device(MGSLPC_INFO *info)
	if (!mgslpc_device_list)
		mgslpc_device_list = info;
	else {
		MGSLPC_INFO *current_dev = mgslpc_device_list;
		current_dev = mgslpc_device_list;
		while( current_dev->next_device )
			current_dev = current_dev->next_device;
		current_dev->next_device = info;
@@ -2737,10 +2748,30 @@ static void mgslpc_add_device(MGSLPC_INFO *info)
		info->device_name, info->io_base, info->irq_level);

#if SYNCLINK_GENERIC_HDLC
	hdlcdev_init(info);
	ret = hdlcdev_init(info);
	if (ret != 0)
		goto failed;
#endif
	tty_port_register_device(&info->port, serial_driver, info->line,

	tty_dev = tty_port_register_device(&info->port, serial_driver, info->line,
			&info->p_dev->dev);
	if (IS_ERR(tty_dev)) {
		ret = PTR_ERR(tty_dev);
#if SYNCLINK_GENERIC_HDLC
		hdlcdev_exit(info);
#endif
		goto failed;
	}

	return 0;

failed:
	if (current_dev)
		current_dev->next_device = NULL;
	else
		mgslpc_device_list = NULL;
	mgslpc_device_count--;
	return ret;
}

static void mgslpc_remove_device(MGSLPC_INFO *remove_info)