patch-2.1.80 linux/drivers/sound/audio.c

Next file: linux/drivers/sound/cs4232.c
Previous file: linux/drivers/sound/adlib_card.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.79/linux/drivers/sound/audio.c linux/drivers/sound/audio.c
@@ -362,144 +362,151 @@
 		/* else
 		        printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
 		return -ENXIO;
-	} else switch (cmd) {
-	case SNDCTL_DSP_SYNC:
-		if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
-			return 0;
-		if (audio_devs[dev]->dmap_out->fragment_size == 0)
+	}
+	else switch (cmd) 
+	{
+		case SNDCTL_DSP_SYNC:
+			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+				return 0;
+			if (audio_devs[dev]->dmap_out->fragment_size == 0)
+				return 0;
+			sync_output(dev);
+			DMAbuf_sync(dev);
+			DMAbuf_reset(dev);
 			return 0;
-		sync_output(dev);
-		DMAbuf_sync(dev);
-		DMAbuf_reset(dev);
-		return 0;
 
-	case SNDCTL_DSP_POST:
-		if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
-			return 0;
-		if (audio_devs[dev]->dmap_out->fragment_size == 0)
+		case SNDCTL_DSP_POST:
+			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+				return 0;
+			if (audio_devs[dev]->dmap_out->fragment_size == 0)
+				return 0;
+			audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
+			sync_output(dev);
+			dma_ioctl(dev, SNDCTL_DSP_POST, (caddr_t) 0);
 			return 0;
-		audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
-		sync_output(dev);
-		dma_ioctl(dev, SNDCTL_DSP_POST, (caddr_t) 0);
-		return 0;
-
-	case SNDCTL_DSP_RESET:
-		audio_mode[dev] = AM_NONE;
-		DMAbuf_reset(dev);
-		return 0;
-
-	case SNDCTL_DSP_GETFMTS:
-		val = audio_devs[dev]->format_mask;
-		return __put_user(val, (int *)arg);
-
-	case SNDCTL_DSP_SETFMT:
-		if (__get_user(val, (int *)arg))
-			return -EFAULT;
-		val = set_format(dev, val);
-		return __put_user(val, (int *)arg);
 
-	case SNDCTL_DSP_GETISPACE:
-		if (!(audio_devs[dev]->open_mode & OPEN_READ))
+		case SNDCTL_DSP_RESET:
+			audio_mode[dev] = AM_NONE;
+			DMAbuf_reset(dev);
 			return 0;
-		if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
-			return -EBUSY;
-		return dma_ioctl(dev, cmd, arg);
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
-			return -EPERM;
-		if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
-			return -EBUSY;
-		return dma_ioctl(dev, cmd, arg);
+
+		case SNDCTL_DSP_GETFMTS:
+			val = audio_devs[dev]->format_mask;
+			break;
+	
+		case SNDCTL_DSP_SETFMT:
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			val = set_format(dev, val);
+			break;
+
+		case SNDCTL_DSP_GETISPACE:
+			if (!(audio_devs[dev]->open_mode & OPEN_READ))
+				return 0;
+			if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+				return -EBUSY;
+			return dma_ioctl(dev, cmd, arg);
+
+		case SNDCTL_DSP_GETOSPACE:
+			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+				return -EPERM;
+			if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+				return -EBUSY;
+			return dma_ioctl(dev, cmd, arg);
 		
-	case SNDCTL_DSP_NONBLOCK:
-		dev_nblock[dev] = 1;
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-			info = 1 | DSP_CAP_MMAP;	/* Revision level of this ioctl() */
-			if (audio_devs[dev]->flags & DMA_DUPLEX &&
-			    audio_devs[dev]->open_mode == OPEN_READWRITE)
-				info |= DSP_CAP_DUPLEX;
-			if (audio_devs[dev]->coproc)
-				info |= DSP_CAP_COPROC;
-			if (audio_devs[dev]->d->local_qlen)	/* Device has hidden buffers */
-				info |= DSP_CAP_BATCH;
-			if (audio_devs[dev]->d->trigger)	/* Supports SETTRIGGER */
-				info |= DSP_CAP_TRIGGER;
-			return __put_user(info, (int *)arg);
+		case SNDCTL_DSP_NONBLOCK:
+			dev_nblock[dev] = 1;
+			return 0;
+
+		case SNDCTL_DSP_GETCAPS:
+				info = 1 | DSP_CAP_MMAP;	/* Revision level of this ioctl() */
+				if (audio_devs[dev]->flags & DMA_DUPLEX &&
+					audio_devs[dev]->open_mode == OPEN_READWRITE)
+					info |= DSP_CAP_DUPLEX;
+				if (audio_devs[dev]->coproc)
+					info |= DSP_CAP_COPROC;
+				if (audio_devs[dev]->d->local_qlen)	/* Device has hidden buffers */
+					info |= DSP_CAP_BATCH;
+				if (audio_devs[dev]->d->trigger)	/* Supports SETTRIGGER */
+					info |= DSP_CAP_TRIGGER;
+				break;
 			
