diff mbox series

[14/41] ALSA: usb-audio: Create endpoint objects at parsing phase

Message ID 20201123085347.19667-15-tiwai@suse.de (mailing list archive)
State New, archived
Headers show
Series USB audio refactoring for better implicit feedback support | expand

Commit Message

Takashi Iwai Nov. 23, 2020, 8:53 a.m. UTC
Currently snd_usb_endpoint objects are created at first when the
substream is opened and tries to assign the endpoints corresponding to
the matching audioformat.  But since basically the all endpoints have
been already parsed and the information have been obtained, we may
create the endpoint objects statically at the init phase.  It's easier
to manage for the implicit fb case, for example.

This patch changes the endpoint object management and lets the parser
to create the all endpoint objects.

This change shouldn't bring any functional changes.

Tested-by: Keith Milner <kamilner@superlative.org>
Tested-by: Dylan Robinson <dylan_robinson@motu.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/endpoint.c | 87 ++++++++++++++++++++--------------------------------
 sound/usb/endpoint.h | 10 +++---
 sound/usb/pcm.c      | 27 ++++++++--------
 sound/usb/stream.c   | 16 ++++++++++
 4 files changed, 67 insertions(+), 73 deletions(-)

Comments

František Kučera Jan. 3, 2021, 5:09 p.m. UTC | #1
Dne 23. 11. 20 v 9:53 Takashi Iwai napsal(a):
> Currently snd_usb_endpoint objects are created at first when the
> substream is opened and tries to assign the endpoints corresponding to
> the matching audioformat.  But since basically the all endpoints have
> been already parsed and the information have been obtained, we may
> create the endpoint objects statically at the init phase.  It's easier
> to manage for the implicit fb case, for example.
>
> This patch changes the endpoint object management and lets the parser
> to create the all endpoint objects.
>
> This change shouldn't bring any functional changes.

The Pioneer DJ DJM-250MK2 (implemented in 73d8c9408434, 14335d8b9e1a, cdc01a1558de) stopped working.

After bisecting, it seems that it worked in 5fd255f4fe97 and stopped working in 54cb31901b83.

The arecord says: set_params:1407: Unable to install hw params

And even playback is impossible in this version. But there is no error in the log. However in later versions (e.g. eda809aef534) I found errors in kern.log:

usb 1-3: Cannot find EP 0x1 to open

usb 1-3: Cannot find EP 0x82 to open

(each repeats 20 or more times, seems to be in pcm.c in subs->data_endpoint = snd_usb_endpoint_open(chip, fmt, hw_params, false);)

Could you please check it? I am not sure whether it should be fixed in the DJM-250MK2 specific code or here.

Thanks,

Franta
Takashi Iwai Jan. 3, 2021, 5:19 p.m. UTC | #2
On Sun, 03 Jan 2021 18:09:41 +0100,
František Kučera wrote:
> 
> Dne 23. 11. 20 v 9:53 Takashi Iwai napsal(a):
> > Currently snd_usb_endpoint objects are created at first when the
> > substream is opened and tries to assign the endpoints corresponding to
> > the matching audioformat.  But since basically the all endpoints have
> > been already parsed and the information have been obtained, we may
> > create the endpoint objects statically at the init phase.  It's easier
> > to manage for the implicit fb case, for example.
> >
> > This patch changes the endpoint object management and lets the parser
> > to create the all endpoint objects.
> >
> > This change shouldn't bring any functional changes.
> 
> The Pioneer DJ DJM-250MK2 (implemented in 73d8c9408434, 14335d8b9e1a, cdc01a1558de) stopped working.
> 
> After bisecting, it seems that it worked in 5fd255f4fe97 and stopped working in 54cb31901b83.
> 
> The arecord says: set_params:1407: Unable to install hw params
> 
> And even playback is impossible in this version. But there is no error in the log. However in later versions (e.g. eda809aef534) I found errors in kern.log:
> 
> usb 1-3: Cannot find EP 0x1 to open
> 
> usb 1-3: Cannot find EP 0x82 to open
> 
> (each repeats 20 or more times, seems to be in pcm.c in subs->data_endpoint = snd_usb_endpoint_open(chip, fmt, hw_params, false);)
> 
> Could you please check it? I am not sure whether it should be fixed in the DJM-250MK2 specific code or here.

Could you give lsusb -v output as well as /proc/asound/card*/usbmixer
and stream* files?  The proc files are at best from both older and new
kernels.


thanks,

Takashi
František Kučera Jan. 3, 2021, 6:15 p.m. UTC | #3
Dne 03. 01. 21 v 18:19 Takashi Iwai napsal(a):
> Could you give lsusb -v output as well as /proc/asound/card*/usbmixer
> and stream* files?  The proc files are at best from both older and new
> kernels.

Here are the files. They look same. The only difference is in the stream0, but it is probably only formatting. I also attached the kern.log from the new version.

When I tried to debug the new version (eda809aef534), it crashed in pcm.c in snd_usb_hw_params() on lines:

    subs->data_endpoint = snd_usb_endpoint_open(chip, fmt, hw_params, false); // error in log: usb 3-3: Cannot find EP 0x1 to open // (or 0x82)
    if (!subs->data_endpoint) {
        ret = -EINVAL;
        goto unlock; // was here
    }

