PR#39651
Fix two problems in umass: * usb xfers being freed before being removed from pipe, leading to null deref * config_activate requests not supported, which leads to config_deactivate requests not being passed through. Spotted by jmcneill@ Added mechanism to usbdi allowing the default pipe to be aborted
This commit is contained in:
parent
0107bf153f
commit
beb501f394
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: umass.c,v 1.129 2008/09/06 21:49:00 rmind Exp $ */
|
||||
/* $NetBSD: umass.c,v 1.130 2008/12/12 05:35:11 jmorse Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -124,7 +124,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.129 2008/09/06 21:49:00 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.130 2008/12/12 05:35:11 jmorse Exp $");
|
||||
|
||||
#include "atapibus.h"
|
||||
#include "scsibus.h"
|
||||
|
@ -692,7 +692,11 @@ umass_activate(device_t dev, enum devact act)
|
|||
|
||||
switch (act) {
|
||||
case DVACT_ACTIVATE:
|
||||
rv = EOPNOTSUPP;
|
||||
if (scbus == NULL || scbus->sc_child == NULL)
|
||||
break;
|
||||
rv = config_activate(scbus->sc_child);
|
||||
DPRINTF(UDMASS_USB, ("%s: umass activate: child "
|
||||
"returned %d\n", USBDEVNAME(sc->sc_dev), rv));
|
||||
break;
|
||||
|
||||
case DVACT_DEACTIVATE:
|
||||
|
@ -700,7 +704,7 @@ umass_activate(device_t dev, enum devact act)
|
|||
if (scbus == NULL || scbus->sc_child == NULL)
|
||||
break;
|
||||
rv = config_deactivate(scbus->sc_child);
|
||||
DPRINTF(UDMASS_USB, ("%s: umass_activate: child "
|
||||
DPRINTF(UDMASS_USB, ("%s: umass_deactivate: child "
|
||||
"returned %d\n", USBDEVNAME(sc->sc_dev), rv));
|
||||
break;
|
||||
}
|
||||
|
@ -714,20 +718,24 @@ umass_disco(struct umass_softc *sc)
|
|||
|
||||
DPRINTF(UDMASS_GEN, ("umass_disco\n"));
|
||||
|
||||
/* Remove all the pipes. */
|
||||
for (i = 0 ; i < UMASS_NEP ; i++) {
|
||||
if (sc->sc_pipe[i] != NULL) {
|
||||
usbd_abort_pipe(sc->sc_pipe[i]);
|
||||
usbd_close_pipe(sc->sc_pipe[i]);
|
||||
sc->sc_pipe[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Some xfers may be queued in the default pipe */
|
||||
usbd_abort_default_pipe(sc->sc_udev);
|
||||
|
||||
/* Free the xfers. */
|
||||
for (i = 0; i < XFER_NR; i++)
|
||||
if (sc->transfer_xfer[i] != NULL) {
|
||||
usbd_free_xfer(sc->transfer_xfer[i]);
|
||||
sc->transfer_xfer[i] = NULL;
|
||||
}
|
||||
|
||||
/* Remove all the pipes. */
|
||||
for (i = 0 ; i < UMASS_NEP ; i++) {
|
||||
if (sc->sc_pipe[i] != NULL) {
|
||||
usbd_close_pipe(sc->sc_pipe[i]);
|
||||
sc->sc_pipe[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: usbdi.c,v 1.124 2008/10/11 05:07:20 jmcneill Exp $ */
|
||||
/* $NetBSD: usbdi.c,v 1.125 2008/12/12 05:35:11 jmorse Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.124 2008/10/11 05:07:20 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.125 2008/12/12 05:35:11 jmorse Exp $");
|
||||
|
||||
#include "opt_compat_netbsd.h"
|
||||
|
||||
|
@ -505,6 +505,15 @@ usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index)
|
|||
return (iface->endpoints[index].edesc);
|
||||
}
|
||||
|
||||
/* Some drivers may wish to abort requests on the default pipe, *
|
||||
* but there is no mechanism for getting a handle on it. */
|
||||
usbd_status
|
||||
usbd_abort_default_pipe(struct usbd_device *device)
|
||||
{
|
||||
|
||||
return usbd_abort_pipe(device->default_pipe);
|
||||
}
|
||||
|
||||
usbd_status
|
||||
usbd_abort_pipe(usbd_pipe_handle pipe)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: usbdi.h,v 1.76 2008/04/28 20:24:01 martin Exp $ */
|
||||
/* $NetBSD: usbdi.h,v 1.77 2008/12/12 05:35:11 jmorse Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -112,6 +112,7 @@ void usbd_get_xfer_status(usbd_xfer_handle, usbd_private_handle *,
|
|||
usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor
|
||||
(usbd_interface_handle, u_int8_t);
|
||||
usbd_status usbd_abort_pipe(usbd_pipe_handle);
|
||||
usbd_status usbd_abort_default_pipe(usbd_device_handle);
|
||||
usbd_status usbd_clear_endpoint_stall(usbd_pipe_handle);
|
||||
usbd_status usbd_clear_endpoint_stall_async(usbd_pipe_handle);
|
||||
void usbd_clear_endpoint_toggle(usbd_pipe_handle);
|
||||
|
|
Loading…
Reference in New Issue