PERFORCE change 153880 for review
Weongyo Jeong
weongyo at FreeBSD.org
Mon Dec 1 03:21:10 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=153880
Change 153880 by weongyo at weongyo_ws on 2008/12/01 11:20:36
- fix a panic when IRP cancel is invoked after detaching.
- after returning IRP cancel routine there's no any guarantee that
IRP structure is maintained at memory so we shouldn't pass IRP
pointer.
Affected files ...
.. //depot/projects/ndisusb/sys/compat/ndis/subr_usbd.c#16 edit
.. //depot/projects/ndisusb/sys/compat/ndis/usbd_var.h#4 edit
Differences ...
==== //depot/projects/ndisusb/sys/compat/ndis/subr_usbd.c#16 (text+ko) ====
@@ -48,7 +48,7 @@
#include <sys/socket.h>
#include <machine/bus.h>
#include <sys/bus.h>
-
+#include <sys/ktr.h>
#include <sys/queue.h>
#include <net/if.h>
@@ -603,22 +603,17 @@
void *priv;
{
struct ndisusb_cancel *nc = priv;
- irp *ip = nc->ip;
- device_t dev = IRP_NDIS_DEV(ip);
- struct ndis_softc *sc = device_get_softc(dev);
- struct usb_attach_arg *uaa = device_get_ivars(dev);
+ struct ndis_softc *sc = device_get_softc(nc->dev);
usbd_status status;
- usbd_xfer_handle xfer;
- usb_rem_task(uaa->device, &nc->task);
- free(priv, M_USBDEV);
+ if (sc->ndisusb_status & NDISUSB_STATUS_DETACH)
+ goto exit;
- xfer = IRP_NDISUSB_XFER(ip);
- IRP_NDISUSB_XFER(ip) = NULL;
-
status = usbd_abort_pipe(sc->ndisusb_ep[NDISUSB_ENDPT_IIN]);
if (status != USBD_NORMAL_COMPLETION)
- device_printf(dev, "IIN can't be canceld");
+ device_printf(nc->dev, "IIN can't be canceld");
+exit:
+ free(nc, M_USBDEV);
}
static int32_t
@@ -638,8 +633,11 @@
return (-1);
}
- nc->ip = ip;
+ nc->dev = dev;
+ nc->xfer = IRP_NDISUSB_XFER(ip);
usb_init_task(&nc->task, usbd_irpcancel_iin_cb, nc);
+
+ IRP_NDISUSB_XFER(ip) = NULL;
usb_add_task(uaa->device, &nc->task, USB_TASKQ_DRIVER);
IoReleaseCancelSpinLock(ip->irp_cancelirql);
@@ -797,21 +795,18 @@
void *priv;
{
struct ndisusb_cancel *nc = priv;
- irp *ip = nc->ip;
- device_t dev = IRP_NDIS_DEV(ip);
- struct usb_attach_arg *uaa = device_get_ivars(dev);
+ struct ndis_softc *sc = device_get_softc(nc->dev);
usbd_status status;
- usbd_xfer_handle xfer;
+ usbd_xfer_handle xfer = nc->xfer;
- usb_rem_task(uaa->device, &nc->task);
- free(priv, M_USBDEV);
+ if (sc->ndisusb_status & NDISUSB_STATUS_DETACH)
+ goto exit;
- xfer = IRP_NDISUSB_XFER(ip);
- IRP_NDISUSB_XFER(ip) = NULL;
-
status = usbd_abort_pipe(xfer->pipe);
if (status != USBD_NORMAL_COMPLETION)
- device_printf(dev, "can't be canceld");
+ device_printf(nc->dev, "can't be canceld");
+exit:
+ free(nc, M_USBDEV);
}
static int32_t
@@ -847,8 +842,11 @@
return (-1);
}
- nc->ip = ip;
+ nc->dev = dev;
+ nc->xfer = IRP_NDISUSB_XFER(ip);
usb_init_task(&nc->task, usbd_irpcancel_cb, nc);
+
+ IRP_NDISUSB_XFER(ip) = NULL;
usb_add_task(uaa->device, &nc->task, USB_TASKQ_DRIVER);
IoReleaseCancelSpinLock(ip->irp_cancelirql);
==== //depot/projects/ndisusb/sys/compat/ndis/usbd_var.h#4 (text+ko) ====
@@ -189,8 +189,9 @@
/* used for IRP cancel. */
struct ndisusb_cancel {
+ device_t dev;
+ usbd_xfer_handle xfer;
struct usb_task task;
- irp *ip;
};
extern image_patch_table usbd_functbl[];
More information about the p4-projects
mailing list