static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
				     unsigned char __user *userbuf,
				     unsigned char *kernelbuf, long count)
{
	unsigned long flags;
	long result = 0, count1;
	struct snd_rawmidi_runtime *runtime = substream->runtime;
	unsigned long appl_ptr;

	spin_lock_irqsave(&runtime->lock, flags);
	while (count > 0 && runtime->avail) {
		count1 = runtime->buffer_size - runtime->appl_ptr;
		if (count1 > count)
			count1 = count;
		if (count1 > (int)runtime->avail)
			count1 = runtime->avail;

		/* update runtime->appl_ptr before unlocking for userbuf */
		appl_ptr = runtime->appl_ptr;
		runtime->appl_ptr += count1;
		runtime->appl_ptr %= runtime->buffer_size;
		runtime->avail -= count1;

		if (kernelbuf)
			memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1);
		if (userbuf) {
			spin_unlock_irqrestore(&runtime->lock, flags);
			if (copy_to_user(userbuf + result,
					 runtime->buffer + appl_ptr, count1)) {
				return result > 0 ? result : -EFAULT;
			}
			spin_lock_irqsave(&runtime->lock, flags);
		}
		result += count1;
		count -= count1;
	}
	spin_unlock_irqrestore(&runtime->lock, flags);
	return result;
}
static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
				     unsigned char __user *userbuf,
				     unsigned char *kernelbuf, long count)
{
	unsigned long flags;
	long result = 0, count1;
	struct snd_rawmidi_runtime *runtime = substream->runtime;
	unsigned long appl_ptr;

	spin_lock_irqsave(&runtime->lock, flags);
	while (count > 0 && runtime->avail) {
		count1 = runtime->buffer_size - runtime->appl_ptr;
		if (count1 > count)
			count1 = count;
		if (count1 > (int)runtime->avail)
			count1 = runtime->avail;

		 
		appl_ptr = runtime->appl_ptr;
		runtime->appl_ptr += count1;
		runtime->appl_ptr %= runtime->buffer_size;
		runtime->avail -= count1;

		if (kernelbuf)
			memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1);
		if (userbuf) {
			spin_unlock_irqrestore(&runtime->lock, flags);
			if (copy_to_user(userbuf + result,
					 runtime->buffer + appl_ptr, count1)) {
				return result > 0 ? result : -EFAULT;
			}
			spin_lock_irqsave(&runtime->lock, flags);
		}
		result += count1;
		count -= count1;
	}
	spin_unlock_irqrestore(&runtime->lock, flags);
	return result;
}