From patchwork Tue Feb 25 14:01:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micha=C5=82_Nazarewicz?= X-Patchwork-Id: 3717501 Return-Path: X-Original-To: patchwork-linux-arm-msm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id E0F09BF13A for ; Tue, 25 Feb 2014 14:54:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8A340201D3 for ; Tue, 25 Feb 2014 14:54:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0A40C201CD for ; Tue, 25 Feb 2014 14:54:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752617AbaBYOyT (ORCPT ); Tue, 25 Feb 2014 09:54:19 -0500 Received: from mail-ea0-f182.google.com ([209.85.215.182]:64733 "EHLO mail-ea0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752072AbaBYOyR convert rfc822-to-8bit (ORCPT ); Tue, 25 Feb 2014 09:54:17 -0500 Received: by mail-ea0-f182.google.com with SMTP id r15so176673ead.41 for ; Tue, 25 Feb 2014 06:54:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:in-reply-to:date:organization:references :user-agent:face:message-id:mime-version:content-type :content-transfer-encoding; bh=JhF3TLlx4jTmVpcj7IErRwvRlnVOyqGYBIOe0ikFTr8=; b=pcI4xij4Z5tqRIBiOCbNfg8JaLvpfkR5WPEGtTONNyi1u6Kf8AWNxKYEpuKlhYf70c ZLNTOZArR+N0/Ml9z63pZ0RgN7CZ0ejOphdoik9CrVTyb0dZekFnfB6YFfxa5J7IK7CE NtICN1PNHEXwnzEICZF40D5Gg031BiXy9Vppx9FrdIPt9dKGhWtcLYlaHYAbwc+ERtQh +X0rI1DP94PBQ1+8/spGlbtAjtz8ob59NzQkVcvB4QMks+umQHlwilBwCbM+3T2/krTf dNaLBZqAuX6dIAzSrhzGdLv5s0flDZ9Cb5m5EDNHTINAfcYscERrE6m1OM+JwZSo3eHL jjag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:in-reply-to:date :organization:references:user-agent:face:message-id:mime-version :content-type:content-transfer-encoding; bh=JhF3TLlx4jTmVpcj7IErRwvRlnVOyqGYBIOe0ikFTr8=; b=WVHYZHaFEIh98wC/PhUKgGMZ8jiGwkbdUkTx4u8oe7egZjrnpGMzluMWZBcJnuZ/Zq wkPDR3TW5b6BvUkIfLNw/53bAKEqMIX+IwOjz6sfG+UeCJq/xi49Uxp38rDb40NK8gsx DqCUP5JZiK2z+hR5tYX5Mm4TB0NJXm/65qbQ3zT+Z5cEK+08o5qFuZBJhvuaTnvaf74p FHuAfOkj0+Qr+F3TvYzlaLRgEj/Jl8CPvQlc/odmLg2C4hFaD17ahEAOeKVc6AE8n8ja muc7NtZ8G+AXJtGXsIDgZHsIU+mBhvMprEyflN4mTCZvRshG3Qh5gim7DzXsTObCEIAL gwaw== X-Gm-Message-State: ALoCoQlcnSeBtsmMwKkfd/CqtvMJzBRWGhYQQbg7mujFrJ1TJqQGvDKqTGQwuPQXov98zvPAg96d+EoSyzzeQCSOa5RJTbHh8BCBENu0oGw3KgxpsAmGFqpl/kVnDJ2JLBJxOObH54pzRa9tEBuBVBuSvHoSjauB3Et2OwqJVLr0IlG7XM68L2KRMCYs63tCekaDdTCEzz3PcpqJmo76XcIyKggXv36b1Q== X-Received: by 10.14.103.67 with SMTP id e43mr237030eeg.94.1393340056294; Tue, 25 Feb 2014 06:54:16 -0800 (PST) Received: from mpn-glaptop.roam.corp.google.com ([2620:0:105f:311:2d65:1cad:edbf:b982]) by mx.google.com with ESMTPSA id l4sm42179199eeo.9.2014.02.25.06.54.13 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 25 Feb 2014 06:54:14 -0800 (PST) From: Michal Nazarewicz To: Manu Gautam , balbi@ti.com, jackp@codeaurora.org, pheatwol@codeaurora.org Cc: linux-usb@vger.kernel.org, linux-arm-msm@vger.kernel.org, benoit@android.com, andrzej.p@samsung.com, gregkh@linuxfoundation.org, Manu Gautam Subject: [RFC] usb: gadget: f_fs: Add flags to descriptors block In-Reply-To: <1387877408-17567-1-git-send-email-mgautam@codeaurora.org> Date: Tue, 25 Feb 2014 15:01:33 +0100 Organization: http://mina86.com/ References: <1387877408-17567-1-git-send-email-mgautam@codeaurora.org> User-Agent: Notmuch/0.17+15~gb65ca8e (http://notmuchmail.org) Emacs/24.3.50.1 (x86_64-unknown-linux-gnu) X-Face: PbkBB1w#)bOqd`iCe"Ds{e+!C7`pkC9a|f)Qo^BMQvy\q5x3?vDQJeN(DS?|-^$uMti[3D*#^_Ts"pU$jBQLq~Ud6iNwAw_r_o_4]|JO?]}P_}Nc&"p#D(ZgUb4uCNPe7~a[DbPG0T~!&c.y$Ur,=N4RT>]dNpd; KFrfMCylc}gc??'U2j,!8%xdD Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAJFBMVEWbfGlUPDDHgE57V0jUupKjgIObY0PLrom9mH4dFRK4gmjPs41MxjOgAAACQElEQVQ4jW3TMWvbQBQHcBk1xE6WyALX1069oZBMlq+ouUwpEQQ6uRjttkWP4CmBgGM0BQLBdPFZYPsyFUo6uEtKDQ7oy/U96XR2Ux8ehH/89Z6enqxBcS7Lg81jmSuujrfCZcLI/TYYvbGj+jbgFpHJ/bqQAUISj8iLyu4LuFHJTosxsucO4jSDNE0Hq3hwK/ceQ5sx97b8LcUDsILfk+ovHkOIsMbBfg43VuQ5Ln9YAGCkUdKJoXR9EclFBhixy3EGVz1K6eEkhxCAkeMMnqoAhAKwhoUJkDrCqvbecaYINlFKSRS1i12VKH1XpUd4qxL876EkMcDvHj3s5RBajHHMlA5iK32e0C7VgG0RlzFPvoYHZLRmAC0BmNcBruhkE0KsMsbEc62ZwUJDxWUdMsMhVqovoT96i/DnX/ASvz/6hbCabELLk/6FF/8PNpPCGqcZTGFcBhhAaZZDbQPaAB3+KrWWy2XgbYDNIinkdWAFcCpraDE/knwe5DBqGmgzESl1p2E4MWAz0VUPgYYzmfWb9yS4vCvgsxJriNTHoIBz5YteBvg+VGISQWUqhMiByPIPpygeDBE6elD973xWwKkEiHZAHKjhuPsFnBuArrzxtakRcISv+XMIPl4aGBUJm8Emk7qBYU8IlgNEIpiJhk/No24jHwkKTFHDWfPniR4iw5vJaw2nzSjfq2zffcE/GDjRC2dn0J0XwPAbDL84TvaFCJEU4Oml9pRyEUhR3Cl2t01AoEjRbs0sYugp14/4X5n4pU4EHHnMAAAAAElFTkSuQmCC X-PGP: 50751FF4 X-PGP-FP: AC1F 5F5C D418 88F8 CC84 5858 2060 4012 5075 1FF4 X-Hashcash: 1:20:140225:benoit@android.com::D8Zu/I0BGep18O3L:00000000000000000000000000000000000000000000b8s X-Hashcash: 1:20:140225:gregkh@linuxfoundation.org::dKYWWbSYG/QRlIhP:000000000000000000000000000000000000DLl X-Hashcash: 1:20:140225:mgautam@codeaurora.org::Kut4TBDAJh6I3wXE:0000000000000000000000000000000000000000FtI X-Hashcash: 1:20:140225:linux-arm-msm@vger.kernel.org::teGazWaSqSX0/Orn:000000000000000000000000000000001iwa X-Hashcash: 1:20:140225:balbi@ti.com::5/Mw+mA4HSqxYacn:000003XQu X-Hashcash: 1:20:140225:pheatwol@codeaurora.org::8Czz46aQ9ZRxQspf:000000000000000000000000000000000000001ims X-Hashcash: 1:20:140225:jackp@codeaurora.org::JSmTLi5IUHMfaKoh:000000000000000000000000000000000000000003Eyz X-Hashcash: 1:20:140225:mgautam@codeaurora.org::KctKEbJLf4ovtkf5:0000000000000000000000000000000000000003bMS X-Hashcash: 1:20:140225:andrzej.p@samsung.com::5/eGTllPN6JkPjMy:00000000000000000000000000000000000000004VWl X-Hashcash: 1:20:140225:linux-usb@vger.kernel.org::53IuiE3NRrr/lXYu:000000000000000000000000000000000000GpNj Message-ID: MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This reworks the way SuperSpeed descriptors are added and instead of having a magick after full and high speed descriptors, it reworks the whole descriptors block to include a flags field which lists which descriptors are present and makes future extensions possible. Signed-off-by: Michal Nazarewicz --- Just to repeat what I wrote on my phone which is unable to send text/plain messages: On Tue, Feb 25 2014, Micha? Nazarewicz wrote: > On Feb 25, 2014 5:47 AM, "Manu Gautam" wrote: >> Is this patch good now to be added to your queue (if not already in)? >> It applied cleanly on your next branch. > > Actually, recent LWN article about flags in syscalls got me thinking and > maybe it's good this patch is not yet in Felipe's queue. > > I admit I screwed up when I designed the headers format, but now that we > change it to accommodate SuperSpeed, I think we should go ahead and change > the format by adding flags field. > > […] > > Sorry to mention this only now, but I believe that's the right thing to do. This patch implements this new format and in doing so simplifies, in my opinion, the code a bit. It needs to be applied on top of Manu's patch. It has not been tested at all, not even compile-tested. This is because whenever I try to compile the kernel, I get this nice message in my logs: mce: [Hardware Error]: Machine check events logged thermal_sys: Critical temperature reached(100 C),shutting down thermal_sys: Critical temperature reached(100 C),shutting down Sorry about that. drivers/usb/gadget/f_fs.c | 136 +++++++++++++++--------------------- drivers/usb/gadget/u_fs.h | 12 ++-- include/uapi/linux/usb/functionfs.h | 49 ++++++++----- 3 files changed, 94 insertions(+), 103 deletions(-) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 928959d..7d01bd6 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -1167,7 +1167,7 @@ static void ffs_data_clear(struct ffs_data *ffs) if (ffs->epfiles) ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count); - kfree(ffs->raw_descs); + kfree(ffs->raw_descs_data); kfree(ffs->raw_strings); kfree(ffs->stringtabs); } @@ -1179,12 +1179,12 @@ static void ffs_data_reset(struct ffs_data *ffs) ffs_data_clear(ffs); ffs->epfiles = NULL; + ffs->raw_descs_data = NULL; ffs->raw_descs = NULL; ffs->raw_strings = NULL; ffs->stringtabs = NULL; - ffs->raw_fs_hs_descs_length = 0; - ffs->raw_ss_descs_length = 0; + ffs->real_descs_length = 0; ffs->fs_descs_count = 0; ffs->hs_descs_count = 0; ffs->ss_descs_count = 0; @@ -1598,89 +1598,76 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, static int __ffs_data_got_descs(struct ffs_data *ffs, char *const _data, size_t len) { - unsigned fs_count, hs_count, ss_count = 0; - int fs_len, hs_len, ss_len, ret = -EINVAL; - char *data = _data; + char *data = _data, *raw_descs; + unsigned counts[3], flags; + int ret = -EINVAL, i; ENTER(); - if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_DESCRIPTORS_MAGIC || - get_unaligned_le32(data + 4) != len)) + if (get_unaligned_le32(data + 4) != len) goto error; - fs_count = get_unaligned_le32(data + 8); - hs_count = get_unaligned_le32(data + 12); - - data += 16; - len -= 16; - if (likely(fs_count)) { - fs_len = ffs_do_descs(fs_count, data, len, - __ffs_data_do_entity, ffs); - if (unlikely(fs_len < 0)) { - ret = fs_len; + switch (get_unaligned_le32(data)) { + case FUNCTIONFS_DESCRIPTORS_MAGIC: + flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC; + data += 8; + len -= 8; + break; + case FUNCTIONFS_DESCRIPTORS_MAGIC_V2: + flags = get_unaligned_le32(data + 8); + if (flags & ~(FUNCTIONFS_HAS_FS_DESC | + FUNCTIONFS_HAS_HS_DESC | + FUNCTIONFS_HAS_SS_DESC)) { + ret = -ENOSYS; goto error; } - - data += fs_len; - len -= fs_len; - } else { - fs_len = 0; + data += 12; + len -= 12; + break; + default: + goto error; } - if (likely(hs_count)) { - hs_len = ffs_do_descs(hs_count, data, len, - __ffs_data_do_entity, ffs); - if (unlikely(hs_len < 0)) { - ret = hs_len; + /* Read fs_count, hs_count and ss_count (if present) */ + for (i = 0; i < 3; ++i) { + if (!(flags & (1 << i))) { + counts[i] = 0; + } else if (len < 4) { goto error; + } else { + counts[i] = get_unaligned_le32(data); + data += 4; + len -= 4; } - - data += hs_len; - len -= hs_len; - } else { - hs_len = 0; } - if (len >= 8) { - /* Check SS_MAGIC for presence of ss_descs and get SS_COUNT */ - if (get_unaligned_le32(data) != FUNCTIONFS_SS_DESC_MAGIC) - goto einval; - - ss_count = get_unaligned_le32(data + 4); - data += 8; - len -= 8; - } - - if (!fs_count && !hs_count && !ss_count) - goto einval; - - if (ss_count) { - ss_len = ffs_do_descs(ss_count, data, len, + /* Read descriptors */ + raw_descs = data; + for (i = 0; i < 3; ++i) { + if (!counts[i]) + continue; + ret = ffs_do_descs(descs[i].count, data, len, __ffs_data_do_entity, ffs); - if (unlikely(ss_len < 0)) { - ret = ss_len; + if (ret < 0) goto error; - } - ret = ss_len; - } else { - ss_len = 0; - ret = 0; + data += ret; + len -= ret; } - if (unlikely(len != ret)) - goto einval; + if (raw_descs == data || len) { + ret = -EINVAL; + goto error; + } - ffs->raw_fs_hs_descs_length = fs_len + hs_len; - ffs->raw_ss_descs_length = ss_len; - ffs->raw_descs = _data; - ffs->fs_descs_count = fs_count; - ffs->hs_descs_count = hs_count; - ffs->ss_descs_count = ss_count; + ffs->raw_descs_data = _data; + ffs->raw_descs = raw_descs; + ffs->raw_descs_length = data - raw_descs; + ffs->fs_descs_count = counts[0]; + ffs->hs_descs_count = counts[1]; + ffs->ss_descs_count = counts[2]; return 0; -einval: - ret = -EINVAL; error: kfree(_data); return ret; @@ -2092,8 +2079,7 @@ static int _ffs_func_bind(struct usb_configuration *c, vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs, super ? ffs->ss_descs_count + 1 : 0); vla_item_with_sz(d, short, inums, ffs->interfaces_count); - vla_item_with_sz(d, char, raw_descs, - ffs->raw_fs_hs_descs_length + ffs->raw_ss_descs_length); + vla_item_with_sz(d, char, raw_descs, ffs->raw_raw_descs_length); char *vlabuf; ENTER(); @@ -2109,15 +2095,9 @@ static int _ffs_func_bind(struct usb_configuration *c, /* Zero */ memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz); - /* Copy only raw (hs,fs) descriptors (until ss_magic and ss_count) */ - memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs + 16, - ffs->raw_fs_hs_descs_length); - /* Copy SS descs present @ header + hs_fs_descs + ss_magic + ss_count */ - if (func->ffs->ss_descs_count) - memcpy(vla_ptr(vlabuf, d, raw_descs) + - ffs->raw_fs_hs_descs_length, - ffs->raw_descs + 16 + ffs->raw_fs_hs_descs_length + 8, - ffs->raw_ss_descs_length); + /* Copy descriptors */ + memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs, + ffs->raw_descs_length); memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz); for (ret = ffs->eps_count; ret; --ret) { @@ -2599,7 +2579,7 @@ static int _ffs_name_dev(struct ffs_dev *dev, const char *name) existing = _ffs_find_dev(name); if (existing) return -EBUSY; - + dev->name = name; return 0; @@ -2682,7 +2662,7 @@ static void ffs_release_dev(struct ffs_data *ffs_data) ffs_dev = ffs_data->private_data; if (ffs_dev) ffs_dev->mounted = false; - + if (ffs_dev->ffs_release_dev_callback) ffs_dev->ffs_release_dev_callback(ffs_dev); diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h index 08bf26e..866c848 100644 --- a/drivers/usb/gadget/u_fs.h +++ b/drivers/usb/gadget/u_fs.h @@ -210,15 +210,13 @@ struct ffs_data { /* filled by __ffs_data_got_descs() */ /* - * Real descriptors are 16 bytes after raw_descs (so you need - * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the - * first full speed descriptor). - * raw_fs_hs_descs_length does not have those 16 bytes added. - * ss_descs are 8 bytes (ss_magic + count) pass the hs_descs + * raw_descs is what you kfree, real_descs points inside of raw_descs, + * where full speed, high speed and super speed descriptors start. + * real_descs_length is the length of all those descriptors. */ const void *raw_descs; - unsigned raw_fs_hs_descs_length; - unsigned raw_ss_descs_length; + const void *real_descs; + unsigned real_descs_length; unsigned fs_descs_count; unsigned hs_descs_count; unsigned ss_descs_count; diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h index 0f8f7be..ee6fcbc 100644 --- a/include/uapi/linux/usb/functionfs.h +++ b/include/uapi/linux/usb/functionfs.h @@ -10,7 +10,14 @@ enum { FUNCTIONFS_DESCRIPTORS_MAGIC = 1, - FUNCTIONFS_STRINGS_MAGIC = 2 + FUNCTIONFS_STRINGS_MAGIC = 2, + FUNCTIONFS_DESCRIPTORS_MAGIC_V2 = 3, +}; + +enum functionfs_flags { + FUNCTIONFS_HAS_FS_DESC = 1, + FUNCTIONFS_HAS_HS_DESC = 2, + FUNCTIONFS_HAS_SS_DESC = 4, }; #define FUNCTIONFS_SS_DESC_MAGIC 0x0055DE5C @@ -30,33 +37,39 @@ struct usb_endpoint_descriptor_no_audio { /* - * All numbers must be in little endian order. - */ - -struct usb_functionfs_descs_head { - __le32 magic; - __le32 length; - __le32 fs_count; - __le32 hs_count; -} __attribute__((packed)); - -/* * Descriptors format: * * | off | name | type | description | * |-----+-----------+--------------+--------------------------------------| - * | 0 | magic | LE32 | FUNCTIONFS_{FS,HS}_DESCRIPTORS_MAGIC | + * | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC_V2 | + * | 4 | length | LE32 | length of the whole data chunk | + * | 8 | flags | LE32 | combination of functionfs_flags | + * | | fs_count | LE32 | number of full-speed descriptors | + * | | hs_count | LE32 | number of high-speed descriptors | + * | | ss_count | LE32 | number of high-speed descriptors | + * | | fs_descrs | Descriptor[] | list of full-speed descriptors | + * | | hs_descrs | Descriptor[] | list of high-speed descriptors | + * | | ss_descrs | Descriptor[] | list of high-speed descriptors | + * + * Depending on which flags are set, various fields may be missing in the + * structure. Any flags that are not recognised cause the whole block to be + * rejected with -ENOSYS. + * + * Legacy descriptors format: + * + * | off | name | type | description | + * |-----+-----------+--------------+--------------------------------------| + * | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC | * | 4 | length | LE32 | length of the whole data chunk | * | 8 | fs_count | LE32 | number of full-speed descriptors | * | 12 | hs_count | LE32 | number of high-speed descriptors | * | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | - * | | ss_magic | LE32 | FUNCTIONFS_SS_DESC_MAGIC | - * | | ss_count | LE32 | number of super-speed descriptors | - * | | ss_descrs | Descriptor[] | list of super-speed descriptors | * - * ss_magic: if present then it implies that SS_DESCs are also present - * descs are just valid USB descriptors and have the following format: + * All numbers must be in little endian order. + * + * Descriptor[] is an array of valid USB descriptors which have the following + * format: * * | off | name | type | description | * |-----+-----------------+------+--------------------------|