From owner-p4-projects@FreeBSD.ORG Thu Sep 4 19:52:45 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 032E31065672; Thu, 4 Sep 2008 19:52:45 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BB4F9106564A for ; Thu, 4 Sep 2008 19:52:44 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id A81A68FC1D for ; Thu, 4 Sep 2008 19:52:44 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id m84Jqiml069453 for ; Thu, 4 Sep 2008 19:52:44 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id m84JqiIF069451 for perforce@freebsd.org; Thu, 4 Sep 2008 19:52:44 GMT (envelope-from hselasky@FreeBSD.org) Date: Thu, 4 Sep 2008 19:52:44 GMT Message-Id: <200809041952.m84JqiIF069451@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 149220 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Sep 2008 19:52:45 -0000 http://perforce.freebsd.org/chv.cgi?CH=149220 Change 149220 by hselasky@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 @@ -39,6 +45,8 @@ #include +#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); }