vserver 1.9.3
[linux-2.6.git] / sound / core / rawmidi.c
index df904d1..1c753cd 100644 (file)
@@ -23,6 +23,7 @@
 #include <sound/core.h>
 #include <linux/major.h>
 #include <linux/init.h>
+#include <linux/smp_lock.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/time.h>
@@ -44,10 +45,8 @@ static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
 static int boot_devs;
 module_param_array(midi_map, int, boot_devs, 0444);
 MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device.");
-MODULE_PARM_SYNTAX(midi_map, "default:0,skill:advanced");
 module_param_array(amidi_map, int, boot_devs, 0444);
 MODULE_PARM_DESC(amidi_map, "Raw MIDI device number assigned to 2nd OSS device.");
-MODULE_PARM_SYNTAX(amidi_map, "default:1,skill:advanced");
 #endif /* CONFIG_SND_OSSEMUL */
 
 static int snd_rawmidi_free(snd_rawmidi_t *rawmidi);
@@ -269,7 +268,7 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice,
                list2 = list2->next;
        }
        if (mode & SNDRV_RAWMIDI_LFLG_INPUT) {
-               input = snd_kcalloc(sizeof(snd_rawmidi_runtime_t), GFP_KERNEL);
+               input = kcalloc(1, sizeof(*input), GFP_KERNEL);
                if (input == NULL) {
                        err = -ENOMEM;
                        goto __error;
@@ -291,7 +290,7 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice,
        if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
                if (soutput->opened)
                        goto __skip_output;
-               output = snd_kcalloc(sizeof(snd_rawmidi_runtime_t), GFP_KERNEL);
+               output = kcalloc(1, sizeof(*output), GFP_KERNEL);
                if (output == NULL) {
                        err = -ENOMEM;
                        goto __error;
@@ -398,7 +397,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
        if ((file->f_flags & O_APPEND) || maj != CONFIG_SND_MAJOR) /* OSS emul? */
                fflags |= SNDRV_RAWMIDI_LFLG_APPEND;
        fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK;
-       rawmidi_file = snd_magic_kmalloc(snd_rawmidi_file_t, 0, GFP_KERNEL);
+       rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL);
        if (rawmidi_file == NULL) {
                snd_card_file_remove(card, file);
                return -ENOMEM;
@@ -447,7 +446,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
                file->private_data = rawmidi_file;
        } else {
                snd_card_file_remove(card, file);
-               snd_magic_kfree(rawmidi_file);
+               kfree(rawmidi_file);
        }
        up(&rmidi->open_mutex);
        return err;
@@ -512,11 +511,11 @@ static int snd_rawmidi_release(struct inode *inode, struct file *file)
        snd_rawmidi_t *rmidi;
        int err;
 
-       rfile = snd_magic_cast(snd_rawmidi_file_t, file->private_data, return -ENXIO);
+       rfile = file->private_data;
        err = snd_rawmidi_kernel_release(rfile);
        rmidi = rfile->rmidi;
        wake_up(&rmidi->open_wait);
-       snd_magic_kfree(rfile);
+       kfree(rfile);
        snd_card_file_remove(rmidi->card, file);
        return err;
 }
@@ -675,13 +674,13 @@ static int snd_rawmidi_input_status(snd_rawmidi_substream_t * substream,
        return 0;
 }
 
-static insnd_rawmidi_ioctl(struct inode *inode, struct file *file,
-                            unsigned int cmd, unsigned long arg)
+static inline int _snd_rawmidi_ioctl(struct inode *inode, struct file *file,
+                                    unsigned int cmd, unsigned long arg)
 {
        snd_rawmidi_file_t *rfile;
        void __user *argp = (void __user *)arg;
 
-       rfile = snd_magic_cast(snd_rawmidi_file_t, file->private_data, return -ENXIO);
+       rfile = file->private_data;
        if (((cmd >> 8) & 0xff) != 'W')
                return -ENOTTY;
        switch (cmd) {
@@ -786,6 +785,17 @@ static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
        return -ENOTTY;
 }
 
+/* FIXME: need to unlock BKL to allow preemption */
+static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
+                            unsigned int cmd, unsigned long arg)
+{
+       int err;
+       unlock_kernel();
+       err = _snd_rawmidi_ioctl(inode, file, cmd, arg);
+       lock_kernel();
+       return err;
+}
+
 int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
                              unsigned int cmd, unsigned long arg)
 {
@@ -944,7 +954,7 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
        snd_rawmidi_substream_t *substream;
        snd_rawmidi_runtime_t *runtime;
 
-       rfile = snd_magic_cast(snd_rawmidi_file_t, file->private_data, return -ENXIO);
+       rfile = file->private_data;
        substream = rfile->input;
        if (substream == NULL)
                return -EIO;
@@ -974,6 +984,8 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
                }
                spin_unlock_irq(&runtime->lock);
                count1 = snd_rawmidi_kernel_read1(substream, buf, count, 0);
+               if (count1 < 0)
+                       return result > 0 ? result : count1;
                result += count1;
                buf += count1;
                count -= count1;
@@ -1176,7 +1188,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size
        snd_rawmidi_runtime_t *runtime;
        snd_rawmidi_substream_t *substream;
 
