From 3db4a768d4aa21845af9912117e1b890c69a7760 Mon Sep 17 00:00:00 2001 From: augustss Date: Fri, 16 Nov 2001 01:57:47 +0000 Subject: [PATCH] Handle devices that disappear during reset gracefully. --- sys/dev/usb/uhub.c | 21 +++++++++++++++++++-- sys/dev/usb/usb_subr.c | 7 +++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index 0d79c8198797..7e7a73d57f1c 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhub.c,v 1.53 2001/11/13 06:24:55 lukem Exp $ */ +/* $NetBSD: uhub.c,v 1.54 2001/11/16 01:57:47 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */ /* @@ -43,7 +43,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.53 2001/11/13 06:24:55 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.54 2001/11/16 01:57:47 augustss Exp $"); #include #include @@ -429,6 +429,23 @@ uhub_explore(usbd_device_handle dev) port); continue; } + /* Get port status again, it might have changed during reset */ + err = usbd_get_port_status(dev, port, &up->status); + if (err) { + DPRINTF(("uhub_explore: get port status failed, " + "error=%s\n", usbd_errstr(err))); + continue; + } + status = UGETW(up->status.wPortStatus); + change = UGETW(up->status.wPortChange); + if (!(status & UPS_CURRENT_CONNECT_STATUS)) { + /* Nothing connected, just ignore it. */ +#ifdef DIAGNOSTIC + printf("%s: device disappeared on port %d\n", + USBDEVNAME(sc->sc_dev), port); +#endif + continue; + } /* Get device info and set its address. */ err = usbd_new_device(USBDEV(sc->sc_dev), dev->bus, diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 3eeca4421376..dce284a3f313 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: usb_subr.c,v 1.91 2001/11/13 06:24:56 lukem Exp $ */ +/* $NetBSD: usb_subr.c,v 1.92 2001/11/16 01:57:47 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ /* @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.91 2001/11/13 06:24:56 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.92 2001/11/16 01:57:47 augustss Exp $"); #include #include @@ -354,6 +354,9 @@ usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps) err)); return (err); } + /* If the device disappeared, just give up. */ + if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) + return (USBD_NORMAL_COMPLETION); } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0); if (n == 0) return (USBD_TIMEOUT);