* [PATCHv2 0/7] Several improvements to USB gadgets
@ 2010-05-28 10:02 Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 1/7] USB: gadget: g_mass_storage: static data instead of dynamic allocation Michal Nazarewicz
0 siblings, 1 reply; 9+ messages in thread
From: Michal Nazarewicz @ 2010-05-28 10:02 UTC (permalink / raw)
To: linux-usb; +Cc: David Brownell, Kyungmin Park, Marek Szyprowski, linux-kernel
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; CHARSET=EUC-KR, Size: 3667 bytes --]
Hello everyone,
I'm resending my earlier patchsets with two changes.
First of all, there was a tiny coding style bug in one of the patches
(reported by Sergei Shtylyov).
Second of all, David has shown some concerns about overcomplicating
the g_multi driver by introducing several Kconfig options. I assumed
he knows better and so excluded this particular patch from the set.
The other patch modifying the g_multi is however legitimate in my
opinion as it clears the code and fixes some section mismatch
warnings.
The whole patchset introduces several improvements to USB gadgets,
functions, etc.:
Michal Nazarewicz (7):
USB: gadget: g_mass_storage: static data instead of dynamic
allocation
A micro optimisation preventing a kmalloc call() which would otherwise
be always called at the very beginning for the same area size.
This was submitted previously but Greg did not included it in his
quilt tree (unless I overlooked something) so I'll posting it again
for completeness. Sorry if that creates confusion.
In my opinion this is worth including as it simplifies the code a bit
and removes the call to kmalloc/kfree (hidden in fsg_common_init)
which in my opinion is a good thing as well.
Note, that the next patch won't apply without this one -- conflict is
trivial to solve though.
USB: gadget: f_mass_storage: fsg_add() renamed to fsg_bind_config()
USB: gadget: f_fs: functionfs_add() renamed to
functionfs_bind_config()
All other functions use foo_bind_config() to add function to USB
configuration so changed the names for mass storage and FunctionFS as
well.
The inconstancy apparent in multifunction gadgets stroke me for quite
some time now. I was always reluctant to submit patch thinking that
it would be just stupid name change but finally couldn't stand it. ;)
In case of mass storage the old (fsg_add()) function is still
available but marked deprecated. In case of FFS the old
(functionfs_add()) function has been removed.
USB: gadget: composite: usb_string_ids_*() functions added
USB: gadget: f_fs: use usb_string_ids_n()
usb_string_ids_n() and usb_string_ids_tab() functions added for batch
sting IDs requests.
USB: gadget: g_multi: code clean up and refactoring
USB: gadget: g_multi: added documentation and INF files
g_multi clean up, fixes, etc. Also, the last patch includes a bit of
documentation for g_multi and an INF file tested with Windows XP SP3.
Hopefully, someone will find it useful.
Documentation/usb/gadget_multi.txt | 160 ++++++++++++++++++
Documentation/usb/gadget_multi_rndis.inf | 200 ++++++++++++++++++++++
Documentation/usb/gadget_multi_serial.inf | 44 +++++
drivers/usb/gadget/Kconfig | 1 +
drivers/usb/gadget/composite.c | 67 +++++++-
drivers/usb/gadget/f_fs.c | 36 ++---
drivers/usb/gadget/f_mass_storage.c | 13 +-
drivers/usb/gadget/g_ffs.c | 2 +-
drivers/usb/gadget/mass_storage.c | 13 +-
drivers/usb/gadget/multi.c | 262 ++++++++++++++++-------------
include/linux/usb/composite.h | 4 +
include/linux/usb/functionfs.h | 6 +-
12 files changed, 656 insertions(+), 152 deletions(-)
create mode 100644 Documentation/usb/gadget_multi.txt
create mode 100644 Documentation/usb/gadget_multi_rndis.inf
create mode 100644 Documentation/usb/gadget_multi_serial.inf
--
Best regards, _ _
| Humble Liege of Serenely Enlightened Majesty of o' \,=./ `o
| Computer Science, Michał "mina86" Nazarewicz (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCHv2 1/7] USB: gadget: g_mass_storage: static data instead of dynamic allocation
2010-05-28 10:02 [PATCHv2 0/7] Several improvements to USB gadgets Michal Nazarewicz
@ 2010-05-28 10:02 ` Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 2/7] USB: gadget: f_mass_storage: fsg_add() renamed to fsg_bind_config() Michal Nazarewicz
0 siblings, 1 reply; 9+ messages in thread
From: Michal Nazarewicz @ 2010-05-28 10:02 UTC (permalink / raw)
To: linux-usb; +Cc: David Brownell, Kyungmin Park, Marek Szyprowski, linux-kernel
This patch changes msg_do_config() function so that it uses
a static object for a fsg_common structure instead of dynamically
allocated. This is a micro-optimisation.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/usb/gadget/mass_storage.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index 705cc1f..a3349f2 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -143,7 +143,7 @@ static int msg_thread_exits(struct fsg_common *common)
static int __init msg_do_config(struct usb_configuration *c)
{
- struct fsg_common *common;
+ static struct fsg_common common, *retp;
struct fsg_config config;
int ret;
@@ -154,12 +154,13 @@ static int __init msg_do_config(struct usb_configuration *c)
fsg_config_from_params(&config, &mod_data);
config.thread_exits = msg_thread_exits;
- common = fsg_common_init(0, c->cdev, &config);
- if (IS_ERR(common))
- return PTR_ERR(common);
- ret = fsg_add(c->cdev, c, common);
- fsg_common_put(common);
+ retp = fsg_common_init(&common, c->cdev, &config);
+ if (IS_ERR(retp))
+ return PTR_ERR(retp);
+
+ ret = fsg_add(c->cdev, c, &common);
+ fsg_common_put(&common);
return ret;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 2/7] USB: gadget: f_mass_storage: fsg_add() renamed to fsg_bind_config()
2010-05-28 10:02 ` [PATCHv2 1/7] USB: gadget: g_mass_storage: static data instead of dynamic allocation Michal Nazarewicz
@ 2010-05-28 10:02 ` Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 3/7] USB: gadget: f_fs: functionfs_add() renamed to functionfs_bind_config() Michal Nazarewicz
0 siblings, 1 reply; 9+ messages in thread
From: Michal Nazarewicz @ 2010-05-28 10:02 UTC (permalink / raw)
To: linux-usb; +Cc: David Brownell, Kyungmin Park, Marek Szyprowski, linux-kernel
Mass Storage Function had a bit unique name for function
used to add it to USB configuration. Renamed as to match
naming convention of other functions.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/usb/gadget/f_mass_storage.c | 13 ++++++++++---
drivers/usb/gadget/mass_storage.c | 2 +-
drivers/usb/gadget/multi.c | 4 ++--
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 7d05a0b..072cbf9 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -3023,9 +3023,9 @@ static struct usb_gadget_strings *fsg_strings_array[] = {
NULL,
};
-static int fsg_add(struct usb_composite_dev *cdev,
- struct usb_configuration *c,
- struct fsg_common *common)
+static int fsg_bind_config(struct usb_composite_dev *cdev,
+ struct usb_configuration *c,
+ struct fsg_common *common)
{
struct fsg_dev *fsg;
int rc;
@@ -3072,6 +3072,13 @@ error_free_fsg:
return rc;
}
+static inline int __deprecated __maybe_unused
+fsg_add(struct usb_composite_dev *cdev,
+ struct usb_configuration *c,
+ struct fsg_common *common)
+{
+ return fsg_bind_config(cdev, c, common);
+}
/************************* Module parameters *************************/
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index a3349f2..d6975f4 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -159,7 +159,7 @@ static int __init msg_do_config(struct usb_configuration *c)
if (IS_ERR(retp))
return PTR_ERR(retp);
- ret = fsg_add(c->cdev, c, &common);
+ ret = fsg_bind_config(c->cdev, c, &common);
fsg_common_put(&common);
return ret;
}
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index a930d7f..d3d3140 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -172,7 +172,7 @@ static int __init rndis_do_config(struct usb_configuration *c)
if (ret < 0)
return ret;
- ret = fsg_add(c->cdev, c, fsg_common);
+ ret = fsg_bind_config(c->cdev, c, fsg_common);
if (ret < 0)
return ret;
@@ -208,7 +208,7 @@ static int __init cdc_do_config(struct usb_configuration *c)
if (ret < 0)
return ret;
- ret = fsg_add(c->cdev, c, fsg_common);
+ ret = fsg_bind_config(c->cdev, c, fsg_common);
if (ret < 0)
return ret;
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 3/7] USB: gadget: f_fs: functionfs_add() renamed to functionfs_bind_config()
2010-05-28 10:02 ` [PATCHv2 2/7] USB: gadget: f_mass_storage: fsg_add() renamed to fsg_bind_config() Michal Nazarewicz
@ 2010-05-28 10:02 ` Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 4/7] USB: gadget: composite: usb_string_ids_*() functions added Michal Nazarewicz
0 siblings, 1 reply; 9+ messages in thread
From: Michal Nazarewicz @ 2010-05-28 10:02 UTC (permalink / raw)
To: linux-usb; +Cc: David Brownell, Kyungmin Park, Marek Szyprowski, linux-kernel
FunctionFS had a bit unique name for function used to add it
to USB configuration. Renamed as to match naming convention
of other functions.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/usb/gadget/f_fs.c | 6 +++---
drivers/usb/gadget/g_ffs.c | 2 +-
include/linux/usb/functionfs.h | 6 +++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index d69eccf..3fe120f 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1480,9 +1480,9 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
}
-static int functionfs_add(struct usb_composite_dev *cdev,
- struct usb_configuration *c,
- struct ffs_data *ffs)
+static int functionfs_bind_config(struct usb_composite_dev *cdev,
+ struct usb_configuration *c,
+ struct ffs_data *ffs)
{
struct ffs_function *func;
int ret;
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 4b0e4a0..2f26470 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -388,7 +388,7 @@ static int __gfs_do_config(struct usb_configuration *c,
return ret;
}
- ret = functionfs_add(c->cdev, c, gfs_ffs_data);
+ ret = functionfs_bind_config(c->cdev, c, gfs_ffs_data);
if (unlikely(ret < 0))
return ret;
diff --git a/include/linux/usb/functionfs.h b/include/linux/usb/functionfs.h
index a34a2a0..6f649c1 100644
--- a/include/linux/usb/functionfs.h
+++ b/include/linux/usb/functionfs.h
@@ -180,9 +180,9 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
static void functionfs_unbind(struct ffs_data *ffs)
__attribute__((nonnull));
-static int functionfs_add(struct usb_composite_dev *cdev,
- struct usb_configuration *c,
- struct ffs_data *ffs)
+static int functionfs_bind_config(struct usb_composite_dev *cdev,
+ struct usb_configuration *c,
+ struct ffs_data *ffs)
__attribute__((warn_unused_result, nonnull));
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 4/7] USB: gadget: composite: usb_string_ids_*() functions added
2010-05-28 10:02 ` [PATCHv2 3/7] USB: gadget: f_fs: functionfs_add() renamed to functionfs_bind_config() Michal Nazarewicz
@ 2010-05-28 10:02 ` Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 5/7] USB: gadget: f_fs: use usb_string_ids_n() Michal Nazarewicz
0 siblings, 1 reply; 9+ messages in thread
From: Michal Nazarewicz @ 2010-05-28 10:02 UTC (permalink / raw)
To: linux-usb; +Cc: David Brownell, Kyungmin Park, Marek Szyprowski, linux-kernel
usb_string_ids_tab() and usb_string_ids_n() functions added to
the composite framework. The first accepts an array of
usb_string object and for each registeres a string id and the
second registeres a given number of ids and returns the first.
This may simplify string ids registration since gadgets and
composite functions won't have to call usb_string_id() several
times and each time check for errer status -- all this will be
done with a single call.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/usb/gadget/composite.c | 67 ++++++++++++++++++++++++++++++++++++++--
include/linux/usb/composite.h | 4 ++
2 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 391d169..cd1a952 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -673,9 +673,10 @@ static int get_string(struct usb_composite_dev *cdev,
* string IDs. Drivers for functions, configurations, or gadgets will
* then store that ID in the appropriate descriptors and string table.
*
- * All string identifier should be allocated using this routine, to
- * ensure that for example different functions don't wrongly assign
- * different meanings to the same identifier.
+ * All string identifier should be allocated using this,
+ * @usb_string_ids_tab() or @usb_string_ids_n() routine, to ensure
+ * that for example different functions don't wrongly assign different
+ * meanings to the same identifier.
*/
int usb_string_id(struct usb_composite_dev *cdev)
{
@@ -687,6 +688,66 @@ int usb_string_id(struct usb_composite_dev *cdev)
return -ENODEV;
}
+/**
+ * usb_string_ids() - allocate unused string IDs in batch
+ * @cdev: the device whose string descriptor IDs are being allocated
+ * @str: an array of usb_string objects to assign numbers to
+ * Context: single threaded during gadget setup
+ *
+ * @usb_string_ids() is called from bind() callbacks to allocate
+ * string IDs. Drivers for functions, configurations, or gadgets will
+ * then copy IDs from the string table to the appropriate descriptors
+ * and string table for other languages.
+ *
+ * All string identifier should be allocated using this,
+ * @usb_string_id() or @usb_string_ids_n() routine, to ensure that for
+ * example different functions don't wrongly assign different meanings
+ * to the same identifier.
+ */
+int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str)
+{
+ int next = cdev->next_string_id;
+
+ for (; str->s; ++str) {
+ if (unlikely(next == 255))
+ return -ENODEV;
+ str->id = ++next;
+ }
+
+ cdev->next_string_id = next;
+
+ return 0;
+}
+
+/**
+ * usb_string_ids_n() - allocate unused string IDs in batch
+ * @cdev: the device whose string descriptor IDs are being allocated
+ * @n: number of string IDs to allocate
+ * Context: single threaded during gadget setup
+ *
+ * Returns the first requested ID. This ID and next @n-1 IDs are now
+ * valid IDs. At least providind that @n is non zore because if it
+ * is, returns last requested ID which is now very useful information.
+ *
+ * @usb_string_ids_n() is called from bind() callbacks to allocate
+ * string IDs. Drivers for functions, configurations, or gadgets will
+ * then store that ID in the appropriate descriptors and string table.
+ *
+ * All string identifier should be allocated using this,
+ * @usb_string_id() or @usb_string_ids_n() routine, to ensure that for
+ * example different functions don't wrongly assign different meanings
+ * to the same identifier.
+ */
+int usb_string_ids_n(struct usb_composite_dev *c, unsigned n)
+{
+ unsigned next = c->next_string_id;
+ if (unlikely(n > 254 || (unsigned)next + n > 255))
+ return -ENODEV;
+ c->next_string_id += n;
+ return next + 1;
+}
+
+
/*-------------------------------------------------------------------------*/
static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req)
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 139353e..f378075 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -342,6 +342,10 @@ struct usb_composite_dev {
};
extern int usb_string_id(struct usb_composite_dev *c);
+extern int usb_string_ids_tab(struct usb_composite_dev *c,
+ struct usb_string *str);
+extern int usb_string_ids_n(struct usb_composite_dev *c, unsigned n);
+
/* messaging utils */
#define DBG(d, fmt, args...) \
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 5/7] USB: gadget: f_fs: use usb_string_ids_n()
2010-05-28 10:02 ` [PATCHv2 4/7] USB: gadget: composite: usb_string_ids_*() functions added Michal Nazarewicz
@ 2010-05-28 10:02 ` Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 6/7] USB: gadget: g_multi: code clean up and refactoring Michal Nazarewicz
2010-05-28 14:53 ` [PATCHv2.1] USB: gadget: f_fs: use usb_string_ids_n() Michal Nazarewicz
0 siblings, 2 replies; 9+ messages in thread
From: Michal Nazarewicz @ 2010-05-28 10:02 UTC (permalink / raw)
To: linux-usb; +Cc: David Brownell, Kyungmin Park, Marek Szyprowski, linux-kernel
Use usb_string_ids_n() function to simplify string ids
registeration.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/usb/gadget/f_fs.c | 30 ++++++++++++------------------
1 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 3fe120f..b121aa1 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1377,7 +1377,8 @@ static void ffs_data_reset(struct ffs_data *ffs)
static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
{
- unsigned i, count;
+ struct usb_gadget_strings **lang;
+ unsigned first_id;
ENTER();
@@ -1385,7 +1386,9 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
|| test_and_set_bit(FFS_FL_BOUND, &ffs->flags)))
return -EBADFD;
- ffs_data_get(ffs);
+ first_id = usb_string_ids_n(cdev, ffs->strings_count);
+ if (unlikely(first_id < 0))
+ return first_id;
ffs->ep0req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);
if (unlikely(!ffs->ep0req))
@@ -1393,25 +1396,16 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
ffs->ep0req->complete = ffs_ep0_complete;
ffs->ep0req->context = ffs;
- /* Get strings identifiers */
- for (count = ffs->strings_count, i = 0; i < count; ++i) {
- struct usb_gadget_strings **lang;
-
- int id = usb_string_id(cdev);
- if (unlikely(id < 0)) {
- usb_ep_free_request(cdev->gadget->ep0, ffs->ep0req);
- ffs->ep0req = NULL;
- return id;
- }
-
- lang = ffs->stringtabs;
- do {
- (*lang)->strings[i].id = id;
- ++lang;
- } while (*lang);
+ lang = ffs->stringtabs;
+ while (*lang) {
+ struct usb_string *str = (*lang)->strings;
+ int id = first_id;
+ for (; str->s; ++id, ++str)
+ str->id = id;
}
ffs->gadget = cdev->gadget;
+ ffs_data_get(ffs);
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 6/7] USB: gadget: g_multi: code clean up and refactoring
2010-05-28 10:02 ` [PATCHv2 5/7] USB: gadget: f_fs: use usb_string_ids_n() Michal Nazarewicz
@ 2010-05-28 10:02 ` Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 7/7] USB: gadget: g_multi: added documentation and INF files Michal Nazarewicz
2010-05-28 14:53 ` [PATCHv2.1] USB: gadget: f_fs: use usb_string_ids_n() Michal Nazarewicz
1 sibling, 1 reply; 9+ messages in thread
From: Michal Nazarewicz @ 2010-05-28 10:02 UTC (permalink / raw)
To: linux-usb; +Cc: David Brownell, Kyungmin Park, Marek Szyprowski, linux-kernel
The Multifunction Compasite Gadget have been cleaned up
and refactored so hopefully it looks prettier and works
at least as good as before changes.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/usb/gadget/Kconfig | 1 +
drivers/usb/gadget/multi.c | 262 +++++++++++++++++++++++++-------------------
2 files changed, 148 insertions(+), 115 deletions(-)
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 649c0c5..1a3270d 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -862,6 +862,7 @@ config USB_G_NOKIA
config USB_G_MULTI
tristate "Multifunction Composite Gadget (EXPERIMENTAL)"
depends on BLOCK && NET
+ select USB_G_MULTI_CDC if ! USB_G_MULTI_RNDIS
help
The Multifunction Composite Gadget provides Ethernet (RNDIS
and/or CDC Ethernet), mass storage and ACM serial link
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index d3d3140..c7a5b58 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/utsname.h>
+#include <linux/module.h>
#if defined USB_ETH_RNDIS
@@ -35,14 +36,13 @@
#define DRIVER_DESC "Multifunction Composite Gadget"
-#define DRIVER_VERSION "2009/07/21"
-/*-------------------------------------------------------------------------*/
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Michal Nazarewicz");
+MODULE_LICENSE("GPL");
-#define MULTI_VENDOR_NUM 0x0525 /* XXX NetChip */
-#define MULTI_PRODUCT_NUM 0xa4ab /* XXX */
-/*-------------------------------------------------------------------------*/
+/***************************** All the files... *****************************/
/*
* kbuild is not very cooperative with respect to linking separately
@@ -57,6 +57,8 @@
#include "config.c"
#include "epautoconf.c"
+#include "f_mass_storage.c"
+
#include "u_serial.c"
#include "f_acm.c"
@@ -68,13 +70,26 @@
#endif
#include "u_ether.c"
-#undef DBG /* u_ether.c has broken idea about macros */
-#undef VDBG /* so clean up after it */
-#undef ERROR
-#undef INFO
-#include "f_mass_storage.c"
-/*-------------------------------------------------------------------------*/
+
+/***************************** Device Descriptor ****************************/
+
+#define MULTI_VENDOR_NUM 0x0525 /* XXX NetChip */
+#define MULTI_PRODUCT_NUM 0xa4ab /* XXX */
+
+
+enum {
+ __MULTI_NO_CONFIG,
+#ifdef CONFIG_USB_G_MULTI_RNDIS
+ MULTI_RNDIS_CONFIG_NUM,
+#endif
+#ifdef CONFIG_USB_G_MULTI_CDC
+ MULTI_CDC_CONFIG_NUM,
+#endif
+ __MULTI_NUM_CONFIGS_HELPER,
+ MULTI_NUM_CONFIGS = __MULTI_NUM_CONFIGS_HELPER - 1
+};
+
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
@@ -82,80 +97,81 @@ static struct usb_device_descriptor device_desc = {
.bcdUSB = cpu_to_le16(0x0200),
- /* .bDeviceClass = USB_CLASS_COMM, */
- /* .bDeviceSubClass = 0, */
- /* .bDeviceProtocol = 0, */
- .bDeviceClass = 0xEF,
+ .bDeviceClass = USB_CLASS_MISC /* 0xEF */,
.bDeviceSubClass = 2,
.bDeviceProtocol = 1,
- /* .bMaxPacketSize0 = f(hardware) */
/* Vendor and product id can be overridden by module parameters. */
.idVendor = cpu_to_le16(MULTI_VENDOR_NUM),
.idProduct = cpu_to_le16(MULTI_PRODUCT_NUM),
- /* .bcdDevice = f(hardware) */
- /* .iManufacturer = DYNAMIC */
- /* .iProduct = DYNAMIC */
- /* NO SERIAL NUMBER */
- .bNumConfigurations = 1,
+ .bNumConfigurations = MULTI_NUM_CONFIGS,
};
-static struct usb_otg_descriptor otg_descriptor = {
- .bLength = sizeof otg_descriptor,
- .bDescriptorType = USB_DT_OTG,
-
- /* REVISIT SRP-only hardware is possible, although
- * it would not be called "OTG" ...
- */
- .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
-};
static const struct usb_descriptor_header *otg_desc[] = {
- (struct usb_descriptor_header *) &otg_descriptor,
+ (struct usb_descriptor_header *) &(struct usb_otg_descriptor){
+ .bLength = sizeof(struct usb_otg_descriptor),
+ .bDescriptorType = USB_DT_OTG,
+
+ /* REVISIT SRP-only hardware is possible, although
+ * it would not be called "OTG" ... */
+ .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
+ },
NULL,
};
-/* string IDs are assigned dynamically */
-
-#define STRING_MANUFACTURER_IDX 0
-#define STRING_PRODUCT_IDX 1
+enum {
+ MULTI_STRING_MANUFACTURER_IDX,
+ MULTI_STRING_PRODUCT_IDX,
+#ifdef CONFIG_USB_G_MULTI_RNDIS
+ MULTI_STRING_RNDIS_CONFIG_IDX,
+#endif
+#ifdef CONFIG_USB_G_MULTI_CDC
+ MULTI_STRING_CDC_CONFIG_IDX,
+#endif
+};
static char manufacturer[50];
static struct usb_string strings_dev[] = {
- [STRING_MANUFACTURER_IDX].s = manufacturer,
- [STRING_PRODUCT_IDX].s = DRIVER_DESC,
+ [MULTI_STRING_MANUFACTURER_IDX].s = manufacturer,
+ [MULTI_STRING_PRODUCT_IDX].s = DRIVER_DESC,
+#ifdef CONFIG_USB_G_MULTI_RNDIS
+ [MULTI_STRING_RNDIS_CONFIG_IDX].s = "Multifunction with RNDIS",
+#endif
+#ifdef CONFIG_USB_G_MULTI_CDC
+ [MULTI_STRING_CDC_CONFIG_IDX].s = "Multifunction with CDC ECM",
+#endif
{ } /* end of list */
};
-static struct usb_gadget_strings stringtab_dev = {
- .language = 0x0409, /* en-us */
- .strings = strings_dev,
-};
-
static struct usb_gadget_strings *dev_strings[] = {
- &stringtab_dev,
+ &(struct usb_gadget_strings){
+ .language = 0x0409, /* en-us */
+ .strings = strings_dev,
+ },
NULL,
};
-static u8 hostaddr[ETH_ALEN];
/****************************** Configurations ******************************/
-static struct fsg_module_parameters mod_data = {
- .stall = 1
-};
-FSG_MODULE_PARAMETERS(/* no prefix */, mod_data);
+static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
+FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+
+static struct fsg_common fsg_common;
+
+static u8 hostaddr[ETH_ALEN];
-static struct fsg_common *fsg_common;
+/********** RNDIS **********/
#ifdef USB_ETH_RNDIS
-static int __init rndis_do_config(struct usb_configuration *c)
+static __ref int rndis_do_config(struct usb_configuration *c)
{
int ret;
@@ -172,26 +188,42 @@ static int __init rndis_do_config(struct usb_configuration *c)
if (ret < 0)
return ret;
- ret = fsg_bind_config(c->cdev, c, fsg_common);
+ ret = fsg_bind_config(c->cdev, c, &fsg_common);
if (ret < 0)
return ret;
return 0;
}
-static struct usb_configuration rndis_config_driver = {
- .label = "Multifunction Composite (RNDIS + MS + ACM)",
- .bind = rndis_do_config,
- .bConfigurationValue = 2,
- /* .iConfiguration = DYNAMIC */
- .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
-};
+static int rndis_config_register(struct usb_composite_dev *cdev)
+{
+ static struct usb_configuration config = {
+ .bind = rndis_do_config,
+ .bConfigurationValue = MULTI_RNDIS_CONFIG_NUM,
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+ };
+
+ config.label = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].s;
+ config.iConfiguration = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].id;
+
+ return usb_add_config(cdev, &config);
+}
+
+#else
+
+static int rndis_config_register(struct usb_composite_dev *cdev)
+{
+ return 0;
+}
#endif
+
+/********** CDC ECM **********/
+
#ifdef CONFIG_USB_G_MULTI_CDC
-static int __init cdc_do_config(struct usb_configuration *c)
+static __ref int cdc_do_config(struct usb_configuration *c)
{
int ret;
@@ -208,20 +240,33 @@ static int __init cdc_do_config(struct usb_configuration *c)
if (ret < 0)
return ret;
- ret = fsg_bind_config(c->cdev, c, fsg_common);
+ ret = fsg_bind_config(c->cdev, c, &fsg_common);
if (ret < 0)
return ret;
return 0;
}
-static struct usb_configuration cdc_config_driver = {
- .label = "Multifunction Composite (CDC + MS + ACM)",
- .bind = cdc_do_config,
- .bConfigurationValue = 1,
- /* .iConfiguration = DYNAMIC */
- .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
-};
+static int cdc_config_register(struct usb_composite_dev *cdev)
+{
+ static struct usb_configuration config = {
+ .bind = cdc_do_config,
+ .bConfigurationValue = MULTI_CDC_CONFIG_NUM,
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+ };
+
+ config.label = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].s;
+ config.iConfiguration = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].id;
+
+ return usb_add_config(cdev, &config);
+}
+
+#else
+
+static int cdc_config_register(struct usb_composite_dev *cdev)
+{
+ return 0;
+}
#endif
@@ -230,7 +275,7 @@ static struct usb_configuration cdc_config_driver = {
/****************************** Gadget Bind ******************************/
-static int __init multi_bind(struct usb_composite_dev *cdev)
+static int __ref multi_bind(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
int status, gcnum;
@@ -252,67 +297,57 @@ static int __init multi_bind(struct usb_composite_dev *cdev)
goto fail0;
/* set up mass storage function */
- fsg_common = fsg_common_from_params(0, cdev, &mod_data);
- if (IS_ERR(fsg_common)) {
- status = PTR_ERR(fsg_common);
- goto fail1;
+ {
+ void *retp;
+ retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
+ if (IS_ERR(retp)) {
+ status = PTR_ERR(retp);
+ goto fail1;
+ }
}
-
+ /* set bcdDevice */
gcnum = usb_gadget_controller_number(gadget);
- if (gcnum >= 0)
+ if (gcnum >= 0) {
device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
- else {
- /* We assume that can_support_ecm() tells the truth;
- * but if the controller isn't recognized at all then
- * that assumption is a bit more likely to be wrong.
- */
- WARNING(cdev, "controller '%s' not recognized\n",
- gadget->name);
+ } else {
+ WARNING(cdev, "controller '%s' not recognized\n", gadget->name);
device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
}
+ /* allocate string descriptor numbers */
- /* Allocate string descriptor numbers ... note that string
- * contents can be overridden by the composite_dev glue.
- */
-
- /* device descriptor strings: manufacturer, product */
snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
init_utsname()->sysname, init_utsname()->release,
gadget->name);
- status = usb_string_id(cdev);
- if (status < 0)
- goto fail2;
- strings_dev[STRING_MANUFACTURER_IDX].id = status;
- device_desc.iManufacturer = status;
- status = usb_string_id(cdev);
- if (status < 0)
+ status = usb_string_ids_tab(cdev, strings_dev);
+ if (unlikely(status < 0))
goto fail2;
- strings_dev[STRING_PRODUCT_IDX].id = status;
- device_desc.iProduct = status;
-#ifdef USB_ETH_RNDIS
- /* register our first configuration */
- status = usb_add_config(cdev, &rndis_config_driver);
- if (status < 0)
+ device_desc.iManufacturer =
+ strings_dev[MULTI_STRING_MANUFACTURER_IDX].id;
+ device_desc.iProduct =
+ strings_dev[MULTI_STRING_PRODUCT_IDX].id;
+
+ /* register configurations */
+ status = rndis_config_register(cdev);
+ if (unlikely(status < 0))
goto fail2;
-#endif
-#ifdef CONFIG_USB_G_MULTI_CDC
- /* register our second configuration */
- status = usb_add_config(cdev, &cdc_config_driver);
- if (status < 0)
+ status = cdc_config_register(cdev);
+ if (unlikely(status < 0))
goto fail2;
-#endif
- dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
- fsg_common_put(fsg_common);
+ /* we're done */
+ dev_info(&gadget->dev, DRIVER_DESC "\n");
+ fsg_common_put(&fsg_common);
return 0;
+
+ /* error recovery */
fail2:
- fsg_common_put(fsg_common);
+ fsg_common_put(&fsg_common);
fail1:
gserial_cleanup();
fail0:
@@ -339,18 +374,15 @@ static struct usb_composite_driver multi_driver = {
.unbind = __exit_p(multi_unbind),
};
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR("Michal Nazarewicz");
-MODULE_LICENSE("GPL");
-static int __init g_multi_init(void)
+static int __init multi_init(void)
{
return usb_composite_register(&multi_driver);
}
-module_init(g_multi_init);
+module_init(multi_init);
-static void __exit g_multi_cleanup(void)
+static void __exit multi_exit(void)
{
usb_composite_unregister(&multi_driver);
}
-module_exit(g_multi_cleanup);
+module_exit(multi_exit);
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 7/7] USB: gadget: g_multi: added documentation and INF files
2010-05-28 10:02 ` [PATCHv2 6/7] USB: gadget: g_multi: code clean up and refactoring Michal Nazarewicz
@ 2010-05-28 10:02 ` Michal Nazarewicz
0 siblings, 0 replies; 9+ messages in thread
From: Michal Nazarewicz @ 2010-05-28 10:02 UTC (permalink / raw)
To: linux-usb; +Cc: David Brownell, Kyungmin Park, Marek Szyprowski, linux-kernel
A short documentation of the g_multi driver along with INF
files for Windows XP SP3 are provided.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Documentation/usb/gadget_multi.txt | 160 +++++++++++++++++++++++
Documentation/usb/gadget_multi_rndis.inf | 200 +++++++++++++++++++++++++++++
Documentation/usb/gadget_multi_serial.inf | 44 +++++++
3 files changed, 404 insertions(+), 0 deletions(-)
create mode 100644 Documentation/usb/gadget_multi.txt
create mode 100644 Documentation/usb/gadget_multi_rndis.inf
create mode 100644 Documentation/usb/gadget_multi_serial.inf
diff --git a/Documentation/usb/gadget_multi.txt b/Documentation/usb/gadget_multi.txt
new file mode 100644
index 0000000..dead74e
--- /dev/null
+++ b/Documentation/usb/gadget_multi.txt
@@ -0,0 +1,160 @@
+ -*- org -*-
+
+* Overview
+
+The Multifunction Composite Gadget (or g_multi) is a customisable
+composite gadget that makes extensive use of the composite framework
+to provide a... multifunction gadget.
+
+In it's standard configuration it provides a single USB configuration
+with RNDIS[1] (that is Ethernet), USB CDC[2] ACM (that is serial) and
+USB Mass Storage functions.
+
+Each function can be disabled via a Kconfig option. There's also
+a CDC ECM (Ethernet) function which can be turned on. If, however,
+CDC ECM and RNDIS are enabled the gadget will have two configurations
+-- one with RNDIS and another with CDC ECM[3].
+
+Please not, however, that if you use non-standard configuration you
+may need to change vendor and/or product ID.
+
+* Host drivers
+
+To make use of the gadget one needs to make it work on host side --
+without that there's no hope of achieving anything with the gadget.
+As one might expect, things one need to do very from system to system.
+
+** Linux host drivers
+
+Since the gadget uses standard composite framework and appears as such
+to Linux host it does not need any additional drivers on Linux host
+side. All the functions are handled by respective drivers designed
+for them.
+
+This is also true for two configuration set-up with RNDIS
+configuration being the first one. Linux host will use the second
+configuration with CDC ECM which should work better under Linux.
+
+** Windows host drivers
+
+For the gadget two work under Windown two conditions have to be met:
+
+*** Detecting as composite gadget
+
+First of all, Windows need to detect the gadget as an USB composite
+gadget which on its own have some conditions[4]. If they are met,
+Windows lets USB Generic Parent Driver[5] handle the device which then
+tries to much drivers for each individual interface (sort of, don't
+get into too many details).
+
+The good news is, you do not have to worry about most of conditions!
+
+The only thing to worry is that the gadget has to have a single
+configuration so a dual RNDIS and CDC ECM gadget won't work unless you
+create a proper INF -- and of course, if you do submit it!
+
+*** Attaching drivers for each function
+
+The other, trickier thing is making Windows attach drivers to each
+individual function.
+
+For mass storage it is trivial since Windows detect it's an interface
+implementing USB Mass Storage class and selects appropriate driver.
+
+Things are harder with RDNIS and CDC ACM.
+
+**** RNDIS
+
+To make Windows select RNDIS drivers for the first function in the
+gadget, one needs to use the [[file:gadget_multi_rndis.inf]] file
+provided with this document. It "attaches" Window's RNDIS driver to
+the first interface of the gadget.
+
+Please note, that while testing we encountered some issues[6] when
+RNDIS was not the first interface. You do not need to worry abut it
+unless you are trying to develop your own gadget in which case watch
+out for this bug.
+
+**** CDC ACM
+
+Similarly, [[file:gadget_multi_serial.inf]] is provided for CDC ACM.
+Note, however that it also requires an usbser.sys file which can be
+extracted form Windows XP SP3 cab files.
+
+There is another usbser.sys file floating around the Internet but as
+we were testing the gadget it failed to work. It is very likely that
+one needs usbser.sys in version intended for one's version of Windows.
+
+We do net claim to be experts as far as INF files are considered so we
+think that there should be a better way of defining files in the
+[[file:gadget_multi_serial.inf]] so that it will work regardless of SP
+version installed. Again, if you happen to hack a better INF do not
+hesitate submitting it!
+
+**** Customising the gadget
+
+If you intend to hack the g_multi gadget be advised that rearranging
+functions will obviously change interface numbers for each of the
+functionality. As an effect provided INFs won't work since they have
+interface numbers hard-coded in them (it's not hard to change those
+though).
+
+This also means, that after experimenting with g_multi and changing
+provided functions one should change gadget's vendor and/or product ID
+so there will be no collision with other customised gadgets or the
+original gadget.
+
+Failing to comply may cause brain damage after wondering for hours why
+things don't work as intended before realising Windows have cached
+some drivers information (changing USB port may sometimes help).
+
+**** Improvements in INF files
+
+It needs to be noted that we are not Windows driver experts and as
+such we do not claim that provided INF files are flawless or that they
+will work on each and every Windows versions (they were tested on
+Windows XP SP3 only).
+
+The bottom line is, if you can improve the INF files, please do and
+share the results[7]. :)
+
+** Other systems
+
+At this moment, drivers for any other systems have not been tested.
+Knowing how MacOS is based on BSD and BSD is an Open Source it is
+believed that it should (read: "I have no idea whether it will") work
+out-of-the-box.
+
+For more exotic systems I have even less to say...
+
+Any testing and drivers *are* *welcome*!
+
+* Authors
+
+This document has been written by Michal Nazarewicz
+([[mailto:mina86@mina86.com]]) and the INF files have been hacked by
+Marek Szyprowski ([[mailto:m.szyprowski@samsung.com]]) basing on the
+[[file:linux.inf]] file provided for Ethernet gadget and description
+from [[file:gadget_serial.txt]].
+
+* Footnotes
+
+[1] Remote Network Driver Interface Specification,
+[[http://msdn.microsoft.com/en-us/library/ee484414.aspx]].
+
+[2] Communications Device Class Abstract Control Model, spec for this
+and other USB classes can be found at
+[[http://www.usb.org/developers/devclass_docs/]].
+
+[3] CDC Ethernet Control Model.
+
+[4] [[http://msdn.microsoft.com/en-us/library/ff537109(v=VS.85).aspx]].
+
+[5] [[http://msdn.microsoft.com/en-us/library/ff539234(v=VS.85).aspx]].
+
+[6] To put it in some other nice words, Windows failed to respond to
+any user input.
+
+[7] Possibility to say `git rev-list --author='Your Name'
+linus/master|wc -l` returns non-zero -- priceless. :]
+
diff --git a/Documentation/usb/gadget_multi_rndis.inf b/Documentation/usb/gadget_multi_rndis.inf
new file mode 100644
index 0000000..9bd13a9
--- /dev/null
+++ b/Documentation/usb/gadget_multi_rndis.inf
@@ -0,0 +1,200 @@
+; MS-Windows driver config matching some basic modes of the
+; Linux-USB Ethernet/RNDIS gadget firmware:
+;
+; - RNDIS plus CDC Ethernet ... this may be familiar as a DOCSIS
+; cable modem profile, and supports most non-Microsoft USB hosts
+;
+; - RNDIS plus CDC Subset ... used by hardware that incapable of
+; full CDC Ethernet support.
+;
+; Microsoft only directly supports RNDIS drivers, and bundled them into XP.
+; The Microsoft "Remote NDIS USB Driver Kit" is currently found at:
+; http://www.microsoft.com/whdc/hwdev/resources/HWservices/rndis.mspx
+
+
+[Version]
+Signature = "$CHICAGO$"
+Class = Net
+ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
+Provider = %Linux%
+Compatible = 1
+MillenniumPreferred = .ME
+DriverVer = 03/30/2004,0.0.0.0
+; catalog file would be used by WHQL
+;CatalogFile = Linux.cat
+
+[Manufacturer]
+%Linux% = LinuxDevices,NT.5.1
+
+[LinuxDevices]
+; NetChip IDs, used by both firmware modes
+%LinuxDevice% = RNDIS, USB\VID_0525&PID_a4ab&MI_00
+
+[LinuxDevices.NT.5.1]
+%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4ab&MI_00
+
+[ControlFlags]
+ExcludeFromSelect=*
+
+; Windows 98, Windows 98 Second Edition specific sections --------
+
+[RNDIS]
+DeviceID = usb8023
+MaxInstance = 512
+DriverVer = 03/30/2004,0.0.0.0
+AddReg = RNDIS_AddReg_98, RNDIS_AddReg_Common
+
+[RNDIS_AddReg_98]
+HKR, , DevLoader, 0, *ndis
+HKR, , DeviceVxDs, 0, usb8023.sys
+HKR, NDIS, LogDriverName, 0, "usb8023"
+HKR, NDIS, MajorNdisVersion, 1, 5
+HKR, NDIS, MinorNdisVersion, 1, 0
+HKR, Ndi\Interfaces, DefUpper, 0, "ndis3,ndis4,ndis5"
+HKR, Ndi\Interfaces, DefLower, 0, "ethernet"
+HKR, Ndi\Interfaces, UpperRange, 0, "ndis3,ndis4,ndis5"
+HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
+HKR, Ndi\Install, ndis3, 0, "RNDIS_Install_98"
+HKR, Ndi\Install, ndis4, 0, "RNDIS_Install_98"
+HKR, Ndi\Install, ndis5, 0, "RNDIS_Install_98"
+HKR, Ndi, DeviceId, 0, "USB\VID_0525&PID_a4ab&MI_00"
+
+[RNDIS_Install_98]
+CopyFiles=RNDIS_CopyFiles_98
+
+[RNDIS_CopyFiles_98]
+usb8023.sys, usb8023w.sys, , 0
+rndismp.sys, rndismpw.sys, , 0
+
+; Windows Millennium Edition specific sections --------------------
+
+[RNDIS.ME]
+DeviceID = usb8023
+MaxInstance = 512
+DriverVer = 03/30/2004,0.0.0.0
+AddReg = RNDIS_AddReg_ME, RNDIS_AddReg_Common
+Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
+BusType = 15
+
+[RNDIS_AddReg_ME]
+HKR, , DevLoader, 0, *ndis
+HKR, , DeviceVxDs, 0, usb8023.sys
+HKR, NDIS, LogDriverName, 0, "usb8023"
+HKR, NDIS, MajorNdisVersion, 1, 5
+HKR, NDIS, MinorNdisVersion, 1, 0
+HKR, Ndi\Interfaces, DefUpper, 0, "ndis3,ndis4,ndis5"
+HKR, Ndi\Interfaces, DefLower, 0, "ethernet"
+HKR, Ndi\Interfaces, UpperRange, 0, "ndis3,ndis4,ndis5"
+HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
+HKR, Ndi\Install, ndis3, 0, "RNDIS_Install_ME"
+HKR, Ndi\Install, ndis4, 0, "RNDIS_Install_ME"
+HKR, Ndi\Install, ndis5, 0, "RNDIS_Install_ME"
+HKR, Ndi, DeviceId, 0, "USB\VID_0525&PID_a4ab&MI_00"
+
+[RNDIS_Install_ME]
+CopyFiles=RNDIS_CopyFiles_ME
+
+[RNDIS_CopyFiles_ME]
+usb8023.sys, usb8023m.sys, , 0
+rndismp.sys, rndismpm.sys, , 0
+
+; Windows 2000 specific sections ---------------------------------
+
+[RNDIS.NT]
+Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
+BusType = 15
+DriverVer = 03/30/2004,0.0.0.0
+AddReg = RNDIS_AddReg_NT, RNDIS_AddReg_Common
+CopyFiles = RNDIS_CopyFiles_NT
+
+[RNDIS.NT.Services]
+AddService = USB_RNDIS, 2, RNDIS_ServiceInst_NT, RNDIS_EventLog
+
+[RNDIS_CopyFiles_NT]
+; no rename of files on Windows 2000, use the 'k' names as is
+usb8023k.sys, , , 0
+rndismpk.sys, , , 0
+
+[RNDIS_ServiceInst_NT]
+DisplayName = %ServiceDisplayName%
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %12%\usb8023k.sys
+LoadOrderGroup = NDIS
+AddReg = RNDIS_WMI_AddReg_NT
+
+[RNDIS_WMI_AddReg_NT]
+HKR, , MofImagePath, 0x00020000, "System32\drivers\rndismpk.sys"
+
+; Windows XP specific sections -----------------------------------
+
+[RNDIS.NT.5.1]
+Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
+BusType = 15
+DriverVer = 03/30/2004,0.0.0.0
+AddReg = RNDIS_AddReg_NT, RNDIS_AddReg_Common
+; no copyfiles - the files are already in place
+
+[RNDIS.NT.5.1.Services]
+AddService = USB_RNDIS, 2, RNDIS_ServiceInst_51, RNDIS_EventLog
+
+[RNDIS_ServiceInst_51]
+DisplayName = %ServiceDisplayName%
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %12%\usb8023.sys
+LoadOrderGroup = NDIS
+AddReg = RNDIS_WMI_AddReg_51
+
+[RNDIS_WMI_AddReg_51]
+HKR, , MofImagePath, 0x00020000, "System32\drivers\rndismp.sys"
+
+; Windows 2000 and Windows XP common sections --------------------
+
+[RNDIS_AddReg_NT]
+HKR, Ndi, Service, 0, "USB_RNDIS"
+HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
+HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
+
+[RNDIS_EventLog]
+AddReg = RNDIS_EventLog_AddReg
+
+[RNDIS_EventLog_AddReg]
+HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\netevent.dll"
+HKR, , TypesSupported, 0x00010001, 7
+
+; Common Sections -------------------------------------------------
+
+[RNDIS_AddReg_Common]
+HKR, NDI\params\NetworkAddress, ParamDesc, 0, %NetworkAddress%
+HKR, NDI\params\NetworkAddress, type, 0, "edit"
+HKR, NDI\params\NetworkAddress, LimitText, 0, "12"
+HKR, NDI\params\NetworkAddress, UpperCase, 0, "1"
+HKR, NDI\params\NetworkAddress, default, 0, " "
+HKR, NDI\params\NetworkAddress, optional, 0, "1"
+
+[SourceDisksNames]
+1=%SourceDisk%,,1
+
+[SourceDisksFiles]
+usb8023m.sys=1
+rndismpm.sys=1
+usb8023w.sys=1
+rndismpw.sys=1
+usb8023k.sys=1
+rndismpk.sys=1
+
+[DestinationDirs]
+RNDIS_CopyFiles_98 = 10, system32/drivers
+RNDIS_CopyFiles_ME = 10, system32/drivers
+RNDIS_CopyFiles_NT = 12
+
+[Strings]
+ServiceDisplayName = "USB Remote NDIS Network Device Driver"
+NetworkAddress = "Network Address"
+Linux = "Linux Developer Community"
+LinuxDevice = "RNDIS Gadget/Linux Multifunction Gadget"
+SourceDisk = "Linux RNDIS Gadget Driver Install Disk"
+
diff --git a/Documentation/usb/gadget_multi_serial.inf b/Documentation/usb/gadget_multi_serial.inf
new file mode 100644
index 0000000..984232f
--- /dev/null
+++ b/Documentation/usb/gadget_multi_serial.inf
@@ -0,0 +1,44 @@
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%LINUX%
+DriverVer=08/17/2004,0.0.2.1
+; Copyright (C) 2004 Al Borchers (alborchers@steinerpoint.com)
+
+[Manufacturer]
+%LINUX%=GSerialDeviceList
+
+[GSerialDeviceList]
+%GSERIAL%=GSerialInstall, USB\VID_0525&PID_A4AB&MI_02
+
+[DestinationDirs]
+DefaultDestDir=10,System32\Drivers
+
+[GSerialInstall]
+CopyFiles=GSerialCopyFiles
+AddReg=GSerialAddReg
+
+[GSerialCopyFiles]
+usbser.sys
+
+[GSerialAddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[GSerialInstall.Services]
+AddService = usbser,0x0002,GSerialService
+
+[GSerialService]
+DisplayName = %GSERIAL_DISPLAY_NAME%
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER
+StartType = 3 ; SERVICE_DEMAND_START
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL
+ServiceBinary = %10%\System32\Drivers\usbser.sys
+LoadOrderGroup = Base
+
+[Strings]
+LINUX = "Linux"
+GSERIAL = "Serial Gadget/Linux Multifunction Gadget"
+GSERIAL_DISPLAY_NAME = "Serial Gadget/Linux Multifunction Gadget"
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2.1] USB: gadget: f_fs: use usb_string_ids_n()
2010-05-28 10:02 ` [PATCHv2 5/7] USB: gadget: f_fs: use usb_string_ids_n() Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 6/7] USB: gadget: g_multi: code clean up and refactoring Michal Nazarewicz
@ 2010-05-28 14:53 ` Michal Nazarewicz
1 sibling, 0 replies; 9+ messages in thread
From: Michal Nazarewicz @ 2010-05-28 14:53 UTC (permalink / raw)
To: linux-usb; +Cc: David Brownell, Kyungmin Park, Marek Szyprowski, linux-kernel
Use usb_string_ids_n() function to simplify string ids
registeration.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
This fixes to silly bugs in my previous patch. One was that first_id
was unsigned should "first_id < 0" would be always false and in the
"lang" loop I forgot to include ++lang.
drivers/usb/gadget/f_fs.c | 29 +++++++++++------------------
1 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 3fe120f..b7c4905 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1377,7 +1377,8 @@ static void ffs_data_reset(struct ffs_data *ffs)
static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
{
- unsigned i, count;
+ struct usb_gadget_strings **lang;
+ int first_id;
ENTER();
@@ -1385,7 +1386,9 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
|| test_and_set_bit(FFS_FL_BOUND, &ffs->flags)))
return -EBADFD;
- ffs_data_get(ffs);
+ first_id = usb_string_ids_n(cdev, ffs->strings_count);
+ if (unlikely(first_id < 0))
+ return first_id;
ffs->ep0req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);
if (unlikely(!ffs->ep0req))
@@ -1393,25 +1396,15 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
ffs->ep0req->complete = ffs_ep0_complete;
ffs->ep0req->context = ffs;
- /* Get strings identifiers */
- for (count = ffs->strings_count, i = 0; i < count; ++i) {
- struct usb_gadget_strings **lang;
-
- int id = usb_string_id(cdev);
- if (unlikely(id < 0)) {
- usb_ep_free_request(cdev->gadget->ep0, ffs->ep0req);
- ffs->ep0req = NULL;
- return id;
- }
-
- lang = ffs->stringtabs;
- do {
- (*lang)->strings[i].id = id;
- ++lang;
- } while (*lang);
+ for (lang = ffs->stringtabs; *lang; ++lang) {
+ struct usb_string *str = (*lang)->strings;
+ unsigned id = first_id;
+ for (; str->s; ++id, ++str)
+ str->id = id;
}
ffs->gadget = cdev->gadget;
+ ffs_data_get(ffs);
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-05-28 14:52 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-28 10:02 [PATCHv2 0/7] Several improvements to USB gadgets Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 1/7] USB: gadget: g_mass_storage: static data instead of dynamic allocation Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 2/7] USB: gadget: f_mass_storage: fsg_add() renamed to fsg_bind_config() Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 3/7] USB: gadget: f_fs: functionfs_add() renamed to functionfs_bind_config() Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 4/7] USB: gadget: composite: usb_string_ids_*() functions added Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 5/7] USB: gadget: f_fs: use usb_string_ids_n() Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 6/7] USB: gadget: g_multi: code clean up and refactoring Michal Nazarewicz
2010-05-28 10:02 ` [PATCHv2 7/7] USB: gadget: g_multi: added documentation and INF files Michal Nazarewicz
2010-05-28 14:53 ` [PATCHv2.1] USB: gadget: f_fs: use usb_string_ids_n() Michal Nazarewicz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox