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 = ð_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