snd_emux_port_t * snd_emux_create_port(snd_emux_t *emu, char *name, int max_channels, int oss_port, snd_seq_port_callback_t *callback) { snd_emux_port_t *p; int i, type, cap; /* Allocate structures for this channel */ if ((p = snd_magic_kcalloc(snd_emux_port_t, 0, GFP_KERNEL)) == NULL) { snd_printk("no memory\n"); return NULL; } p->chset.channels = snd_kcalloc(max_channels * sizeof(snd_midi_channel_t), GFP_KERNEL); if (p->chset.channels == NULL) { snd_printk("no memory\n"); snd_magic_kfree(p); return NULL; } for (i = 0; i < max_channels; i++) p->chset.channels[i].number = i; p->chset.private_data = p; p->chset.max_channels = max_channels; p->emu = emu; p->chset.client = emu->client; #ifdef SNDRV_EMUX_USE_RAW_EFFECT snd_emux_create_effect(p); #endif callback->private_free = free_port; callback->private_data = p; cap = SNDRV_SEQ_PORT_CAP_WRITE; if (oss_port) { type = SNDRV_SEQ_PORT_TYPE_SPECIFIC; } else { type = DEFAULT_MIDI_TYPE; cap |= SNDRV_SEQ_PORT_CAP_SUBS_WRITE; } p->chset.port = snd_seq_event_port_attach(emu->client, callback, cap, type, max_channels, emu->max_voices, name); return p; }
static int snd_info_entry_open(struct inode *inode, struct file *file) { snd_info_entry_t *entry; snd_info_private_data_t *data; snd_info_buffer_t *buffer; struct proc_dir_entry *p; int mode, err; down(&info_mutex); p = (struct proc_dir_entry *) inode->u.generic_ip; entry = p == NULL ? NULL : (snd_info_entry_t *)p->data; if (entry == NULL) { up(&info_mutex); return -ENODEV; } #ifndef LINUX_2_3 MOD_INC_USE_COUNT; #endif if (entry->module && !try_inc_mod_count(entry->module)) { err = -EFAULT; goto __error1; } mode = file->f_flags & O_ACCMODE; if (mode == O_RDONLY || mode == O_RDWR) { if ((entry->content == SNDRV_INFO_CONTENT_TEXT && !entry->c.text.read_size) || (entry->content == SNDRV_INFO_CONTENT_DATA && entry->c.ops->read == NULL) || entry->content == SNDRV_INFO_CONTENT_DEVICE) { err = -ENODEV; goto __error; } } if (mode == O_WRONLY || mode == O_RDWR) { if ((entry->content == SNDRV_INFO_CONTENT_TEXT && !entry->c.text.write_size) || (entry->content == SNDRV_INFO_CONTENT_DATA && entry->c.ops->write == NULL) || entry->content == SNDRV_INFO_CONTENT_DEVICE) { err = -ENODEV; goto __error; } } data = snd_magic_kcalloc(snd_info_private_data_t, 0, GFP_KERNEL); if (data == NULL) { err = -ENOMEM; goto __error; } data->entry = entry; switch (entry->content) { case SNDRV_INFO_CONTENT_TEXT: if (mode == O_RDONLY || mode == O_RDWR) { buffer = (snd_info_buffer_t *) snd_kcalloc(sizeof(snd_info_buffer_t), GFP_KERNEL); if (buffer == NULL) { snd_magic_kfree(data); err = -ENOMEM; goto __error; } buffer->len = (entry->c.text.read_size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); buffer->buffer = vmalloc(buffer->len); if (buffer->buffer == NULL) { kfree(buffer); snd_magic_kfree(data); err = -ENOMEM; goto __error; } buffer->curr = buffer->buffer; data->rbuffer = buffer; } if (mode == O_WRONLY || mode == O_RDWR) { buffer = (snd_info_buffer_t *) snd_kcalloc(sizeof(snd_info_buffer_t), GFP_KERNEL); if (buffer == NULL) { if (mode == O_RDWR) { vfree(data->rbuffer->buffer); kfree(data->rbuffer); } snd_magic_kfree(data); err = -ENOMEM; goto __error; } buffer->len = (entry->c.text.write_size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); buffer->buffer = vmalloc(buffer->len); if (buffer->buffer == NULL) { if (mode == O_RDWR) { vfree(data->rbuffer->buffer); kfree(data->rbuffer); } kfree(buffer); snd_magic_kfree(data); err = -ENOMEM; goto __error; } buffer->curr = buffer->buffer; data->wbuffer = buffer; } break; case SNDRV_INFO_CONTENT_DATA: /* data */ if (entry->c.ops->open) { if ((err = entry->c.ops->open(entry, mode, &data->file_private_data)) < 0) { snd_magic_kfree(data); goto __error; } } break; } file->private_data = data; up(&info_mutex); if (entry->content == SNDRV_INFO_CONTENT_TEXT && (mode == O_RDONLY || mode == O_RDWR)) { if (entry->c.text.read) { down(&entry->access); entry->c.text.read(entry, data->rbuffer); up(&entry->access); } } return 0; __error: dec_mod_count(entry->module); __error1: #ifndef LINUX_2_3 MOD_DEC_USE_COUNT; #endif up(&info_mutex); return err; }