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