Commit f2adc4f8 authored by Michal Nazarewicz's avatar Michal Nazarewicz Committed by Greg Kroah-Hartman

USB: gadget: composite: usb_string_ids_*() functions added

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: default avatarMichal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7898aee1
...@@ -673,20 +673,83 @@ static int get_string(struct usb_composite_dev *cdev, ...@@ -673,20 +673,83 @@ static int get_string(struct usb_composite_dev *cdev,
* string IDs. Drivers for functions, configurations, or gadgets will * string IDs. Drivers for functions, configurations, or gadgets will
* then store that ID in the appropriate descriptors and string table. * then store that ID in the appropriate descriptors and string table.
* *
* All string identifier should be allocated using this routine, to * All string identifier should be allocated using this,
* ensure that for example different functions don't wrongly assign * @usb_string_ids_tab() or @usb_string_ids_n() routine, to ensure
* different meanings to the same identifier. * that for example different functions don't wrongly assign different
* meanings to the same identifier.
*/ */
int usb_string_id(struct usb_composite_dev *cdev) int usb_string_id(struct usb_composite_dev *cdev)
{ {
if (cdev->next_string_id < 254) { if (cdev->next_string_id < 254) {
/* string id 0 is reserved */ /* string id 0 is reserved by USB spec for list of
* supported languages */
/* 255 reserved as well? -- mina86 */
cdev->next_string_id++; cdev->next_string_id++;
return cdev->next_string_id; return cdev->next_string_id;
} }
return -ENODEV; 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 >= 254))
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 > 254))
return -ENODEV;
c->next_string_id += n;
return next + 1;
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req)
......
...@@ -342,6 +342,10 @@ struct usb_composite_dev { ...@@ -342,6 +342,10 @@ struct usb_composite_dev {
}; };
extern int usb_string_id(struct usb_composite_dev *c); 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 */ /* messaging utils */
#define DBG(d, fmt, args...) \ #define DBG(d, fmt, args...) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment