sound/usb/line6/pcm.c
Source file repositories/reference/linux-study-clean/sound/usb/line6/pcm.c
File Facts
- System
- Linux kernel
- Corpus path
sound/usb/line6/pcm.c- Extension
.c- Size
- 15612 bytes
- Lines
- 605
- Domain
- Driver Families
- Bucket
- sound/usb
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hlinux/export.hsound/core.hsound/control.hsound/pcm.hsound/pcm_params.hcapture.hdriver.hplayback.h
Detected Declarations
function Copyrightfunction snd_line6_impulse_volume_getfunction snd_line6_impulse_volume_putfunction snd_line6_impulse_period_infofunction snd_line6_impulse_period_getfunction snd_line6_impulse_period_putfunction line6_unlink_audio_urbsfunction line6_wait_clear_audio_urbsfunction get_streamfunction line6_buffer_acquirefunction line6_buffer_releasefunction line6_stream_startfunction line6_stream_stopfunction scoped_guardfunction snd_line6_triggerfunction snd_pcm_group_for_each_entryfunction snd_line6_pointerfunction __line6_pcm_releasefunction line6_pcm_releasefunction line6_pcm_acquirefunction snd_line6_hw_paramsfunction snd_line6_hw_freefunction snd_line6_control_playback_infofunction snd_line6_control_playback_getfunction snd_line6_control_playback_putfunction cleanup_urbsfunction line6_cleanup_pcmfunction snd_line6_new_pcmfunction line6_pcm_disconnectfunction line6_init_pcmfunction snd_line6_prepareexport line6_pcm_releaseexport line6_pcm_acquireexport line6_init_pcm
Annotated Snippet
if (err < 0) {
line6pcm->impulse_volume = 0;
return err;
}
} else {
line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
}
return 1;
}
/* impulse response period controls */
static int snd_line6_impulse_period_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 2000;
return 0;
}
static int snd_line6_impulse_period_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
ucontrol->value.integer.value[0] = line6pcm->impulse_period;
return 0;
}
static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
int value = ucontrol->value.integer.value[0];
if (line6pcm->impulse_period == value)
return 0;
line6pcm->impulse_period = value;
return 1;
}
/*
Unlink all currently active URBs.
*/
static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm,
struct line6_pcm_stream *pcms)
{
int i;
for (i = 0; i < line6pcm->line6->iso_buffers; i++) {
if (test_bit(i, &pcms->active_urbs)) {
if (!test_and_set_bit(i, &pcms->unlink_urbs))
usb_unlink_urb(pcms->urbs[i]);
}
}
}
/*
Wait until unlinking of all currently active URBs has been finished.
*/
static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm,
struct line6_pcm_stream *pcms)
{
int timeout = HZ;
int i;
int alive;
do {
alive = 0;
for (i = 0; i < line6pcm->line6->iso_buffers; i++) {
if (test_bit(i, &pcms->active_urbs))
alive++;
}
if (!alive)
break;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while (--timeout > 0);
if (alive)
dev_err(line6pcm->line6->ifcdev,
"timeout: still %d active urbs..\n", alive);
}
static inline struct line6_pcm_stream *
get_stream(struct snd_line6_pcm *line6pcm, int direction)
{
return (direction == SNDRV_PCM_STREAM_PLAYBACK) ?
&line6pcm->out : &line6pcm->in;
Annotation
- Immediate include surface: `linux/slab.h`, `linux/export.h`, `sound/core.h`, `sound/control.h`, `sound/pcm.h`, `sound/pcm_params.h`, `capture.h`, `driver.h`.
- Detected declarations: `function Copyright`, `function snd_line6_impulse_volume_get`, `function snd_line6_impulse_volume_put`, `function snd_line6_impulse_period_info`, `function snd_line6_impulse_period_get`, `function snd_line6_impulse_period_put`, `function line6_unlink_audio_urbs`, `function line6_wait_clear_audio_urbs`, `function get_stream`, `function line6_buffer_acquire`.
- Atlas domain: Driver Families / sound/usb.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.