FreeBSD Bugzilla – Attachment 65686 Details for
Bug 97271
Fix Multiple ugen panics
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
ugen-multiple-panics.patch
ugen-multiple-panics.patch (text/plain), 5.71 KB, created by
amistry
on 2006-05-14 21:20:27 UTC
(
hide
)
Description:
ugen-multiple-panics.patch
Filename:
MIME Type:
Creator:
amistry
Created:
2006-05-14 21:20:27 UTC
Size:
5.71 KB
patch
obsolete
>--- /sys/dev/usb/ugen.c.orig Thu Dec 15 16:57:32 2005 >+++ /sys/dev/usb/ugen.c Tue May 9 12:16:28 2006 >@@ -1,4 +1,4 @@ >-/* $NetBSD: ugen.c,v 1.59 2002/07/11 21:14:28 augustss Exp $ */ >+/* $NetBSD: ugen.c,v 1.79 2006/03/01 12:38:13 yamt Exp $ */ > > /* Also already merged from NetBSD: > * $NetBSD: ugen.c,v 1.61 2002/09/23 05:51:20 simonb Exp $ >@@ -284,6 +284,9 @@ > ugen_make_devnodes(sc); > #endif > >+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, >+ USBDEV(sc->sc_dev)); >+ > USB_ATTACH_SUCCESS_RETURN; > } > >@@ -383,6 +386,7 @@ > M_WAITOK); > niface_cache = niface; > >+ memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints); > for (ifaceno = 0; ifaceno < niface; ifaceno++) { > DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); > err = usbd_device2interface_handle(dev, ifaceno, &iface); >@@ -511,7 +515,7 @@ > for (dir = OUT; dir <= IN; dir++) { > if (flag & (dir == OUT ? FWRITE : FREAD)) { > sce = &sc->sc_endpoints[endpt][dir]; >- if (sce->edesc == 0) >+ if (sce == 0 ||sce->edesc == 0) > return (ENXIO); > } > } >@@ -650,7 +654,7 @@ > if (!(flag & (dir == OUT ? FWRITE : FREAD))) > continue; > sce = &sc->sc_endpoints[endpt][dir]; >- if (sce->pipeh == NULL) >+ if (sce == NULL || sce->pipeh == NULL) > continue; > DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n", > endpt, dir, sce)); >@@ -835,6 +839,9 @@ > > USB_GET_SC(ugen, UGENUNIT(dev), sc); > >+ if(sc->sc_dying) >+ return (EIO); >+ > UGEN_DEV_REF(dev, sc); > error = ugen_do_read(sc, endpt, uio, flag); > UGEN_DEV_RELE(dev, sc); >@@ -933,6 +940,9 @@ > > USB_GET_SC(ugen, UGENUNIT(dev), sc); > >+ if (sc->sc_dying) >+ return (EIO); >+ > UGEN_DEV_REF(dev, sc); > error = ugen_do_write(sc, endpt, uio, flag); > UGEN_DEV_RELE(dev, sc); >@@ -969,8 +979,31 @@ > return; > USB_GET_SC(ugen, UGENUNIT(dev), sc); > sce = &sc->sc_endpoints[endpt][IN]; >- if (sce->pipeh) >- usbd_abort_pipe(sce->pipeh); >+ if (sce) >+ { >+ if(sce->pipeh) >+ usbd_abort_pipe(sce->pipeh); >+ >+ if (sce->state & UGEN_ASLP) { >+ sce->state &= ~UGEN_ASLP; >+ DPRINTFN(5, ("ugenpurge: waking %p\n", sce)); >+ wakeup(sce); >+ } >+ selwakeuppri(&sce->rsel, PZERO); >+ } >+ sce = &sc->sc_endpoints[endpt][OUT]; >+ if (sce) >+ { >+ if(sce->pipeh) >+ usbd_abort_pipe(sce->pipeh); >+ >+ if (sce->state & UGEN_ASLP) { >+ sce->state &= ~UGEN_ASLP; >+ DPRINTFN(5, ("ugenpurge: waking %p\n", sce)); >+ wakeup(sce); >+ } >+ selwakeuppri(&sce->rsel, PZERO); >+ } > } > #endif > >@@ -994,11 +1027,13 @@ > for (i = 0; i < USB_MAX_ENDPOINTS; i++) { > for (dir = OUT; dir <= IN; dir++) { > sce = &sc->sc_endpoints[i][dir]; >- if (sce->pipeh) >+ if (sce && sce->pipeh) > usbd_abort_pipe(sce->pipeh); >+ selwakeuppri(&sce->rsel, PZERO); > } > } > >+ > #if defined(__NetBSD__) || defined(__OpenBSD__) > s = splusb(); > if (sc->sc_refcnt > 0) { >@@ -1035,6 +1070,9 @@ > destroy_dev(sc->dev); > #endif > >+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, >+ USBDEV(sc->sc_dev)); >+ > return (0); > } > >@@ -1292,7 +1330,7 @@ > /* This flag only affects read */ > sce = &sc->sc_endpoints[endpt][IN]; > >- if (sce->pipeh == NULL) { >+ if (sce == NULL || sce->pipeh == NULL) { > printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n"); > return (EIO); > } >@@ -1304,6 +1342,12 @@ > return (0); > case USB_SET_TIMEOUT: > sce = &sc->sc_endpoints[endpt][IN]; >+ if (sce == NULL >+ /* XXX this shouldn't happen, but the distinction between >+ input and output pipes isn't clear enough. >+ || sce->pipeh == NULL */ >+ ) >+ return (EINVAL); > sce->timeout = *(int *)addr; > return (0); > default: >@@ -1331,9 +1375,6 @@ > err = ugen_set_config(sc, *(int *)addr); > switch (err) { > case USBD_NORMAL_COMPLETION: >-#if defined(__FreeBSD__) >- ugen_make_devnodes(sc); >-#endif > break; > case USBD_IN_USE: > return (EBUSY); >@@ -1541,6 +1582,9 @@ > > USB_GET_SC(ugen, UGENUNIT(dev), sc); > >+ if (sc->sc_dying) >+ return (EIO); >+ > UGEN_DEV_REF(dev, sc); > error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p); > UGEN_DEV_RELE(dev, sc); >@@ -1555,14 +1599,32 @@ > int revents = 0; > int s; > >+ /* Do not allow to poll a control endpoint */ >+ if ( UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT ) >+ return (EIO); >+ > USB_GET_SC(ugen, UGENUNIT(dev), sc); > > if (sc->sc_dying) > return (EIO); > >- /* XXX always IN */ >- sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; >-#ifdef DIAGNOSTIC >+ if((events & POLLIN) && (events & POLLOUT)) { >+ printf("ugenpoll: POLLIN and POLLOUT? We're not handling it, so bail.\n"); >+ return (EIO); >+ } >+ >+ if(events & (POLLIN | POLLRDNORM)) >+ sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; >+ else if(events & (POLLOUT | POLLWRNORM)) >+ sce = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT]; >+ else { >+ printf("ugenpoll: unhandled input event\n"); >+ return (EIO); >+ } >+ >+ if (sce == NULL) >+ return (EIO); >+ > if (!sce->edesc) { > printf("ugenpoll: no edesc\n"); > return (EIO); >@@ -1571,23 +1633,26 @@ > printf("ugenpoll: no pipe\n"); > return (EIO); > } >-#endif > s = splusb(); > switch (sce->edesc->bmAttributes & UE_XFERTYPE) { > case UE_INTERRUPT: >- if (events & (POLLIN | POLLRDNORM)) { >- if (sce->q.c_cc > 0) >+ if (sce->q.c_cc > 0) { >+ if (events & (POLLIN | POLLRDNORM)) > revents |= events & (POLLIN | POLLRDNORM); >- else >- selrecord(p, &sce->rsel); >+ else if (events & (POLLOUT | POLLWRNORM)) >+ revents |= events & (POLLOUT | POLLWRNORM); >+ } else { >+ selrecord(p, &sce->rsel); > } > break; > case UE_ISOCHRONOUS: >- if (events & (POLLIN | POLLRDNORM)) { >- if (sce->cur != sce->fill) >+ if (sce->cur != sce->fill) { >+ if (events & (POLLIN | POLLRDNORM)) > revents |= events & (POLLIN | POLLRDNORM); >- else >- selrecord(p, &sce->rsel); >+ else if (events & (POLLOUT | POLLWRNORM)) >+ revents |= events & (POLLOUT | POLLWRNORM); >+ } else { >+ selrecord(p, &sce->rsel); > } > break; > case UE_BULK:
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 97271
: 65686