sound/usb/usx2y/usx2yhwdeppcm.c
Source file repositories/reference/linux-study-clean/sound/usb/usx2y/usx2yhwdeppcm.c
File Facts
- System
- Linux kernel
- Corpus path
sound/usb/usx2y/usx2yhwdeppcm.c- Extension
.c- Size
- 23261 bytes
- Lines
- 773
- Domain
- Driver Families
- Bucket
- sound/usb
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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/delay.hlinux/gfp.husbusx2yaudio.csound/hwdep.h
Detected Declarations
function transportfunction usx2y_iso_frames_per_bufferfunction usx2y_hwdep_urb_play_preparefunction usx2y_usbpcm_urb_capt_iso_advancefunction usx2y_usbpcm_usbframe_completefunction i_usx2y_usbpcm_urb_completefunction usx2y_hwdep_urb_releasefunction usx2y_usbpcm_urbs_releasefunction usx2y_usbpcm_subs_startup_finishfunction i_usx2y_usbpcm_subs_startupfunction usx2y_usbpcm_urbs_allocatefunction snd_usx2y_usbpcm_hw_freefunction usx2y_usbpcm_subs_startupfunction usx2y_usbpcm_urbs_startfunction snd_usx2y_usbpcm_preparefunction snd_usx2y_usbpcm_openfunction snd_usx2y_usbpcm_closefunction usx2y_pcms_busy_checkfunction snd_usx2y_hwdep_pcm_openfunction snd_usx2y_hwdep_pcm_releasefunction snd_usx2y_hwdep_pcm_vm_openfunction snd_usx2y_hwdep_pcm_mmapfunction snd_usx2y_hwdep_pcm_private_freefunction usx2y_hwdep_pcm_newfunction usx2y_hwdep_pcm_new
Annotated Snippet
if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
dev_err(&usx2y->dev->dev,
"active frame status %i. Most probably some hardware problem.\n",
urb->iso_frame_desc[i].status);
return urb->iso_frame_desc[i].status;
}
lens += urb->iso_frame_desc[i].actual_length / usx2y->stride;
}
hwptr_done += lens;
if (hwptr_done >= runtime->buffer_size)
hwptr_done -= runtime->buffer_size;
subs->hwptr_done = hwptr_done;
subs->transfer_done += lens;
/* update the pointer, call callback if necessary */
if (subs->transfer_done >= runtime->period_size) {
subs->transfer_done -= runtime->period_size;
snd_pcm_period_elapsed(subs->pcm_substream);
}
return 0;
}
static int usx2y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
struct usx2ydev *usx2y)
{
return (runtime->buffer_size * 1000) / usx2y->rate + 1; //FIXME: so far only correct period_size == 2^x ?
}
/*
* prepare urb for playback data pipe
*
* we copy the data directly from the pcm buffer.
* the current position to be copied is held in hwptr field.
* since a urb can handle only a single linear buffer, if the total
* transferred area overflows the buffer boundary, we cannot send
* it directly from the buffer. thus the data is once copied to
* a temporary buffer and urb points to that.
*/
static int usx2y_hwdep_urb_play_prepare(struct snd_usx2y_substream *subs,
struct urb *urb)
{
int count, counts, pack;
struct usx2ydev *usx2y = subs->usx2y;
struct snd_usx2y_hwdep_pcm_shm *shm = usx2y->hwdep_pcm_shm;
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
if (shm->playback_iso_start < 0) {
shm->playback_iso_start = shm->captured_iso_head -
usx2y_iso_frames_per_buffer(runtime, usx2y);
if (shm->playback_iso_start < 0)
shm->playback_iso_start += ARRAY_SIZE(shm->captured_iso);
shm->playback_iso_head = shm->playback_iso_start;
}
count = 0;
for (pack = 0; pack < nr_of_packs(); pack++) {
/* calculate the size of a packet */
counts = shm->captured_iso[shm->playback_iso_head].length / usx2y->stride;
if (counts < 43 || counts > 50) {
dev_err(&usx2y->dev->dev, "should not be here with counts=%i\n", counts);
return -EPIPE;
}
/* set up descriptor */
urb->iso_frame_desc[pack].offset = shm->captured_iso[shm->playback_iso_head].offset;
urb->iso_frame_desc[pack].length = shm->captured_iso[shm->playback_iso_head].length;
if (atomic_read(&subs->state) != STATE_RUNNING)
memset((char *)urb->transfer_buffer + urb->iso_frame_desc[pack].offset, 0,
urb->iso_frame_desc[pack].length);
if (++shm->playback_iso_head >= ARRAY_SIZE(shm->captured_iso))
shm->playback_iso_head = 0;
count += counts;
}
urb->transfer_buffer_length = count * usx2y->stride;
return 0;
}
static void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream *subs,
struct urb *urb)
{
struct usb_iso_packet_descriptor *desc;
struct snd_usx2y_hwdep_pcm_shm *shm;
int pack, head;
for (pack = 0; pack < nr_of_packs(); ++pack) {
desc = urb->iso_frame_desc + pack;
if (subs) {
shm = subs->usx2y->hwdep_pcm_shm;
head = shm->captured_iso_head + 1;
if (head >= ARRAY_SIZE(shm->captured_iso))
head = 0;
shm->captured_iso[head].frame = urb->start_frame + pack;
Annotation
- Immediate include surface: `linux/delay.h`, `linux/gfp.h`, `usbusx2yaudio.c`, `sound/hwdep.h`.
- Detected declarations: `function transport`, `function usx2y_iso_frames_per_buffer`, `function usx2y_hwdep_urb_play_prepare`, `function usx2y_usbpcm_urb_capt_iso_advance`, `function usx2y_usbpcm_usbframe_complete`, `function i_usx2y_usbpcm_urb_complete`, `function usx2y_hwdep_urb_release`, `function usx2y_usbpcm_urbs_release`, `function usx2y_usbpcm_subs_startup_finish`, `function i_usx2y_usbpcm_subs_startup`.
- Atlas domain: Driver Families / sound/usb.
- Implementation status: source 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.