PERFORCE change 154848 for review
Weongyo Jeong
weongyo at FreeBSD.org
Tue Dec 16 20:35:32 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=154848
Change 154848 by weongyo at weongyo_ws on 2008/12/17 04:35:04
fix a page fault that it occured at ZD1211B USB adapter.
Affected files ...
.. //depot/projects/ndisusb/sys/compat/ndis/subr_usbd.c#25 edit
Differences ...
==== //depot/projects/ndisusb/sys/compat/ndis/subr_usbd.c#25 (text+ko) ====
@@ -115,6 +115,8 @@
static usb_interface_descriptor_t *USBD_ParseConfigurationDescriptor(
usb_config_descriptor_t *, uint8_t, uint8_t);
+#define USBD_STATUS_IIN_ERROR 0x1
+static int usbd_iin_error;
/*
* We need to wrap these functions because these need `context switch' from
* Windows to UNIX before it's called.
@@ -931,8 +933,34 @@
usbd_private_handle priv;
usbd_status status;
{
+ int set = 0;
+
+ /*
+ * We should handle the interrupt IN pipe specially. For a example,
+ * ZD1211B NDIS driver uses the interrupt IN pipe so we opens its pipe
+ * using usbd_open_pipe_intr(). In a case of we forcibly plug out
+ * the ZD1211B USB adapter then firstly usbd_open_pipe_intr() calls our
+ * callback function whose the value of the status is USBD_IOERROR.
+ * As a next return, sometimes it returns USBD_CANCELLED. The problem
+ * is that at this case when we get USBD_IOERROR status we try to free
+ * IRP related with the interrupt IN pipe. As next if we get
+ * USBD_CANCELLED, in the previous we tried to free again so it causes
+ * a page fault. I don't know why the USB framework reports errors
+ * twice. To solve this problem we only handle first error.
+ *
+ * XXX I don't want to use a global variable and don't like this like
+ * a hack but no way to pass `sc' safely because `priv' can be a pointer
+ * which already be freed.
+ */
+ if (status == USBD_NORMAL_COMPLETION)
+ usbd_iin_error &= ~USBD_STATUS_IIN_ERROR;
+ if (status == USBD_IOERROR) {
+ usbd_iin_error |= USBD_STATUS_IIN_ERROR;
+ set = 1;
+ }
- usbd_xferadd(xfer, priv, status, 0);
+ if ((!(usbd_iin_error & USBD_STATUS_IIN_ERROR)) || set == 1)
+ usbd_xferadd(xfer, priv, status, 0);
}
static void
More information about the p4-projects
mailing list