Before that, it did not enter these conditional blocks:

    if (!fmt) { ... }

    if (fmt->implicit_fb) { ... }

    if (ret < 0), if (ret < 0)

    if (subs->data_endpoint) { ... }

Franta
Bus 001 Device 002: ID 2b73:0017 Pioneer DJ Corporation DJM-250MK2
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x2b73 
  idProduct          0x0017 
  bcdDevice            1.06
  iManufacturer           1 Pioneer DJ Corporation
  iProduct                2 DJM-250MK2
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x00a2
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       1
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               3
        bRefresh                0
        bSynchAddress           0
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               3
        bRefresh                0
        bSynchAddress           0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
      bInterfaceProtocol      0 
      iInterface              0 
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength       0x0009
        bInCollection           1
        baInterfaceNr(0)        2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      3 MIDI Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      MIDIStreaming Interface Descriptor:
        bLength                 7
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength       0x0041
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               1 Embedded
        bJackID                 3
        iJack                   0 
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               2 External
        bJackID                 1
        iJack                   0 
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               2 External
        bJackID                 4
        bNrInputPins            1
        baSourceID( 0)          3
        BaSourcePin( 0)         1
        iJack                   0 
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               1 Embedded
        bJackID                 2
        bNrInputPins            1
        baSourceID( 0)          1
        BaSourcePin( 0)         1
        iJack                   0 
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 5
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         1
          baAssocJackID( 0)       2
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 5
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         1
          baAssocJackID( 0)       3
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      52
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x87  EP 7 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               4
Device Status:     0x0001
  Self Powered
Bus 001 Device 002: ID 2b73:0017 Pioneer DJ Corporation DJM-250MK2
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x2b73 
  idProduct          0x0017 
  bcdDevice            1.06
  iManufacturer           1 Pioneer DJ Corporation
  iProduct                2 DJM-250MK2
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x00a2
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       1
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               3
        bRefresh                0
        bSynchAddress           0
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               3
        bRefresh                0
        bSynchAddress           0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
      bInterfaceProtocol      0 
      iInterface              0 
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength       0x0009
        bInCollection           1
        baInterfaceNr(0)        2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      3 MIDI Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      MIDIStreaming Interface Descriptor:
        bLength                 7
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength       0x0041
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               1 Embedded
        bJackID                 3
        iJack                   0 
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               2 External
        bJackID                 1
        iJack                   0 
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               2 External
        bJackID                 4
        bNrInputPins            1
        baSourceID( 0)          3
        BaSourcePin( 0)         1
        iJack                   0 
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               1 Embedded
        bJackID                 2
        bNrInputPins            1
        baSourceID( 0)          1
        BaSourcePin( 0)         1
        iJack                   0 
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 5
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         1
          baAssocJackID( 0)       2
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 5
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         1
          baAssocJackID( 0)       3
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      52
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x87  EP 7 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               4
Device Status:     0x0001
  Self Powered
Bus 001 Device 002: ID 2b73:0017 Pioneer DJ Corporation DJM-250MK2
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x2b73 
  idProduct          0x0017 
  bcdDevice            1.06
  iManufacturer           1 Pioneer DJ Corporation
  iProduct                2 DJM-250MK2
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x00a2
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       1
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               3
        bRefresh                0
        bSynchAddress           0
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               3
        bRefresh                0
        bSynchAddress           0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
      bInterfaceProtocol      0 
      iInterface              0 
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength       0x0009
        bInCollection           1
        baInterfaceNr(0)        2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      3 MIDI Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      MIDIStreaming Interface Descriptor:
        bLength                 7
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength       0x0041
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               1 Embedded
        bJackID                 3
        iJack                   0 
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               2 External
        bJackID                 1
        iJack                   0 
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               2 External
        bJackID                 4
        bNrInputPins            1
        baSourceID( 0)          3
        BaSourcePin( 0)         1
        iJack                   0 
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               1 Embedded
        bJackID                 2
        bNrInputPins            1
        baSourceID( 0)          1
        BaSourcePin( 0)         1
        iJack                   0 
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 5
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         1
          baAssocJackID( 0)       2
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 5
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         1
          baAssocJackID( 0)       3
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      52
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x87  EP 7 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               4
Device Status:     0x0001
  Self Powered
Pioneer DJ Corporation DJM-250MK2 at usb-0000:00:12.2-3, high speed : USB Audio

Playback:
  Status: Stop
  Interface 0
    Altset 1
    Format: S24_3LE
    Channels: 8
    Endpoint: 1 OUT (ASYNC)
    Rates: 48000
    Data packet interval: 500 us
    Bits: 0

Capture:
  Status: Stop
  Interface 0
    Altset 1
    Format: S24_3LE
    Channels: 8
    Endpoint: 2 IN (ASYNC)
    Rates: 48000
    Data packet interval: 500 us
    Bits: 0
Pioneer DJ Corporation DJM-250MK2 at usb-0000:00:12.2-3, high speed : USB Audio

Playback:
  Status: Stop
  Interface 0
    Altset 1
    Format: S24_3LE
    Channels: 8
    Endpoint: 1 OUT (ASYNC)
    Rates: 48000
    Data packet interval: 500 us
    Bits: 0

Capture:
  Status: Stop
  Interface 0
    Altset 1
    Format: S24_3LE
    Channels: 8
    Endpoint: 2 IN (ASYNC)
    Rates: 48000
    Data packet interval: 500 us
    Bits: 0
