summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/uhub.c40
-rw-r--r--sys/dev/usb/usb_port.h6
-rw-r--r--sys/dev/usb/usb_subr.c68
3 files changed, 50 insertions, 64 deletions
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
index d4f6833..2e99a1f 100644
--- a/sys/dev/usb/uhub.c
+++ b/sys/dev/usb/uhub.c
@@ -90,10 +90,9 @@ Static usbd_status uhub_explore(usbd_device_handle hub);
Static void uhub_intr(usbd_xfer_handle, usbd_private_handle,usbd_status);
#if defined(__FreeBSD__)
-Static bus_driver_added_t uhub_driver_added;
Static bus_child_detached_t uhub_child_detached;
-int uhub_child_location_str(device_t, device_t, char*, size_t);
-int uhub_child_pnpinfo_str(device_t, device_t, char*, size_t);
+Static bus_child_location_str_t uhub_child_location_str;
+Static bus_child_pnpinfo_str_t uhub_child_pnpinfo_str;
#endif
@@ -111,25 +110,26 @@ CFATTACH_DECL(uhub_uhub, sizeof(struct uhub_softc),
uhub_match, uhub_attach, uhub_detach, uhub_activate);
#elif defined(__FreeBSD__)
USB_DECLARE_DRIVER_INIT(uhub,
- DEVMETHOD(bus_driver_added, uhub_driver_added),
- DEVMETHOD(bus_child_detached, uhub_child_detached),
- DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str),
- DEVMETHOD(bus_child_location_str, uhub_child_location_str),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown)
- );
+ DEVMETHOD(bus_child_detached, uhub_child_detached),
+ DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str),
+ DEVMETHOD(bus_child_location_str, uhub_child_location_str),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown)
+ );
/* Create the driver instance for the hub connected to usb case. */
devclass_t uhubroot_devclass;
Static device_method_t uhubroot_methods[] = {
DEVMETHOD(bus_child_detached, uhub_child_detached),
- DEVMETHOD(device_probe, uhub_match),
- DEVMETHOD(device_attach, uhub_attach),
- DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str),
DEVMETHOD(bus_child_location_str, uhub_child_location_str),
+ DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+ DEVMETHOD(device_probe, uhub_match),
+ DEVMETHOD(device_attach, uhub_attach),
DEVMETHOD(device_detach, uhub_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
@@ -714,18 +714,6 @@ uhub_child_detached(device_t self, device_t child)
}
}
}
-
-Static void
-uhub_driver_added(device_t _dev, driver_t *_driver)
-{
- /*
- * Don't do anything, as reprobing does not work currently.
- * In the future we should properly allocate ivars so we can
- * leave the devices attached to the newbus tree. Once we do
- * that, then we can reprobe on driver loading with the
- * default driver added routines.
- */
-}
#endif
diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h
index bb9addc..abfac81 100644
--- a/sys/dev/usb/usb_port.h
+++ b/sys/dev/usb/usb_port.h
@@ -417,7 +417,11 @@ typedef struct callout usb_callout_t;
#define PWR_RESUME 0
#define PWR_SUSPEND 1
-#define config_detach(dev, flag) device_delete_child(device_get_parent(dev), dev)
+#define config_detach(dev, flag) \
+ do { \
+ free(device_get_ivars(dev), M_USB); \
+ device_delete_child(device_get_parent(dev), dev); \
+ } while (0);
typedef struct malloc_type *usb_malloc_type;
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index 52e363d..3f50e63 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -853,20 +853,22 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
#if defined(__FreeBSD__)
- /*
- * XXX uaa is a static var. Not a problem as it _should_ be used only
- * during probe and attach. Should be changed however.
- */
- device_t bdev;
+ /* XXX FreeBSD may leak resources on failure cases -- fixme */
+ device_t bdev;
+ struct usb_attach_arg *uaap;
+
bdev = device_add_child(parent, NULL, -1);
if (!bdev) {
- printf("%s: Device creation failed\n", USBDEVNAME(dev->bus->bdev));
- return (USBD_INVAL);
+ device_printf(parent, "Device creation failed\n");
+ return (USBD_INVAL);
}
- device_set_ivars(bdev, &uaa);
device_quiet(bdev);
+ uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT);
+ if (uaap == NULL) {
+ return (USBD_INVAL);
+ }
+ device_set_ivars(bdev, uaap);
#endif
-
uaa.device = dev;
uaa.iface = NULL;
uaa.ifaces = NULL;
@@ -888,15 +890,14 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
return (USBD_NOMEM);
dev->subdevs[0] = bdev;
dev->subdevs[1] = 0;
+ *uaap = uaa;
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
if (dv) {
return (USBD_NORMAL_COMPLETION);
- } else {
- tmpdv = dev->subdevs;
- dev->subdevs = NULL;
- free(tmpdv, M_USB);
}
-
+ tmpdv = dev->subdevs;
+ dev->subdevs = NULL;
+ free(tmpdv, M_USB);
DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
@@ -915,10 +916,6 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
printf("%s: port %d, set config at addr %d failed\n",
USBDEVPTRNAME(parent), port, addr);
#endif
-#if defined(__FreeBSD__)
- device_delete_child(parent, bdev);
-#endif
-
return (err);
}
nifaces = dev->cdesc->bNumInterface;
@@ -929,18 +926,11 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
uaa.nifaces = nifaces;
dev->subdevs = malloc((nifaces+1) * sizeof dv, M_USB,M_NOWAIT);
if (dev->subdevs == NULL) {
-#if defined(__FreeBSD__)
- device_delete_child(parent, bdev);
-#endif
return (USBD_NOMEM);
}
dev->ifacenums = malloc((nifaces) * sizeof(*dev->ifacenums),
M_USB,M_NOWAIT);
if (dev->ifacenums == NULL) {
- free(tmpdv, M_USB);
-#if defined(__FreeBSD__)
- device_delete_child(parent, bdev);
-#endif
return (USBD_NOMEM);
}
@@ -953,6 +943,7 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
dev->subdevs[found] = bdev;
dev->subdevs[found + 1] = 0;
dev->ifacenums[found] = i;
+ *uaap = uaa;
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print,
usbd_submatch);
if (dv != NULL) {
@@ -963,11 +954,15 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
/* create another child for the next iface */
bdev = device_add_child(parent, NULL, -1);
if (!bdev) {
- printf("%s: Device creation failed\n",
- USBDEVNAME(dev->bus->bdev));
+ device_printf(parent,
+ "Device add failed\n");
return (USBD_NORMAL_COMPLETION);
}
- device_set_ivars(bdev, &uaa);
+ uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT);
+ if (uaap == NULL) {
+ return (USBD_NOMEM);
+ }
+ device_set_ivars(bdev, uaap);
device_quiet(bdev);
#endif
} else {
@@ -976,8 +971,9 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
}
if (found != 0) {
#if defined(__FreeBSD__)
- /* remove the last created child again; it is unused */
+ /* remove the last created child. It is unused */
device_delete_child(parent, bdev);
+ /* free(uaap, M_USB); */ /* May be needed? xxx */
#endif
return (USBD_NORMAL_COMPLETION);
}
@@ -1000,18 +996,19 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
uaa.configno = UHUB_UNK_CONFIGURATION;
uaa.ifaceno = UHUB_UNK_INTERFACE;
dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
- if (dev->subdevs == 0)
+ if (dev->subdevs == 0) {
return (USBD_NOMEM);
+ }
dev->subdevs[0] = bdev;
dev->subdevs[1] = 0;
+ *uaap = uaa;
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
if (dv != NULL) {
return (USBD_NORMAL_COMPLETION);
- } else {
- tmpdv = dev->subdevs;
- dev->subdevs = 0;
- free(tmpdv, M_USB);
}
+ tmpdv = dev->subdevs;
+ dev->subdevs = 0;
+ free(tmpdv, M_USB);
/*
* The generic attach failed, but leave the device as it is.
@@ -1019,9 +1016,6 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
* fully operational and not harming anyone.
*/
DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
-#if defined(__FreeBSD__)
- device_delete_child(parent, bdev);
-#endif
return (USBD_NORMAL_COMPLETION);
}
OpenPOWER on IntegriCloud