aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/rawmidi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/rawmidi.c')
-rw-r--r--sound/core/rawmidi.c41
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
914static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, 913static 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
955static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, 955static 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
1134static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, 1135static 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,
1185long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream, 1188long 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
1191static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, 1194static 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;