Pioneer DJ Corporation DJM-250MK2 at usb-0000:00:12.2-3, high speed : USB Audio

Playback:
  Status: Stop
  Interface 0
    Altset 1
    Format: S24_3LE
    Channels: 8
    Endpoint: 0x01 (1 OUT) (ASYNC)
    Rates: 48000
    Data packet interval: 500 us
    Bits: 0

Capture:
  Status: Stop
  Interface 0
    Altset 1
    Format: S24_3LE
    Channels: 8
    Endpoint: 0x82 (2 IN) (ASYNC)
    Rates: 48000
    Data packet interval: 500 us
    Bits: 0
USB Mixer: usb_id=0x2b730017, ctrlif=1, ctlerr=0
Card: Pioneer DJ Corporation DJM-250MK2 at usb-0000:00:12.2-3, high speed
  Unit: 0
    Control: name="Playback 5-6 Playback Switch", index=0
  Unit: 0
    Control: name="Playback 3-4 Playback Switch", index=0
  Unit: 0
    Control: name="Playback 1-2 Playback Switch", index=0
  Unit: 0
    Control: name="Capture 5-6 Capture Switch", index=0
  Unit: 0
    Control: name="Capture 3-4 Capture Switch", index=0
  Unit: 0
    Control: name="Capture 1-2 Capture Switch", index=0
  Unit: 0
    Control: name="Master Capture Level Capture Switch", index=0
USB Mixer: usb_id=0x2b730017, ctrlif=1, ctlerr=0
Card: Pioneer DJ Corporation DJM-250MK2 at usb-0000:00:12.2-3, high speed
  Unit: 0
    Control: name="Playback 5-6 Playback Switch", index=0
  Unit: 0
    Control: name="Playback 3-4 Playback Switch", index=0
  Unit: 0
    Control: name="Playback 1-2 Playback Switch", index=0
  Unit: 0
    Control: name="Capture 5-6 Capture Switch", index=0
  Unit: 0
    Control: name="Capture 3-4 Capture Switch", index=0
  Unit: 0
    Control: name="Capture 1-2 Capture Switch", index=0
  Unit: 0
    Control: name="Master Capture Level Capture Switch", index=0
USB Mixer: usb_id=0x2b730017, ctrlif=1, ctlerr=0
Card: Pioneer DJ Corporation DJM-250MK2 at usb-0000:00:12.2-3, high speed
  Unit: 0
    Control: name="Playback 5-6 Playback Switch", index=0
  Unit: 0
    Control: name="Playback 3-4 Playback Switch", index=0
  Unit: 0
    Control: name="Playback 1-2 Playback Switch", index=0
  Unit: 0
    Control: name="Capture 5-6 Capture Switch", index=0
  Unit: 0
    Control: name="Capture 3-4 Capture Switch", index=0
  Unit: 0
    Control: name="Capture 1-2 Capture Switch", index=0
  Unit: 0
    Control: name="Master Capture Level Capture Switch", index=0
Takashi Iwai Jan. 5, 2021, 9:29 a.m. UTC | #4
On Sun, 03 Jan 2021 19:15:48 +0100,
František Kučera wrote:
> 
> Dne 03. 01. 21 v 18:19 Takashi Iwai napsal(a):
> > Could you give lsusb -v output as well as /proc/asound/card*/usbmixer
> > and stream* files?  The proc files are at best from both older and new
> > kernels.
> 
> Here are the files. They look same. The only difference is in the stream0, but it is probably only formatting. I also attached the kern.log from the new version.

Thanks.

It must be something specific to the devices with the fixed stream
qurik.  Could you try the patch below?


Takashi

-- 8< --
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -155,9 +155,6 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 
 	stream = (fp->endpoint & USB_DIR_IN)
 		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
-	err = snd_usb_add_audio_stream(chip, stream, fp);
-	if (err < 0)
-		goto error;
 	if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
 	    fp->altset_idx >= iface->num_altsetting) {
 		err = -EINVAL;
@@ -176,6 +173,11 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 		fp->datainterval = snd_usb_parse_datainterval(chip, alts);
 	if (fp->maxpacksize == 0)
 		fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
+
+	err = snd_usb_add_audio_stream(chip, stream, fp);
+	if (err < 0)
+		goto error;
+
 	usb_set_interface(chip->dev, fp->iface, 0);
 	snd_usb_init_pitch(chip, fp);
 	snd_usb_init_sample_rate(chip, fp, fp->rate_max);
Takashi Iwai Jan. 5, 2021, 1:20 p.m. UTC | #5
On Tue, 05 Jan 2021 10:29:24 +0100,
Takashi Iwai wrote:
> 
> On Sun, 03 Jan 2021 19:15:48 +0100,
> František Kučera wrote:
> > 
> > Dne 03. 01. 21 v 18:19 Takashi Iwai napsal(a):
> > > Could you give lsusb -v output as well as /proc/asound/card*/usbmixer
> > > and stream* files?  The proc files are at best from both older and new
> > > kernels.
> > 
> > Here are the files. They look same. The only difference is in the stream0, but it is probably only formatting. I also attached the kern.log from the new version.
> 
> Thanks.
> 
> It must be something specific to the devices with the fixed stream
> qurik.  Could you try the patch below?

Scratch that.  The call of snd_usb_add_endpoint() is needed explicitly
now at the quirk itself.

Below is the v2 patch.  Please give it a try.


thanks,

Takashi

-- 8< --
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -120,6 +120,38 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip,
 	return 0;
 }
 
