Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 8 Dec 2007 10:29:59 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 130482 for review
Message-ID:  <200712081029.lB8ATxfx026109@repoman.freebsd.org>

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

Change 130482 by hselasky@hselasky_laptop001 on 2007/12/08 10:29:20

	
	This commit is related to USB device side support.
	
	o Move "struct usb_temp_setup" into "usb_subr.h" .
	o The scratch field in "struct usbd_device" is now a union.
	o Added global functions to "usb_template.c" that are used
	  for entry points to building and accessing USB descriptors.
	o Added "usb_template.c" to "conf/files" and the USB module.

Affected files ...

.. //depot/projects/usb/src/sys/conf/files#20 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.c#68 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#67 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_template.c#2 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_template.h#3 edit
.. //depot/projects/usb/src/sys/modules/usb/Makefile#4 edit

Differences ...

==== //depot/projects/usb/src/sys/conf/files#20 (text+ko) ====

@@ -1145,6 +1145,7 @@
 dev/usb/usb_quirks.c		optional usb
 dev/usb/usb_requests.c		optional usb
 dev/usb/usb_subr.c		optional usb
+dev/usb/usb_template.c		optional usb
 dev/usb/usb_transfer.c		optional usb
 dev/usb/usb_compat_linux.c	optional usb
 dev/usb/uscanner.c		optional uscanner

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

@@ -1507,24 +1507,24 @@
 
 	/* get serial number string */
 	err = usbreq_get_string_any
-	    (udev, &usb_global_lock, udev->scratch, sizeof(udev->scratch),
-	    udev->ddesc.iSerialNumber);
+	    (udev, &usb_global_lock, udev->scratch[0].data,
+	    sizeof(udev->scratch), udev->ddesc.iSerialNumber);
 
-	strlcpy(udev->serial, udev->scratch, sizeof(udev->serial));
+	strlcpy(udev->serial, udev->scratch[0].data, sizeof(udev->serial));
 
 	/* get manufacturer string */
 	err = usbreq_get_string_any
-	    (udev, &usb_global_lock, udev->scratch, sizeof(udev->scratch),
-	    udev->ddesc.iManufacturer);
+	    (udev, &usb_global_lock, udev->scratch[0].data,
+	    sizeof(udev->scratch), udev->ddesc.iManufacturer);
 
-	strlcpy(udev->manufacturer, udev->scratch, sizeof(udev->manufacturer));
+	strlcpy(udev->manufacturer, udev->scratch[0].data, sizeof(udev->manufacturer));
 
 	/* get product string */
 	err = usbreq_get_string_any
-	    (udev, &usb_global_lock, udev->scratch, sizeof(udev->scratch),
-	    udev->ddesc.iProduct);
+	    (udev, &usb_global_lock, udev->scratch[0].data,
+	    sizeof(udev->scratch), udev->ddesc.iProduct);
 
-	strlcpy(udev->product, udev->scratch, sizeof(udev->product));
+	strlcpy(udev->product, udev->scratch[0].data, sizeof(udev->product));
 
 	/* finish up all the strings */
 	usbd_finish_vp_info(udev);
@@ -1655,6 +1655,8 @@
 	}
 	usbd_transfer_unsetup(udev->default_xfer, 1);
 
+	usbd_temp_unsetup(udev);
+
 	sx_destroy(udev->default_sx);
 
 	mtx_destroy(udev->default_mtx);
