svn commit: r214429 - head/sys/dev/usb

Hans Petter Selasky hselasky at FreeBSD.org
Wed Oct 27 17:38:06 UTC 2010


Author: hselasky
Date: Wed Oct 27 17:38:05 2010
New Revision: 214429
URL: http://svn.freebsd.org/changeset/base/214429

Log:
  Add support for setting per-interface PnP information.
  
  Submitted by:	Nick Hibma
  Approved by:	thompsa (mentor)

Modified:
  head/sys/dev/usb/usb_device.c
  head/sys/dev/usb/usb_hub.c
  head/sys/dev/usb/usbdi.h

Modified: head/sys/dev/usb/usb_device.c
==============================================================================
--- head/sys/dev/usb/usb_device.c	Wed Oct 27 17:20:19 2010	(r214428)
+++ head/sys/dev/usb/usb_device.c	Wed Oct 27 17:38:05 2010	(r214429)
@@ -88,7 +88,7 @@ static void	usb_init_endpoint(struct usb
 		    struct usb_endpoint *);
 static void	usb_unconfigure(struct usb_device *, uint8_t);
 static void	usb_detach_device_sub(struct usb_device *, device_t *,
-		    uint8_t);
+		    char **, uint8_t);
 static uint8_t	usb_probe_and_attach_sub(struct usb_device *,
 		    struct usb_attach_arg *);
 static void	usb_init_attach_arg(struct usb_device *,
@@ -1035,9 +1035,10 @@ usb_reset_iface_endpoints(struct usb_dev
  *------------------------------------------------------------------------*/
 static void
 usb_detach_device_sub(struct usb_device *udev, device_t *ppdev,
-    uint8_t flag)
+    char **ppnpinfo, uint8_t flag)
 {
 	device_t dev;
+	char *pnpinfo;
 	int err;
 
 	dev = *ppdev;
@@ -1069,11 +1070,17 @@ usb_detach_device_sub(struct usb_device 
 			goto error;
 		}
 	}
+
+	pnpinfo = *ppnpinfo;
+	if (pnpinfo != NULL) {
+		*ppnpinfo = NULL;
+		free(pnpinfo, M_USBDEV);
+	}
 	return;
 
 error:
 	/* Detach is not allowed to fail in the USB world */
-	panic("A USB driver would not detach\n");
+	panic("usb_detach_device_sub: A USB driver would not detach\n");
 }
 
 /*------------------------------------------------------------------------*
@@ -1122,7 +1129,8 @@ usb_detach_device(struct usb_device *ude
 			/* looks like the end of the USB interfaces */
 			break;
 		}
-		usb_detach_device_sub(udev, &iface->subdev, flag);
+		usb_detach_device_sub(udev, &iface->subdev,
+		    &iface->pnpinfo, flag);
 	}
 }
 
@@ -2714,3 +2722,37 @@ usbd_enum_is_locked(struct usb_device *u
 {
 	return (sx_xlocked(&udev->enum_sx));
 }
+
+/*
+ * The following function is used to set the per-interface specific
+ * plug and play information. The string referred to by the pnpinfo
+ * argument can safely be freed after calling this function. The
+ * pnpinfo of an interface will be reset at device detach or when
+ * passing a NULL argument to this function. This function
+ * returns zero on success, else a USB_ERR_XXX failure code.
+ */
+
+usb_error_t 
+usbd_set_pnpinfo(struct usb_device *udev, uint8_t iface_index, const char *pnpinfo)
+{
+	struct usb_interface *iface;
+
+	iface = usbd_get_iface(udev, iface_index);
+	if (iface == NULL)
+		return (USB_ERR_INVAL);
+
+	if (iface->pnpinfo != NULL) {
+		free(iface->pnpinfo, M_USBDEV);
+		iface->pnpinfo = NULL;
+	}
+
+	if (pnpinfo == NULL || pnpinfo[0] == 0)
+		return (0);		/* success */
+
+	iface->pnpinfo = strdup(pnpinfo, M_USBDEV);
+	if (iface->pnpinfo == NULL)
+		return (USB_ERR_NOMEM);
+
+	return (0);			/* success */
+}
+

Modified: head/sys/dev/usb/usb_hub.c
==============================================================================
--- head/sys/dev/usb/usb_hub.c	Wed Oct 27 17:20:19 2010	(r214428)
+++ head/sys/dev/usb/usb_hub.c	Wed Oct 27 17:38:05 2010	(r214429)
@@ -1330,7 +1330,7 @@ uhub_child_pnpinfo_string(device_t paren
 		    "devclass=0x%02x devsubclass=0x%02x "
 		    "sernum=\"%s\" "
 		    "release=0x%04x "
-		    "intclass=0x%02x intsubclass=0x%02x",
+		    "intclass=0x%02x intsubclass=0x%02x" "%s%s",
 		    UGETW(res.udev->ddesc.idVendor),
 		    UGETW(res.udev->ddesc.idProduct),
 		    res.udev->ddesc.bDeviceClass,
@@ -1338,7 +1338,9 @@ uhub_child_pnpinfo_string(device_t paren
 		    usb_get_serial(res.udev),
 		    UGETW(res.udev->ddesc.bcdDevice),
 		    iface->idesc->bInterfaceClass,
-		    iface->idesc->bInterfaceSubClass);
+		    iface->idesc->bInterfaceSubClass,
+		    iface->pnpinfo ? " " : "",
+		    iface->pnpinfo ? iface->pnpinfo : "");
 	} else {
 		if (buflen) {
 			buf[0] = '\0';

Modified: head/sys/dev/usb/usbdi.h
==============================================================================
--- head/sys/dev/usb/usbdi.h	Wed Oct 27 17:20:19 2010	(r214428)
+++ head/sys/dev/usb/usbdi.h	Wed Oct 27 17:38:05 2010	(r214429)
@@ -171,6 +171,7 @@ struct usb_interface {
 	struct usb_host_interface *cur_altsetting;
 	struct usb_device *linux_udev;
 	void   *bsd_priv_sc;		/* device specific information */
+	char   *pnpinfo;		/* additional PnP-info for this interface */
 	uint8_t	num_altsetting;		/* number of alternate settings */
 	uint8_t	bsd_iface_index;
 };
@@ -444,6 +445,8 @@ enum usb_hc_mode usbd_get_mode(struct us
 enum usb_dev_speed usbd_get_speed(struct usb_device *udev);
 void	device_set_usb_desc(device_t dev);
 void	usb_pause_mtx(struct mtx *mtx, int _ticks);
+usb_error_t	usbd_set_pnpinfo(struct usb_device *udev,
+			uint8_t iface_index, const char *pnpinfo);
 
 const struct usb_device_id *usbd_lookup_id_by_info(
 	    const struct usb_device_id *id, usb_size_t sizeof_id,


More information about the svn-src-all mailing list