+static int add_audio_stream_from_fixed_fmt(struct snd_usb_audio *chip,
+					   struct audioformat *fp)
+{
+	int stream, err;
+
+	stream = (fp->endpoint & USB_DIR_IN) ?
+		SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
+
+	snd_usb_audioformat_set_sync_ep(chip, fp);
+
+	err = snd_usb_add_audio_stream(chip, stream, fp);
+	if (err < 0)
+		return err;
+
+	/* add endpoints */
+	err = snd_usb_add_endpoint(chip, fp->endpoint,
+				   SND_USB_ENDPOINT_TYPE_DATA);
+	if (err < 0)
+		return err;
+
+	if (fp->sync_ep) {
+		err = snd_usb_add_endpoint(chip, fp->sync_ep,
+					   fp->implicit_fb ?
+					   SND_USB_ENDPOINT_TYPE_DATA :
+					   SND_USB_ENDPOINT_TYPE_SYNC);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
 /*
  * create a stream for an endpoint/altsetting without proper descriptors
  */
@@ -131,8 +163,8 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 	struct audioformat *fp;
 	struct usb_host_interface *alts;
 	struct usb_interface_descriptor *altsd;
-	int stream, err;
 	unsigned *rate_table = NULL;
+	int err;
 
 	fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
 	if (!fp)
@@ -153,11 +185,6 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 		fp->rate_table = rate_table;
 	}
 
-	stream = (fp->endpoint & USB_DIR_IN)
-		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
-	err = snd_usb_add_audio_stream(chip, stream, fp);
-	if (err < 0)
-		goto error;
 	if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
 	    fp->altset_idx >= iface->num_altsetting) {
 		err = -EINVAL;
@@ -176,6 +203,11 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 		fp->datainterval = snd_usb_parse_datainterval(chip, alts);
 	if (fp->maxpacksize == 0)
 		fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
+
+	err = add_audio_stream_from_fixed_fmt(chip, fp);
+	if (err < 0)
+		goto error;
+
 	usb_set_interface(chip->dev, fp->iface, 0);
 	snd_usb_init_pitch(chip, fp);
 	snd_usb_init_sample_rate(chip, fp, fp->rate_max);
@@ -417,7 +449,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
 	struct usb_host_interface *alts;
 	struct usb_interface_descriptor *altsd;
 	struct audioformat *fp;
-	int stream, err;
+	int err;
 
 	/* both PCM and MIDI interfaces have 2 or more altsettings */
 	if (iface->num_altsetting < 2)
@@ -482,9 +514,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
 		return -ENXIO;
 	}
 
-	stream = (fp->endpoint & USB_DIR_IN)
-		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
-	err = snd_usb_add_audio_stream(chip, stream, fp);
+	err = add_audio_stream_from_fixed_fmt(chip, fp);
 	if (err < 0) {
 		list_del(&fp->list); /* unlink for avoiding double-free */
 		kfree(fp);
František Kučera Jan. 5, 2021, 10:27 p.m. UTC | #6
Dne 05. 01. 21 v 14:20 Takashi Iwai napsal(a):
> The call of snd_usb_add_endpoint() is needed explicitly
> now at the quirk itself.
>
> Below is the v2 patch.  Please give it a try.

I applied your v2 patch to f6e7a024bfe5 version and tested with DJM-250MK2. It seems working (playback, recording).

The original error messages (usb 1-3: Cannot find EP 0x1 to open, usb 1-3: Cannot find EP 0x82 to open) disappeared from the log. And new one occurred (Incompatible EP setup for 0x82 - repeats many times). However DJM-250MK2 works again.

Thanks,

Franta
Takashi Iwai Jan. 6, 2021, 9:03 a.m. UTC | #7
On Tue, 05 Jan 2021 23:27:14 +0100,
František Kučera wrote:
> 
> Dne 05. 01. 21 v 14:20 Takashi Iwai napsal(a):
> > The call of snd_usb_add_endpoint() is needed explicitly
> > now at the quirk itself.
> >
> > Below is the v2 patch.  Please give it a try.
> 
> I applied your v2 patch to f6e7a024bfe5 version and tested with DJM-250MK2. It seems working (playback, recording).
> 
> The original error messages (usb 1-3: Cannot find EP 0x1 to open, usb 1-3: Cannot find EP 0x82 to open) disappeared from the log. And new one occurred (Incompatible EP setup for 0x82 - repeats many times). However DJM-250MK2 works again.

OK, then could you try the v3 patch below?


Takashi

-- 8< --
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH v3] ALSA: usb-audio: Fix the missing endpoints creations for
 quirks

The recent change in the endpoint management moved the endpoint object
creation from the stream open time to the parser of the audio
descriptor.  It works fine for the standard audio, but it overlooked
the other places that create audio streams via quirks
(QUIRK_AUDIO_FIXED_ENDPOINT) like the reported Pioneer devices;
those call snd_usb_add_audio_stream() manually, hence they miss the
endpoints, eventually resulting in the error at opening streams.
Moreover, now the sync EP setup was moved to the explicit call of
snd_usb_audioformat_set_sync_ep(), and this needs to be added for
those places, too.

