Greg:
This patch contains changes to usbcore making the core responsible for
deallocating memory for usb_hcd structures, rather than calling back into
the host controller drivers. This solves a long-standing oops, since the
drivers may have been unloaded from memory by the time the release routine
is called. (There probably are some Bugzilla entries caused by this, but
I don't know which ones.)
To really fix this up properly will require merging the HCD "glue" layer
into the higher core structures. As things stand now, a usb_hcd contains
a usb_bus member, and the usb_bus is associated with a class_device: when
the class_device is released the usb_hcd gets deallocated. It's awkward
in that neither the usb_hcd nor the usb_bus has its own reference count,
and the class_device is created when the bus is registered (not when it is
initialized).
Please apply.
Alan Stern
Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
===== drivers/usb/core/hcd-pci.c 1.63 vs edited =====
--- 1.63/drivers/usb/core/hcd-pci.c 2004-10-20 12:53:13 -04:00
+++ edited/drivers/usb/core/hcd-pci.c 2004-10-28 11:33:42 -04:00
@@ -38,14 +38,6 @@
/*-------------------------------------------------------------------------*/
-static void hcd_pci_release(struct usb_bus *bus)
-{
- struct usb_hcd *hcd = bus->hcpriv;
-
- if (hcd)
- hcd->driver->hcd_free(hcd);
-}
-
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
@@ -160,7 +152,7 @@
if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
- driver->hcd_free (hcd);
+ kfree (hcd);
goto clean_2;
}
@@ -194,8 +186,8 @@
usb_bus_init (&hcd->self);
hcd->self.op = &usb_hcd_operations;
+ hcd->self.release = &usb_hcd_release;
hcd->self.hcpriv = (void *) hcd;
- hcd->self.release = &hcd_pci_release;
init_timer (&hcd->rh_timer);
INIT_LIST_HEAD (&hcd->dev_list);
===== drivers/usb/core/hcd.c 1.161 vs edited =====
--- 1.161/drivers/usb/core/hcd.c 2004-10-20 12:38:07 -04:00
+++ edited/drivers/usb/core/hcd.c 2004-10-28 11:28:41 -04:00
@@ -1605,3 +1605,13 @@
}
EXPORT_SYMBOL (usb_hc_died);
+/*-------------------------------------------------------------------------*/
+
+void usb_hcd_release(struct usb_bus *bus)
+{
+ struct usb_hcd *hcd;
+
+ hcd = container_of (bus, struct usb_hcd, self);
+ kfree(hcd);
+}
+EXPORT_SYMBOL (usb_hcd_release);
===== drivers/usb/core/hcd.h 1.91 vs edited =====
--- 1.91/drivers/usb/core/hcd.h 2004-10-20 12:53:13 -04:00
+++ edited/drivers/usb/core/hcd.h 2004-10-28 11:26:59 -04:00
@@ -192,7 +192,6 @@
/* memory lifecycle */
struct usb_hcd *(*hcd_alloc) (void);
- void (*hcd_free) (struct usb_hcd *hcd);
/* manage i/o requests, device state */
int (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
@@ -360,6 +359,8 @@
return usb_register_root_hub (usb_dev, hcd->self.controller);
}
+
+extern void usb_hcd_release (struct usb_bus *);
extern void usb_set_device_state(struct usb_device *udev,
enum usb_device_state new_state);
-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel