sound/isa/msnd/msnd.c
Source file repositories/reference/linux-study-clean/sound/isa/msnd/msnd.c
File Facts
- System
- Linux kernel
- Corpus path
sound/isa/msnd/msnd.c- Extension
.c- Size
- 19097 bytes
- Lines
- 698
- Domain
- Driver Families
- Bucket
- sound/isa
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/sched/signal.hlinux/types.hlinux/interrupt.hlinux/io.hlinux/fs.hlinux/delay.hlinux/module.hsound/core.hsound/initval.hsound/pcm.hsound/pcm_params.hmsnd.h
Detected Declarations
function yetfunction snd_msnd_wait_TXDEfunction snd_msnd_wait_HC0function snd_msnd_send_dsp_cmdfunction snd_msnd_send_wordfunction snd_msnd_upload_hostfunction __snd_msnd_enable_irqfunction __snd_msnd_disable_irqfunction snd_msnd_enable_irqfunction snd_msnd_disable_irqfunction snd_msnd_force_irqfunction get_play_delay_jiffiesfunction snd_msnd_dsp_write_flushfunction snd_msnd_dsp_haltfunction snd_msnd_DARQfunction snd_msnd_DAPQfunction snd_msnd_play_reset_queuefunction snd_msnd_capture_reset_queuefunction snd_msnd_playback_openfunction snd_msnd_playback_closefunction snd_msnd_playback_hw_paramsfunction snd_msnd_playback_preparefunction snd_msnd_playback_triggerfunction snd_msnd_playback_pointerfunction snd_msnd_capture_openfunction snd_msnd_capture_closefunction snd_msnd_capture_preparefunction snd_msnd_capture_triggerfunction snd_msnd_capture_pointerfunction snd_msnd_capture_hw_paramsfunction snd_msnd_pcmexport snd_msnd_init_queueexport snd_msnd_send_dsp_cmdexport snd_msnd_send_wordexport snd_msnd_upload_hostexport snd_msnd_enable_irqexport snd_msnd_disable_irqexport snd_msnd_force_irqexport snd_msnd_dsp_haltexport snd_msnd_DARQexport snd_msnd_DAPQexport snd_msnd_pcm
Annotated Snippet
if (file) {
dev_dbg(chip->card->dev, LOGNAME
": Stopping read for %p\n", file);
chip->mode &= ~FMODE_READ;
}
clear_bit(F_AUDIO_READ_INUSE, &chip->flags);
}
if ((file ? file->f_mode : chip->mode) & FMODE_WRITE) {
if (test_bit(F_WRITING, &chip->flags)) {
snd_msnd_dsp_write_flush(chip);
snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_STOP);
}
snd_msnd_disable_irq(chip);
if (file) {
dev_dbg(chip->card->dev,
LOGNAME ": Stopping write for %p\n", file);
chip->mode &= ~FMODE_WRITE;
}
clear_bit(F_AUDIO_WRITE_INUSE, &chip->flags);
}
}
EXPORT_SYMBOL(snd_msnd_dsp_halt);
int snd_msnd_DARQ(struct snd_msnd *chip, int bank)
{
int /*size, n,*/ timeout = 3;
u16 wTmp;
/* void *DAQD; */
/* Increment the tail and check for queue wrap */
wTmp = readw(chip->DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size);
if (wTmp > readw(chip->DARQ + JQS_wSize))
wTmp = 0;
while (wTmp == readw(chip->DARQ + JQS_wHead) && timeout--)
udelay(1);
if (chip->capturePeriods == 2) {
void __iomem *pDAQ = chip->mappedbase + DARQ_DATA_BUFF +
bank * DAQDS__size + DAQDS_wStart;
unsigned short offset = 0x3000 + chip->capturePeriodBytes;
if (readw(pDAQ) != PCTODSP_BASED(0x3000))
offset = 0x3000;
writew(PCTODSP_BASED(offset), pDAQ);
}
writew(wTmp, chip->DARQ + JQS_wTail);
#if 0
/* Get our digital audio queue struct */
DAQD = bank * DAQDS__size + chip->mappedbase + DARQ_DATA_BUFF;
/* Get length of data */
size = readw(DAQD + DAQDS_wSize);
/* Read data from the head (unprotected bank 1 access okay
since this is only called inside an interrupt) */
outb(HPBLKSEL_1, chip->io + HP_BLKS);
n = msnd_fifo_write(&chip->DARF,
(char *)(chip->base + bank * DAR_BUFF_SIZE),
size, 0);
if (n <= 0) {
outb(HPBLKSEL_0, chip->io + HP_BLKS);
return n;
}
outb(HPBLKSEL_0, chip->io + HP_BLKS);
#endif
return 1;
}
EXPORT_SYMBOL(snd_msnd_DARQ);
int snd_msnd_DAPQ(struct snd_msnd *chip, int start)
{
u16 DAPQ_tail;
int protect = start, nbanks = 0;
void __iomem *DAQD;
static int play_banks_submitted;
/* unsigned long flags;
spin_lock_irqsave(&chip->lock, flags); not necessary */
DAPQ_tail = readw(chip->DAPQ + JQS_wTail);
while (DAPQ_tail != readw(chip->DAPQ + JQS_wHead) || start) {
int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size);
if (start) {
start = 0;
play_banks_submitted = 0;
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/sched/signal.h`, `linux/types.h`, `linux/interrupt.h`, `linux/io.h`, `linux/fs.h`, `linux/delay.h`, `linux/module.h`.
- Detected declarations: `function yet`, `function snd_msnd_wait_TXDE`, `function snd_msnd_wait_HC0`, `function snd_msnd_send_dsp_cmd`, `function snd_msnd_send_word`, `function snd_msnd_upload_host`, `function __snd_msnd_enable_irq`, `function __snd_msnd_disable_irq`, `function snd_msnd_enable_irq`, `function snd_msnd_disable_irq`.
- Atlas domain: Driver Families / sound/isa.
- 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.