diff options
Diffstat (limited to 'sound/core/seq/oss/seq_oss_init.c')
| -rw-r--r-- | sound/core/seq/oss/seq_oss_init.c | 88 |
1 files changed, 44 insertions, 44 deletions
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index ca5a2ed4d7c..b9184d20c39 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c @@ -28,7 +28,10 @@ #include "seq_oss_timer.h" #include "seq_oss_event.h" #include <linux/init.h> +#include <linux/export.h> #include <linux/moduleparam.h> +#include <linux/slab.h> +#include <linux/workqueue.h> /* * common variables @@ -58,6 +61,14 @@ static void free_devinfo(void *private); #define call_ctl(type,rec) snd_seq_kernel_client_ctl(system_client, type, rec) +/* call snd_seq_oss_midi_lookup_ports() asynchronously */ +static void async_call_lookup_ports(struct work_struct *work) +{ + snd_seq_oss_midi_lookup_ports(system_client); +} + +static DECLARE_WORK(async_lookup_work, async_call_lookup_ports); + /* * create sequencer client for OSS sequencer */ @@ -81,10 +92,6 @@ snd_seq_oss_create_client(void) goto __error; system_client = rc; - debug_printk(("new client = %d\n", rc)); - - /* look up midi devices */ - snd_seq_oss_midi_lookup_ports(system_client); /* create annoucement receiver port */ memset(port, 0, sizeof(*port)); @@ -113,6 +120,9 @@ snd_seq_oss_create_client(void) } rc = 0; + /* look up midi devices */ + schedule_work(&async_lookup_work); + __error: kfree(port); return rc; @@ -158,6 +168,7 @@ receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic int snd_seq_oss_delete_client(void) { + cancel_work_sync(&async_lookup_work); if (system_client >= 0) snd_seq_delete_kernel_client(system_client); @@ -176,49 +187,48 @@ snd_seq_oss_open(struct file *file, int level) int i, rc; struct seq_oss_devinfo *dp; - if ((dp = kzalloc(sizeof(*dp), GFP_KERNEL)) == NULL) { - snd_printk(KERN_ERR "can't malloc device info\n"); + dp = kzalloc(sizeof(*dp), GFP_KERNEL); + if (!dp) { + pr_err("ALSA: seq_oss: can't malloc device info\n"); return -ENOMEM; } - debug_printk(("oss_open: dp = %p\n", dp)); + + dp->cseq = system_client; + dp->port = -1; + dp->queue = -1; for (i = 0; i < SNDRV_SEQ_OSS_MAX_CLIENTS; i++) { if (client_table[i] == NULL) break; } - if (i >= SNDRV_SEQ_OSS_MAX_CLIENTS) { - snd_printk(KERN_ERR "too many applications\n"); - kfree(dp); - return -ENOMEM; - } dp->index = i; - dp->cseq = system_client; - dp->port = -1; - dp->queue = -1; - dp->readq = NULL; - dp->writeq = NULL; + if (i >= SNDRV_SEQ_OSS_MAX_CLIENTS) { + pr_err("ALSA: seq_oss: too many applications\n"); + rc = -ENOMEM; + goto _error; + } /* look up synth and midi devices */ snd_seq_oss_synth_setup(dp); snd_seq_oss_midi_setup(dp); if (dp->synth_opened == 0 && dp->max_mididev == 0) { - /* snd_printk(KERN_ERR "no device found\n"); */ + /* pr_err("ALSA: seq_oss: no device found\n"); */ rc = -ENODEV; goto _error; } /* create port */ - debug_printk(("create new port\n")); - if ((rc = create_port(dp)) < 0) { - snd_printk(KERN_ERR "can't create port\n"); + rc = create_port(dp); + if (rc < 0) { + pr_err("ALSA: seq_oss: can't create port\n"); goto _error; } /* allocate queue */ - debug_printk(("allocate queue\n")); - if ((rc = alloc_seq_queue(dp)) < 0) + rc = alloc_seq_queue(dp); + if (rc < 0) goto _error; /* set address */ @@ -233,32 +243,30 @@ snd_seq_oss_open(struct file *file, int level) dp->file_mode = translate_mode(file); /* initialize read queue */ - debug_printk(("initialize read queue\n")); if (is_read_mode(dp->file_mode)) { - if ((dp->readq = snd_seq_oss_readq_new(dp, maxqlen)) == NULL) { + dp->readq = snd_seq_oss_readq_new(dp, maxqlen); + if (!dp->readq) { rc = -ENOMEM; goto _error; } } /* initialize write queue */ - debug_printk(("initialize write queue\n")); if (is_write_mode(dp->file_mode)) { dp->writeq = snd_seq_oss_writeq_new(dp, maxqlen); - if (dp->writeq == NULL) { + if (!dp->writeq) { rc = -ENOMEM; goto _error; } } /* initialize timer */ - debug_printk(("initialize timer\n")); - if ((dp->timer = snd_seq_oss_timer_new(dp)) == NULL) { - snd_printk(KERN_ERR "can't alloc timer\n"); + dp->timer = snd_seq_oss_timer_new(dp); + if (!dp->timer) { + pr_err("ALSA: seq_oss: can't alloc timer\n"); rc = -ENOMEM; goto _error; } - debug_printk(("timer initialized\n")); /* set private data pointer */ file->private_data = dp; @@ -272,15 +280,13 @@ snd_seq_oss_open(struct file *file, int level) client_table[dp->index] = dp; num_clients++; - debug_printk(("open done\n")); return 0; _error: snd_seq_oss_synth_cleanup(dp); snd_seq_oss_midi_cleanup(dp); - i = dp->queue; + delete_seq_queue(dp->queue); delete_port(dp); - delete_seq_queue(i); return rc; } @@ -332,7 +338,6 @@ create_port(struct seq_oss_devinfo *dp) return rc; dp->port = port.addr.port; - debug_printk(("new port = %d\n", port.addr.port)); return 0; } @@ -343,10 +348,11 @@ create_port(struct seq_oss_devinfo *dp) static int delete_port(struct seq_oss_devinfo *dp) { - if (dp->port < 0) + if (dp->port < 0) { + kfree(dp); return 0; + } - debug_printk(("delete_port %i\n", dp->port)); return snd_seq_event_port_detach(dp->cseq, dp->port); } @@ -384,7 +390,7 @@ delete_seq_queue(int queue) qinfo.queue = queue; rc = call_ctl(SNDRV_SEQ_IOCTL_DELETE_QUEUE, &qinfo); if (rc < 0) - printk(KERN_ERR "seq-oss: unable to delete queue %d (%d)\n", queue, rc); + pr_err("ALSA: seq_oss: unable to delete queue %d (%d)\n", queue, rc); return rc; } @@ -421,21 +427,16 @@ snd_seq_oss_release(struct seq_oss_devinfo *dp) client_table[dp->index] = NULL; num_clients--; - debug_printk(("resetting..\n")); snd_seq_oss_reset(dp); - debug_printk(("cleaning up..\n")); snd_seq_oss_synth_cleanup(dp); snd_seq_oss_midi_cleanup(dp); /* clear slot */ - debug_printk(("releasing resource..\n")); queue = dp->queue; if (dp->port >= 0) delete_port(dp); delete_seq_queue(queue); - - debug_printk(("release done\n")); } @@ -449,7 +450,6 @@ snd_seq_oss_drain_write(struct seq_oss_devinfo *dp) return; if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) && dp->writeq) { - debug_printk(("syncing..\n")); while (snd_seq_oss_writeq_sync(dp->writeq)) ; } |
