From: Greg KH <greg@kroah.com>
To: Zwane Mwaikambo <zwane@linuxpower.ca>,
Harald Welte <laforge@gnumonks.org>
Cc: Linux Kernel <linux-kernel@vger.kernel.org>,
linux-usb-devel@lists.sourceforge.net
Subject: [PATCH] fix different usb-serial oopses for 2.6.7
Date: Tue, 29 Jun 2004 14:37:56 -0700 [thread overview]
Message-ID: <20040629213756.GA21065@kroah.com> (raw)
In-Reply-To: <20040616192503.GL12494@sunbeam.de.gnumonks.org> <Pine.LNX.4.58.0406231216270.3273@montezuma.fsmlabs.com>
Hi,
Ok, thanks to both of you posting bug reports that seemed quite
different, I think I've finally fixed both of your issues. The patch
below is what I've just added to my trees and will send to Linus in a
bit, and should solve both problems.
Basically the issue was 2 things:
- Zwane correctly found that we shouldn't have been calling the
usb_driver_release_interface() call on disconnect, but if you
didn't make this call, we leaked memory. This was because of
the next piece...
- Harald noticed that if you unloaded a usb-serial driver with
the device still plugged in, and then removed it, the kernel
oopsed. He also noticed double calls to the disconnect
function. This was because we were incorrectly binding the
device to the usb serial generic driver instead of the one
that was controlling it.
So, by fixing the usb-serial generic issue, that fixed the fact that we
shouldn't have been calling the release_interface() call, as it isn't
necessary (the usb core will take care of it.)
Thanks to everyone for helping out here, and if with this patch, you
still have problems, please let me know...
/me crosses his fingers
greg k-h
USB: fix bug where removing usb-serial modules or usb serial devices could oops
This fixes the issue where the Generic driver would bind to all usb-serial
devices, so the disconnect would not properly go to the real driver that
controlled the device. This was very bad when unloading the module with
the device still connected.
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
diff -Nru a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
--- a/drivers/usb/serial/generic.c 2004-06-29 14:32:36 -07:00
+++ b/drivers/usb/serial/generic.c 2004-06-29 14:32:36 -07:00
@@ -53,6 +53,32 @@
.num_ports = 1,
.shutdown = usb_serial_generic_shutdown,
};
+
+/* we want to look at all devices, as the vendor/product id can change
+ * depending on the command line argument */
+static struct usb_device_id generic_serial_ids[] = {
+ {.driver_info = 42},
+ {}
+};
+
+static int generic_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ const struct usb_device_id *id_pattern;
+
+ id_pattern = usb_match_id(interface, generic_device_ids);
+ if (id_pattern != NULL)
+ return usb_serial_probe(interface, id);
+ return -ENODEV;
+}
+
+static struct usb_driver generic_driver = {
+ .owner = THIS_MODULE,
+ .name = "usbserial_generic",
+ .probe = generic_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = generic_serial_ids,
+};
#endif
int usb_serial_generic_register (int _debug)
@@ -67,6 +93,12 @@
/* register our generic driver with ourselves */
retval = usb_serial_register (&usb_serial_generic_device);
+ if (retval)
+ goto exit;
+ retval = usb_register(&generic_driver);
+ if (retval)
+ usb_serial_deregister(&usb_serial_generic_device);
+exit:
#endif
return retval;
}
@@ -75,6 +107,7 @@
{
#ifdef CONFIG_USB_SERIAL_GENERIC
/* remove our generic driver */
+ usb_deregister(&generic_driver);
usb_serial_deregister (&usb_serial_generic_device);
#endif
}
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c 2004-06-29 14:32:36 -07:00
+++ b/drivers/usb/serial/usb-serial.c 2004-06-29 14:32:36 -07:00
@@ -355,25 +355,12 @@
#define DRIVER_DESC "USB Serial Driver core"
-#ifdef CONFIG_USB_SERIAL_GENERIC
-/* we want to look at all devices, as the vendor/product id can change
- * depending on the command line argument */
-static struct usb_device_id generic_serial_ids[] = {
- {.driver_info = 42},
- {}
-};
-
-#endif /* CONFIG_USB_SERIAL_GENERIC */
-
/* Driver structure we register with the USB core */
static struct usb_driver usb_serial_driver = {
.owner = THIS_MODULE,
.name = "usbserial",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
-#ifdef CONFIG_USB_SERIAL_GENERIC
- .id_table = generic_serial_ids,
-#endif
};
/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
@@ -1383,22 +1370,9 @@
void usb_serial_deregister(struct usb_serial_device_type *device)
{
- struct usb_serial *serial;
- int i;
-
info("USB Serial deregistering driver %s", device->name);
-
- /* clear out the serial_table if the device is attached to a port */
- for(i = 0; i < SERIAL_TTY_MINORS; ++i) {
- serial = serial_table[i];
- if ((serial != NULL) && (serial->type == device)) {
- usb_driver_release_interface (&usb_serial_driver, serial->interface);
- usb_serial_disconnect (serial->interface);
- }
- }
-
list_del(&device->driver_list);
- usb_serial_bus_deregister (device);
+ usb_serial_bus_deregister(device);
}
next prev parent reply other threads:[~2004-06-29 21:40 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-06-07 21:54 [BK PATCH] USB fixes for 2.6.7-rc3 Greg KH
[not found] ` <10866458194180@kroah.com>
[not found] ` <20040616091710.GS12494@sunbeam.de.gnumonks.org>
[not found] ` <20040616170409.GK12494@sunbeam.de.gnumonks.org>
[not found] ` <20040616175800.GB13937@kroah.com>
2004-06-23 6:33 ` Oops w/ USB serial + modular ipaq Zwane Mwaikambo
2004-06-23 8:21 ` Zwane Mwaikambo
2004-06-23 16:10 ` Greg KH
2004-06-23 17:01 ` Zwane Mwaikambo
2004-06-29 21:37 ` Greg KH [this message]
2004-06-30 4:50 ` [PATCH] fix different usb-serial oopses for 2.6.7 Zwane Mwaikambo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040629213756.GA21065@kroah.com \
--to=greg@kroah.com \
--cc=laforge@gnumonks.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb-devel@lists.sourceforge.net \
--cc=zwane@linuxpower.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox