sound/isa/gus/gus_mem.c

Source file repositories/reference/linux-study-clean/sound/isa/gus/gus_mem.c

File Facts

System
Linux kernel
Corpus path
sound/isa/gus/gus_mem.c
Extension
.c
Size
8580 bytes
Lines
317
Domain
Driver Families
Bucket
sound/isa
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (pblock->ptr > nblock->ptr) {
			nblock->prev = pblock->prev;
			nblock->next = pblock;
			pblock->prev = nblock;
			if (pblock == alloc->first)
				alloc->first = nblock;
			else
				nblock->prev->next = nblock;
			return nblock;
		}
		pblock = pblock->next;
	}
	nblock->next = NULL;
	if (alloc->last == NULL) {
		nblock->prev = NULL;
		alloc->first = alloc->last = nblock;
	} else {
		nblock->prev = alloc->last;
		alloc->last->next = nblock;
		alloc->last = nblock;
	}
	return nblock;
}

int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * block)
{
	if (block->share) {	/* ok.. shared block */
		block->share--;
		return 0;
	}
	if (alloc->first == block) {
		alloc->first = block->next;
		if (block->next)
			block->next->prev = NULL;
	} else {
		block->prev->next = block->next;
		if (block->next)
			block->next->prev = block->prev;
	}
	if (alloc->last == block) {
		alloc->last = block->prev;
		if (block->prev)
			block->prev->next = NULL;
	} else {
		block->next->prev = block->prev;
		if (block->prev)
			block->prev->next = block->next;
	}
	kfree(block->name);
	kfree(block);
	return 0;
}

static struct snd_gf1_mem_block *snd_gf1_mem_look(struct snd_gf1_mem * alloc,
					     unsigned int address)
{
	struct snd_gf1_mem_block *block;

	for (block = alloc->first; block; block = block->next) {
		if (block->ptr == address) {
			return block;
		}
	}
	return NULL;
}

static struct snd_gf1_mem_block *snd_gf1_mem_share(struct snd_gf1_mem * alloc,
					      unsigned int *share_id)
{
	struct snd_gf1_mem_block *block;

	if (!share_id[0] && !share_id[1] &&
	    !share_id[2] && !share_id[3])
		return NULL;
	for (block = alloc->first; block; block = block->next)
		if (!memcmp(share_id, block->share_id,
				sizeof(block->share_id)))
			return block;
	return NULL;
}

static int snd_gf1_mem_find(struct snd_gf1_mem * alloc,
			    struct snd_gf1_mem_block * block,
			    unsigned int size, int w_16, int align)
{
	struct snd_gf1_bank_info *info = w_16 ? alloc->banks_16 : alloc->banks_8;
	unsigned int idx, boundary;
	int size1;
	struct snd_gf1_mem_block *pblock;
	unsigned int ptr1, ptr2;

Annotation

Implementation Notes