Currently CONFIG_SND_OSSEMUL is selected by each config like
CONFIG_SND_PCM_OSS. But, as see in the raw MIDI code that is built
conditionally with CONFIG_SND_OSSEMUL, we should rather make
CONFIG_SND_OSSEMUL user-selectable as the top kconfig item, and leave
the rest depending on it.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Use the same print format of snd_pcm_debug_name() for userspace tracing
program.
Suggested-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Results of ioctl(2) with SNDRV_PCM_IOCTL_HW_REFINE and
SNDRV_PCM_IOCTL_HW_PARAMS are different, because the latter has single
value for several parameters; e.g. channels of PCM substream. Selection
of the single value is done independently of application of constraints.
It's helpful for developers to trace the selection process.
This commit adds tracepoints to snd_pcm_hw_params_choose() for the
purpose.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
As of v4.12, snd_pcm_hw_params_choose() is just called in a process
context of ioctl(2) with SNDRV_PCM_IOCTL_HW_PARAMS. The function locates
in a different file, which has no tracepoints.
This commit moves the function to a file with the tracepoints for later
commit.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
When drivers register no flags about information of PCM hardware, ALSA
PCM core fixups it roughly. Currently, this operation places in a
function snd_pcm_hw_refine(). It can be moved to a function
fixup_unreferenced_params() because it doesn't affects operations
between these two functions.
This idea is better to bundle codes with similar purposes and this commit
achieves it.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
A structure for parameters of PCM runtime has parameters which are
not classified as mask/interval type. They are decided only when
corresponding normal parameters have unique values.
* struct snd_pcm_hw_params.msbits
* struct snd_pcm_hw_params.rate_num
* struct snd_pcm_hw_params.rate_den
* struct snd_pcm_hw_params.fifo_size
Current implementation of hw_params ioctl sometimes doesn't decide these
parameters even if corresponding parameters are fixed, because these
parameters are evaluated before a call of snd_pcm_hw_params_choose().
This commit adds a helper function to process the parameters and call it
in proper positions.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
To fixup some parameters, ALSA PCM core refers the other parameters as
constants. There're some macros for this purpose.
This commit replaces codes with them.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Drivers add rules of parameters to runtime of PCM substream, when
applications open ALSA PCM character device. When applications call
ioctl(2) with SNDRV_PCM_IOCTL_HW_REFINE or SNDRV_PCM_IOCTL_HW_PARAMS, the
rules are applied to the parameters and return the result to user space.
The rule can have dependency between parameters. Additionally, it can have
condition flags about application of rules. Userspace applications can
indicate the flags to suppress change of parameters.
This commit attempts to describe the mechanism.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
A commit 8bea869c5e ("ALSA: PCM midlevel: improve fifo_size handling")
allows drivers to implement calculation of fifo size in parameter
structure. This calculation runs only when two of the other parameters
have single value.
In ALSA PCM core, there're some helper functions for the case. This commit
applies the functions instead of value comparison.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit modifies current for readability in below aspects:
- use bool type variable instead of int type variable assigned to 0/1
- move variable definition from loop to top of the function definition
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
A local variable is used to judge whether a parameter should be handled
due to reverse dependency of the other rules. However, this can be
obsoleted by check of a sentinel in dependency array.
This commit removes the local variable and check the sentinel to reduce
stack usage.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
In a process to calculate parameters of PCM substream, application of all
rules is iterated several times till parameter dependencies are satisfied.
In current implementation, two loops are used for the design, however this
brings two-level indentation and decline readability.
This commit attempts to reduce the indentation by using goto statement,
instead of outer while loop.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Application of rules to parameters of PCM substream is done in a call of
snd_pcm_hw_refine(), while the function includes much codes and is not
enough friendly to readers.
This commit splits the codes to a separated function so that readers can
get it easily. I leave desicion into compilers to merge the function into
its callee.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Application of constraints to interval-type parameters for PCM substream
is done in a call of snd_pcm_hw_refine(), while the function includes
much codes and is not enough friendly to readers.
This commit splits the codes to a separated function so that readers can
get it easily. I leave desicion into compilers to merge the function into
its callee.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Application of constraints to mask-type parameters for PCM substream is
done in a call of snd_pcm_hw_refine(), while the function includes much
codes and is not enough friendly to readers.
This commit splits the codes to a separated function so that readers can
get it easily. I leave desicion into compilers to merge the function into
its callee.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
In a previous commit, tracepoints are added for PCM parameter processing.
As long as I know, this implementation increases size of relocatable
object by 35%. For vendors who are conscious of memory footprint, it
brings apparent disadvantage.
This commit utilizes CONFIG_SND_DEBUG configuration to enable/disable the
tracepoints.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
When working for devices which support configurable modes for its data
transmission or which consists of several components, developers are
likely to use rules of parameters of PCM substream. However, there's no
infrastructure to assist their work.
In old days, ALSA PCM core got a local 'RULES_DEBUG' macro to debug
refinement of parameters for PCM substream. Although this is merely a
makeshift. With some modifications, we get the infrastructure.
This commit is for the purpose. Refinement of mask/interval type of
PCM parameters is probed as tracepoint events as 'hw_mask_param' and
'hw_interval_param' on existent 'snd_pcm' subsystem.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
For accessing the snd_timer_user queue indices, we take tu->qlock.
But it's forgotten in a couple of places.
The one in snd_timer_user_params() should be safe without the
spinlock as the timer is already stopped. But it's better for
consistency.
The one in poll is just a read-out, so it's not inevitably needed, but
it'd be good to make the result consistent, too.
Tested-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
ALSA timer may reallocate the user queue upon request, and it happens
at three places for now: at opening, at SNDRV_TIMER_IOCTL_PARAMS, and
at SNDRV_TIMER_IOCTL_SELECT. However, the last one,
snd_timer_user_tselect(), doesn't need to reallocate the buffer since
it doesn't change the queue size. It does just because tu->tread
might have been changed before starting the timer.
Instead of *_SELECT ioctl, we should reallocate the queue at
SNDRV_TIMER_IOCTL_TREAD; then the timer is guaranteed to be stopped,
thus we can reassign the buffer more safely.
This patch implements that with a slight code refactoring.
Essentially, the patch achieves:
- Introduce realloc_user_queue() for (re-)allocating the ring buffer,
and call it from all places. Also, realloc_user_queue() uses
kcalloc() for avoiding possible leaks.
- Add the buffer reallocation at SNDRV_TIMER_IOCTL_TREAD. When it
fails, tu->tread is restored to the old value, too.
- Drop the buffer reallocation at snd_timer_user_tselect().
Tested-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
snd_timer_user_tselect() reallocates the queue buffer dynamically, but
it forgot to reset its indices. Since the read may happen
concurrently with ioctl and snd_timer_user_tselect() allocates the
buffer via kmalloc(), this may lead to the leak of uninitialized
kernel-space data, as spotted via KMSAN:
BUG: KMSAN: use of unitialized memory in snd_timer_user_read+0x6c4/0xa10
CPU: 0 PID: 1037 Comm: probe Not tainted 4.11.0-rc5+ #2739
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:16
dump_stack+0x143/0x1b0 lib/dump_stack.c:52
kmsan_report+0x12a/0x180 mm/kmsan/kmsan.c:1007
kmsan_check_memory+0xc2/0x140 mm/kmsan/kmsan.c:1086
copy_to_user ./arch/x86/include/asm/uaccess.h:725
snd_timer_user_read+0x6c4/0xa10 sound/core/timer.c:2004
do_loop_readv_writev fs/read_write.c:716
__do_readv_writev+0x94c/0x1380 fs/read_write.c:864
do_readv_writev fs/read_write.c:894
vfs_readv fs/read_write.c:908
do_readv+0x52a/0x5d0 fs/read_write.c:934
SYSC_readv+0xb6/0xd0 fs/read_write.c:1021
SyS_readv+0x87/0xb0 fs/read_write.c:1018
This patch adds the missing reset of queue indices. Together with the
previous fix for the ioctl/read race, we cover the whole problem.
Reported-by: Alexander Potapenko <glider@google.com>
Tested-by: Alexander Potapenko <glider@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The read from ALSA timer device, the function snd_timer_user_tread(),
may access to an uninitialized struct snd_timer_user fields when the
read is concurrently performed while the ioctl like
snd_timer_user_tselect() is invoked. We have already fixed the races
among ioctls via a mutex, but we seem to have forgotten the race
between read vs ioctl.
This patch simply applies (more exactly extends the already applied
range of) tu->ioctl_lock in snd_timer_user_tread() for closing the
race window.
Reported-by: Alexander Potapenko <glider@google.com>
Tested-by: Alexander Potapenko <glider@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The snd_pcm_oss_writev3() and snd_pcm_oss_readv3() are used only in
io.c with CONFIG_SND_PCM_OSS_PLUGINS=y. Add an ifdef to reduce the
build of these functions.
Along with it, since they are called always for in-kernel copy, reduce
the argument and call snd_pcm_kernel_writev() and *_readv() directly
instead.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This is the last-standing one: kill the set_fs() usage in PCM OSS
layer by replacing with the new API functions to deal with the direct
in-kernel buffer copying.
The code to fill the silence can be replaced even to a one-liner to
pass NULL buffer instead of the manual copying.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Now all materials are ready, let's allow the direct in-kernel
read/write, i.e. a kernel-space buffer is passed for read or write,
instead of the normal user-space buffer. This feature is used by OSS
layer and UAC1 driver, for example.
The __snd_pcm_lib_xfer() takes in_kernel argument that indicates the
in-kernel buffer copy. When this flag is set, another transfer code
is used. It's either via copy_kernel PCM ops or the normal memcpy(),
depending on the driver setup.
As external API, snd_pcm_kernel_read(), *_write() and other variants
are provided.
That's all. This support is really simple because of the code
refactoring until now.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Both __snd_pcm_lib_read() and __snd_pcm_write() functions have almost
the same code to loop over samples. For simplification, this patch
unifies both as the single helper, __snd_pcm_lib_xfer().
Other than that, there should be no functional change by this patch.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This patch proceeds more abstraction of PCM read/write loop codes.
For both interleaved and non-interleaved transfers, the same copy or
silence transfer code (which is defined as pcm_transfer_f) is used
now. This became possible since we switched to byte size to copy_*
and fill_silence ops argument instead of frames.
And, for both read and write, we can use the same copy function (which
is defined as pcm_copy_f), just depending on whether interleaved or
non-interleaved mode.
The transfer function is determined at the beginning of the loop,
depending on whether the driver gives the specific copy ops or it's
the standard read/write.
Another bonus by this change is that we now guarantee the silencing
behavior when NULL buffer is passed to write helpers. It'll simplify
some codes later.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Make snd_pcm_lib_read() and *_write() static inline functions that
call the common helper functions directly. This reduces a slight
amount of codes, and at the same time, it's a preparation for the
further cleanups / fixes.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Just shuffle the codes, without any change otherwise.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Now that all users of old copy and silence ops have been converted to
the new PCM ops, the old stuff can be retired and go away.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
For supporting the explicit in-kernel copy of PCM buffer data, and
also for further code refactoring, three new PCM ops, copy_user,
copy_kernel and fill_silence, are introduced. The old copy and
silence ops will be deprecated and removed later once when all callers
are converted.
The copy_kernel ops is the new one, and it's supposed to transfer the
PCM data from the given kernel buffer to the hardware ring-buffer (or
vice-versa depending on the stream direction), while the copy_user ops
is equivalent with the former copy ops, to transfer the data from the
user-space buffer.
The major difference of the new copy_* and fill_silence ops from the
previous ops is that the new ops take bytes instead of frames for size
and position arguments. It has two merits: first, it allows the
callback implementation often simpler (just call directly memcpy() &
co), and second, it may unify the implementations of both interleaved
and non-interleaved cases, as we'll see in the later patch.
As of this stage, copy_kernel ops isn't referred yet, but only
copy_user is used.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
We need to include pcm_local.h to clean up some smatch warnings:
symbol 'snd_pcm_timer_done' was not declared. Should it be static?
symbol 'snd_pcm_timer_init' was not declared. Should it be static?
symbol 'snd_pcm_timer_resolution_change' was not declared. Should
it be static?
Also remove some extraneous tabs on empty lines and replace space
intentation with a tab.
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Declare snd_kcontrol_new structures as const as they are only passed an
argument to the function snd_ctl_new1. This argument is of type const,
so snd_kcontrol_new structures having this property can be made const.
Done using Coccinelle:
@r disable optional_qualifier@
identifier x;
position p;
@@
static struct snd_kcontrol_new x@p={...};
@ok@
identifier r.x;
position p;
@@
snd_ctl_new1(&x@p,...)
@bad@
position p != {r.p,ok.p};
identifier r.x;
@@
x@p
@depends on !bad disable optional_qualifier@
identifier r.x;
@@
+const
struct snd_kcontrol_new x;
Cross compiled these files:
sound/aoa/codecs/tas.c - powerpc
sound/mips/{hal2.c/sgio2audio.c} - mips
sound/ppc/{awacs.c/beep.c/tumbler.c} - powerpc
sound/soc/sh/siu_dai.c - sh
Could not find an architecture to compile sound/sh/aica.c.
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Several files are used to construct PCM core module, a.k.a snd-pcm.
Although available APIs are described in 'include/sound/pcm.h', some of
them are not exported as symbols in kernel space. Such APIs are just for
module local usage.
This commit adds module local header file and move some function prototypes
into it so that scopes of them are controlled properly and developers
get no confusion from unavailable symbols.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Although the ack callback is supposed to be called at each appl_ptr or
hw_ptr update, we missed a few opportunities: namely, forward, rewind
and sync_ptr.
Formerly calling ack at rewind may have leaded to unexpected results
due to the forgotten negative appl_ptr update in indirect-PCM helper,
which is the major user of the PCM ack callback. But now we fixed
this oversights, thus we can call ack callback safely even at rewind
callback -- of course with the proper handling of the error from the
callback.
This patch adds the calls of ack callback in the places mentioned in
the above.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
In current implementation of ALSA control core, list operation has
a limitation to handle 16384 entries at once. This seems due to
allocation in kernel space to copy data from user space.
With a commit 53e7bf4525 ("ALSA: control: Simplify snd_ctl_elem_list()
implementation"), for the operation, ALSA control core copies data
into user space directly. No need to care of kernel spaces anymore.
This commit purges the limitation.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
We used to use kmalloc (more exactly, krealloc()) for creating and
growing the temporary buffer for text proc write. It can grow up to
16kB, and it's already a bit doubtful whether it's always safe to use
kmalloc(). With the recent addition of kvmalloc(), we can have a
better chance for succeed of memory allocation, so let's switch to
that new API.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
PCM core code has a few usages of set_fs(), mostly for two codepaths:
- The DELAY ioctl call from pcm_compat.c
- The ioctl wrapper in kernel context for PCM OSS and other
This patch removes the set_fs() usage in these places by a slight code
refactoring. For the former point, snd_pcm_delay() is changed to
return the value directly instead of putting the value to the given
address. Each caller stores the result in an appropriate manner.
For fixing the latter, snd_pcm_lib_kernel_ioctl() is changed to call
the functions directly as well. For achieving it, now the function
accepts only the limited set of ioctls that have been used, so far.
The primary user of this function is the PCM OSS layer, and the only
other user is USB UAC1 gadget driver. Both drivers don't need the
full set of ioctls.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This patch simplifies the code of snd_ctl_elem_list() in the following
ways:
- Avoid a vmalloc() temporary buffer but do copy in each iteration;
the vmalloc buffer was introduced at the time we took the spinlock
for the ctl element management.
- Use the standard list_for_each_entry() macro
- Merge two loops into one;
it used to be a loop for skipping until offset becomes zero and
another loop to copy the data. They can be folded into a single
loop easily.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Tested-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Factor out the common codes in snd_pcm_*_forward() and *_rewind()
functions to simplify the codes. No functional changes.
Reviewd-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The mostly same codes for checking the current PCM state and calling
hwsync are found in a few places. This patch simplifies them by
creating a common helper function.
It also fixes a couple of cases where we missed the proper state check
(e.g. PAUSED state wasn't handled in rewind and snd_pcm_hwsync()),
too.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Only one of the two declarations has the const modifier in the
argument list, so we get a warning when CONFIG_SND_PCM_OSS_PLUGINS
is disabled:
sound/core/oss/pcm_oss.c: In function 'snd_pcm_oss_change_params':
sound/core/oss/pcm_oss.c:898:47: error: passing argument 2 of 'snd_pcm_plug_slave_format' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
This makes the two declarations match again.
Fixes: e76bf3c4b4 ("ALSA: pcm/oss: refer to parameters instead of copying to reduce usage of kernel stack")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Recent compilers produce a harmless warning for the new pcm_call_notify()
macro when CONFIG_SND_PCM_OSS is disabled:
sound/core/pcm.c: In function 'snd_pcm_free':
sound/core/pcm.c:905:37: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
This turns the empty macro into a 'do {} while (0)' statement to avoid
the warning.
Fixes: 58f30d650c ("ALSA: pcm: Build pcm notifier code conditionally")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
In a function snd_pcm_hw_params_choose(), target parameters are arranged
into a table. Though each entry of this table is read-only, they don't
have const qualifier.
This commit adds the qualifier.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Some functions in compatibility layer for Open Sound System interface has
local variable to copy some parameters in runtime of PCM substream, while
this can be replaced with reference of pointers to parameter itself. This
brings an advantage to reduce usage of kernel stack.
This commit applies this idea.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
ALSA pcm core has hw_param_interval_c() to pick up parameter with const
qualifier for safe programming.
This commit applies it to the cases.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
There's a read-only table for each sampling rate, while it doesn't have
const qualifier and can be modified.
This commit add the qualifier. As a result, a symbol for the table
moves from .data section to .rodata.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>