diff options
Diffstat (limited to 'drivers/usb/class')
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 22 | 
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 8ac25adf31b..387dc6c8ad2 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -593,7 +593,6 @@ static void acm_port_destruct(struct tty_port *port)  	dev_dbg(&acm->control->dev, "%s\n", __func__); -	tty_unregister_device(acm_tty_driver, acm->minor);  	acm_release_minor(acm);  	usb_put_intf(acm->control);  	kfree(acm->country_codes); @@ -977,6 +976,8 @@ static int acm_probe(struct usb_interface *intf,  	int num_rx_buf;  	int i;  	int combined_interfaces = 0; +	struct device *tty_dev; +	int rv = -ENOMEM;  	/* normal quirks */  	quirks = (unsigned long)id->driver_info; @@ -1339,11 +1340,24 @@ skip_countries:  	usb_set_intfdata(data_interface, acm);  	usb_get_intf(control_interface); -	tty_port_register_device(&acm->port, acm_tty_driver, minor, +	tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,  			&control_interface->dev); +	if (IS_ERR(tty_dev)) { +		rv = PTR_ERR(tty_dev); +		goto alloc_fail8; +	}  	return 0; +alloc_fail8: +	if (acm->country_codes) { +		device_remove_file(&acm->control->dev, +				&dev_attr_wCountryCodes); +		device_remove_file(&acm->control->dev, +				&dev_attr_iCountryCodeRelDate); +	} +	device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);  alloc_fail7: +	usb_set_intfdata(intf, NULL);  	for (i = 0; i < ACM_NW; i++)  		usb_free_urb(acm->wb[i].urb);  alloc_fail6: @@ -1359,7 +1373,7 @@ alloc_fail2:  	acm_release_minor(acm);  	kfree(acm);  alloc_fail: -	return -ENOMEM; +	return rv;  }  static void stop_data_traffic(struct acm *acm) @@ -1411,6 +1425,8 @@ static void acm_disconnect(struct usb_interface *intf)  	stop_data_traffic(acm); +	tty_unregister_device(acm_tty_driver, acm->minor); +  	usb_free_urb(acm->ctrlurb);  	for (i = 0; i < ACM_NW; i++)  		usb_free_urb(acm->wb[i].urb);  |