Skip to content

Commit

Permalink
[PATCH] USB: fix usb reference count bug in cdc-acm driver
Browse files Browse the repository at this point in the history
This increases the reference count on the usb cdc acm control interface
which is referred to by the tty interface provided by the driver. This
allows the deferred removal of the tty after the physical device is
disconnected if the tty is held open at the time of disconnection.

Signed-off-by: brian@murphy.dk
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
brian@murphy.dk authored and Greg Kroah-Hartman committed Jul 12, 2005
1 parent a3fdf4e commit 83ef344
Showing 1 changed file with 16 additions and 15 deletions.
31 changes: 16 additions & 15 deletions drivers/usb/class/cdc-acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,17 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
return -EIO;
}

static void acm_tty_unregister(struct acm *acm)
{
tty_unregister_device(acm_tty_driver, acm->minor);
usb_put_intf(acm->control);
acm_table[acm->minor] = NULL;
usb_free_urb(acm->ctrlurb);
usb_free_urb(acm->readurb);
usb_free_urb(acm->writeurb);
kfree(acm);
}

static void acm_tty_close(struct tty_struct *tty, struct file *filp)
{
struct acm *acm = tty->driver_data;
Expand All @@ -436,14 +447,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
usb_kill_urb(acm->ctrlurb);
usb_kill_urb(acm->writeurb);
usb_kill_urb(acm->readurb);
} else {
tty_unregister_device(acm_tty_driver, acm->minor);
acm_table[acm->minor] = NULL;
usb_free_urb(acm->ctrlurb);
usb_free_urb(acm->readurb);
usb_free_urb(acm->writeurb);
kfree(acm);
}
} else
acm_tty_unregister(acm);
}
up(&open_sem);
}
Expand Down Expand Up @@ -905,7 +910,8 @@ static int acm_probe (struct usb_interface *intf,

usb_driver_claim_interface(&acm_driver, data_interface, acm);

tty_register_device(acm_tty_driver, minor, &intf->dev);
usb_get_intf(control_interface);
tty_register_device(acm_tty_driver, minor, &control_interface->dev);

acm_table[minor] = acm;
usb_set_intfdata (intf, acm);
Expand Down Expand Up @@ -954,12 +960,7 @@ static void acm_disconnect(struct usb_interface *intf)
usb_driver_release_interface(&acm_driver, acm->data);

if (!acm->used) {
tty_unregister_device(acm_tty_driver, acm->minor);
acm_table[acm->minor] = NULL;
usb_free_urb(acm->ctrlurb);
usb_free_urb(acm->readurb);
usb_free_urb(acm->writeurb);
kfree(acm);
acm_tty_unregister(acm);
up(&open_sem);
return;
}
Expand Down

0 comments on commit 83ef344

Please sign in to comment.