version 1.152.2.1, 2008/05/18 12:34:52 |
version 1.152.2.2, 2008/06/04 02:05:21 |
Line 41 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 41 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/systm.h> |
#include <sys/systm.h> |
#include <sys/kernel.h> |
#include <sys/kernel.h> |
#include <sys/malloc.h> |
#include <sys/malloc.h> |
#if defined(__NetBSD__) || defined(__OpenBSD__) |
|
#include <sys/device.h> |
#include <sys/device.h> |
#include <sys/select.h> |
#include <sys/select.h> |
#elif defined(__FreeBSD__) |
|
#include <sys/module.h> |
|
#include <sys/bus.h> |
|
#endif |
|
#include <sys/proc.h> |
#include <sys/proc.h> |
|
|
#include <sys/bus.h> |
#include <sys/bus.h> |
Line 60 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 55 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <dev/usb/usbdevs.h> |
#include <dev/usb/usbdevs.h> |
#include <dev/usb/usb_quirks.h> |
#include <dev/usb/usb_quirks.h> |
|
|
#if defined(__FreeBSD__) |
|
#include <machine/clock.h> |
|
#define delay(d) DELAY(d) |
|
#endif |
|
|
|
#ifdef USB_DEBUG |
#ifdef USB_DEBUG |
#define DPRINTF(x) if (usbdebug) logprintf x |
#define DPRINTF(x) if (usbdebug) logprintf x |
#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x |
#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x |
Line 81 Static void usbd_devinfo_vp(usbd_device_ |
|
Line 71 Static void usbd_devinfo_vp(usbd_device_ |
|
char *p, int usedev, |
char *p, int usedev, |
int useencoded ); |
int useencoded ); |
Static int usbd_getnewaddr(usbd_bus_handle bus); |
Static int usbd_getnewaddr(usbd_bus_handle bus); |
#if defined(__NetBSD__) |
|
Static int usbd_print(void *, const char *); |
Static int usbd_print(void *, const char *); |
Static int usbd_ifprint(void *, const char *); |
Static int usbd_ifprint(void *, const char *); |
Static int usbd_submatch(device_ptr_t, struct cfdata *, |
|
const int *, void *); |
|
Static int usbd_ifsubmatch(device_ptr_t, struct cfdata *, |
|
const int *, void *); |
|
#elif defined(__OpenBSD__) |
|
Static int usbd_print(void *aux, const char *pnp); |
|
Static int usbd_submatch(device_ptr_t, void *, void *); |
|
#endif |
|
Static void usbd_free_iface_data(usbd_device_handle dev, int ifcno); |
Static void usbd_free_iface_data(usbd_device_handle dev, int ifcno); |
Static void usbd_kill_pipe(usbd_pipe_handle); |
Static void usbd_kill_pipe(usbd_pipe_handle); |
|
usbd_status usbd_attach_roothub(device_t, usbd_device_handle); |
Static usbd_status usbd_probe_and_attach(device_ptr_t parent, |
Static usbd_status usbd_probe_and_attach(device_ptr_t parent, |
usbd_device_handle dev, int port, int addr); |
usbd_device_handle dev, int port, int addr); |
|
|
Line 781 usbd_getnewaddr(usbd_bus_handle bus) |
|
Line 763 usbd_getnewaddr(usbd_bus_handle bus) |
|
return (-1); |
return (-1); |
} |
} |
|
|
|
usbd_status |
|
usbd_attach_roothub(device_t parent, usbd_device_handle dev) |
|
{ |
|
struct usb_attach_arg uaa; |
|
usb_device_descriptor_t *dd = &dev->ddesc; |
|
device_t dv; |
|
|
|
uaa.device = dev; |
|
uaa.usegeneric = 0; |
|
uaa.port = 0; |
|
uaa.vendor = UGETW(dd->idVendor); |
|
uaa.product = UGETW(dd->idProduct); |
|
uaa.release = UGETW(dd->bcdDevice); |
|
uaa.class = dd->bDeviceClass; |
|
uaa.subclass = dd->bDeviceSubClass; |
|
uaa.proto = dd->bDeviceProtocol; |
|
|
|
dv = config_found_ia(parent, "usbroothubif", &uaa, 0); |
|
if (dv) { |
|
dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); |
|
if (dev->subdevs == NULL) |
|
return (USBD_NOMEM); |
|
dev->subdevs[0] = dv; |
|
dev->subdevlen = 1; |
|
} |
|
return (USBD_NORMAL_COMPLETION); |
|
} |
|
|
usbd_status |
usbd_status |
usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev, |
usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev, |
Line 794 usbd_probe_and_attach(device_ptr_t paren |
|
Line 803 usbd_probe_and_attach(device_ptr_t paren |
|
device_ptr_t dv; |
device_ptr_t dv; |
usbd_interface_handle *ifaces; |
usbd_interface_handle *ifaces; |
|
|
#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; |
|
bdev = device_add_child(parent, NULL, -1, &uaa); |
|
if (!bdev) { |
|
printf("%s: Device creation failed\n", USBDEVNAME(dev->bus->bdev)); |
|
return (USBD_INVAL); |
|
} |
|
device_quiet(bdev); |
|
#endif |
|
|
|
uaa.device = dev; |
uaa.device = dev; |
uaa.usegeneric = 0; |
uaa.usegeneric = 0; |
uaa.port = port; |
uaa.port = port; |
Line 820 usbd_probe_and_attach(device_ptr_t paren |
|
Line 815 usbd_probe_and_attach(device_ptr_t paren |
|
|
|
/* First try with device specific drivers. */ |
/* First try with device specific drivers. */ |
DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n")); |
DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n")); |
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch); |
dv = config_found_sm_loc(parent, "usbdevif", NULL, &uaa, usbd_print, |
|
config_stdsubmatch); |
if (dv) { |
if (dv) { |
dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); |
dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); |
if (dev->subdevs == NULL) |
if (dev->subdevs == NULL) |
return (USBD_NOMEM); |
return (USBD_NOMEM); |
dev->subdevs[0] = dv; |
dev->subdevs[0] = dv; |
dev->subdevs[1] = 0; |
dev->subdevlen = 1; |
return (USBD_NORMAL_COMPLETION); |
return (USBD_NORMAL_COMPLETION); |
} |
} |
|
|
Line 854 usbd_probe_and_attach(device_ptr_t paren |
|
Line 850 usbd_probe_and_attach(device_ptr_t paren |
|
printf("%s: port %d, set config at addr %d failed\n", |
printf("%s: port %d, set config at addr %d failed\n", |
USBDEVPTRNAME(parent), port, addr); |
USBDEVPTRNAME(parent), port, addr); |
#endif |
#endif |
#if defined(__FreeBSD__) |
|
device_delete_child(parent, bdev); |
|
#endif |
|
|
|
return (err); |
return (err); |
} |
} |
nifaces = dev->cdesc->bNumInterface; |
nifaces = dev->cdesc->bNumInterface; |
Line 869 usbd_probe_and_attach(device_ptr_t paren |
|
Line 861 usbd_probe_and_attach(device_ptr_t paren |
|
ifaces[i] = &dev->ifaces[i]; |
ifaces[i] = &dev->ifaces[i]; |
uiaa.ifaces = ifaces; |
uiaa.ifaces = ifaces; |
uiaa.nifaces = nifaces; |
uiaa.nifaces = nifaces; |
dev->subdevs = malloc((nifaces+1) * sizeof dv, M_USB,M_NOWAIT); |
dev->subdevs = malloc(nifaces * sizeof dv, M_USB, |
|
M_NOWAIT|M_ZERO); |
if (dev->subdevs == NULL) { |
if (dev->subdevs == NULL) { |
free(ifaces, M_USB); |
free(ifaces, M_USB); |
nomem: |
nomem: |
#if defined(__FreeBSD__) |
|
device_delete_child(parent, bdev); |
|
#endif |
|
return (USBD_NOMEM); |
return (USBD_NOMEM); |
} |
} |
|
dev->subdevlen = nifaces; |
|
|
found = 0; |
found = 0; |
for (i = 0; i < nifaces; i++) { |
for (i = 0; i < nifaces; i++) { |
|
|
uiaa.subclass = ifaces[i]->idesc->bInterfaceSubClass; |
uiaa.subclass = ifaces[i]->idesc->bInterfaceSubClass; |
uiaa.proto = ifaces[i]->idesc->bInterfaceProtocol; |
uiaa.proto = ifaces[i]->idesc->bInterfaceProtocol; |
uiaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; |
uiaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; |
dv = USB_DO_IFATTACH(dev, bdev, parent, &uiaa, usbd_ifprint, |
dv = config_found_sm_loc(parent, "usbifif", NULL, &uiaa, |
usbd_ifsubmatch); |
usbd_ifprint, config_stdsubmatch); |
if (dv != NULL) { |
if (dv != NULL) { |
dev->subdevs[found++] = dv; |
found++; |
dev->subdevs[found] = 0; |
dev->subdevs[i] = dv; |
ifaces[i] = 0; /* consumed */ |
ifaces[i] = 0; /* consumed */ |
|
|
#if defined(__FreeBSD__) |
|
/* create another child for the next iface */ |
|
bdev = device_add_child(parent, NULL, -1,&uaa); |
|
if (!bdev) { |
|
printf("%s: Device creation failed\n", |
|
USBDEVNAME(dev->bus->bdev)); |
|
free(ifaces, M_USB); |
|
return (USBD_NORMAL_COMPLETION); |
|
} |
|
device_quiet(bdev); |
|
#endif |
|
} |
} |
} |
} |
if (found != 0) { |
if (found != 0) { |
#if defined(__FreeBSD__) |
|
/* remove the last created child again; it is unused */ |
|
device_delete_child(parent, bdev); |
|
#endif |
|
free(ifaces, M_USB); |
free(ifaces, M_USB); |
return (USBD_NORMAL_COMPLETION); |
return (USBD_NORMAL_COMPLETION); |
} |
} |
free(ifaces, M_USB); |
free(ifaces, M_USB); |
free(dev->subdevs, M_USB); |
free(dev->subdevs, M_USB); |
dev->subdevs = 0; |
dev->subdevs = 0; |
|
dev->subdevlen = 0; |
} |
} |
/* No interfaces were attached in any of the configurations. */ |
/* No interfaces were attached in any of the configurations. */ |
|
|
|
|
|
|
/* Finally try the generic driver. */ |
/* Finally try the generic driver. */ |
uaa.usegeneric = 1; |
uaa.usegeneric = 1; |
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch); |
dv = config_found_sm_loc(parent, "usbdevif", NULL, &uaa, usbd_print, |
|
config_stdsubmatch); |
if (dv != NULL) { |
if (dv != NULL) { |
dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); |
dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); |
if (dev->subdevs == 0) |
if (dev->subdevs == 0) |
return (USBD_NOMEM); |
return (USBD_NOMEM); |
dev->subdevs[0] = dv; |
dev->subdevs[0] = dv; |
dev->subdevs[1] = 0; |
dev->subdevlen = 1; |
return (USBD_NORMAL_COMPLETION); |
return (USBD_NORMAL_COMPLETION); |
} |
} |
|
|
|
|
* fully operational and not harming anyone. |
* fully operational and not harming anyone. |
*/ |
*/ |
DPRINTF(("usbd_probe_and_attach: generic attach failed\n")); |
DPRINTF(("usbd_probe_and_attach: generic attach failed\n")); |
#if defined(__FreeBSD__) |
|
device_delete_child(parent, bdev); |
|
#endif |
|
return (USBD_NORMAL_COMPLETION); |
return (USBD_NORMAL_COMPLETION); |
} |
} |
|
|
Line 1129 usbd_new_device(device_ptr_t parent, usb |
|
Line 1103 usbd_new_device(device_ptr_t parent, usb |
|
|
|
usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev); |
usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev); |
|
|
|
if (port == 0) { /* root hub */ |
|
KASSERT(addr == 1); |
|
usbd_attach_roothub(parent, dev); |
|
return (USBD_NORMAL_COMPLETION); |
|
} |
|
|
err = usbd_probe_and_attach(parent, dev, port, addr); |
err = usbd_probe_and_attach(parent, dev, port, addr); |
if (err) { |
if (err) { |
usbd_remove_device(dev, up); |
usbd_remove_device(dev, up); |
Line 1167 usbd_remove_device(usbd_device_handle de |
|
Line 1147 usbd_remove_device(usbd_device_handle de |
|
free(dev, M_USB); |
free(dev, M_USB); |
} |
} |
|
|
#if defined(__NetBSD__) || defined(__OpenBSD__) |
|
int |
int |
usbd_print(void *aux, const char *pnp) |
usbd_print(void *aux, const char *pnp) |
{ |
{ |
Line 1184 usbd_print(void *aux, const char *pnp) |
|
Line 1163 usbd_print(void *aux, const char *pnp) |
|
aprint_normal("%s, %s", devinfo, pnp); |
aprint_normal("%s, %s", devinfo, pnp); |
free(devinfo, M_TEMP); |
free(devinfo, M_TEMP); |
} |
} |
if (uaa->port != 0) |
aprint_normal(" port %d", uaa->port); |
aprint_normal(" port %d", uaa->port); |
|
#if 0 |
#if 0 |
/* |
/* |
* It gets very crowded with these locators on the attach line. |
* It gets very crowded with these locators on the attach line. |
Line 1210 usbd_ifprint(void *aux, const char *pnp) |
|
Line 1188 usbd_ifprint(void *aux, const char *pnp) |
|
DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device)); |
DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device)); |
if (pnp) |
if (pnp) |
return (QUIET); |
return (QUIET); |
if (uaa->port != 0) |
aprint_normal(" port %d", uaa->port); |
aprint_normal(" port %d", uaa->port); |
aprint_normal(" configuration %d", uaa->configno); |
if (uaa->configno != UHUB_UNK_CONFIGURATION) |
aprint_normal(" interface %d", uaa->ifaceno); |
aprint_normal(" configuration %d", uaa->configno); |
|
if (uaa->ifaceno != UHUB_UNK_INTERFACE) |
|
aprint_normal(" interface %d", uaa->ifaceno); |
|
#if 0 |
#if 0 |
/* |
/* |
* It gets very crowded with these locators on the attach line. |
* It gets very crowded with these locators on the attach line. |
Line 1232 usbd_ifprint(void *aux, const char *pnp) |
|
Line 1207 usbd_ifprint(void *aux, const char *pnp) |
|
return (UNCONF); |
return (UNCONF); |
} |
} |
|
|
#if defined(__NetBSD__) |
|
int |
|
usbd_submatch(struct device *parent, struct cfdata *cf, |
|
const int *ldesc, void *aux) |
|
{ |
|
#elif defined(__OpenBSD__) |
|
int |
|
usbd_submatch(struct device *parent, void *match, void *aux) |
|
{ |
|
struct cfdata *cf = match; |
|
#endif |
|
struct usb_attach_arg *uaa = aux; |
|
|
|
DPRINTFN(5,("usbd_submatch port=%d,%d " |
|
"vendor=%d,%d product=%d,%d release=%d,%d\n", |
|
uaa->port, cf->uhubcf_port, |
|
uaa->vendor, cf->uhubcf_vendor, |
|
uaa->product, cf->uhubcf_product, |
|
uaa->release, cf->uhubcf_release)); |
|
if (uaa->port != 0 && /* root hub has port 0, it should match */ |
|
((cf->uhubcf_port != UHUB_UNK_PORT && |
|
cf->uhubcf_port != uaa->port) || |
|
(uaa->vendor != UHUB_UNK_VENDOR && |
|
cf->uhubcf_vendor != UHUB_UNK_VENDOR && |
|
cf->uhubcf_vendor != uaa->vendor) || |
|
(uaa->product != UHUB_UNK_PRODUCT && |
|
cf->uhubcf_product != UHUB_UNK_PRODUCT && |
|
cf->uhubcf_product != uaa->product) || |
|
(uaa->release != UHUB_UNK_RELEASE && |
|
cf->uhubcf_release != UHUB_UNK_RELEASE && |
|
cf->uhubcf_release != uaa->release) |
|
) |
|
) |
|
return 0; |
|
return (config_match(parent, cf, aux)); |
|
} |
|
|
|
int |
|
usbd_ifsubmatch(struct device *parent, struct cfdata *cf, |
|
const int *ldesc, void *aux) |
|
{ |
|
struct usbif_attach_arg *uaa = aux; |
|
|
|
DPRINTFN(5,("usbd_submatch port=%d,%d configno=%d,%d " |
|
"ifaceno=%d,%d vendor=%d,%d product=%d,%d release=%d,%d\n", |
|
uaa->port, cf->uhubcf_port, |
|
uaa->configno, cf->uhubcf_configuration, |
|
uaa->ifaceno, cf->uhubcf_interface, |
|
uaa->vendor, cf->uhubcf_vendor, |
|
uaa->product, cf->uhubcf_product, |
|
uaa->release, cf->uhubcf_release)); |
|
if (uaa->port != 0 && /* root hub has port 0, it should match */ |
|
((cf->uhubcf_port != UHUB_UNK_PORT && |
|
cf->uhubcf_port != uaa->port) || |
|
(uaa->configno != UHUB_UNK_CONFIGURATION && |
|
cf->uhubcf_configuration != UHUB_UNK_CONFIGURATION && |
|
cf->uhubcf_configuration != uaa->configno) || |
|
(uaa->ifaceno != UHUB_UNK_INTERFACE && |
|
cf->uhubcf_interface != UHUB_UNK_INTERFACE && |
|
cf->uhubcf_interface != uaa->ifaceno) || |
|
(uaa->vendor != UHUB_UNK_VENDOR && |
|
cf->uhubcf_vendor != UHUB_UNK_VENDOR && |
|
cf->uhubcf_vendor != uaa->vendor) || |
|
(uaa->product != UHUB_UNK_PRODUCT && |
|
cf->uhubcf_product != UHUB_UNK_PRODUCT && |
|
cf->uhubcf_product != uaa->product) || |
|
(uaa->release != UHUB_UNK_RELEASE && |
|
cf->uhubcf_release != UHUB_UNK_RELEASE && |
|
cf->uhubcf_release != uaa->release) |
|
) |
|
) |
|
return 0; |
|
return (config_match(parent, cf, aux)); |
|
} |
|
|
|
#endif |
|
|
|
void |
void |
usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di, |
usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di, |
int usedev) |
int usedev) |
{ |
{ |
struct usbd_port *p; |
struct usbd_port *p; |
int i, err, s; |
int i, j, err, s; |
|
|
di->udi_bus = device_unit(dev->bus->usbctl); |
di->udi_bus = device_unit(dev->bus->usbctl); |
di->udi_addr = dev->address; |
di->udi_addr = dev->address; |
Line 1336 usbd_fill_deviceinfo(usbd_device_handle |
|
Line 1234 usbd_fill_deviceinfo(usbd_device_handle |
|
di->udi_power = dev->self_powered ? 0 : dev->power; |
di->udi_power = dev->self_powered ? 0 : dev->power; |
di->udi_speed = dev->speed; |
di->udi_speed = dev->speed; |
|
|
if (dev->subdevs != NULL) { |
if (dev->subdevlen > 0) { |
for (i = 0; dev->subdevs[i] && |
for (i = 0, j = 0; i < dev->subdevlen && |
i < USB_MAX_DEVNAMES; i++) { |
j < USB_MAX_DEVNAMES; i++) { |
strncpy(di->udi_devnames[i], USBDEVPTRNAME(dev->subdevs[i]), |
if (!dev->subdevs[i]) |
|
continue; |
|
strncpy(di->udi_devnames[j], USBDEVPTRNAME(dev->subdevs[i]), |
USB_MAX_DEVNAMELEN); |
USB_MAX_DEVNAMELEN); |
di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0'; |
di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0'; |
|
j++; |
} |
} |
} else { |
} else { |
i = 0; |
j = 0; |
} |
} |
for (/*i is set */; i < USB_MAX_DEVNAMES; i++) |
for (/* j is set */; j < USB_MAX_DEVNAMES; j++) |
di->udi_devnames[i][0] = 0; /* empty */ |
di->udi_devnames[j][0] = 0; /* empty */ |
|
|
if (dev->hub) { |
if (dev->hub) { |
for (i = 0; |
for (i = 0; |
Line 1381 usbd_fill_deviceinfo_old(usbd_device_han |
|
Line 1282 usbd_fill_deviceinfo_old(usbd_device_han |
|
int usedev) |
int usedev) |
{ |
{ |
struct usbd_port *p; |
struct usbd_port *p; |
int i, err, s; |
int i, j, err, s; |
|
|
di->udi_bus = device_unit(dev->bus->usbctl); |
di->udi_bus = device_unit(dev->bus->usbctl); |
di->udi_addr = dev->address; |
di->udi_addr = dev->address; |
Line 1399 usbd_fill_deviceinfo_old(usbd_device_han |
|
Line 1300 usbd_fill_deviceinfo_old(usbd_device_han |
|
di->udi_power = dev->self_powered ? 0 : dev->power; |
di->udi_power = dev->self_powered ? 0 : dev->power; |
di->udi_speed = dev->speed; |
di->udi_speed = dev->speed; |
|
|
if (dev->subdevs != NULL) { |
if (dev->subdevlen > 0) { |
for (i = 0; dev->subdevs[i] && |
for (i = 0, j = 0; i < dev->subdevlen && |
i < USB_MAX_DEVNAMES; i++) { |
j < USB_MAX_DEVNAMES; i++) { |
strncpy(di->udi_devnames[i], USBDEVPTRNAME(dev->subdevs[i]), |
if (!dev->subdevs[i]) |
|
continue; |
|
strncpy(di->udi_devnames[j], USBDEVPTRNAME(dev->subdevs[i]), |
USB_MAX_DEVNAMELEN); |
USB_MAX_DEVNAMELEN); |
di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0'; |
di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0'; |
|
j++; |
} |
} |
} else { |
} else { |
i = 0; |
j = 0; |
} |
} |
for (/*i is set */; i < USB_MAX_DEVNAMES; i++) |
for (/* j is set */; j < USB_MAX_DEVNAMES; j++) |
di->udi_devnames[i][0] = 0; /* empty */ |
di->udi_devnames[j][0] = 0; /* empty */ |
|
|
if (dev->hub) { |
if (dev->hub) { |
for (i = 0; |
for (i = 0; |
Line 1455 usb_free_device(usbd_device_handle dev) |
|
Line 1359 usb_free_device(usbd_device_handle dev) |
|
} |
} |
if (dev->cdesc != NULL) |
if (dev->cdesc != NULL) |
free(dev->cdesc, M_USB); |
free(dev->cdesc, M_USB); |
if (dev->subdevs != NULL) |
if (dev->subdevlen > 0) { |
free(dev->subdevs, M_USB); |
free(dev->subdevs, M_USB); |
|
dev->subdevlen = 0; |
|
} |
free(dev, M_USB); |
free(dev, M_USB); |
} |
} |
|
|
Line 1494 usb_disconnect_port(struct usbd_port *up |
|
Line 1400 usb_disconnect_port(struct usbd_port *up |
|
} |
} |
#endif |
#endif |
|
|
if (dev->subdevs != NULL) { |
if (dev->subdevlen > 0) { |
DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n")); |
DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n")); |
for (i = 0; dev->subdevs[i]; i++) { |
for (i = 0; i < dev->subdevlen; i++) { |
|
if (!dev->subdevs[i]) |
|
continue; |
printf("%s: at %s", USBDEVPTRNAME(dev->subdevs[i]), |
printf("%s: at %s", USBDEVPTRNAME(dev->subdevs[i]), |
hubname); |
hubname); |
if (up->portno != 0) |
if (up->portno != 0) |
Line 1511 usb_disconnect_port(struct usbd_port *up |
|
Line 1419 usb_disconnect_port(struct usbd_port *up |
|
up->device = NULL; |
up->device = NULL; |
usb_free_device(dev); |
usb_free_device(dev); |
} |
} |
|
|
#ifdef __OpenBSD__ |
|
void *usb_realloc(void *p, u_int size, int pool, int flags) |
|
{ |
|
void *q; |
|
|
|
q = malloc(size, pool, flags); |
|
if (q == NULL) |
|
return (NULL); |
|
bcopy(p, q, size); |
|
free(p, pool); |
|
return (q); |
|
} |
|
#endif |
|