diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-10-11 18:30:51 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-10-11 18:30:51 +0000 |
commit | cb538c3cbe26e67bac2b85c75da7259a005d264e (patch) | |
tree | 694f7d46090bea822baee9de257c2e4b36c48a69 /sys | |
parent | 34c122070511a878f53978ec92c6f596fa88cc4d (diff) |
serialize usbd_probe_and_attach(); only let one usb device be match'd and
attached at a time; ok kettenis
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/usb_subr.c | 45 | ||||
-rw-r--r-- | sys/dev/usb/usbdi.c | 7 |
2 files changed, 37 insertions, 15 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index c30b6b5c70b..d0245d6f44d 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usb_subr.c,v 1.61 2007/10/06 23:50:55 krw Exp $ */ +/* $OpenBSD: usb_subr.c,v 1.62 2007/10/11 18:30:50 deraadt Exp $ */ /* $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ @@ -46,6 +46,7 @@ #include <sys/device.h> #include <sys/selinfo.h> #include <sys/proc.h> +#include <sys/rwlock.h> #include <machine/bus.h> @@ -833,6 +834,9 @@ usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int port, usbd_status err; struct device *dv; usbd_interface_handle *ifaces; + extern struct rwlock usbpalock; + + rw_enter_write(&usbpalock); uaa.device = dev; uaa.iface = NULL; @@ -847,15 +851,18 @@ usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int port, uaa.release = UGETW(dd->bcdDevice); /* 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 = config_found_sm(parent, &uaa, usbd_print, usbd_submatch); if (dv) { dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); - if (dev->subdevs == NULL) - return (USBD_NOMEM); + if (dev->subdevs == NULL) { + err = USBD_NOMEM; + goto fail; + } dev->subdevs[0] = dv; dev->subdevs[1] = 0; - return (USBD_NORMAL_COMPLETION); + err = USBD_NORMAL_COMPLETION; + goto fail; } DPRINTF(("usbd_probe_and_attach: no device specific driver found\n")); @@ -877,14 +884,16 @@ usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int port, parent->dv_xname, port, addr); #endif - return (err); + goto fail; } nifaces = dev->cdesc->bNumInterface; uaa.configno = dev->cdesc->bConfigurationValue; ifaces = malloc(nifaces * sizeof(usbd_interface_handle), M_USB, M_NOWAIT); - if (ifaces == NULL) - return (USBD_NOMEM); + if (ifaces == NULL) { + err = USBD_NOMEM; + goto fail; + } for (i = 0; i < nifaces; i++) ifaces[i] = &dev->ifaces[i]; uaa.ifaces = ifaces; @@ -893,7 +902,8 @@ usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int port, dev->subdevs = malloc(len, M_USB, M_NOWAIT | M_ZERO); if (dev->subdevs == NULL) { free(ifaces, M_USB); - return (USBD_NOMEM); + err = USBD_NOMEM; + goto fail; } found = 0; @@ -912,7 +922,8 @@ usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int port, } free(ifaces, M_USB); if (found != 0) { - return (USBD_NORMAL_COMPLETION); + err = USBD_NORMAL_COMPLETION; + goto fail; } free(dev->subdevs, M_USB); dev->subdevs = 0; @@ -932,11 +943,14 @@ usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int port, dv = config_found_sm(parent, &uaa, usbd_print, usbd_submatch); if (dv != NULL) { dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); - if (dev->subdevs == 0) - return (USBD_NOMEM); + if (dev->subdevs == 0) { + err = USBD_NOMEM; + goto fail; + } dev->subdevs[0] = dv; dev->subdevs[1] = 0; - return (USBD_NORMAL_COMPLETION); + err = USBD_NORMAL_COMPLETION; + goto fail; } /* @@ -945,7 +959,10 @@ usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int port, * fully operational and not harming anyone. */ DPRINTF(("usbd_probe_and_attach: generic attach failed\n")); - return (USBD_NORMAL_COMPLETION); + err = USBD_NORMAL_COMPLETION; +fail: + rw_exit_write(&usbpalock); + return (err); } diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index 4a8e0e2f1df..eed4a617f61 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usbdi.c,v 1.33 2007/06/18 11:37:04 mbalmer Exp $ */ +/* $OpenBSD: usbdi.c,v 1.34 2007/10/11 18:30:50 deraadt Exp $ */ /* $NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */ @@ -45,6 +45,7 @@ #include <sys/device.h> #include <sys/malloc.h> #include <sys/proc.h> +#include <sys/rwlock.h> #include <machine/bus.h> @@ -72,9 +73,13 @@ usbd_status usbd_open_pipe_ival(usbd_interface_handle, u_int8_t, u_int8_t, int usbd_nbuses = 0; +struct rwlock usbpalock; + void usbd_init(void) { + if (usbd_nbuses == 0) + rw_init(&usbpalock, "usbpalock"); usbd_nbuses++; } |