This patch addresses those regressions for quirks.  It adds a local
helper function add_audio_stream_from_fixed_fmt(), which does the all
needed tasks, and replaces the calls of snd_usb_add_audio_stream()
with this new function.

Also, since the implicit feedback can be handled generically, drop
the implicit feedback quirk entries for those devices.
This fixes the missing sync_ep_idx entry, too.

Fixes: 54cb31901b83 ("ALSA: usb-audio: Create endpoint objects at parsing phase")
Reported-by: František Kučera <konference@frantovo.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/implicit.c |  2 --
 sound/usb/quirks.c   | 54 ++++++++++++++++++++++++++++++++++++--------
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c
index 931042a6a051..3e0d8a59dddb 100644
--- a/sound/usb/implicit.c
+++ b/sound/usb/implicit.c
@@ -58,8 +58,6 @@ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
 	IMPLICIT_FB_FIXED_DEV(0x0499, 0x172f, 0x81, 2), /* Steinberg UR22C */
 	IMPLICIT_FB_FIXED_DEV(0x0d9a, 0x00df, 0x81, 2), /* RTX6001 */
 	IMPLICIT_FB_FIXED_DEV(0x22f0, 0x0006, 0x81, 3), /* Allen&Heath Qu-16 */
-	IMPLICIT_FB_FIXED_DEV(0x2b73, 0x000a, 0x82, 0), /* Pioneer DJ DJM-900NXS2 */
-	IMPLICIT_FB_FIXED_DEV(0x2b73, 0x0017, 0x82, 0), /* Pioneer DJ DJM-250MK2 */
 	IMPLICIT_FB_FIXED_DEV(0x1686, 0xf029, 0x82, 2), /* Zoom UAC-2 */
 	IMPLICIT_FB_FIXED_DEV(0x2466, 0x8003, 0x86, 2), /* Fractal Audio Axe-Fx II */
 	IMPLICIT_FB_FIXED_DEV(0x0499, 0x172a, 0x86, 2), /* Yamaha MODX */
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index e4a690bb4c99..b70e2ebc3e29 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -120,6 +120,40 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip,
 	return 0;
 }
 
+/* create the audio stream and the corresponding endpoints from the fixed
+ * audioformat object; this is used for quirks with the fixed EPs
+ */
+static int add_audio_stream_from_fixed_fmt(struct snd_usb_audio *chip,
+					   struct audioformat *fp)
+{
+	int stream, err;
+
+	stream = (fp->endpoint & USB_DIR_IN) ?
+		SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
+
+	snd_usb_audioformat_set_sync_ep(chip, fp);
+
+	err = snd_usb_add_audio_stream(chip, stream, fp);
+	if (err < 0)
+		return err;
+
+	err = snd_usb_add_endpoint(chip, fp->endpoint,
+				   SND_USB_ENDPOINT_TYPE_DATA);
+	if (err < 0)
+		return err;
+
+	if (fp->sync_ep) {
+		err = snd_usb_add_endpoint(chip, fp->sync_ep,
+					   fp->implicit_fb ?
+					   SND_USB_ENDPOINT_TYPE_DATA :
+					   SND_USB_ENDPOINT_TYPE_SYNC);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
 /*
  * create a stream for an endpoint/altsetting without proper descriptors
  */
@@ -131,8 +165,8 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 	struct audioformat *fp;
 	struct usb_host_interface *alts;
 	struct usb_interface_descriptor *altsd;
-	int stream, err;
 	unsigned *rate_table = NULL;
+	int err;
 
 	fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
 	if (!fp)
@@ -153,11 +187,6 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 		fp->rate_table = rate_table;
 	}
 
-	stream = (fp->endpoint & USB_DIR_IN)
-		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
-	err = snd_usb_add_audio_stream(chip, stream, fp);
-	if (err < 0)
-		goto error;
 	if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
 	    fp->altset_idx >= iface->num_altsetting) {
 		err = -EINVAL;
@@ -176,6 +205,13 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 		fp->datainterval = snd_usb_parse_datainterval(chip, alts);
 	if (fp->maxpacksize == 0)
 		fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
+	if (!fp->fmt_type)
+		fp->fmt_type = UAC_FORMAT_TYPE_I;
+
+	err = add_audio_stream_from_fixed_fmt(chip, fp);
+	if (err < 0)
+		goto error;
+
 	usb_set_interface(chip->dev, fp->iface, 0);
 	snd_usb_init_pitch(chip, fp);
 	snd_usb_init_sample_rate(chip, fp, fp->rate_max);
@@ -417,7 +453,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
 	struct usb_host_interface *alts;
 	struct usb_interface_descriptor *altsd;
 	struct audioformat *fp;
-	int stream, err;
+	int err;
 
 	/* both PCM and MIDI interfaces have 2 or more altsettings */
 	if (iface->num_altsetting < 2)
@@ -482,9 +518,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
 		return -ENXIO;
 	}
 
