diff options
Diffstat (limited to 'sound/core/rawmidi.c')
-rw-r--r-- | sound/core/rawmidi.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index b8e700b94e59..f7ea7287c59c 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -19,7 +19,6 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <sound/driver.h> | ||
23 | #include <sound/core.h> | 22 | #include <sound/core.h> |
24 | #include <linux/major.h> | 23 | #include <linux/major.h> |
25 | #include <linux/init.h> | 24 | #include <linux/init.h> |
@@ -912,7 +911,8 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, | |||
912 | } | 911 | } |
913 | 912 | ||
914 | static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, | 913 | static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, |
915 | unsigned char *buf, long count, int kernel) | 914 | unsigned char __user *userbuf, |
915 | unsigned char *kernelbuf, long count) | ||
916 | { | 916 | { |
917 | unsigned long flags; | 917 | unsigned long flags; |
918 | long result = 0, count1; | 918 | long result = 0, count1; |
@@ -925,11 +925,11 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, | |||
925 | spin_lock_irqsave(&runtime->lock, flags); | 925 | spin_lock_irqsave(&runtime->lock, flags); |
926 | if (count1 > (int)runtime->avail) | 926 | if (count1 > (int)runtime->avail) |
927 | count1 = runtime->avail; | 927 | count1 = runtime->avail; |
928 | if (kernel) { | 928 | if (kernelbuf) |
929 | memcpy(buf + result, runtime->buffer + runtime->appl_ptr, count1); | 929 | memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1); |
930 | } else { | 930 | if (userbuf) { |
931 | spin_unlock_irqrestore(&runtime->lock, flags); | 931 | spin_unlock_irqrestore(&runtime->lock, flags); |
932 | if (copy_to_user((char __user *)buf + result, | 932 | if (copy_to_user(userbuf + result, |
933 | runtime->buffer + runtime->appl_ptr, count1)) { | 933 | runtime->buffer + runtime->appl_ptr, count1)) { |
934 | return result > 0 ? result : -EFAULT; | 934 | return result > 0 ? result : -EFAULT; |
935 | } | 935 | } |
@@ -949,7 +949,7 @@ long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream, | |||
949 | unsigned char *buf, long count) | 949 | unsigned char *buf, long count) |
950 | { | 950 | { |
951 | snd_rawmidi_input_trigger(substream, 1); | 951 | snd_rawmidi_input_trigger(substream, 1); |
952 | return snd_rawmidi_kernel_read1(substream, buf, count, 1); | 952 | return snd_rawmidi_kernel_read1(substream, NULL/*userbuf*/, buf, count); |
953 | } | 953 | } |
954 | 954 | ||
955 | static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, | 955 | static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, |
@@ -990,8 +990,9 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun | |||
990 | } | 990 | } |
991 | spin_unlock_irq(&runtime->lock); | 991 | spin_unlock_irq(&runtime->lock); |
992 | count1 = snd_rawmidi_kernel_read1(substream, | 992 | count1 = snd_rawmidi_kernel_read1(substream, |
993 | (unsigned char __force *)buf, | 993 | (unsigned char __user *)buf, |
994 | count, 0); | 994 | NULL/*kernelbuf*/, |
995 | count); | ||
995 | if (count1 < 0) | 996 | if (count1 < 0) |
996 | return result > 0 ? result : count1; | 997 | return result > 0 ? result : count1; |
997 | result += count1; | 998 | result += count1; |
@@ -1132,13 +1133,15 @@ int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, | |||
1132 | } | 1133 | } |
1133 | 1134 | ||
1134 | static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, | 1135 | static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, |
1135 | const unsigned char *buf, long count, int kernel) | 1136 | const unsigned char __user *userbuf, |
1137 | const unsigned char *kernelbuf, | ||
1138 | long count) | ||
1136 | { | 1139 | { |
1137 | unsigned long flags; | 1140 | unsigned long flags; |
1138 | long count1, result; | 1141 | long count1, result; |
1139 | struct snd_rawmidi_runtime *runtime = substream->runtime; | 1142 | struct snd_rawmidi_runtime *runtime = substream->runtime; |
1140 | 1143 | ||
1141 | snd_assert(buf != NULL, return -EINVAL); | 1144 | snd_assert(kernelbuf != NULL || userbuf != NULL, return -EINVAL); |
1142 | snd_assert(runtime->buffer != NULL, return -EINVAL); | 1145 | snd_assert(runtime->buffer != NULL, return -EINVAL); |
1143 | 1146 | ||
1144 | result = 0; | 1147 | result = 0; |
@@ -1155,12 +1158,13 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, | |||
1155 | count1 = count; | 1158 | count1 = count; |
1156 | if (count1 > (long)runtime->avail) | 1159 | if (count1 > (long)runtime->avail) |
1157 | count1 = runtime->avail; | 1160 | count1 = runtime->avail; |
1158 | if (kernel) { | 1161 | if (kernelbuf) |
1159 | memcpy(runtime->buffer + runtime->appl_ptr, buf, count1); | 1162 | memcpy(runtime->buffer + runtime->appl_ptr, |
1160 | } else { | 1163 | kernelbuf + result, count1); |
1164 | else if (userbuf) { | ||
1161 | spin_unlock_irqrestore(&runtime->lock, flags); | 1165 | spin_unlock_irqrestore(&runtime->lock, flags); |
1162 | if (copy_from_user(runtime->buffer + runtime->appl_ptr, | 1166 | if (copy_from_user(runtime->buffer + runtime->appl_ptr, |
1163 | (char __user *)buf, count1)) { | 1167 | userbuf + result, count1)) { |
1164 | spin_lock_irqsave(&runtime->lock, flags); | 1168 | spin_lock_irqsave(&runtime->lock, flags); |
1165 | result = result > 0 ? result : -EFAULT; | 1169 | result = result > 0 ? result : -EFAULT; |
1166 | goto __end; | 1170 | goto __end; |
@@ -1171,7 +1175,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, | |||
1171 | runtime->appl_ptr %= runtime->buffer_size; | 1175 | runtime->appl_ptr %= runtime->buffer_size; |
1172 | runtime->avail -= count1; | 1176 | runtime->avail -= count1; |
1173 | result += count1; | 1177 | result += count1; |
1174 | buf += count1; | ||
1175 | count -= count1; | 1178 | count -= count1; |
1176 | } | 1179 | } |
1177 | __end: | 1180 | __end: |
@@ -1185,7 +1188,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, | |||
1185 | long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream, | 1188 | long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream, |
1186 | const unsigned char *buf, long count) | 1189 | const unsigned char *buf, long count) |
1187 | { | 1190 | { |
1188 | return snd_rawmidi_kernel_write1(substream, buf, count, 1); | 1191 | return snd_rawmidi_kernel_write1(substream, NULL, buf, count); |
1189 | } | 1192 | } |
1190 | 1193 | ||
1191 | static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, | 1194 | static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, |
@@ -1225,9 +1228,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, | |||
1225 | spin_lock_irq(&runtime->lock); | 1228 | spin_lock_irq(&runtime->lock); |
1226 | } | 1229 | } |
1227 | spin_unlock_irq(&runtime->lock); | 1230 | spin_unlock_irq(&runtime->lock); |
1228 | count1 = snd_rawmidi_kernel_write1(substream, | 1231 | count1 = snd_rawmidi_kernel_write1(substream, buf, NULL, count); |
1229 | (unsigned char __force *)buf, | ||
1230 | count, 0); | ||
1231 | if (count1 < 0) | 1232 | if (count1 < 0) |
1232 | return result > 0 ? result : count1; | 1233 | return result > 0 ? result : count1; |
1233 | result += count1; | 1234 | result += count1; |