summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/usb_subr.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index 655a4e3..bbb2b78 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#endif
#include <sys/proc.h>
+#include <sys/sysctl.h>
#include <machine/bus.h>
@@ -816,20 +817,27 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
device_ptr_t dv;
device_ptr_t *tmpdv;
usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
+ char *devinfo;
#if defined(__FreeBSD__)
/* XXX FreeBSD may leak resources on failure cases -- fixme */
device_t bdev;
struct usb_attach_arg *uaap;
+ devinfo = malloc(1024, M_USB, M_NOWAIT);
+ if (devinfo == NULL) {
+ device_printf(parent, "Can't allocate memory for probe string\n");
+ return (USBD_NOMEM);
+ }
bdev = device_add_child(parent, NULL, -1);
if (!bdev) {
+ free(devinfo, M_USB);
device_printf(parent, "Device creation failed\n");
return (USBD_INVAL);
}
- device_quiet(bdev);
uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT);
if (uaap == NULL) {
+ free(devinfo, M_USB);
return (USBD_INVAL);
}
device_set_ivars(bdev, uaap);
@@ -851,13 +859,18 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
dev->ifacenums = NULL;
dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
- if (dev->subdevs == NULL)
+ if (dev->subdevs == NULL) {
+ free(devinfo, M_USB);
return (USBD_NOMEM);
+ }
dev->subdevs[0] = bdev;
dev->subdevs[1] = 0;
*uaap = uaa;
+ usbd_devinfo(dev, 1, devinfo);
+ device_set_desc_copy(bdev, devinfo);
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
if (dv) {
+ free(devinfo, M_USB);
return (USBD_NORMAL_COMPLETION);
}
/*
@@ -885,6 +898,7 @@ 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
+ free(devinfo, M_USB);
return (err);
}
nifaces = dev->cdesc->bNumInterface;
@@ -895,11 +909,13 @@ 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) {
+ free(devinfo, M_USB);
return (USBD_NOMEM);
}
dev->ifacenums = malloc((nifaces) * sizeof(*dev->ifacenums),
M_USB,M_NOWAIT);
if (dev->ifacenums == NULL) {
+ free(devinfo, M_USB);
return (USBD_NOMEM);
}
@@ -913,18 +929,20 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
dev->subdevs[found + 1] = 0;
dev->ifacenums[found] = i;
*uaap = uaa;
+ usbd_devinfo(dev, 1, devinfo);
+ device_set_desc_copy(bdev, devinfo);
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print,
usbd_submatch);
if (dv != NULL) {
ifaces[i] = 0; /* consumed */
found++;
-
-#if defined(__FreeBSD__)
+#ifdef __FreeBSD__
/* create another child for the next iface */
bdev = device_add_child(parent, NULL, -1);
if (!bdev) {
device_printf(parent,
"Device add failed\n");
+ free(devinfo, M_USB);
return (USBD_NORMAL_COMPLETION);
}
uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT);
@@ -932,15 +950,16 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
return (USBD_NOMEM);
}
device_set_ivars(bdev, uaap);
- device_quiet(bdev);
#endif
} else {
dev->subdevs[found] = 0;
}
}
+#ifdef __FreeBSD__
if (found != 0) {
-#if defined(__FreeBSD__)
/* remove the last created child. It is unused */
+ free(uaap, M_USB);
+ free(devinfo, M_USB);
device_delete_child(parent, bdev);
/* free(uaap, M_USB); */ /* May be needed? xxx */
#endif
@@ -966,15 +985,17 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
uaa.ifaceno = UHUB_UNK_INTERFACE;
dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
if (dev->subdevs == 0) {
+ free(devinfo, M_USB);
return (USBD_NOMEM);
}
dev->subdevs[0] = bdev;
dev->subdevs[1] = 0;
*uaap = uaa;
+ usbd_devinfo(dev, 1, devinfo);
+ device_set_desc_copy(bdev, devinfo);
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
- if (dv != NULL) {
+ if (dv != NULL)
return (USBD_NORMAL_COMPLETION);
- }
/*
* The generic attach failed, but leave the device as it is.
OpenPOWER on IntegriCloud