-	case SOUND_PCM_WRITE_RATE:
-		if (__get_user(val, (int *)arg))
-			return -EFAULT;
-		val = audio_devs[dev]->d->set_speed(dev, val);
-		return __put_user(val, (int *)arg);
-
-	case SOUND_PCM_READ_RATE:
-		val = audio_devs[dev]->d->set_speed(dev, 0);
-		return __put_user(val, (int *)arg);
-		
-	case SNDCTL_DSP_STEREO:
-		if (__get_user(val, (int *)arg))
-			return -EFAULT;
-		if (val > 1 || val < 0)
-			return -EINVAL;
-		val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
-		return __put_user(val, (int *)arg);
-
-	case SOUND_PCM_WRITE_CHANNELS:
-		if (__get_user(val, (int *)arg))
-			return -EFAULT;
-		val = audio_devs[dev]->d->set_channels(dev, val);
-		return __put_user(val, (int *)arg);
-
-	case SOUND_PCM_READ_CHANNELS:
-		val = audio_devs[dev]->d->set_channels(dev, 0);
-		return __put_user(val, (int *)arg);
+		case SOUND_PCM_WRITE_RATE:
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			val = audio_devs[dev]->d->set_speed(dev, val);
+			break;
+
+		case SOUND_PCM_READ_RATE:
+			val = audio_devs[dev]->d->set_speed(dev, 0);
+			break;
+			
+		case SNDCTL_DSP_STEREO:
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			if (val > 1 || val < 0)
+				return -EINVAL;
+			val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
+			break;
+
+		case SOUND_PCM_WRITE_CHANNELS:
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			val = audio_devs[dev]->d->set_channels(dev, val);
+			break;
+
+		case SOUND_PCM_READ_CHANNELS:
+			val = audio_devs[dev]->d->set_channels(dev, 0);
+			break;
 		
-	case SOUND_PCM_READ_BITS:
-		val = audio_devs[dev]->d->set_bits(dev, 0);
-		return __put_user(val, (int *)arg);
-
-	case SNDCTL_DSP_SETDUPLEX:
-		if (audio_devs[dev]->open_mode != OPEN_READWRITE)
-			return -EPERM;
-		return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;
-
-	case SNDCTL_DSP_PROFILE:
-		if (__get_user(val, (int *)arg))
-			return -EFAULT;
-		if (audio_devs[dev]->open_mode & OPEN_WRITE)
-			audio_devs[dev]->dmap_out->applic_profile = val;
-		if (audio_devs[dev]->open_mode & OPEN_READ)
-			audio_devs[dev]->dmap_in->applic_profile = val;
-		return 0;
+		case SOUND_PCM_READ_BITS:
+			val = audio_devs[dev]->d->set_bits(dev, 0);
+			break;
+
+		case SNDCTL_DSP_SETDUPLEX:
+			if (audio_devs[dev]->open_mode != OPEN_READWRITE)
+				return -EPERM;
+			return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;
+
+		case SNDCTL_DSP_PROFILE:
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			if (audio_devs[dev]->open_mode & OPEN_WRITE)
+				audio_devs[dev]->dmap_out->applic_profile = val;
+			if (audio_devs[dev]->open_mode & OPEN_READ)
+				audio_devs[dev]->dmap_in->applic_profile = val;
+			return 0;
 		
-	case SNDCTL_DSP_GETODELAY:
-		dmap = audio_devs[dev]->dmap_out;
-		if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
-			return -EINVAL;
-		if (!(dmap->flags & DMA_ALLOC_DONE))
-			return __put_user(0, (int *)arg);
+		case SNDCTL_DSP_GETODELAY:
+			dmap = audio_devs[dev]->dmap_out;
+			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+				return -EINVAL;
+			if (!(dmap->flags & DMA_ALLOC_DONE))
+			{
+				val=0;
+				break;
+			}
 		
