PERFORCE change 149220 for review

Hans Petter Selasky hselasky at FreeBSD.org
Thu Sep 4 19:52:45 UTC 2008


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

Change 149220 by hselasky at hselasky_laptop001 on 2008/09/04 19:52:38

	
	Fix MTP templates and add support for vendor specific USB descriptors.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_handle_request.c#8 edit
.. //depot/projects/usb/src/sys/dev/usb2/include/usb2_standard.h#7 edit
.. //depot/projects/usb/src/sys/dev/usb2/template/usb2_template.c#9 edit
.. //depot/projects/usb/src/sys/dev/usb2/template/usb2_template.h#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/template/usb2_template_cdce.c#6 edit
.. //depot/projects/usb/src/sys/dev/usb2/template/usb2_template_msc.c#5 edit
.. //depot/projects/usb/src/sys/dev/usb2/template/usb2_template_mtp.c#5 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_handle_request.c#8 (text+ko) ====

@@ -419,6 +419,7 @@
 	uint16_t wValue;
 	uint16_t wIndex;
 	uint8_t state;
+	usb2_error_t err;
 	union {
 		uWord	wStatus;
 		uint8_t	buf[2];
@@ -564,11 +565,25 @@
 		break;
 	default:
 		/* we use "USB_ADD_BYTES" to de-const the src_zcopy */
-		if (usb2_handle_iface_request(xfer,
+		err = usb2_handle_iface_request(xfer,
 		    USB_ADD_BYTES(&src_zcopy, 0),
-		    &max_len, req, off, state)) {
-			goto tr_stalled;
+		    &max_len, req, off, state);
+		if (err == 0) {
+			goto tr_valid;
 		}
+		/*
+		 * Reset zero-copy pointer and max length
+		 * variable in case they were unintentionally
+		 * set:
+		 */
+		src_zcopy = NULL;
+		max_len = 0;
+
+		/*
+		 * Check if we have a vendor specific
+		 * descriptor:
+		 */
+		goto tr_handle_get_descriptor;
 	}
 	goto tr_valid;
 

==== //depot/projects/usb/src/sys/dev/usb2/include/usb2_standard.h#7 (text+ko) ====

@@ -283,6 +283,7 @@
 
 #define	UICLASS_PHYSICAL	0x05
 #define	UICLASS_IMAGE		0x06
+#define	UISUBCLASS_SIC		1	/* still image class */
 #define	UICLASS_PRINTER		0x07
 #define	UISUBCLASS_PRINTER	1
 #define	UIPROTO_PRINTER_UNI	1

==== //depot/projects/usb/src/sys/dev/usb2/template/usb2_template.c#9 (text+ko) ====

@@ -69,6 +69,7 @@
 static void *usb2_temp_get_qualifier_desc(struct usb2_device *udev);
 static void *usb2_temp_get_config_desc(struct usb2_device *udev, uint16_t *pLength, uint8_t index);
 static const void *usb2_temp_get_string_desc(struct usb2_device *udev, uint16_t lang_id, uint8_t string_index);
+static const void *usb2_temp_get_vendor_desc(struct usb2_device *udev, const struct usb2_device_request *req);
 static const void *usb2_temp_get_hub_desc(struct usb2_device *udev);
 static void usb2_temp_get_desc(struct usb2_device *udev, struct usb2_device_request *req, const void **pPtr, uint16_t *pLength);
 static usb2_error_t usb2_temp_setup(struct usb2_device *udev, const struct usb2_temp_device_desc *tdd);
@@ -955,6 +956,29 @@
 }
 
 /*------------------------------------------------------------------------*
+ *	usb2_temp_get_vendor_desc
+ *
+ * Returns:
+ *  NULL: No vendor descriptor found.
+ *  Else: Pointer to a vendor descriptor.
+ *------------------------------------------------------------------------*/
+static const void *
+usb2_temp_get_vendor_desc(struct usb2_device *udev,
+    const struct usb2_device_request *req)
+{
+	const struct usb2_temp_device_desc *tdd;
+
+	tdd = usb2_temp_get_tdd(udev);
+	if (tdd == NULL) {
+		return (NULL);
+	}
+	if (tdd->getVendorDesc == NULL) {
+		return (NULL);
+	}
+	return ((tdd->getVendorDesc) (req));
+}
+
+/*------------------------------------------------------------------------*
  *	usb2_temp_get_string_desc
  *
  * Returns:
@@ -1023,6 +1047,10 @@
 			goto tr_stalled;
 		}
 		break;
+	case UT_READ_VENDOR_DEVICE:
+	case UT_READ_VENDOR_OTHER:
+		buf = usb2_temp_get_vendor_desc(udev, req);
+		goto tr_valid;
 	default:
 		goto tr_stalled;
 	}

==== //depot/projects/usb/src/sys/dev/usb2/template/usb2_template.h#4 (text+ko) ====

@@ -31,6 +31,7 @@
 #define	_USB_TEMPLATE_H_
 
 typedef const void *(usb2_temp_get_string_desc_t)(uint16_t lang_id, uint8_t string_index);
+typedef const void *(usb2_temp_get_vendor_desc_t)(const struct usb2_device_request *req);
 
 struct usb2_temp_packet_size {
 	uint16_t mps[USB_SPEED_MAX];
@@ -67,6 +68,7 @@
 
 struct usb2_temp_device_desc {
 	usb2_temp_get_string_desc_t *getStringDesc;
+	usb2_temp_get_vendor_desc_t *getVendorDesc;
 	const struct usb2_temp_config_desc **ppConfigDesc;
 	uint16_t idVendor;
 	uint16_t idProduct;

==== //depot/projects/usb/src/sys/dev/usb2/template/usb2_template_cdce.c#6 (text+ko) ====

@@ -271,8 +271,8 @@
 const struct usb2_temp_device_desc usb2_template_cdce = {
 	.getStringDesc = &eth_get_string_desc,
 	.ppConfigDesc = eth_configs,
-	.idVendor = 0,
-	.idProduct = 0,
+	.idVendor = 0x0001,
+	.idProduct = 0x0001,
 	.bcdDevice = 0x0100,
 	.bDeviceClass = UDCLASS_COMM,
 	.bDeviceSubClass = 0,

==== //depot/projects/usb/src/sys/dev/usb2/template/usb2_template_msc.c#5 (text+ko) ====

@@ -148,8 +148,8 @@
 const struct usb2_temp_device_desc usb2_template_msc = {
 	.getStringDesc = &msc_get_string_desc,
 	.ppConfigDesc = msc_configs,
-	.idVendor = 0,
-	.idProduct = 0,
+	.idVendor = 0x0001,
+	.idProduct = 0x0001,
 	.bcdDevice = 0x0100,
 	.bDeviceClass = UDCLASS_COMM,
 	.bDeviceSubClass = 0,

==== //depot/projects/usb/src/sys/dev/usb2/template/usb2_template_mtp.c#5 (text+ko) ====

@@ -30,6 +30,12 @@
 /*
  * This file contains the USB templates for an USB Message Transfer
  * Protocol device.
+ *
+ * NOTE: It is common practice that MTP devices use some dummy
+ * descriptor cludges to be automatically detected by the host
+ * operating system. These descriptors are documented in the LibMTP
+ * library at sourceforge.net. The alternative is to supply the host
+ * operating system the VID and PID of your device.
  */
 
 #include <dev/usb2/include/usb2_standard.h>