-	stream = (fp->endpoint & USB_DIR_IN)
-		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
-	err = snd_usb_add_audio_stream(chip, stream, fp);
+	err = add_audio_stream_from_fixed_fmt(chip, fp);
 	if (err < 0) {
 		list_del(&fp->list); /* unlink for avoiding double-free */
 		kfree(fp);
František Kučera Jan. 6, 2021, 7:01 p.m. UTC | #8
Dne 06. 01. 21 v 10:03 Takashi Iwai napsal(a):
> OK, then could you try the v3 patch below?

I tried v3 patch. Playback works, but recording does not - i found errors like these in the log during recording:

Jan  6 18:07:08 antracit kernel: [  619.973372] retire_capture_urb: 21 callbacks suppressed
Jan  6 18:07:13 antracit kernel: [  624.974175] retire_capture_urb: 9993 callbacks suppressed
Jan  6 18:07:18 antracit kernel: [  629.978015] retire_capture_urb: 9999 callbacks suppressed
Jan  6 18:08:04 antracit kernel: [  675.932930] retire_capture_urb: 102 callbacks suppressed
Jan  6 18:08:09 antracit kernel: [  680.936305] retire_capture_urb: 9998 callbacks suppressed
Jan  6 18:08:14 antracit kernel: [  685.940643] retire_capture_urb: 10000 callbacks suppressed
Jan  6 18:09:45 antracit kernel: [  776.168655] retire_capture_urb: 302 callbacks suppressed
Jan  6 18:09:50 antracit kernel: [  781.169504] retire_capture_urb: 9993 callbacks suppressed
Jan  6 18:09:55 antracit kernel: [  786.173337] retire_capture_urb: 9999 callbacks suppressed

(the original "Incompatible EP setup for 0x82" error was also present in the log)

The arecord command does nothing and after few seconds it fails with:

$ arecord -D hw:CARD=DJM250MK2 -f S24_3LE -c 8 -r 48000 > v3.wav
Recording WAVE 'stdin' : Signed 24 bit Little Endian in 3bytes, Rate 48000 Hz, Channels 8
arecord: pcm_read:2153: read error: Input/output error

The stream0 files from v2 and v3 differs in: Playback / Implicit Feedback Mode: Yes/No


BTW: playback or capture sometimes returns error for the first time but next attempts are successful. However I saw this behavior even in the older versions, so it is nothing v3 specific.

This is the error I got sometimes during the first run:

$ arecord -D hw:CARD=DJM250MK2 -f S24_3LE -c 8 -r 48000 > v3.wav
Recording WAVE 'stdin' : Signed 24 bit Little Endian in 3bytes, Rate 48000 Hz, Channels 8
arecord: set_params:1407: Unable to install hw params:
ACCESS:  RW_INTERLEAVED
FORMAT:  S24_3LE
SUBFORMAT:  STD
SAMPLE_BITS: 24
FRAME_BITS: 192
CHANNELS: 8
RATE: 48000
PERIOD_TIME: (455104 455105)
PERIOD_SIZE: 21845
PERIOD_BYTES: 524280
PERIODS: 2
BUFFER_TIME: (910208 910209)
BUFFER_SIZE: 43690
BUFFER_BYTES: 1048560
TICK_TIME: 0

If I execute the same command again, it works. (but not in v3).

Franta
Pioneer DJ Corporation DJM-250MK2 at usb-0000:00:12.2-3, high speed : USB Audio

Playback:
  Status: Stop
  Interface 0
    Altset 1
    Format: S24_3LE
    Channels: 8
    Endpoint: 0x01 (1 OUT) (ASYNC)
    Rates: 48000
    Data packet interval: 500 us
    Bits: 0
    Sync Endpoint: 0x82 (2 IN)
    Sync EP Interface: 0
    Sync EP Altset: 1
    Implicit Feedback Mode: No

Capture:
  Status: Stop
  Interface 0
    Altset 1
    Format: S24_3LE
    Channels: 8
    Endpoint: 0x82 (2 IN) (ASYNC)
    Rates: 48000
    Data packet interval: 500 us
    Bits: 0
    Sync Endpoint: 0x82 (2 IN)
    Sync EP Interface: 0
    Sync EP Altset: 1
    Implicit Feedback Mode: No
Takashi Iwai Jan. 7, 2021, 1:30 p.m. UTC | #9
On Wed, 06 Jan 2021 20:01:16 +0100,
František Kučera wrote:
> 
> Dne 06. 01. 21 v 10:03 Takashi Iwai napsal(a):
> > OK, then could you try the v3 patch below?
> 
> I tried v3 patch. Playback works, but recording does not - i found errors like these in the log during recording:

Hm.  There seem more problems than I've thought.  The Pioneer devices
are special and don't look like the generic application of the
implicit fb works.

Now I worked on v4 patch set.  Will post in another thread.


thanks,

Takashi
diff mbox series

Patch

diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 94490d706013..eb459db511f8 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -440,22 +440,19 @@  static void snd_complete_urb(struct urb *urb)
 }
 
 /*
- * Get the existing endpoint object corresponding EP, iface and alt numbers
+ * Get the existing endpoint object corresponding EP
  * Returns NULL if not present.
- * Call inside chip->mutex locking for avoiding the race.
  */
 struct snd_usb_endpoint *
-snd_usb_get_endpoint(struct snd_usb_audio *chip,
-		     int ep_num, int iface, int altsetting)
+snd_usb_get_endpoint(struct snd_usb_audio *chip, int ep_num)
 {
 	struct snd_usb_endpoint *ep;
 
 	list_for_each_entry(ep, &chip->ep_list, list) {
-		if (ep->ep_num == ep_num &&
-		    ep->iface == iface &&
-		    ep->altsetting == altsetting)
+		if (ep->ep_num == ep_num)
 			return ep;
 	}
+
 	return NULL;
 }
 
