[PATCH v2 0/8] ALSA: emu10k1: add support for high-bitrate modes of E-MU cards

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This series is what all the work was about: support the "dual-/quad-pumped"
modes of the E-MU cards.

Oswald Buddenhagen (8):
  ALSA: emu10k1: introduce alternative E-MU D.A.S. mode
  ALSA: emu10k1: improve mixer control naming in E-MU D.A.S. mode
  ALSA: emu10k1: set the "no filtering" bits on PCM voices
  ALSA: emu10k1: make playback in E-MU D.A.S. mode 32-bit
  ALSA: add snd_ctl_add_locked()
  ALSA: emu10k1: add support for 2x/4x word clocks in E-MU D.A.S. mode
  ALSA: emu10k1: add high-rate capture in E-MU D.A.S. mode
  ALSA: emu10k1: add high-rate playback in E-MU D.A.S. mode

 include/sound/control.h          |   1 +
 include/sound/emu10k1.h          |  11 +
 sound/core/control.c             |  31 ++
 sound/pci/emu10k1/emu10k1.c      |  29 +-
 sound/pci/emu10k1/emu10k1_main.c |  19 +-
 sound/pci/emu10k1/emufx.c        | 109 +++-
 sound/pci/emu10k1/emumixer.c     | 901 +++++++++++++++++++++++++++----
 sound/pci/emu10k1/emupcm.c       | 422 +++++++++++++--
 sound/pci/emu10k1/emuproc.c      |   5 +
 sound/pci/emu10k1/io.c           |  30 +-
 sound/pci/emu10k1/voice.c        |   6 +
 11 files changed, 1383 insertions(+), 181 deletions(-)

