[PATCH] usb: core: message: remove extra endianness conversion in usb_set_isoch_delay

2018-05-25 Thread Ruslan Bilovol
No need to do extra endianness conversion in
usb_set_isoch_delay because it is already done
in usb_control_msg()

Fixes: 886ee36e7205 ("usb: core: add support for USB_REQ_SET_ISOCH_DELAY")
Cc: Dmytro Panchenko <dmytro.panche...@globallogic.com>
Cc: Felipe Balbi <felipe.ba...@linux.intel.com>
Cc: stable <sta...@vger.kernel.org> # v4.16+
Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/core/message.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 0c11d40..7b13700 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -940,7 +940,7 @@ int usb_set_isoch_delay(struct usb_device *dev)
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_ISOCH_DELAY,
USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
-   cpu_to_le16(dev->hub_delay), 0, NULL, 0,
+   dev->hub_delay, 0, NULL, 0,
USB_CTRL_SET_TIMEOUT);
 }
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/1] USB Audio Device Class 3.0 Gadget support

2017-12-07 Thread Ruslan Bilovol
Hi Felipe,

On Mon, Dec 4, 2017 at 1:36 PM, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Ruslan Bilovol <ruslan.bilo...@gmail.com> writes:
>> On Tue, Nov 7, 2017 at 3:52 AM, Ruslan Bilovol <ruslan.bilo...@gmail.com> 
>> wrote:
>>> Hi,
>>>
>>> This patch adds USB Audio Device Class 3.0 [1] function
>>> support to gadget subsystem.
>>> I didn't add UAC3 support to legacy gadget as it will
>>> make preprocessor configuration too complex (UAC3 device
>>> must have two configurations for backward compatibility,
>>> first is UAC1/2 and second is UAC3), yet also I'm too lazy
>>> to do that and verify all possible configurations.
>>>
>>> For modern ConfigFS interface I'll provide my configuration
>>> for testing below; testing was done on a BeagleBone Black
>>> board.
>>>
>>> This patch depends on uac3 header files from include dir
>>> which I'll post as part of ALSA host UAC3 patch and will
>>> provide the link to it here.
>>
>> http://www.spinics.net/lists/alsa-devel/msg69071.html
>
> Once that patch hits upstream, then we can queue this for merge window
> otherwise we will just have issues and create unbisectable points in the
> tree.

Takashi promised to create an immutable branch for that purpose.

However, I'm currently reworking configfs part of UAC3 for channels
configuration handling, which is now more clear after sharing missing
parts of UAC3 spec by Pierre-Louis Bossart during host side patches
review; so I will send v2 soon.

Thanks,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/1] USB Audio Device Class 3.0 Gadget support

2017-11-06 Thread Ruslan Bilovol
On Tue, Nov 7, 2017 at 3:52 AM, Ruslan Bilovol <ruslan.bilo...@gmail.com> wrote:
> Hi,
>
> This patch adds USB Audio Device Class 3.0 [1] function
> support to gadget subsystem.
> I didn't add UAC3 support to legacy gadget as it will
> make preprocessor configuration too complex (UAC3 device
> must have two configurations for backward compatibility,
> first is UAC1/2 and second is UAC3), yet also I'm too lazy
> to do that and verify all possible configurations.
>
> For modern ConfigFS interface I'll provide my configuration
> for testing below; testing was done on a BeagleBone Black
> board.
>
> This patch depends on uac3 header files from include dir
> which I'll post as part of ALSA host UAC3 patch and will
> provide the link to it here.

http://www.spinics.net/lists/alsa-devel/msg69071.html

Thanks,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/1] USB Audio Device Class 3.0 Gadget support

2017-11-06 Thread Ruslan Bilovol
Hi,

This patch adds USB Audio Device Class 3.0 [1] function
support to gadget subsystem.
I didn't add UAC3 support to legacy gadget as it will
make preprocessor configuration too complex (UAC3 device
must have two configurations for backward compatibility,
first is UAC1/2 and second is UAC3), yet also I'm too lazy
to do that and verify all possible configurations.

For modern ConfigFS interface I'll provide my configuration
for testing below; testing was done on a BeagleBone Black
board.

This patch depends on uac3 header files from include dir
which I'll post as part of ALSA host UAC3 patch and will
provide the link to it here.

uac_3

mkdir cfg
mount none cfg -t configfs
mkdir cfg/usb_gadget/g1
cd cfg/usb_gadget/g1
mkdir configs/c.1
mkdir functions/uac3.0
mkdir strings/0x409
mkdir configs/c.1/strings/0x409
echo 0x0101 > idProduct
echo 0x1d6b > idVendor
echo my-serial-num > strings/0x409/serialnumber
echo my-manufacturer > strings/0x409/manufacturer
echo "Test gadget" > strings/0x409/product
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
ln -s functions/uac3.0 configs/c.1
echo musb-hdrc.0 > UDC

uac_3 + uac2

mkdir cfg
mount none cfg -t configfs
mkdir cfg/usb_gadget/g1
cd cfg/usb_gadget/g1
mkdir configs/c.1
mkdir functions/uac2.0
mkdir strings/0x409
mkdir configs/c.1/strings/0x409
echo "Test gadget" > strings/0x409/product
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
ln -s functions/uac2.0 configs/c.1
mkdir configs/c.2
mkdir functions/uac3.0
mkdir strings/0x409
mkdir configs/c.2/strings/0x409
echo "Conf 2" > configs/c.2/strings/0x409/configuration
echo 120 > configs/c.2/MaxPower
ln -s functions/uac3.0 configs/c.2
echo 0x0101 > idProduct
echo 0x1d6b > idVendor
echo my-serial-num > strings/0x409/serialnumber
echo my-manufacturer > strings/0x409/manufacturer
echo musb-hdrc.0 > UDC


[1] http://www.usb.org/developers/docs/devclass_docs/USB_Audio_v3.0.zip

Ruslan Bilovol (1):
  usb: gadget: add USB Audio Device Class 3.0 gadget support

 Documentation/ABI/testing/configfs-usb-gadget-uac3 |   14 +
 Documentation/usb/gadget-testing.txt   |   41 +
 drivers/usb/gadget/Kconfig |   22 +
 drivers/usb/gadget/function/Makefile   |2 +
 drivers/usb/gadget/function/f_uac3.c   | 1497 
 drivers/usb/gadget/function/u_uac3.h   |   38 +
 drivers/usb/gadget/legacy/Kconfig  |3 +-
 7 files changed, 1616 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac3
 create mode 100644 drivers/usb/gadget/function/f_uac3.c
 create mode 100644 drivers/usb/gadget/function/u_uac3.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/1] usb: gadget: add USB Audio Device Class 3.0 gadget support

2017-11-06 Thread Ruslan Bilovol
Recently released USB Audio Class 3.0 specification
introduces many significant changes comparing to
previous versions, like
 - new Power Domains, support for LPM/L1
 - new Cluster descriptor
 - changed layout of all class-specific descriptors
 - new High Capability descriptors
 - New class-specific String descriptors
 - new and removed units
 - additional sources for interrupts
 - removed Type II Audio Data Formats
 - ... and many other things (check spec)

It also provides backward compatibility through
multiple configurations, as well as requires
mandatory support for BADD (Basic Audio Device
Definition) on each ADC3.0 compliant device

This patch adds UAC3 gadget support basing on UAC3
specification, implementing Generic I/O Profile
(BAOF + BAIF) from BADD document.

There are still few areas for future improvements
because not all functionality is completely
implemented, for example volume, mute and
power management handling has dummy implementation
in some places

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 Documentation/ABI/testing/configfs-usb-gadget-uac3 |   14 +
 Documentation/usb/gadget-testing.txt   |   41 +
 drivers/usb/gadget/Kconfig |   22 +
 drivers/usb/gadget/function/Makefile   |2 +
 drivers/usb/gadget/function/f_uac3.c   | 1497 
 drivers/usb/gadget/function/u_uac3.h   |   38 +
 drivers/usb/gadget/legacy/Kconfig  |3 +-
 7 files changed, 1616 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac3
 create mode 100644 drivers/usb/gadget/function/f_uac3.c
 create mode 100644 drivers/usb/gadget/function/u_uac3.h

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac3 
b/Documentation/ABI/testing/configfs-usb-gadget-uac3
new file mode 100644
index 000..54bb00e
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-usb-gadget-uac3
@@ -0,0 +1,14 @@
+What:  /config/usb-gadget/gadget/functions/uac3.name
+Date:  Nov 2017
+KernelVersion: 4.16
+Description:
+   The attributes:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
+   req_number - the number of pre-allocated request
+   for both capture and playback
diff --git a/Documentation/usb/gadget-testing.txt 
b/Documentation/usb/gadget-testing.txt
index fbc397d..36d5e2b 100644
--- a/Documentation/usb/gadget-testing.txt
+++ b/Documentation/usb/gadget-testing.txt
@@ -21,6 +21,7 @@ provided by gadgets.
 18. UVC function
 19. PRINTER function
 20. UAC1 function (new API)
+21. UAC3 function
 
 
 1. ACM function
@@ -817,3 +818,43 @@ e.g.:
 
 $ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \
 aplay -D default:CARD=OdroidU3
+
+21. UAC3 function
+=
+
+The function is provided by usb_f_uac3.ko module.
+
+Function-specific configfs interface
+
+
+The function name to use when creating the function directory is "uac3".
+The uac3 function provides these attributes in its function directory:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
+   req_number - the number of pre-allocated request for both capture
+and playback
+
+The attributes have sane default values.
+
+Testing the UAC3 function
+-
+
+device: run the gadget
+host: aplay -l # should list our USB Audio Gadget
+
+This function does not require real hardware support, it just
+sends a stream of audio data to/from the host. In order to
+actually hear something at the device side, a command similar
+to this must be used at the device side:
+
+$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 &
+
+e.g.:
+
+$ arecord -f dat -t wav -D hw:CARD=UAC3Gadget,DEV=0 | \
+aplay -D default:CARD=OdroidU3
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 31cce78..d53ae7d 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -200,6 +200,9 @@ config USB_F_UAC1_LEGACY
 config USB_F_UAC2
tristate
 
+config USB_F_UAC3
+   tristate
+
 config USB_F_UVC
tristate
 
@@ -418,6 +421,25 @@ config USB_CONFIGFS_F_UAC2
  received from the USB Host and choose to provide whatever it
  wants as audio data to the USB Host.
 
+config USB_CONFIGFS_F_UAC3
+   bool "Audio Class 3.0"
+   depends on USB_CONFIGFS
+   depends on SND
+   select USB_LIBCOMPOSITE
+   select SND_PCM
+   select USB_U_A

[PATCH 1/3] include: usb: audio: specify exact endiannes of descriptors

2017-06-25 Thread Ruslan Bilovol
USB spec says that multiple byte fields are stored in
little-endian order (see chapter 8.1 of USB2.0 spec and
chapter 7.1 of USB3.0 spec), thus mark such fields as LE
for UAC1 and UAC2 headers

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 include/linux/usb/audio-v2.h   | 14 +++---
 include/uapi/linux/usb/audio.h |  6 +++---
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h
index c5f2158..fd73bc0 100644
--- a/include/linux/usb/audio-v2.h
+++ b/include/linux/usb/audio-v2.h
@@ -115,13 +115,13 @@ struct uac2_input_terminal_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bTerminalID;
-   __u16 wTerminalType;
+   __le16 wTerminalType;
__u8 bAssocTerminal;
__u8 bCSourceID;
__u8 bNrChannels;
-   __u32 bmChannelConfig;
+   __le32 bmChannelConfig;
__u8 iChannelNames;
-   __u16 bmControls;
+   __le16 bmControls;
__u8 iTerminal;
 } __attribute__((packed));
 
@@ -132,11 +132,11 @@ struct uac2_output_terminal_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bTerminalID;
-   __u16 wTerminalType;
+   __le16 wTerminalType;
__u8 bAssocTerminal;
__u8 bSourceID;
__u8 bCSourceID;
-   __u16 bmControls;
+   __le16 bmControls;
__u8 iTerminal;
 } __attribute__((packed));
 
@@ -164,9 +164,9 @@ struct uac2_as_header_descriptor {
__u8 bTerminalLink;
__u8 bmControls;
__u8 bFormatType;
-   __u32 bmFormats;
+   __le32 bmFormats;
__u8 bNrChannels;
-   __u32 bmChannelConfig;
+   __le32 bmChannelConfig;
__u8 iChannelNames;
 } __attribute__((packed));
 
diff --git a/include/uapi/linux/usb/audio.h b/include/uapi/linux/usb/audio.h
index d2314be..a4680a5 100644
--- a/include/uapi/linux/usb/audio.h
+++ b/include/uapi/linux/usb/audio.h
@@ -333,7 +333,7 @@ struct uac_processing_unit_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
-   __u16 wProcessType;
+   __le16 wProcessType;
__u8 bNrInPins;
__u8 baSourceID[];
 } __attribute__ ((packed));
@@ -491,8 +491,8 @@ struct uac_format_type_ii_ext_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
-   __u16 wMaxBitRate;
-   __u16 wSamplesPerFrame;
+   __le16 wMaxBitRate;
+   __le16 wSamplesPerFrame;
__u8 bHeaderLength;
__u8 bSideBandProtocol;
 } __attribute__((packed));
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] usb: gadget: f_uac1: endianness fixes.

2017-06-25 Thread Ruslan Bilovol
As per USB spec, multiple-bytes fields are stored
in little-endian order. Use CPU<->LE helpers for
such fields.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/function/f_uac1.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac1.c 
b/drivers/usb/gadget/function/f_uac1.c
index 8656f84..29efbed 100644
--- a/drivers/usb/gadget/function/f_uac1.c
+++ b/drivers/usb/gadget/function/f_uac1.c
@@ -92,9 +92,9 @@ static inline struct f_uac1 *func_to_uac1(struct usb_function 
*f)
.bDescriptorType =  USB_DT_CS_INTERFACE,
.bDescriptorSubtype =   UAC_INPUT_TERMINAL,
.bTerminalID =  USB_OUT_IT_ID,
-   .wTerminalType =UAC_TERMINAL_STREAMING,
+   .wTerminalType =cpu_to_le16(UAC_TERMINAL_STREAMING),
.bAssocTerminal =   0,
-   .wChannelConfig =   0x3,
+   .wChannelConfig =   cpu_to_le16(0x3),
 };
 
 #define IO_OUT_OT_ID   2
@@ -103,7 +103,7 @@ static inline struct f_uac1 *func_to_uac1(struct 
usb_function *f)
.bDescriptorType= USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
.bTerminalID= IO_OUT_OT_ID,
-   .wTerminalType  = UAC_OUTPUT_TERMINAL_SPEAKER,
+   .wTerminalType  = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER),
.bAssocTerminal = 0,
.bSourceID  = USB_OUT_IT_ID,
 };
@@ -114,9 +114,9 @@ static inline struct f_uac1 *func_to_uac1(struct 
usb_function *f)
.bDescriptorType= USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_INPUT_TERMINAL,
.bTerminalID= IO_IN_IT_ID,
-   .wTerminalType  = UAC_INPUT_TERMINAL_MICROPHONE,
+   .wTerminalType  = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE),
.bAssocTerminal = 0,
-   .wChannelConfig = 0x3,
+   .wChannelConfig = cpu_to_le16(0x3),
 };
 
 #define USB_IN_OT_ID   4
@@ -125,7 +125,7 @@ static inline struct f_uac1 *func_to_uac1(struct 
usb_function *f)
.bDescriptorType =  USB_DT_CS_INTERFACE,
.bDescriptorSubtype =   UAC_OUTPUT_TERMINAL,
.bTerminalID =  USB_IN_OT_ID,
-   .wTerminalType =UAC_TERMINAL_STREAMING,
+   .wTerminalType =cpu_to_le16(UAC_TERMINAL_STREAMING),
.bAssocTerminal =   0,
.bSourceID =IO_IN_IT_ID,
 };
@@ -174,7 +174,7 @@ static inline struct f_uac1 *func_to_uac1(struct 
usb_function *f)
.bDescriptorSubtype =   UAC_AS_GENERAL,
.bTerminalLink =USB_OUT_IT_ID,
.bDelay =   1,
-   .wFormatTag =   UAC_FORMAT_TYPE_I_PCM,
+   .wFormatTag =   cpu_to_le16(UAC_FORMAT_TYPE_I_PCM),
 };
 
 static struct uac1_as_header_descriptor as_in_header_desc = {
@@ -183,7 +183,7 @@ static inline struct f_uac1 *func_to_uac1(struct 
usb_function *f)
.bDescriptorSubtype =   UAC_AS_GENERAL,
.bTerminalLink =USB_IN_OT_ID,
.bDelay =   1,
-   .wFormatTag =   UAC_FORMAT_TYPE_I_PCM,
+   .wFormatTag =   cpu_to_le16(UAC_FORMAT_TYPE_I_PCM),
 };
 
 DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1);
@@ -606,8 +606,8 @@ static int f_audio_bind(struct usb_configuration *c, struct 
usb_function *f)
if (status)
goto fail;
 
-   audio->out_ep_maxpsize = as_out_ep_desc.wMaxPacketSize;
-   audio->in_ep_maxpsize = as_in_ep_desc.wMaxPacketSize;
+   audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize);
+   audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize);
audio->params.c_chmask = audio_opts->c_chmask;
audio->params.c_srate = audio_opts->c_srate;
audio->params.c_ssize = audio_opts->c_ssize;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] USB Audio gadget endianness fixes

2017-06-25 Thread Ruslan Bilovol
Audio gadget refactoring patches touched few function
files and triggered kbuild test robot verification
who found some endianness issues by sparse tool.

Since most of these issues existed from beginning
in f_uac2 and f_uac1_legacy drivers (and were inherited
be f_uac1), it seems nobody run audio gadgets
on big-endian systems.

I fixed only f_uac1/f_uac2 issues leaving leagacy uac1
driver untouched. USB audio headers also were updated.

I tested patches only on LE system because I have no
big-endian hardware. Also there is no anymore
endianness warnings from sparse during kernel build.

For big endian case tested only build which also
doesn't produce sparse warnings anymore.

Ruslan Bilovol (3):
  include: usb: audio: specify exact endiannes of descriptors
  usb: gadget: f_uac1: endianness fixes.
  usb: gadget: f_uac2: endianness fixes.

 drivers/usb/gadget/function/f_uac1.c | 20 ++--
 drivers/usb/gadget/function/f_uac2.c | 25 ++---
 include/linux/usb/audio-v2.h | 14 +++---
 include/uapi/linux/usb/audio.h   |  6 +++---
 4 files changed, 34 insertions(+), 31 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] usb: gadget: f_uac2: endianness fixes.

2017-06-25 Thread Ruslan Bilovol
As per USB spec, multiple-bytes fields are stored
in little-endian order. Use CPU<->LE helpers for
such fields.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/function/f_uac2.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index 9082ce2..f05c3f3 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -168,7 +168,7 @@ enum {
.bAssocTerminal = 0,
.bCSourceID = USB_OUT_CLK_ID,
.iChannelNames = 0,
-   .bmControls = (CONTROL_RDWR << COPY_CTRL),
+   .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
 };
 
 /* Input Terminal for I/O-In */
@@ -182,7 +182,7 @@ enum {
.bAssocTerminal = 0,
.bCSourceID = USB_IN_CLK_ID,
.iChannelNames = 0,
-   .bmControls = (CONTROL_RDWR << COPY_CTRL),
+   .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
 };
 
 /* Ouput Terminal for USB_IN */
@@ -196,7 +196,7 @@ enum {
.bAssocTerminal = 0,
.bSourceID = IO_IN_IT_ID,
.bCSourceID = USB_IN_CLK_ID,
-   .bmControls = (CONTROL_RDWR << COPY_CTRL),
+   .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
 };
 
 /* Ouput Terminal for I/O-Out */
@@ -210,7 +210,7 @@ enum {
.bAssocTerminal = 0,
.bSourceID = USB_OUT_IT_ID,
.bCSourceID = USB_OUT_CLK_ID,
-   .bmControls = (CONTROL_RDWR << COPY_CTRL),
+   .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
 };
 
 static struct uac2_ac_header_descriptor ac_hdr_desc = {
@@ -220,9 +220,10 @@ enum {
.bDescriptorSubtype = UAC_MS_HEADER,
.bcdADC = cpu_to_le16(0x200),
.bCategory = UAC2_FUNCTION_IO_BOX,
-   .wTotalLength = sizeof in_clk_src_desc + sizeof out_clk_src_desc
-+ sizeof usb_out_it_desc + sizeof io_in_it_desc
-   + sizeof usb_in_ot_desc + sizeof io_out_ot_desc,
+   .wTotalLength = cpu_to_le16(sizeof in_clk_src_desc
+   + sizeof out_clk_src_desc + sizeof usb_out_it_desc
+   + sizeof io_in_it_desc + sizeof usb_in_ot_desc
+   + sizeof io_out_ot_desc),
.bmControls = 0,
 };
 
@@ -569,10 +570,12 @@ static void set_ep_max_packet_size(const struct 
f_uac2_opts *uac2_opts,
return ret;
}
 
-   agdev->in_ep_maxpsize = max(fs_epin_desc.wMaxPacketSize,
-   hs_epin_desc.wMaxPacketSize);
-   agdev->out_ep_maxpsize = max(fs_epout_desc.wMaxPacketSize,
-   hs_epout_desc.wMaxPacketSize);
+   agdev->in_ep_maxpsize = max_t(u16,
+   le16_to_cpu(fs_epin_desc.wMaxPacketSize),
+   le16_to_cpu(hs_epin_desc.wMaxPacketSize));
+   agdev->out_ep_maxpsize = max_t(u16,
+   le16_to_cpu(fs_epout_desc.wMaxPacketSize),
+   le16_to_cpu(hs_epout_desc.wMaxPacketSize));
 
hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 0/4] USB Audio Gadget refactoring

2017-06-18 Thread Ruslan Bilovol
Hi Felipe,

This is v5 of audio gadget refactoring.
Note, that legacy f_uac1 function is broken since v4.10
by commit 7e4da3fcf7c9 ("usb: gadget: composite: Test
get_alt() presence instead of set_alt()"). The fact that
at v4.12-rc5 time nobody cares about may be a good sign
that number of users is small if any. Thus making it
legacy makes sence.

This series depends on legacy f_uac1 fix I posted before:
http://www.spinics.net/lists/linux-usb/msg158373.html
Without this fix it's not possible to check that refactoring
didn't break legacy f_uac1 functionality



I came to this patch series when wanted to do two things:
 - use UAC1 as virtual ALSA sound card on gadget side,
   just like UAC2 is used so it's possible to do rate
   resampling
 - have both playback/capture support in UAC1

Since I wanted to have same behavior for both UAC1/UAC2,
obviously I've got an utility part (u_audio.c) for
virtual ALSA sound card handling like we have
for ethernet(u_ether) or serial(u_serial) functions.
Function-specific parts (f_uac1/f_uac2) became almost 
as storage for class-specific USB descriptors, some
boilerplate for configfs, binding and few USB
config request handling.

Originally in RFC [1] I've posted before, there was
major change to f_uac1 after that it couldn't do
direct play to existing ALSA sound card anymore,
representing audio on gadget side as virtual
ALSA sound card where audio streams are simply
sinked to and sourced from it, so it may break
current usecase for some people (and that's why
it was RFC).

During RFC discussion, it was agreed to not touch
existing f_uac1 implementation and create new one
instead. At v4 patchet discussion another approach
was agreed - current f_uac1.c gets renamed to
f_uac1_legacy.c and introduced a *new* f_uac1.c
instead that is done in current patchset (v5)

Now, it's possible to use existing user-space
applications for audio routing between Audio Gadget
and real sound card. I personally use alsaloop tool
from alsautils and have ability to create PCM
loopback between two different ALSA cards using
rate resampling, which was not possible with previous
"direct play to ALSA card" approach in f_uac1. 

While here, also dropped redundant platform
driver/device creation in f_uac2 driver (as well as
didn't add "never implemented" volume/mute functionality
in f_uac1_legacy to f_uac1) that made this work even
easier to do.

This series is tested with both legacy g_audio.ko and
modern configfs approaches under Ubuntu 14.04 (UAC1 and
UAC2) and under Windows7 x64 (UAC1 only) having
perfect results in all cases.

Comments, testing are welcome.

v5 changes:
 - after discussion with Felipe, switched to another
   approach with making current f_uac1 legacy and
   introducing a new f_uac1.c instead
 - addressed Jassi's copyright comments

v4 changes:
 - renamed f_uac1_newapi to f_uac1_acard that is
   more meaningful
 - rebased on top of balbi/next

v3 changes:
 - renamed u_audio exported symbols so they don't
   conflict with old f_uac1 if both are built-in.

v2 changes:
 - do not touch f_uac1, instead created f_uac1_newapi
 - added documentation for f_uac1_newapi
 - rebased on top of v4.8-rc1

[1] https://lkml.org/lkml/2016/5/23/649

Ruslan Bilovol (4):
  usb: gadget: f_uac2: remove platform driver/device creation
  usb: gadget: f_uac2: split out audio core
  usb: gadget: function: make current f_uac1 implementation legacy
  usb: gadget: add f_uac1 variant based on a new u_audio api

 Documentation/ABI/testing/configfs-usb-gadget-uac1 |   18 +-
 .../ABI/testing/configfs-usb-gadget-uac1_legacy|   12 +
 Documentation/usb/gadget-testing.txt   |   53 +-
 drivers/usb/gadget/Kconfig |   29 +-
 drivers/usb/gadget/function/Makefile   |5 +-
 drivers/usb/gadget/function/f_uac1.c   |  906 +++--
 drivers/usb/gadget/function/f_uac1_legacy.c| 1021 
 drivers/usb/gadget/function/f_uac2.c   |  795 ++-
 drivers/usb/gadget/function/u_audio.c  |  662 +
 drivers/usb/gadget/function/u_audio.h  |   95 ++
 drivers/usb/gadget/function/u_uac1.h   |   87 +-
 .../gadget/function/{u_uac1.c => u_uac1_legacy.c}  |7 +-
 drivers/usb/gadget/function/u_uac1_legacy.h|   82 ++
 drivers/usb/gadget/legacy/Kconfig  |   15 +-
 drivers/usb/gadget/legacy/audio.c  |   55 +-
 15 files changed, 2494 insertions(+), 1348 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy
 create mode 100644 drivers/usb/gadget/function/f_uac1_legacy.c
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h
 rename drivers/usb/gadget/function/{u_uac1.c => u_uac1_legacy.c} (98%)
 create mode 100644 drivers/usb/gadget/function/u_uac1_legacy.h

-- 
1.9.1

--

[PATCH v5 1/4] usb: gadget: f_uac2: remove platform driver/device creation

2017-06-18 Thread Ruslan Bilovol
Simplify f_uac2 by removing platform driver/device
creation; use composite's usb_gadget device as
parent for sound card and for debug prints.
This removes extra layer of code without any functional
change.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/function/f_uac2.c | 107 +--
 1 file changed, 28 insertions(+), 79 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index 5a7ba05..f674bae 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -13,7 +13,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include 
@@ -51,8 +50,6 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-static const char *uac2_name = "snd_uac2";
-
 struct uac2_req {
struct uac2_rtd_params *pp; /* parent param */
struct usb_request *req;
@@ -81,9 +78,6 @@ struct uac2_rtd_params {
 };
 
 struct snd_uac2_chip {
-   struct platform_device pdev;
-   struct platform_driver pdrv;
-
struct uac2_rtd_params p_prm;
struct uac2_rtd_params c_prm;
 
@@ -122,6 +116,7 @@ struct audio_dev {
 
struct usb_ep *in_ep, *out_ep;
struct usb_function func;
+   struct usb_gadget *gadget;
 
/* The ALSA Sound Card it represents on the USB-Client side */
struct snd_uac2_chip uac2;
@@ -140,12 +135,6 @@ struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u)
 }
 
 static inline
-struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p)
-{
-   return container_of(p, struct snd_uac2_chip, pdev);
-}
-
-static inline
 struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev)
 {
return container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
@@ -254,7 +243,7 @@ uint num_channels(uint chanmask)
 
 exit:
if (usb_ep_queue(ep, req, GFP_ATOMIC))
-   dev_err(>pdev.dev, "%d Error!\n", __LINE__);
+   dev_err(uac2->card->dev, "%d Error!\n", __LINE__);
 
if (update_alsa)
snd_pcm_period_elapsed(substream);
@@ -440,23 +429,22 @@ static int uac2_pcm_null(struct snd_pcm_substream 
*substream)
.prepare = uac2_pcm_null,
 };
 
-static int snd_uac2_probe(struct platform_device *pdev)
+static int snd_uac2_probe(struct audio_dev *audio_dev)
 {
-   struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev);
+   struct snd_uac2_chip *uac2 = _dev->uac2;
struct snd_card *card;
struct snd_pcm *pcm;
-   struct audio_dev *audio_dev;
struct f_uac2_opts *opts;
int err;
int p_chmask, c_chmask;
 
-   audio_dev = uac2_to_agdev(uac2);
opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst);
p_chmask = opts->p_chmask;
c_chmask = opts->c_chmask;
 
/* Choose any slot, with no id */
-   err = snd_card_new(>dev, -1, NULL, THIS_MODULE, 0, );
+   err = snd_card_new(_dev->gadget->dev,
+   -1, NULL, THIS_MODULE, 0, );
if (err < 0)
return err;
 
@@ -481,16 +469,15 @@ static int snd_uac2_probe(struct platform_device *pdev)
 
strcpy(card->driver, "UAC2_Gadget");
strcpy(card->shortname, "UAC2_Gadget");
-   sprintf(card->longname, "UAC2_Gadget %i", pdev->id);
+   sprintf(card->longname, "UAC2_Gadget %i", card->dev->id);
 
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);
 
err = snd_card_register(card);
-   if (!err) {
-   platform_set_drvdata(pdev, card);
+
+   if (!err)
return 0;
-   }
 
 snd_fail:
snd_card_free(card);
@@ -501,9 +488,9 @@ static int snd_uac2_probe(struct platform_device *pdev)
return err;
 }
 
-static int snd_uac2_remove(struct platform_device *pdev)
+static int snd_uac2_remove(struct audio_dev *audio_dev)
 {
-   struct snd_card *card = platform_get_drvdata(pdev);
+   struct snd_card *card = audio_dev->uac2.card;
 
if (card)
return snd_card_free(card);
@@ -511,45 +498,6 @@ static int snd_uac2_remove(struct platform_device *pdev)
return 0;
 }
 
-static void snd_uac2_release(struct device *dev)
-{
-   dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
-}
-
-static int alsa_uac2_init(struct audio_dev *agdev)
-{
-   struct snd_uac2_chip *uac2 = >uac2;
-   int err;
-
-   uac2->pdrv.probe = snd_uac2_probe;
-   uac2->pdrv.remove = snd_uac2_remove;
-   uac2->pdrv.driver.name = uac2_name;
-
-   uac2->pdev.id = 0;
-   uac2->pdev.name = uac2_name;
-   uac2->pdev.dev.release = snd_uac2_release;
-
-   /* Register snd_uac2 driver */
-   err = platform_driver_register(>pdrv);
-   if (err)
-

[PATCH v5 2/4] usb: gadget: f_uac2: split out audio core

2017-06-18 Thread Ruslan Bilovol
Abstract the peripheral side ALSA sound card code from
the f_uac2 function into a component that can be called
by various functions, so the various flavors can be split
apart and selectively reused.

Visible changes:
 - add uac_params structure to pass audio paramteres for
   g_audio_setup
 - make ALSA sound card's name configurable
 - add [in/out]_ep_maxpsize
 - allocate snd_uac_chip structure during g_audio_setup
 - add u_audio_[start/stop]_[capture/playback] functions

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/Kconfig|   4 +
 drivers/usb/gadget/function/Makefile  |   1 +
 drivers/usb/gadget/function/f_uac2.c  | 718 --
 drivers/usb/gadget/function/u_audio.c | 662 +++
 drivers/usb/gadget/function/u_audio.h |  95 +
 drivers/usb/gadget/legacy/Kconfig |   1 +
 6 files changed, 845 insertions(+), 636 deletions(-)
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index b3c879b..3b0ffd6 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -158,6 +158,9 @@ config USB_U_SERIAL
 config USB_U_ETHER
tristate
 
+config USB_U_AUDIO
+   tristate
+
 config USB_F_SERIAL
tristate
 
@@ -381,6 +384,7 @@ config USB_CONFIGFS_F_UAC2
depends on SND
select USB_LIBCOMPOSITE
select SND_PCM
+   select USB_U_AUDIO
select USB_F_UAC2
help
  This Audio function is compatible with USB Audio Class
diff --git a/drivers/usb/gadget/function/Makefile 
b/drivers/usb/gadget/function/Makefile
index cb8c225..b29f2ae 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -32,6 +32,7 @@ usb_f_mass_storage-y  := f_mass_storage.o 
storage_common.o
 obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
 usb_f_fs-y := f_fs.o
 obj-$(CONFIG_USB_F_FS) += usb_f_fs.o
+obj-$(CONFIG_USB_U_AUDIO)  += u_audio.o
 usb_f_uac1-y   := f_uac1.o u_uac1.o
 obj-$(CONFIG_USB_F_UAC1)   += usb_f_uac1.o
 usb_f_uac2-y   := f_uac2.o
diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index f674bae..9082ce2 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -15,10 +15,7 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-
+#include "u_audio.h"
 #include "u_uac2.h"
 
 /*
@@ -50,455 +47,23 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-struct uac2_req {
-   struct uac2_rtd_params *pp; /* parent param */
-   struct usb_request *req;
+struct f_uac2 {
+   struct g_audio g_audio;
+   u8 ac_intf, as_in_intf, as_out_intf;
+   u8 ac_alt, as_in_alt, as_out_alt;   /* needed for get_alt() */
 };
 
-struct uac2_rtd_params {
-   struct snd_uac2_chip *uac2; /* parent chip */
-   bool ep_enabled; /* if the ep is enabled */
-   /* Size of the ring buffer */
-   size_t dma_bytes;
-   unsigned char *dma_area;
-
-   struct snd_pcm_substream *ss;
-
-   /* Ring buffer */
-   ssize_t hw_ptr;
-
-   void *rbuf;
-
-   size_t period_size;
-
-   unsigned max_psize;
-   struct uac2_req *ureq;
-
-   spinlock_t lock;
-};
-
-struct snd_uac2_chip {
-   struct uac2_rtd_params p_prm;
-   struct uac2_rtd_params c_prm;
-
-   struct snd_card *card;
-   struct snd_pcm *pcm;
-
-   /* timekeeping for the playback endpoint */
-   unsigned int p_interval;
-   unsigned int p_residue;
-
-   /* pre-calculated values for playback iso completion */
-   unsigned int p_pktsize;
-   unsigned int p_pktsize_residue;
-   unsigned int p_framesize;
-};
-
-#define BUFF_SIZE_MAX  (PAGE_SIZE * 16)
-#define PRD_SIZE_MAX   PAGE_SIZE
-#define MIN_PERIODS4
-
-static struct snd_pcm_hardware uac2_pcm_hardware = {
-   .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
-| SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
-| SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
-   .rates = SNDRV_PCM_RATE_CONTINUOUS,
-   .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX,
-   .buffer_bytes_max = BUFF_SIZE_MAX,
-   .period_bytes_max = PRD_SIZE_MAX,
-   .periods_min = MIN_PERIODS,
-};
-
-struct audio_dev {
-   u8 ac_intf, ac_alt;
-   u8 as_out_intf, as_out_alt;
-   u8 as_in_intf, as_in_alt;
-
-   struct usb_ep *in_ep, *out_ep;
-   struct usb_function func;
-   struct usb_gadget *gadget;
-
-   /* The ALSA Sound Card it represents on the USB-Client side */
-   struct snd_uac2_chip uac2;
-};
-
-static inline
-struct audio_dev *func_to_agdev(struct usb_function *f)
-{
-   return container_of(f, struct audio_dev, func);
-}
-
-static inline
-struc

[PATCH v5 4/4] usb: gadget: add f_uac1 variant based on a new u_audio api

2017-06-18 Thread Ruslan Bilovol
This patch adds a new function 'f_uac1'
(f_uac1 with virtual "ALSA card") that
uses recently created u_audio API. Comparing
to legacy f_uac1 function implementation it
doesn't require any real Audio codec to be
present on the device. In f_uac1 audio
streams are simply sinked to and sourced
from a virtual ALSA sound card created
using u_audio API.

Legacy f_uac1 approach is to write audio
samples directly to existing ALSA sound
card

f_uac1 approach is more generic/flexible
one - create an ALSA sound card that
represents USB Audio function and allows to
be used by userspace application that
may choose to do whatever it wants with the
data received from the USB Host and choose
to provide whatever it wants as audio data
to the USB Host.

f_uac1 also has capture support (gadget->host)
thanks to easy implementation via u_audio.
By default, capture interface has 48000kHz/2ch
configuration, same as playback channel has.

f_uac1 descriptors naming convention
uses f_uac2 driver naming convention that
makes it more common and meaningful.

Comparing to f_uac1_legacy, the f_uac1 doesn't
have volume/mute functionality. This is because
the f_uac1 volume/mute feature unit was dummy
implementation since that driver creation (2009)
and never had any real volume control or mute
functionality, so there is no any difference
here.

Since f_uac1 functionality, exposed
interface to userspace (virtual ALSA card),
input parameters are so different comparing
to f_uac1_legacy, that there is no any
reason to keep them in the same file/module,
and separate function was created.

g_audio can be built using one of existing
UAC functions (f_uac1, f_uac1_legacy or f_uac2)

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 Documentation/ABI/testing/configfs-usb-gadget-uac1 |  14 +
 Documentation/usb/gadget-testing.txt   |  44 ++
 drivers/usb/gadget/Kconfig |  25 +-
 drivers/usb/gadget/function/Makefile   |   2 +
 drivers/usb/gadget/function/f_uac1.c   | 802 +
 drivers/usb/gadget/function/u_uac1.h   |  41 ++
 drivers/usb/gadget/legacy/Kconfig  |  18 +-
 drivers/usb/gadget/legacy/audio.c  |  69 +-
 8 files changed, 1000 insertions(+), 15 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1
 create mode 100644 drivers/usb/gadget/function/f_uac1.c
 create mode 100644 drivers/usb/gadget/function/u_uac1.h

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 
b/Documentation/ABI/testing/configfs-usb-gadget-uac1
new file mode 100644
index 000..abfe447
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1
@@ -0,0 +1,14 @@
+What:  /config/usb-gadget/gadget/functions/uac1.name
+Date:  June 2017
+KernelVersion: 4.14
+Description:
+   The attributes:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
+   req_number - the number of pre-allocated request
+   for both capture and playback
diff --git a/Documentation/usb/gadget-testing.txt 
b/Documentation/usb/gadget-testing.txt
index ce51d6e..fbc397d 100644
--- a/Documentation/usb/gadget-testing.txt
+++ b/Documentation/usb/gadget-testing.txt
@@ -20,6 +20,7 @@ provided by gadgets.
 17. UAC2 function
 18. UVC function
 19. PRINTER function
+20. UAC1 function (new API)
 
 
 1. ACM function
@@ -773,3 +774,46 @@ host:
 
 More advanced testing can be done with the prn_example
 described in Documentation/usb/gadget-printer.txt.
+
+
+20. UAC1 function (virtual ALSA card, using u_audio API)
+=
+
+The function is provided by usb_f_uac1.ko module.
+It will create a virtual ALSA card and the audio streams are simply
+sinked to and sourced from it.
+
+Function-specific configfs interface
+
+
+The function name to use when creating the function directory is "uac1".
+The uac1 function provides these attributes in its function directory:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
+   req_number - the number of pre-allocated request for both capture
+and playback
+
+The attributes have sane default values.
+
+Testing the UAC1 function
+-
+
+device: run the gadget
+host: aplay -l # should list our USB Audio Gadget
+
+This function does not require real hardware support, it just
+sends a stream of audio data to/from the host. In order to
+actually hear something at the d

[PATCH v5 3/4] usb: gadget: function: make current f_uac1 implementation legacy

2017-06-18 Thread Ruslan Bilovol
Before introducing new f_uac1 function (with virtual
ALSA card) make current implementation legacy.

This includes renaming of existing files, some
variables, config options and documentation

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 ...gadget-uac1 => configfs-usb-gadget-uac1_legacy} |  2 +-
 Documentation/usb/gadget-testing.txt   |  9 +++--
 drivers/usb/gadget/Kconfig |  8 ++--
 drivers/usb/gadget/function/Makefile   |  4 +-
 .../gadget/function/{f_uac1.c => f_uac1_legacy.c}  | 45 +++---
 .../gadget/function/{u_uac1.c => u_uac1_legacy.c}  |  7 ++--
 .../gadget/function/{u_uac1.h => u_uac1_legacy.h}  |  8 ++--
 drivers/usb/gadget/legacy/Kconfig  |  6 +--
 drivers/usb/gadget/legacy/audio.c  | 26 ++---
 9 files changed, 59 insertions(+), 56 deletions(-)
 rename Documentation/ABI/testing/{configfs-usb-gadget-uac1 => 
configfs-usb-gadget-uac1_legacy} (84%)
 rename drivers/usb/gadget/function/{f_uac1.c => f_uac1_legacy.c} (95%)
 rename drivers/usb/gadget/function/{u_uac1.c => u_uac1_legacy.c} (98%)
 rename drivers/usb/gadget/function/{u_uac1.h => u_uac1_legacy.h} (94%)

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 
b/Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy
similarity index 84%
rename from Documentation/ABI/testing/configfs-usb-gadget-uac1
rename to Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy
index 8ba9a12..b2eaefd 100644
--- a/Documentation/ABI/testing/configfs-usb-gadget-uac1
+++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy
@@ -1,4 +1,4 @@
-What:  /config/usb-gadget/gadget/functions/uac1.name
+What:  /config/usb-gadget/gadget/functions/uac1_legacy.name
 Date:  Sep 2014
 KernelVersion: 3.18
 Description:
diff --git a/Documentation/usb/gadget-testing.txt 
b/Documentation/usb/gadget-testing.txt
index fb0cc4d..ce51d6e 100644
--- a/Documentation/usb/gadget-testing.txt
+++ b/Documentation/usb/gadget-testing.txt
@@ -16,7 +16,7 @@ provided by gadgets.
 13. RNDIS function
 14. SERIAL function
 15. SOURCESINK function
-16. UAC1 function
+16. UAC1 function (legacy implementation)
 17. UAC2 function
 18. UVC function
 19. PRINTER function
@@ -589,15 +589,16 @@ device: run the gadget
 host: test-usb (tools/usb/testusb.c)
 
 
-16. UAC1 function
+16. UAC1 function (legacy implementation)
 =
 
-The function is provided by usb_f_uac1.ko module.
+The function is provided by usb_f_uac1_legacy.ko module.
 
 Function-specific configfs interface
 
 
-The function name to use when creating the function directory is "uac1".
+The function name to use when creating the function directory
+is "uac1_legacy".
 The uac1 function provides these attributes in its function directory:
 
audio_buf_size - audio buffer size
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 3b0ffd6..01c2e2b 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -191,7 +191,7 @@ config USB_F_MASS_STORAGE
 config USB_F_FS
tristate
 
-config USB_F_UAC1
+config USB_F_UAC1_LEGACY
tristate
 
 config USB_F_UAC2
@@ -365,13 +365,13 @@ config USB_CONFIGFS_F_FS
  implemented in kernel space (for instance Ethernet, serial or
  mass storage) and other are implemented in user space.
 
-config USB_CONFIGFS_F_UAC1
-   bool "Audio Class 1.0"
+config USB_CONFIGFS_F_UAC1_LEGACY
+   bool "Audio Class 1.0 (legacy implementation)"
depends on USB_CONFIGFS
depends on SND
select USB_LIBCOMPOSITE
select SND_PCM
-   select USB_F_UAC1
+   select USB_F_UAC1_LEGACY
help
  This Audio function implements 1 AudioControl interface,
  1 AudioStreaming Interface each for USB-OUT and USB-IN.
diff --git a/drivers/usb/gadget/function/Makefile 
b/drivers/usb/gadget/function/Makefile
index b29f2ae..50ee517 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -33,8 +33,8 @@ obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
 usb_f_fs-y := f_fs.o
 obj-$(CONFIG_USB_F_FS) += usb_f_fs.o
 obj-$(CONFIG_USB_U_AUDIO)  += u_audio.o
-usb_f_uac1-y   := f_uac1.o u_uac1.o
-obj-$(CONFIG_USB_F_UAC1)   += usb_f_uac1.o
+usb_f_uac1_legacy-y:= f_uac1_legacy.o u_uac1_legacy.o
+obj-$(CONFIG_USB_F_UAC1_LEGACY)+= usb_f_uac1_legacy.o
 usb_f_uac2-y   := f_uac2.o
 obj-$(CONFIG_USB_F_UAC2)   += usb_f_uac2.o
 usb_f_uvc-y:= f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o 
uvc_configfs.o
diff --git a/drivers/usb/gadget/function/f_uac1.c 
b/drivers/usb/gadget/function/f_uac1_legacy.c
similarity index 95%
rename from drivers/usb/gadget/function/f_uac1.c
rename to drivers/usb/gadget/function/

[PATCH] usb: gadget: function: f_uac1: implement get_alt()

2017-06-17 Thread Ruslan Bilovol
After commit 7e4da3fcf7c9 ("usb: gadget: composite:
Test get_alt() presence instead of set_alt()") f_uac1
function became broken because it doesn't have
get_alt() callback implementation and composite
framework never set altsetting 1 for audiostreaming
interface. On host site it looks like:

 [424339.017711] 21:1:1: usb_set_interface failed (-32)

Since host can't set altsetting 1, it can't start
playing audio.

In order to fix it implemented get_alt along with
minor improvements (error conditions checking)
similar to what existing f_uac2 has.

Cc: Krzysztof Opasiak <k.opas...@samsung.com>
Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/function/f_uac1.c | 40 +++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/function/f_uac1.c 
b/drivers/usb/gadget/function/f_uac1.c
index f2ac0cb..5dfc94b 100644
--- a/drivers/usb/gadget/function/f_uac1.c
+++ b/drivers/usb/gadget/function/f_uac1.c
@@ -277,6 +277,9 @@ static void f_audio_buffer_free(struct f_audio_buf 
*audio_buf)
 struct f_audio {
struct gaudio   card;
 
+   u8 ac_intf, ac_alt;
+   u8 as_intf, as_alt;
+
/* endpoints handle full and/or high speeds */
struct usb_ep   *out_ep;
 
@@ -586,7 +589,20 @@ static int f_audio_set_alt(struct usb_function *f, 
unsigned intf, unsigned alt)
req_count = opts->req_count;
audio_buf_size = opts->audio_buf_size;
 
-   if (intf == 1) {
+   /* No i/f has more than 2 alt settings */
+   if (alt > 1) {
+   ERROR(cdev, "%s:%d Error!\n", __func__, __LINE__);
+   return -EINVAL;
+   }
+
+   if (intf == audio->ac_intf) {
+   /* Control I/f has only 1 AltSetting - 0 */
+   if (alt) {
+   ERROR(cdev, "%s:%d Error!\n", __func__, __LINE__);
+   return -EINVAL;
+   }
+   return 0;
+   } else if (intf == audio->as_intf) {
if (alt == 1) {
err = config_ep_by_speed(cdev->gadget, f, out_ep);
if (err)
@@ -631,11 +647,28 @@ static int f_audio_set_alt(struct usb_function *f, 
unsigned intf, unsigned alt)
schedule_work(>playback_work);
}
}
+   audio->as_alt = alt;
}
 
return err;
 }
 
+static int f_audio_get_alt(struct usb_function *f, unsigned intf)
+{
+   struct f_audio  *audio = func_to_audio(f);
+   struct usb_composite_dev *cdev = f->config->cdev;
+
+   if (intf == audio->ac_intf)
+   return audio->ac_alt;
+   else if (intf == audio->as_intf)
+   return audio->as_alt;
+   else
+   ERROR(cdev, "%s:%d Invalid Interface %d!\n",
+ __func__, __LINE__, intf);
+
+   return -EINVAL;
+}
+
 static void f_audio_disable(struct usb_function *f)
 {
return;
@@ -702,12 +735,16 @@ static void f_audio_build_desc(struct f_audio *audio)
if (status < 0)
goto fail;
ac_interface_desc.bInterfaceNumber = status;
+   audio->ac_intf = status;
+   audio->ac_alt = 0;
 
status = usb_interface_id(c, f);
if (status < 0)
goto fail;
as_interface_alt_0_desc.bInterfaceNumber = status;
as_interface_alt_1_desc.bInterfaceNumber = status;
+   audio->as_intf = status;
+   audio->as_alt = 0;
 
status = -ENODEV;
 
@@ -966,6 +1003,7 @@ static struct usb_function *f_audio_alloc(struct 
usb_function_instance *fi)
audio->card.func.bind = f_audio_bind;
audio->card.func.unbind = f_audio_unbind;
audio->card.func.set_alt = f_audio_set_alt;
+   audio->card.func.get_alt = f_audio_get_alt;
audio->card.func.setup = f_audio_setup;
audio->card.func.disable = f_audio_disable;
audio->card.func.free_func = f_audio_free;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/3] USB Audio Gadget refactoring

2017-06-06 Thread Ruslan Bilovol
On Tue, Jun 6, 2017 at 12:41 PM, Felipe Balbi  wrote:
>
> Hi,
>
> Greg KH  writes:
>>> > I'm OK with dropping legacy f_uac1 implementation.
>>> >
>>> > Another idea I was thinking about is to implement simple in-kernel
>>> > driver which will do the same as existing alsaloop tool userspace
>>> > tool does (so legacy users will need to load two kernel modules
>>> > and get same functionality). But this seems to be a wrong way,
>>> > since It known that Linux kernel community doesn't like to take drivers
>>> > with same functionality as existing userspace tools already have.
>>> >
>>> > So bottom line: since I'm not a legacy f_uac1 user, there is no
>>> > difference for me how to handle it - remove legacy f_uac1 completely,
>>> > rename it to f_uac1_legacy or add separate f_uac1_acard function.
>>> >
>>> > So if dropping of legacy f_uac1 implementation is OK for you,
>>> > I can do it quickly in next patchset.
>>>
>>> Personally, I don't want duplicated functionality and I think the
>>> virtual sound card approach is much better. Then again, removing
>>> functionality we already support is kind of odd.
>>>
>>> Greg, Alan, what do you guys think? Do we keep a duplicated function
>>> around or do we just tell people to rely on alsaloop? Personally, I
>>> think we're better off with the flexibility of the virtual sound card,
>>> what's your take?
>>
>> If the in-kernel driver will do more things, and we don't break the
>> existing setups using alsaloop, then I don't see the problem, except
>> that we now have to maintain two things :)
>>
>> If you don't mind the maintenance, fine with me...
>
> Okay, I don't think many will continue to use f_uac1.c. Ruslan, can you
> update your series so that current f_uac1.c gets renamed to
> f_uac1_legacy.c and you introduce a *new* f_uac1.c instead?

Yes sure, I'll post an updated patch series soon

Best regards,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 resend] omap: usb: host: remove deprecated flags and structures

2017-06-02 Thread Ruslan Bilovol
From: Ruslan Bilovol <ruslan.bilo...@ti.com>

These flags and structures are deprecated and there is
no anymore users of them, so it's safe to remove them.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@ti.com>
---

Although this patch was acked-by Felipe Balbi and Roger Quadros back
in 2013, it was never picked up by maintainers.

Still applies to v4.12-rc3 and saves few bytes of memory


 include/linux/platform_data/usb-omap.h | 20 
 1 file changed, 20 deletions(-)

diff --git a/include/linux/platform_data/usb-omap.h 
b/include/linux/platform_data/usb-omap.h
index fa579b4..4c7acbe 100644
--- a/include/linux/platform_data/usb-omap.h
+++ b/include/linux/platform_data/usb-omap.h
@@ -38,34 +38,14 @@ enum usbhs_omap_port_mode {
OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM
 };
 
-struct usbtll_omap_platform_data {
-   enum usbhs_omap_port_mode   port_mode[OMAP3_HS_USB_PORTS];
-};
-
-struct ehci_hcd_omap_platform_data {
-   enum usbhs_omap_port_mode   port_mode[OMAP3_HS_USB_PORTS];
-   int reset_gpio_port[OMAP3_HS_USB_PORTS];
-   struct regulator*regulator[OMAP3_HS_USB_PORTS];
-   unsignedphy_reset:1;
-};
-
-struct ohci_hcd_omap_platform_data {
-   enum usbhs_omap_port_mode   port_mode[OMAP3_HS_USB_PORTS];
-   unsignedes2_compatibility:1;
-};
-
 struct usbhs_omap_platform_data {
int nports;
enum usbhs_omap_port_mode   port_mode[OMAP3_HS_USB_PORTS];
int reset_gpio_port[OMAP3_HS_USB_PORTS];
struct regulator*regulator[OMAP3_HS_USB_PORTS];
 
-   struct ehci_hcd_omap_platform_data  *ehci_data;
-   struct ohci_hcd_omap_platform_data  *ohci_data;
-
/* OMAP3 <= ES2.1 have a single ulpi bypass control bit */
unsigned single_ulpi_bypass:1;
-   unsigned es2_compatibility:1;
unsigned phy_reset:1;
 };
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/3] USB Audio Gadget refactoring

2017-06-02 Thread Ruslan Bilovol
Hi,

On Fri, Jun 2, 2017 at 12:42 PM, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Ruslan Bilovol <ruslan.bilo...@gmail.com> writes:
>> I came to this patch series when wanted to do two things:
>>  - use UAC1 as virtual ALSA sound card on gadget side,
>>just like UAC2 is used so it's possible to do rate
>>resampling
>>  - have both playback/capture support in UAC1
>>
>> Since I wanted to have same behavior for both UAC1/UAC2,
>> obviously I've got an utility part (u_audio.c) for
>> virtual ALSA sound card handling like we have
>> for ethernet(u_ether) or serial(u_serial) functions.
>> Function-specific parts (f_uac1/f_uac2) became almost
>> as storage for class-specific USB descriptors, some
>> boilerplate for configfs, binding and few USB
>> config request handling.
>>
>> Originally in RFC [1] I've posted before, there was
>> major change to f_uac1 after that it couldn't do
>> direct play to existing ALSA sound card anymore,
>> representing audio on gadget side as virtual
>> ALSA sound card where audio streams are simply
>> sinked to and sourced from it, so it may break
>> current usecase for some people (and that's why
>> it was RFC).
>>
>> During RFC discussion, it was agreed to not touch
>> existing f_uac1 implementation and create new one
>> instead. This patchset (v4) introduced new function
>> named f_uac1_acard and doesn't touch current f_uac1
>> implementation, so people still can use old behavior
>
> Do you have a pointer to the original RFC discussion where this was
> discussed? If we really *must* keep the old implementation, I would
> rather rename that to f_uac1_legacy. Still, I find it unlikely that
> anybody will care about the old implementation.

It is on LKML (which is down for me) [1] or alternative archive [2]

>
>> Now, it's possible to use existing user-space
>> applications for audio routing between Audio Gadget
>> and real sound card. I personally use alsaloop tool
>> from alsautils and have ability to create PCM
>> loopback between two different ALSA cards using
>> rate resampling, which was not possible with previous
>> "direct play to ALSA card" approach in f_uac1.
>
> this is really good result and will actually make it a lot easier for
> testing things out.
>
>> While here, also dropped redundant platform
>> driver/device creation in f_uac2 driver (as well as
>> didn't add "never implemented" volume/mute functionality
>> in f_uac1 to f_uac1_acard) that made this work even
>> easier to do.
>>
>> This series is tested with both legacy g_audio.ko and
>> modern configfs approaches under Ubuntu 14.04 (UAC1 and
>> UAC2) and under Windows7 x64 (UAC1 only) having
>> perfect results in all cases.
>>
>> Comments, testing are welcome.
>>
>> v4 changes:
>>  - renamed f_uac1_newapi to f_uac1_acard that is
>>more meaningful
>
> I really don't get why you wanna keep both f_uac1 and f_uac1_acard. Why
> do we need to maintain the old uac1 implementation? Why two separate
> files?

In first RFC ([1],[2]) I did exactly what you wrote here (removed
old uac1 implementation and replaced it by new one) but got feedback
that it will break things for existing f_uac1 legacy users and it's better to
have separate implementation.

I'm OK with dropping legacy f_uac1 implementation.

Another idea I was thinking about is to implement simple in-kernel
driver which will do the same as existing alsaloop tool userspace
tool does (so legacy users will need to load two kernel modules
and get same functionality). But this seems to be a wrong way,
since It known that Linux kernel community doesn't like to take drivers
with same functionality as existing userspace tools already have.

So bottom line: since I'm not a legacy f_uac1 user, there is no
difference for me how to handle it - remove legacy f_uac1 completely,
rename it to f_uac1_legacy or add separate f_uac1_acard function.

So if dropping of legacy f_uac1 implementation is OK for you,
I can do it quickly in next patchset.

[1] https://lkml.org/lkml/2016/5/23/649
[2] https://marc.info/?t=14640475881=1=4

Regards,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 2/3] usb: gadget: f_uac2: split out audio core

2017-06-02 Thread Ruslan Bilovol
Hi Felipe,

On Fri, Jun 2, 2017 at 12:34 PM, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Ruslan Bilovol <ruslan.bilo...@gmail.com> writes:
>> Abstract the peripheral side ALSA sound card code from
>> the f_uac2 function into a component that can be called
>> by various functions, so the various flavors can be split
>> apart and selectively reused.
>>
>> Visible changes:
>>  - add uac_params structure to pass audio paramteres for
>>g_audio_setup
>>  - make ALSA sound card's name configurable
>>  - add [in/out]_ep_maxpsize
>>  - allocate snd_uac_chip structure during g_audio_setup
>>  - add u_audio_[start/stop]_[capture/playback] functions
>>
>> Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
>
> this doesn't apply on testing/next, care to rebase?
>

sure, I'll rebase it and address comments from Jassi

Regards,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 3/3] usb: gadget: add f_uac1 variant based on a new u_audio api

2017-05-29 Thread Ruslan Bilovol
On Fri, May 26, 2017 at 6:52 PM, Julian Scheel <jul...@jusst.de> wrote:
> On 18.05.2017 00:37, Ruslan Bilovol wrote:
>>
>> This patch adds a new function 'f_uac1_acard'
>> (f_uac1 with virtual "ALSA card") that
>> uses recently created u_audio API. Comparing
>> to legacy f_uac1 function implementation it
>> doesn't require any real Audio codec to be
>> present on the device. In f_uac1_acard audio
>> streams are simply sinked to and sourced
>> from a virtual ALSA sound card created
>> using u_audio API.
>>
>> Legacy f_uac1 approach is to write audio
>> samples directly to existing ALSA sound
>> card
>>
>> f_uac1_acard approach is more generic/flexible
>> one - create an ALSA sound card that
>> represents USB Audio function and allows to
>> be used by userspace application that
>> may choose to do whatever it wants with the
>> data received from the USB Host and choose
>> to provide whatever it wants as audio data
>> to the USB Host.
>>
>> f_uac1_acard also has capture support (gadget->host)
>> thanks to easy implementation via u_audio.
>> By default, capture interface has 48000kHz/2ch
>> configuration, same as playback channel has.
>>
>> f_uac1_acard descriptors naming convention
>> uses f_uac2 driver naming convention that
>> makes it more common and meaningful.
>>
>> Comparing to f_uac1, the f_uac1_acard doesn't
>> have volume/mute functionality. This is because
>> the f_uac1 volume/mute feature unit was dummy
>> implementation since that driver creation (2009)
>> and never had any real volume control or mute
>> functionality, so there is no any difference
>> here.
>>
>> Since f_uac1_acard functionality, exposed
>> interface to userspace (virtual ALSA card),
>> input parameters are so different comparing
>> to legace f_uac1, that there is no any
>> reason to keep them in the same file/module,
>> and separate function was created.
>>
>> g_audio can be built using one of existing
>> UAC functions (f_uac1, f_uac1_acard or f_uac2)
>>
>> Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
>> ---
>>   .../ABI/testing/configfs-usb-gadget-uac1_acard |  14 +
>>   Documentation/usb/gadget-testing.txt   |  45 ++
>>   drivers/usb/gadget/Kconfig |  21 +
>>   drivers/usb/gadget/function/Makefile   |   2 +
>>   drivers/usb/gadget/function/f_uac1_acard.c | 803
>> +
>>   drivers/usb/gadget/function/u_uac1_acard.h |  41 ++
>>   drivers/usb/gadget/legacy/Kconfig  |  15 +-
>>   drivers/usb/gadget/legacy/audio.c  |  53 ++
>>   8 files changed, 992 insertions(+), 2 deletions(-)
>>   create mode 100644
>> Documentation/ABI/testing/configfs-usb-gadget-uac1_acard
>>   create mode 100644 drivers/usb/gadget/function/f_uac1_acard.c
>>   create mode 100644 drivers/usb/gadget/function/u_uac1_acard.h
>>
>
> Tested on iMX7D using chipidea usb gadget controller. Tested Windows 10 and
> Linux 4.11 as host. Both work fine.
>
> Tested-by: Julian Scheel <jul...@jusst.de>

Thanks for testing it.

I'll wait for additional reviews/comments next few days and than will
send new patchset with addressed comments.

Also current patchset have minor conflict when applied on top of
Felipe's testing/next branch which is moved to 4.12-rc1. I've
resolved conflict but did only build test so far.
Anyway I uploaded rebased patches to github [1] if anybody
wants to try them.

[1] https://github.com/rbilovol/kernel/commits/usbaudio-v4.12-balbi-testing-next

Best regards,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 2/3] usb: gadget: f_uac2: split out audio core

2017-05-29 Thread Ruslan Bilovol
On Mon, May 22, 2017 at 6:58 PM, Jassi Brar <jassisinghb...@gmail.com> wrote:
> On Thu, May 18, 2017 at 4:07 AM, Ruslan Bilovol
> <ruslan.bilo...@gmail.com> wrote:
>> Abstract the peripheral side ALSA sound card code from
>> the f_uac2 function into a component that can be called
>> by various functions, so the various flavors can be split
>> apart and selectively reused.
>>
>> Visible changes:
>>  - add uac_params structure to pass audio paramteres for
>>g_audio_setup
>>  - make ALSA sound card's name configurable
>>  - add [in/out]_ep_maxpsize
>>  - allocate snd_uac_chip structure during g_audio_setup
>>  - add u_audio_[start/stop]_[capture/playback] functions
>>
>> Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
>> ---
>>  drivers/usb/gadget/Kconfig|   4 +
>>  drivers/usb/gadget/function/Makefile  |   1 +
>>  drivers/usb/gadget/function/f_uac2.c  | 721 
>> --
>>  drivers/usb/gadget/function/u_audio.c | 661 +++
>>  drivers/usb/gadget/function/u_audio.h |  95 +
>>  drivers/usb/gadget/legacy/Kconfig |   1 +
>>  6 files changed, 846 insertions(+), 637 deletions(-)
>>  create mode 100644 drivers/usb/gadget/function/u_audio.c
>>  create mode 100644 drivers/usb/gadget/function/u_audio.h
>>
>> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
>> index c164d6b..2ba0ace 100644
>> --- a/drivers/usb/gadget/Kconfig
>> +++ b/drivers/usb/gadget/Kconfig
>> @@ -158,6 +158,9 @@ config USB_U_SERIAL
>>  config USB_U_ETHER
>> tristate
>>
>> +config USB_U_AUDIO
>> +   tristate
>> +
>>  config USB_F_SERIAL
>> tristate
>>
>> @@ -381,6 +384,7 @@ config USB_CONFIGFS_F_UAC2
>> depends on SND
>> select USB_LIBCOMPOSITE
>> select SND_PCM
>> +   select USB_U_AUDIO
>> select USB_F_UAC2
>> help
>>   This Audio function is compatible with USB Audio Class
>> diff --git a/drivers/usb/gadget/function/Makefile 
>> b/drivers/usb/gadget/function/Makefile
>> index cb8c225..b29f2ae 100644
>> --- a/drivers/usb/gadget/function/Makefile
>> +++ b/drivers/usb/gadget/function/Makefile
>> @@ -32,6 +32,7 @@ usb_f_mass_storage-y  := f_mass_storage.o 
>> storage_common.o
>>  obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
>>  usb_f_fs-y := f_fs.o
>>  obj-$(CONFIG_USB_F_FS) += usb_f_fs.o
>> +obj-$(CONFIG_USB_U_AUDIO)  += u_audio.o
>>  usb_f_uac1-y   := f_uac1.o u_uac1.o
>>  obj-$(CONFIG_USB_F_UAC1)   += usb_f_uac1.o
>>  usb_f_uac2-y   := f_uac2.o
>> diff --git a/drivers/usb/gadget/function/f_uac2.c 
>> b/drivers/usb/gadget/function/f_uac2.c
>> index d4565b5..059a14a 100644
>> --- a/drivers/usb/gadget/function/f_uac2.c
>> +++ b/drivers/usb/gadget/function/f_uac2.c
>> @@ -15,10 +15,7 @@
>>  #include 
>>  #include 
>>
>> -#include 
>> -#include 
>> -#include 
>> -
>> +#include "u_audio.h"
>>  #include "u_uac2.h"
>>
>>  /*
>> @@ -50,455 +47,23 @@
>>  #define UNFLW_CTRL 8
>>  #define OVFLW_CTRL 10
>>
>> -struct uac2_req {
>> -   struct uac2_rtd_params *pp; /* parent param */
>> -   struct usb_request *req;
>> -};
>> -
>> -struct uac2_rtd_params {
>> -   struct snd_uac2_chip *uac2; /* parent chip */
>> -   bool ep_enabled; /* if the ep is enabled */
>> -   /* Size of the ring buffer */
>> -   size_t dma_bytes;
>> -   unsigned char *dma_area;
>> -
>> -   struct snd_pcm_substream *ss;
>> -
>> -   /* Ring buffer */
>> -   ssize_t hw_ptr;
>> -
>> -   void *rbuf;
>> -
>> -   size_t period_size;
>> -
>> -   unsigned max_psize;
>> -   struct uac2_req *ureq;
>> -
>> -   spinlock_t lock;
>> -};
>> -
>> -struct snd_uac2_chip {
>> -   struct uac2_rtd_params p_prm;
>> -   struct uac2_rtd_params c_prm;
>> -
>> -   struct snd_card *card;
>> -   struct snd_pcm *pcm;
>> -
>> -   /* timekeeping for the playback endpoint */
>> -   unsigned int p_interval;
>> -   unsigned int p_residue;
>> -
>> -   /* pre-calculated values for playback iso completion */
>> -   unsigned int p_pktsize;
>> -   unsigned int p_pktsize_residue;
>&

[PATCH v4 0/3] USB Audio Gadget refactoring

2017-05-17 Thread Ruslan Bilovol
I came to this patch series when wanted to do two things:
 - use UAC1 as virtual ALSA sound card on gadget side,
   just like UAC2 is used so it's possible to do rate
   resampling
 - have both playback/capture support in UAC1

Since I wanted to have same behavior for both UAC1/UAC2,
obviously I've got an utility part (u_audio.c) for
virtual ALSA sound card handling like we have
for ethernet(u_ether) or serial(u_serial) functions.
Function-specific parts (f_uac1/f_uac2) became almost 
as storage for class-specific USB descriptors, some
boilerplate for configfs, binding and few USB
config request handling.

Originally in RFC [1] I've posted before, there was
major change to f_uac1 after that it couldn't do
direct play to existing ALSA sound card anymore,
representing audio on gadget side as virtual
ALSA sound card where audio streams are simply
sinked to and sourced from it, so it may break
current usecase for some people (and that's why
it was RFC).

During RFC discussion, it was agreed to not touch
existing f_uac1 implementation and create new one
instead. This patchset (v4) introduced new function
named f_uac1_acard and doesn't touch current f_uac1
implementation, so people still can use old behavior

Now, it's possible to use existing user-space
applications for audio routing between Audio Gadget
and real sound card. I personally use alsaloop tool
from alsautils and have ability to create PCM
loopback between two different ALSA cards using
rate resampling, which was not possible with previous
"direct play to ALSA card" approach in f_uac1. 

While here, also dropped redundant platform
driver/device creation in f_uac2 driver (as well as
didn't add "never implemented" volume/mute functionality
in f_uac1 to f_uac1_acard) that made this work even
easier to do.

This series is tested with both legacy g_audio.ko and
modern configfs approaches under Ubuntu 14.04 (UAC1 and
UAC2) and under Windows7 x64 (UAC1 only) having
perfect results in all cases.

Comments, testing are welcome.

v4 changes:
 - renamed f_uac1_newapi to f_uac1_acard that is
   more meaningful
 - rebased on top of balbi/next

v3 changes:
 - renamed u_audio exported symbols so they don't
   conflict with old f_uac1 if both are built-in.

v2 changes:
 - do not touch f_uac1, instead created f_uac1_newapi
 - added documentation for f_uac1_newapi
 - rebased on top of v4.8-rc1

[1] https://lkml.org/lkml/2016/5/23/649

Ruslan Bilovol (3):
  usb: gadget: f_uac2: remove platform driver/device creation
  usb: gadget: f_uac2: split out audio core
  usb: gadget: add f_uac1 variant based on a new u_audio api

 .../ABI/testing/configfs-usb-gadget-uac1_acard |  14 +
 Documentation/usb/gadget-testing.txt   |  45 ++
 drivers/usb/gadget/Kconfig |  25 +
 drivers/usb/gadget/function/Makefile   |   3 +
 drivers/usb/gadget/function/f_uac1_acard.c | 803 +
 drivers/usb/gadget/function/f_uac2.c   | 798 +++-
 drivers/usb/gadget/function/u_audio.c  | 661 +
 drivers/usb/gadget/function/u_audio.h  |  95 +++
 drivers/usb/gadget/function/u_uac1_acard.h |  41 ++
 drivers/usb/gadget/legacy/Kconfig  |  14 +-
 drivers/usb/gadget/legacy/audio.c  |  53 ++
 11 files changed, 1850 insertions(+), 702 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_acard
 create mode 100644 drivers/usb/gadget/function/f_uac1_acard.c
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h
 create mode 100644 drivers/usb/gadget/function/u_uac1_acard.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 2/3] usb: gadget: f_uac2: split out audio core

2017-05-17 Thread Ruslan Bilovol
Abstract the peripheral side ALSA sound card code from
the f_uac2 function into a component that can be called
by various functions, so the various flavors can be split
apart and selectively reused.

Visible changes:
 - add uac_params structure to pass audio paramteres for
   g_audio_setup
 - make ALSA sound card's name configurable
 - add [in/out]_ep_maxpsize
 - allocate snd_uac_chip structure during g_audio_setup
 - add u_audio_[start/stop]_[capture/playback] functions

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/Kconfig|   4 +
 drivers/usb/gadget/function/Makefile  |   1 +
 drivers/usb/gadget/function/f_uac2.c  | 721 --
 drivers/usb/gadget/function/u_audio.c | 661 +++
 drivers/usb/gadget/function/u_audio.h |  95 +
 drivers/usb/gadget/legacy/Kconfig |   1 +
 6 files changed, 846 insertions(+), 637 deletions(-)
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index c164d6b..2ba0ace 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -158,6 +158,9 @@ config USB_U_SERIAL
 config USB_U_ETHER
tristate
 
+config USB_U_AUDIO
+   tristate
+
 config USB_F_SERIAL
tristate
 
@@ -381,6 +384,7 @@ config USB_CONFIGFS_F_UAC2
depends on SND
select USB_LIBCOMPOSITE
select SND_PCM
+   select USB_U_AUDIO
select USB_F_UAC2
help
  This Audio function is compatible with USB Audio Class
diff --git a/drivers/usb/gadget/function/Makefile 
b/drivers/usb/gadget/function/Makefile
index cb8c225..b29f2ae 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -32,6 +32,7 @@ usb_f_mass_storage-y  := f_mass_storage.o 
storage_common.o
 obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
 usb_f_fs-y := f_fs.o
 obj-$(CONFIG_USB_F_FS) += usb_f_fs.o
+obj-$(CONFIG_USB_U_AUDIO)  += u_audio.o
 usb_f_uac1-y   := f_uac1.o u_uac1.o
 obj-$(CONFIG_USB_F_UAC1)   += usb_f_uac1.o
 usb_f_uac2-y   := f_uac2.o
diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index d4565b5..059a14a 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -15,10 +15,7 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-
+#include "u_audio.h"
 #include "u_uac2.h"
 
 /*
@@ -50,455 +47,23 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-struct uac2_req {
-   struct uac2_rtd_params *pp; /* parent param */
-   struct usb_request *req;
-};
-
-struct uac2_rtd_params {
-   struct snd_uac2_chip *uac2; /* parent chip */
-   bool ep_enabled; /* if the ep is enabled */
-   /* Size of the ring buffer */
-   size_t dma_bytes;
-   unsigned char *dma_area;
-
-   struct snd_pcm_substream *ss;
-
-   /* Ring buffer */
-   ssize_t hw_ptr;
-
-   void *rbuf;
-
-   size_t period_size;
-
-   unsigned max_psize;
-   struct uac2_req *ureq;
-
-   spinlock_t lock;
-};
-
-struct snd_uac2_chip {
-   struct uac2_rtd_params p_prm;
-   struct uac2_rtd_params c_prm;
-
-   struct snd_card *card;
-   struct snd_pcm *pcm;
-
-   /* timekeeping for the playback endpoint */
-   unsigned int p_interval;
-   unsigned int p_residue;
-
-   /* pre-calculated values for playback iso completion */
-   unsigned int p_pktsize;
-   unsigned int p_pktsize_residue;
-   unsigned int p_framesize;
+struct f_uac2 {
+   struct g_audio g_audio;
+   u8 ac_intf, as_in_intf, as_out_intf;
+   u8 ac_alt, as_in_alt, as_out_alt;   /* needed for get_alt() */
 };
 
-#define BUFF_SIZE_MAX  (PAGE_SIZE * 16)
-#define PRD_SIZE_MAX   PAGE_SIZE
-#define MIN_PERIODS4
-
-static struct snd_pcm_hardware uac2_pcm_hardware = {
-   .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
-| SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
-| SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
-   .rates = SNDRV_PCM_RATE_CONTINUOUS,
-   .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX,
-   .buffer_bytes_max = BUFF_SIZE_MAX,
-   .period_bytes_max = PRD_SIZE_MAX,
-   .periods_min = MIN_PERIODS,
-};
-
-struct audio_dev {
-   u8 ac_intf, ac_alt;
-   u8 as_out_intf, as_out_alt;
-   u8 as_in_intf, as_in_alt;
-
-   struct usb_ep *in_ep, *out_ep;
-   struct usb_function func;
-   struct usb_gadget *gadget;
-
-   /* The ALSA Sound Card it represents on the USB-Client side */
-   struct snd_uac2_chip uac2;
-};
-
-static inline
-struct audio_dev *func_to_agdev(struct usb_function *f)
+static inline struct f_uac2 *func_to_uac2(struct usb_function *f)
 {
-   ret

[PATCH v4 3/3] usb: gadget: add f_uac1 variant based on a new u_audio api

2017-05-17 Thread Ruslan Bilovol
This patch adds a new function 'f_uac1_acard'
(f_uac1 with virtual "ALSA card") that
uses recently created u_audio API. Comparing
to legacy f_uac1 function implementation it
doesn't require any real Audio codec to be
present on the device. In f_uac1_acard audio
streams are simply sinked to and sourced
from a virtual ALSA sound card created
using u_audio API.

Legacy f_uac1 approach is to write audio
samples directly to existing ALSA sound
card

f_uac1_acard approach is more generic/flexible
one - create an ALSA sound card that
represents USB Audio function and allows to
be used by userspace application that
may choose to do whatever it wants with the
data received from the USB Host and choose
to provide whatever it wants as audio data
to the USB Host.

f_uac1_acard also has capture support (gadget->host)
thanks to easy implementation via u_audio.
By default, capture interface has 48000kHz/2ch
configuration, same as playback channel has.

f_uac1_acard descriptors naming convention
uses f_uac2 driver naming convention that
makes it more common and meaningful.

Comparing to f_uac1, the f_uac1_acard doesn't
have volume/mute functionality. This is because
the f_uac1 volume/mute feature unit was dummy
implementation since that driver creation (2009)
and never had any real volume control or mute
functionality, so there is no any difference
here.

Since f_uac1_acard functionality, exposed
interface to userspace (virtual ALSA card),
input parameters are so different comparing
to legace f_uac1, that there is no any
reason to keep them in the same file/module,
and separate function was created.

g_audio can be built using one of existing
UAC functions (f_uac1, f_uac1_acard or f_uac2)

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 .../ABI/testing/configfs-usb-gadget-uac1_acard |  14 +
 Documentation/usb/gadget-testing.txt   |  45 ++
 drivers/usb/gadget/Kconfig |  21 +
 drivers/usb/gadget/function/Makefile   |   2 +
 drivers/usb/gadget/function/f_uac1_acard.c | 803 +
 drivers/usb/gadget/function/u_uac1_acard.h |  41 ++
 drivers/usb/gadget/legacy/Kconfig  |  15 +-
 drivers/usb/gadget/legacy/audio.c  |  53 ++
 8 files changed, 992 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_acard
 create mode 100644 drivers/usb/gadget/function/f_uac1_acard.c
 create mode 100644 drivers/usb/gadget/function/u_uac1_acard.h

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1_acard 
b/Documentation/ABI/testing/configfs-usb-gadget-uac1_acard
new file mode 100644
index 000..2cffeaa
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_acard
@@ -0,0 +1,14 @@
+What:  /config/usb-gadget/gadget/functions/uac1_acard.name
+Date:  May 2017
+KernelVersion: 4.13
+Description:
+   The attributes:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
+   req_number - the number of pre-allocated request
+   for both capture and playback
diff --git a/Documentation/usb/gadget-testing.txt 
b/Documentation/usb/gadget-testing.txt
index fb0cc4d..ecff3ec 100644
--- a/Documentation/usb/gadget-testing.txt
+++ b/Documentation/usb/gadget-testing.txt
@@ -20,6 +20,7 @@ provided by gadgets.
 17. UAC2 function
 18. UVC function
 19. PRINTER function
+20. UAC1 function (new API)
 
 
 1. ACM function
@@ -772,3 +773,47 @@ host:
 
 More advanced testing can be done with the prn_example
 described in Documentation/usb/gadget-printer.txt.
+
+
+20. UAC1 function (virtual ALSA card, using u_audio API)
+=
+
+The function is provided by usb_f_uac1_acard.ko module.
+It will create a virtual ALSA card and the audio streams are simply
+sinked to and sourced from it.
+
+Function-specific configfs interface
+
+
+The function name to use when creating the function directory
+is "uac1_acard". The uac1_acard function provides these attributes
+in its function directory:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
+   req_number - the number of pre-allocated request for both capture
+and playback
+
+The attributes have sane default values.
+
+Testing the UAC1 function
+-
+
+device: run the gadget
+host: aplay -l # should list our USB Audio Gadget
+
+This function does not require real hardware support, it just
+sends a

[PATCH v4 1/3] usb: gadget: f_uac2: remove platform driver/device creation

2017-05-17 Thread Ruslan Bilovol
Simplify f_uac2 by removing platform driver/device
creation; use composite's usb_gadget device as
parent for sound card and for debug prints.
This removes extra layer of code without any functional
change.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/function/f_uac2.c | 107 +--
 1 file changed, 28 insertions(+), 79 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index f6a0d3a..d4565b5 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -13,7 +13,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include 
@@ -51,8 +50,6 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-static const char *uac2_name = "snd_uac2";
-
 struct uac2_req {
struct uac2_rtd_params *pp; /* parent param */
struct usb_request *req;
@@ -81,9 +78,6 @@ struct uac2_rtd_params {
 };
 
 struct snd_uac2_chip {
-   struct platform_device pdev;
-   struct platform_driver pdrv;
-
struct uac2_rtd_params p_prm;
struct uac2_rtd_params c_prm;
 
@@ -122,6 +116,7 @@ struct audio_dev {
 
struct usb_ep *in_ep, *out_ep;
struct usb_function func;
+   struct usb_gadget *gadget;
 
/* The ALSA Sound Card it represents on the USB-Client side */
struct snd_uac2_chip uac2;
@@ -140,12 +135,6 @@ struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u)
 }
 
 static inline
-struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p)
-{
-   return container_of(p, struct snd_uac2_chip, pdev);
-}
-
-static inline
 struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev)
 {
return container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
@@ -254,7 +243,7 @@ uint num_channels(uint chanmask)
 
 exit:
if (usb_ep_queue(ep, req, GFP_ATOMIC))
-   dev_err(>pdev.dev, "%d Error!\n", __LINE__);
+   dev_err(uac2->card->dev, "%d Error!\n", __LINE__);
 
if (update_alsa)
snd_pcm_period_elapsed(substream);
@@ -440,23 +429,22 @@ static int uac2_pcm_null(struct snd_pcm_substream 
*substream)
.prepare = uac2_pcm_null,
 };
 
-static int snd_uac2_probe(struct platform_device *pdev)
+static int snd_uac2_probe(struct audio_dev *audio_dev)
 {
-   struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev);
+   struct snd_uac2_chip *uac2 = _dev->uac2;
struct snd_card *card;
struct snd_pcm *pcm;
-   struct audio_dev *audio_dev;
struct f_uac2_opts *opts;
int err;
int p_chmask, c_chmask;
 
-   audio_dev = uac2_to_agdev(uac2);
opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst);
p_chmask = opts->p_chmask;
c_chmask = opts->c_chmask;
 
/* Choose any slot, with no id */
-   err = snd_card_new(>dev, -1, NULL, THIS_MODULE, 0, );
+   err = snd_card_new(_dev->gadget->dev,
+   -1, NULL, THIS_MODULE, 0, );
if (err < 0)
return err;
 
@@ -481,16 +469,15 @@ static int snd_uac2_probe(struct platform_device *pdev)
 
strcpy(card->driver, "UAC2_Gadget");
strcpy(card->shortname, "UAC2_Gadget");
-   sprintf(card->longname, "UAC2_Gadget %i", pdev->id);
+   sprintf(card->longname, "UAC2_Gadget %i", card->dev->id);
 
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);
 
err = snd_card_register(card);
-   if (!err) {
-   platform_set_drvdata(pdev, card);
+
+   if (!err)
return 0;
-   }
 
 snd_fail:
snd_card_free(card);
@@ -501,9 +488,9 @@ static int snd_uac2_probe(struct platform_device *pdev)
return err;
 }
 
-static int snd_uac2_remove(struct platform_device *pdev)
+static int snd_uac2_remove(struct audio_dev *audio_dev)
 {
-   struct snd_card *card = platform_get_drvdata(pdev);
+   struct snd_card *card = audio_dev->uac2.card;
 
if (card)
return snd_card_free(card);
@@ -511,45 +498,6 @@ static int snd_uac2_remove(struct platform_device *pdev)
return 0;
 }
 
-static void snd_uac2_release(struct device *dev)
-{
-   dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
-}
-
-static int alsa_uac2_init(struct audio_dev *agdev)
-{
-   struct snd_uac2_chip *uac2 = >uac2;
-   int err;
-
-   uac2->pdrv.probe = snd_uac2_probe;
-   uac2->pdrv.remove = snd_uac2_remove;
-   uac2->pdrv.driver.name = uac2_name;
-
-   uac2->pdev.id = 0;
-   uac2->pdev.name = uac2_name;
-   uac2->pdev.dev.release = snd_uac2_release;
-
-   /* Register snd_uac2 driver */
-   err = platform_driver_register(>pdrv);
-   if (err)
-

Re: [PATCH v3 0/3] USB Audio Gadget refactoring

2017-02-04 Thread Ruslan Bilovol
Hi Felipe,

On Mon, Aug 29, 2016 at 11:05 AM, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Ruslan Bilovol <ruslan.bilo...@gmail.com> writes:
>> I came to this patch series when wanted to do two things:
>>  - use UAC1 as virtual ALSA sound card on gadget side,
>>just like UAC2 is used so it's possible to do rate
>>resampling
>>  - have both playback/capture support in UAC1
>>
>> Since I wanted to have same behavior for both UAC1/UAC2,
>> obviously I've got an utility part (u_audio.c) for
>> virtual ALSA sound card handling like we have
>> for ethernet(u_ether) or serial(u_serial) functions.
>> Function-specific parts (f_uac1/f_uac2) became almost
>> as storage for class-specific USB descriptors, some
>> boilerplate for configfs, binding and few USB
>> config request handling.
>>
>> Originally in RFC [1] I've posted before, there was
>> major change to f_uac1 after that it couldn't do
>> direct play to existing ALSA sound card anymore,
>> representing audio on gadget side as virtual
>> ALSA sound card where audio streams are simply
>> sinked to and sourced from it, so it may break
>> current usecase for some people (and that's why
>> it was RFC).
>>
>> During RFC discussion, it was agreed to not touch
>> existing f_uac1 implementation and create new one
>> instead. This patchset (v2) introduced new function
>> named f_uac1_newapi and doesn't touch current f_uac1
>> implementation, so people still can use old behavior
>>
>> Now, it's possible to use existing user-space
>> applications for audio routing between Audio Gadget
>> and real sound card. I personally use alsaloop tool
>> from alsautils and have ability to create PCM
>> loopback between two different ALSA cards using
>> rate resampling, which was not possible with previous
>> "direct play to ALSA card" approach in f_uac1.
>>
>> While here, also dropped redundant platform
>> driver/device creation in f_uac2 driver (as well as
>> didn't add "never implemented" volume/mute functionality
>> in f_uac1 to f_uac1_newapi) that made this work even
>> easier to do.
>>
>> This series is tested with both legacy g_audio.ko and
>> modern configfs approaches under Ubuntu 14.04 (UAC1 and
>> UAC2) and under Windows7 x64 (UAC1 only) having
>> perfect results in all cases.
>>
>> Comments, testing are welcome.
>>
>> v3 changes:
>>  - renamed u_audio exported symbols so they don't
>>conflict with old f_uac1 if both are built-in.
>>
>> v2 changes:
>>  - do not touch f_uac1, instead created f_uac1_newapi
>
> f_uac1_newapi What the hell man? :-s

Yes, sometimes it's difficult to create laconic name that shows
difference to old f_uac1. We can name it alternatively
"f_uac1_alsa" or maybe anybody else have good idea here.
I just wanted to show here that it's f_uac1 with completely
different functionality (expose ALSA card to userspace
instead of consuming existing one)

>
> Sure you can't change f_uac1 to newapi without introducing userland
> visible changes? We really don't want to add another copy of f_uac1,
> sorry.

Do you mean same f_uac1.ko module will be able to use existing
ALSA card (old api) and create it own as well (new api) in the same
time at runtime?

By the way, while I understand your desire to not introduce
userland visible changes, in this particular case it doesn't
make much sense, since that's, again, two opposite approaches
to consume and transfer data to userspace
Moreover, now old f_uac1 and new f_uac1_newapi have
different functionality exposed to host (first one has only
playback, second one - playback+capture), so even USB
descriptors are different.

So userspace compatibility in this case will make f_uac1
driver too difficult to maintain and add new functionality.

So I prefer to keep the new version of f_uac1 function
and let it move forward with new features.

Best regards,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/3] USB Audio Gadget refactoring

2016-08-17 Thread Ruslan Bilovol
I came to this patch series when wanted to do two things:
 - use UAC1 as virtual ALSA sound card on gadget side,
   just like UAC2 is used so it's possible to do rate
   resampling
 - have both playback/capture support in UAC1

Since I wanted to have same behavior for both UAC1/UAC2,
obviously I've got an utility part (u_audio.c) for
virtual ALSA sound card handling like we have
for ethernet(u_ether) or serial(u_serial) functions.
Function-specific parts (f_uac1/f_uac2) became almost 
as storage for class-specific USB descriptors, some
boilerplate for configfs, binding and few USB
config request handling.

Originally in RFC [1] I've posted before, there was
major change to f_uac1 after that it couldn't do
direct play to existing ALSA sound card anymore,
representing audio on gadget side as virtual
ALSA sound card where audio streams are simply
sinked to and sourced from it, so it may break
current usecase for some people (and that's why
it was RFC).

During RFC discussion, it was agreed to not touch
existing f_uac1 implementation and create new one
instead. This patchset (v2) introduced new function
named f_uac1_newapi and doesn't touch current f_uac1
implementation, so people still can use old behavior

Now, it's possible to use existing user-space
applications for audio routing between Audio Gadget
and real sound card. I personally use alsaloop tool
from alsautils and have ability to create PCM
loopback between two different ALSA cards using
rate resampling, which was not possible with previous
"direct play to ALSA card" approach in f_uac1. 

While here, also dropped redundant platform
driver/device creation in f_uac2 driver (as well as
didn't add "never implemented" volume/mute functionality
in f_uac1 to f_uac1_newapi) that made this work even
easier to do.

This series is tested with both legacy g_audio.ko and
modern configfs approaches under Ubuntu 14.04 (UAC1 and
UAC2) and under Windows7 x64 (UAC1 only) having
perfect results in all cases.

Comments, testing are welcome.

v3 changes:
 - renamed u_audio exported symbols so they don't
   conflict with old f_uac1 if both are built-in.

v2 changes:
 - do not touch f_uac1, instead created f_uac1_newapi
 - added documentation for f_uac1_newapi
 - rebased on top of v4.8-rc1

[1] https://lkml.org/lkml/2016/5/23/649

Ruslan Bilovol (3):
  usb: gadget: f_uac2: remove platform driver/device creation
  usb: gadget: f_uac2: split out audio core
  usb: gadget: add f_uac1 variant based on new u_audio api

 .../ABI/testing/configfs-usb-gadget-uac1_newapi|  12 +
 Documentation/usb/gadget-testing.txt   |  41 ++
 drivers/usb/gadget/Kconfig |  25 +
 drivers/usb/gadget/function/Makefile   |   3 +
 drivers/usb/gadget/function/f_uac1_newapi.c| 795 +
 drivers/usb/gadget/function/f_uac2.c   | 778 +++-
 drivers/usb/gadget/function/u_audio.c  | 632 
 drivers/usb/gadget/function/u_audio.h  |  93 +++
 drivers/usb/gadget/function/u_uac1_newapi.h|  39 +
 drivers/usb/gadget/legacy/Kconfig  |  14 +-
 drivers/usb/gadget/legacy/audio.c  |  52 ++
 11 files changed, 1801 insertions(+), 683 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
 create mode 100644 drivers/usb/gadget/function/f_uac1_newapi.c
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h
 create mode 100644 drivers/usb/gadget/function/u_uac1_newapi.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/3] usb: gadget: f_uac2: remove platform driver/device creation

2016-08-17 Thread Ruslan Bilovol
Simplify f_uac2 by removing platform driver/device
creation; use composite's usb_gadget device as
parent for sound card and for debug prints.
This removes extra layer of code without any functional
change.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/function/f_uac2.c | 107 +--
 1 file changed, 28 insertions(+), 79 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index cd214ec8..e14628c 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -13,7 +13,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include 
@@ -54,8 +53,6 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-static const char *uac2_name = "snd_uac2";
-
 struct uac2_req {
struct uac2_rtd_params *pp; /* parent param */
struct usb_request *req;
@@ -84,9 +81,6 @@ struct uac2_rtd_params {
 };
 
 struct snd_uac2_chip {
-   struct platform_device pdev;
-   struct platform_driver pdrv;
-
struct uac2_rtd_params p_prm;
struct uac2_rtd_params c_prm;
 
@@ -125,6 +119,7 @@ struct audio_dev {
 
struct usb_ep *in_ep, *out_ep;
struct usb_function func;
+   struct usb_gadget *gadget;
 
/* The ALSA Sound Card it represents on the USB-Client side */
struct snd_uac2_chip uac2;
@@ -143,12 +138,6 @@ struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u)
 }
 
 static inline
-struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p)
-{
-   return container_of(p, struct snd_uac2_chip, pdev);
-}
-
-static inline
 struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev)
 {
return container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
@@ -257,7 +246,7 @@ agdev_iso_complete(struct usb_ep *ep, struct usb_request 
*req)
 
 exit:
if (usb_ep_queue(ep, req, GFP_ATOMIC))
-   dev_err(>pdev.dev, "%d Error!\n", __LINE__);
+   dev_err(uac2->card->dev, "%d Error!\n", __LINE__);
 
if (update_alsa)
snd_pcm_period_elapsed(substream);
@@ -441,23 +430,22 @@ static struct snd_pcm_ops uac2_pcm_ops = {
.prepare = uac2_pcm_null,
 };
 
-static int snd_uac2_probe(struct platform_device *pdev)
+static int snd_uac2_probe(struct audio_dev *audio_dev)
 {
-   struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev);
+   struct snd_uac2_chip *uac2 = _dev->uac2;
struct snd_card *card;
struct snd_pcm *pcm;
-   struct audio_dev *audio_dev;
struct f_uac2_opts *opts;
int err;
int p_chmask, c_chmask;
 
-   audio_dev = uac2_to_agdev(uac2);
opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst);
p_chmask = opts->p_chmask;
c_chmask = opts->c_chmask;
 
/* Choose any slot, with no id */
-   err = snd_card_new(>dev, -1, NULL, THIS_MODULE, 0, );
+   err = snd_card_new(_dev->gadget->dev,
+   -1, NULL, THIS_MODULE, 0, );
if (err < 0)
return err;
 
@@ -482,16 +470,15 @@ static int snd_uac2_probe(struct platform_device *pdev)
 
strcpy(card->driver, "UAC2_Gadget");
strcpy(card->shortname, "UAC2_Gadget");
-   sprintf(card->longname, "UAC2_Gadget %i", pdev->id);
+   sprintf(card->longname, "UAC2_Gadget %i", card->dev->id);
 
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);
 
err = snd_card_register(card);
-   if (!err) {
-   platform_set_drvdata(pdev, card);
+
+   if (!err)
return 0;
-   }
 
 snd_fail:
snd_card_free(card);
@@ -502,9 +489,9 @@ snd_fail:
return err;
 }
 
-static int snd_uac2_remove(struct platform_device *pdev)
+static int snd_uac2_remove(struct audio_dev *audio_dev)
 {
-   struct snd_card *card = platform_get_drvdata(pdev);
+   struct snd_card *card = audio_dev->uac2.card;
 
if (card)
return snd_card_free(card);
@@ -512,45 +499,6 @@ static int snd_uac2_remove(struct platform_device *pdev)
return 0;
 }
 
-static void snd_uac2_release(struct device *dev)
-{
-   dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
-}
-
-static int alsa_uac2_init(struct audio_dev *agdev)
-{
-   struct snd_uac2_chip *uac2 = >uac2;
-   int err;
-
-   uac2->pdrv.probe = snd_uac2_probe;
-   uac2->pdrv.remove = snd_uac2_remove;
-   uac2->pdrv.driver.name = uac2_name;
-
-   uac2->pdev.id = 0;
-   uac2->pdev.name = uac2_name;
-   uac2->pdev.dev.release = snd_uac2_release;
-
-   /* Register snd_uac2 driver */
-   err = platform_driver_register(>pdrv);
-   if (err)
-   return err;
-
-   

[PATCH v3 3/3] usb: gadget: add f_uac1 variant based on new u_audio api

2016-08-17 Thread Ruslan Bilovol
This patch adds new function f_uac1_newapi that
uses recently created u_audio api. This makes
f_uac1_newapi implementation much simpler by
reusing existing u_audio core utilities.

This also drops previous f_uac1 approach (write
audio samples directly to existing ALSA sound
card) and moves to more generic/flexible
one - create an f_uac1 ALSA sound card that
represents USB Audio function and allows to
be used by userspace tools.

f_uac1_newapi also has capture support (gadget->host).
By default, capture interface has 48000kHz/2ch
configuration, same as playback channel has.

f_uac1_newapi descriptors naming conventios
uses f_uac2 driver naming convention that
makes it more common and meaningful.

Comparing to f_uac1, the f_uac1_newapi doesn't
have volume/mute functionality. This is because
the volume/mute feature unit was dummy
implementation since that driver creation (2009)
and never had real volume control or mute
functionality.

g_audio can be built using one of existing
uac functions (f_uac1, f_uac1_newapi or f_uac2)

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 .../ABI/testing/configfs-usb-gadget-uac1_newapi|  12 +
 Documentation/usb/gadget-testing.txt   |  41 ++
 drivers/usb/gadget/Kconfig |  21 +
 drivers/usb/gadget/function/Makefile   |   2 +
 drivers/usb/gadget/function/f_uac1_newapi.c| 795 +
 drivers/usb/gadget/function/u_uac1_newapi.h|  39 +
 drivers/usb/gadget/legacy/Kconfig  |  15 +-
 drivers/usb/gadget/legacy/audio.c  |  52 ++
 8 files changed, 975 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
 create mode 100644 drivers/usb/gadget/function/f_uac1_newapi.c
 create mode 100644 drivers/usb/gadget/function/u_uac1_newapi.h

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi 
b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
new file mode 100644
index 000..d355275
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
@@ -0,0 +1,12 @@
+What:  /config/usb-gadget/gadget/functions/uac1_newapi.name
+Date:  Aug 2016
+KernelVersion: 4.9
+Description:
+   The attributes:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
diff --git a/Documentation/usb/gadget-testing.txt 
b/Documentation/usb/gadget-testing.txt
index 5819605..4598d7f 100644
--- a/Documentation/usb/gadget-testing.txt
+++ b/Documentation/usb/gadget-testing.txt
@@ -20,6 +20,7 @@ provided by gadgets.
 17. UAC2 function
 18. UVC function
 19. PRINTER function
+20. UAC1 function (new API)
 
 
 1. ACM function
@@ -770,3 +771,43 @@ host:
 
 More advanced testing can be done with the prn_example
 described in Documentation/usb/gadget-printer.txt.
+
+
+20. UAC1 function (new API, using u_audio)
+=
+
+The function is provided by usb_f_uac1_newapi.ko module.
+
+Function-specific configfs interface
+
+
+The function name to use when creating the function directory
+is "uac1_newapi". The uac1_newapi function provides these attributes
+in its function directory:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
+
+The attributes have sane default values.
+
+Testing the UAC1 function
+-
+
+device: run the gadget
+host: aplay -l # should list our USB Audio Gadget
+
+This function does not require real hardware support, it just
+sends a stream of audio data to/from the host. In order to
+actually hear something at the device side, a command similar
+to this must be used at the device side:
+
+$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 &
+
+e.g.:
+
+$ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \
+aplay -D default:CARD=OdroidU3
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index a25afd8..abcb539 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -194,6 +194,9 @@ config USB_F_FS
 config USB_F_UAC1
tristate
 
+config USB_F_UAC1_NEWAPI
+   tristate
+
 config USB_F_UAC2
tristate
 
@@ -397,6 +400,24 @@ config USB_CONFIGFS_F_UAC1
  This driver requires a real Audio codec to be present
  on the device.
 
+config USB_CONFIGFS_F_UAC1_NEWAPI
+   bool "Audio Class 1.0 (new API)"
+   depends on USB_CONFIGFS
+   depends on SND
+   select USB_LIBCOMPOSITE
+   select SND_PCM
+   select USB_U_AUDIO
+   sele

[PATCH v3 2/3] usb: gadget: f_uac2: split out audio core

2016-08-17 Thread Ruslan Bilovol
Abstract the peripheral side ALSA sound card code from
the f_uac2 function into a component that can be called
by various functions, so the various flavors can be split
apart and selectively reused.

Visible changes:
 - add uac_params structure to pass audio paramteres for
   g_audio_setup
 - make ALSA sound card's name configurable
 - add [in/out]_ep_maxpsize
 - allocate snd_uac_chip structure during g_audio_setup
 - add u_audio_[start/stop]_[capture/playback] functions

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/Kconfig|   4 +
 drivers/usb/gadget/function/Makefile  |   1 +
 drivers/usb/gadget/function/f_uac2.c  | 699 --
 drivers/usb/gadget/function/u_audio.c | 632 ++
 drivers/usb/gadget/function/u_audio.h |  93 +
 drivers/usb/gadget/legacy/Kconfig |   1 +
 6 files changed, 813 insertions(+), 617 deletions(-)
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 3c3f31c..a25afd8 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -158,6 +158,9 @@ config USB_U_SERIAL
 config USB_U_ETHER
tristate
 
+config USB_U_AUDIO
+   tristate
+
 config USB_F_SERIAL
tristate
 
@@ -400,6 +403,7 @@ config USB_CONFIGFS_F_UAC2
depends on SND
select USB_LIBCOMPOSITE
select SND_PCM
+   select USB_U_AUDIO
select USB_F_UAC2
help
  This Audio function is compatible with USB Audio Class
diff --git a/drivers/usb/gadget/function/Makefile 
b/drivers/usb/gadget/function/Makefile
index cb8c225..b29f2ae 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -32,6 +32,7 @@ usb_f_mass_storage-y  := f_mass_storage.o 
storage_common.o
 obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
 usb_f_fs-y := f_fs.o
 obj-$(CONFIG_USB_F_FS) += usb_f_fs.o
+obj-$(CONFIG_USB_U_AUDIO)  += u_audio.o
 usb_f_uac1-y   := f_uac1.o u_uac1.o
 obj-$(CONFIG_USB_F_UAC1)   += usb_f_uac1.o
 usb_f_uac2-y   := f_uac2.o
diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index e14628c..ef8e976 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -15,15 +15,9 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-
+#include "u_audio.h"
 #include "u_uac2.h"
 
-/* Keep everyone on toes */
-#define USB_XFERS  2
-
 /*
  * The driver implements a simple UAC_2 topology.
  * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
@@ -53,453 +47,23 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-struct uac2_req {
-   struct uac2_rtd_params *pp; /* parent param */
-   struct usb_request *req;
-};
-
-struct uac2_rtd_params {
-   struct snd_uac2_chip *uac2; /* parent chip */
-   bool ep_enabled; /* if the ep is enabled */
-   /* Size of the ring buffer */
-   size_t dma_bytes;
-   unsigned char *dma_area;
-
-   struct snd_pcm_substream *ss;
-
-   /* Ring buffer */
-   ssize_t hw_ptr;
-
-   void *rbuf;
-
-   size_t period_size;
-
-   unsigned max_psize;
-   struct uac2_req ureq[USB_XFERS];
-
-   spinlock_t lock;
-};
-
-struct snd_uac2_chip {
-   struct uac2_rtd_params p_prm;
-   struct uac2_rtd_params c_prm;
-
-   struct snd_card *card;
-   struct snd_pcm *pcm;
-
-   /* timekeeping for the playback endpoint */
-   unsigned int p_interval;
-   unsigned int p_residue;
-
-   /* pre-calculated values for playback iso completion */
-   unsigned int p_pktsize;
-   unsigned int p_pktsize_residue;
-   unsigned int p_framesize;
-};
-
-#define BUFF_SIZE_MAX  (PAGE_SIZE * 16)
-#define PRD_SIZE_MAX   PAGE_SIZE
-#define MIN_PERIODS4
-
-static struct snd_pcm_hardware uac2_pcm_hardware = {
-   .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
-| SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
-| SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
-   .rates = SNDRV_PCM_RATE_CONTINUOUS,
-   .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX,
-   .buffer_bytes_max = BUFF_SIZE_MAX,
-   .period_bytes_max = PRD_SIZE_MAX,
-   .periods_min = MIN_PERIODS,
-};
-
-struct audio_dev {
-   u8 ac_intf, ac_alt;
-   u8 as_out_intf, as_out_alt;
-   u8 as_in_intf, as_in_alt;
-
-   struct usb_ep *in_ep, *out_ep;
-   struct usb_function func;
-   struct usb_gadget *gadget;
-
-   /* The ALSA Sound Card it represents on the USB-Client side */
-   struct snd_uac2_chip uac2;
+struct f_uac2 {
+   struct g_audio g_audio;
+   u8 ac_intf, as_in_intf, as_out_intf;
+   u8 ac_alt, as_in_alt, as_out_alt;   /* needed for get_al

Re: [PATCH v2 2/3] usb: gadget: f_uac2: split out audio core

2016-08-16 Thread Ruslan Bilovol
On Tue, Aug 16, 2016 at 9:20 PM, kbuild test robot <l...@intel.com> wrote:
> Hi Ruslan,
>
> [auto build test ERROR on balbi-usb/next]
> [also build test ERROR on v4.8-rc2 next-20160816]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Ruslan-Bilovol/USB-Audio-Gadget-refactoring/20160814-185318
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git next
> config: x86_64-randconfig-a0-08162223 (attached as .config)
> compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>drivers/usb/gadget/function/usb_f_uac1.o: In function `gaudio_setup':
>>> (.text+0x16ce): multiple definition of `gaudio_setup'
>drivers/usb/gadget/function/u_audio.o:u_audio.c:(.text+0x937): first 
> defined here
>drivers/usb/gadget/function/usb_f_uac1.o: In function `gaudio_cleanup':
>>> (.text+0x1147): multiple definition of `gaudio_cleanup'
>drivers/usb/gadget/function/u_audio.o:u_audio.c:(.text+0x3f): first 
> defined here
>

Arrgh, it now conflicts in this patchset where we keep old f_uac1
functionality. Will fix it in next patchset.

Best regards,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 0/3] USB Audio Gadget refactoring

2016-08-16 Thread Ruslan Bilovol
On Tue, Aug 16, 2016 at 12:16 PM, Peter Chen <hzpeterc...@gmail.com> wrote:
> On Sun, Aug 14, 2016 at 01:21:21AM +0300, Ruslan Bilovol wrote:
>> I came to this patch series when wanted to do two things:
>>  - use UAC1 as virtual ALSA sound card on gadget side,
>>just like UAC2 is used so it's possible to do rate
>>resampling
>>  - have both playback/capture support in UAC1
>>
>> Since I wanted to have same behavior for both UAC1/UAC2,
>> obviously I've got an utility part (u_audio.c) for
>> virtual ALSA sound card handling like we have
>> for ethernet(u_ether) or serial(u_serial) functions.
>> Function-specific parts (f_uac1/f_uac2) became almost
>> as storage for class-specific USB descriptors, some
>> boilerplate for configfs, binding and few USB
>> config request handling.
>>
>> Originally in RFC [1] I've posted before, there was
>> major change to f_uac1 after that it couldn't do
>> direct play to existing ALSA sound card anymore,
>> representing audio on gadget side as virtual
>> ALSA sound card where audio streams are simply
>> sinked to and sourced from it, so it may break
>> current usecase for some people (and that's why
>> it was RFC).
>>
>> During RFC discussion, it was agreed to not touch
>> existing f_uac1 implementation and create new one
>> instead. This patchset (v2) introduced new function
>> named f_uac1_newapi and doesn't touch current f_uac1
>> implementation, so people still can use old behavior
>>
>> Now, it's possible to use existing user-space
>> applications for audio routing between Audio Gadget
>> and real sound card. I personally use alsaloop tool
>> from alsautils and have ability to create PCM
>> loopback between two different ALSA cards using
>> rate resampling, which was not possible with previous
>> "direct play to ALSA card" approach in f_uac1.
>>
>> While here, also dropped redundant platform
>> driver/device creation in f_uac2 driver (as well as
>> didn't add "never implemented" volume/mute functionality
>> in f_uac1 to f_uac1_newapi) that made this work even
>> easier to do.
>>
>> This series is tested with both legacy g_audio.ko and
>> modern configfs approaches under Ubuntu 14.04 (UAC1 and
>> UAC2) and under Windows7 x64 (UAC1 only) having
>> perfect results in all cases.
>>
>
> I find UAC2 (UAC1 is ok)  support is not well with the latest mainline
> kernel w/o your patch set. The windows7 can't install the driver
> successfully and the playback shows underrun (using local codec)
> using Linux host.

As Clemens already pointed, Windows 7 doesn't have
UAC2 support "out of the box". That's why I tested only UAC1 on it.

>
> Do you use the unchanged mainline kernel?

Yes, this patchset is based on v4.8-rc1 tag.

>
> My configfs parameters like below:
> echo 2 > functions/uac2.1/c_ssize
> echo 48000 > functions/uac2.1/c_srate
> echo 3 > functions/uac2.1/c_chmask
> echo 2 > functions/uac2.1/p_ssize
> echo 48000 > functions/uac2.1/p_srate
> echo 3 > functions/uac2.1/p_chmask

I usually don't change these (use default values here)

I use BeagleBone Black for this patchset verification.
Here is how I configure it through configfs:

uac_2

mkdir cfg
mount none cfg -t configfs
mkdir cfg/usb_gadget/g1
cd cfg/usb_gadget/g1
mkdir configs/c.1
mkdir functions/uac2.0
mkdir strings/0x409
mkdir configs/c.1/strings/0x409
echo 0x0101 > idProduct
echo 0x1d6b > idVendor
echo my-serial-num > strings/0x409/serialnumber
echo my-manufacturer > strings/0x409/manufacturer
echo "Test gadget" > strings/0x409/product
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
ln -s functions/uac2.0 configs/c.1
echo musb-hdrc.0.auto > UDC


uac_1 (new api)
-
mkdir cfg
mount none cfg -t configfs
mkdir cfg/usb_gadget/g1
cd cfg/usb_gadget/g1
mkdir configs/c.1
mkdir functions/uac1_newapi.0
mkdir strings/0x409
mkdir configs/c.1/strings/0x409
echo 0x0101 > idProduct
echo 0x1d6b > idVendor
echo my-serial-num > strings/0x409/serialnumber
echo my-manufacturer > strings/0x409/manufacturer
echo "Test gadget" > strings/0x409/product
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
ln -s functions/uac1_newapi.0 configs/c.1
echo musb-hdrc.0.auto > UDC


>
>
> Console output:
> root@imx6qdlsolo:~# arecord -f dat -t wav -D hw:1,0 | aplay -D hw:0,0 &
> [1] 859
> root@imx6qdlsolo:~#
> root@imx6qdlsolo:~# Recording WAVE 'stdin' : Signed 16 bit Little
> Endian, Rate 48000 Hz, Stereo
> Playing WAVE 'stdin' : Signed 1

Re: [PATCH v2 3/3] usb: gadget: add f_uac1 variant based on new u_audio api

2016-08-16 Thread Ruslan Bilovol
On Tue, Aug 16, 2016 at 5:52 AM, Peter Chen <hzpeterc...@gmail.com> wrote:
> On Sun, Aug 14, 2016 at 01:21:24AM +0300, Ruslan Bilovol wrote:
>> This patch adds new function f_uac1_newapi that
>> uses recently created u_audio api. This makes
>> f_uac1_newapi implementation much simpler by
>> reusing existing u_audio core utilities.
>>
>> This also drops previous f_uac1 approach (write
>> audio samples directly to existing ALSA sound
>> card) and moves to more generic/flexible
>> one - create an f_uac1 ALSA sound card that
>> represents USB Audio function and allows to
>> be used by userspace tools.
>>
>> f_uac1_newapi also has capture support (gadget->host).
>> By default, capture interface has 48000kHz/2ch
>> configuration, same as playback channel has.
>>
>> f_uac1_newapi descriptors naming conventios
>> uses f_uac2 driver naming convention that
>> makes it more common and meaningful.
>>
>> Comparing to f_uac1, the f_uac1_newapi doesn't
>> have volume/mute functionality. This is because
>> the volume/mute feature unit was dummy
>> implementation since that driver creation (2009)
>> and never had real volume control or mute
>> functionality.
>>
>> g_audio can be built using one of existing
>> uac functions (f_uac1, f_uac1_newapi or f_uac2)
>>
>> Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
>> ---
>>  .../ABI/testing/configfs-usb-gadget-uac1_newapi|  12 +
>>  Documentation/usb/gadget-testing.txt   |  41 ++
>>  drivers/usb/gadget/Kconfig |  21 +
>>  drivers/usb/gadget/function/Makefile   |   2 +
>>  drivers/usb/gadget/function/f_uac1_newapi.c| 795 
>> +
>>  drivers/usb/gadget/function/u_uac1_newapi.h|  39 +
>>  drivers/usb/gadget/legacy/Kconfig  |  15 +-
>>  drivers/usb/gadget/legacy/audio.c  |  52 ++
>>  8 files changed, 975 insertions(+), 2 deletions(-)
>>  create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
>>  create mode 100644 drivers/usb/gadget/function/f_uac1_newapi.c
>>  create mode 100644 drivers/usb/gadget/function/u_uac1_newapi.h
>>
>> diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi 
>> b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
>> new file mode 100644
>> index 000..d355275
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
>> @@ -0,0 +1,12 @@
>> +What:/config/usb-gadget/gadget/functions/uac1_newapi.name
>> +Date:Aug 2016
>> +KernelVersion:   4.9
>> +Description:
>> + The attributes:
>> +
>> + c_chmask - capture channel mask
>> + c_srate - capture sampling rate
>> + c_ssize - capture sample size (bytes)
>> + p_chmask - playback channel mask
>> + p_srate - playback sampling rate
>> + p_ssize - playback sample size (bytes)
>> diff --git a/Documentation/usb/gadget-testing.txt 
>> b/Documentation/usb/gadget-testing.txt
>> index 5819605..4598d7f 100644
>> --- a/Documentation/usb/gadget-testing.txt
>> +++ b/Documentation/usb/gadget-testing.txt
>> @@ -20,6 +20,7 @@ provided by gadgets.
>>  17. UAC2 function
>>  18. UVC function
>>  19. PRINTER function
>> +20. UAC1 function (new API)
>>
>>
>>  1. ACM function
>> @@ -770,3 +771,43 @@ host:
>>
>>  More advanced testing can be done with the prn_example
>>  described in Documentation/usb/gadget-printer.txt.
>> +
>> +
>> +20. UAC1 function (new API, using u_audio)
>> +=
>> +
>> +The function is provided by usb_f_uac1_newapi.ko module.
>> +
>> +Function-specific configfs interface
>> +
>> +
>> +The function name to use when creating the function directory
>> +is "uac1_newapi". The uac1_newapi function provides these attributes
>> +in its function directory:
>> +
>> + c_chmask - capture channel mask
>> + c_srate - capture sampling rate
>> + c_ssize - capture sample size (bytes)
>> + p_chmask - playback channel mask
>> + p_srate - playback sampling rate
>> + p_ssize - playback sample size (bytes)
>> +
>> +The attributes have sane default values.
>> +
>> +Testing the UAC1 function
>> +-
>> +
>> +device: run the gadget
>> +host: aplay

[PATCH v2 1/3] usb: gadget: f_uac2: remove platform driver/device creation

2016-08-14 Thread Ruslan Bilovol
Simplify f_uac2 by removing platform driver/device
creation; use composite's usb_gadget device as
parent for sound card and for debug prints.
This removes extra layer of code without any functional
change.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/function/f_uac2.c | 107 +--
 1 file changed, 28 insertions(+), 79 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index cd214ec8..e14628c 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -13,7 +13,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include 
@@ -54,8 +53,6 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-static const char *uac2_name = "snd_uac2";
-
 struct uac2_req {
struct uac2_rtd_params *pp; /* parent param */
struct usb_request *req;
@@ -84,9 +81,6 @@ struct uac2_rtd_params {
 };
 
 struct snd_uac2_chip {
-   struct platform_device pdev;
-   struct platform_driver pdrv;
-
struct uac2_rtd_params p_prm;
struct uac2_rtd_params c_prm;
 
@@ -125,6 +119,7 @@ struct audio_dev {
 
struct usb_ep *in_ep, *out_ep;
struct usb_function func;
+   struct usb_gadget *gadget;
 
/* The ALSA Sound Card it represents on the USB-Client side */
struct snd_uac2_chip uac2;
@@ -143,12 +138,6 @@ struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u)
 }
 
 static inline
-struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p)
-{
-   return container_of(p, struct snd_uac2_chip, pdev);
-}
-
-static inline
 struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev)
 {
return container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
@@ -257,7 +246,7 @@ agdev_iso_complete(struct usb_ep *ep, struct usb_request 
*req)
 
 exit:
if (usb_ep_queue(ep, req, GFP_ATOMIC))
-   dev_err(>pdev.dev, "%d Error!\n", __LINE__);
+   dev_err(uac2->card->dev, "%d Error!\n", __LINE__);
 
if (update_alsa)
snd_pcm_period_elapsed(substream);
@@ -441,23 +430,22 @@ static struct snd_pcm_ops uac2_pcm_ops = {
.prepare = uac2_pcm_null,
 };
 
-static int snd_uac2_probe(struct platform_device *pdev)
+static int snd_uac2_probe(struct audio_dev *audio_dev)
 {
-   struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev);
+   struct snd_uac2_chip *uac2 = _dev->uac2;
struct snd_card *card;
struct snd_pcm *pcm;
-   struct audio_dev *audio_dev;
struct f_uac2_opts *opts;
int err;
int p_chmask, c_chmask;
 
-   audio_dev = uac2_to_agdev(uac2);
opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst);
p_chmask = opts->p_chmask;
c_chmask = opts->c_chmask;
 
/* Choose any slot, with no id */
-   err = snd_card_new(>dev, -1, NULL, THIS_MODULE, 0, );
+   err = snd_card_new(_dev->gadget->dev,
+   -1, NULL, THIS_MODULE, 0, );
if (err < 0)
return err;
 
@@ -482,16 +470,15 @@ static int snd_uac2_probe(struct platform_device *pdev)
 
strcpy(card->driver, "UAC2_Gadget");
strcpy(card->shortname, "UAC2_Gadget");
-   sprintf(card->longname, "UAC2_Gadget %i", pdev->id);
+   sprintf(card->longname, "UAC2_Gadget %i", card->dev->id);
 
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);
 
err = snd_card_register(card);
-   if (!err) {
-   platform_set_drvdata(pdev, card);
+
+   if (!err)
return 0;
-   }
 
 snd_fail:
snd_card_free(card);
@@ -502,9 +489,9 @@ snd_fail:
return err;
 }
 
-static int snd_uac2_remove(struct platform_device *pdev)
+static int snd_uac2_remove(struct audio_dev *audio_dev)
 {
-   struct snd_card *card = platform_get_drvdata(pdev);
+   struct snd_card *card = audio_dev->uac2.card;
 
if (card)
return snd_card_free(card);
@@ -512,45 +499,6 @@ static int snd_uac2_remove(struct platform_device *pdev)
return 0;
 }
 
-static void snd_uac2_release(struct device *dev)
-{
-   dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
-}
-
-static int alsa_uac2_init(struct audio_dev *agdev)
-{
-   struct snd_uac2_chip *uac2 = >uac2;
-   int err;
-
-   uac2->pdrv.probe = snd_uac2_probe;
-   uac2->pdrv.remove = snd_uac2_remove;
-   uac2->pdrv.driver.name = uac2_name;
-
-   uac2->pdev.id = 0;
-   uac2->pdev.name = uac2_name;
-   uac2->pdev.dev.release = snd_uac2_release;
-
-   /* Register snd_uac2 driver */
-   err = platform_driver_register(>pdrv);
-   if (err)
-   return err;
-
-   

[PATCH v2 3/3] usb: gadget: add f_uac1 variant based on new u_audio api

2016-08-14 Thread Ruslan Bilovol
This patch adds new function f_uac1_newapi that
uses recently created u_audio api. This makes
f_uac1_newapi implementation much simpler by
reusing existing u_audio core utilities.

This also drops previous f_uac1 approach (write
audio samples directly to existing ALSA sound
card) and moves to more generic/flexible
one - create an f_uac1 ALSA sound card that
represents USB Audio function and allows to
be used by userspace tools.

f_uac1_newapi also has capture support (gadget->host).
By default, capture interface has 48000kHz/2ch
configuration, same as playback channel has.

f_uac1_newapi descriptors naming conventios
uses f_uac2 driver naming convention that
makes it more common and meaningful.

Comparing to f_uac1, the f_uac1_newapi doesn't
have volume/mute functionality. This is because
the volume/mute feature unit was dummy
implementation since that driver creation (2009)
and never had real volume control or mute
functionality.

g_audio can be built using one of existing
uac functions (f_uac1, f_uac1_newapi or f_uac2)

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 .../ABI/testing/configfs-usb-gadget-uac1_newapi|  12 +
 Documentation/usb/gadget-testing.txt   |  41 ++
 drivers/usb/gadget/Kconfig |  21 +
 drivers/usb/gadget/function/Makefile   |   2 +
 drivers/usb/gadget/function/f_uac1_newapi.c| 795 +
 drivers/usb/gadget/function/u_uac1_newapi.h|  39 +
 drivers/usb/gadget/legacy/Kconfig  |  15 +-
 drivers/usb/gadget/legacy/audio.c  |  52 ++
 8 files changed, 975 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
 create mode 100644 drivers/usb/gadget/function/f_uac1_newapi.c
 create mode 100644 drivers/usb/gadget/function/u_uac1_newapi.h

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi 
b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
new file mode 100644
index 000..d355275
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
@@ -0,0 +1,12 @@
+What:  /config/usb-gadget/gadget/functions/uac1_newapi.name
+Date:  Aug 2016
+KernelVersion: 4.9
+Description:
+   The attributes:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
diff --git a/Documentation/usb/gadget-testing.txt 
b/Documentation/usb/gadget-testing.txt
index 5819605..4598d7f 100644
--- a/Documentation/usb/gadget-testing.txt
+++ b/Documentation/usb/gadget-testing.txt
@@ -20,6 +20,7 @@ provided by gadgets.
 17. UAC2 function
 18. UVC function
 19. PRINTER function
+20. UAC1 function (new API)
 
 
 1. ACM function
@@ -770,3 +771,43 @@ host:
 
 More advanced testing can be done with the prn_example
 described in Documentation/usb/gadget-printer.txt.
+
+
+20. UAC1 function (new API, using u_audio)
+=
+
+The function is provided by usb_f_uac1_newapi.ko module.
+
+Function-specific configfs interface
+
+
+The function name to use when creating the function directory
+is "uac1_newapi". The uac1_newapi function provides these attributes
+in its function directory:
+
+   c_chmask - capture channel mask
+   c_srate - capture sampling rate
+   c_ssize - capture sample size (bytes)
+   p_chmask - playback channel mask
+   p_srate - playback sampling rate
+   p_ssize - playback sample size (bytes)
+
+The attributes have sane default values.
+
+Testing the UAC1 function
+-
+
+device: run the gadget
+host: aplay -l # should list our USB Audio Gadget
+
+This function does not require real hardware support, it just
+sends a stream of audio data to/from the host. In order to
+actually hear something at the device side, a command similar
+to this must be used at the device side:
+
+$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 &
+
+e.g.:
+
+$ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \
+aplay -D default:CARD=OdroidU3
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index a25afd8..abcb539 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -194,6 +194,9 @@ config USB_F_FS
 config USB_F_UAC1
tristate
 
+config USB_F_UAC1_NEWAPI
+   tristate
+
 config USB_F_UAC2
tristate
 
@@ -397,6 +400,24 @@ config USB_CONFIGFS_F_UAC1
  This driver requires a real Audio codec to be present
  on the device.
 
+config USB_CONFIGFS_F_UAC1_NEWAPI
+   bool "Audio Class 1.0 (new API)"
+   depends on USB_CONFIGFS
+   depends on SND
+   select USB_LIBCOMPOSITE
+   select SND_PCM
+   select USB_U_AUDIO
+   sele

[PATCH v2 2/3] usb: gadget: f_uac2: split out audio core

2016-08-14 Thread Ruslan Bilovol
Abstract the peripheral side ALSA sound card code from
the f_uac2 function into a component that can be called
by various functions, so the various flavors can be split
apart and selectively reused.

Visible changes:
 - add uac_params structure to pass audio paramteres for
   gaudio_setup
 - make ALSA sound card's name configurable
 - add [in/out]_ep_maxpsize
 - allocate snd_uac_chip structure during gaudio_setup
 - add gaudio_[start/stop]_[capture/playback] functions

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/Kconfig|   4 +
 drivers/usb/gadget/function/Makefile  |   1 +
 drivers/usb/gadget/function/f_uac2.c  | 699 --
 drivers/usb/gadget/function/u_audio.c | 632 ++
 drivers/usb/gadget/function/u_audio.h |  93 +
 drivers/usb/gadget/legacy/Kconfig |   1 +
 6 files changed, 813 insertions(+), 617 deletions(-)
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 3c3f31c..a25afd8 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -158,6 +158,9 @@ config USB_U_SERIAL
 config USB_U_ETHER
tristate
 
+config USB_U_AUDIO
+   tristate
+
 config USB_F_SERIAL
tristate
 
@@ -400,6 +403,7 @@ config USB_CONFIGFS_F_UAC2
depends on SND
select USB_LIBCOMPOSITE
select SND_PCM
+   select USB_U_AUDIO
select USB_F_UAC2
help
  This Audio function is compatible with USB Audio Class
diff --git a/drivers/usb/gadget/function/Makefile 
b/drivers/usb/gadget/function/Makefile
index cb8c225..b29f2ae 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -32,6 +32,7 @@ usb_f_mass_storage-y  := f_mass_storage.o 
storage_common.o
 obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
 usb_f_fs-y := f_fs.o
 obj-$(CONFIG_USB_F_FS) += usb_f_fs.o
+obj-$(CONFIG_USB_U_AUDIO)  += u_audio.o
 usb_f_uac1-y   := f_uac1.o u_uac1.o
 obj-$(CONFIG_USB_F_UAC1)   += usb_f_uac1.o
 usb_f_uac2-y   := f_uac2.o
diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index e14628c..2cf1495 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -15,15 +15,9 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-
+#include "u_audio.h"
 #include "u_uac2.h"
 
-/* Keep everyone on toes */
-#define USB_XFERS  2
-
 /*
  * The driver implements a simple UAC_2 topology.
  * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
@@ -53,453 +47,23 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-struct uac2_req {
-   struct uac2_rtd_params *pp; /* parent param */
-   struct usb_request *req;
-};
-
-struct uac2_rtd_params {
-   struct snd_uac2_chip *uac2; /* parent chip */
-   bool ep_enabled; /* if the ep is enabled */
-   /* Size of the ring buffer */
-   size_t dma_bytes;
-   unsigned char *dma_area;
-
-   struct snd_pcm_substream *ss;
-
-   /* Ring buffer */
-   ssize_t hw_ptr;
-
-   void *rbuf;
-
-   size_t period_size;
-
-   unsigned max_psize;
-   struct uac2_req ureq[USB_XFERS];
-
-   spinlock_t lock;
-};
-
-struct snd_uac2_chip {
-   struct uac2_rtd_params p_prm;
-   struct uac2_rtd_params c_prm;
-
-   struct snd_card *card;
-   struct snd_pcm *pcm;
-
-   /* timekeeping for the playback endpoint */
-   unsigned int p_interval;
-   unsigned int p_residue;
-
-   /* pre-calculated values for playback iso completion */
-   unsigned int p_pktsize;
-   unsigned int p_pktsize_residue;
-   unsigned int p_framesize;
-};
-
-#define BUFF_SIZE_MAX  (PAGE_SIZE * 16)
-#define PRD_SIZE_MAX   PAGE_SIZE
-#define MIN_PERIODS4
-
-static struct snd_pcm_hardware uac2_pcm_hardware = {
-   .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
-| SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
-| SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
-   .rates = SNDRV_PCM_RATE_CONTINUOUS,
-   .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX,
-   .buffer_bytes_max = BUFF_SIZE_MAX,
-   .period_bytes_max = PRD_SIZE_MAX,
-   .periods_min = MIN_PERIODS,
-};
-
-struct audio_dev {
-   u8 ac_intf, ac_alt;
-   u8 as_out_intf, as_out_alt;
-   u8 as_in_intf, as_in_alt;
-
-   struct usb_ep *in_ep, *out_ep;
-   struct usb_function func;
-   struct usb_gadget *gadget;
-
-   /* The ALSA Sound Card it represents on the USB-Client side */
-   struct snd_uac2_chip uac2;
+struct f_uac2 {
+   struct gaudio gaudio;
+   u8 ac_intf, as_in_intf, as_out_intf;
+   u8 ac_alt, as_in_alt, as_out_alt;   /* needed for get_al

[PATCH v2 0/3] USB Audio Gadget refactoring

2016-08-14 Thread Ruslan Bilovol
I came to this patch series when wanted to do two things:
 - use UAC1 as virtual ALSA sound card on gadget side,
   just like UAC2 is used so it's possible to do rate
   resampling
 - have both playback/capture support in UAC1

Since I wanted to have same behavior for both UAC1/UAC2,
obviously I've got an utility part (u_audio.c) for
virtual ALSA sound card handling like we have
for ethernet(u_ether) or serial(u_serial) functions.
Function-specific parts (f_uac1/f_uac2) became almost 
as storage for class-specific USB descriptors, some
boilerplate for configfs, binding and few USB
config request handling.

Originally in RFC [1] I've posted before, there was
major change to f_uac1 after that it couldn't do
direct play to existing ALSA sound card anymore,
representing audio on gadget side as virtual
ALSA sound card where audio streams are simply
sinked to and sourced from it, so it may break
current usecase for some people (and that's why
it was RFC).

During RFC discussion, it was agreed to not touch
existing f_uac1 implementation and create new one
instead. This patchset (v2) introduced new function
named f_uac1_newapi and doesn't touch current f_uac1
implementation, so people still can use old behavior

Now, it's possible to use existing user-space
applications for audio routing between Audio Gadget
and real sound card. I personally use alsaloop tool
from alsautils and have ability to create PCM
loopback between two different ALSA cards using
rate resampling, which was not possible with previous
"direct play to ALSA card" approach in f_uac1. 

While here, also dropped redundant platform
driver/device creation in f_uac2 driver (as well as
didn't add "never implemented" volume/mute functionality
in f_uac1 to f_uac1_newapi) that made this work even
easier to do.

This series is tested with both legacy g_audio.ko and
modern configfs approaches under Ubuntu 14.04 (UAC1 and
UAC2) and under Windows7 x64 (UAC1 only) having
perfect results in all cases.

Comments, testing are welcome.

v2 changes:
 - do not touch f_uac1, instead created f_uac1_newapi
 - added documentation for f_uac1_newapi
 - rebased on top of v4.8-rc1

[1] https://lkml.org/lkml/2016/5/23/649

Ruslan Bilovol (3):
  usb: gadget: f_uac2: remove platform driver/device creation
  usb: gadget: f_uac2: split out audio core
  usb: gadget: add f_uac1 variant based on new u_audio api

 .../ABI/testing/configfs-usb-gadget-uac1_newapi|  12 +
 Documentation/usb/gadget-testing.txt   |  41 ++
 drivers/usb/gadget/Kconfig |  25 +
 drivers/usb/gadget/function/Makefile   |   3 +
 drivers/usb/gadget/function/f_uac1_newapi.c| 795 +
 drivers/usb/gadget/function/f_uac2.c   | 778 +++-
 drivers/usb/gadget/function/u_audio.c  | 632 
 drivers/usb/gadget/function/u_audio.h  |  93 +++
 drivers/usb/gadget/function/u_uac1_newapi.h|  39 +
 drivers/usb/gadget/legacy/Kconfig  |  14 +-
 drivers/usb/gadget/legacy/audio.c  |  56 +-
 11 files changed, 1803 insertions(+), 685 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi
 create mode 100644 drivers/usb/gadget/function/f_uac1_newapi.c
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h
 create mode 100644 drivers/usb/gadget/function/u_uac1_newapi.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/5] USB Audio Gadget refactoring

2016-07-26 Thread Ruslan Bilovol
On Tue, Jul 26, 2016 at 3:02 PM, Krzysztof Opasiak
<k.opas...@samsung.com> wrote:
>
>
> On 07/26/2016 10:53 AM, Jassi Brar wrote:
>> On Tue, Jul 26, 2016 at 7:01 AM, Ruslan Bilovol
>> <ruslan.bilo...@gmail.com> wrote:
>>> On Fri, Jul 15, 2016 at 10:43 AM, Clemens Ladisch <clem...@ladisch.de> 
>>> wrote:
>>>>>> On Tue, May 24, 2016 at 2:50 AM, Ruslan Bilovol
>>>>>> <ruslan.bilo...@gmail.com> wrote:
>>>>>>> it may break current usecase for some people
>>>>
>>>> And what are the benefits that justify breaking the kernel API?
>>>
>>>
>>> Main limitation with current f_uac1 design is - it can be used only on 
>>> systems
>>> with real ALSA card present and can have only exact number of
>>> channels / sampling rate as sink card has.
>>> Yet it is not flexible - can't do audio processing between f_uac1 and the 
>>> card.
>>> Also if someone wants to bind f_uac1 it to another sound card he has to
>>> unload g_audio or reconfigure it through configfs - that means USB
>>> reenumeration on host device.
>>>
>>> If you have a "virtual sound card", audio processing is done in userspace
>>> and is more flexible. You even don't need to have a real sound card and
>>> can use some userspace application for playing/capturing audio samples.
>>> Moreover, existing f_uac2 (that is USB Audio Class 2.0 function
>>> implementation) already uses approach of "virtual sound card"
>>>
>> While I agree the virtual sound card approach is the right way, I am
>> not sure if we should break the userspace api that the existing UAC1
>> driver exposes. Maybe we should add another virtual-sound-card
>> exposing UAC1 driver ... and hopefully very similar to (or just port
>> of) the f_audio_source.c from android.
>
> Definitely agree with this opinion. I don't see any benefits of breaking
> the API here instead of adding just another USB function. Maybe even
> some pieces of code could be shared with f_uac1.c but I think that this
> should be a brand new function.
>

So if we want to keep old API working, easiest (and cleanest) way is
to create a new f_uac1.c version and kconfig symbol, for example
f_uac1_newapi.c and CONFIG_USB_F_UAC1_NEWAPI
There is no sence to share some pieces of code with f_uac1.c just
because it is changed too drastically.

So I'll implement it in v2 if there is no any objections

Best regards,
Ruslan Bilovol
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/5] USB Audio Gadget refactoring

2016-07-26 Thread Ruslan Bilovol
On Tue, Jul 26, 2016 at 11:53 AM, Jassi Brar <jassisinghb...@gmail.com> wrote:
> On Tue, Jul 26, 2016 at 7:01 AM, Ruslan Bilovol
> <ruslan.bilo...@gmail.com> wrote:
>> On Fri, Jul 15, 2016 at 10:43 AM, Clemens Ladisch <clem...@ladisch.de> wrote:
>>>>> On Tue, May 24, 2016 at 2:50 AM, Ruslan Bilovol
>>>>> <ruslan.bilo...@gmail.com> wrote:
>>>>>> it may break current usecase for some people
>>>
>>> And what are the benefits that justify breaking the kernel API?
>>
>>
>> Main limitation with current f_uac1 design is - it can be used only on 
>> systems
>> with real ALSA card present and can have only exact number of
>> channels / sampling rate as sink card has.
>> Yet it is not flexible - can't do audio processing between f_uac1 and the 
>> card.
>> Also if someone wants to bind f_uac1 it to another sound card he has to
>> unload g_audio or reconfigure it through configfs - that means USB
>> reenumeration on host device.
>>
>> If you have a "virtual sound card", audio processing is done in userspace
>> and is more flexible. You even don't need to have a real sound card and
>> can use some userspace application for playing/capturing audio samples.
>> Moreover, existing f_uac2 (that is USB Audio Class 2.0 function
>> implementation) already uses approach of "virtual sound card"
>>
> While I agree the virtual sound card approach is the right way, I am
> not sure if we should break the userspace api that the existing UAC1
> driver exposes. Maybe we should add another virtual-sound-card
> exposing UAC1 driver

This approach is quite easy to implement and I though about it when
started to work on this patch series, but due to my lazyness I wanted
to get some comments before doing extra work.

> ... and hopefully very similar to (or just port
> of) the f_audio_source.c from android.

Current patch series reuses code from f_uac2 (in u_audio) and
makes it in some sense similar to f_audio_source.c.

The f_audio_source.c implementation has additional functionality
like more accurate data transferring (w.r.t timings), that can be
ported to u_audio separately.

Best regards,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/5] USB Audio Gadget refactoring

2016-07-25 Thread Ruslan Bilovol
On Fri, Jul 15, 2016 at 10:43 AM, Clemens Ladisch <clem...@ladisch.de> wrote:
>>> On Tue, May 24, 2016 at 2:50 AM, Ruslan Bilovol
>>> <ruslan.bilo...@gmail.com> wrote:
>>>> it may break current usecase for some people
>
> And what are the benefits that justify breaking the kernel API?


Main limitation with current f_uac1 design is - it can be used only on systems
with real ALSA card present and can have only exact number of
channels / sampling rate as sink card has.
Yet it is not flexible - can't do audio processing between f_uac1 and the card.
Also if someone wants to bind f_uac1 it to another sound card he has to
unload g_audio or reconfigure it through configfs - that means USB
reenumeration on host device.

If you have a "virtual sound card", audio processing is done in userspace
and is more flexible. You even don't need to have a real sound card and
can use some userspace application for playing/capturing audio samples.
Moreover, existing f_uac2 (that is USB Audio Class 2.0 function
implementation) already uses approach of "virtual sound card"

A real cases when it's required to have UAC1 gadget represented as virtual
sound card on gadget side:
 - android accessory f_audio_source.c implementation, android plays audio
   directly to UAC1 "virtual sound card"
 - some 3G/LTE voice USB sticks with Linux as firmware have user-space
   application inside that receives audio from network and need to source/sink
   it to some sound card (UAC1)
 - USB sound card with complex audio processing inside, made on small
   Linux-powered device ("sound-studio")

What's annoying is we have two quite similar USB Audio Classes
implementations(f_uac1 and f_uac2) that have opposite audio
representations: first transfers audio samples directly to real ALSA card,
second exposes virtual ALSA card. That means you have to implement
similar things (capture/playback, etc) in different way. With new design
both implementations provide same "API" (virtual sound card), allowing
us to reuse a lot of code and implement new features much easier (look
at adding of capture support to f_uac1 in PATCH 5/5 - that was very simple
and consists almost from adding new USB descriptors and reusing existing
code from newly created u_audio.c)

Also new USB Audio Gadget design follows existing approach for
another USB Classes:
 - serial gadgets use u_serial and expose virtual TTY port
 - networking gadgets use u_ether and expose virtual network interface
 - uvc gadget exposes virtual v4l device
 - midi gadget exposes virtual sound card
 - etc, etc

Of course disadvantage of new approach for UAC1 gadget is you need to
use some userspace application for routing audio from virtual to real
sound card, like in case of UAC2 gadget. But thanks to existing
applications like alsaloop it's not difficult nowadays.

The answer I want to get in this RFC - can we drop current f_uac1 approach,
simplify USB Audio Gadget by reusing common code.
Or "we do not break userspace" (or API) and have to live with it forever.

Best regards,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/5] USB Audio Gadget refactoring

2016-07-14 Thread Ruslan Bilovol
Ping?

On Wed, Jun 8, 2016 at 11:03 AM, Ruslan Bilovol
<ruslan.bilo...@gmail.com> wrote:
> Hi guys,
>
> Any feedback on this patch series? Has anybody had a chance to test it?
>
> Regards,
> Ruslan
>
> On Tue, May 24, 2016 at 2:50 AM, Ruslan Bilovol
> <ruslan.bilo...@gmail.com> wrote:
>> I came to this patch series when wanted to do two things:
>>  - use UAC1 as virtual ALSA sound card on gadget side,
>>just like UAC2 is used so it's possible to do rate
>>resampling
>>  - have both playback/capture support in UAC1
>>
>> Since I wanted to have same behavior for both UAC1/UAC2,
>> obviously I've got an utility part (u_audio.c) for
>> virtual ALSA sound card handling like we have
>> for ethernet(u_ether) or serial(u_serial) functions.
>> Function-specific parts (f_uac1/f_uac2) became almost
>> as storage for class-specfic USB descriptors, some
>> boilerplate for configfs, binding and few USB
>> config request handling.
>>
>> Major change to f_uac1 it that it can't do
>> direct play to existing ALSA sound card anymore,
>> representing audio on gadget side as virtual
>> ALSA sound card where audio streams are simply
>> sinked to and sourced from it, so it may break
>> current usecase for some people (and that's why
>> it's RFC).
>>
>> Luckily, it's possible to use existing user-space
>> applications for audio routing between Audio Gadget
>> and real sound card. I personally use alsaloop tool
>> from alsautils and have ability to create PCM
>> loopback between two different ALSA cards using
>> rate resampling, which is not possible with previous
>> "direct play to ALSA card" approach in f_uac1.
>>
>> While here, also dropped redundant platform
>> driver/device creation in f_uac2 driver as well as
>> "never implemented" volume/mute functionality in f_uac1
>> that made this work even easier to do.
>>
>> This series is tested with both legacy g_audio.ko and
>> modern configfs approaches under Ubuntu 14.04 (UAC1 and
>> UAC2) and under Windows7 x64 (UAC1 only) having
>> perfect results in all cases.
>>
>> Some changes may have lack of good description that may
>> be obvious for me but not so clear for others, but I
>> hope to fix it in next versions.
>>
>> Comments, testing are welcome.
>>
>> Ruslan Bilovol (5):
>>   usb: gadget: f_uac2: remove platform driver/device creation
>>   usb: gadget: f_uac2: split out audio core
>>   usb: gadget: f_uac1: drop volume/mute functionality
>>   usb: gadget: f_uac1: switch to u_audio core utilities
>>   usb: gadget: f_uac1: add capture support
>>
>>  drivers/usb/gadget/Kconfig|  13 +-
>>  drivers/usb/gadget/function/Makefile  |   3 +-
>>  drivers/usb/gadget/function/f_uac1.c  | 842 
>> +-
>>  drivers/usb/gadget/function/f_uac2.c  | 778 ---
>>  drivers/usb/gadget/function/u_audio.c | 632 +
>>  drivers/usb/gadget/function/u_audio.h |  93 
>>  drivers/usb/gadget/function/u_uac1.c  | 314 -
>>  drivers/usb/gadget/function/u_uac1.h  |  71 +--
>>  drivers/usb/gadget/legacy/Kconfig |   1 +
>>  drivers/usb/gadget/legacy/audio.c |  54 ++-
>>  10 files changed, 1208 insertions(+), 1593 deletions(-)
>>  create mode 100644 drivers/usb/gadget/function/u_audio.c
>>  create mode 100644 drivers/usb/gadget/function/u_audio.h
>>  delete mode 100644 drivers/usb/gadget/function/u_uac1.c
>>
>> --
>> 1.9.1
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/5] USB Audio Gadget refactoring

2016-06-08 Thread Ruslan Bilovol
Hi guys,

Any feedback on this patch series? Has anybody had a chance to test it?

Regards,
Ruslan

On Tue, May 24, 2016 at 2:50 AM, Ruslan Bilovol
<ruslan.bilo...@gmail.com> wrote:
> I came to this patch series when wanted to do two things:
>  - use UAC1 as virtual ALSA sound card on gadget side,
>just like UAC2 is used so it's possible to do rate
>resampling
>  - have both playback/capture support in UAC1
>
> Since I wanted to have same behavior for both UAC1/UAC2,
> obviously I've got an utility part (u_audio.c) for
> virtual ALSA sound card handling like we have
> for ethernet(u_ether) or serial(u_serial) functions.
> Function-specific parts (f_uac1/f_uac2) became almost
> as storage for class-specfic USB descriptors, some
> boilerplate for configfs, binding and few USB
> config request handling.
>
> Major change to f_uac1 it that it can't do
> direct play to existing ALSA sound card anymore,
> representing audio on gadget side as virtual
> ALSA sound card where audio streams are simply
> sinked to and sourced from it, so it may break
> current usecase for some people (and that's why
> it's RFC).
>
> Luckily, it's possible to use existing user-space
> applications for audio routing between Audio Gadget
> and real sound card. I personally use alsaloop tool
> from alsautils and have ability to create PCM
> loopback between two different ALSA cards using
> rate resampling, which is not possible with previous
> "direct play to ALSA card" approach in f_uac1.
>
> While here, also dropped redundant platform
> driver/device creation in f_uac2 driver as well as
> "never implemented" volume/mute functionality in f_uac1
> that made this work even easier to do.
>
> This series is tested with both legacy g_audio.ko and
> modern configfs approaches under Ubuntu 14.04 (UAC1 and
> UAC2) and under Windows7 x64 (UAC1 only) having
> perfect results in all cases.
>
> Some changes may have lack of good description that may
> be obvious for me but not so clear for others, but I
> hope to fix it in next versions.
>
> Comments, testing are welcome.
>
> Ruslan Bilovol (5):
>   usb: gadget: f_uac2: remove platform driver/device creation
>   usb: gadget: f_uac2: split out audio core
>   usb: gadget: f_uac1: drop volume/mute functionality
>   usb: gadget: f_uac1: switch to u_audio core utilities
>   usb: gadget: f_uac1: add capture support
>
>  drivers/usb/gadget/Kconfig|  13 +-
>  drivers/usb/gadget/function/Makefile  |   3 +-
>  drivers/usb/gadget/function/f_uac1.c  | 842 
> +-
>  drivers/usb/gadget/function/f_uac2.c  | 778 ---
>  drivers/usb/gadget/function/u_audio.c | 632 +
>  drivers/usb/gadget/function/u_audio.h |  93 
>  drivers/usb/gadget/function/u_uac1.c  | 314 -
>  drivers/usb/gadget/function/u_uac1.h  |  71 +--
>  drivers/usb/gadget/legacy/Kconfig |   1 +
>  drivers/usb/gadget/legacy/audio.c |  54 ++-
>  10 files changed, 1208 insertions(+), 1593 deletions(-)
>  create mode 100644 drivers/usb/gadget/function/u_audio.c
>  create mode 100644 drivers/usb/gadget/function/u_audio.h
>  delete mode 100644 drivers/usb/gadget/function/u_uac1.c
>
> --
> 1.9.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 3/5] usb: gadget: f_uac1: drop volume/mute functionality

2016-05-23 Thread Ruslan Bilovol
The volume/mute feature unit was dummy implementation
since this driver creation (2009) and never had
real volume control or mute functionality.
Since it was never implemented, drop it and
increase maintainability of the driver.
Those who want real volume/mute support may
revert this patch and add needed handlers

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/function/f_uac1.c | 182 +--
 1 file changed, 5 insertions(+), 177 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac1.c 
b/drivers/usb/gadget/function/f_uac1.c
index f2ac0cb..ba498af 100644
--- a/drivers/usb/gadget/function/f_uac1.c
+++ b/drivers/usb/gadget/function/f_uac1.c
@@ -17,9 +17,6 @@
 
 #include "u_uac1.h"
 
-static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value);
-static int generic_get_cmd(struct usb_audio_control *con, u8 cmd);
-
 /*
  * DESCRIPTORS ... most are static, but strings and full
  * configuration descriptors are built on demand.
@@ -49,9 +46,9 @@ static struct usb_interface_descriptor ac_interface_desc = {
 DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
 
 #define UAC_DT_AC_HEADER_LENGTH
UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES)
-/* 1 input terminal, 1 output terminal and 1 feature unit */
+/* 1 input terminal and 1 output terminal */
 #define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + 
UAC_DT_INPUT_TERMINAL_SIZE \
-   + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0))
+   + UAC_DT_OUTPUT_TERMINAL_SIZE)
 /* B.3.2  Class-Specific AC Interface Descriptor */
 static struct uac1_ac_header_descriptor_1 ac_header_desc = {
.bLength =  UAC_DT_AC_HEADER_LENGTH,
@@ -77,54 +74,15 @@ static struct uac_input_terminal_descriptor 
input_terminal_desc = {
.wChannelConfig =   0x3,
 };
 
-DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0);
-
-#define FEATURE_UNIT_ID2
-static struct uac_feature_unit_descriptor_0 feature_unit_desc = {
-   .bLength= UAC_DT_FEATURE_UNIT_SIZE(0),
-   .bDescriptorType= USB_DT_CS_INTERFACE,
-   .bDescriptorSubtype = UAC_FEATURE_UNIT,
-   .bUnitID= FEATURE_UNIT_ID,
-   .bSourceID  = INPUT_TERMINAL_ID,
-   .bControlSize   = 2,
-   .bmaControls[0] = (UAC_FU_MUTE | UAC_FU_VOLUME),
-};
-
-static struct usb_audio_control mute_control = {
-   .list = LIST_HEAD_INIT(mute_control.list),
-   .name = "Mute Control",
-   .type = UAC_FU_MUTE,
-   /* Todo: add real Mute control code */
-   .set = generic_set_cmd,
-   .get = generic_get_cmd,
-};
-
-static struct usb_audio_control volume_control = {
-   .list = LIST_HEAD_INIT(volume_control.list),
-   .name = "Volume Control",
-   .type = UAC_FU_VOLUME,
-   /* Todo: add real Volume control code */
-   .set = generic_set_cmd,
-   .get = generic_get_cmd,
-};
-
-static struct usb_audio_control_selector feature_unit = {
-   .list = LIST_HEAD_INIT(feature_unit.list),
-   .id = FEATURE_UNIT_ID,
-   .name = "Mute & Volume Control",
-   .type = UAC_FEATURE_UNIT,
-   .desc = (struct usb_descriptor_header *)_unit_desc,
-};
-
-#define OUTPUT_TERMINAL_ID 3
+#define OUTPUT_TERMINAL_ID 2
 static struct uac1_output_terminal_descriptor output_terminal_desc = {
.bLength= UAC_DT_OUTPUT_TERMINAL_SIZE,
.bDescriptorType= USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
.bTerminalID= OUTPUT_TERMINAL_ID,
.wTerminalType  = UAC_OUTPUT_TERMINAL_SPEAKER,
-   .bAssocTerminal = FEATURE_UNIT_ID,
-   .bSourceID  = FEATURE_UNIT_ID,
+   .bAssocTerminal = 0,
+   .bSourceID  = INPUT_TERMINAL_ID,
 };
 
 /* B.4.1  Standard AS Interface Descriptor */
@@ -195,7 +153,6 @@ static struct usb_descriptor_header *f_audio_desc[] = {
 
(struct usb_descriptor_header *)_terminal_desc,
(struct usb_descriptor_header *)_terminal_desc,
-   (struct usb_descriptor_header *)_unit_desc,
 
(struct usb_descriptor_header *)_interface_alt_0_desc,
(struct usb_descriptor_header *)_interface_alt_1_desc,
@@ -212,7 +169,6 @@ enum {
STR_AC_IF,
STR_INPUT_TERMINAL,
STR_INPUT_TERMINAL_CH_NAMES,
-   STR_FEAT_DESC_0,
STR_OUTPUT_TERMINAL,
STR_AS_IF_ALT0,
STR_AS_IF_ALT1,
@@ -222,7 +178,6 @@ static struct usb_string strings_uac1[] = {
[STR_AC_IF].s = "AC Interface",
[STR_INPUT_TERMINAL].s = "Input terminal",
[STR_INPUT_TERMINAL_CH_NAMES].s = "Channels",
-   [STR_FEAT_DESC_0].s = "Volume control & mute",
[STR_OUTPUT_TERMINAL].s = "Output terminal",
[STR_AS_IF_ALT0].s = "AS Interface",
[STR_AS_IF_ALT1].s = "AS Interface

[RFC PATCH 2/5] usb: gadget: f_uac2: split out audio core

2016-05-23 Thread Ruslan Bilovol
Abstract the peripheral side ALSA sound card code from
the f_uac2 function into a component that can be called
by various functions, so the various flavors can be split
apart and selectively reused.

Visible changes:
 - add uac_params structure to pass audio paramteres for
   gaudio_setup
 - make ALSA sound card's name configurable
 - add [in/out]_ep_maxpsize
 - allocate snd_uac_chip structure during gaudio_setup
 - add gaudio_[start/stop]_[capture/playback] functions

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/Kconfig|   4 +
 drivers/usb/gadget/function/Makefile  |   1 +
 drivers/usb/gadget/function/f_uac2.c  | 699 --
 drivers/usb/gadget/function/u_audio.c | 632 ++
 drivers/usb/gadget/function/u_audio.h |  93 +
 drivers/usb/gadget/legacy/Kconfig |   1 +
 6 files changed, 813 insertions(+), 617 deletions(-)
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index af5d922..42d8508 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -157,6 +157,9 @@ config USB_U_SERIAL
 config USB_U_ETHER
tristate
 
+config USB_U_AUDIO
+   tristate
+
 config USB_F_SERIAL
tristate
 
@@ -399,6 +402,7 @@ config USB_CONFIGFS_F_UAC2
depends on SND
select USB_LIBCOMPOSITE
select SND_PCM
+   select USB_U_AUDIO
select USB_F_UAC2
help
  This Audio function is compatible with USB Audio Class
diff --git a/drivers/usb/gadget/function/Makefile 
b/drivers/usb/gadget/function/Makefile
index cb8c225..b29f2ae 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -32,6 +32,7 @@ usb_f_mass_storage-y  := f_mass_storage.o 
storage_common.o
 obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
 usb_f_fs-y := f_fs.o
 obj-$(CONFIG_USB_F_FS) += usb_f_fs.o
+obj-$(CONFIG_USB_U_AUDIO)  += u_audio.o
 usb_f_uac1-y   := f_uac1.o u_uac1.o
 obj-$(CONFIG_USB_F_UAC1)   += usb_f_uac1.o
 usb_f_uac2-y   := f_uac2.o
diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index 8b46f05..a6c91a6 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -15,15 +15,9 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-
+#include "u_audio.h"
 #include "u_uac2.h"
 
-/* Keep everyone on toes */
-#define USB_XFERS  2
-
 /*
  * The driver implements a simple UAC_2 topology.
  * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
@@ -53,453 +47,23 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-struct uac2_req {
-   struct uac2_rtd_params *pp; /* parent param */
-   struct usb_request *req;
-};
-
-struct uac2_rtd_params {
-   struct snd_uac2_chip *uac2; /* parent chip */
-   bool ep_enabled; /* if the ep is enabled */
-   /* Size of the ring buffer */
-   size_t dma_bytes;
-   unsigned char *dma_area;
-
-   struct snd_pcm_substream *ss;
-
-   /* Ring buffer */
-   ssize_t hw_ptr;
-
-   void *rbuf;
-
-   size_t period_size;
-
-   unsigned max_psize;
-   struct uac2_req ureq[USB_XFERS];
-
-   spinlock_t lock;
-};
-
-struct snd_uac2_chip {
-   struct uac2_rtd_params p_prm;
-   struct uac2_rtd_params c_prm;
-
-   struct snd_card *card;
-   struct snd_pcm *pcm;
-
-   /* timekeeping for the playback endpoint */
-   unsigned int p_interval;
-   unsigned int p_residue;
-
-   /* pre-calculated values for playback iso completion */
-   unsigned int p_pktsize;
-   unsigned int p_pktsize_residue;
-   unsigned int p_framesize;
-};
-
-#define BUFF_SIZE_MAX  (PAGE_SIZE * 16)
-#define PRD_SIZE_MAX   PAGE_SIZE
-#define MIN_PERIODS4
-
-static struct snd_pcm_hardware uac2_pcm_hardware = {
-   .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
-| SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
-| SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
-   .rates = SNDRV_PCM_RATE_CONTINUOUS,
-   .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX,
-   .buffer_bytes_max = BUFF_SIZE_MAX,
-   .period_bytes_max = PRD_SIZE_MAX,
-   .periods_min = MIN_PERIODS,
-};
-
-struct audio_dev {
-   u8 ac_intf, ac_alt;
-   u8 as_out_intf, as_out_alt;
-   u8 as_in_intf, as_in_alt;
-
-   struct usb_ep *in_ep, *out_ep;
-   struct usb_function func;
-   struct usb_gadget *gadget;
-
-   /* The ALSA Sound Card it represents on the USB-Client side */
-   struct snd_uac2_chip uac2;
+struct f_uac2 {
+   struct gaudio gaudio;
+   u8 ac_intf, as_in_intf, as_out_intf;
+   u8 ac_alt, as_in_alt, as_out_alt;   /* needed for get_al

[RFC PATCH 0/5] USB Audio Gadget refactoring

2016-05-23 Thread Ruslan Bilovol
I came to this patch series when wanted to do two things:
 - use UAC1 as virtual ALSA sound card on gadget side,
   just like UAC2 is used so it's possible to do rate
   resampling
 - have both playback/capture support in UAC1

Since I wanted to have same behavior for both UAC1/UAC2,
obviously I've got an utility part (u_audio.c) for
virtual ALSA sound card handling like we have
for ethernet(u_ether) or serial(u_serial) functions.
Function-specific parts (f_uac1/f_uac2) became almost 
as storage for class-specfic USB descriptors, some
boilerplate for configfs, binding and few USB
config request handling.

Major change to f_uac1 it that it can't do
direct play to existing ALSA sound card anymore,
representing audio on gadget side as virtual
ALSA sound card where audio streams are simply
sinked to and sourced from it, so it may break
current usecase for some people (and that's why
it's RFC).

Luckily, it's possible to use existing user-space
applications for audio routing between Audio Gadget
and real sound card. I personally use alsaloop tool
from alsautils and have ability to create PCM
loopback between two different ALSA cards using
rate resampling, which is not possible with previous
"direct play to ALSA card" approach in f_uac1. 

While here, also dropped redundant platform
driver/device creation in f_uac2 driver as well as
"never implemented" volume/mute functionality in f_uac1
that made this work even easier to do.

This series is tested with both legacy g_audio.ko and
modern configfs approaches under Ubuntu 14.04 (UAC1 and
UAC2) and under Windows7 x64 (UAC1 only) having
perfect results in all cases.

Some changes may have lack of good description that may
be obvious for me but not so clear for others, but I
hope to fix it in next versions.

Comments, testing are welcome.

Ruslan Bilovol (5):
  usb: gadget: f_uac2: remove platform driver/device creation
  usb: gadget: f_uac2: split out audio core
  usb: gadget: f_uac1: drop volume/mute functionality
  usb: gadget: f_uac1: switch to u_audio core utilities
  usb: gadget: f_uac1: add capture support

 drivers/usb/gadget/Kconfig|  13 +-
 drivers/usb/gadget/function/Makefile  |   3 +-
 drivers/usb/gadget/function/f_uac1.c  | 842 +-
 drivers/usb/gadget/function/f_uac2.c  | 778 ---
 drivers/usb/gadget/function/u_audio.c | 632 +
 drivers/usb/gadget/function/u_audio.h |  93 
 drivers/usb/gadget/function/u_uac1.c  | 314 -
 drivers/usb/gadget/function/u_uac1.h  |  71 +--
 drivers/usb/gadget/legacy/Kconfig |   1 +
 drivers/usb/gadget/legacy/audio.c |  54 ++-
 10 files changed, 1208 insertions(+), 1593 deletions(-)
 create mode 100644 drivers/usb/gadget/function/u_audio.c
 create mode 100644 drivers/usb/gadget/function/u_audio.h
 delete mode 100644 drivers/usb/gadget/function/u_uac1.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 1/5] usb: gadget: f_uac2: remove platform driver/device creation

2016-05-23 Thread Ruslan Bilovol
Simplify f_uac2 by removing platform driver/device
creation; use composite's usb_gadget device as
parent for sound card and for debug prints.
This removes extra layer of code without any functional
change.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/function/f_uac2.c | 107 +--
 1 file changed, 28 insertions(+), 79 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index 186d4b1..8b46f05 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -13,7 +13,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include 
@@ -54,8 +53,6 @@
 #define UNFLW_CTRL 8
 #define OVFLW_CTRL 10
 
-static const char *uac2_name = "snd_uac2";
-
 struct uac2_req {
struct uac2_rtd_params *pp; /* parent param */
struct usb_request *req;
@@ -84,9 +81,6 @@ struct uac2_rtd_params {
 };
 
 struct snd_uac2_chip {
-   struct platform_device pdev;
-   struct platform_driver pdrv;
-
struct uac2_rtd_params p_prm;
struct uac2_rtd_params c_prm;
 
@@ -125,6 +119,7 @@ struct audio_dev {
 
struct usb_ep *in_ep, *out_ep;
struct usb_function func;
+   struct usb_gadget *gadget;
 
/* The ALSA Sound Card it represents on the USB-Client side */
struct snd_uac2_chip uac2;
@@ -143,12 +138,6 @@ struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u)
 }
 
 static inline
-struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p)
-{
-   return container_of(p, struct snd_uac2_chip, pdev);
-}
-
-static inline
 struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev)
 {
return container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
@@ -257,7 +246,7 @@ agdev_iso_complete(struct usb_ep *ep, struct usb_request 
*req)
 
 exit:
if (usb_ep_queue(ep, req, GFP_ATOMIC))
-   dev_err(>pdev.dev, "%d Error!\n", __LINE__);
+   dev_err(uac2->card->dev, "%d Error!\n", __LINE__);
 
if (update_alsa)
snd_pcm_period_elapsed(substream);
@@ -441,23 +430,22 @@ static struct snd_pcm_ops uac2_pcm_ops = {
.prepare = uac2_pcm_null,
 };
 
-static int snd_uac2_probe(struct platform_device *pdev)
+static int snd_uac2_probe(struct audio_dev *audio_dev)
 {
-   struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev);
+   struct snd_uac2_chip *uac2 = _dev->uac2;
struct snd_card *card;
struct snd_pcm *pcm;
-   struct audio_dev *audio_dev;
struct f_uac2_opts *opts;
int err;
int p_chmask, c_chmask;
 
-   audio_dev = uac2_to_agdev(uac2);
opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst);
p_chmask = opts->p_chmask;
c_chmask = opts->c_chmask;
 
/* Choose any slot, with no id */
-   err = snd_card_new(>dev, -1, NULL, THIS_MODULE, 0, );
+   err = snd_card_new(_dev->gadget->dev,
+   -1, NULL, THIS_MODULE, 0, );
if (err < 0)
return err;
 
@@ -482,16 +470,15 @@ static int snd_uac2_probe(struct platform_device *pdev)
 
strcpy(card->driver, "UAC2_Gadget");
strcpy(card->shortname, "UAC2_Gadget");
-   sprintf(card->longname, "UAC2_Gadget %i", pdev->id);
+   sprintf(card->longname, "UAC2_Gadget %i", card->dev->id);
 
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);
 
err = snd_card_register(card);
-   if (!err) {
-   platform_set_drvdata(pdev, card);
+
+   if (!err)
return 0;
-   }
 
 snd_fail:
snd_card_free(card);
@@ -502,9 +489,9 @@ snd_fail:
return err;
 }
 
-static int snd_uac2_remove(struct platform_device *pdev)
+static int snd_uac2_remove(struct audio_dev *audio_dev)
 {
-   struct snd_card *card = platform_get_drvdata(pdev);
+   struct snd_card *card = audio_dev->uac2.card;
 
if (card)
return snd_card_free(card);
@@ -512,45 +499,6 @@ static int snd_uac2_remove(struct platform_device *pdev)
return 0;
 }
 
-static void snd_uac2_release(struct device *dev)
-{
-   dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
-}
-
-static int alsa_uac2_init(struct audio_dev *agdev)
-{
-   struct snd_uac2_chip *uac2 = >uac2;
-   int err;
-
-   uac2->pdrv.probe = snd_uac2_probe;
-   uac2->pdrv.remove = snd_uac2_remove;
-   uac2->pdrv.driver.name = uac2_name;
-
-   uac2->pdev.id = 0;
-   uac2->pdev.name = uac2_name;
-   uac2->pdev.dev.release = snd_uac2_release;
-
-   /* Register snd_uac2 driver */
-   err = platform_driver_register(>pdrv);
-   if (err)
-   return err;
-
-   

[RFC PATCH 5/5] usb: gadget: f_uac1: add capture support

2016-05-23 Thread Ruslan Bilovol
Add capture support (gadget->host) to the f_uac1
driver. This requires renaming of some descriptors,
enums etc that were used exclusively for playback
path. To make it meaningful, f_uac2 driver naming
convention has been used.

By default, capture interface has 48000kHz/2ch
configuration, same as playback channel has.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/Kconfig   |   7 +-
 drivers/usb/gadget/function/f_uac1.c | 265 ---
 drivers/usb/gadget/function/u_uac1.h |   6 +
 drivers/usb/gadget/legacy/audio.c|  18 +++
 4 files changed, 239 insertions(+), 57 deletions(-)

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index fd6ee1d..ffe611a 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -395,10 +395,11 @@ config USB_CONFIGFS_F_UAC1
  This Audio function implements 1 AudioControl interface,
  1 AudioStreaming Interface each for USB-OUT and USB-IN.
  This driver doesn't expect any real Audio codec to be present
- on the device - the audio streams are simply sinked to
- a virtual ALSA sound card created. The user-space
+ on the device - the audio streams are simply sinked to and
+ sourced from a virtual ALSA sound card created. The user-space
  application may choose to do whatever it wants with the data
- received from the USB Host.
+ received from the USB Host and choose to provide whatever it
+ wants as audio data to the USB Host.
 
 config USB_CONFIGFS_F_UAC2
bool "Audio Class 2.0"
diff --git a/drivers/usb/gadget/function/f_uac1.c 
b/drivers/usb/gadget/function/f_uac1.c
index 120bba9..fcbf204 100644
--- a/drivers/usb/gadget/function/f_uac1.c
+++ b/drivers/usb/gadget/function/f_uac1.c
@@ -22,8 +22,8 @@
 
 struct f_uac1 {
struct gaudio gaudio;
-   u8 ac_intf, as_out_intf;
-   u8 ac_alt, as_out_alt;  /* needed for get_alt() */
+   u8 ac_intf, as_in_intf, as_out_intf;
+   u8 ac_alt, as_in_alt, as_out_alt;   /* needed for get_alt() */
 };
 
 static inline struct f_uac1 *func_to_uac1(struct usb_function *f)
@@ -37,12 +37,17 @@ static inline struct f_uac1 *func_to_uac1(struct 
usb_function *f)
  */
 
 /*
- * We have two interfaces- AudioControl and AudioStreaming
- * TODO: only supcard playback currently
+ * We have three interfaces- AudioControl and 2 AudioStreaming
+ *
+ * The driver implements a simple UAC_1 topology.
+ * USB-OUT -> IT_1 -> OT_2 -> ALSA_Capture
+ * ALSA_Playback -> IT_3 -> OT_4 -> USB-IN
  */
-#define F_AUDIO_AC_INTERFACE   0
-#define F_AUDIO_AS_INTERFACE   1
-#define F_AUDIO_NUM_INTERFACES 1
+#define F_AUDIO_AC_INTERFACE   0
+#define F_AUDIO_AS_OUT_INTERFACE   1
+#define F_AUDIO_AS_IN_INTERFACE2
+/* Number of streaming interfaces */
+#define F_AUDIO_NUM_INTERFACES 2
 
 /* B.3.1  Standard AC Interface Descriptor */
 static struct usb_interface_descriptor ac_interface_desc = {
@@ -57,14 +62,14 @@ static struct usb_interface_descriptor ac_interface_desc = {
  * The number of AudioStreaming and MIDIStreaming interfaces
  * in the Audio Interface Collection
  */
-DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
+DECLARE_UAC_AC_HEADER_DESCRIPTOR(2);
 
 #define UAC_DT_AC_HEADER_LENGTH
UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES)
-/* 1 input terminal and 1 output terminal */
-#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + 
UAC_DT_INPUT_TERMINAL_SIZE \
-   + UAC_DT_OUTPUT_TERMINAL_SIZE)
+/* 2 input terminals and 2 output terminals */
+#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH \
+   + 2*UAC_DT_INPUT_TERMINAL_SIZE + 2*UAC_DT_OUTPUT_TERMINAL_SIZE)
 /* B.3.2  Class-Specific AC Interface Descriptor */
-static struct uac1_ac_header_descriptor_1 ac_header_desc = {
+static struct uac1_ac_header_descriptor_2 ac_header_desc = {
.bLength =  UAC_DT_AC_HEADER_LENGTH,
.bDescriptorType =  USB_DT_CS_INTERFACE,
.bDescriptorSubtype =   UAC_HEADER,
@@ -72,35 +77,76 @@ static struct uac1_ac_header_descriptor_1 ac_header_desc = {
.wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH),
.bInCollection =F_AUDIO_NUM_INTERFACES,
.baInterfaceNr = {
-   /* Interface number of the first AudioStream interface */
+   /* Interface number of the AudioStream interfaces */
[0] =   1,
+   [1] =   2,
}
 };
 
-#define INPUT_TERMINAL_ID  1
-static struct uac_input_terminal_descriptor input_terminal_desc = {
+#define USB_OUT_IT_ID  1
+static struct uac_input_terminal_descriptor usb_out_it_desc = {
.bLength =  UAC_DT_INPUT_TERMINAL_SIZE,
.bDescriptorType =  USB_DT_CS_INTERFACE,
.bDescriptorSubtype =   UAC_INPUT_TERMINAL,
-   .bTerminalID =  INPUT_TERMINAL_ID,
+   .bTerminalID =  

[RFC PATCH 4/5] usb: gadget: f_uac1: switch to u_audio core utilities

2016-05-23 Thread Ruslan Bilovol
Reuse existing u_audio core utilities making f_uac1
much simpler.

This also drops previous f_uac1 approach (write audio
samples directly to existing ALSA sound card) and moves
to more generic/flexible one - create an f_uac1 ALSA
sound card that represents USB Audio function and
allows to be used by userspace tools.

As a side effect, using u_audio it will be much
easier to create gadget -> PC Host audio stream
in the future

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/usb/gadget/Kconfig   |   8 +-
 drivers/usb/gadget/function/Makefile |   2 +-
 drivers/usb/gadget/function/f_uac1.c | 431 +++
 drivers/usb/gadget/function/u_uac1.c | 314 -
 drivers/usb/gadget/function/u_uac1.h |  65 +-
 drivers/usb/gadget/legacy/Kconfig|   2 +-
 drivers/usb/gadget/legacy/audio.c|  42 ++--
 7 files changed, 162 insertions(+), 702 deletions(-)
 delete mode 100644 drivers/usb/gadget/function/u_uac1.c

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 42d8508..fd6ee1d 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -389,12 +389,16 @@ config USB_CONFIGFS_F_UAC1
depends on SND
select USB_LIBCOMPOSITE
select SND_PCM
+   select USB_U_AUDIO
select USB_F_UAC1
help
  This Audio function implements 1 AudioControl interface,
  1 AudioStreaming Interface each for USB-OUT and USB-IN.
- This driver requires a real Audio codec to be present
- on the device.
+ This driver doesn't expect any real Audio codec to be present
+ on the device - the audio streams are simply sinked to
+ a virtual ALSA sound card created. The user-space
+ application may choose to do whatever it wants with the data
+ received from the USB Host.
 
 config USB_CONFIGFS_F_UAC2
bool "Audio Class 2.0"
diff --git a/drivers/usb/gadget/function/Makefile 
b/drivers/usb/gadget/function/Makefile
index b29f2ae..bd9d7d5 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -33,7 +33,7 @@ obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
 usb_f_fs-y := f_fs.o
 obj-$(CONFIG_USB_F_FS) += usb_f_fs.o
 obj-$(CONFIG_USB_U_AUDIO)  += u_audio.o
-usb_f_uac1-y   := f_uac1.o u_uac1.o
+usb_f_uac1-y   := f_uac1.o
 obj-$(CONFIG_USB_F_UAC1)   += usb_f_uac1.o
 usb_f_uac2-y   := f_uac2.o
 obj-$(CONFIG_USB_F_UAC2)   += usb_f_uac2.o
diff --git a/drivers/usb/gadget/function/f_uac1.c 
b/drivers/usb/gadget/function/f_uac1.c
index ba498af..120bba9 100644
--- a/drivers/usb/gadget/function/f_uac1.c
+++ b/drivers/usb/gadget/function/f_uac1.c
@@ -4,6 +4,8 @@
  * Copyright (C) 2008 Bryan Wu <coolo...@kernel.org>
  * Copyright (C) 2008 Analog Devices, Inc
  *
+ * Copyright (C) 2016 Ruslan Bilovol <ruslan.bilo...@gmail.com>
+ *
  * Enter bugs at http://blackfin.uclinux.org/
  *
  * Licensed under the GPL-2 or later.
@@ -15,8 +17,20 @@
 #include 
 #include 
 
+#include "u_audio.h"
 #include "u_uac1.h"
 
+struct f_uac1 {
+   struct gaudio gaudio;
+   u8 ac_intf, as_out_intf;
+   u8 ac_alt, as_out_alt;  /* needed for get_alt() */
+};
+
+static inline struct f_uac1 *func_to_uac1(struct usb_function *f)
+{
+   return container_of(f, struct f_uac1, gaudio.func);
+}
+
 /*
  * DESCRIPTORS ... most are static, but strings and full
  * configuration descriptors are built on demand.
@@ -198,130 +212,6 @@ static struct usb_gadget_strings *uac1_strings[] = {
  * This function is an ALSA sound card following USB Audio Class Spec 1.0.
  */
 
-/*-*/
-struct f_audio_buf {
-   u8 *buf;
-   int actual;
-   struct list_head list;
-};
-
-static struct f_audio_buf *f_audio_buffer_alloc(int buf_size)
-{
-   struct f_audio_buf *copy_buf;
-
-   copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC);
-   if (!copy_buf)
-   return ERR_PTR(-ENOMEM);
-
-   copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC);
-   if (!copy_buf->buf) {
-   kfree(copy_buf);
-   return ERR_PTR(-ENOMEM);
-   }
-
-   return copy_buf;
-}
-
-static void f_audio_buffer_free(struct f_audio_buf *audio_buf)
-{
-   kfree(audio_buf->buf);
-   kfree(audio_buf);
-}
-/*-*/
-
-struct f_audio {
-   struct gaudio   card;
-
-   /* endpoints handle full and/or high speeds */
-   struct usb_ep   *out_ep;
-
-   spinlock_t  lock;
-   struct f_audio_buf *copy_buf;
-   struct work_struct playback_work;
-   struct list_head play_queue;
-};
-
-static inline struct f_audio *func_to_audio(struct usb_function *f)

Re: [PATCH v4] kconfig/symbol.c: handle choice_values that depend on 'm' symbols

2016-03-30 Thread Ruslan Bilovol
Hi,

On Thu, Mar 31, 2016 at 1:08 AM, Bin Liu <binml...@gmail.com> wrote:
> Hi,
>
> On Fri, Aug 15, 2014 at 2:37 AM, Dirk Gouders <d...@gouders.net> wrote:
>> Bin Liu <binml...@gmail.com> writes:
>>
>>> Dirk,
>>>
>>> On Thu, Aug 14, 2014 at 1:52 AM, Dirk Gouders <d...@gouders.net> wrote:
>>>> Bin Liu <binml...@gmail.com> writes:
>>>>
>>>>> All,
>>>>>
>>>>> On Mon, Nov 18, 2013 at 12:08 PM, Yann E. MORIN <yann.morin.1...@free.fr> 
>>>>> wrote:
>>>>>> Dirk, All,
>>>>>>
>>>>>> On 2013-11-07 15:05 +0100, Dirk Gouders spake thusly:
>>>>>>> If choices consist of choice_values that depend on symbols set to 'm',
>>>>>>> those choice_values are not set to 'n' if the choice is changed from
>>>>>>> 'm' to 'y' (in which case only one active choice_value is allowed).
>>>>>>> Those values are also written to the config file causing modules to be
>>>>>>> built when they should not.
>>>>>>>
>>>>>>> The following config can be used to reproduce and examine the problem;
>>>>>>> with the frontend of your choice set "Choice 0" and "Choice 1" to 'm',
>>>>>>> then set "Tristate Choice" to 'y' and save the configuration:
>>>>>>>
>>>>>>> config modules
>>>>>>>   boolean modules
>>>>>>>   default y
>>>>>>>   option modules
>>>>>>>
>>>>>>> config dependency
>>>>>>>   tristate "Dependency"
>>>>>>>   default m
>>>>>>>
>>>>>>> choice
>>>>>>>   prompt "Tristate Choice"
>>>>>>>   default choice0
>>>>>>>
>>>>>>> config choice0
>>>>>>>   tristate "Choice 0"
>>>>>>>
>>>>>>> config choice1
>>>>>>>   tristate "Choice 1"
>>>>>>>   depends on dependency
>>>>>>>
>>>>>>> endchoice
>>>>>>>
>>>>>>> This patch sets choice_values' visibility that depend on symbols set
>>>>>>> to 'm' to 'n' if the corresponding choice is set to 'y'.  This makes
>>>>>>> them disappear from the choice list and will also cause the
>>>>>>> choice_values' value set to 'n' in sym_calc_value() and as a result
>>>>>>> they are written as "not set" to the resulting .config file.
>>>>>>>
>>>>>>> Reported-by: Sebastian Andrzej Siewior <bige...@linutronix.de>
>>>>>>> Signed-off-by: Dirk Gouders <d...@gouders.net>
>>>>>>> Tested-by: Sebastian Andrzej Siewior <bige...@linutronix.de>
>>>>>>
>>>>>> Acked-by: "Yann E. MORIN" <yann.morin.1...@free.fr>
>>>>>>
>>>>>> It will be in my tree soon. Thanks!
>>>>>
>>>>> I don't see this patch in 3.16 but 3.16 does not have the issue any
>>>>> more. Anyone has an idea how the issue got fixed? I am trying to find
>>>>> the right patch to backport.
>>>>
>>>> With the above sample kconfig I still see the issue.  How did you
>>>> notice the issue got fixed?
>>>
>>> I did not pay much attention on the above sample kconfig, but just
>>> focused on the USB gadget driver kconfig issue initially reported by
>>> Sebastian. I saw the issue exists in 3.14, but does not in 3.16,
>>> unless I messed up with my test. I will test 3.16 again some time next
>>> week.
>>
>> Hi Bin,
>>
>> I now also re-tested the initially reported steps to reproduce the
>> issue:
>>
>> 
>>> in USB gadget menu (that is Device Drivers ---> USB support ---> USB
>>> Gadget Support --->  USB Gadget Drivers) I can create a configuration
>>> which is "lost". Here is how to reproduce it:
>>>
>>> - first config two gadgets as M:
>>> USB Gadget Drivers
>>>   Audio Gadget
>>>   Ethernet Gadget
>>>   MIDI Gadget
>>>
>>>  save config & leave
>>>
>>> - now start menu config again and go to the same menu, now select
>>>   built-in:
>>>   <*>   USB Gadget Drivers (Ethernet Gadget
>>>   the ethernet gadget is chosen automatically because we can have only
>>>   one gadget selected.
>>>   save config & leave
>>>
>>> - step three, go back to the menu and you will see that everything is
>>>   as it was (the <*> is ignored).
>> 
>>
>> Here, I still see the problem (I was wondering if the issue has been
>> solved/gone by a kconfig-file modification).
>
> This issue was gone since 3.16, but came back again due to commit
> 1fd6d08 ARM: omap2plus_defconfig: Enable n900 modem as loadable modules.
>

I can confirm this issue too, faced it on v4.5 (but didn't try v4.6-rc1 yet)

-- 
Best regards,
Ruslan Bilovol
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] phy: twl4030-usb: fix musb-hdrc name for non-dt case

2016-03-24 Thread Ruslan Bilovol
musb device is allocated with PLATFORM_DEVID_AUTO, fix
incorrect lookup name in non-dt case.
This fixes issue with musb initialization on Nokia N900
in boardfile boot mode.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 drivers/phy/phy-twl4030-usb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 840f3ea..a48214f 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -735,7 +735,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
}
 
if (pdata)
-   err = phy_create_lookup(phy, "usb", "musb-hdrc.0");
+   err = phy_create_lookup(phy, "usb", "musb-hdrc.0.auto");
if (err)
return err;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 1/3] USB: add descriptors from USB Power Delivery spec

2016-03-10 Thread Ruslan Bilovol
On Thu, Mar 10, 2016 at 3:59 PM, Oliver Neukum  wrote:
> Adding the descriptors of chapter 9.2 of the Power Delivery spec.
>
> Signed-off-by: Oliver Neukum 
> ---
>  include/uapi/linux/usb/ch9.h | 98 
> 
>  1 file changed, 98 insertions(+)
>
> diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
> index 06d6c62..1046c55 100644
> --- a/include/uapi/linux/usb/ch9.h
> +++ b/include/uapi/linux/usb/ch9.h
> @@ -914,6 +914,104 @@ struct usb_ssp_cap_descriptor {
>  } __attribute__((packed));
>
>  /*
> + * USB Power Delivery Capability Descriptor:
> + * Defines capabilities for PD
> + */
> +/* Defines the various PD Capabilities of this device */
> +#define USB_PD_POWER_DELIVERY_CAPABILITY   0x06
> +/* Provides information on each battery supported by the device */
> +#define USB_PD_BATTERY_INFO_CAPABILITY 0x07
> +/* The Consumer characteristics of a Port on the device */
> +#define USB_PD_PD_CONSUMER_PORT_CAPABILITY 0x08
> +/* The provider characteristics of a Port on the device */
> +#define USB_PD_PD_PROVIDER_PORT_CAPABILITY 0x09
> +
> +struct usb_pd_cap_descriptor {
> +   __u8  bLength;
> +   __u8  bDescriptorType;
> +   __u8  bDevCapabilityType; /* set to USB_PD_POWER_DELIVERY_CAPABILITY 
> */
> +   __u8  bReserved;
> +   __le32 bmAttributes;
> +#define USB_PD_CAP_BATTERY_CHARGING(1 << 1) /* supports Battery Charging 
> specification */
> +#define USB_PD_CAP_USB_PD  (1 << 2) /* supports USB Power 
> Delivery specification */
> +#define USB_PD_CAP_PROVIDER(1 << 3) /* can provide power */
> +#define USB_PD_CAP_CONSUMER(1 << 4) /* can consume power */
> +#define USB_PD_CAP_CHARGING_POLICY (1 << 5) /* supports CHARGING_POLICY 
> feature */
> +#define USB_PD_CAP_TYPE_C_CURRENT  (1 << 6) /* supports power 
> capabilities defined in the USB Type-C Specification */
> +
> +#define USB_PD_CAP_PWR_AC  (1 << 8)
> +#define USB_PD_CAP_PWR_BAT (1 << 9)
> +#define USB_PD_CAP_PWR_USE_V_BUS   (1 << 14)

Thank you for fixing uSB_xxx here

> +
> +   __le16 bmProviderPorts; /* Bit zero refers to the UFP of the device */
> +   __le16 bmConsumerPorts;
> +   __le16 bcdBCVersion;
> +   __le16 bcdPDVersion;
> +   __le16 bcdUSBTypeCVersion;
> +} __attribute__((packed));
> +
> +struct usb_pd_cap_battery_info_descriptor {
> +   __u8 bLength;
> +   __u8 bDescriptorType;
> +   __u8 bDevCapabilityType;
> +   /* Index of string descriptor shall contain the user friendly name 
> for this battery */
> +   __u8 iBattery;
> +   /* Index of string descriptor shall contain the Serial Number String 
> for this battery */
> +   __u8 iSerial;
> +   __u8 iManufacturer;
> +   __u8 bBatteryId; /* uniquely identifies this battery in status 
> Messages */
> +   __u8 bReserved;
> +   /*
> +* Shall contain the Battery Charge value above which this
> +* battery is considered to be fully charged but not necessarily
> +* “topped off.”
> +*/
> +   __le32 dwChargedThreshold; /* in mWh */
> +   /*
> +* Shall contain the minimum charge level of this battery such
> +* that above this threshold, a device can be assured of being
> +* able to power up successfully (see Battery Charging 1.2).
> +*/
> +   __le32 dwWeakThreshold; /* in mWh */
> +   __le32 dwBatteryDesignCapacity; /* in mWh */
> +   __le32 dwBatteryLastFullchargeCapacity; /* in mWh */
> +} __attribute__((packed));
> +
> +struct usb_pd_cap_consumer_port_descriptor {
> +   __u8 bLength;
> +   __u8 bDescriptorType;
> +   __u8 bDevCapabilityType;
> +   __u8 bReserved;
> +   __u8 bmCapabilities;
> +/* port will oerate under: */
> +#define uSB_PD_CAP_CONSUMER_BC (1 << 0) /* BC */
> +#define uSB_PD_CAP_CONSUMER_PD (1 << 1) /* PD */
> +#define uSB_PD_CAP_CONSUMER_TYPE_C (1 << 2) /* USB Type-C Current */

However, this typo still exists here ^

> +   __le16 wMinVoltage; /* in 50mV units */
> +   __le16 wMaxVoltage; /* in 50mV units */
> +   __u16 wReserved;
> +   __le32 dwMaxOperatingPower; /* in 10 mW - operating at steady state */
> +   __le32 dwMaxPeakPower; /* in 10mW units - operating at peak power */
> +   __le32 dwMaxPeakPowerTime; /* in 100ms units - duration of peak */
> +#define uSB_PD_CAP_CONSUMER_UNKNOWN_PEAK_POWER_TIME 0x

and here ^

> +} __attribute__((packed));
> +
> +struct usb_pd_cap_provider_port_descriptor {
> +   __u8 bLength;
> +   __u8 bDescriptorType;
> +   __u8 bDevCapabilityType;
> +   __u8 bReserved1;
> +   __u8 bmCapabilities;
> +/* port will oerate under: */
> +#define uSB_PD_CAP_PROVIDER_BC (1 << 0) /* BC */
> +#define uSB_PD_CAP_PROVIDER_PD (1 << 1) /* PD */
> +#define uSB_PD_CAP_PROVIDER_TYPE_C (1 << 2) /* USB Type-C 

Re: [RFC Patch 1/3] USB: add descriptors from USB Power Delivery spec

2016-03-10 Thread Ruslan Bilovol
Hi,

On Thu, Mar 10, 2016 at 12:45 PM, Felipe Balbi
 wrote:
>
> Hi,
>
> Oliver Neukum  writes:
>> [ text/plain ]
>> Adding the descriptors of chapter 9.2 of the Power Delivery spec.
>>
>> Signed-off-by: Oliver Neukum 
>> ---
>>  include/uapi/linux/usb/ch9.h | 94 
>> 
>>  1 file changed, 94 insertions(+)
>>
>> diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
>> index 252ac16..c9f2bc2 100644
>> --- a/include/uapi/linux/usb/ch9.h
>> +++ b/include/uapi/linux/usb/ch9.h
>> @@ -913,6 +913,100 @@ struct usb_ssp_cap_descriptor {
>>  } __attribute__((packed));
>>
>>  /*
>> + * USB Power Delivery Capability Descriptor:
>> + * Defines capabilities for PD
>> + */
>> +#define USB_PD_POWER_DELIVERY_CAPABILITY (0x06)  /* Defines the various 
>> PD Capabilities of this device */
>> +#define USB_PD_BATTERY_INFO_CAPABILITY   (0x07)  /* Provides 
>> information on each battery supported by the device */
>> +#define USB_PD_PD_CONSUMER_PORT_CAPABILITY   (0x08)  /* The Consumer 
>> characteristics of a Port on the device */
>> +#define USB_PD_PD_PROVIDER_PORT_CAPABILITY   (0x09)  /* The provider 
>> characteristics of a Port on the device */
>
> any chance you can avoid the extra long lines ?
>
>> +struct usb_pd_cap_descriptor {
>> + __u8  bLength;
>> + __u8  bDescriptorType;
>> + __u8  bDevCapabilityType; /* set to USB_PD_POWER_DELIVERY_CAPABILITY */
>> + __u8  bReserved;
>> + __le32 bmAttributes;
>> +#define uSB_PD_CAP_BATTERY_CHARGING  ( 1 << 1 ) /* supports Battery 
>> Charging specification */
>> +#define uSB_PD_CAP_USB_PD( 1 << 2 ) /* supports USB Power 
>> Delivery specification */
>> +#define uSB_PD_CAP_PROVIDER  ( 1 << 3 ) /* can provide power */
>> +#define uSB_PD_CAP_CONSUMER  ( 1 << 4 ) /* can consume power */
>> +#define uSB_PD_CAP_CHARGING_POLICY   ( 1 << 5 ) /* supports CHARGING_POLICY 
>> feature */
>> +#define uSB_PD_CAP_TYPE_C_CURRENT( 1 << 6 ) /* supports power 
>> capabilities defined in the USB Type-C Specification */
>> +
>> +#define uSB_PD_CAP_PWR_AC( 1 << 8 )
>> +#define uSB_PD_CAP_PWR_BAT   ( 1 << 9 )
>> +#define uSB_PD_CAP_PWR_USE_V_BUS ( 1 << 14 )
>
> why the extra spaces inside () ?

Also it's not clear why these macro start with lowercase letter (e.g.
why uSB_XXX instead of USB_XXX), looks like a typo.

>
> --
> balbi

-- 
Best regards,
Ruslan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: gadgetfs regression (NULL ptr deref) since v4.4-rc7

2016-02-08 Thread Ruslan Bilovol
Hi Vegard,

On Mon, Feb 8, 2016 at 1:27 AM, Vegard Nossum <vegard.nos...@oracle.com> wrote:
> Hi,
>
> Using gadgetfs on latest mainline, I get the following NULL pointer
> dereference:
>
> BUG: unable to handle kernel NULL pointer dereference at   (null)
> IP: [] __list_del_entry+0x29/0xc0
> PGD 34f067 PUD 355067 PMD 0
> Oops:  [#1] DEBUG_PAGEALLOC
> CPU: 0 PID: 35 Comm: afl-fuzz Not tainted 4.5.0-rc2 #1
> task: 882b1ec0 ti: 8833c000 task.ti: 8833c000
> RIP: 0010:[]  []
> __list_del_entry+0x29/0xc0
> RSP: 0018:8833fe30  EFLAGS: 00010207
> RAX:  RBX: 8138c108 RCX: dead0200
> RDX:  RSI: 0061 RDI: 8138c108
> RBP: 8833fe30 R08:  R09: 
> R10:  R11: 0246 R12: 8138b928
> R13: 8138c040 R14: 88000ec0da20 R15: 8833ff58
> FS:  77ff2740() GS:8135d000() knlGS:
> CS:  0010 DS:  ES:  CR0: 80050033
> CR2:  CR3: 00335000 CR4: 001406b0
> Stack:
>  8833fe48 81138f2d 8138bbd0 8833fe70
>  811c880b 882f3000 88000ec109a0 88298aa0
>  8833fe88 811ce040 8834cdc0 8833feb8
> Call Trace:
>  [] list_del+0xd/0x30
>  [] usb_gadget_unregister_driver+0xdb/0xf0
>  [] dev_release+0x20/0x60
>  [] __fput+0x4c/0x130
>  [] fput+0x9/0x10
>  [] task_work_run+0x67/0xa0
>  [] exit_to_usermode_loop+0x8f/0xa0
>  [] syscall_return_slowpath+0x3d/0x40
>  [] int_ret_from_sys_call+0x25/0x8f
> Code: ff ff 55 48 8b 07 48 b9 00 01 00 00 00 00 ad de 48 8b 57 08 48 89 e5
> 48 39 c8 74 29 48 b9 00 02 00 00 00 00 ad de 48 39 ca 74 3a <4c> 8b 02 4c 39
> c7 75 52 4c 8b 40 08 4c 39 c7 75 66 48 89 50 08
> RIP  [] __list_del_entry+0x29/0xc0
>  RSP 
> CR2: 
> ---[ end trace e6cfe1de661dcffe ]---
>
> Reverting this commit fixes the problem for me:
>
> commit 855ed04a3758b205e84b269f92d26ab36ed8e2f7
> Author: Ruslan Bilovol <ruslan.bilo...@gmail.com>
> Date:   Mon Nov 23 09:56:38 2015 +0100
>
> usb: gadget: udc-core: independent registration of gadgets and gadget
> drivers
>
> Though I am still seeing some occasional lockups. Thanks,
>

Original version of this patch had checking of input parameters
(see change in usb_gadget_unregister_driver at
https://lkml.org/lkml/2015/6/22/559) but this approach was
rejected by Alan Stern many times so final version pushed by
Marek Szyprowski doesn't have it, and we have this NULL pointer
dereference.
But this means there is a bug in GadgetFS that was hidden
previously: it tries to deregister gadget driver that was not previously
registered. Previous implementation was returning -ENODEV
retval, current one just does NULL pointer dereference.

At least need to fix GadgetFS that seems to by buggy in
gadget driver unregistering, and I still say we need to nave
input parameters checking in externally visible functions like
usb_gadget_unregister_driver().

Meanwhile you can try following patch that returns checking of input
parameters back and see if it helps.

Best regards,
Ruslan



diff --git a/drivers/usb/gadget/udc/udc-core.c
b/drivers/usb/gadget/udc/udc-core.c
index fd73a3e..f1d375f 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -597,9 +597,16 @@ int usb_gadget_unregister_driver(struct
usb_gadget_driver *driver)
}

if (ret) {
-   list_del(>pending);
-   ret = 0;
+   struct usb_gadget_driver *tmp;
+
+   list_for_each_entry(tmp, _driver_pending_list, pending)
+   if (tmp == driver) {
+   list_del(>pending);
+   ret = 0;
+   break;
+   }
}
+
mutex_unlock(_lock);
return ret;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7 0/4] usb/gadget: independent registration of gadgets and gadget drivers

2015-11-26 Thread Ruslan Bilovol
Hi Marek,

On Mon, Nov 23, 2015 at 10:56 AM, Marek Szyprowski
<m.szyprow...@samsung.com> wrote:
> Hello,
>
> This is a resurrection of the patches initially submitted by Ruslan
> Bilovol in the following thread: https://lkml.org/lkml/2015/6/22/554
>
> The changes since the original submission (v5) includes rebase onto
> latest linux-next branch, simplification of the code requested by Alan
> Stern and Felipe Balbi, removal of a patch, which deleted __init/__exit
> attributes (this change has been already merged) and fixes of the
> checkpatch issues.

Thank you for handling it as I'm still to busy for continuing on this feature.

Best regards,
Ruslan

>
> This feature is urgently needed, because it is not longer possible to
> use workaround to avoid deferred probe in UDC drivers due to
> not-yet-probed i2c regulator drivers (for more information see
> https://lkml.org/lkml/2015/10/30/374 ).
>
> This patchset has been successfully tested on Odroid XU3 boards with
> DWC3 UDC driver being deferred by missing regulator drivers.
>
> Best regards
> Marek Szyprowski
> Samsung R Institute Poland
>
>
> Patch summary:
>
> Ruslan Bilovol (4):
>   usb: gadget: bind UDC by name passed via usb_gadget_driver structure
>   usb: gadget: configfs: pass UDC name via usb_gadget_driver struct
>   usb: gadget: udc-core: remove unused usb_udc_attach_driver()
>   usb: gadget: udc-core: independent registration of gadgets and gadget
> drivers
>
>  drivers/usb/gadget/configfs.c | 29 +++---
>  drivers/usb/gadget/udc/udc-core.c | 79 
> ++-
>  include/linux/usb/gadget.h|  8 +++-
>  3 files changed, 67 insertions(+), 49 deletions(-)
>
> --
> 1.9.2
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 0/5] usb/gadget: independent registration of gadgets and gadget drivers

2015-11-02 Thread Ruslan Bilovol
Hi Maxime,

On Mon, Oct 19, 2015 at 11:11 AM, Maxime Ripard
<maxime.rip...@free-electrons.com> wrote:
> Hi,
>
> On Tue, Jun 23, 2015 at 01:01:09AM +0300, Ruslan Bilovol wrote:
>> This patchset adds independent registration of gadgets
>> and gadget drivers to udc-core. This is very useful for
>> built-in modules into kernel case since it's possible
>> situation that gadget driver is probing at a time
>> when no gadgets are registered in udc-core.
>> In this case instead of silently failing without
>> of any attempt to recover, with independent registration
>> of gadgets and gadget drivers there is no matter
>> in which order gadgets and gadget drivers are
>> probed/registered.
>>
>> This patch has side-effect on gadget drivers that had
>> __init/__exit attributes on some paths like bind/unbind
>> and (since bind/unbind may happen at any time) should
>> not use them now. This is covered by forth patch
>>
>
> Has there been any progress on these patches? They're fixing some real
> issue that we're seeing, and it seems to both work quite well and not
> generate a lot of pushback.

This patch series has stack on review due to different views
on checking input parameters of externally visible function.

I see there is no any way to get these patches accepted other
than skip checking validity of some input parameters as
was pointed by Alan, although I disagree with it.

I will post updated patch series later

Best regards,
Ruslan


>
> Thanks!
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 2/5] usb: gadget: configfs: pass UDC name via usb_gadget_driver struct

2015-06-27 Thread Ruslan Bilovol
Hi Krzysztof,

On Tue, Jun 23, 2015 at 9:54 AM, Krzysztof Opasiak
k.opas...@samsung.com wrote:
 Hello,

 On 06/23/2015 12:01 AM, Ruslan Bilovol wrote:

 Now when udc-core supports binding to specific UDC by passing
 its name via 'udc_name' member of usb_gadget_driver struct,
 switch to this generic approach.

 Tested-by: Maxime Ripard maxime.rip...@free-electrons.com
 Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
 ---
   drivers/usb/gadget/configfs.c | 27 ++-
   1 file changed, 14 insertions(+), 13 deletions(-)

 diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
 index c42765b..efad021 100644
 --- a/drivers/usb/gadget/configfs.c
 +++ b/drivers/usb/gadget/configfs.c
 @@ -54,7 +54,6 @@ struct gadget_info {
 struct list_head string_list;
 struct list_head available_func;

 -   const char *udc_name;
   #ifdef CONFIG_USB_OTG
 struct usb_otg_descriptor otg;
   #endif
 @@ -230,21 +229,21 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct
 gadget_info *gi,

   static ssize_t gadget_dev_desc_UDC_show(struct gadget_info *gi, char
 *page)
   {
 -   return sprintf(page, %s\n, gi-udc_name ?: );
 +   return sprintf(page, %s\n, gi-composite.gadget_driver.udc_name
 ?: );
   }

   static int unregister_gadget(struct gadget_info *gi)
   {
 int ret;

 -   if (!gi-udc_name)
 +   if (!gi-composite.gadget_driver.udc_name)
 return -ENODEV;

 ret = usb_gadget_unregister_driver(gi-composite.gadget_driver);
 if (ret)
 return ret;
 -   kfree(gi-udc_name);
 -   gi-udc_name = NULL;
 +   kfree(gi-composite.gadget_driver.udc_name);
 +   gi-composite.gadget_driver.udc_name = NULL;
 return 0;
   }

 @@ -267,14 +266,16 @@ static ssize_t gadget_dev_desc_UDC_store(struct
 gadget_info *gi,
 if (ret)
 goto err;
 } else {
 -   if (gi-udc_name) {
 +   if (gi-composite.gadget_driver.udc_name) {


 You are using this very long if condition in a few places, maybe it would be
 more suitable to define a macro or inline function for this? Something like
 gadget_dev_bound() or gadget_dev_is_active() or some other more suitable
 name.

Yes, it makes sense, since there are 11 places where this long access
to udc_name is used.
However, it is used not only in if conditions but also for changing
udc_name, so need to add some getters/setters, something like
#define gi_to_udc_name(gi)
((gi)-composite.gadget_driver.udc_name)
#define gi_set_udc_name(gi,name)
((gi)-composite.gadget_driver.udc_name = (name))

Best regards,
Ruslan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 5/5] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-06-27 Thread Ruslan Bilovol
Hi Alan,

On Tue, Jun 23, 2015 at 5:08 PM, Alan Stern st...@rowland.harvard.edu wrote:
 On Tue, 23 Jun 2015, Ruslan Bilovol wrote:

 Change behavior during registration of gadgets and
 gadget drivers in udc-core. Instead of previous
 approach when for successful probe of usb gadget driver
 at least one usb gadget should be already registered
 use another one where gadget drivers and gadgets
 can be registered in udc-core independently.

 Independent registration of gadgets and gadget drivers
 is useful for built-in into kernel gadget and gadget
 driver case - because it's possible that gadget is
 really probed only on late_init stage (due to deferred
 probe) whereas gadget driver's probe is silently failed
 on module_init stage due to no any UDC added.

 Also it is useful for modules case - now there is no
 difference what module to insert first: gadget module
 or gadget driver one.

 Tested-by: Maxime Ripard maxime.rip...@free-electrons.com
 Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com

 @@ -484,6 +507,16 @@ int usb_gadget_unregister_driver(struct 
 usb_gadget_driver *driver)
   break;
   }

 + if (ret) {
 + struct usb_gadget_driver *tmp;
 +
 + list_for_each_entry(tmp, gadget_driver_pending_list, pending)
 + if (tmp == driver) {
 + list_del(driver-pending);
 + ret = 0;
 + break;
 + }
 + }

 Weren't you going to replace this loop with a simple list_del()?  IIRC,
 this is the third time I have asked you to make this change.

I understand the improvement that replacing this loop with a list_del()
may bring for us, but I disagree with doing it in this particular case.

The reason is simple. The usb_gadget_unregister_driver() funciton is
externally visible so we can get junk as input. Current implementation
checks passed pointer and only after that does list_del(), or
returns -EINVAL. Your variant will do list_del() unconditionally, that
may cause a kernel crash or unexpected behavior in case of junk
passed with *driver. The list_del_init() usage can't help here since
there is no way to check that list_head structure is initialized with correct
data or contains junk.

There is no noticeable performance loss with current implementation,just
because current use case is pretty simple: one gadget driver per one UDC,
and usually there is only one UDC per machine (or rare cases with few
UDCs), thus number of pending gadget drivers is relatively small.
We can return back to this discussion if someone needs to register
many gadget drivers, and want to improve performance, because
there are few existing places (not created by me) in this file that uses
same approach of walking through list of registered gadget drivers.

As a bottom line, choosing between stability and little performance
improvement, I prefer stability.

Best regards,
Ruslan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 4/5] usb: gadget: legacy: don't use __init/__exit attributes for bind/unbind path

2015-06-22 Thread Ruslan Bilovol
In order to prepare to independent gadgets and
gadget drivers registration in udc-core, some of the
functions can't have __init/__exit attributes (almost
only bind/unbind callbacks are affected)

Tested-by: Maxime Ripard maxime.rip...@free-electrons.com
Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/legacy/acm_ms.c   |  6 +++---
 drivers/usb/gadget/legacy/audio.c|  6 +++---
 drivers/usb/gadget/legacy/cdc2.c |  6 +++---
 drivers/usb/gadget/legacy/dbgp.c |  2 +-
 drivers/usb/gadget/legacy/ether.c|  8 
 drivers/usb/gadget/legacy/gmidi.c|  6 +++---
 drivers/usb/gadget/legacy/hid.c  |  6 +++---
 drivers/usb/gadget/legacy/mass_storage.c |  4 ++--
 drivers/usb/gadget/legacy/multi.c| 16 
 drivers/usb/gadget/legacy/ncm.c  |  6 +++---
 drivers/usb/gadget/legacy/nokia.c|  6 +++---
 drivers/usb/gadget/legacy/printer.c  |  6 +++---
 drivers/usb/gadget/legacy/serial.c   |  2 +-
 drivers/usb/gadget/legacy/webcam.c   |  4 ++--
 drivers/usb/gadget/legacy/zero.c |  2 +-
 15 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/usb/gadget/legacy/acm_ms.c 
b/drivers/usb/gadget/legacy/acm_ms.c
index c30b7b5..3a48aab 100644
--- a/drivers/usb/gadget/legacy/acm_ms.c
+++ b/drivers/usb/gadget/legacy/acm_ms.c
@@ -121,7 +121,7 @@ static struct usb_function *f_msg;
 /*
  * We _always_ have both ACM and mass storage functions.
  */
-static int __init acm_ms_do_config(struct usb_configuration *c)
+static int acm_ms_do_config(struct usb_configuration *c)
 {
struct fsg_opts *opts;
int status;
@@ -174,7 +174,7 @@ static struct usb_configuration acm_ms_config_driver = {
 
 /*-*/
 
-static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+static int acm_ms_bind(struct usb_composite_dev *cdev)
 {
struct usb_gadget   *gadget = cdev-gadget;
struct fsg_opts *opts;
@@ -249,7 +249,7 @@ fail_get_msg:
return status;
 }
 
-static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
+static int acm_ms_unbind(struct usb_composite_dev *cdev)
 {
usb_put_function(f_msg);
usb_put_function_instance(fi_msg);
diff --git a/drivers/usb/gadget/legacy/audio.c 
b/drivers/usb/gadget/legacy/audio.c
index f46a395..ba95518 100644
--- a/drivers/usb/gadget/legacy/audio.c
+++ b/drivers/usb/gadget/legacy/audio.c
@@ -167,7 +167,7 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 /*-*/
 
-static int __init audio_do_config(struct usb_configuration *c)
+static int audio_do_config(struct usb_configuration *c)
 {
int status;
 
@@ -216,7 +216,7 @@ static struct usb_configuration audio_config_driver = {
 
 /*-*/
 
-static int __init audio_bind(struct usb_composite_dev *cdev)
+static int audio_bind(struct usb_composite_dev *cdev)
 {
 #ifndef CONFIG_GADGET_UAC1
struct f_uac2_opts  *uac2_opts;
@@ -276,7 +276,7 @@ fail:
return status;
 }
 
-static int __exit audio_unbind(struct usb_composite_dev *cdev)
+static int audio_unbind(struct usb_composite_dev *cdev)
 {
 #ifdef CONFIG_GADGET_UAC1
if (!IS_ERR_OR_NULL(f_uac1))
diff --git a/drivers/usb/gadget/legacy/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c
index 2e85d94..8d1985c 100644
--- a/drivers/usb/gadget/legacy/cdc2.c
+++ b/drivers/usb/gadget/legacy/cdc2.c
@@ -104,7 +104,7 @@ static struct usb_function_instance *fi_ecm;
 /*
  * We _always_ have both CDC ECM and CDC ACM functions.
  */
-static int __init cdc_do_config(struct usb_configuration *c)
+static int cdc_do_config(struct usb_configuration *c)
 {
int status;
 
@@ -153,7 +153,7 @@ static struct usb_configuration cdc_config_driver = {
 
 /*-*/
 
-static int __init cdc_bind(struct usb_composite_dev *cdev)
+static int cdc_bind(struct usb_composite_dev *cdev)
 {
struct usb_gadget   *gadget = cdev-gadget;
struct f_ecm_opts   *ecm_opts;
@@ -211,7 +211,7 @@ fail:
return status;
 }
 
-static int __exit cdc_unbind(struct usb_composite_dev *cdev)
+static int cdc_unbind(struct usb_composite_dev *cdev)
 {
usb_put_function(f_acm);
usb_put_function_instance(fi_serial);
diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c
index 633683a..7c42b01 100644
--- a/drivers/usb/gadget/legacy/dbgp.c
+++ b/drivers/usb/gadget/legacy/dbgp.c
@@ -284,7 +284,7 @@ fail_1:
return -ENODEV;
 }
 
-static int __init dbgp_bind(struct usb_gadget *gadget,
+static int dbgp_bind(struct usb_gadget *gadget,
struct usb_gadget_driver *driver)
 {
int err, stp;
diff --git a/drivers/usb/gadget/legacy/ether.c 
b/drivers/usb/gadget

[PATCH v5 5/5] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-06-22 Thread Ruslan Bilovol
Change behavior during registration of gadgets and
gadget drivers in udc-core. Instead of previous
approach when for successful probe of usb gadget driver
at least one usb gadget should be already registered
use another one where gadget drivers and gadgets
can be registered in udc-core independently.

Independent registration of gadgets and gadget drivers
is useful for built-in into kernel gadget and gadget
driver case - because it's possible that gadget is
really probed only on late_init stage (due to deferred
probe) whereas gadget driver's probe is silently failed
on module_init stage due to no any UDC added.

Also it is useful for modules case - now there is no
difference what module to insert first: gadget module
or gadget driver one.

Tested-by: Maxime Ripard maxime.rip...@free-electrons.com
Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 49 ---
 include/linux/usb/gadget.h|  2 ++
 2 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index 441877d..5a764ea 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -51,8 +51,12 @@ struct usb_udc {
 
 static struct class *udc_class;
 static LIST_HEAD(udc_list);
+static LIST_HEAD(gadget_driver_pending_list);
 static DEFINE_MUTEX(udc_lock);
 
+static int udc_bind_to_driver(struct usb_udc *udc,
+   struct usb_gadget_driver *driver);
+
 /* - */
 
 #ifdef CONFIG_HAS_DMA
@@ -264,6 +268,7 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
void (*release)(struct device *dev))
 {
struct usb_udc  *udc;
+   struct usb_gadget_driver *driver;
int ret = -ENOMEM;
 
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
@@ -311,6 +316,18 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc-vbus = true;
 
+   /* pick up one of pending gadget drivers */
+   list_for_each_entry(driver, gadget_driver_pending_list, pending) {
+   if (!driver-udc_name || strcmp(driver-udc_name,
+   dev_name(udc-dev)) == 0) {
+   ret = udc_bind_to_driver(udc, driver);
+   if (ret)
+   goto err4;
+   list_del(driver-pending);
+   break;
+   }
+   }
+
mutex_unlock(udc_lock);
 
return 0;
@@ -382,9 +399,16 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
list_del(udc-list);
mutex_unlock(udc_lock);
 
-   if (udc-driver)
+   if (udc-driver) {
+   struct usb_gadget_driver *driver = udc-driver;
+
usb_gadget_remove_driver(udc);
 
+   mutex_lock(udc_lock);
+   list_add(driver-pending, gadget_driver_pending_list);
+   mutex_unlock(udc_lock);
+   }
+
kobject_uevent(udc-dev.kobj, KOBJ_REMOVE);
flush_work(gadget-work);
device_unregister(udc-dev);
@@ -442,11 +466,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver 
*driver)
if (!ret)
break;
}
-   if (ret)
-   ret = -ENODEV;
-   else if (udc-driver)
-   ret = -EBUSY;
-   else
+   if (!ret  !udc-driver)
goto found;
} else {
list_for_each_entry(udc, udc_list, list) {
@@ -456,9 +476,12 @@ int usb_gadget_probe_driver(struct usb_gadget_driver 
*driver)
}
}
 
-   pr_debug(couldn't find an available UDC\n);
+   list_add_tail(driver-pending, gadget_driver_pending_list);
+   pr_info(udc-core: couldn't find an available UDC 
+   - added [%s] to list of pending drivers\n,
+   driver-function);
mutex_unlock(udc_lock);
-   return ret;
+   return 0;
 found:
ret = udc_bind_to_driver(udc, driver);
mutex_unlock(udc_lock);
@@ -484,6 +507,16 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver 
*driver)
break;
}
 
+   if (ret) {
+   struct usb_gadget_driver *tmp;
+
+   list_for_each_entry(tmp, gadget_driver_pending_list, pending)
+   if (tmp == driver) {
+   list_del(driver-pending);
+   ret = 0;
+   break;
+   }
+   }
mutex_unlock(udc_lock);
return ret;
 }
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 5482d13..9c6fe22

[PATCH v5 3/5] usb: gadget: udc-core: remove unused usb_udc_attach_driver()

2015-06-22 Thread Ruslan Bilovol
Now when last user of usb_udc_attach_driver() is switched
to passing UDC name via usb_gadget_driver struct, it's safe
to remove this function

Tested-by: Maxime Ripard maxime.rip...@free-electrons.com
Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 26 --
 include/linux/usb/gadget.h|  2 --
 2 files changed, 28 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index b431129..441877d 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -427,32 +427,6 @@ err1:
return ret;
 }
 
-int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver)
-{
-   struct usb_udc *udc = NULL;
-   int ret = -ENODEV;
-
-   mutex_lock(udc_lock);
-   list_for_each_entry(udc, udc_list, list) {
-   ret = strcmp(name, dev_name(udc-dev));
-   if (!ret)
-   break;
-   }
-   if (ret) {
-   ret = -ENODEV;
-   goto out;
-   }
-   if (udc-driver) {
-   ret = -EBUSY;
-   goto out;
-   }
-   ret = udc_bind_to_driver(udc, driver);
-out:
-   mutex_unlock(udc_lock);
-   return ret;
-}
-EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
-
 int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 {
struct usb_udc  *udc = NULL;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 8bba379..5482d13 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -933,8 +933,6 @@ extern int usb_add_gadget_udc_release(struct device *parent,
struct usb_gadget *gadget, void (*release)(struct device *dev));
 extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget 
*gadget);
 extern void usb_del_gadget_udc(struct usb_gadget *gadget);
-extern int usb_udc_attach_driver(const char *name,
-   struct usb_gadget_driver *driver);
 
 /*-*/
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in


[PATCH v5 2/5] usb: gadget: configfs: pass UDC name via usb_gadget_driver struct

2015-06-22 Thread Ruslan Bilovol
Now when udc-core supports binding to specific UDC by passing
its name via 'udc_name' member of usb_gadget_driver struct,
switch to this generic approach.

Tested-by: Maxime Ripard maxime.rip...@free-electrons.com
Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/configfs.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index c42765b..efad021 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -54,7 +54,6 @@ struct gadget_info {
struct list_head string_list;
struct list_head available_func;
 
-   const char *udc_name;
 #ifdef CONFIG_USB_OTG
struct usb_otg_descriptor otg;
 #endif
@@ -230,21 +229,21 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct 
gadget_info *gi,
 
 static ssize_t gadget_dev_desc_UDC_show(struct gadget_info *gi, char *page)
 {
-   return sprintf(page, %s\n, gi-udc_name ?: );
+   return sprintf(page, %s\n, gi-composite.gadget_driver.udc_name ?: 
);
 }
 
 static int unregister_gadget(struct gadget_info *gi)
 {
int ret;
 
-   if (!gi-udc_name)
+   if (!gi-composite.gadget_driver.udc_name)
return -ENODEV;
 
ret = usb_gadget_unregister_driver(gi-composite.gadget_driver);
if (ret)
return ret;
-   kfree(gi-udc_name);
-   gi-udc_name = NULL;
+   kfree(gi-composite.gadget_driver.udc_name);
+   gi-composite.gadget_driver.udc_name = NULL;
return 0;
 }
 
@@ -267,14 +266,16 @@ static ssize_t gadget_dev_desc_UDC_store(struct 
gadget_info *gi,
if (ret)
goto err;
} else {
-   if (gi-udc_name) {
+   if (gi-composite.gadget_driver.udc_name) {
ret = -EBUSY;
goto err;
}
-   ret = usb_udc_attach_driver(name, gi-composite.gadget_driver);
-   if (ret)
+   gi-composite.gadget_driver.udc_name = name;
+   ret = usb_gadget_probe_driver(gi-composite.gadget_driver);
+   if (ret) {
+   gi-composite.gadget_driver.udc_name = NULL;
goto err;
-   gi-udc_name = name;
+   }
}
mutex_unlock(gi-lock);
return len;
@@ -438,9 +439,9 @@ static int config_usb_cfg_unlink(
 * remove the function.
 */
mutex_lock(gi-lock);
-   if (gi-udc_name)
+   if (gi-composite.gadget_driver.udc_name)
unregister_gadget(gi);
-   WARN_ON(gi-udc_name);
+   WARN_ON(gi-composite.gadget_driver.udc_name);
 
list_for_each_entry(f, cfg-func_list, list) {
if (f-fi == fi) {
@@ -917,10 +918,10 @@ static int os_desc_unlink(struct config_item *os_desc_ci,
struct usb_composite_dev *cdev = gi-cdev;
 
mutex_lock(gi-lock);
-   if (gi-udc_name)
+   if (gi-composite.gadget_driver.udc_name)
unregister_gadget(gi);
cdev-os_desc_config = NULL;
-   WARN_ON(gi-udc_name);
+   WARN_ON(gi-composite.gadget_driver.udc_name);
mutex_unlock(gi-lock);
return 0;
 }
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in


[PATCH v5 0/5] usb/gadget: independent registration of gadgets and gadget drivers

2015-06-22 Thread Ruslan Bilovol
This patchset adds independent registration of gadgets
and gadget drivers to udc-core. This is very useful for
built-in modules into kernel case since it's possible
situation that gadget driver is probing at a time
when no gadgets are registered in udc-core.
In this case instead of silently failing without
of any attempt to recover, with independent registration
of gadgets and gadget drivers there is no matter
in which order gadgets and gadget drivers are
probed/registered.

This patch has side-effect on gadget drivers that had
__init/__exit attributes on some paths like bind/unbind
and (since bind/unbind may happen at any time) should
not use them now. This is covered by forth patch

=
v5:
 - this set of patches (that I already forgot about) has been
   successfully tested by Maxime Ripard, who sent me confirmation via
   personal email, so his Tested-by tag is added to the patches
 - rebased onto latest 'next' branch of Felipe Balbi's tree

v4:
 - misc fixes - addressed Alan's and Sergei's comments
 - rebased onto latest 'next' branch of Felipe Balbi's tree
 
v3:
 - addressed Alan's comments - now UDC name and pending
   gadget drivers list is a part of struct usb_gadget_driver.
 - removed usb_udc_attach_driver() function that became unused
   and not needed now

v2:
 - changed first patch to have only deferred probe part
   (because Gadget Bus seems to be better variant when
   some more complicated behavior will be required)
 - rebased to latest 'next' branch of Felipe Balbi's tree

Ruslan Bilovol (5):
  usb: gadget: bind UDC by name passed via usb_gadget_driver structure
  usb: gadget: configfs: pass UDC name via usb_gadget_driver struct
  usb: gadget: udc-core: remove unused usb_udc_attach_driver()
  usb: gadget: legacy: don't use __init/__exit attributes for
bind/unbind path
  usb: gadget: udc-core: independent registration of gadgets and gadget
drivers

 drivers/usb/gadget/configfs.c| 27 +-
 drivers/usb/gadget/legacy/acm_ms.c   |  6 +--
 drivers/usb/gadget/legacy/audio.c|  6 +--
 drivers/usb/gadget/legacy/cdc2.c |  6 +--
 drivers/usb/gadget/legacy/dbgp.c |  2 +-
 drivers/usb/gadget/legacy/ether.c|  8 +--
 drivers/usb/gadget/legacy/gmidi.c|  6 +--
 drivers/usb/gadget/legacy/hid.c  |  6 +--
 drivers/usb/gadget/legacy/mass_storage.c |  4 +-
 drivers/usb/gadget/legacy/multi.c| 16 +++---
 drivers/usb/gadget/legacy/ncm.c  |  6 +--
 drivers/usb/gadget/legacy/nokia.c|  6 +--
 drivers/usb/gadget/legacy/printer.c  |  6 +--
 drivers/usb/gadget/legacy/serial.c   |  2 +-
 drivers/usb/gadget/legacy/webcam.c   |  4 +-
 drivers/usb/gadget/legacy/zero.c |  2 +-
 drivers/usb/gadget/udc/udc-core.c| 87 
 include/linux/usb/gadget.h   |  8 ++-
 18 files changed, 117 insertions(+), 91 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in


[PATCH v5 1/5] usb: gadget: bind UDC by name passed via usb_gadget_driver structure

2015-06-22 Thread Ruslan Bilovol
Introduce new 'udc_name' member to usb_gadget_driver structure.
The 'udc_name' is a name of UDC that usb_gadget_driver should
be bound to. If udc_name is NULL, it will be bound to any
available UDC.

Tested-by: Maxime Ripard maxime.rip...@free-electrons.com
Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 24 +++-
 include/linux/usb/gadget.h|  4 
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index d69c355..b431129 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -456,21 +456,35 @@ EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
 int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 {
struct usb_udc  *udc = NULL;
-   int ret;
+   int ret = -ENODEV;
 
if (!driver || !driver-bind || !driver-setup)
return -EINVAL;
 
mutex_lock(udc_lock);
-   list_for_each_entry(udc, udc_list, list) {
-   /* For now we take the first one */
-   if (!udc-driver)
+   if (driver-udc_name) {
+   list_for_each_entry(udc, udc_list, list) {
+   ret = strcmp(driver-udc_name, dev_name(udc-dev));
+   if (!ret)
+   break;
+   }
+   if (ret)
+   ret = -ENODEV;
+   else if (udc-driver)
+   ret = -EBUSY;
+   else
goto found;
+   } else {
+   list_for_each_entry(udc, udc_list, list) {
+   /* For now we take the first one */
+   if (!udc-driver)
+   goto found;
+   }
}
 
pr_debug(couldn't find an available UDC\n);
mutex_unlock(udc_lock);
-   return -ENODEV;
+   return ret;
 found:
ret = udc_bind_to_driver(udc, driver);
mutex_unlock(udc_lock);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 4f3dfb7..8bba379 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -824,6 +824,8 @@ static inline int usb_gadget_disconnect(struct usb_gadget 
*gadget)
  * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
  * and should be called in_interrupt.
  * @driver: Driver model state for this driver.
+ * @udc_name: A name of UDC this driver should be bound to. If udc_name is 
NULL,
+ * this driver will be bound to any available UDC.
  *
  * Devices are disabled till a gadget driver successfully bind()s, which
  * means the driver will handle setup() requests needed to enumerate (and
@@ -884,6 +886,8 @@ struct usb_gadget_driver {
 
/* FIXME support safe rmmod */
struct device_driverdriver;
+
+   char*udc_name;
 };
 
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in


Re: [PATCH v4 5/5] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-03-15 Thread Ruslan Bilovol
HI Alan,

On Fri, Mar 13, 2015 at 4:39 PM, Alan Stern st...@rowland.harvard.edu wrote:
 On Thu, 12 Mar 2015, Ruslan Bilovol wrote:

 Change behavior during registration of gadgets and
 gadget drivers in udc-core. Instead of previous
 approach when for successful probe of usb gadget driver
 at least one usb gadget should be already registered
 use another one where gadget drivers and gadgets
 can be registered in udc-core independently.

 Independent registration of gadgets and gadget drivers
 is useful for built-in into kernel gadget and gadget
 driver case - because it's possible that gadget is
 really probed only on late_init stage (due to deferred
 probe) whereas gadget driver's probe is silently failed
 on module_init stage due to no any UDC added.

 Also it is useful for modules case - now there is no
 difference what module to insert first: gadget module
 or gadget driver one.


 @@ -366,9 +383,16 @@ found:
   list_del(udc-list);
   mutex_unlock(udc_lock);

 - if (udc-driver)
 + if (udc-driver) {
 + struct usb_gadget_driver *driver = udc-driver;
 +
   usb_gadget_remove_driver(udc);

 + mutex_lock(udc_lock);
 + list_add(driver-pending, gadget_driver_pending_list);
 + mutex_unlock(udc_lock);
 + }

 I'm not sure this is a good idea.  Gadget drivers probably don't expect
 to be bound again after they are unbound.

This already has been discussed some time ago:
https://lkml.org/lkml/2015/2/9/497
The bottom line was - such gadget drivers are buggy and need to be fixed
since there is no known restrictions in binding gadget drivers to UDC multiple
times


 Besides, when would this gadget driver get bound to a UDC?  Not until
 the next UDC is added -- even if there already are some unbound UDCs.

Currently this gadget driver will get bound to a UDC only when next UDC
is added. It seems there is no users of this feature, so I didn't
add full implementation of this (that I had in version #1 if this patch:
https://lkml.org/lkml/2015/1/28/1079 )



 @@ -468,6 +491,16 @@ int usb_gadget_unregister_driver(struct 
 usb_gadget_driver *driver)
   break;
   }

 + if (ret) {
 + struct usb_gadget_driver *tmp;
 +
 + list_for_each_entry(tmp, gadget_driver_pending_list, pending)
 + if (tmp == driver) {
 + list_del(driver-pending);
 + ret = 0;
 + break;
 + }
 + }

 You could avoid this loop and simply do list_del(driver-pending), if
 you made sure driver-pending was initialized.

It would be good to avoid this loop but the question is how to make sure
that driver-pending is not only initialized (prev and next are not NULL),
but also contains valid data?

Best regards,
Ruslan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 0/5] usb/gadget: independent registration of gadgets and gadget drivers

2015-03-12 Thread Ruslan Bilovol
This patchset adds independent registration of gadgets
and gadget drivers to udc-core. This is very useful for
built-in modules into kernel case since it's possible
situation that gadget driver is probing at a time
when no gadgets are registered in udc-core.
In this case instead of silently failing without
of any attempt to recover, with independent registration
of gadgets and gadget drivers there is no matter
in which order gadgets and gadget drivers are
probed/registered.

This patch has side-effect on gadget drivers that had
__init/__exit attributes on some paths like bind/unbind
and (since bind/unbind may happen at any time) should
not use them now. This is covered by forth patch

=
v4:
 - misc fixes - addressed Alan's and Sergei's comments
 - rebased onto latest 'next' branch of Felipe Balbi's tree
 
v3:
 - addressed Alan's comments - now UDC name and pending
   gadget drivers list is a part of struct usb_gadget_driver.
 - removed usb_udc_attach_driver() function that became unused
   and not needed now

v2:
 - changed first patch to have only deferred probe part
   (because Gadget Bus seems to be better variant when
   some more complicated behavior will be required)
 - rebased to latest 'next' branch of Felipe Balbi's tree


Ruslan Bilovol (5):
  usb: gadget: bind UDC by name passed via usb_gadget_driver structure
  usb: gadget: configfs: pass UDC name via usb_gadget_driver struct
  usb: gadget: udc-core: remove unused usb_udc_attach_driver()
  usb: gadget: legacy: don't use __init/__exit attributes for
bind/unbind path
  usb: gadget: udc-core: independent registration of gadgets and gadget
drivers

 drivers/usb/gadget/configfs.c| 27 +-
 drivers/usb/gadget/legacy/acm_ms.c   |  6 +--
 drivers/usb/gadget/legacy/audio.c|  6 +--
 drivers/usb/gadget/legacy/cdc2.c |  6 +--
 drivers/usb/gadget/legacy/dbgp.c |  2 +-
 drivers/usb/gadget/legacy/ether.c|  8 +--
 drivers/usb/gadget/legacy/gmidi.c|  6 +--
 drivers/usb/gadget/legacy/hid.c  |  6 +--
 drivers/usb/gadget/legacy/mass_storage.c |  4 +-
 drivers/usb/gadget/legacy/multi.c| 16 +++---
 drivers/usb/gadget/legacy/ncm.c  |  6 +--
 drivers/usb/gadget/legacy/nokia.c|  6 +--
 drivers/usb/gadget/legacy/printer.c  |  6 +--
 drivers/usb/gadget/legacy/serial.c   |  2 +-
 drivers/usb/gadget/legacy/webcam.c   |  4 +-
 drivers/usb/gadget/legacy/zero.c |  2 +-
 drivers/usb/gadget/udc/udc-core.c| 87 
 include/linux/usb/gadget.h   |  8 ++-
 18 files changed, 117 insertions(+), 91 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 3/5] usb: gadget: udc-core: remove unused usb_udc_attach_driver()

2015-03-12 Thread Ruslan Bilovol
Now when last user of usb_udc_attach_driver() is switched
to passing UDC name via usb_gadget_driver struct, it's safe
to remove this function

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 26 --
 include/linux/usb/gadget.h|  2 --
 2 files changed, 28 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index da738ee..3165d48 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -411,32 +411,6 @@ err1:
return ret;
 }
 
-int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver)
-{
-   struct usb_udc *udc = NULL;
-   int ret = -ENODEV;
-
-   mutex_lock(udc_lock);
-   list_for_each_entry(udc, udc_list, list) {
-   ret = strcmp(name, dev_name(udc-dev));
-   if (!ret)
-   break;
-   }
-   if (ret) {
-   ret = -ENODEV;
-   goto out;
-   }
-   if (udc-driver) {
-   ret = -EBUSY;
-   goto out;
-   }
-   ret = udc_bind_to_driver(udc, driver);
-out:
-   mutex_unlock(udc_lock);
-   return ret;
-}
-EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
-
 int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 {
struct usb_udc  *udc = NULL;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 6d26657..b584ed2 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -930,8 +930,6 @@ extern int usb_add_gadget_udc_release(struct device *parent,
struct usb_gadget *gadget, void (*release)(struct device *dev));
 extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget 
*gadget);
 extern void usb_del_gadget_udc(struct usb_gadget *gadget);
-extern int usb_udc_attach_driver(const char *name,
-   struct usb_gadget_driver *driver);
 
 /*-*/
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 5/5] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-03-12 Thread Ruslan Bilovol
Change behavior during registration of gadgets and
gadget drivers in udc-core. Instead of previous
approach when for successful probe of usb gadget driver
at least one usb gadget should be already registered
use another one where gadget drivers and gadgets
can be registered in udc-core independently.

Independent registration of gadgets and gadget drivers
is useful for built-in into kernel gadget and gadget
driver case - because it's possible that gadget is
really probed only on late_init stage (due to deferred
probe) whereas gadget driver's probe is silently failed
on module_init stage due to no any UDC added.

Also it is useful for modules case - now there is no
difference what module to insert first: gadget module
or gadget driver one.

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 49 ---
 include/linux/usb/gadget.h|  2 ++
 2 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index 3165d48..53571dd 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -48,8 +48,12 @@ struct usb_udc {
 
 static struct class *udc_class;
 static LIST_HEAD(udc_list);
+static LIST_HEAD(gadget_driver_pending_list);
 static DEFINE_MUTEX(udc_lock);
 
+static int udc_bind_to_driver(struct usb_udc *udc,
+   struct usb_gadget_driver *driver);
+
 /* - */
 
 #ifdef CONFIG_HAS_DMA
@@ -243,6 +247,7 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
void (*release)(struct device *dev))
 {
struct usb_udc  *udc;
+   struct usb_gadget_driver *driver;
int ret = -ENOMEM;
 
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
@@ -288,6 +293,18 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
 
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
 
+   /* pick up one of pending gadget drivers */
+   list_for_each_entry(driver, gadget_driver_pending_list, pending) {
+   if (!driver-udc_name || strcmp(driver-udc_name,
+   dev_name(udc-dev)) == 0) {
+   ret = udc_bind_to_driver(udc, driver);
+   if (ret)
+   goto err4;
+   list_del(driver-pending);
+   break;
+   }
+   }
+
mutex_unlock(udc_lock);
 
return 0;
@@ -366,9 +383,16 @@ found:
list_del(udc-list);
mutex_unlock(udc_lock);
 
-   if (udc-driver)
+   if (udc-driver) {
+   struct usb_gadget_driver *driver = udc-driver;
+
usb_gadget_remove_driver(udc);
 
+   mutex_lock(udc_lock);
+   list_add(driver-pending, gadget_driver_pending_list);
+   mutex_unlock(udc_lock);
+   }
+
kobject_uevent(udc-dev.kobj, KOBJ_REMOVE);
flush_work(gadget-work);
device_unregister(udc-dev);
@@ -426,11 +450,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver 
*driver)
if (!ret)
break;
}
-   if (ret)
-   ret = -ENODEV;
-   else if (udc-driver)
-   ret = -EBUSY;
-   else
+   if (!ret  !udc-driver)
goto found;
} else {
list_for_each_entry(udc, udc_list, list) {
@@ -440,9 +460,12 @@ int usb_gadget_probe_driver(struct usb_gadget_driver 
*driver)
}
}
 
-   pr_debug(couldn't find an available UDC\n);
+   list_add_tail(driver-pending, gadget_driver_pending_list);
+   pr_info(udc-core: couldn't find an available UDC 
+   - added [%s] to list of pending drivers\n,
+   driver-function);
mutex_unlock(udc_lock);
-   return ret;
+   return 0;
 found:
ret = udc_bind_to_driver(udc, driver);
mutex_unlock(udc_lock);
@@ -468,6 +491,16 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver 
*driver)
break;
}
 
+   if (ret) {
+   struct usb_gadget_driver *tmp;
+
+   list_for_each_entry(tmp, gadget_driver_pending_list, pending)
+   if (tmp == driver) {
+   list_del(driver-pending);
+   ret = 0;
+   break;
+   }
+   }
mutex_unlock(udc_lock);
return ret;
 }
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index b584ed2..ccf872f 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -823,6 +823,7 @@ static inline int

[PATCH v4 1/5] usb: gadget: bind UDC by name passed via usb_gadget_driver structure

2015-03-12 Thread Ruslan Bilovol
Introduce new 'udc_name' member to usb_gadget_driver structure.
The 'udc_name' is a name of UDC that usb_gadget_driver should
be bound to. If udc_name is NULL, it will be bound to any
available UDC.

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 24 +++-
 include/linux/usb/gadget.h|  4 
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index 5a81cb0..da738ee 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -440,21 +440,35 @@ EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
 int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 {
struct usb_udc  *udc = NULL;
-   int ret;
+   int ret = -ENODEV;
 
if (!driver || !driver-bind || !driver-setup)
return -EINVAL;
 
mutex_lock(udc_lock);
-   list_for_each_entry(udc, udc_list, list) {
-   /* For now we take the first one */
-   if (!udc-driver)
+   if (driver-udc_name) {
+   list_for_each_entry(udc, udc_list, list) {
+   ret = strcmp(driver-udc_name, dev_name(udc-dev));
+   if (!ret)
+   break;
+   }
+   if (ret)
+   ret = -ENODEV;
+   else if (udc-driver)
+   ret = -EBUSY;
+   else
goto found;
+   } else {
+   list_for_each_entry(udc, udc_list, list) {
+   /* For now we take the first one */
+   if (!udc-driver)
+   goto found;
+   }
}
 
pr_debug(couldn't find an available UDC\n);
mutex_unlock(udc_lock);
-   return -ENODEV;
+   return ret;
 found:
ret = udc_bind_to_driver(udc, driver);
mutex_unlock(udc_lock);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 02476b3..6d26657 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -821,6 +821,8 @@ static inline int usb_gadget_disconnect(struct usb_gadget 
*gadget)
  * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
  * and should be called in_interrupt.
  * @driver: Driver model state for this driver.
+ * @udc_name: A name of UDC this driver should be bound to. If udc_name is 
NULL,
+ * this driver will be bound to any available UDC.
  *
  * Devices are disabled till a gadget driver successfully bind()s, which
  * means the driver will handle setup() requests needed to enumerate (and
@@ -881,6 +883,8 @@ struct usb_gadget_driver {
 
/* FIXME support safe rmmod */
struct device_driverdriver;
+
+   char*udc_name;
 };
 
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 2/5] usb: gadget: configfs: pass UDC name via usb_gadget_driver struct

2015-03-12 Thread Ruslan Bilovol
Now when udc-core supports binding to specific UDC by passing
its name via 'udc_name' member of usb_gadget_driver struct,
switch to this generic approach.

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/configfs.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index c42765b..efad021 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -54,7 +54,6 @@ struct gadget_info {
struct list_head string_list;
struct list_head available_func;
 
-   const char *udc_name;
 #ifdef CONFIG_USB_OTG
struct usb_otg_descriptor otg;
 #endif
@@ -230,21 +229,21 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct 
gadget_info *gi,
 
 static ssize_t gadget_dev_desc_UDC_show(struct gadget_info *gi, char *page)
 {
-   return sprintf(page, %s\n, gi-udc_name ?: );
+   return sprintf(page, %s\n, gi-composite.gadget_driver.udc_name ?: 
);
 }
 
 static int unregister_gadget(struct gadget_info *gi)
 {
int ret;
 
-   if (!gi-udc_name)
+   if (!gi-composite.gadget_driver.udc_name)
return -ENODEV;
 
ret = usb_gadget_unregister_driver(gi-composite.gadget_driver);
if (ret)
return ret;
-   kfree(gi-udc_name);
-   gi-udc_name = NULL;
+   kfree(gi-composite.gadget_driver.udc_name);
+   gi-composite.gadget_driver.udc_name = NULL;
return 0;
 }
 
@@ -267,14 +266,16 @@ static ssize_t gadget_dev_desc_UDC_store(struct 
gadget_info *gi,
if (ret)
goto err;
} else {
-   if (gi-udc_name) {
+   if (gi-composite.gadget_driver.udc_name) {
ret = -EBUSY;
goto err;
}
-   ret = usb_udc_attach_driver(name, gi-composite.gadget_driver);
-   if (ret)
+   gi-composite.gadget_driver.udc_name = name;
+   ret = usb_gadget_probe_driver(gi-composite.gadget_driver);
+   if (ret) {
+   gi-composite.gadget_driver.udc_name = NULL;
goto err;
-   gi-udc_name = name;
+   }
}
mutex_unlock(gi-lock);
return len;
@@ -438,9 +439,9 @@ static int config_usb_cfg_unlink(
 * remove the function.
 */
mutex_lock(gi-lock);
-   if (gi-udc_name)
+   if (gi-composite.gadget_driver.udc_name)
unregister_gadget(gi);
-   WARN_ON(gi-udc_name);
+   WARN_ON(gi-composite.gadget_driver.udc_name);
 
list_for_each_entry(f, cfg-func_list, list) {
if (f-fi == fi) {
@@ -917,10 +918,10 @@ static int os_desc_unlink(struct config_item *os_desc_ci,
struct usb_composite_dev *cdev = gi-cdev;
 
mutex_lock(gi-lock);
-   if (gi-udc_name)
+   if (gi-composite.gadget_driver.udc_name)
unregister_gadget(gi);
cdev-os_desc_config = NULL;
-   WARN_ON(gi-udc_name);
+   WARN_ON(gi-composite.gadget_driver.udc_name);
mutex_unlock(gi-lock);
return 0;
 }
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 4/5] usb: gadget: legacy: don't use __init/__exit attributes for bind/unbind path

2015-03-12 Thread Ruslan Bilovol
In order to prepare to independent gadgets and
gadget drivers registration in udc-core, some of the
functions can't have __init/__exit attributes (almost
only bind/unbind callbacks are affected)

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/legacy/acm_ms.c   |  6 +++---
 drivers/usb/gadget/legacy/audio.c|  6 +++---
 drivers/usb/gadget/legacy/cdc2.c |  6 +++---
 drivers/usb/gadget/legacy/dbgp.c |  2 +-
 drivers/usb/gadget/legacy/ether.c|  8 
 drivers/usb/gadget/legacy/gmidi.c|  6 +++---
 drivers/usb/gadget/legacy/hid.c  |  6 +++---
 drivers/usb/gadget/legacy/mass_storage.c |  4 ++--
 drivers/usb/gadget/legacy/multi.c| 16 
 drivers/usb/gadget/legacy/ncm.c  |  6 +++---
 drivers/usb/gadget/legacy/nokia.c|  6 +++---
 drivers/usb/gadget/legacy/printer.c  |  6 +++---
 drivers/usb/gadget/legacy/serial.c   |  2 +-
 drivers/usb/gadget/legacy/webcam.c   |  4 ++--
 drivers/usb/gadget/legacy/zero.c |  2 +-
 15 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/usb/gadget/legacy/acm_ms.c 
b/drivers/usb/gadget/legacy/acm_ms.c
index c30b7b5..3a48aab 100644
--- a/drivers/usb/gadget/legacy/acm_ms.c
+++ b/drivers/usb/gadget/legacy/acm_ms.c
@@ -121,7 +121,7 @@ static struct usb_function *f_msg;
 /*
  * We _always_ have both ACM and mass storage functions.
  */
-static int __init acm_ms_do_config(struct usb_configuration *c)
+static int acm_ms_do_config(struct usb_configuration *c)
 {
struct fsg_opts *opts;
int status;
@@ -174,7 +174,7 @@ static struct usb_configuration acm_ms_config_driver = {
 
 /*-*/
 
-static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+static int acm_ms_bind(struct usb_composite_dev *cdev)
 {
struct usb_gadget   *gadget = cdev-gadget;
struct fsg_opts *opts;
@@ -249,7 +249,7 @@ fail_get_msg:
return status;
 }
 
-static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
+static int acm_ms_unbind(struct usb_composite_dev *cdev)
 {
usb_put_function(f_msg);
usb_put_function_instance(fi_msg);
diff --git a/drivers/usb/gadget/legacy/audio.c 
b/drivers/usb/gadget/legacy/audio.c
index f46a395..ba95518 100644
--- a/drivers/usb/gadget/legacy/audio.c
+++ b/drivers/usb/gadget/legacy/audio.c
@@ -167,7 +167,7 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 /*-*/
 
-static int __init audio_do_config(struct usb_configuration *c)
+static int audio_do_config(struct usb_configuration *c)
 {
int status;
 
@@ -216,7 +216,7 @@ static struct usb_configuration audio_config_driver = {
 
 /*-*/
 
-static int __init audio_bind(struct usb_composite_dev *cdev)
+static int audio_bind(struct usb_composite_dev *cdev)
 {
 #ifndef CONFIG_GADGET_UAC1
struct f_uac2_opts  *uac2_opts;
@@ -276,7 +276,7 @@ fail:
return status;
 }
 
-static int __exit audio_unbind(struct usb_composite_dev *cdev)
+static int audio_unbind(struct usb_composite_dev *cdev)
 {
 #ifdef CONFIG_GADGET_UAC1
if (!IS_ERR_OR_NULL(f_uac1))
diff --git a/drivers/usb/gadget/legacy/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c
index 2e85d94..8d1985c 100644
--- a/drivers/usb/gadget/legacy/cdc2.c
+++ b/drivers/usb/gadget/legacy/cdc2.c
@@ -104,7 +104,7 @@ static struct usb_function_instance *fi_ecm;
 /*
  * We _always_ have both CDC ECM and CDC ACM functions.
  */
-static int __init cdc_do_config(struct usb_configuration *c)
+static int cdc_do_config(struct usb_configuration *c)
 {
int status;
 
@@ -153,7 +153,7 @@ static struct usb_configuration cdc_config_driver = {
 
 /*-*/
 
-static int __init cdc_bind(struct usb_composite_dev *cdev)
+static int cdc_bind(struct usb_composite_dev *cdev)
 {
struct usb_gadget   *gadget = cdev-gadget;
struct f_ecm_opts   *ecm_opts;
@@ -211,7 +211,7 @@ fail:
return status;
 }
 
-static int __exit cdc_unbind(struct usb_composite_dev *cdev)
+static int cdc_unbind(struct usb_composite_dev *cdev)
 {
usb_put_function(f_acm);
usb_put_function_instance(fi_serial);
diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c
index 633683a..7c42b01 100644
--- a/drivers/usb/gadget/legacy/dbgp.c
+++ b/drivers/usb/gadget/legacy/dbgp.c
@@ -284,7 +284,7 @@ fail_1:
return -ENODEV;
 }
 
-static int __init dbgp_bind(struct usb_gadget *gadget,
+static int dbgp_bind(struct usb_gadget *gadget,
struct usb_gadget_driver *driver)
 {
int err, stp;
diff --git a/drivers/usb/gadget/legacy/ether.c 
b/drivers/usb/gadget/legacy/ether.c
index c5fdc61..4283969 100644
--- a/drivers/usb

Re: [PATCHv3 5/5] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-03-10 Thread Ruslan Bilovol
Hi Alan,

On Tue, Feb 17, 2015 at 11:51 PM, Alan Stern st...@rowland.harvard.edu wrote:
 On Tue, 17 Feb 2015, Ruslan Bilovol wrote:

 Change behavior during registration of gadgets and
 gadget drivers in udc-core. Instead of previous
 approach when for successful probe of usb gadget driver
 at least one usb gadget should be already registered
 use another one where gadget drivers and gadgets
 can be registered in udc-core independently.

 Independent registration of gadgets and gadget drivers
 is useful for built-in into kernel gadget and gadget
 driver case - because it's possible that gadget is
 really probed only on late_init stage (due to deferred
 probe) whereas gadget driver's probe is silently failed
 on module_init stage due to no any UDC added.

 Also it is useful for modules case - now there is no
 difference what module to insert first: gadget module
 or gadget driver one.

 Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
 ---
  drivers/usb/gadget/udc/udc-core.c | 51 
 ++-
  include/linux/usb/gadget.h|  2 ++
  2 files changed, 42 insertions(+), 11 deletions(-)

 diff --git a/drivers/usb/gadget/udc/udc-core.c 
 b/drivers/usb/gadget/udc/udc-core.c
 index a960f3f..9e82497 100644
 --- a/drivers/usb/gadget/udc/udc-core.c
 +++ b/drivers/usb/gadget/udc/udc-core.c
 @@ -48,8 +48,11 @@ struct usb_udc {

  static struct class *udc_class;
  static LIST_HEAD(udc_list);
 +static LIST_HEAD(gadget_driver_pending_list);
  static DEFINE_MUTEX(udc_lock);

 +static int udc_bind_to_driver(struct usb_udc *udc,
 + struct usb_gadget_driver *driver);

 Strange indentation, not at all like the other continuation lines in
 this source file.

 Also, there should be a blank line here, as in the original file.

Will fix it


  /* 
 - */

  #ifdef   CONFIG_HAS_DMA
 @@ -243,6 +246,7 @@ int usb_add_gadget_udc_release(struct device *parent, 
 struct usb_gadget *gadget,
   void (*release)(struct device *dev))
  {
   struct usb_udc  *udc;
 + struct usb_gadget_driver *pgadget;

 Don't call it pgadget.  None of the other pointer variables in this
 file have an extra p added to the beginnings of their names.

It seems this name is confusing (it is intended to have pending
gadget meaning). Will change it in next patch version


   int ret = -ENOMEM;

   udc = kzalloc(sizeof(*udc), GFP_KERNEL);
 @@ -288,6 +292,18 @@ int usb_add_gadget_udc_release(struct device *parent, 
 struct usb_gadget *gadget,

   usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);

 + /* pick up one of pending gadget drivers */
 + list_for_each_entry(pgadget, gadget_driver_pending_list, pending) {
 + if (!pgadget-udc_name || strcmp(pgadget-udc_name,
 + dev_name(udc-dev)) == 0) {
 + ret = udc_bind_to_driver(udc, pgadget);

 Are you sure it's safe to call this routine while holding the udc_lock
 mutex?

Yes, it's safe here, in the only place where it was used before
this routine is also called while holding the udc_lock mutex
(see usb_gadget_probe_driver)


 + if (ret)
 + goto err4;
 + list_del(pgadget-pending);

 Use list_del_init().

 + break;
 + }
 + }
 +
   mutex_unlock(udc_lock);

   return 0;
 @@ -364,10 +380,11 @@ found:
   dev_vdbg(gadget-dev.parent, unregistering gadget\n);

   list_del(udc-list);
 - mutex_unlock(udc_lock);
 -
 - if (udc-driver)
 + if (udc-driver) {
 + list_add(udc-driver-pending, gadget_driver_pending_list);
   usb_gadget_remove_driver(udc);

 Are you sure it's safe to call this routine while holding the udc_lock
 mutex?

Should not be any issue here but it's possible to prevent this, will do it
in next patch version


 + }
 + mutex_unlock(udc_lock);

   kobject_uevent(udc-dev.kobj, KOBJ_REMOVE);
   flush_work(gadget-work);
 @@ -426,24 +443,26 @@ int usb_gadget_probe_driver(struct usb_gadget_driver 
 *driver)
   if (!ret)
   break;
   }
 - if (ret)
 - ret = -ENODEV;
 - else if (udc-driver)
 - ret = -EBUSY;
 - else
 + if (!ret  udc-driver) {
 + mutex_unlock(udc_lock);
 + return -EBUSY;

 This is a judgement call.  It might be better to return 0 and add the
 gadget driver to the pending list.

Yes, that makes sense, will change it


 + } else if (!ret) {
   goto found;
 + }
   } else {
   list_for_each_entry(udc, udc_list, list) {
   /* For now we take the first one */
   if (!udc-driver

Re: [PATCHv3 1/5] usb: gadget: bind UDC by name passed via usb_gadget_driver structure

2015-03-10 Thread Ruslan Bilovol
Hi Sergei,

On Wed, Feb 18, 2015 at 2:05 PM, Sergei Shtylyov
sergei.shtyl...@cogentembedded.com wrote:
 Hello.

 On 2/18/2015 12:17 AM, Ruslan Bilovol wrote:

 Introduce new 'udc_name' member to usb_gadget_driver structure.
 The 'udc_name' is a name of UDC that usb_gadget_driver should
 be bound to. If udc_name is NULL, it will be bound to any
 available UDC.


 Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
 ---
   drivers/usb/gadget/udc/udc-core.c | 25 -
   include/linux/usb/gadget.h|  4 
   2 files changed, 24 insertions(+), 5 deletions(-)


 diff --git a/drivers/usb/gadget/udc/udc-core.c
 b/drivers/usb/gadget/udc/udc-core.c
 index 5a81cb0..e1079e08 100644
 --- a/drivers/usb/gadget/udc/udc-core.c
 +++ b/drivers/usb/gadget/udc/udc-core.c
 @@ -440,21 +440,36 @@ EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
   int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
   {
 struct usb_udc  *udc = NULL;
 -   int ret;
 +   int ret = -ENODEV;

 if (!driver || !driver-bind || !driver-setup)
 return -EINVAL;

 mutex_lock(udc_lock);
 -   list_for_each_entry(udc, udc_list, list) {
 -   /* For now we take the first one */
 -   if (!udc-driver)
 +   if (driver-udc_name) {
 +   list_for_each_entry(udc, udc_list, list) {
 +   ret = strcmp(driver-udc_name,
 dev_name(udc-dev));
 +   if (!ret)
 +   break;
 +   }
 +   if (ret)
 +   ret = -ENODEV;
 +   else if (udc-driver)
 +   ret = -EBUSY;
 +   else
 goto found;
 +   } else {
 +   list_for_each_entry(udc, udc_list, list) {
 +   /* For now we take the first one */
 +   if (!udc-driver)
 +   goto found;
 +   }
 +   ret = -ENODEV;


Already assigned the same value by the initializer.

Thanks for pointing to this, will be fixed in next patch version


 }

 pr_debug(couldn't find an available UDC\n);
 mutex_unlock(udc_lock);
 -   return -ENODEV;
 +   return ret;
   found:
 ret = udc_bind_to_driver(udc, driver);
 mutex_unlock(udc_lock);

 [...]

 WBR, Sergei



Best regards,
Ruslan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-02-17 Thread Ruslan Bilovol
Hi Andrzej,

On Mon, Feb 16, 2015 at 10:07 AM, Andrzej Pietrasiewicz
andrze...@samsung.com wrote:
 W dniu 15.02.2015 o 23:43, Ruslan Bilovol pisze:

 snip


 In my opinion all things which you have described are working out-of-box
 when you use configfs interface. It's mostly ready so you may create
 equivalent of most legacy gadgets (apart from printer and tcm) and
 just bind from one udc to another whenever you want.


 It's because legacy gadgets are easy to use and usually don't need any
 userspace-side configuration. Are there any plans to remove legacy
 drivers in the future?


 I'm not going to express strong opinions here, but their name implies
 that this can happen, some time in the future.

 And I also think it will not happen before the userspace part
 (libusbg, gt, gadgetd etc) is mature enough. My personal opinion
 in that matter is that it will take at least a couple of years
 to remove legacy gadgets entirely.

OK, so it looks like there is a sense even to add new gadget/functions
with legacy support

Thanks,
Ruslan


 AP

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 0/5] usb/gadget: independent registration of gadgets and gadget drivers

2015-02-17 Thread Ruslan Bilovol
This patchset adds independent registration of gadgets
and gadget drivers to udc-core. This is very useful for
built-in modules into kernel case since it's possible
situation that gadget driver is probing at a time
when no gadgets are registered in udc-core.
In this case instead of silently failing without
of any attempt to recover, with independent registration
of gadgets and gadget drivers there is no matter
in which order gadgets and gadget drivers are
probed/registered.

This patch has side-effect on gadget drivers that had
__init/__exit attributes on some paths like bind/unbind
and (since bind/unbind may happen at any time) should
not use them now. This is covered by forth patch

=
v3:
 - addressed Alan's comments - now UDC name and pending
   gadget drivers list is a part of struct usb_gadget_driver.
 - removed usb_udc_attach_driver() function that became unused
   and not needed now

v2:
 - changed first patch to have only deferred probe part
   (because Gadget Bus seems to be better variant when
   some more complicated behavior will be required)
 - rebased to latest 'next' branch of Felipe Balbi's tree


Ruslan Bilovol (5):
  usb: gadget: bind UDC by name passed via usb_gadget_driver structure
  usb: gadge: configfs: pass UDC name via usb_gadget_driver struct
  usb: gadget: udc-core: remove unused usb_udc_attach_driver()
  usb: gadget: legacy: don't use __init/__exit attributes for
bind/unbind path
  usb: gadget: udc-core: independent registration of gadgets and gadget
drivers

 drivers/usb/gadget/configfs.c| 27 +-
 drivers/usb/gadget/legacy/acm_ms.c   |  6 +--
 drivers/usb/gadget/legacy/audio.c|  6 +--
 drivers/usb/gadget/legacy/cdc2.c |  6 +--
 drivers/usb/gadget/legacy/dbgp.c |  2 +-
 drivers/usb/gadget/legacy/ether.c|  8 +--
 drivers/usb/gadget/legacy/gmidi.c|  6 +--
 drivers/usb/gadget/legacy/hid.c  |  6 +--
 drivers/usb/gadget/legacy/mass_storage.c |  4 +-
 drivers/usb/gadget/legacy/multi.c| 16 +++---
 drivers/usb/gadget/legacy/ncm.c  |  6 +--
 drivers/usb/gadget/legacy/nokia.c|  6 +--
 drivers/usb/gadget/legacy/printer.c  |  6 +--
 drivers/usb/gadget/legacy/serial.c   |  2 +-
 drivers/usb/gadget/legacy/webcam.c   |  4 +-
 drivers/usb/gadget/legacy/zero.c |  2 +-
 drivers/usb/gadget/udc/udc-core.c| 88 +++-
 include/linux/usb/gadget.h   |  8 ++-
 18 files changed, 116 insertions(+), 93 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 2/5] usb: gadge: configfs: pass UDC name via usb_gadget_driver struct

2015-02-17 Thread Ruslan Bilovol
Now when udc-core supports binding to specific UDC by passing
its name via 'udc_name' member of usb_gadget_driver struct,
switch to this generic approach.

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/configfs.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 7564814..b6aae63 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -54,7 +54,6 @@ struct gadget_info {
struct list_head string_list;
struct list_head available_func;
 
-   const char *udc_name;
 #ifdef CONFIG_USB_OTG
struct usb_otg_descriptor otg;
 #endif
@@ -230,21 +229,21 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct 
gadget_info *gi,
 
 static ssize_t gadget_dev_desc_UDC_show(struct gadget_info *gi, char *page)
 {
-   return sprintf(page, %s\n, gi-udc_name ?: );
+   return sprintf(page, %s\n, gi-composite.gadget_driver.udc_name ?: 
);
 }
 
 static int unregister_gadget(struct gadget_info *gi)
 {
int ret;
 
-   if (!gi-udc_name)
+   if (!gi-composite.gadget_driver.udc_name)
return -ENODEV;
 
ret = usb_gadget_unregister_driver(gi-composite.gadget_driver);
if (ret)
return ret;
-   kfree(gi-udc_name);
-   gi-udc_name = NULL;
+   kfree(gi-composite.gadget_driver.udc_name);
+   gi-composite.gadget_driver.udc_name = NULL;
return 0;
 }
 
@@ -267,14 +266,16 @@ static ssize_t gadget_dev_desc_UDC_store(struct 
gadget_info *gi,
if (ret)
goto err;
} else {
-   if (gi-udc_name) {
+   if (gi-composite.gadget_driver.udc_name) {
ret = -EBUSY;
goto err;
}
-   ret = usb_udc_attach_driver(name, gi-composite.gadget_driver);
-   if (ret)
+   gi-composite.gadget_driver.udc_name = name;
+   ret = usb_gadget_probe_driver(gi-composite.gadget_driver);
+   if (ret) {
+   gi-composite.gadget_driver.udc_name = NULL;
goto err;
-   gi-udc_name = name;
+   }
}
mutex_unlock(gi-lock);
return len;
@@ -438,9 +439,9 @@ static int config_usb_cfg_unlink(
 * remove the function.
 */
mutex_lock(gi-lock);
-   if (gi-udc_name)
+   if (gi-composite.gadget_driver.udc_name)
unregister_gadget(gi);
-   WARN_ON(gi-udc_name);
+   WARN_ON(gi-composite.gadget_driver.udc_name);
 
list_for_each_entry(f, cfg-func_list, list) {
if (f-fi == fi) {
@@ -917,10 +918,10 @@ static int os_desc_unlink(struct config_item *os_desc_ci,
struct usb_composite_dev *cdev = gi-cdev;
 
mutex_lock(gi-lock);
-   if (gi-udc_name)
+   if (gi-composite.gadget_driver.udc_name)
unregister_gadget(gi);
cdev-os_desc_config = NULL;
-   WARN_ON(gi-udc_name);
+   WARN_ON(gi-composite.gadget_driver.udc_name);
mutex_unlock(gi-lock);
return 0;
 }
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 5/5] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-02-17 Thread Ruslan Bilovol
Change behavior during registration of gadgets and
gadget drivers in udc-core. Instead of previous
approach when for successful probe of usb gadget driver
at least one usb gadget should be already registered
use another one where gadget drivers and gadgets
can be registered in udc-core independently.

Independent registration of gadgets and gadget drivers
is useful for built-in into kernel gadget and gadget
driver case - because it's possible that gadget is
really probed only on late_init stage (due to deferred
probe) whereas gadget driver's probe is silently failed
on module_init stage due to no any UDC added.

Also it is useful for modules case - now there is no
difference what module to insert first: gadget module
or gadget driver one.

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 51 ++-
 include/linux/usb/gadget.h|  2 ++
 2 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index a960f3f..9e82497 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -48,8 +48,11 @@ struct usb_udc {
 
 static struct class *udc_class;
 static LIST_HEAD(udc_list);
+static LIST_HEAD(gadget_driver_pending_list);
 static DEFINE_MUTEX(udc_lock);
 
+static int udc_bind_to_driver(struct usb_udc *udc,
+   struct usb_gadget_driver *driver);
 /* - */
 
 #ifdef CONFIG_HAS_DMA
@@ -243,6 +246,7 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
void (*release)(struct device *dev))
 {
struct usb_udc  *udc;
+   struct usb_gadget_driver *pgadget;
int ret = -ENOMEM;
 
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
@@ -288,6 +292,18 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
 
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
 
+   /* pick up one of pending gadget drivers */
+   list_for_each_entry(pgadget, gadget_driver_pending_list, pending) {
+   if (!pgadget-udc_name || strcmp(pgadget-udc_name,
+   dev_name(udc-dev)) == 0) {
+   ret = udc_bind_to_driver(udc, pgadget);
+   if (ret)
+   goto err4;
+   list_del(pgadget-pending);
+   break;
+   }
+   }
+
mutex_unlock(udc_lock);
 
return 0;
@@ -364,10 +380,11 @@ found:
dev_vdbg(gadget-dev.parent, unregistering gadget\n);
 
list_del(udc-list);
-   mutex_unlock(udc_lock);
-
-   if (udc-driver)
+   if (udc-driver) {
+   list_add(udc-driver-pending, gadget_driver_pending_list);
usb_gadget_remove_driver(udc);
+   }
+   mutex_unlock(udc_lock);
 
kobject_uevent(udc-dev.kobj, KOBJ_REMOVE);
flush_work(gadget-work);
@@ -426,24 +443,26 @@ int usb_gadget_probe_driver(struct usb_gadget_driver 
*driver)
if (!ret)
break;
}
-   if (ret)
-   ret = -ENODEV;
-   else if (udc-driver)
-   ret = -EBUSY;
-   else
+   if (!ret  udc-driver) {
+   mutex_unlock(udc_lock);
+   return -EBUSY;
+   } else if (!ret) {
goto found;
+   }
} else {
list_for_each_entry(udc, udc_list, list) {
/* For now we take the first one */
if (!udc-driver)
goto found;
}
-   ret = -ENODEV;
}
 
-   pr_debug(couldn't find an available UDC\n);
+   list_add_tail(driver-pending, gadget_driver_pending_list);
+   pr_info(udc-core: couldn't find an available UDC 
+   - added [%s] to list of pending drivers\n,
+   driver-function);
mutex_unlock(udc_lock);
-   return ret;
+   return 0;
 found:
ret = udc_bind_to_driver(udc, driver);
mutex_unlock(udc_lock);
@@ -469,6 +488,16 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver 
*driver)
break;
}
 
+   if (ret) {
+   struct usb_gadget_driver *tmp;
+
+   list_for_each_entry(tmp, gadget_driver_pending_list, pending)
+   if (tmp == driver) {
+   list_del(driver-pending);
+   ret = 0;
+   break;
+   }
+   }
mutex_unlock(udc_lock);
return ret;
 }
diff --git a/include/linux/usb

[PATCHv3 1/5] usb: gadget: bind UDC by name passed via usb_gadget_driver structure

2015-02-17 Thread Ruslan Bilovol
Introduce new 'udc_name' member to usb_gadget_driver structure.
The 'udc_name' is a name of UDC that usb_gadget_driver should
be bound to. If udc_name is NULL, it will be bound to any
available UDC.

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 25 -
 include/linux/usb/gadget.h|  4 
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index 5a81cb0..e1079e08 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -440,21 +440,36 @@ EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
 int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 {
struct usb_udc  *udc = NULL;
-   int ret;
+   int ret = -ENODEV;
 
if (!driver || !driver-bind || !driver-setup)
return -EINVAL;
 
mutex_lock(udc_lock);
-   list_for_each_entry(udc, udc_list, list) {
-   /* For now we take the first one */
-   if (!udc-driver)
+   if (driver-udc_name) {
+   list_for_each_entry(udc, udc_list, list) {
+   ret = strcmp(driver-udc_name, dev_name(udc-dev));
+   if (!ret)
+   break;
+   }
+   if (ret)
+   ret = -ENODEV;
+   else if (udc-driver)
+   ret = -EBUSY;
+   else
goto found;
+   } else {
+   list_for_each_entry(udc, udc_list, list) {
+   /* For now we take the first one */
+   if (!udc-driver)
+   goto found;
+   }
+   ret = -ENODEV;
}
 
pr_debug(couldn't find an available UDC\n);
mutex_unlock(udc_lock);
-   return -ENODEV;
+   return ret;
 found:
ret = udc_bind_to_driver(udc, driver);
mutex_unlock(udc_lock);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index e2f00fd..3e7aab1 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -821,6 +821,8 @@ static inline int usb_gadget_disconnect(struct usb_gadget 
*gadget)
  * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
  * and should be called in_interrupt.
  * @driver: Driver model state for this driver.
+ * @udc_name: A name of UDC this driver should be bound to. If udc_name is 
NULL,
+ * this driver will be bound to any available UDC.
  *
  * Devices are disabled till a gadget driver successfully bind()s, which
  * means the driver will handle setup() requests needed to enumerate (and
@@ -881,6 +883,8 @@ struct usb_gadget_driver {
 
/* FIXME support safe rmmod */
struct device_driverdriver;
+
+   char*udc_name;
 };
 
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 3/5] usb: gadget: udc-core: remove unused usb_udc_attach_driver()

2015-02-17 Thread Ruslan Bilovol
Now when last user of usb_udc_attach_driver() is switched
to passing UDC name via usb_gadget_driver struct, it's safe
to remove this function

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 26 --
 include/linux/usb/gadget.h|  2 --
 2 files changed, 28 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index e1079e08..a960f3f 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -411,32 +411,6 @@ err1:
return ret;
 }
 
-int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver)
-{
-   struct usb_udc *udc = NULL;
-   int ret = -ENODEV;
-
-   mutex_lock(udc_lock);
-   list_for_each_entry(udc, udc_list, list) {
-   ret = strcmp(name, dev_name(udc-dev));
-   if (!ret)
-   break;
-   }
-   if (ret) {
-   ret = -ENODEV;
-   goto out;
-   }
-   if (udc-driver) {
-   ret = -EBUSY;
-   goto out;
-   }
-   ret = udc_bind_to_driver(udc, driver);
-out:
-   mutex_unlock(udc_lock);
-   return ret;
-}
-EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
-
 int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 {
struct usb_udc  *udc = NULL;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 3e7aab1..6070e8d 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -930,8 +930,6 @@ extern int usb_add_gadget_udc_release(struct device *parent,
struct usb_gadget *gadget, void (*release)(struct device *dev));
 extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget 
*gadget);
 extern void usb_del_gadget_udc(struct usb_gadget *gadget);
-extern int usb_udc_attach_driver(const char *name,
-   struct usb_gadget_driver *driver);
 
 /*-*/
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 4/5] usb: gadget: legacy: don't use __init/__exit attributes for bind/unbind path

2015-02-17 Thread Ruslan Bilovol
In order to prepare to independent gadgets and
gadget drivers registration in udc-core, some of the
functions can't have __init/__exit attributes (almost
only bind/unbind callbacks are affected)

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/legacy/acm_ms.c   |  6 +++---
 drivers/usb/gadget/legacy/audio.c|  6 +++---
 drivers/usb/gadget/legacy/cdc2.c |  6 +++---
 drivers/usb/gadget/legacy/dbgp.c |  2 +-
 drivers/usb/gadget/legacy/ether.c|  8 
 drivers/usb/gadget/legacy/gmidi.c|  6 +++---
 drivers/usb/gadget/legacy/hid.c  |  6 +++---
 drivers/usb/gadget/legacy/mass_storage.c |  4 ++--
 drivers/usb/gadget/legacy/multi.c| 16 
 drivers/usb/gadget/legacy/ncm.c  |  6 +++---
 drivers/usb/gadget/legacy/nokia.c|  6 +++---
 drivers/usb/gadget/legacy/printer.c  |  6 +++---
 drivers/usb/gadget/legacy/serial.c   |  2 +-
 drivers/usb/gadget/legacy/webcam.c   |  4 ++--
 drivers/usb/gadget/legacy/zero.c |  2 +-
 15 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/usb/gadget/legacy/acm_ms.c 
b/drivers/usb/gadget/legacy/acm_ms.c
index c30b7b5..3a48aab 100644
--- a/drivers/usb/gadget/legacy/acm_ms.c
+++ b/drivers/usb/gadget/legacy/acm_ms.c
@@ -121,7 +121,7 @@ static struct usb_function *f_msg;
 /*
  * We _always_ have both ACM and mass storage functions.
  */
-static int __init acm_ms_do_config(struct usb_configuration *c)
+static int acm_ms_do_config(struct usb_configuration *c)
 {
struct fsg_opts *opts;
int status;
@@ -174,7 +174,7 @@ static struct usb_configuration acm_ms_config_driver = {
 
 /*-*/
 
-static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+static int acm_ms_bind(struct usb_composite_dev *cdev)
 {
struct usb_gadget   *gadget = cdev-gadget;
struct fsg_opts *opts;
@@ -249,7 +249,7 @@ fail_get_msg:
return status;
 }
 
-static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
+static int acm_ms_unbind(struct usb_composite_dev *cdev)
 {
usb_put_function(f_msg);
usb_put_function_instance(fi_msg);
diff --git a/drivers/usb/gadget/legacy/audio.c 
b/drivers/usb/gadget/legacy/audio.c
index f46a395..ba95518 100644
--- a/drivers/usb/gadget/legacy/audio.c
+++ b/drivers/usb/gadget/legacy/audio.c
@@ -167,7 +167,7 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 /*-*/
 
-static int __init audio_do_config(struct usb_configuration *c)
+static int audio_do_config(struct usb_configuration *c)
 {
int status;
 
@@ -216,7 +216,7 @@ static struct usb_configuration audio_config_driver = {
 
 /*-*/
 
-static int __init audio_bind(struct usb_composite_dev *cdev)
+static int audio_bind(struct usb_composite_dev *cdev)
 {
 #ifndef CONFIG_GADGET_UAC1
struct f_uac2_opts  *uac2_opts;
@@ -276,7 +276,7 @@ fail:
return status;
 }
 
-static int __exit audio_unbind(struct usb_composite_dev *cdev)
+static int audio_unbind(struct usb_composite_dev *cdev)
 {
 #ifdef CONFIG_GADGET_UAC1
if (!IS_ERR_OR_NULL(f_uac1))
diff --git a/drivers/usb/gadget/legacy/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c
index 2e85d94..8d1985c 100644
--- a/drivers/usb/gadget/legacy/cdc2.c
+++ b/drivers/usb/gadget/legacy/cdc2.c
@@ -104,7 +104,7 @@ static struct usb_function_instance *fi_ecm;
 /*
  * We _always_ have both CDC ECM and CDC ACM functions.
  */
-static int __init cdc_do_config(struct usb_configuration *c)
+static int cdc_do_config(struct usb_configuration *c)
 {
int status;
 
@@ -153,7 +153,7 @@ static struct usb_configuration cdc_config_driver = {
 
 /*-*/
 
-static int __init cdc_bind(struct usb_composite_dev *cdev)
+static int cdc_bind(struct usb_composite_dev *cdev)
 {
struct usb_gadget   *gadget = cdev-gadget;
struct f_ecm_opts   *ecm_opts;
@@ -211,7 +211,7 @@ fail:
return status;
 }
 
-static int __exit cdc_unbind(struct usb_composite_dev *cdev)
+static int cdc_unbind(struct usb_composite_dev *cdev)
 {
usb_put_function(f_acm);
usb_put_function_instance(fi_serial);
diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c
index 633683a..7c42b01 100644
--- a/drivers/usb/gadget/legacy/dbgp.c
+++ b/drivers/usb/gadget/legacy/dbgp.c
@@ -284,7 +284,7 @@ fail_1:
return -ENODEV;
 }
 
-static int __init dbgp_bind(struct usb_gadget *gadget,
+static int dbgp_bind(struct usb_gadget *gadget,
struct usb_gadget_driver *driver)
 {
int err, stp;
diff --git a/drivers/usb/gadget/legacy/ether.c 
b/drivers/usb/gadget/legacy/ether.c
index c5fdc61..4283969 100644
--- a/drivers/usb

Re: [PATCH 1/2] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-02-15 Thread Ruslan Bilovol
Hi Alan,

On Mon, Feb 9, 2015 at 10:00 PM, Alan Stern st...@rowland.harvard.edu wrote:
 On Mon, 9 Feb 2015, Krzysztof Opasiak wrote:

  Why bother matching by name?  Why not simply take the first
  available
  UDC?

 Because you may have more than one udc. This would allow to pick one by
 name just like using configfs interface.

 Clearly it would be more flexible to allow the user to do the matching,
 the way configfs does (sysfs too).

   Main feature of my path is not only deferred binding of gadget
  driver,
   but also possibility to register/unregister udc at any time.
   This is useful for user who can load, for example, udc module
   if needed and unload it safely, not touching gadget driver.
 
  We can already do that with the existing code.  There's no need for
  a
  patch.
 
  Also, it's not clear that the existing gadget drivers will work
  properly if they are unbound from one UDC and then bound again to
  another one.  They were not written with that sort of thing in
  mind.
 

 What you have described is one of basics configfs features.
 You should be able to bind and unbind your gadget whenever you want
 and it should work properly after doing:

 ## create gadget
 $ echo udc.0  UDC
 $ echo   UDC
 $ echo udc.1  UDC

 Function shouldn't care which udc it has been bound previously.
 Only current one is important and on each unbind each function
 should cleanup its state and prepare to be bound to another udc.
 Configfs interface doesn't prohibit this and I haven't seen any
 info about such restriction.

 It's not prohibited, but it also was never required.  Therefore it may
 not be implemented in all gadget drivers.

  If some function is not working in
 such situation there is a bug in that function and it should be fixed.

 That's fine.  I wasn't pointing out a fundamental limitation, just a
 fact that will have to be taken into account.

 Anyway, instead of going through all this, why not do what I suggested
 earlier (see http://marc.info/?l=linux-usbm=139888691230119w=2) and
 create a gadget bus type?  That would give userspace explicit control
 over which gadget driver was bound to which UDC.

 Or maybe that's not a very good fit with the existing code, since most
 gadget drivers assume they will be bound to only one UDC at a time.  So
 instead, why not create a sysfs interface that allows userspace to
 control which gadget drivers are bound to which UDCs?

 As I recall, the original problem people were complaining about was
 deferred probing.  They didn't need fancy matching; all they wanted was
 the ability to bind a gadget driver to a UDC some time after the gadget
 driver was loaded and initialized.  Something simple like Robert
 Baldyga's patch is enough to do that.

I looked over my patch and see that it doesn't automatically rebind
gadget driver to another available UDC after previous UDC is unbound.
The Gadget Bus mentioned previously is good thing but so far it seems there
is no users of such approach. So I left only deferred registration
from my patch.
I still keep it inside of udc-core since we also need to keep tracking UDC name
if somebody wanted to bind gadget driver to specific UDC and it looks
like good place to maintain this. I'll send second version of patches soon

-- 
Best regards,
Ruslan Bilvol
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-02-15 Thread Ruslan Bilovol
Hi Krzysztof,

On Tue, Feb 10, 2015 at 10:47 AM, Krzysztof Opasiak
k.opas...@samsung.com wrote:


 -Original Message-
 From: Ruslan Bilovol [mailto:ruslan.bilo...@gmail.com]
 Sent: Tuesday, February 10, 2015 12:46 AM
 To: Alan Stern
 Cc: Krzysztof Opasiak; Peter Chen; linux-usb@vger.kernel.org;
 linux-ker...@vger.kernel.org; Balbi, Felipe;
 gre...@linuxfoundation.org; Andrzej Pietrasiewicz
 Subject: Re: [PATCH 1/2] usb: gadget: udc-core: independent
 registration of gadgets and gadget drivers

 Hi guys,

 On Mon, Feb 9, 2015 at 10:00 PM, Alan Stern
 st...@rowland.harvard.edu wrote:
  On Mon, 9 Feb 2015, Krzysztof Opasiak wrote:
 
   Why bother matching by name?  Why not simply take the first
   available
   UDC?
 
  Because you may have more than one udc. This would allow to pick
 one by
  name just like using configfs interface.
 
  Clearly it would be more flexible to allow the user to do the
 matching,
  the way configfs does (sysfs too).
 
Main feature of my path is not only deferred binding of
 gadget
   driver,
but also possibility to register/unregister udc at any time.
This is useful for user who can load, for example, udc
 module
if needed and unload it safely, not touching gadget driver.
  
   We can already do that with the existing code.  There's no
 need for
   a
   patch.
  
   Also, it's not clear that the existing gadget drivers will
 work
   properly if they are unbound from one UDC and then bound again
 to
   another one.  They were not written with that sort of thing in
   mind.
  
 
  What you have described is one of basics configfs features.
  You should be able to bind and unbind your gadget whenever you
 want
  and it should work properly after doing:
 
  ## create gadget
  $ echo udc.0  UDC
  $ echo   UDC
  $ echo udc.1  UDC
 
  Function shouldn't care which udc it has been bound previously.
  Only current one is important and on each unbind each function
  should cleanup its state and prepare to be bound to another udc.
  Configfs interface doesn't prohibit this and I haven't seen any
  info about such restriction.

 Thank you Krzysztof for this explanation that makes things more
 clear
 for reviewers.

 
  It's not prohibited, but it also was never required.  Therefore
 it may
  not be implemented in all gadget drivers.
 
   If some function is not working in
  such situation there is a bug in that function and it should be
 fixed.
 
  That's fine.  I wasn't pointing out a fundamental limitation,
 just a
  fact that will have to be taken into account.

 I also don't see any restrictions to bind/unbind gadget driver few
 times
 and in case of such bug we just can fix it. I didn't see any issue
 with
 gadget drivers that I used for verification, however, to be honest,
 I didn't
 test it with all possible ones.
 Anyway, it should work in legacy way (one gadget driver is bound to
 one uds)
 so current behavior at least is not broken.

 
  Anyway, instead of going through all this, why not do what I
 suggested
  earlier (see http://marc.info/?l=linux-usbm=139888691230119w=2)
 and
  create a gadget bus type?  That would give userspace explicit
 control
  over which gadget driver was bound to which UDC.

 Exactly, my patch transforms udc-core to something like tiny bus
 with very basic
 functionality. But in mentioned mailthread I see good ideas that is
 possible to
 implement with small overhead.

 
  Or maybe that's not a very good fit with the existing code, since
 most
  gadget drivers assume they will be bound to only one UDC at a
 time.  So
  instead, why not create a sysfs interface that allows userspace
 to
  control which gadget drivers are bound to which UDCs?
 
  As I recall, the original problem people were complaining about
 was
  deferred probing.  They didn't need fancy matching; all they
 wanted was
  the ability to bind a gadget driver to a UDC some time after the
 gadget
  driver was loaded and initialized.  Something simple like Robert
  Baldyga's patch is enough to do that.

 This simplicity is also a limitation. As I mentioned before,
 sometimes it is
 needed to be able to bind/unbind gadget driver multiple times to
 different UDCs.
 A real case I faced recently is SoC with HighSpeed-only and
 SuperSpeed-only
 UDCs. SuperSpeed-only UDC can't work on USB 2.0 speeds and vice
 versa.
 The system has USB3.0 USB connector with soldered HS lines from
 mentioned HS-only and SS lines from SS-only UDCs. Each UDC has it's
 own
 device driver, so if we want to use both of them with one gadget
 driver, we
 must be able to bind/unbind it multiple times to different UDCs.
 Another one usecase is users who can unload udc drivers without
 carrying
 about gadget drivers.
 Third usecase is, for example, developers who can switch between
 dummy_hcd
 and real UDC hardware without unloading gadget driver.


 Just a stupid question. Why don't you use configfs composite gadget
 instead of legacy gadgets?

 In my opinion all things which you have described

Re: [PATCH 1/2] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-02-09 Thread Ruslan Bilovol
Hi guys,

On Mon, Feb 9, 2015 at 10:00 PM, Alan Stern st...@rowland.harvard.edu wrote:
 On Mon, 9 Feb 2015, Krzysztof Opasiak wrote:

  Why bother matching by name?  Why not simply take the first
  available
  UDC?

 Because you may have more than one udc. This would allow to pick one by
 name just like using configfs interface.

 Clearly it would be more flexible to allow the user to do the matching,
 the way configfs does (sysfs too).

   Main feature of my path is not only deferred binding of gadget
  driver,
   but also possibility to register/unregister udc at any time.
   This is useful for user who can load, for example, udc module
   if needed and unload it safely, not touching gadget driver.
 
  We can already do that with the existing code.  There's no need for
  a
  patch.
 
  Also, it's not clear that the existing gadget drivers will work
  properly if they are unbound from one UDC and then bound again to
  another one.  They were not written with that sort of thing in
  mind.
 

 What you have described is one of basics configfs features.
 You should be able to bind and unbind your gadget whenever you want
 and it should work properly after doing:

 ## create gadget
 $ echo udc.0  UDC
 $ echo   UDC
 $ echo udc.1  UDC

 Function shouldn't care which udc it has been bound previously.
 Only current one is important and on each unbind each function
 should cleanup its state and prepare to be bound to another udc.
 Configfs interface doesn't prohibit this and I haven't seen any
 info about such restriction.

Thank you Krzysztof for this explanation that makes things more clear
for reviewers.


 It's not prohibited, but it also was never required.  Therefore it may
 not be implemented in all gadget drivers.

  If some function is not working in
 such situation there is a bug in that function and it should be fixed.

 That's fine.  I wasn't pointing out a fundamental limitation, just a
 fact that will have to be taken into account.

I also don't see any restrictions to bind/unbind gadget driver few times
and in case of such bug we just can fix it. I didn't see any issue with
gadget drivers that I used for verification, however, to be honest, I didn't
test it with all possible ones.
Anyway, it should work in legacy way (one gadget driver is bound to one uds)
so current behavior at least is not broken.


 Anyway, instead of going through all this, why not do what I suggested
 earlier (see http://marc.info/?l=linux-usbm=139888691230119w=2) and
 create a gadget bus type?  That would give userspace explicit control
 over which gadget driver was bound to which UDC.

Exactly, my patch transforms udc-core to something like tiny bus with very basic
functionality. But in mentioned mailthread I see good ideas that is possible to
implement with small overhead.


 Or maybe that's not a very good fit with the existing code, since most
 gadget drivers assume they will be bound to only one UDC at a time.  So
 instead, why not create a sysfs interface that allows userspace to
 control which gadget drivers are bound to which UDCs?

 As I recall, the original problem people were complaining about was
 deferred probing.  They didn't need fancy matching; all they wanted was
 the ability to bind a gadget driver to a UDC some time after the gadget
 driver was loaded and initialized.  Something simple like Robert
 Baldyga's patch is enough to do that.

This simplicity is also a limitation. As I mentioned before, sometimes it is
needed to be able to bind/unbind gadget driver multiple times to different UDCs.
A real case I faced recently is SoC with HighSpeed-only and SuperSpeed-only
UDCs. SuperSpeed-only UDC can't work on USB 2.0 speeds and vice versa.
The system has USB3.0 USB connector with soldered HS lines from
mentioned HS-only and SS lines from SS-only UDCs. Each UDC has it's own
device driver, so if we want to use both of them with one gadget driver, we
must be able to bind/unbind it multiple times to different UDCs.
Another one usecase is users who can unload udc drivers without carrying
about gadget drivers.
Third usecase is, for example, developers who can switch between dummy_hcd
and real UDC hardware without unloading gadget driver.

I'll work on improved version and will send new patch soon...

Best regards,
Ruslan


 Alan Stern

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-02-08 Thread Ruslan Bilovol
Hi Alan,

On Thu, Jan 29, 2015 at 5:56 PM, Alan Stern st...@rowland.harvard.edu wrote:
 On Thu, 29 Jan 2015, Ruslan Bilovol wrote:

 Change behavior during registration of gadgets and
 gadget drivers in udc-core. Instead of previous
 approach when for successful probe of usb gadget driver
 at least one usb gadget should be already registered
 use another one where gadget drivers and gadgets
 can be registered in udc-core independently.

 Independent registration of gadgets and gadget drivers
 is useful for built-in into kernel gadget and gadget
 driver case - because it's possible that gadget is
 really probed only on late_init stage (due to deferred
 probe) whereas gadget driver's probe is silently failed
 on module_init stage due to no any UDC added.

 Also it is useful for modules case - now there is no
 difference what module to insert first: gadget module
 or gadget driver one.

 It's possible to do all this much more simply.  In fact, I posted a
 patch some time ago to do exactly this (but I can't find a copy of it
 anywhere).

Unfortunately I didn't find your patch.


 Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
 ---
  drivers/usb/gadget/udc/udc-core.c | 113 
 +++---
  1 file changed, 105 insertions(+), 8 deletions(-)

 diff --git a/drivers/usb/gadget/udc/udc-core.c 
 b/drivers/usb/gadget/udc/udc-core.c
 index e31d574..4c9412b 100644
 --- a/drivers/usb/gadget/udc/udc-core.c
 +++ b/drivers/usb/gadget/udc/udc-core.c
 @@ -43,13 +43,23 @@ struct usb_udc {
   struct usb_gadget_driver*driver;
   struct usb_gadget   *gadget;
   struct device   dev;
 + boolbind_by_name;
 + struct list_headlist;
 +};
 +
 +struct pending_gadget_driver {
 + struct usb_gadget_driver*driver;
 + char*udc_name;
   struct list_headlist;
  };

 You don't need all this stuff.  What's the point of keeping track of
 names?  If there are any unbound gadget drivers pending, a newly
 registered UDC should bind to the first one available.

It's because gadget driver may be bound to usb_gadget in two ways:
 - standard way - in this case any available udc will be picked up
 - by name of udc, in this case only matching udc will be picked up

Main feature of my path is not only deferred binding of gadget driver,
but also possibility to register/unregister udc at any time.
This is useful for user who can load, for example, udc module
if needed and unload it safely, not touching gadget driver.
Another example is USB device controllers that consist of pair of
HS+SS controllers, each one having its own udc driver. In this case
it's possible to switch SS/HS by registering/unregistering corresponding
udc and not touching gadget driver.

I did all of this inside of udc-core because it looks like to be best place for
udc - gadget driver housekeeping. Also it is verified on lot of combinations
of udc and gadget drivers that can be built-in or build as modules

Best regards,
Ruslan


 Just add a pending list_head into the usb_gadget_driver structure and
 forget about all the rest.  (Or try to find my patch in the mailing
 list archives somehow see if you think it needs to be changed.)

 Alan Stern

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] usb: gadget: legacy: don't use __init/__exit attributes for bind/unbind path

2015-01-28 Thread Ruslan Bilovol
Since it's possible now to do independent gadget and
gadget driver registration in udc-core, some of the
functions can't have __init/__exit attributes (almost
bind/unbind callbacks are affected)

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/legacy/acm_ms.c   |  6 +++---
 drivers/usb/gadget/legacy/audio.c|  6 +++---
 drivers/usb/gadget/legacy/cdc2.c |  6 +++---
 drivers/usb/gadget/legacy/dbgp.c |  2 +-
 drivers/usb/gadget/legacy/ether.c|  8 
 drivers/usb/gadget/legacy/gmidi.c|  6 +++---
 drivers/usb/gadget/legacy/hid.c  |  6 +++---
 drivers/usb/gadget/legacy/mass_storage.c |  4 ++--
 drivers/usb/gadget/legacy/multi.c| 16 
 drivers/usb/gadget/legacy/ncm.c  |  6 +++---
 drivers/usb/gadget/legacy/nokia.c|  6 +++---
 drivers/usb/gadget/legacy/printer.c  |  6 +++---
 drivers/usb/gadget/legacy/serial.c   |  2 +-
 drivers/usb/gadget/legacy/webcam.c   |  4 ++--
 drivers/usb/gadget/legacy/zero.c |  2 +-
 15 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/usb/gadget/legacy/acm_ms.c 
b/drivers/usb/gadget/legacy/acm_ms.c
index c30b7b5..3a48aab 100644
--- a/drivers/usb/gadget/legacy/acm_ms.c
+++ b/drivers/usb/gadget/legacy/acm_ms.c
@@ -121,7 +121,7 @@ static struct usb_function *f_msg;
 /*
  * We _always_ have both ACM and mass storage functions.
  */
-static int __init acm_ms_do_config(struct usb_configuration *c)
+static int acm_ms_do_config(struct usb_configuration *c)
 {
struct fsg_opts *opts;
int status;
@@ -174,7 +174,7 @@ static struct usb_configuration acm_ms_config_driver = {
 
 /*-*/
 
-static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+static int acm_ms_bind(struct usb_composite_dev *cdev)
 {
struct usb_gadget   *gadget = cdev-gadget;
struct fsg_opts *opts;
@@ -249,7 +249,7 @@ fail_get_msg:
return status;
 }
 
-static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
+static int acm_ms_unbind(struct usb_composite_dev *cdev)
 {
usb_put_function(f_msg);
usb_put_function_instance(fi_msg);
diff --git a/drivers/usb/gadget/legacy/audio.c 
b/drivers/usb/gadget/legacy/audio.c
index f46a395..ba95518 100644
--- a/drivers/usb/gadget/legacy/audio.c
+++ b/drivers/usb/gadget/legacy/audio.c
@@ -167,7 +167,7 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 /*-*/
 
-static int __init audio_do_config(struct usb_configuration *c)
+static int audio_do_config(struct usb_configuration *c)
 {
int status;
 
@@ -216,7 +216,7 @@ static struct usb_configuration audio_config_driver = {
 
 /*-*/
 
-static int __init audio_bind(struct usb_composite_dev *cdev)
+static int audio_bind(struct usb_composite_dev *cdev)
 {
 #ifndef CONFIG_GADGET_UAC1
struct f_uac2_opts  *uac2_opts;
@@ -276,7 +276,7 @@ fail:
return status;
 }
 
-static int __exit audio_unbind(struct usb_composite_dev *cdev)
+static int audio_unbind(struct usb_composite_dev *cdev)
 {
 #ifdef CONFIG_GADGET_UAC1
if (!IS_ERR_OR_NULL(f_uac1))
diff --git a/drivers/usb/gadget/legacy/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c
index 2e85d94..8d1985c 100644
--- a/drivers/usb/gadget/legacy/cdc2.c
+++ b/drivers/usb/gadget/legacy/cdc2.c
@@ -104,7 +104,7 @@ static struct usb_function_instance *fi_ecm;
 /*
  * We _always_ have both CDC ECM and CDC ACM functions.
  */
-static int __init cdc_do_config(struct usb_configuration *c)
+static int cdc_do_config(struct usb_configuration *c)
 {
int status;
 
@@ -153,7 +153,7 @@ static struct usb_configuration cdc_config_driver = {
 
 /*-*/
 
-static int __init cdc_bind(struct usb_composite_dev *cdev)
+static int cdc_bind(struct usb_composite_dev *cdev)
 {
struct usb_gadget   *gadget = cdev-gadget;
struct f_ecm_opts   *ecm_opts;
@@ -211,7 +211,7 @@ fail:
return status;
 }
 
-static int __exit cdc_unbind(struct usb_composite_dev *cdev)
+static int cdc_unbind(struct usb_composite_dev *cdev)
 {
usb_put_function(f_acm);
usb_put_function_instance(fi_serial);
diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c
index 633683a..7c42b01 100644
--- a/drivers/usb/gadget/legacy/dbgp.c
+++ b/drivers/usb/gadget/legacy/dbgp.c
@@ -284,7 +284,7 @@ fail_1:
return -ENODEV;
 }
 
-static int __init dbgp_bind(struct usb_gadget *gadget,
+static int dbgp_bind(struct usb_gadget *gadget,
struct usb_gadget_driver *driver)
 {
int err, stp;
diff --git a/drivers/usb/gadget/legacy/ether.c 
b/drivers/usb/gadget/legacy/ether.c
index c5fdc61..4283969 100644
--- a/drivers/usb

[PATCH 1/2] usb: gadget: udc-core: independent registration of gadgets and gadget drivers

2015-01-28 Thread Ruslan Bilovol
Change behavior during registration of gadgets and
gadget drivers in udc-core. Instead of previous
approach when for successful probe of usb gadget driver
at least one usb gadget should be already registered
use another one where gadget drivers and gadgets
can be registered in udc-core independently.

Independent registration of gadgets and gadget drivers
is useful for built-in into kernel gadget and gadget
driver case - because it's possible that gadget is
really probed only on late_init stage (due to deferred
probe) whereas gadget driver's probe is silently failed
on module_init stage due to no any UDC added.

Also it is useful for modules case - now there is no
difference what module to insert first: gadget module
or gadget driver one.

Signed-off-by: Ruslan Bilovol ruslan.bilo...@gmail.com
---
 drivers/usb/gadget/udc/udc-core.c | 113 +++---
 1 file changed, 105 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index e31d574..4c9412b 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -43,13 +43,23 @@ struct usb_udc {
struct usb_gadget_driver*driver;
struct usb_gadget   *gadget;
struct device   dev;
+   boolbind_by_name;
+   struct list_headlist;
+};
+
+struct pending_gadget_driver {
+   struct usb_gadget_driver*driver;
+   char*udc_name;
struct list_headlist;
 };
 
 static struct class *udc_class;
 static LIST_HEAD(udc_list);
+static LIST_HEAD(gadget_driver_pending_list);
 static DEFINE_MUTEX(udc_lock);
 
+static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver 
*driver,
+   bool 
bind_by_name);
 /* - */
 
 #ifdef CONFIG_HAS_DMA
@@ -244,6 +254,7 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
 {
struct usb_udc  *udc;
int ret = -ENOMEM;
+   struct pending_gadget_driver *pending;
 
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
if (!udc)
@@ -288,6 +299,24 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
 
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
 
+   if (!list_empty(gadget_driver_pending_list)) {
+   pending = list_first_entry(gadget_driver_pending_list,
+   struct pending_gadget_driver, list);
+
+   if (pending-udc_name) {
+   if (!strcmp(pending-udc_name, dev_name(udc-dev))) {
+   udc_bind_to_driver(udc, pending-driver, true);
+   list_del(pending-list);
+   kfree(pending-udc_name);
+   kfree(pending);
+   }
+   } else {
+   udc_bind_to_driver(udc, pending-driver, false);
+   list_del(pending-list);
+   kfree(pending);
+   }
+   }
+
mutex_unlock(udc_lock);
 
return 0;
@@ -364,10 +393,32 @@ found:
dev_vdbg(gadget-dev.parent, unregistering gadget\n);
 
list_del(udc-list);
-   mutex_unlock(udc_lock);
 
-   if (udc-driver)
+   if (udc-driver) {
+   struct pending_gadget_driver *pending;
+
+   pending = kzalloc(sizeof(*pending), GFP_KERNEL);
+   if (!pending)
+   goto err;
+
+   if (udc-bind_by_name) {
+   pending-udc_name = kstrdup(dev_name(udc-dev),
+   GFP_KERNEL);
+   if (!pending-udc_name) {
+   kfree(pending);
+   goto err;
+   }
+   }
+
+   pending-driver = udc-driver;
+   list_add_tail(pending-list, gadget_driver_pending_list);
+
+   pr_info(udc-core: added [%s] to list of pending drivers\n,
+   pending-driver-function);
+err:
usb_gadget_remove_driver(udc);
+   }
+   mutex_unlock(udc_lock);
 
kobject_uevent(udc-dev.kobj, KOBJ_REMOVE);
flush_work(gadget-work);
@@ -378,7 +429,8 @@ EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
 
 /* - */
 
-static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver 
*driver)
+static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver 
*driver,
+   bool 
bind_by_name)
 {
int ret

[PATCH 0/2] usb/gadget: independent registration of gadgets and gadget

2015-01-28 Thread Ruslan Bilovol
This patchset adds independent registration of gadgets
and gadget drivers to udc-core. This is very useful for
built-in modules into kernel case since it's possible
situation that gadget driver is probing at a time
when no gadgets are registered in udc-core.
In this case instead of silently failing without
of any attempt to recover, with independent registration
of gadgets and gadget drivers there is no matter
in which order gadgets and gadget drivers are
probed/registered.
Also it's possible to add/remove gadgets or gadget
drivers many times since it's now correctly handled
by the udc-core

This patch has side-effect on gadget drivers that had
__init/__exit attributes on some paths like bind/unbind
and (since bind/unbind may happen at any time) should
not use them now. This is covered by second patch
(please let me know if I need to break it into separate
patches for each gadget driver)

Ruslan Bilovol (2):
  usb: gadget: udc-core: independent registration of gadgets and gadget
drivers
  usb: gadget: legacy: don't use __init/__exit attributes for
bind/unbind path

 drivers/usb/gadget/legacy/acm_ms.c   |   6 +-
 drivers/usb/gadget/legacy/audio.c|   6 +-
 drivers/usb/gadget/legacy/cdc2.c |   6 +-
 drivers/usb/gadget/legacy/dbgp.c |   2 +-
 drivers/usb/gadget/legacy/ether.c|   8 +--
 drivers/usb/gadget/legacy/gmidi.c|   6 +-
 drivers/usb/gadget/legacy/hid.c  |   6 +-
 drivers/usb/gadget/legacy/mass_storage.c |   4 +-
 drivers/usb/gadget/legacy/multi.c|  16 ++---
 drivers/usb/gadget/legacy/ncm.c  |   6 +-
 drivers/usb/gadget/legacy/nokia.c|   6 +-
 drivers/usb/gadget/legacy/printer.c  |   6 +-
 drivers/usb/gadget/legacy/serial.c   |   2 +-
 drivers/usb/gadget/legacy/webcam.c   |   4 +-
 drivers/usb/gadget/legacy/zero.c |   2 +-
 drivers/usb/gadget/udc/udc-core.c| 112 ---
 16 files changed, 147 insertions(+), 51 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: usb media detection issue on USB_MUSB_HDRC on kernel 3.17

2014-10-29 Thread Ruslan Bilovol
Hi Enric

On Wed, Oct 29, 2014 at 1:44 PM, Enric Balletbo Serra
eballe...@gmail.com wrote:

 Hi all,

 2014-10-26 10:10 GMT+01:00 Angelo Dureghello angel...@gmail.com:
  Had some progresses:
 
  on kernel 3.17, musb controller driver is set to start as OTG mode as
  default. So as first thing, since my board has ID pin shorted to ground, i
  changed the default mode to MUSB_HOST., as it was on kernel 3.5.1
 
  So with same settings of 3.5.1 now key is detected correctly at first
  insertion, but after a removal, the stick is not detected anymore.
 
  Issue seems visible in drivers/usb/musb/da8xx.c, inside irqreturn_t
  da8xx_musb_interrupt() routine.
 
  looking the /sys fs, i see that the mode moves in time order as:
 
  |boot:   vbus off  b_idle||
  boot:   vbus off  a_wait_vrise||
  insertion:  vbus off  a_host|
  removal:vbus off  b_idle
 
  After last b_host, the state never moves back to a_wait_vrise.
 
  After the removal, the interrupt call irqreturn_t da8xx_musb_interrupt()
  seems broken and seems never called anymore.
 
  Regards.
 

 I'll add more information to this thread.

 Seems MUSB is also broken on OMAP3 boards, booting in OTG mode I'm not
 able to make it work when a pendrive is connected to the port. Forcing
 HOST mode I get following messages:

 [   13.244567] usb 2-1: new high-speed USB device number 2 using musb-hdrc
 [   13.503234] usb 2-1: device v058f p6387 is not supported
 [   13.592346] usb usb2-port1: unable to enumerate USB device

You need to disable CONFIG_USB_OTG_WHITELIST option to avoid this.
Or add your device to white list of supported devices.

Best regards,
Ruslan

 OTOH the OTG port as gadget works.

 Regards,
Enric
 --
 To unsubscribe from this list: send the line unsubscribe linux-usb in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html




-- 
Best regards,
Ruslan Bilvol
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: omap4 ehci sporadic resume issue

2013-06-27 Thread Ruslan Bilovol
Hello guys,

On Thu, Jun 27, 2013 at 8:56 PM, Michael Trimarchi
mich...@amarulasolutions.com wrote:
 Hi Roger

 On Thu, Jun 27, 2013 at 05:49:41PM +0300, Roger Quadros wrote:
 +Ruslan

 On 06/27/2013 05:17 PM, Michael Trimarchi wrote:
  Hi Roger
 
  On Thu, Jun 27, 2013 at 04:59:38PM +0300, Roger Quadros wrote:
  Hi Michael,
 
  On 06/27/2013 02:51 PM, Michael Trimarchi wrote:
  Hi
 
  I'm working on omap4460 with two ulpi connected to (SMSC3320 - HUB 
  SMSC2514) or (TUSB1210 - HUB SMSC2514).
  The problem only happen when both port are used and after few suspend 
  resume are triggered.
  If I use just one port there is no issue on suspend resume. I already 
  covered all TI
  errata that I know and I'm working on TI kernel.
 
  The problem is here
 
  [   77.701934] ehci-omap ehci-omap.0: irq status a004 Async Recl PCD
 
  Both ports change status from 001005 to 001009 (you have a log just 
  after).
  So from host point of view both hub connected are not working in HS mode.
  After that the omap ehci has gone because the bus can not work in FS and 
  LS and I can not recover from here.
  Status of transceivers are dumped and they are ok after resume.
 
  Do you have any suggestion?
 
  I'm not very sure but both ports suddenly changing state like that look 
  like
  a hardware issue. Also, it is strange that you can reproduce it only when 
  two
  ports are simultaneously in use. Unfortunately, I can't match your setup 
  with 2 ULPI
 
  Yes I know that TI doesn't have any setup like that.
 
  ports.
 
  I have a OMAP5 uEVM that uses 2 ports but it won't be identical to your 
  setup as
  they are on HSIC and not ULPI.
 
  Did you try errata i693?
 
  Yes I have it. It's not clear if I need to wait after
  ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
  polling the suspendM of the SMSC or the suspend status of the PORT or I can
  switch just after this instruction. Because TI kernel use an msleep of 4 
  mseconds and then switch. It could be a timing issue on how errata is 
  implemented when I have two ports? How this internal count works?


 The OMAP EHCI controller transparently sets the suspendM bit of the PHY when 
 you
 set the PORT_SUSPEND feature on the EHCI port. So you don't need to poll for 
 anything.


 A delay is necessary. If we apply the errata to the port before a delay the 
 errata
 doesn't work.

 /* Use internal 60Mhz clock ULPIBx */
 temp_reg = omap_readl(L3INIT_HSUSBHOST_CLKCTRL);
 temp_reg |= 1  (8 + port);
 temp_reg = ~(1  (24 + port));
 omap_writel(temp_reg, L3INIT_HSUSBHOST_CLKCTRL);

 /* Wait 2ms to have transceiver transaction */
 mdelay(2);

 /* Use external clock ULPIBx */
 temp_reg = ~(1  (8 + port));
 temp_reg |= 1  (24 + port);
 omap_writel(temp_reg, L3INIT_HSUSBHOST_CLKCTRL);

 Now it's not clear to me what happen if I apply this clock too early 
 (transeceiver still
 driver the clock) or too late. Any clue?

We need to wait 3ms for entire USB bus to go into suspend after
setting the PORT_SUSPEND bit. During this time, internal OMAP EHCI logic
will communicate with PHY so it is not safe to switch the clocks to
internal source.
That's why with 2ms delay it fails. 4ms delay (3ms + 1ms for safety)
is enough here
and is successfully used last few years for production devices.

-- 
Best regards,
Ruslan Bilvol



 What the errata says is that once software sets the PORT_SUSPEND feature, 
 the PHY will
 got into suspend and cut the PHY clock sooner than required for the EHCI 
 controller to
 complete its suspend operations. (NOTE: this is only applicable when the PHY 
 is providing the
 ulpi_clk).


 Yes this is the case

 What the workaround does is to just wait for a while (don't know why 4ms), 
 and remux the
 ulpi_clock to an internal 60MHz clock for a while so that it can complete 
 its suspend operations.

 What happen if I apply a big delay after PORT_SUSPEND. Will the internal 
 state machine of the omap
 continue to wait the clock?

 Michael


 
  First time is 18, and then?
 
 I think it is 18 for every port suspend.

 
  Also, are you suspending and resuming only the USB or the entire system?
 
 
  Whole system. Right the only susbsytem that doens't go to suspend is the 
  FSUSB
  but this depends on the bootloader.

 OK.

 cheers,
 -roger
 --
 To unsubscribe from this list: send the line unsubscribe linux-usb in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: omap4 ehci sporadic resume issue

2013-06-27 Thread Ruslan Bilovol
On Thu, Jun 27, 2013 at 10:24 PM, Michael Trimarchi
mich...@amarulasolutions.com wrote:
 Hi

 On Thu, Jun 27, 2013 at 09:59:35PM +0300, Ruslan Bilovol wrote:
 Hello guys,

 On Thu, Jun 27, 2013 at 8:56 PM, Michael Trimarchi
 mich...@amarulasolutions.com wrote:
  Hi Roger
 
  On Thu, Jun 27, 2013 at 05:49:41PM +0300, Roger Quadros wrote:
  +Ruslan
 
  On 06/27/2013 05:17 PM, Michael Trimarchi wrote:
   Hi Roger
  
   On Thu, Jun 27, 2013 at 04:59:38PM +0300, Roger Quadros wrote:
   Hi Michael,
  
   On 06/27/2013 02:51 PM, Michael Trimarchi wrote:
   Hi
  
   I'm working on omap4460 with two ulpi connected to (SMSC3320 - HUB 
   SMSC2514) or (TUSB1210 - HUB SMSC2514).
   The problem only happen when both port are used and after few suspend 
   resume are triggered.
   If I use just one port there is no issue on suspend resume. I already 
   covered all TI
   errata that I know and I'm working on TI kernel.
  
   The problem is here
  
   [   77.701934] ehci-omap ehci-omap.0: irq status a004 Async Recl PCD
  
   Both ports change status from 001005 to 001009 (you have a log just 
   after).
   So from host point of view both hub connected are not working in HS 
   mode.
   After that the omap ehci has gone because the bus can not work in FS 
   and LS and I can not recover from here.
   Status of transceivers are dumped and they are ok after resume.
  
   Do you have any suggestion?
  
   I'm not very sure but both ports suddenly changing state like that 
   look like
   a hardware issue. Also, it is strange that you can reproduce it only 
   when two
   ports are simultaneously in use. Unfortunately, I can't match your 
   setup with 2 ULPI
  
   Yes I know that TI doesn't have any setup like that.
  
   ports.
  
   I have a OMAP5 uEVM that uses 2 ports but it won't be identical to 
   your setup as
   they are on HSIC and not ULPI.
  
   Did you try errata i693?
  
   Yes I have it. It's not clear if I need to wait after
   ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
   polling the suspendM of the SMSC or the suspend status of the PORT or I 
   can
   switch just after this instruction. Because TI kernel use an msleep of 
   4 mseconds and then switch. It could be a timing issue on how errata is 
   implemented when I have two ports? How this internal count works?
 
 
  The OMAP EHCI controller transparently sets the suspendM bit of the PHY 
  when you
  set the PORT_SUSPEND feature on the EHCI port. So you don't need to poll 
  for anything.
 
 
  A delay is necessary. If we apply the errata to the port before a delay 
  the errata
  doesn't work.
 
  /* Use internal 60Mhz clock ULPIBx */
  temp_reg = omap_readl(L3INIT_HSUSBHOST_CLKCTRL);
  temp_reg |= 1  (8 + port);
  temp_reg = ~(1  (24 + port));
  omap_writel(temp_reg, L3INIT_HSUSBHOST_CLKCTRL);
 
  /* Wait 2ms to have transceiver transaction */
  mdelay(2);
 
  /* Use external clock ULPIBx */
  temp_reg = ~(1  (8 + port));
  temp_reg |= 1  (24 + port);
  omap_writel(temp_reg, L3INIT_HSUSBHOST_CLKCTRL);
 
  Now it's not clear to me what happen if I apply this clock too early 
  (transeceiver still
  driver the clock) or too late. Any clue?

 We need to wait 3ms for entire USB bus to go into suspend after
 setting the PORT_SUSPEND bit. During this time, internal OMAP EHCI logic
 will communicate with PHY so it is not safe to switch the clocks to
 internal source.
 That's why with 2ms delay it fails. 4ms delay (3ms + 1ms for safety)
 is enough here
 and is successfully used last few years for production devices.

 Well this mdelay is the switch of the clock and not the delay after
 PORT_SUSPEND. So after writing PORT_SUSPEND I need to wait
 4ms and then in 2ms you have a lot of clock to reach the 18 count. Correct?

Yes, sorry for confusing :)
Moreover, 2ms is more than enough, errata document says about 1ms delay
(and probably may be decreased up to few useconds)


 Anyway I understand, but why both hub connected to the smsc3320 move from
 HS to FS? So it's not important if there is a drift of delay but it must
 be = 4ms. Correct?

 The code works if I just use one port or remove one hub ;)

 Now the code is like this:

 temp = ~(PORT_WKCONN_E | PORT_RWC_BITS);
 temp |= PORT_WKDISC_E | PORT_WKOC_E;
 ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);

 mdelay(4);
 omap_ehci_erratum_i693(ehci, ((wIndex  0xff) - 1));

 The code of the function is up on this email.

Do you have locks around this software workaround?
The patch I did against 3.4 linux kernel may be helpful for
you in such case: http://review.omapzoom.org/28515
Another patch extends this WA for all OMAP4 SoCs:
http://review.omapzoom.org/31108

Regards
Ruslan


 Michael


 --
 Best regards,
 Ruslan Bilvol

 
 
  What the errata says is that once software sets the PORT_SUSPEND feature, 
  the PHY will
  got into suspend and cut the PHY clock sooner than required for the EHCI 
  controller to
  complete its suspend operations. (NOTE: this is only applicable when the 
  PHY is providing

Re: musb throughput issues

2013-05-13 Thread Ruslan Bilovol
Hi Frederik,

On Fri, May 10, 2013 at 2:22 PM, Frederik Schmid
frederik.sch...@rubico.se wrote:
 Hi Ruslan,

 Thanks for the tips! A few comments below:

 On Friday 10 May 2013 13.54.53 Ruslan Bilovol wrote:
 Hello Frederic,

 On Fri, May 10, 2013 at 12:54 PM, Frederik Schmid

 frederik.sch...@rubico.se wrote:
  Well, my conclusion is that this setup, IDS-camera + musb, is horribly
  sensitive to interrupt latency.
 
  If the musb-interrupt is blocked for ~100us the pipe is stalled. Most of
  the interrupts on my target were routed to CPU0 while CPU1 had few.
 
  When I re-route the musb interrupts to CPU1 throughput increases to
  ~120Mbps but I've only reduced the probability of the interrupt being
  blocked.
 If you want to increase throughput over musb on omap4, usually next steps
 help: - route musb IRQ to another CPU if possible

 Done that.

 - check if musb uses DMA mode (not PIO)

 It does.

 - check if the data (urb) passed to musb is aligned, if not - apply next
 patch:
 https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=
 8408fd1d83e39bf856d31a36b70bcc53527702fd - play with double packet buffering

 Didn't check but I applied your patch anyway. Doesn't seem to make any
 difference.

 - increase OPP - this will reduce latency

 I'm not sure what this means. Something to do with power management? Is there
 something specific I could try?

yes. here is some documentation about it:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/power/opp.txt

Regards,
Ruslan



 But I can say that on OMAP4 throughput over musb will be lower than
 over ehci controller because
 ehci one does many things in HW whereas musb have to do some of them in SW.
 My scores for musb were ~145 Mbits/s for bulk transfers, but they
 probably may be increased after additional tuning.

  The only hope this application has is if MODE1 in the controller could
  alleviate latency dependence but MODE1 seems quite broken in the hardware?
 
  musb_host.c:
 
  /* Disadvantage of using mode 1:
   *  It's basically usable only for mass storage class; essentially all
   *  other protocols also terminate transfers on short packets.
   * ...
   */
 
  Best regards,
  Frederik
 
  On Friday 10 May 2013 07.26.35 Frederik Schmid wrote:
  Hi Greg,
 
  The kernel is based on 3.4.11 from omapzoom.org (ti-ubuntu-3.4-1487) with
  Variscite BSP patches from:
 
  http://www.variwiki.com/index.php?title=VAR-SOM-OM44_-_Ubuntu_Precise
 
  I was expecting 200-250Mbps which is entirly possible on the same chip
  using its ehci-controller. musb seems to sustain this speed also, for
  most of the time, until a glitch like the one in the screenshot stalls
  the pipe.
 
  We don't want to use the ehci-controller because it's already bogged down
  with an ethernet controller.
 
  Regards,
  Frederik
 
  On Thursday 09 May 2013 08.12.47 Greg KH wrote:
   On Thu, May 09, 2013 at 10:44:05AM +0200, Frederik Schmid wrote:
Hi,
   
I'm developing a camera application on a TI OMAP4460. I have a cmos
usb-camera from IDS (UI-1551-LE-C-HQ) connected to the OTG-port (musb
as
host) on the OMAP.
   
I get very poor frame rates with this setup reliably. The throughput
rate
is ~50-70Mbps. (1600x1200,8bpp,3-5fps)
   
I uploaded a screenshot of a packet trace here:
   
http://i.imgur.com/26XL23T.png
   
The host seems to keep up with the camera most of the time but
occasionally
some kind of glitch causes the host to lag behind and the camera
signals
STALL because of buffer overrun.
  
   What kernel version are you using?  And what data rate do you expect to
   be getting with this hardware configuration?
  
   thanks,
  
   greg k-h
 
  --
  To unsubscribe from this list: send the line unsubscribe linux-usb in
  the body of a message to majord...@vger.kernel.org
  More majordomo info at  http://vger.kernel.org/majordomo-info.html
 
  --
  To unsubscribe from this list: send the line unsubscribe linux-usb in
  the body of a message to majord...@vger.kernel.org
  More majordomo info at  http://vger.kernel.org/majordomo-info.html
 --
 To unsubscribe from this list: send the line unsubscribe linux-usb in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: musb throughput issues

2013-05-10 Thread Ruslan Bilovol
Hello Frederic,

On Fri, May 10, 2013 at 12:54 PM, Frederik Schmid
frederik.sch...@rubico.se wrote:
 Well, my conclusion is that this setup, IDS-camera + musb, is horribly
 sensitive to interrupt latency.

 If the musb-interrupt is blocked for ~100us the pipe is stalled. Most of the
 interrupts on my target were routed to CPU0 while CPU1 had few.

 When I re-route the musb interrupts to CPU1 throughput increases to ~120Mbps
 but I've only reduced the probability of the interrupt being blocked.

If you want to increase throughput over musb on omap4, usually next steps help:
- route musb IRQ to another CPU if possible
- check if musb uses DMA mode (not PIO)
- check if the data (urb) passed to musb is aligned, if not - apply next patch:
  
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8408fd1d83e39bf856d31a36b70bcc53527702fd
- play with double packet buffering
- increase OPP - this will reduce latency

But I can say that on OMAP4 throughput over musb will be lower than
over ehci controller because
ehci one does many things in HW whereas musb have to do some of them in SW.
My scores for musb were ~145 Mbits/s for bulk transfers, but they
probably may be increased after additional tuning.


 The only hope this application has is if MODE1 in the controller could
 alleviate latency dependence but MODE1 seems quite broken in the hardware?

 musb_host.c:

 /* Disadvantage of using mode 1:
  *  It's basically usable only for mass storage class; essentially all
  *  other protocols also terminate transfers on short packets.
  * ...
  */

 Best regards,
 Frederik

 On Friday 10 May 2013 07.26.35 Frederik Schmid wrote:
 Hi Greg,

 The kernel is based on 3.4.11 from omapzoom.org (ti-ubuntu-3.4-1487) with
 Variscite BSP patches from:

 http://www.variwiki.com/index.php?title=VAR-SOM-OM44_-_Ubuntu_Precise

 I was expecting 200-250Mbps which is entirly possible on the same chip using
 its ehci-controller. musb seems to sustain this speed also, for most of the
 time, until a glitch like the one in the screenshot stalls the pipe.

 We don't want to use the ehci-controller because it's already bogged down
 with an ethernet controller.

 Regards,
 Frederik

 On Thursday 09 May 2013 08.12.47 Greg KH wrote:
  On Thu, May 09, 2013 at 10:44:05AM +0200, Frederik Schmid wrote:
   Hi,
  
   I'm developing a camera application on a TI OMAP4460. I have a cmos
   usb-camera from IDS (UI-1551-LE-C-HQ) connected to the OTG-port (musb as
   host) on the OMAP.
  
   I get very poor frame rates with this setup reliably. The throughput
   rate
   is ~50-70Mbps. (1600x1200,8bpp,3-5fps)
  
   I uploaded a screenshot of a packet trace here:
  
   http://i.imgur.com/26XL23T.png
  
   The host seems to keep up with the camera most of the time but
   occasionally
   some kind of glitch causes the host to lag behind and the camera
   signals
   STALL because of buffer overrun.
 
  What kernel version are you using?  And what data rate do you expect to
  be getting with this hardware configuration?
 
  thanks,
 
  greg k-h

 --
 To unsubscribe from this list: send the line unsubscribe linux-usb in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 --
 To unsubscribe from this list: send the line unsubscribe linux-usb in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Best regards,
Ruslan Bilvol
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: musb: gadget: fix enumeration on heavy-loaded systems

2013-04-17 Thread Ruslan Bilovol
Hi Ravi,

On Tue, Apr 16, 2013 at 7:57 PM, B, Ravi ravib...@ti.com wrote:
 -Original Message-
 From: linux-usb-ow...@vger.kernel.org [mailto:linux-usb-
 ow...@vger.kernel.org] On Behalf Of Bilovol, Ruslan
 Sent: Tuesday, April 16, 2013 9:12 PM
 To: Balbi, Felipe; gre...@linuxfoundation.org; linux-usb@vger.kernel.org;
 linux-ker...@vger.kernel.org
 Subject: [PATCH] usb: musb: gadget: fix enumeration on heavy-loaded
 systems

 From musb point of view, the Address Assignment sequence during
 device enumeration is next:
  - first ep0 interrupt:
   * read the address from USB_REQ_SET_ADDRESS request
   * set up CSR0L.DataEnd bit (that is ACK
 signalization for the host)
  - second ep0 interrupt:
   * indicates that the request completed successfully
   * set up musb device address
 Now musb device should answer to this address

 From the host perspective, if peripheral device acquires
 SET_ADDRESS request, it now may be accessed only using that address.
 However, on heavy loaded systems, time between first and
 second musb ep0 interrupts may be too long and musb controller
 misses requests between.

 What is meant by heavily loaded system? Is the device is heavily loaded 
 during enumeration stage? Why second ep0 interrupt is too long? whether 
 interrupt occurrence to interrupt service is taking too long?

I mean production system with aggressive power management and tens of
interrupt sources.
On such systems and in low CPU frequency case, you may meet condition
when time between
IRQ firing and ISR entering is increased in few times.

In particular case of OMAP4 where I met this issue, time between first
and second ep0 interrupt
sometimes may be up to 800-900 uS and in this case the USB30CV test fails.
If this time is 200-300 uS, the test successfully passes.

Unfortunately, this time is not predictable and depends on many factors so
this patch ensures we change the address as soon as sent ACK to the host.


 As result, device enumeration may be
 unsuccessful. This can be checked on USB3.0 Host and
 using USB3.0 test suite (from usb.org) running ch9 tests
 for USB2.0 devices.

 You mean the usb2.0 musb controller (in device mode) connected to USB3.0 host?

Correct. USB2.0 musb controller in device mode, connected to USB3.0
host that runs
USB30CV utility for USB2.0 devices


 Usually 'Addressed state/TD9.1: Device Descriptor Test' will fail

 The fix consists in checking CSR0L.DataEnd state and assigning
 the device address in the first ep0 interrupt handling, so
 delay is as minimal as possible

 Signed-off-by: Ruslan Bilovol ruslan.bilo...@ti.com
 ---
  drivers/usb/musb/musb_gadget_ep0.c |   31 +++
  1 file changed, 31 insertions(+)

 diff --git a/drivers/usb/musb/musb_gadget_ep0.c
 b/drivers/usb/musb/musb_gadget_ep0.c
 index c9c1ac4..59bc5a5 100644
 --- a/drivers/usb/musb/musb_gadget_ep0.c
 +++ b/drivers/usb/musb/musb_gadget_ep0.c
 @@ -885,6 +885,37 @@ stall:
  finish:
   musb_writew(regs, MUSB_CSR0,
   musb-ackpend);
 +
 + /*
 +  * If we are at end of SET_ADDRESS sequence,
 +  * update the address immediately if possible,
 +  * otherwise we may miss packets between
 +  * sending ACK from musb side and musb's next
 +  * interrupt handler firing (in which we update
 +  * the address). At least this fixes next
 +  * USB2.0 ch9 test of USB30CV utility:
 +  * Addressed state - Device Descriptor test
 +  */
 + if (musb-set_address  (musb-ackpend 
 + MUSB_CSR0_P_DATAEND) 
 + (musb-ep0_state ==
 + MUSB_EP0_STAGE_STATUSIN)) {
 + u16 ack_delay = 500;
 +
 + while ((musb_readw(regs, MUSB_CSR0) 
 + MUSB_CSR0_P_DATAEND) 
 + --ack_delay) {
 + cpu_relax();
 + udelay(1);
 + }
 +
 + if (ack_delay) {
 + musb-set_address = false;
 + musb_writeb(mbase, MUSB_FADDR,
 + musb-address);
 + }
 + }
 +
   musb-ackpend = 0;
   }
   }

 --
 Ravi B

Re: [PATCH] usb: musb: gadget: fix enumeration on heavy-loaded systems

2013-04-17 Thread Ruslan Bilovol
On Wed, Apr 17, 2013 at 3:07 PM, B, Ravi ravib...@ti.com wrote:
 Ruslan

  Subject: [PATCH] usb: musb: gadget: fix enumeration on heavy-loaded
  systems
 
  From musb point of view, the Address Assignment sequence during
  device enumeration is next:
   - first ep0 interrupt:
* read the address from USB_REQ_SET_ADDRESS request
* set up CSR0L.DataEnd bit (that is ACK
  signalization for the host)
   - second ep0 interrupt:
* indicates that the request completed successfully
* set up musb device address
  Now musb device should answer to this address
 
  From the host perspective, if peripheral device acquires
  SET_ADDRESS request, it now may be accessed only using that address.
  However, on heavy loaded systems, time between first and
  second musb ep0 interrupts may be too long and musb controller
  misses requests between.
 
  What is meant by heavily loaded system? Is the device is heavily loaded
 during enumeration stage? Why second ep0 interrupt is too long? whether
 interrupt occurrence to interrupt service is taking too long?

 I mean production system with aggressive power management and tens of
 interrupt sources.
 On such systems and in low CPU frequency case, you may meet condition
 when time between
 IRQ firing and ISR entering is increased in few times.

 In particular case of OMAP4 where I met this issue, time between first
 and second ep0 interrupt
 sometimes may be up to 800-900 uS and in this case the USB30CV test fails.
 If this time is 200-300 uS, the test successfully passes.

 Unfortunately, this time is not predictable and depends on many factors so
 this patch ensures we change the address as soon as sent ACK to the host.

 
  As result, device enumeration may be
  unsuccessful. This can be checked on USB3.0 Host and
  using USB3.0 test suite (from usb.org) running ch9 tests
  for USB2.0 devices.
 
  You mean the usb2.0 musb controller (in device mode) connected to USB3.0
 host?

 Correct. USB2.0 musb controller in device mode, connected to USB3.0
 host that runs
 USB30CV utility for USB2.0 devices

 
  Usually 'Addressed state/TD9.1: Device Descriptor Test' will fail
 
  The fix consists in checking CSR0L.DataEnd state and assigning
  the device address in the first ep0 interrupt handling, so
  delay is as minimal as possible
 
  Signed-off-by: Ruslan Bilovol ruslan.bilo...@ti.com
  ---
   drivers/usb/musb/musb_gadget_ep0.c |   31
 +++
   1 file changed, 31 insertions(+)
 
  diff --git a/drivers/usb/musb/musb_gadget_ep0.c
  b/drivers/usb/musb/musb_gadget_ep0.c
  index c9c1ac4..59bc5a5 100644
  --- a/drivers/usb/musb/musb_gadget_ep0.c
  +++ b/drivers/usb/musb/musb_gadget_ep0.c
  @@ -885,6 +885,37 @@ stall:
   finish:
musb_writew(regs, MUSB_CSR0,
musb-ackpend);
  +
  + /*
  +  * If we are at end of SET_ADDRESS
 sequence,
  +  * update the address immediately if
 possible,
  +  * otherwise we may miss packets between
  +  * sending ACK from musb side and musb's
 next
  +  * interrupt handler firing (in which we
 update
  +  * the address). At least this fixes next
  +  * USB2.0 ch9 test of USB30CV utility:
  +  * Addressed state - Device Descriptor
 test
  +  */
  + if (musb-set_address  (musb-ackpend 
  +
 MUSB_CSR0_P_DATAEND) 
  + (musb-ep0_state ==
  + MUSB_EP0_STAGE_STATUSIN))
 {
  + u16 ack_delay = 500;
  +
  + while ((musb_readw(regs,
 MUSB_CSR0) 
  +
 MUSB_CSR0_P_DATAEND) 
  + --ack_delay) {
  + cpu_relax();
  + udelay(1);
  + }
  +

 No need to loop here. It is self clearing bit.

Yes, it is self-clearing bit and this is what we exactly use here. We
are waiting for this bit
self-clearing (that signalizes the end of Status Phase) or waiting for
end of our timeout (when ack_delay == 0)


  + if (ack_delay) {
  + musb-set_address =
 false;
  + musb_writeb(mbase,
 MUSB_FADDR,
  + musb-
 address);
  + }

 Setting the address before status phase could lead to dropping of status  
 packet(IN token) by controller, because the status phase is addressed to 
 device with zero address

[PATCH] usb: musb: gadget: fix enumeration on heavy-loaded systems

2013-04-16 Thread Ruslan Bilovol
From musb point of view, the Address Assignment sequence during
device enumeration is next:
 - first ep0 interrupt:
* read the address from USB_REQ_SET_ADDRESS request
* set up CSR0L.DataEnd bit (that is ACK
  signalization for the host)
 - second ep0 interrupt:
* indicates that the request completed successfully
* set up musb device address
  Now musb device should answer to this address

From the host perspective, if peripheral device acquires
SET_ADDRESS request, it now may be accessed only using that address.
However, on heavy loaded systems, time between first and
second musb ep0 interrupts may be too long and musb controller
misses requests between. As result, device enumeration may be
unsuccessful. This can be checked on USB3.0 Host and
using USB3.0 test suite (from usb.org) running ch9 tests
for USB2.0 devices.
Usually 'Addressed state/TD9.1: Device Descriptor Test' will fail

The fix consists in checking CSR0L.DataEnd state and assigning
the device address in the first ep0 interrupt handling, so
delay is as minimal as possible

Signed-off-by: Ruslan Bilovol ruslan.bilo...@ti.com
---
 drivers/usb/musb/musb_gadget_ep0.c |   31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/usb/musb/musb_gadget_ep0.c 
b/drivers/usb/musb/musb_gadget_ep0.c
index c9c1ac4..59bc5a5 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -885,6 +885,37 @@ stall:
 finish:
musb_writew(regs, MUSB_CSR0,
musb-ackpend);
+
+   /*
+* If we are at end of SET_ADDRESS sequence,
+* update the address immediately if possible,
+* otherwise we may miss packets between
+* sending ACK from musb side and musb's next
+* interrupt handler firing (in which we update
+* the address). At least this fixes next
+* USB2.0 ch9 test of USB30CV utility:
+* Addressed state - Device Descriptor test
+*/
+   if (musb-set_address  (musb-ackpend 
+   MUSB_CSR0_P_DATAEND) 
+   (musb-ep0_state ==
+   MUSB_EP0_STAGE_STATUSIN)) {
+   u16 ack_delay = 500;
+
+   while ((musb_readw(regs, MUSB_CSR0) 
+   MUSB_CSR0_P_DATAEND) 
+   --ack_delay) {
+   cpu_relax();
+   udelay(1);
+   }
+
+   if (ack_delay) {
+   musb-set_address = false;
+   musb_writeb(mbase, MUSB_FADDR,
+   musb-address);
+   }
+   }
+
musb-ackpend = 0;
}
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/1] usb: musb: improve throughput in HOST mode

2013-03-29 Thread Ruslan Bilovol
Hi guys,

This is a resend (and v3) of my patch:
http://permalink.gmane.org/gmane.linux.usb.general/67238

At this moment it has been successfully tested and
used on top of 3.0 and 3.4 kernels on omap4 devices
so it would be great to have it in upstream too.

Regards,
Ruslan

v3: Implementation has been little bit changed
to keep MUSB struct hc_driver as 'const' (as per
Felipe's comments). Verified on top of 3.9-rc4. 


Ruslan Bilovol (1):
  usb: musb: implement (un)map_urb_for_dma hooks

 drivers/usb/musb/musb_host.c |  117 ++
 1 file changed, 117 insertions(+)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/1] usb: musb: implement (un)map_urb_for_dma hooks

2013-03-29 Thread Ruslan Bilovol
MUSB controller cannot work in DMA mode with misaligned buffers,
switching in PIO mode.

HCD core has hooks that allow to override the default DMA
mapping and unmapping routines for host controllers that have
special DMA requirements, such as alignment constraints.

It is observed that work in PIO mode is slow and it's better
to align buffers properly before passing them to MUSB

This increased throughput 80-120 MBits/s over musb@omap4 with
USB Gigabit Ethernet adapter attached.

Some ideas are taken from ehci-tegra.c

Signed-off-by: Ruslan Bilovol ruslan.bilo...@ti.com
---
 drivers/usb/musb/musb_host.c |  117 ++
 1 file changed, 117 insertions(+)

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 1ce1fcf..33277c9 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2465,6 +2465,118 @@ static int musb_bus_resume(struct usb_hcd *hcd)
return 0;
 }
 
+
+#ifndef CONFIG_MUSB_PIO_ONLY
+
+#define MUSB_USB_DMA_ALIGN 4
+
+struct musb_temp_buffer {
+   void *kmalloc_ptr;
+   void *old_xfer_buffer;
+   u8 data[0];
+};
+
+static void musb_free_temp_buffer(struct urb *urb)
+{
+   enum dma_data_direction dir;
+   struct musb_temp_buffer *temp;
+
+   if (!(urb-transfer_flags  URB_ALIGNED_TEMP_BUFFER))
+   return;
+
+   dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+   temp = container_of(urb-transfer_buffer, struct musb_temp_buffer,
+   data);
+
+   if (dir == DMA_FROM_DEVICE) {
+   memcpy(temp-old_xfer_buffer, temp-data,
+  urb-transfer_buffer_length);
+   }
+   urb-transfer_buffer = temp-old_xfer_buffer;
+   kfree(temp-kmalloc_ptr);
+
+   urb-transfer_flags = ~URB_ALIGNED_TEMP_BUFFER;
+}
+
+static int musb_alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
+{
+   enum dma_data_direction dir;
+   struct musb_temp_buffer *temp;
+   void *kmalloc_ptr;
+   size_t kmalloc_size;
+
+   if (urb-num_sgs || urb-sg ||
+   urb-transfer_buffer_length == 0 ||
+   !((uintptr_t)urb-transfer_buffer  (MUSB_USB_DMA_ALIGN - 1)))
+   return 0;
+
+   dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+   /* Allocate a buffer with enough padding for alignment */
+   kmalloc_size = urb-transfer_buffer_length +
+   sizeof(struct musb_temp_buffer) + MUSB_USB_DMA_ALIGN - 1;
+
+   kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
+   if (!kmalloc_ptr)
+   return -ENOMEM;
+
+   /* Position our struct temp_buffer such that data is aligned */
+   temp = PTR_ALIGN(kmalloc_ptr, MUSB_USB_DMA_ALIGN);
+
+
+   temp-kmalloc_ptr = kmalloc_ptr;
+   temp-old_xfer_buffer = urb-transfer_buffer;
+   if (dir == DMA_TO_DEVICE)
+   memcpy(temp-data, urb-transfer_buffer,
+  urb-transfer_buffer_length);
+   urb-transfer_buffer = temp-data;
+
+   urb-transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
+
+   return 0;
+}
+
+static int musb_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags)
+{
+   struct musb *musb = hcd_to_musb(hcd);
+   int ret;
+
+   /*
+* The DMA engine in RTL1.8 and above cannot handle
+* DMA addresses that are not aligned to a 4 byte boundary.
+* For such engine implemented (un)map_urb_for_dma hooks.
+* Do not use these hooks for RTL1.8
+*/
+   if (musb-hwvers  MUSB_HWVERS_1800)
+   return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
+
+   ret = musb_alloc_temp_buffer(urb, mem_flags);
+   if (ret)
+   return ret;
+
+   ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
+   if (ret)
+   musb_free_temp_buffer(urb);
+
+   return ret;
+}
+
+static void musb_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+{
+   struct musb *musb = hcd_to_musb(hcd);
+
+   usb_hcd_unmap_urb_for_dma(hcd, urb);
+
+   /* Do not use this hook for RTL1.8 (see description above) */
+   if (musb-hwvers  MUSB_HWVERS_1800)
+   return;
+
+   musb_free_temp_buffer(urb);
+}
+#endif /* !CONFIG_MUSB_PIO_ONLY */
+
 const struct hc_driver musb_hc_driver = {
.description= musb-hcd,
.product_desc   = MUSB HDRC host driver,
@@ -2484,6 +2596,11 @@ const struct hc_driver musb_hc_driver = {
.urb_dequeue= musb_urb_dequeue,
.endpoint_disable   = musb_h_disable,
 
+#ifndef CONFIG_MUSB_PIO_ONLY
+   .map_urb_for_dma= musb_map_urb_for_dma,
+   .unmap_urb_for_dma  = musb_unmap_urb_for_dma,
+#endif
+
.hub_status_data= musb_hub_status_data,
.hub_control= musb_hub_control,
.bus_suspend= musb_bus_suspend,
-- 
1.7.9.5

--
To unsubscribe from this list

Re: [PATCH RESEND v2 1/1] usb: musb: implement (un)map_urb_for_dma hooks

2013-03-28 Thread Ruslan Bilovol
Hi Felipe,

On Wed, Mar 27, 2013 at 3:17 PM, Felipe Balbi ba...@ti.com wrote:
 Hi,

 On Thu, Mar 14, 2013 at 08:12:09PM +0200, Ruslan Bilovol wrote:
 MUSB controller cannot work in DMA mode with misaligned buffers,
 switching in PIO mode.

 HCD core has hooks that allow to override the default DMA
 mapping and unmapping routines for host controllers that have
 special DMA requirements, such as alignment contraints.

 It is observed that work in PIO mode is slow and it's better
 to align buffers properly before passing them to MUSB

 This increased throughput 80-120 MBits/s over musb@omap4 with
 USB Gigabit ethernet adapter attached.

 Some ideas taken from ehci-tegra.c

 Signed-off-by: Ruslan Bilovol ruslan.bilo...@ti.com
 ---
  drivers/usb/musb/musb_core.c |   14 ++
  drivers/usb/musb/musb_host.c |  102 
 +-
  drivers/usb/musb/musb_host.h |2 +-
  3 files changed, 116 insertions(+), 2 deletions(-)

 diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
 index 60b41cc..91ac166 100644
 --- a/drivers/usb/musb/musb_core.c
 +++ b/drivers/usb/musb/musb_core.c
 @@ -1431,6 +1431,20 @@ static int musb_core_init(u16 musb_type, struct musb 
 *musb)

   /* log release info */
   musb-hwvers = musb_read_hwvers(mbase);
 +
 +#ifndef CONFIG_MUSB_PIO_ONLY
 + /*
 +  * The DMA engine in RTL1.8 and above cannot handle
 +  * DMA addresses that are not aligned to a 4 byte boundary.
 +  * For such engine implemented (un)map_urb_for_dma hooks.
 +  * Do not use these hooks for RTL1.8
 +  */
 + if (musb-hwvers  MUSB_HWVERS_1800) {

 if you move this check to map/unmap and always return error if this is
 true, you can avoid removing 'const' from our struct hc_driver. Would
 that work ?

If we return an error in map/unmap callbacks, this will break urb transferring,
however I can call core function usb_hcd_(un)map_urb_for_dma() instead of
returning the error (and that is default behavior if we do not have
map/unmap callbacks
set for the hc driver) so I can avoid removing 'const' from our struct
hc_driver and this will work.
The side effect will be only in small overhead for this path.

So, will be this OK for you? I will send v3 in this case.

-- 
Best regards,
Ruslan Bilvol


 --
 balbi
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/1] omap usb host platform_data cleanup

2013-03-14 Thread Ruslan Bilovol
Hello guys,

This is v2 of my patch https://patchwork.kernel.org/patch/1232871/
rebased on v3.9-rc2. Removes deprecated flags and structures
and saves few bytes of memory.

Regards,
Ruslan

Ruslan Bilovol (1):
  omap: usb: host: remove deprecated flags and structures

 include/linux/platform_data/usb-omap.h |   20 
 1 file changed, 20 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/1] omap: usb: host: remove deprecated flags and structures

2013-03-14 Thread Ruslan Bilovol
These flags and structures are deprecated and there is
no anymore users of them, so it's safe to remove them.

Signed-off-by: Ruslan Bilovol ruslan.bilo...@ti.com
---
 include/linux/platform_data/usb-omap.h |   20 
 1 file changed, 20 deletions(-)

diff --git a/include/linux/platform_data/usb-omap.h 
b/include/linux/platform_data/usb-omap.h
index fa579b4..4c7acbe 100644
--- a/include/linux/platform_data/usb-omap.h
+++ b/include/linux/platform_data/usb-omap.h
@@ -38,34 +38,14 @@ enum usbhs_omap_port_mode {
OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM
 };
 
-struct usbtll_omap_platform_data {
-   enum usbhs_omap_port_mode   port_mode[OMAP3_HS_USB_PORTS];
-};
-
-struct ehci_hcd_omap_platform_data {
-   enum usbhs_omap_port_mode   port_mode[OMAP3_HS_USB_PORTS];
-   int reset_gpio_port[OMAP3_HS_USB_PORTS];
-   struct regulator*regulator[OMAP3_HS_USB_PORTS];
-   unsignedphy_reset:1;
-};
-
-struct ohci_hcd_omap_platform_data {
-   enum usbhs_omap_port_mode   port_mode[OMAP3_HS_USB_PORTS];
-   unsignedes2_compatibility:1;
-};
-
 struct usbhs_omap_platform_data {
int nports;
enum usbhs_omap_port_mode   port_mode[OMAP3_HS_USB_PORTS];
int reset_gpio_port[OMAP3_HS_USB_PORTS];
struct regulator*regulator[OMAP3_HS_USB_PORTS];
 
-   struct ehci_hcd_omap_platform_data  *ehci_data;
-   struct ohci_hcd_omap_platform_data  *ohci_data;
-
/* OMAP3 = ES2.1 have a single ulpi bypass control bit */
unsigned single_ulpi_bypass:1;
-   unsigned es2_compatibility:1;
unsigned phy_reset:1;
 };
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RESEND v2 0/1] usb: musb: improve throughput in HOST mode

2013-03-14 Thread Ruslan Bilovol
Hi guys,

This is a resend of my patch:
http://permalink.gmane.org/gmane.linux.usb.general/67238

At this moment it has been successfully tested and
used on top of 3.0 and 3.4 kernels on omap4 devices
so it would be great to have it in upstream too.

Regards,
Ruslan


Ruslan Bilovol (1):
  usb: musb: implement (un)map_urb_for_dma hooks

 drivers/usb/musb/musb_core.c |   14 ++
 drivers/usb/musb/musb_host.c |  102 +-
 drivers/usb/musb/musb_host.h |2 +-
 3 files changed, 116 insertions(+), 2 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   >