@@ -466,14 +463,13 @@  snd_usb_get_endpoint(struct snd_usb_audio *chip,
  * snd_usb_add_endpoint: Add an endpoint to an USB audio chip
  *
  * @chip: The chip
- * @alts: The USB host interface
  * @ep_num: The number of the endpoint to use
- * @direction: SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE
  * @type: SND_USB_ENDPOINT_TYPE_DATA or SND_USB_ENDPOINT_TYPE_SYNC
  *
  * If the requested endpoint has not been added to the given chip before,
- * a new instance is created. Otherwise, a pointer to the previoulsy
- * created instance is returned. In case of any error, NULL is returned.
+ * a new instance is created.
+ *
+ * Returns zero on success or a negative error code.
  *
  * New endpoints will be added to chip->ep_list and must be freed by
  * calling snd_usb_endpoint_free().
@@ -481,74 +477,59 @@  snd_usb_get_endpoint(struct snd_usb_audio *chip,
  * For SND_USB_ENDPOINT_TYPE_SYNC, the caller needs to guarantee that
  * bNumEndpoints > 1 beforehand.
  */
-struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
-					      struct usb_host_interface *alts,
-					      int ep_num, int direction, int type)
+int snd_usb_add_endpoint(struct snd_usb_audio *chip, int ep_num, int type)
 {
 	struct snd_usb_endpoint *ep;
-	int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK;
-
-	if (WARN_ON(!alts))
-		return NULL;
+	bool is_playback;
 
-	mutex_lock(&chip->mutex);
-
-	ep = snd_usb_get_endpoint(chip, ep_num,
-				  alts->desc.bInterfaceNumber,
-				  alts->desc.bAlternateSetting);
-	if (ep) {
-		usb_audio_dbg(ep->chip, "Re-using EP %x in iface %d,%d\n",
-			      ep_num, ep->iface, ep->altsetting);
-		goto __exit_unlock;
-	}
+	ep = snd_usb_get_endpoint(chip, ep_num);
+	if (ep)
+		return 0;
 
-	usb_audio_dbg(chip, "Creating new %s %s endpoint #%x\n",
-		      is_playback ? "playback" : "capture",
+	usb_audio_dbg(chip, "Creating new %s endpoint #%x\n",
 		      ep_type_name(type),
 		      ep_num);
-
 	ep = kzalloc(sizeof(*ep), GFP_KERNEL);
 	if (!ep)
-		goto __exit_unlock;
+		return -ENOMEM;
 
 	ep->chip = chip;
 	spin_lock_init(&ep->lock);
 	ep->type = type;
 	ep->ep_num = ep_num;
-	ep->iface = alts->desc.bInterfaceNumber;
-	ep->altsetting = alts->desc.bAlternateSetting;
 	INIT_LIST_HEAD(&ep->ready_playback_urbs);
-	ep_num &= USB_ENDPOINT_NUMBER_MASK;
 
+	is_playback = ((ep_num & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
+	ep_num &= USB_ENDPOINT_NUMBER_MASK;
 	if (is_playback)
 		ep->pipe = usb_sndisocpipe(chip->dev, ep_num);
 	else
 		ep->pipe = usb_rcvisocpipe(chip->dev, ep_num);
 
-	if (type == SND_USB_ENDPOINT_TYPE_SYNC) {
-		if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
-		    get_endpoint(alts, 1)->bRefresh >= 1 &&
-		    get_endpoint(alts, 1)->bRefresh <= 9)
-			ep->syncinterval = get_endpoint(alts, 1)->bRefresh;
+	list_add_tail(&ep->list, &chip->ep_list);
+	return 0;
+}
+
+/* Set up syncinterval and maxsyncsize for a sync EP */
+void snd_usb_endpoint_set_syncinterval(struct snd_usb_audio *chip,
+				       struct snd_usb_endpoint *ep,
+				       struct usb_host_interface *alts)
+{
+	struct usb_endpoint_descriptor *desc = get_endpoint(alts, 1);
+
+	if (ep->type == SND_USB_ENDPOINT_TYPE_SYNC) {
+		if (desc->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
+		    desc->bRefresh >= 1 && desc->bRefresh <= 9)
+			ep->syncinterval = desc->bRefresh;
 		else if (snd_usb_get_speed(chip->dev) == USB_SPEED_FULL)
 			ep->syncinterval = 1;
-		else if (get_endpoint(alts, 1)->bInterval >= 1 &&
-			 get_endpoint(alts, 1)->bInterval <= 16)
-			ep->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
+		else if (desc->bInterval >= 1 && desc->bInterval <= 16)
+			ep->syncinterval = desc->bInterval - 1;
 		else
 			ep->syncinterval = 3;
 
-		ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
+		ep->syncmaxsize = le16_to_cpu(desc->wMaxPacketSize);
 	}
-
-	list_add_tail(&ep->list, &chip->ep_list);
-
-	ep->is_implicit_feedback = 0;
-
-__exit_unlock:
-	mutex_unlock(&chip->mutex);
-
-	return ep;
 }
 
 /*
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index 61487095a766..76b6de7de991 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -6,12 +6,9 @@ 
 #define SND_USB_ENDPOINT_TYPE_SYNC     1
 
 struct snd_usb_endpoint *snd_usb_get_endpoint(struct snd_usb_audio *chip,
-					      int ep_num, int iface,
-					      int altsetting);
+					      int ep_num);
 
-struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
-					      struct usb_host_interface *alts,
-					      int ep_num, int direction, int type);
+int snd_usb_add_endpoint(struct snd_usb_audio *chip, int ep_num, int type);
 
 int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
 				snd_pcm_format_t pcm_format,
@@ -34,6 +31,9 @@  void snd_usb_endpoint_free(struct snd_usb_endpoint *ep);
 int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep);
 int snd_usb_endpoint_slave_next_packet_size(struct snd_usb_endpoint *ep);
 int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep);
+void snd_usb_endpoint_set_syncinterval(struct snd_usb_audio *chip,
+				       struct snd_usb_endpoint *ep,
+				       struct usb_host_interface *alts);
 
 void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
 			     struct snd_usb_endpoint *sender,
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 8ae7d2fdba0d..03b1a02bcff4 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -585,11 +585,7 @@  static int set_sync_endpoint(struct snd_usb_substream *subs,
 	if (!alts)
 		return 0;
 
-	subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip,
-						   alts, ep, !subs->direction,
-						   fmt->implicit_fb ?
-						   SND_USB_ENDPOINT_TYPE_DATA :
-						   SND_USB_ENDPOINT_TYPE_SYNC);
+	subs->sync_endpoint = snd_usb_get_endpoint(subs->stream->chip, ep);
 	if (!subs->sync_endpoint) {
 		if (is_playback &&
 		    (fmt->ep_attr & USB_ENDPOINT_SYNCTYPE) == USB_ENDPOINT_SYNC_NONE)
@@ -597,10 +593,14 @@  static int set_sync_endpoint(struct snd_usb_substream *subs,
 		return -EINVAL;
 	}
 
+	subs->sync_endpoint->iface = fmt->sync_iface;
+	subs->sync_endpoint->altsetting = fmt->sync_altsetting;
 	subs->sync_endpoint->is_implicit_feedback = fmt->implicit_fb;
 
 	subs->data_endpoint->sync_master = subs->sync_endpoint;
 
+	snd_usb_endpoint_set_syncinterval(subs->stream->chip, subs->sync_endpoint, alts);
+
 	if (!subs->sync_endpoint->use_count &&
 	    (subs->data_endpoint->iface != subs->sync_endpoint->iface ||
 	     subs->data_endpoint->altsetting != subs->sync_endpoint->altsetting)) {
@@ -641,8 +641,7 @@  static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
 
 	/* shared EP with implicit fb */
 	if (fmt->implicit_fb && !subs->need_setup_fmt) {
-		ep = snd_usb_get_endpoint(subs->stream->chip, fmt->endpoint,
-					  fmt->iface, fmt->altsetting);
+		ep = snd_usb_get_endpoint(subs->stream->chip, fmt->endpoint);
 		if (ep && ep->use_count > 0)
 			goto add_data_ep;
 	}
@@ -688,12 +687,12 @@  static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
  add_data_ep:
 	subs->interface = fmt->iface;
 	subs->altset_idx = fmt->altset_idx;
-	subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip,
-						   alts, fmt->endpoint, subs->direction,
-						   SND_USB_ENDPOINT_TYPE_DATA);
-
+	subs->data_endpoint = snd_usb_get_endpoint(subs->stream->chip,
+						   fmt->endpoint);
 	if (!subs->data_endpoint)
 		return -EINVAL;
+	subs->data_endpoint->iface = fmt->iface;
+	subs->data_endpoint->altsetting = fmt->altsetting;
 
 	err = set_sync_endpoint(subs, fmt);
 	if (err < 0)
@@ -1294,15 +1293,13 @@  static int apply_hw_constraint_from_sync(struct snd_pcm_runtime *runtime,
 
 	subs->fixed_hw = 0;
 	list_for_each_entry(fp, &subs->fmt_list, list) {
-		ep = snd_usb_get_endpoint(chip, fp->endpoint, fp->iface,
-					  fp->altsetting);
+		ep = snd_usb_get_endpoint(chip, fp->endpoint);
 		if (ep && ep->cur_rate)
 			goto found;
 		if (!fp->implicit_fb)
 			continue;
 		/* for the implicit fb, check the sync ep as well */
-		ep = snd_usb_get_endpoint(chip, fp->sync_ep, fp->sync_iface,
-					  fp->sync_altsetting);
+		ep = snd_usb_get_endpoint(chip, fp->sync_ep);
 		if (ep && ep->cur_rate)
 			goto found;
 	}
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 7087ee2c8174..816fd3e5aada 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -1206,6 +1206,22 @@  static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
 			kfree(pd);
 			return err;
 		}
+
+		/* add endpoints */
+		err = snd_usb_add_endpoint(chip, fp->endpoint,
+					   SND_USB_ENDPOINT_TYPE_DATA);
+		if (err < 0)
+			return err;
+
+		if (fp->sync_ep) {
+			err = snd_usb_add_endpoint(chip, fp->sync_ep,
+						   fp->implicit_fb ?
+						   SND_USB_ENDPOINT_TYPE_DATA :
+						   SND_USB_ENDPOINT_TYPE_SYNC);
+			if (err < 0)
+				return err;
+		}
+
 		/* try to set the interface... */
 		usb_set_interface(chip->dev, iface_no, altno);
 		snd_usb_init_pitch(chip, iface_no, alts, fp);