@@ -1740,9 +1742,9 @@
 void
 usbd_set_desc(device_t dev, struct usbd_device *udev)
 {
-	usbd_devinfo(udev, udev->scratch, sizeof(udev->scratch));
-	device_set_desc_copy(dev, udev->scratch);
-	device_printf(dev, "<%s> on %s\n", udev->scratch,
+	usbd_devinfo(udev, udev->scratch[0].data, sizeof(udev->scratch));
+	device_set_desc_copy(dev, udev->scratch[0].data);
+	device_printf(dev, "<%s> on %s\n", udev->scratch[0].data,
 	    device_get_nameunit(udev->bus->bdev));
 	return;
 }

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

@@ -101,7 +101,9 @@
 struct usbd_std_root_transfer;
 struct usbd_setup_params;
 struct usbd_ifqueue;
+struct usbd_temp_setup;
 struct usb_callout;
+struct usb_temp_device_desc;
 struct module;
 struct malloc_type;
 struct proc;
@@ -114,6 +116,8 @@
 
 typedef void (usbd_std_root_transfer_func_t)(struct usbd_xfer *, struct usbd_std_root_transfer *);
 
+typedef const uint8_t *(usbd_temp_get_desc_t)(struct usbd_device *udev, uint16_t langid, uint8_t type, uint8_t index);
+
 /* USB modes */
 
 enum {
@@ -131,6 +135,18 @@
 	USBD_STD_ROOT_TR_PRE_CALLBACK,
 };
 
+struct usbd_temp_setup {
+	void   *buf;
+	uint32_t size;
+	uint8_t	usb_speed;
+	uint8_t	bNumEndpoints;
+	uint8_t	bInterfaceNumber;
+	uint8_t	bAlternateSetting;
+	uint8_t	bConfigurationValue;
+	uint8_t	bEpToIface[USB_MAX_ENDPOINTS];
+	usbd_status_t err;
+};
+
 struct usbd_bus_methods {
 	void    (*pipe_init) (struct usbd_device *udev, usb_endpoint_descriptor_t *edesc, struct usbd_pipe *pipe);
 	void    (*do_poll) (struct usbd_bus *);
@@ -326,6 +342,8 @@
 	device_t subdevs_end[0];
 	struct usb_device *linux_dev;
 	struct usbd_xfer *default_xfer[1];
+	void   *usb_template_ptr;
+	usbd_temp_get_desc_t *usb_temp_get_desc;
 
 	uint16_t refcount;
 #define	USB_DEV_REFCOUNT_MAX 0xffff
@@ -366,7 +384,12 @@
 	uint8_t	serial[64];		/* serial number */
 	uint8_t	manufacturer[64];	/* manufacturer string */
 	uint8_t	product[64];		/* product string */
-	uint8_t	scratch[128];
+
+	union {
+		struct usbd_temp_setup temp_setup[1];
+		uint8_t	data[128];
+	}	scratch[1];
+
 	uint8_t	detaching;
 	uint8_t	no_strings;		/* flag for no strings */
 };
@@ -750,6 +773,13 @@
 void	usb_needs_explore(struct usbd_device *udev);
 void	usb_needs_probe_and_attach(void);
 
+/* prototypes from usb_template.c */
+
+const void *usbd_temp_get_device_desc(struct usbd_device *udev);
+const void *usbd_temp_get_config_desc(struct usbd_device *udev, uint8_t index);
+usbd_status_t usbd_temp_setup(struct usbd_device *udev, const struct usb_temp_device_desc *tdd);
+void	usbd_temp_unsetup(struct usbd_device *udev);
+
 /* prototypes from usb_transfer.c */
 
 #ifdef USB_DEBUG

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

@@ -38,26 +38,15 @@
 #include <sys/endian.h>
 #include <sys/queue.h>
 #include <sys/lock.h>
+#include <sys/malloc.h>
 
 #include <dev/usb/usb_port.h>
 #include <dev/usb/usb.h>
 #include <dev/usb/usb_subr.h>
 #include <dev/usb/usb_template.h>
 
-struct usb_temp_setup {
-	void   *buf;
-	uint32_t size;
-	uint8_t	usb_speed;
-	uint8_t	bNumEndpoints;
-	uint8_t	bInterfaceNumber;
-	uint8_t	bAlternateSetting;
-	uint8_t	bConfigurationValue;
-	uint8_t	bEpToIface[USB_MAX_ENDPOINTS];
-	usbd_status_t err;
-};
-
 static void
-usbd_make_raw_desc(struct usb_temp_setup *temp,
+usbd_make_raw_desc(struct usbd_temp_setup *temp,
     const uint8_t *raw)
 {
 	void *dst;
@@ -76,7 +65,7 @@
 }
 
 static void
-usbd_make_endpoint_desc(struct usb_temp_setup *temp,
+usbd_make_endpoint_desc(struct usbd_temp_setup *temp,
     const struct usb_temp_endpoint_desc *ted)
 {
 	usb_endpoint_descriptor_t *ed;
@@ -213,7 +202,7 @@
 }
 
 static void
-usbd_make_interface_desc(struct usb_temp_setup *temp,
+usbd_make_interface_desc(struct usbd_temp_setup *temp,
     const struct usb_temp_interface_desc *tid)
 {
 	usb_interface_descriptor_t *id;
@@ -278,7 +267,7 @@
 }
 
 static void
-usbd_make_config_desc(struct usb_temp_setup *temp,
+usbd_make_config_desc(struct usbd_temp_setup *temp,
     const struct usb_temp_config_desc *tcd)
 {
 	usb_config_descriptor_t *cd;
@@ -327,7 +316,7 @@
 }
 
 static void
-usbd_make_device_desc(struct usb_temp_setup *temp,
+usbd_make_device_desc(struct usbd_temp_setup *temp,
     const struct usb_temp_device_desc *tdd)
 {
 	usb_device_descriptor_t *dd;
@@ -394,3 +383,129 @@
 	}
 	return;
 }
+
+const void *
+usbd_temp_get_device_desc(struct usbd_device *udev)
+{
+	const usb_device_descriptor_t *dd;
+
+	dd = udev->usb_template_ptr;
+	if (dd == NULL) {
+		return (NULL);
+	}
+	if (dd->bDescriptorType != UDESC_DEVICE) {
+		/* sanity check failed */
+		return (NULL);
+	}
+	return (dd);
+}
+
+const void *
+usbd_temp_get_config_desc(struct usbd_device *udev, uint8_t index)
+{
+	const usb_device_descriptor_t *dd;
+	const usb_config_descriptor_t *cd;
+	uint16_t temp;
+
+	dd = usbd_temp_get_device_desc(udev);
+	if (dd == NULL) {
+		return (NULL);
+	}
+	if (index >= dd->bNumConfigurations) {
+		/* out of range */
+		return (NULL);
+	}
+	cd = USBD_ADD_BYTES(dd, dd->bLength);
+
+	while (index--) {
+		if (cd->bDescriptorType != UDESC_CONFIG) {
+			/* sanity check failed */
+			return (NULL);
+		}
+		temp = UGETW(cd->wTotalLength);
+		cd = USBD_ADD_BYTES(cd, temp);
+	}
+	return (cd);
+}
+
+/*------------------------------------------------------------------------*
+ *	usbd_temp_setup
+ *
+ * This function generates USB descriptors according to
+ * the given USB template device descriptor.
+ *
+ * Returns:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usbd_status_t
+usbd_temp_setup(struct usbd_device *udev,
+    const struct usb_temp_device_desc *tdd)
+{
+	struct usbd_temp_setup *uts;
+
+	if (tdd == NULL) {
+		/* be NULL safe */
+		return (0);
+	}
+	if (tdd->pGetDescFn == NULL) {
+		/* not initialized properly */
+		return (USBD_INVAL);
+	}
+	uts = udev->scratch[0].temp_setup;
+
+	bzero(uts, sizeof(*uts));
+
+	uts->usb_speed = udev->speed;
+
+	/* first pass */
+
+	usbd_make_device_desc(uts, tdd);
+
+	if (uts->err) {
+		/* some error happened */
+		return (uts->err);
+	}
+	/* allocate zeroed memory */
+	if (uts->size > 0) {
+		uts->buf = malloc(uts->size, M_USB, M_WAITOK | M_ZERO);
+		if (uts->buf == NULL) {
+			/* could not allocate memory */
+			return (USBD_NOMEM);
+		}
+	}
+	/* second pass */
+
+	uts->size = 0;
+
+	usbd_make_device_desc(uts, tdd);
+
+	if (uts->err) {
+		/* some error happened during second pass */
+		free(uts->buf, M_USB);
+		return (uts->err);
+	}
+	udev->usb_template_ptr = uts->buf;
+	udev->usb_temp_get_desc = tdd->pGetDescFn;
+
+	return (uts->err);
+}
+
+/*------------------------------------------------------------------------*
+ *	usbd_temp_unsetup
+ *
+ * This function frees any memory associated with the currently
+ * setup template, if any.
+ *------------------------------------------------------------------------*/
+void
+usbd_temp_unsetup(struct usbd_device *udev)
+{
+	if (udev->usb_template_ptr) {
+
+		free(udev->usb_template_ptr, M_USB);
+
+		udev->usb_template_ptr = NULL;
+		udev->usb_temp_get_desc = NULL;
+	}
+	return;
+}

==== //depot/projects/usb/src/sys/dev/usb/usb_template.h#3 (text+ko) ====

@@ -31,8 +31,6 @@
 #ifndef _USB_TEMPLATE_H_
 #define	_USB_TEMPLATE_H_
 
-typedef const uint8_t * (usbd_temp_get_string_desc_t)(struct usbd_device *udev, uint16_t langid, uint8_t index);
-
 struct usb_temp_packet_size {
 	uint16_t mps[USB_SPEED_MAX];
 };
@@ -41,7 +39,7 @@
 	const void **ppRawDesc;
 	const struct usb_temp_packet_size *pPacketSize;
 	uint8_t	direction;		/* UE_DIR_IN or UE_DIR_OUT */
-	uint8_t	endpoint;	/* endpoint address */
+	uint8_t	endpoint;		/* endpoint address */
 	uint8_t	bmAttributes;
 };
 
@@ -59,11 +57,11 @@
 	const struct usb_temp_interface_desc **ppIfaceDesc;
 	uint8_t	bmAttributes;
 	uint8_t	bMaxPower;
-	uint8_t iConfiguration;
+	uint8_t	iConfiguration;
 };
 
 struct usb_temp_device_desc {
-	usbd_temp_get_string_desc_t *pGetStringDescFn;
+	usbd_temp_get_desc_t *pGetDescFn;
 	const struct usb_temp_config_desc **ppConfigDesc;
 	uint16_t idVendor;
 	uint16_t idProduct;

==== //depot/projects/usb/src/sys/modules/usb/Makefile#4 (text+ko) ====

@@ -15,6 +15,7 @@
 	usb_quirks.c usb_quirks.h \
 	usb_requests.c \
 	usb_subr.c usb_subr.h \
+	usb_template.c usb_template.h \
 	usb_transfer.c \
 	usb_compat_linux.c \
 



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