PERFORCE change 153941 for review

Weongyo Jeong weongyo at FreeBSD.org
Mon Dec 1 23:27:00 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=153941

Change 153941 by weongyo at weongyo_ws on 2008/12/02 07:26:56

	until now there was a serious problem when the driver try to detach
	like system hangs.  I think this problem is fixed with this commit.
	Changelogs are as follows:
	
	  - the return type of irp_cancelfunc which is a function pointer
	    should be `void' not `int32_t'
	  - always set irp_cancel value as TRUE except we encounter out of
	    memory.  I missed a case not setting it that it was a critical.
	  - at usbd_xfertask() even if USB xfer faced errors notify it to
	    the driver.  In the previous it didn't do it so the driver never
	    knows about it; the driver alwasy tried to wait a signal coming
	    in forever.

Affected files ...

.. //depot/projects/ndisusb/sys/compat/ndis/subr_usbd.c#19 edit

Differences ...

==== //depot/projects/ndisusb/sys/compat/ndis/subr_usbd.c#19 (text+ko) ====

@@ -89,9 +89,9 @@
 			    usbd_status);
 static int32_t		 usbd_iodispatch(device_object *, irp *);
 static int32_t		 usbd_ioinvalid(device_object *, irp *);
-static int32_t		 usbd_irpcancel(device_object *, irp *);
+static void		 usbd_irpcancel(device_object *, irp *);
 static void		 usbd_irpcancel_cb(void *);
-static int32_t		 usbd_irpcancel_iin(device_object *, irp *);
+static void		 usbd_irpcancel_iin(device_object *, irp *);
 static void		 usbd_irpcancel_iin_cb(void *);
 static int32_t		 usbd_submit_urb(irp *);
 static int32_t		 usbd_urb2nt(int32_t);
@@ -616,7 +616,7 @@
 	free(nc, M_USBDEV);
 }
 
-static int32_t
+static void
 usbd_irpcancel_iin(dobj, ip)
 	device_object		*dobj;
 	irp			*ip;
@@ -630,7 +630,7 @@
 	if (nc == NULL) {
 		ip->irp_cancel = FALSE;
 		IoReleaseCancelSpinLock(ip->irp_cancelirql);
-		return (-1);
+		return;
 	}
 
 	nc->dev = dev;
@@ -640,9 +640,8 @@
 	IRP_NDISUSB_XFER(ip) = NULL;
 	usb_add_task(uaa->device, &nc->task, USB_TASKQ_DRIVER);
 
+	ip->irp_cancel = TRUE;
 	IoReleaseCancelSpinLock(ip->irp_cancelirql);
-
-	return (0);
 }
 
 static int32_t
@@ -809,7 +808,7 @@
 	free(nc, M_USBDEV);
 }
 
-static int32_t
+static void
 usbd_irpcancel(dobj, ip)
 	device_object		*dobj;
 	irp			*ip;
@@ -819,8 +818,9 @@
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
 
 	if (IRP_NDISUSB_XFER(ip) == NULL) {
+		ip->irp_cancel = TRUE;
 		IoReleaseCancelSpinLock(ip->irp_cancelirql);
-		return (0);
+		return;
 	}
 
 	/*
@@ -839,7 +839,7 @@
 	if (nc == NULL) {
 		ip->irp_cancel = FALSE;
 		IoReleaseCancelSpinLock(ip->irp_cancelirql);
-		return (-1);
+		return;
 	}
 
 	nc->dev = dev;
@@ -849,9 +849,8 @@
 	IRP_NDISUSB_XFER(ip) = NULL;
 	usb_add_task(uaa->device, &nc->task, USB_TASKQ_DRIVER);
 
+	ip->irp_cancel = TRUE;
 	IoReleaseCancelSpinLock(ip->irp_cancelirql);
-
-	return (0);
 }
 
 static usbd_xfer_handle
@@ -980,12 +979,15 @@
 			}
 			if (status == USBD_STALLED)
 				usbd_clear_endpoint_stall_async(xfer->pipe);
-			if (status != USBD_CANCELLED) {
-				device_printf(dev, "can't process status (%s)\n",
-				    usbd_errstr(status));
-				error = 1;
-				goto next;
-			}
+			/*
+			 * NB: just for notice.  We must handle error cases also
+			 * because if we just return without notifying to the
+			 * NDIS driver the driver never knows about that there
+			 * was a error.  This can cause a lot of problems like
+			 * system hangs.
+			 */
+			device_printf(dev, "usb xfer warning (%s)\n"
+			    usbd_errstr(status));
 		}
 		
 		urb = usbd_geturb(ip);


More information about the p4-projects mailing list