Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Dec 2006 10:23:22 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 111621 for review
Message-ID:  <200612131023.kBDANM50031793@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=111621

Change 111621 by hselasky@hselasky_mini_itx on 2006/12/13 10:23:21

	Fix a regression. After this patch it should be possible to do
	kldload-kldunload cycles without having to replug the USB device. 

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb_subr.c#21 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/usb_subr.c#21 (text+ko) ====

@@ -873,6 +873,53 @@
 	return 0;
 }
 
+/* The following function will remove detached 
+ * devices from the interface list. This can
+ * happen during USB device module unload.
+ */
+static void
+usbd_remove_detached_devices(struct usbd_device *udev)
+{
+	device_t *subdev = udev->subdevs;
+	device_t *subdev_end = udev->subdevs_end;
+	uint8_t detached_first = 0;
+
+	PRINTFN(3,("udev=%p\n", udev));
+
+	while (subdev < subdev_end) {
+	    if (subdev[0]) {
+	        if (device_is_attached(subdev[0]) == 0) {
+		    if (device_delete_child(device_get_parent(subdev[0]), 
+					    subdev[0]) == 0) {
+		        subdev[0] = NULL;
+			if (subdev == udev->subdevs) {
+			    detached_first = 1;
+			}
+
+		    } else {
+		        /* Panic here, else one can get a double call to 
+			 * device_detach(). USB devices should never fail
+			 * on detach!
+			 */
+		        panic("device_delete_child() failed!\n");
+		    }
+		}
+	    }
+	    subdev++;
+	}
+
+	if (detached_first) {
+	  if ((udev->probed == USBD_PROBED_SPECIFIC_AND_FOUND) ||
+	      (udev->probed == USBD_PROBED_GENERIC_AND_FOUND)) {
+	      /* The first and only device is gone. 
+	       * Reset the "probed" variable.
+	       */
+	      udev->probed = USBD_PROBED_NOTHING;
+	  }
+	}
+	return;
+}
+
 /* "usbd_probe_and_attach()" is called 
  * from "usbd_new_device()" and "uhub_explore()"
  */
@@ -895,6 +942,8 @@
 		return (USBD_INVAL);
 	}
 
+	usbd_remove_detached_devices(udev);
+
 	bzero(&uaa, sizeof(uaa));
 
 	/* probe and attach */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200612131023.kBDANM50031793>