[E1000]: Fix schedule while atomic when called from mii-tool.
[safe/jmp/linux-2.6] / sound / core / seq / seq_midi.c
index 512ffdd..5929aaf 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   Generic MIDI synth driver for ALSA sequencer
  *   Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- *                         Jaroslav Kysela <perex@suse.cz>
+ *                         Jaroslav Kysela <perex@perex.cz>
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@ Possible options for midisynth module:
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/moduleparam.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
 #include <sound/seq_kernel.h>
@@ -40,7 +40,7 @@ Possible options for midisynth module:
 #include <sound/seq_midi_event.h>
 #include <sound/initval.h>
 
-MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@perex.cz>");
 MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer MIDI synth.");
 MODULE_LICENSE("GPL");
 static int output_buffer_size = PAGE_SIZE;
@@ -70,7 +70,7 @@ struct seq_midisynth_client {
 };
 
 static struct seq_midisynth_client *synths[SNDRV_CARDS];
-static DECLARE_MUTEX(register_mutex);
+static DEFINE_MUTEX(register_mutex);
 
 /* handle rawmidi input event (MIDI v1.0 stream) */
 static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
@@ -270,21 +270,6 @@ static void snd_seq_midisynth_delete(struct seq_midisynth *msynth)
                snd_midi_event_free(msynth->parser);
 }
 
-/* set our client name */
-static int set_client_name(struct seq_midisynth_client *client, struct snd_card *card,
-                          struct snd_rawmidi_info *rmidi)
-{
-       struct snd_seq_client_info cinfo;
-       const char *name;
-
-       memset(&cinfo, 0, sizeof(cinfo));
-       cinfo.client = client->seq_client;
-       cinfo.type = KERNEL_CLIENT;
-       name = rmidi->name[0] ? (const char *)rmidi->name : "External MIDI";
-       strlcpy(cinfo.name, name, sizeof(cinfo.name));
-       return snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
-}
-
 /* register new midi synth port */
 static int
 snd_seq_midisynth_register_port(struct snd_seq_device *dev)
@@ -293,6 +278,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
        struct seq_midisynth *msynth, *ms;
        struct snd_seq_port_info *port;
        struct snd_rawmidi_info *info;
+       struct snd_rawmidi *rmidi = dev->private_data;
        int newclient = 0;
        unsigned int p, ports;
        struct snd_seq_port_callback pcallbacks;
@@ -323,26 +309,27 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
        if (ports > (256 / SNDRV_RAWMIDI_DEVICES))
                ports = 256 / SNDRV_RAWMIDI_DEVICES;
 
-       down(&register_mutex);
+       mutex_lock(&register_mutex);
        client = synths[card->number];
        if (client == NULL) {
                newclient = 1;
                client = kzalloc(sizeof(*client), GFP_KERNEL);
                if (client == NULL) {
-                       up(&register_mutex);
+                       mutex_unlock(&register_mutex);
                        kfree(info);
                        return -ENOMEM;
                }
-               client->seq_client = snd_seq_create_kernel_client(card, 0);
+               client->seq_client =
+                       snd_seq_create_kernel_client(
+                               card, 0, "%s", card->shortname[0] ?
+                               (const char *)card->shortname : "External MIDI");
                if (client->seq_client < 0) {
                        kfree(client);
-                       up(&register_mutex);
+                       mutex_unlock(&register_mutex);
                        kfree(info);
                        return -ENOMEM;
                }
-               set_client_name(client, card, info);
-       } else if (device == 0)
-               set_client_name(client, card, info); /* use the first device's name */
+       }
 
        msynth = kcalloc(ports, sizeof(struct seq_midisynth), GFP_KERNEL);
        port = kmalloc(sizeof(*port), GFP_KERNEL);
@@ -390,7 +377,9 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
                if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) &&
                    info->flags & SNDRV_RAWMIDI_INFO_DUPLEX)
                        port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
-               port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
+               port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
+                       | SNDRV_SEQ_PORT_TYPE_HARDWARE
+                       | SNDRV_SEQ_PORT_TYPE_PORT;
                port->midi_channels = 16;
                memset(&pcallbacks, 0, sizeof(pcallbacks));
                pcallbacks.owner = THIS_MODULE;
@@ -401,6 +390,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
                pcallbacks.unuse = midisynth_unuse;
                pcallbacks.event_input = event_process_midi;
                port->kernel = &pcallbacks;
+               if (rmidi->ops && rmidi->ops->get_port_info)
+                       rmidi->ops->get_port_info(rmidi, p, port);
                if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0)
                        goto __nomem;
                ms->seq_client = client->seq_client;
@@ -411,7 +402,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
        client->num_ports++;
        if (newclient)
                synths[card->number] = client;
-       up(&register_mutex);
+       mutex_unlock(&register_mutex);
        kfree(info);
        kfree(port);
        return 0;       /* success */
@@ -428,7 +419,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
        }
        kfree(info);
        kfree(port);
-       up(&register_mutex);
+       mutex_unlock(&register_mutex);
        return -ENOMEM;
 }
 
@@ -441,10 +432,10 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
        struct snd_card *card = dev->card;
        int device = dev->device, p, ports;
        
-       down(&register_mutex);
+       mutex_lock(&register_mutex);
        client = synths[card->number];
        if (client == NULL || client->ports[device] == NULL) {
-               up(&register_mutex);
+               mutex_unlock(&register_mutex);
                return -ENODEV;
        }
        ports = client->ports_per_device[device];
@@ -460,7 +451,7 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
                synths[card->number] = NULL;
                kfree(client);
        }
-       up(&register_mutex);
+       mutex_unlock(&register_mutex);
        return 0;
 }