sound/oss/dmasound/dmasound_core.c

Source file repositories/reference/linux-study-clean/sound/oss/dmasound/dmasound_core.c

File Facts

System
Linux kernel
Corpus path
sound/oss/dmasound/dmasound_core.c
Extension
.c
Size
44928 bytes
Lines
1562
Domain
Driver Families
Bucket
sound/oss
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations mixer_fops =
{
	.owner		= THIS_MODULE,
	.unlocked_ioctl	= mixer_unlocked_ioctl,
	.compat_ioctl	= compat_ptr_ioctl,
	.open		= mixer_open,
	.release	= mixer_release,
};

static void mixer_init(void)
{
	mixer_unit = register_sound_mixer(&mixer_fops, -1);
	if (mixer_unit < 0)
		return;

	mixer.busy = 0;
	dmasound.treble = 0;
	dmasound.bass = 0;
	if (dmasound.mach.mixer_init)
	    dmasound.mach.mixer_init();
}


    /*
     *  Sound queue stuff, the heart of the driver
     */

struct sound_queue dmasound_write_sq;
static void sq_reset_output(void) ;

static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
{
	int i;

	if (sq->buffers)
		return 0;
	sq->numBufs = num;
	sq->bufSize = size;
	sq->buffers = kmalloc_array (num, sizeof(char *), GFP_KERNEL);
	if (!sq->buffers)
		return -ENOMEM;
	for (i = 0; i < num; i++) {
		sq->buffers[i] = dmasound.mach.dma_alloc(size, GFP_KERNEL);
		if (!sq->buffers[i]) {
			while (i--)
				dmasound.mach.dma_free(sq->buffers[i], size);
			kfree(sq->buffers);
			sq->buffers = NULL;
			return -ENOMEM;
		}
	}
	return 0;
}

static void sq_release_buffers(struct sound_queue *sq)
{
	int i;

	if (sq->buffers) {
		for (i = 0; i < sq->numBufs; i++)
			dmasound.mach.dma_free(sq->buffers[i], sq->bufSize);
		kfree(sq->buffers);
		sq->buffers = NULL;
	}
}


static int sq_setup(struct sound_queue *sq)
{
	int (*setup_func)(void) = NULL;
	int hard_frame ;

	if (sq->locked) { /* are we already set? - and not changeable */
#ifdef DEBUG_DMASOUND
printk("dmasound_core: tried to sq_setup a locked queue\n") ;
#endif
		return -EINVAL ;
	}
	sq->locked = 1 ; /* don't think we have a race prob. here _check_ */

	/* make sure that the parameters are set up
	   This should have been done already...
	*/

	dmasound.mach.init();

	/* OK.  If the user has set fragment parameters explicitly, then we
	   should leave them alone... as long as they are valid.
	   Invalid user fragment params can occur if we allow the whole buffer
	   to be used when the user requests the fragments sizes (with no soft

Annotation

Implementation Notes