sound/pci/cs46xx/dsp_spos_scb_lib.c

Source file repositories/reference/linux-study-clean/sound/pci/cs46xx/dsp_spos_scb_lib.c

File Facts

System
Linux kernel
Corpus path
sound/pci/cs46xx/dsp_spos_scb_lib.c
Extension
.c
Size
47900 bytes
Lines
1750
Domain
Driver Families
Bucket
sound/pci
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

struct proc_scb_info {
	struct dsp_scb_descriptor * scb_desc;
	struct snd_cs46xx *chip;
};

static void remove_symbol (struct snd_cs46xx * chip, struct dsp_symbol_entry * symbol)
{
	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
	int symbol_index = (int)(symbol - ins->symbol_table.symbols);

	if (snd_BUG_ON(ins->symbol_table.nsymbols <= 0))
		return;
	if (snd_BUG_ON(symbol_index < 0 ||
		       symbol_index >= ins->symbol_table.nsymbols))
		return;

	ins->symbol_table.symbols[symbol_index].deleted = 1;

	if (symbol_index < ins->symbol_table.highest_frag_index) {
		ins->symbol_table.highest_frag_index = symbol_index;
	}
  
	if (symbol_index == ins->symbol_table.nsymbols - 1)
		ins->symbol_table.nsymbols --;

	if (ins->symbol_table.highest_frag_index > ins->symbol_table.nsymbols) {
		ins->symbol_table.highest_frag_index = ins->symbol_table.nsymbols;
	}

}

#ifdef CONFIG_SND_PROC_FS
static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
					   struct snd_info_buffer *buffer)
{
	struct proc_scb_info * scb_info  = entry->private_data;
	struct dsp_scb_descriptor * scb = scb_info->scb_desc;
	struct snd_cs46xx *chip = scb_info->chip;
	int j,col;
	void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;

	guard(mutex)(&chip->spos_mutex);
	snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name);

	for (col = 0,j = 0;j < 0x10; j++,col++) {
		if (col == 4) {
			snd_iprintf(buffer,"\n");
			col = 0;
		}
		snd_iprintf(buffer,"%08x ",readl(dst + (scb->address + j) * sizeof(u32)));
	}
  
	snd_iprintf(buffer,"\n");

	if (scb->parent_scb_ptr != NULL) {
		snd_iprintf(buffer,"parent [%s:%04x] ", 
			    scb->parent_scb_ptr->scb_name,
			    scb->parent_scb_ptr->address);
	} else snd_iprintf(buffer,"parent [none] ");
  
	snd_iprintf(buffer,"sub_list_ptr [%s:%04x]\nnext_scb_ptr [%s:%04x]  task_entry [%s:%04x]\n",
		    scb->sub_list_ptr->scb_name,
		    scb->sub_list_ptr->address,
		    scb->next_scb_ptr->scb_name,
		    scb->next_scb_ptr->address,
		    scb->task_entry->symbol_name,
		    scb->task_entry->address);

	snd_iprintf(buffer,"index [%d] ref_count [%d]\n",scb->index,scb->ref_count);  
}
#endif

static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb)
{
	struct dsp_spos_instance * ins = chip->dsp_spos_instance;

	if ( scb->parent_scb_ptr ) {
		/* unlink parent SCB */
		if (snd_BUG_ON(scb->parent_scb_ptr->sub_list_ptr != scb &&
			       scb->parent_scb_ptr->next_scb_ptr != scb))
			return;
  
		if (scb->parent_scb_ptr->sub_list_ptr == scb) {

			if (scb->next_scb_ptr == ins->the_null_scb) {
				/* last and only node in parent sublist */
				scb->parent_scb_ptr->sub_list_ptr = scb->sub_list_ptr;

				if (scb->sub_list_ptr != ins->the_null_scb) {
					scb->sub_list_ptr->parent_scb_ptr = scb->parent_scb_ptr;

Annotation

Implementation Notes