-       rfile = snd_magic_cast(snd_rawmidi_file_t, file->private_data, return -ENXIO);
+       rfile = file->private_data;
        substream = rfile->output;
        runtime = substream->runtime;
        /* we cannot put an atomic message to our buffer */
@@ -1206,14 +1218,14 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size
                spin_unlock_irq(&runtime->lock);
                count1 = snd_rawmidi_kernel_write1(substream, buf, count, 0);
                if (count1 < 0)
-                       continue;
+                       return result > 0 ? result : count1;
                result += count1;
                buf += count1;
                if ((size_t)count1 < count && (file->f_flags & O_NONBLOCK))
                        break;
                count -= count1;
        }
-       while (file->f_flags & O_SYNC) {
+       if (file->f_flags & O_SYNC) {
                spin_lock_irq(&runtime->lock);
                while (runtime->avail != runtime->buffer_size) {
                        wait_queue_t wait;
@@ -1241,7 +1253,7 @@ static unsigned int snd_rawmidi_poll(struct file *file, poll_table * wait)
        snd_rawmidi_runtime_t *runtime;
        unsigned int mask;
 
-       rfile = snd_magic_cast(snd_rawmidi_file_t, file->private_data, return 0);
+       rfile = file->private_data;
        if (rfile->input != NULL) {
                runtime = rfile->input->runtime;
                runtime->trigger = 1;
@@ -1276,7 +1288,7 @@ static void snd_rawmidi_proc_info_read(snd_info_entry_t *entry,
        snd_rawmidi_runtime_t *runtime;
        struct list_head *list;
 
-       rmidi = snd_magic_cast(snd_rawmidi_t, entry->private_data, return);
+       rmidi = entry->private_data;
        snd_iprintf(buffer, "%s\n\n", rmidi->name);
        down(&rmidi->open_mutex);
        if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) {
@@ -1353,7 +1365,7 @@ static int snd_rawmidi_alloc_substreams(snd_rawmidi_t *rmidi,
 
        INIT_LIST_HEAD(&stream->substreams);
        for (idx = 0; idx < count; idx++) {
-               substream = snd_kcalloc(sizeof(snd_rawmidi_substream_t), GFP_KERNEL);
+               substream = kcalloc(1, sizeof(*substream), GFP_KERNEL);
                if (substream == NULL)
                        return -ENOMEM;
                substream->stream = direction;
@@ -1396,7 +1408,7 @@ int snd_rawmidi_new(snd_card_t * card, char *id, int device,
        snd_assert(rrawmidi != NULL, return -EINVAL);
        *rrawmidi = NULL;
        snd_assert(card != NULL, return -ENXIO);
-       rmidi = snd_magic_kcalloc(snd_rawmidi_t, 0, GFP_KERNEL);
+       rmidi = kcalloc(1, sizeof(*rmidi), GFP_KERNEL);
        if (rmidi == NULL)
                return -ENOMEM;
        rmidi->card = card;
@@ -1439,20 +1451,20 @@ static int snd_rawmidi_free(snd_rawmidi_t *rmidi)
        snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
        if (rmidi->private_free)
                rmidi->private_free(rmidi);
-       snd_magic_kfree(rmidi);
+       kfree(rmidi);
        return 0;
 }
 
 static int snd_rawmidi_dev_free(snd_device_t *device)
 {
-       snd_rawmidi_t *rmidi = snd_magic_cast(snd_rawmidi_t, device->device_data, return -ENXIO);
+       snd_rawmidi_t *rmidi = device->device_data;
        return snd_rawmidi_free(rmidi);
 }
 
 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
 static void snd_rawmidi_dev_seq_free(snd_seq_device_t *device)
 {
-       snd_rawmidi_t *rmidi = snd_magic_cast(snd_rawmidi_t, device->private_data, return);
+       snd_rawmidi_t *rmidi = device->private_data;
        rmidi->seq_dev = NULL;
 }
 #endif
@@ -1462,7 +1474,7 @@ static int snd_rawmidi_dev_register(snd_device_t *device)
        int idx, err;
        snd_info_entry_t *entry;
        char name[16];
-       snd_rawmidi_t *rmidi = snd_magic_cast(snd_rawmidi_t, device->device_data, return -ENXIO);
+       snd_rawmidi_t *rmidi = device->device_data;
 
        if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
                return -ENOMEM;
@@ -1539,7 +1551,7 @@ static int snd_rawmidi_dev_register(snd_device_t *device)
 
 static int snd_rawmidi_dev_disconnect(snd_device_t *device)
 {
-       snd_rawmidi_t *rmidi = snd_magic_cast(snd_rawmidi_t, device->device_data, return -ENXIO);
+       snd_rawmidi_t *rmidi = device->device_data;
        int idx;
 
        down(&register_mutex);
@@ -1552,7 +1564,7 @@ static int snd_rawmidi_dev_disconnect(snd_device_t *device)
 static int snd_rawmidi_dev_unregister(snd_device_t *device)
 {
        int idx;
-       snd_rawmidi_t *rmidi = snd_magic_cast(snd_rawmidi_t, device->device_data, return -ENXIO);
+       snd_rawmidi_t *rmidi = device->device_data;
 
        snd_assert(rmidi != NULL, return -ENXIO);
        down(&register_mutex);