@@ -39,6 +45,8 @@
 
 #include <dev/usb2/template/usb2_template.h>
 
+#define	MTP_BREQUEST 0x08
+
 enum {
 	STRING_LANG_INDEX,
 	STRING_MTP_DATA_INDEX,
@@ -93,6 +101,7 @@
 /* prototypes */
 
 static usb2_temp_get_string_desc_t mtp_get_string_desc;
+static usb2_temp_get_vendor_desc_t mtp_get_vendor_desc;
 
 static const struct usb2_temp_packet_size bulk_mps = {
 	.mps[USB_SPEED_FULL] = 64,
@@ -119,16 +128,16 @@
 
 static const struct usb2_temp_endpoint_desc *mtp_data_endpoints[] = {
 	&bulk_in_ep,
+	&bulk_out_ep,
 	&intr_in_ep,
-	&bulk_out_ep,
 	NULL,
 };
 
 static const struct usb2_temp_interface_desc mtp_data_interface = {
 	.ppEndpoints = mtp_data_endpoints,
-	.bInterfaceClass = 6,
-	.bInterfaceSubClass = 1,
-	.bInterfaceProtocol = 1,
+	.bInterfaceClass = UICLASS_IMAGE,
+	.bInterfaceSubClass = UISUBCLASS_SIC,	/* Still Image Class */
+	.bInterfaceProtocol = 1,	/* PIMA 15740 */
 	.iInterface = STRING_MTP_DATA_INDEX,
 };
 
@@ -151,9 +160,10 @@
 
 const struct usb2_temp_device_desc usb2_template_mtp = {
 	.getStringDesc = &mtp_get_string_desc,
+	.getVendorDesc = &mtp_get_vendor_desc,
 	.ppConfigDesc = mtp_configs,
-	.idVendor = 0,
-	.idProduct = 0,
+	.idVendor = 0x0001,
+	.idProduct = 0x0001,
 	.bcdDevice = 0x0100,
 	.bDeviceClass = 0,
 	.bDeviceSubClass = 0,
@@ -164,6 +174,37 @@
 };
 
 /*------------------------------------------------------------------------*
+ *	mtp_get_vendor_desc
+ *
+ * Return values:
+ * NULL: Failure. No such vendor descriptor.
+ * Else: Success. Pointer to vendor descriptor is returned.
+ *------------------------------------------------------------------------*/
+static const void *
+mtp_get_vendor_desc(const struct usb2_device_request *req)
+{
+	static const uint8_t dummy_desc[0x28] = {
+		0x28, 0, 0, 0, 0, 1, 4, 0,
+		1, 0, 0, 0, 0, 0, 0, 0,
+		0, 1, 0x4D, 0x54, 0x50, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+	};
+
+	if ((req->bmRequestType == UT_READ_VENDOR_DEVICE) &&
+	    (req->bRequest == MTP_BREQUEST) && (req->wValue[0] == 0) &&
+	    (req->wValue[1] == 0) && (req->wIndex[1] == 0) &&
+	    ((req->wIndex[0] == 4) || (req->wIndex[0] == 5))) {
+		/*
+		 * By returning this descriptor LibMTP will
+		 * automatically pickup our device.
+		 */
+		return (dummy_desc);
+	}
+	return (NULL);
+}
+
+/*------------------------------------------------------------------------*
  *	mtp_get_string_desc
  *
  * Return values:
@@ -182,6 +223,19 @@
 		[STRING_MTP_SERIAL_INDEX] = &string_mtp_serial,
 	};
 
+	static const uint8_t dummy_desc[0x12] = {
+		0x12, 0x03, 0x4D, 0x00, 0x53, 0x00, 0x46, 0x00,
+		0x54, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00,
+		MTP_BREQUEST, 0x00,
+	};
+
+	if (string_index == 0xEE) {
+		/*
+		 * By returning this string LibMTP will automatically
+		 * pickup our device.
+		 */
+		return (dummy_desc);
+	}
 	if (string_index == 0) {
 		return (&string_lang);
 	}


More information about the p4-projects mailing list