diff options
Diffstat (limited to 'sound/core/seq/oss/seq_oss_midi.c')
-rw-r--r-- | sound/core/seq/oss/seq_oss_midi.c | 85 |
1 files changed, 51 insertions, 34 deletions
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index 2ddfe2226651..f8e247d9e5c9 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -37,6 +37,7 @@ struct seq_oss_midi { struct snd_midi_event *coder; /* MIDI event coder */ struct seq_oss_devinfo *devinfo; /* assigned OSSseq device */ snd_use_lock_t use_lock; + struct mutex open_mutex; }; @@ -63,16 +64,13 @@ static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int snd_seq_oss_midi_lookup_ports(int client) { - struct snd_seq_client_info *clinfo; - struct snd_seq_port_info *pinfo; + struct snd_seq_client_info *clinfo __free(kfree) = NULL; + struct snd_seq_port_info *pinfo __free(kfree) = NULL; clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL); pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); - if (! clinfo || ! pinfo) { - kfree(clinfo); - kfree(pinfo); + if (!clinfo || !pinfo) return -ENOMEM; - } clinfo->client = -1; while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, clinfo) == 0) { if (clinfo->client == client) @@ -82,8 +80,6 @@ snd_seq_oss_midi_lookup_ports(int client) while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, pinfo) == 0) snd_seq_oss_midi_check_new_port(pinfo); } - kfree(clinfo); - kfree(pinfo); return 0; } @@ -152,7 +148,8 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) /* * look for the identical slot */ - if ((mdev = find_slot(pinfo->addr.client, pinfo->addr.port)) != NULL) { + mdev = find_slot(pinfo->addr.client, pinfo->addr.port); + if (mdev) { /* already exists */ snd_use_lock_free(&mdev->use_lock); return 0; @@ -171,9 +168,10 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) mdev->flags = pinfo->capability; mdev->opened = 0; snd_use_lock_init(&mdev->use_lock); + mutex_init(&mdev->open_mutex); /* copy and truncate the name of synth device */ - strlcpy(mdev->name, pinfo->name, sizeof(mdev->name)); + strscpy(mdev->name, pinfo->name, sizeof(mdev->name)); /* create MIDI coder */ if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { @@ -218,7 +216,8 @@ snd_seq_oss_midi_check_exit_port(int client, int port) unsigned long flags; int index; - if ((mdev = find_slot(client, port)) != NULL) { + mdev = find_slot(client, port); + if (mdev) { spin_lock_irqsave(®ister_lock, flags); midi_devs[mdev->seq_device] = NULL; spin_unlock_irqrestore(®ister_lock, flags); @@ -250,7 +249,8 @@ snd_seq_oss_midi_clear_all(void) spin_lock_irqsave(®ister_lock, flags); for (i = 0; i < max_midi_devs; i++) { - if ((mdev = midi_devs[i]) != NULL) { + mdev = midi_devs[i]; + if (mdev) { snd_midi_event_free(mdev->coder); kfree(mdev); midi_devs[i] = NULL; @@ -267,7 +267,9 @@ snd_seq_oss_midi_clear_all(void) void snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp) { + spin_lock_irq(®ister_lock); dp->max_mididev = max_midi_devs; + spin_unlock_irq(®ister_lock); } /* @@ -317,14 +319,17 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode) int perm; struct seq_oss_midi *mdev; struct snd_seq_port_subscribe subs; + int err; - if ((mdev = get_mididev(dp, dev)) == NULL) + mdev = get_mididev(dp, dev); + if (!mdev) return -ENODEV; + mutex_lock(&mdev->open_mutex); /* already used? */ if (mdev->opened && mdev->devinfo != dp) { - snd_use_lock_free(&mdev->use_lock); - return -EBUSY; + err = -EBUSY; + goto unlock; } perm = 0; @@ -334,14 +339,14 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode) perm |= PERM_READ; perm &= mdev->flags; if (perm == 0) { - snd_use_lock_free(&mdev->use_lock); - return -ENXIO; + err = -ENXIO; + goto unlock; } /* already opened? */ if ((mdev->opened & perm) == perm) { - snd_use_lock_free(&mdev->use_lock); - return 0; + err = 0; + goto unlock; } perm &= ~mdev->opened; @@ -366,13 +371,17 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode) } if (! mdev->opened) { - snd_use_lock_free(&mdev->use_lock); - return -ENXIO; + err = -ENXIO; + goto unlock; } mdev->devinfo = dp; + err = 0; + + unlock: + mutex_unlock(&mdev->open_mutex); snd_use_lock_free(&mdev->use_lock); - return 0; + return err; } /* @@ -384,12 +393,12 @@ snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev) struct seq_oss_midi *mdev; struct snd_seq_port_subscribe subs; - if ((mdev = get_mididev(dp, dev)) == NULL) + mdev = get_mididev(dp, dev); + if (!mdev) return -ENODEV; - if (! mdev->opened || mdev->devinfo != dp) { - snd_use_lock_free(&mdev->use_lock); - return 0; - } + mutex_lock(&mdev->open_mutex); + if (!mdev->opened || mdev->devinfo != dp) + goto unlock; memset(&subs, 0, sizeof(subs)); if (mdev->opened & PERM_WRITE) { @@ -408,6 +417,8 @@ snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev) mdev->opened = 0; mdev->devinfo = NULL; + unlock: + mutex_unlock(&mdev->open_mutex); snd_use_lock_free(&mdev->use_lock); return 0; } @@ -421,7 +432,8 @@ snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev) struct seq_oss_midi *mdev; int mode; - if ((mdev = get_mididev(dp, dev)) == NULL) + mdev = get_mididev(dp, dev); + if (!mdev) return 0; mode = 0; @@ -443,7 +455,8 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev) { struct seq_oss_midi *mdev; - if ((mdev = get_mididev(dp, dev)) == NULL) + mdev = get_mididev(dp, dev); + if (!mdev) return; if (! mdev->opened) { snd_use_lock_free(&mdev->use_lock); @@ -491,7 +504,8 @@ snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_ad { struct seq_oss_midi *mdev; - if ((mdev = get_mididev(dp, dev)) == NULL) + mdev = get_mididev(dp, dev); + if (!mdev) return; addr->client = mdev->client; addr->port = mdev->port; @@ -511,7 +525,8 @@ snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private_data) if (dp->readq == NULL) return 0; - if ((mdev = find_slot(ev->source.client, ev->source.port)) == NULL) + mdev = find_slot(ev->source.client, ev->source.port); + if (!mdev) return 0; if (! (mdev->opened & PERM_READ)) { snd_use_lock_free(&mdev->use_lock); @@ -623,7 +638,8 @@ snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, stru { struct seq_oss_midi *mdev; - if ((mdev = get_mididev(dp, dev)) == NULL) + mdev = get_mididev(dp, dev); + if (!mdev) return -ENODEV; if (snd_midi_event_encode_byte(mdev->coder, c, ev)) { snd_seq_oss_fill_addr(dp, ev, mdev->client, mdev->port); @@ -642,12 +658,13 @@ snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info { struct seq_oss_midi *mdev; - if ((mdev = get_mididev(dp, dev)) == NULL) + mdev = get_mididev(dp, dev); + if (!mdev) return -ENXIO; inf->device = dev; inf->dev_type = 0; /* FIXME: ?? */ inf->capabilities = 0; /* FIXME: ?? */ - strlcpy(inf->name, mdev->name, sizeof(inf->name)); + strscpy(inf->name, mdev->name, sizeof(inf->name)); snd_use_lock_free(&mdev->use_lock); return 0; } |