kernels/linux-2.4.0/drivers/sound/dmasound/dmasound_core.c
/*
     *  Here is how the values are used for reading.
     *  The value 'active' simply indicates the DMA is running.  This is done
     *  so the driver semantics are DMA starts when the first read is posted.
     *  The value 'front' indicates the buffer we should next send to the user.
     *  The value 'rear' indicates the buffer the DMA is currently filling.
     *  When 'front' == 'rear' the buffer "ring" is empty (we always have an
     *  empty available).  The 'rear_size' is used to track partial offsets
     *  into the current buffer.  Right now, I just keep the DMA running.  If
     *  the reader can't keep up, the interrupt tosses the oldest buffer.  We
     *  could also shut down the DMA in this case.
     */
Here is how the values are used for reading.
The value 'active' simply indicates the DMA is running.  This is done
so the driver semantics are DMA starts when the first read is posted.
The value 'front' indicates the buffer we should next send to the user.
The value 'rear' indicates the buffer the DMA is currently filling.
When 'front' == 'rear' the buffer "ring" is empty (we always have an
empty available).  The 'rear_size' is used to track partial offsets
into the current buffer.  Right now, I just keep the DMA running.  If
the reader can't keep up, the interrupt tosses the oldest buffer.  We
could also shut down the DMA in this case.
Here is how the values are used for reading . The value ' active ' simply indicates the DMA is running . This is done so the driver semantics are DMA starts when the first read is posted . The value ' front ' indicates the buffer we should next send to the user . The value ' rear ' indicates the buffer the DMA is currently filling . When ' front ' == ' rear ' the buffer " ring " is empty ( we always have an empty available ) . The ' rear_size ' is used to track partial offsets into the current buffer . Right now I just keep the DMA running . If the reader can ' t keep up the interrupt tosses the oldest buffer . We could also shut down the DMA in this case .
static ssize_t sq_read(struct file *file, char *dst, size_t uLeft,
		       loff_t *ppos)
{
	ssize_t	uRead, bLeft, bUsed, uUsed;
	if (uLeft == 0)
		return 0;
	if (!read_sq.active && dmasound.mach.record)
		dmasound.mach.record();	
	uRead = 0;
	while (uLeft > 0) {
		while (read_sq.front == read_sq.rear) {
			if (read_sq.open_mode & O_NONBLOCK) {
			       return uRead > 0 ? uRead : -EAGAIN;
			}
			SLEEP(read_sq.action_queue);
			if (signal_pending(current))
				return uRead > 0 ? uRead : -EINTR;
		}
		bLeft = read_sq.block_size - read_sq.rear_size;
		bUsed = read_sq.rear_size;
		uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft,
					     read_sq.buffers[read_sq.front],
					     &bUsed, bLeft);
		if (uUsed <= 0)
			return uUsed;
		dst += uUsed;
		uRead += uUsed;
		uLeft -= uUsed;
		read_sq.rear_size += bUsed;
		if (read_sq.rear_size >= read_sq.block_size) {
			read_sq.rear_size = 0;
			read_sq.front++;
			if (read_sq.front >= read_sq.max_active)
				read_sq.front = 0;
		}
	}
	return uRead;
}
static ssize_t sq_read ( struct file * file , char * dst , size_t uLeft , loff_t * ppos ) { ssize_t uRead , bLeft , bUsed , uUsed ; if ( uLeft == 0 ) return 0 ; if ( ! read_sq . active && dmasound . mach . record ) dmasound . mach . record ( ) ; uRead = 0 ; while ( uLeft > 0 ) { while ( read_sq . front == read_sq . rear ) { if ( read_sq . open_mode & O_NONBLOCK ) { return uRead > 0 ? uRead : - EAGAIN ; } SLEEP ( read_sq . action_queue ) ; if ( signal_pending ( current ) ) return uRead > 0 ? uRead : - EINTR ; } bLeft = read_sq . block_size - read_sq . rear_size ; bUsed = read_sq . rear_size ; uUsed = sound_copy_translate ( dmasound . trans_read , dst , uLeft , read_sq . buffers [ read_sq . front ] , & bUsed , bLeft ) ; if ( uUsed <= 0 ) return uUsed ; dst += uUsed ; uRead += uUsed ; uLeft -= uUsed ; read_sq . rear_size += bUsed ; if ( read_sq . rear_size >= read_sq . block_size ) { read_sq . rear_size = 0 ; read_sq . front ++ ; if ( read_sq . front >= read_sq . max_active ) read_sq . front = 0 ; } } return uRead ; }
Here is how the values are used for reading.
Here is how the values are used for reading .
/* Kick off the record process. */ /* Move what the user requests, depending upon other options.
	*/ /* When front == rear, the DMA is not done yet.
		*/ /* The amount we move is either what is left in the
		 * current buffer or what the user wants.
		 */