Range-diff against v1:
1:  c8c1fbba5e52 = 1:  7cb49147164f ALSA: emu10k1: introduce alternative E-MU D.A.S. mode
2:  879066428bee = 2:  aa9ead00e045 ALSA: emu10k1: improve mixer control naming in E-MU D.A.S. mode
3:  b663229a0f46 = 3:  ac830e67322f ALSA: emu10k1: set the "no filtering" bits on PCM voices
4:  a9de9a73571e = 4:  26e0b7c02c1d ALSA: emu10k1: make playback in E-MU D.A.S. mode 32-bit
5:  0f1950b03193 ! 5:  94b64e6c123d ALSA: add snd_ctl_add_locked()
    @@ Commit message
         This is in fact more symmetrical to snd_ctl_remove() than snd_ctl_add()
         is - the former could be named snd_ctl_remove_locked() just as well.
     
    +    One may argue that this is going in the wrong direction, as drivers have
    +    no business managing the lock. This may be true in principle, but in
    +    practice the vast majority of controls is created even before the device
    +    was registered, and therefore before any locking is necessary at all.
    +    That means that an even more radical approach of changing snd_ctl_add()
    +    do do no locking, and converting the call sites that actually need
    +    locking to a new function, would better match reality, and would be
    +    somewhat more efficient at that. However, that seems a bit risky and way
    +    too much work.
    +
         This will be used to dynamically change the available controls from
         another control's put() callback, which is already locked.
     
         One might want to add snd_ctl_replace_locked() for completeness, but I
         have no use for it now.
     
         Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@xxxxxx>
    +    ---
    +    v2:
    +    - extended commit message
     
      ## include/sound/control.h ##
     @@ include/sound/control.h: void snd_ctl_notify_one(struct snd_card * card, unsigned int mask, struct snd_kc
6:  511efe4ac7ad ! 6:  7bc314bae7f2 ALSA: emu10k1: add support for 2x/4x word clocks in E-MU D.A.S. mode
    @@ Commit message
         on playback, and throw away the excess ones on capture. Input-to-output
         monitoring does actually use the full sample rate, though.
     
    -    Notably, add_ctls() now uses snd_ctl_add_locked(), so it doesn't
    -    deadlock when called from snd_emu1010_clock_shift_put(). This also
    -    affects the initial creation of the controls, which is OK, as that is
    -    done before the card is registered, so no concurrent access can occur.
    +    Due to hardware constraints, changing the clock multiplier (CM) changes
    +    the available audio ports and the number of available channels. This has
    +    an impact on the channel routing mixer controls. One way to deal with
    +    this would be presenting a union of all possibilities, and simply
    +    ignoring currently inapplicable settings. However, this would be a
    +    terrible user experience, and go against the spirit of prior patches
    +    aimed at decluttering the mixer. Therefore, we do dynamic
    +    reconfiguration (DR) of the mixer in response to changing the CM.
    +
    +    DR is somewhat controversial, as it has the potential to crash poorly
    +    programmed applications. But that in itself isn't a very convincing
    +    argument against it, as by that logic we'd have to ban all hot-plugging.
    +    Such crashes would also not really qualify as regressions, as the D.A.S.
    +    mode is a new opt-in feature, and therefore no previously stable setups
    +    would be impacted. Also, pendantically, the driver already had DR via
    +    SNDRV_EMU10K1_IOCTL_CODE_POKE. A somewhat valid concern is that changing
    +    mixer settings is a non-privileged operation and therefore potential
    +    crashes could be exploited for a somewhat more impactful nuisance attack
    +    on another user than messing with the mixer per se. However, systemd &
    +    co. limit device access to the user currently logged in on the seat
    +    owning the device.
    +
    +    There is a specific concern about doing DR in response to changing a
    +    mixer control's value, as an application may legitimately react to DR by
    +    updating all mixer settings in turn. However, that update should write
    +    the same value to the clock multiplier, thus terminating the recursion.
    +
    +    One may limit DR to merely disabling inapplicable controls, in the hope
    +    that this would be better handled than completely tearing down and
    +    re-creating controls as we do. However, there is no guarantee for that.
    +    And because it is impossible to disable particular enum values within a
    +    control, it would be necessary to have three complete sets of
    +    per-channel controls. This would yield an extremely cluttered and
    +    confusing UI if the application (reasonably) chose to merely visually
    +    disable inactive controls rather than hiding them.
    +
    +    We do the DR synchronously from within snd_emu1010_clock_shift_put().
    +    This was enabled by commit 5bbb1ab5bd ("control: use counting semaphore
    +    as write lock for ELEM_WRITE operation"); we merely need to make
    +    add_ctls() use snd_ctl_add_locked() instead of snd_ctl_add(), so it
    +    doesn't deadlock. That also affects the initial creation of the
    +    controls, which is OK, as that is done before the card is registered, so
    +    no concurrent access can occur.
    +
    +    It would be possible to do the DR in a tasklet after the ioctl finishes.
    +    However, it is not obvious what actual problem that would solve, and the
    +    added asynchronicity would significantly complicate matters, esp. wrt.
    +    the batch updates expected during mixer state restoration.
     
         Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@xxxxxx>
    +    ---
    +    v2:
    +    - expanded commit message
     
      ## include/sound/emu10k1.h ##
     @@ include/sound/emu10k1.h: struct snd_emu1010 {
7:  d5cb50ca707f = 7:  72a156fb32cd ALSA: emu10k1: add high-rate capture in E-MU D.A.S. mode
8:  319425a4ccb6 ! 8:  6d35891832b3 ALSA: emu10k1: add high-rate playback in E-MU D.A.S. mode
    @@ Commit message
         d948035a92 ("Remove PCM xfer_align sw params").
     
         Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@xxxxxx>
    +    ---
    +    v2:
    +    - fixed `sparse` warning re missing __user annotation
     
      ## sound/pci/emu10k1/emufx.c ##
     @@ sound/pci/emu10k1/emufx.c: static int _snd_emu10k1_das_init_efx(struct snd_emu10k1 *emu)
    @@ sound/pci/emu10k1/emupcm.c: static int snd_emu10k1_efx_playback_trigger(struct s
     +		for (i = 0; i < channels; i++) {
     +			for (j = 0; j < subchans; j++) {
     +				u32 *dst = get_dma_ptr_x(runtime, shift, i, j, hwoff);
    -+				u32 *src = (u32 *)buf + j * channels + i;
    ++				u32 __user *src = (u32 __user *)buf + j * channels + i;
     +				for (k = 0; k < frames; k++, dst++, src += voices)
     +					unsafe_get_user(*dst, src, faulted);
     +			}
-- 
2.40.0.152.g15d061e6df




[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux