int snd_gf1_mem_init(struct snd_gus_card * gus) { struct snd_gf1_mem *alloc; struct snd_gf1_mem_block block; #ifdef CONFIG_SND_DEBUG struct snd_info_entry *entry; #endif alloc = &gus->gf1.mem_alloc; mutex_init(&alloc->memory_mutex); alloc->first = alloc->last = NULL; if (!gus->gf1.memory) return 0; memset(&block, 0, sizeof(block)); block.owner = SNDRV_GF1_MEM_OWNER_DRIVER; if (gus->gf1.enh_mode) { block.ptr = 0; block.size = 1024; block.name = kstrdup("InterWave LFOs", GFP_KERNEL); if (snd_gf1_mem_xalloc(alloc, &block) == NULL) return -ENOMEM; } block.ptr = gus->gf1.default_voice_address; block.size = 4; block.name = kstrdup("Voice default (NULL's)", GFP_KERNEL); if (snd_gf1_mem_xalloc(alloc, &block) == NULL) return -ENOMEM; #ifdef CONFIG_SND_DEBUG if (! snd_card_proc_new(gus->card, "gusmem", &entry)) snd_info_set_text_ops(entry, gus, snd_gf1_mem_info_read); #endif return 0; }
snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner, char *name, int size, int w_16, int align, unsigned int *share_id) { snd_gf1_mem_block_t block, *nblock; snd_gf1_mem_lock(alloc, 0); if (share_id != NULL) { nblock = snd_gf1_mem_share(alloc, share_id); if (nblock != NULL) { if (size != (int)nblock->size) { /* TODO: remove in the future */ snd_printk("snd_gf1_mem_alloc - share: sizes differ\n"); goto __std; } nblock->share++; snd_gf1_mem_lock(alloc, 1); return NULL; } } __std: if (snd_gf1_mem_find(alloc, &block, size, w_16, align) < 0) { snd_gf1_mem_lock(alloc, 1); return NULL; } if (share_id != NULL) memcpy(&block.share_id, share_id, sizeof(block.share_id)); block.owner = owner; block.name = snd_kmalloc_strdup(name, GFP_KERNEL); nblock = snd_gf1_mem_xalloc(alloc, &block); snd_gf1_mem_lock(alloc, 1); return nblock; }