-		save_flags (flags);
-		cli();
-		/* Compute number of bytes that have been played */
-		count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
-		if (count < dmap->fragment_size && dmap->qhead != 0)
-			count += dmap->bytes_in_use;	/* Pointer wrap not handled yet */
-		count += dmap->byte_counter;
+			save_flags (flags);
+			cli();
+			/* Compute number of bytes that have been played */
+			count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
+			if (count < dmap->fragment_size && dmap->qhead != 0)
+				count += dmap->bytes_in_use;	/* Pointer wrap not handled yet */
+			count += dmap->byte_counter;
 		
-		/* Substract current count from the number of bytes written by app */
-		count = dmap->user_counter - count;
-		if (count < 0)
-			count = 0;
-		restore_flags (flags);
-		return __put_user(count, (int *)arg);
+			/* Substract current count from the number of bytes written by app */
+			count = dmap->user_counter - count;
+			if (count < 0)
+				count = 0;
+			restore_flags (flags);
+			val = count;
+			break;
 		
-	default:
-		return dma_ioctl(dev, cmd, arg);
+		default:
+			return dma_ioctl(dev, cmd, arg);
 	}
+	return put_user(val, (int *)arg);
 }
 
 void audio_init_devices(void)
@@ -641,7 +648,8 @@
 
 static int dma_subdivide(int dev, struct dma_buffparms *dmap, int fact)
 {
-	if (fact == 0) {
+	if (fact == 0) 
+	{
 		fact = dmap->subdivision;
 		if (fact == 0)
 			fact = 1;
@@ -722,210 +730,222 @@
 	int fact, ret, changed, bits, count, err;
 	unsigned long flags;
 
-	switch (cmd) {
-	case SNDCTL_DSP_SUBDIVIDE:
-		ret = 0;
-		if (__get_user(fact, (int *)arg))
-			return -EFAULT;
-		if (audio_devs[dev]->open_mode & OPEN_WRITE)
-			ret = dma_subdivide(dev, dmap_out, fact);
-		if (ret < 0)
-			return ret;
-		if (audio_devs[dev]->open_mode != OPEN_WRITE ||
-		    (audio_devs[dev]->flags & DMA_DUPLEX &&
-		     audio_devs[dev]->open_mode & OPEN_READ))
-			ret = dma_subdivide(dev, dmap_in, fact);
-		if (ret < 0)
-			return ret;
-		return __put_user(ret, (int *)arg);
-
-	case SNDCTL_DSP_GETISPACE:
-	case SNDCTL_DSP_GETOSPACE:
-		dmap = dmap_out;
-		if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
-			return -EINVAL;
-		if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
-			return -EINVAL;
-		if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
-			dmap = dmap_in;
-		if (dmap->mapping_flags & DMA_MAP_MAPPED)
-			return -EINVAL;
-		if (!(dmap->flags & DMA_ALLOC_DONE))
-			reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
-		info.fragstotal = dmap->nbufs;
-		if (cmd == SNDCTL_DSP_GETISPACE)
-			info.fragments = dmap->qlen;
-		else {
-			if (!DMAbuf_space_in_queue(dev))
-				info.fragments = 0;
-			else {
-				info.fragments = DMAbuf_space_in_queue(dev);
-				if (audio_devs[dev]->d->local_qlen) {
-					int tmp = audio_devs[dev]->d->local_qlen(dev);
-					if (tmp && info.fragments)
-						tmp--;	/*
-							 * This buffer has been counted twice
-							 */
-					info.fragments -= tmp;
+	switch (cmd) 
+	{
+		case SNDCTL_DSP_SUBDIVIDE:
+			ret = 0;
+			if (get_user(fact, (int *)arg))
+				return -EFAULT;
+			if (audio_devs[dev]->open_mode & OPEN_WRITE)
+				ret = dma_subdivide(dev, dmap_out, fact);
+			if (ret < 0)
+				return ret;
+			if (audio_devs[dev]->open_mode != OPEN_WRITE ||
+				(audio_devs[dev]->flags & DMA_DUPLEX &&
+					audio_devs[dev]->open_mode & OPEN_READ))
+				ret = dma_subdivide(dev, dmap_in, fact);
+			if (ret < 0)
+				return ret;
+			break;
+
+		case SNDCTL_DSP_GETISPACE:
+		case SNDCTL_DSP_GETOSPACE:
+			dmap = dmap_out;
+			if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
+				return -EINVAL;
+			if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
+				return -EINVAL;
+			if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
+				dmap = dmap_in;
+			if (dmap->mapping_flags & DMA_MAP_MAPPED)
+				return -EINVAL;
+			if (!(dmap->flags & DMA_ALLOC_DONE))
+				reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
+			info.fragstotal = dmap->nbufs;
+			if (cmd == SNDCTL_DSP_GETISPACE)
+				info.fragments = dmap->qlen;
+			else 
+			{
+				if (!DMAbuf_space_in_queue(dev))
+					info.fragments = 0;
+				else
+				{
+					info.fragments = DMAbuf_space_in_queue(dev);
+					if (audio_devs[dev]->d->local_qlen) 
+					{
+						int tmp = audio_devs[dev]->d->local_qlen(dev);
+						if (tmp && info.fragments)
+							tmp--;	/*
+								 * This buffer has been counted twice
+								 */
+						info.fragments -= tmp;
+					}
 				}
 			}
-		}
-		if (info.fragments < 0)
+			if (info.fragments < 0)
 				info.fragments = 0;
-		else if (info.fragments > dmap->nbufs)
-			info.fragments = dmap->nbufs;
+			else if (info.fragments > dmap->nbufs)
+				info.fragments = dmap->nbufs;
 
-		info.fragsize = dmap->fragment_size;
-		info.bytes = info.fragments * dmap->fragment_size;
+			info.fragsize = dmap->fragment_size;
+			info.bytes = info.fragments * dmap->fragment_size;
 
-		if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
-			info.bytes -= dmap->counts[dmap->qhead];
-		else {
-			info.fragments = info.bytes / dmap->fragment_size;
-			info.bytes -= dmap->user_counter % dmap->fragment_size;
-		}
-		return __copy_to_user(arg, &info, sizeof(info));
+			if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
+				info.bytes -= dmap->counts[dmap->qhead];
+			else 
+			{
+				info.fragments = info.bytes / dmap->fragment_size;
+				info.bytes -= dmap->user_counter % dmap->fragment_size;
+			}
+			return copy_to_user(arg, &info, sizeof(info));
 
-	case SNDCTL_DSP_SETTRIGGER:
-		if (__get_user(bits, (int *)arg))
-			return -EFAULT;
-		bits &= audio_devs[dev]->open_mode;
-		if (audio_devs[dev]->d->trigger == NULL)
-			return -EINVAL;
-		if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
-		    (bits & PCM_ENABLE_OUTPUT))
-			return -EINVAL;
-		save_flags(flags);
-		cli();
-		changed = audio_devs[dev]->enable_bits ^ bits;
-		if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go) {
-			reorganize_buffers(dev, dmap_in, 1);
-			if ((err = audio_devs[dev]->d->prepare_for_input(dev,
+		case SNDCTL_DSP_SETTRIGGER:
+			if (get_user(bits, (int *)arg))
+				return -EFAULT;
+			bits &= audio_devs[dev]->open_mode;
+			if (audio_devs[dev]->d->trigger == NULL)
+				return -EINVAL;
+			if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
+				(bits & PCM_ENABLE_OUTPUT))
+				return -EINVAL;
+			save_flags(flags);
+			cli();
+			changed = audio_devs[dev]->enable_bits ^ bits;
+			if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go) 
+			{
+				reorganize_buffers(dev, dmap_in, 1);
+				if ((err = audio_devs[dev]->d->prepare_for_input(dev,
 					     dmap_in->fragment_size, dmap_in->nbufs)) < 0)
-				return -err;
-			dmap_in->dma_mode = DMODE_INPUT;
+					return -err;
+				dmap_in->dma_mode = DMODE_INPUT;
+				audio_devs[dev]->enable_bits = bits;
+				DMAbuf_activate_recording(dev, dmap_in);
+			}
+			if ((changed & bits) & PCM_ENABLE_OUTPUT &&
+			    (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
+			    audio_devs[dev]->go) 
+			{
+				if (!(dmap_out->flags & DMA_ALLOC_DONE))
+					reorganize_buffers(dev, dmap_out, 0);
+				dmap_out->dma_mode = DMODE_OUTPUT;
+				audio_devs[dev]->enable_bits = bits;
+				dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
+				DMAbuf_launch_output(dev, dmap_out);
+			}
 			audio_devs[dev]->enable_bits = bits;
-			DMAbuf_activate_recording(dev, dmap_in);
-		}
-		if ((changed & bits) & PCM_ENABLE_OUTPUT &&
-		    (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
-		    audio_devs[dev]->go) {
+			if (changed && audio_devs[dev]->d->trigger)
+				audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
+			restore_flags(flags);
+			/* Falls through... */
+
+		case SNDCTL_DSP_GETTRIGGER:
+			ret = audio_devs[dev]->enable_bits;
+			break;
+
+		case SNDCTL_DSP_SETSYNCRO:
+			if (!audio_devs[dev]->d->trigger)
+				return -EINVAL;
+			audio_devs[dev]->d->trigger(dev, 0);
+			audio_devs[dev]->go = 0;
+			return 0;
+
+		case SNDCTL_DSP_GETIPTR:
+			if (!(audio_devs[dev]->open_mode & OPEN_READ))
+				return -EINVAL;
+			save_flags(flags);
+			cli();
+			cinfo.bytes = dmap_in->byte_counter;
+			cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
+			if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
+				cinfo.bytes += dmap_in->bytes_in_use;	/* Pointer wrap not handled yet */
+			cinfo.blocks = dmap_in->qlen;
+			cinfo.bytes += cinfo.ptr;
+			if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
+				dmap_in->qlen = 0;	/* Reset interrupt counter */
+			restore_flags(flags);
+			return copy_to_user(arg, &cinfo, sizeof(cinfo));
+
+		case SNDCTL_DSP_GETOPTR:
+			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+				return -EINVAL;
+
+			save_flags(flags);
+			cli();
+			cinfo.bytes = dmap_out->byte_counter;
+			cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
+			if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
+				cinfo.bytes += dmap_out->bytes_in_use;	/* Pointer wrap not handled yet */
+			cinfo.blocks = dmap_out->qlen;
+			cinfo.bytes += cinfo.ptr;
+			if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
+				dmap_out->qlen = 0;	/* Reset interrupt counter */
+			restore_flags(flags);
+			return copy_to_user(arg, &cinfo, sizeof(cinfo));
+
+		case SNDCTL_DSP_GETODELAY:
+			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+				return -EINVAL;
 			if (!(dmap_out->flags & DMA_ALLOC_DONE))
-				reorganize_buffers(dev, dmap_out, 0);
-			dmap_out->dma_mode = DMODE_OUTPUT;
-			audio_devs[dev]->enable_bits = bits;
-			dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
-			DMAbuf_launch_output(dev, dmap_out);
-		}
-		audio_devs[dev]->enable_bits = bits;
-		if (changed && audio_devs[dev]->d->trigger)
-			audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
-		restore_flags(flags);
-		/* Falls through... */
-
-	case SNDCTL_DSP_GETTRIGGER:
-		ret = audio_devs[dev]->enable_bits;
-		return __put_user(ret, (int *)arg);
-
-	case SNDCTL_DSP_SETSYNCRO:
-		if (!audio_devs[dev]->d->trigger)
-			return -EINVAL;
-		audio_devs[dev]->d->trigger(dev, 0);
-		audio_devs[dev]->go = 0;
-		return 0;
-
-	case SNDCTL_DSP_GETIPTR:
-		if (!(audio_devs[dev]->open_mode & OPEN_READ))
-			return -EINVAL;
-		save_flags(flags);
-		cli();
-		cinfo.bytes = dmap_in->byte_counter;
-		cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
-		if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
-			cinfo.bytes += dmap_in->bytes_in_use;	/* Pointer wrap not handled yet */
-		cinfo.blocks = dmap_in->qlen;
-		cinfo.bytes += cinfo.ptr;
-		if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
-			dmap_in->qlen = 0;	/* Reset interrupt counter */
-		restore_flags(flags);
-		return __copy_to_user(arg, &cinfo, sizeof(cinfo));
-
-	case SNDCTL_DSP_GETOPTR:
-		if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
-			return -EINVAL;
-
-		save_flags(flags);
-		cli();
-		cinfo.bytes = dmap_out->byte_counter;
-		cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
-		if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
-			cinfo.bytes += dmap_out->bytes_in_use;	/* Pointer wrap not handled yet */
-		cinfo.blocks = dmap_out->qlen;
-		cinfo.bytes += cinfo.ptr;
-		if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
-			dmap_out->qlen = 0;	/* Reset interrupt counter */
-		restore_flags(flags);
-		return __copy_to_user(arg, &cinfo, sizeof(cinfo));
-
-	case SNDCTL_DSP_GETODELAY:
-		if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
-			return -EINVAL;
-		if (!(dmap_out->flags & DMA_ALLOC_DONE))
-			return __put_user(0, (int *)arg);
-		save_flags(flags);
-		cli();
-		/* Compute number of bytes that have been played */
-		count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
-		if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
-			count += dmap_out->bytes_in_use;	/* Pointer wrap not handled yet */
-		count += dmap_out->byte_counter;
-		/* Substract current count from the number of bytes written by app */
-		count = dmap_out->user_counter - count;
-		if (count < 0)
-			count = 0;
-		restore_flags (flags);
-		return __put_user(count, (int *)arg);
-
-	case SNDCTL_DSP_POST:
-		if (audio_devs[dev]->dmap_out->qlen > 0)
-			if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
-				DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
-		return 0;
-
-	case SNDCTL_DSP_GETBLKSIZE:
-		dmap = dmap_out;
-		if (audio_devs[dev]->open_mode & OPEN_WRITE)
-			reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
-		if (audio_devs[dev]->open_mode == OPEN_READ ||
-		    (audio_devs[dev]->flags & DMA_DUPLEX &&
-		     audio_devs[dev]->open_mode & OPEN_READ))
-			reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
-		if (audio_devs[dev]->open_mode == OPEN_READ)
-			dmap = dmap_in;
-		ret = dmap->fragment_size;
-		return __put_user(ret, (int *)arg);
-
-	case SNDCTL_DSP_SETFRAGMENT:
-		ret = 0;
-		if (__get_user(fact, (int *)arg))
-			return -EFAULT;
-		if (audio_devs[dev]->open_mode & OPEN_WRITE)
-			ret = dma_set_fragment(dev, dmap_out, fact);
-		if (ret < 0)
-			return ret;
-		if (audio_devs[dev]->open_mode == OPEN_READ ||
-		    (audio_devs[dev]->flags & DMA_DUPLEX &&
-		     audio_devs[dev]->open_mode & OPEN_READ))
-			ret = dma_set_fragment(dev, dmap_in, fact);
-		if (ret < 0)
-			return ret;
-		if (!arg) /* don't know what this is good for, but preserve old semantics */
+			{
+				ret=0;
+				break;
+			}
+			save_flags(flags);
+			cli();
+			/* Compute number of bytes that have been played */
+			count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
+			if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
+				count += dmap_out->bytes_in_use;	/* Pointer wrap not handled yet */
+			count += dmap_out->byte_counter;
+			/* Substract current count from the number of bytes written by app */
+			count = dmap_out->user_counter - count;
+			if (count < 0)
+				count = 0;
+			restore_flags (flags);
+			ret = count;
+			break;
+
+		case SNDCTL_DSP_POST:
+			if (audio_devs[dev]->dmap_out->qlen > 0)
+				if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
+					DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
 			return 0;
-		return __put_user(ret, (int *)arg);
 
-	default:
-		if (!audio_devs[dev]->d->ioctl)
-			return -EINVAL;
-		return audio_devs[dev]->d->ioctl(dev, cmd, arg);
+		case SNDCTL_DSP_GETBLKSIZE:
+			dmap = dmap_out;
+			if (audio_devs[dev]->open_mode & OPEN_WRITE)
+				reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
+			if (audio_devs[dev]->open_mode == OPEN_READ ||
+			    (audio_devs[dev]->flags & DMA_DUPLEX &&
+			     audio_devs[dev]->open_mode & OPEN_READ))
+				reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
+			if (audio_devs[dev]->open_mode == OPEN_READ)
+				dmap = dmap_in;
+			ret = dmap->fragment_size;
+			break;
+
+		case SNDCTL_DSP_SETFRAGMENT:
+			ret = 0;
+			if (get_user(fact, (int *)arg))
+				return -EFAULT;
+			if (audio_devs[dev]->open_mode & OPEN_WRITE)
+				ret = dma_set_fragment(dev, dmap_out, fact);
+			if (ret < 0)
+				return ret;
+			if (audio_devs[dev]->open_mode == OPEN_READ ||
+			    (audio_devs[dev]->flags & DMA_DUPLEX &&
+			     audio_devs[dev]->open_mode & OPEN_READ))
+				ret = dma_set_fragment(dev, dmap_in, fact);
+			if (ret < 0)
+				return ret;
+			if (!arg) /* don't know what this is good for, but preserve old semantics */
+				return 0;
+			break;
+
+		default:
+			if (!audio_devs[dev]->d->ioctl)
+				return -EINVAL;
+			return audio_devs[dev]->d->ioctl(dev, cmd, arg);
 	}
+	return put_user(ret, (int *)arg);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov