⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmabuf.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	dmap->user_counter += l;	dmap->flags |= DMA_DIRTY;	if (dmap->byte_counter >= dmap->max_byte_counter) {		/* Wrap the byte counters */		long decr = dmap->byte_counter;		dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);		decr -= dmap->byte_counter;		dmap->user_counter -= decr;	}	end_ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;	p = (dmap->user_counter - 1) % dmap->bytes_in_use;	dmap->neutral_byte = dmap->raw_buf[p];	/* Update the fragment based bookkeeping too */	while (ptr < end_ptr) {		dmap->counts[dmap->qtail] = dmap->fragment_size;		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;		dmap->qlen++;		ptr += dmap->fragment_size;	}	dmap->counts[dmap->qtail] = dmap->user_counter - ptr;	/*	 *	Let the low level driver to perform some postprocessing to	 *	the written data.	 */	if (adev->d->postprocess_write)		adev->d->postprocess_write(dev);	if (!(dmap->flags & DMA_ACTIVE))		if (dmap->qlen > 1 || (dmap->qlen > 0 && (post || dmap->qlen >= dmap->nbufs - 1)))			DMAbuf_launch_output(dev, dmap);	return 0;}int DMAbuf_start_dma(int dev, unsigned long physaddr, int count, int dma_mode){	struct audio_operations *adev = audio_devs[dev];	struct dma_buffparms *dmap = (dma_mode == DMA_MODE_WRITE) ? adev->dmap_out : adev->dmap_in;	if (dmap->raw_buf == NULL) {		printk(KERN_ERR "sound: DMA buffer(1) == NULL\n");		printk("Device %d, chn=%s\n", dev, (dmap == adev->dmap_out) ? "out" : "in");		return 0;	}	if (dmap->dma < 0)		return 0;	sound_start_dma(dmap, physaddr, count, dma_mode);	return count;}static int local_start_dma(struct audio_operations *adev, unsigned long physaddr, int count, int dma_mode){	struct dma_buffparms *dmap = (dma_mode == DMA_MODE_WRITE) ? adev->dmap_out : adev->dmap_in;	if (dmap->raw_buf == NULL) {		printk(KERN_ERR "sound: DMA buffer(2) == NULL\n");		printk(KERN_ERR "Device %s, chn=%s\n", adev->name, (dmap == adev->dmap_out) ? "out" : "in");		return 0;	}	if (dmap->flags & DMA_NODMA)		return 1;	if (dmap->dma < 0)		return 0;	sound_start_dma(dmap, dmap->raw_buf_phys, dmap->bytes_in_use, dma_mode | DMA_AUTOINIT);	dmap->flags |= DMA_STARTED;	return count;}static void finish_output_interrupt(int dev, struct dma_buffparms *dmap){	struct audio_operations *adev = audio_devs[dev];	if (dmap->audio_callback != NULL)		dmap->audio_callback(dev, dmap->callback_parm);	wake_up(&adev->out_sleeper);	wake_up(&adev->poll_sleeper);}static void do_outputintr(int dev, int dummy){	struct audio_operations *adev = audio_devs[dev];	unsigned long flags;	struct dma_buffparms *dmap = adev->dmap_out;	int this_fragment;	if (dmap->raw_buf == NULL) {		printk(KERN_ERR "Sound: Error. Audio interrupt (%d) after freeing buffers.\n", dev);		return;	}	if (dmap->mapping_flags & DMA_MAP_MAPPED) {	/* Virtual memory mapped access */		/* mmapped access */		dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;		if (dmap->qhead == 0) {	    /* Wrapped */			dmap->byte_counter += dmap->bytes_in_use;			if (dmap->byte_counter >= dmap->max_byte_counter) {	/* Overflow */				long decr = dmap->byte_counter;				dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);				decr -= dmap->byte_counter;				dmap->user_counter -= decr;			}		}		dmap->qlen++;	/* Yes increment it (don't decrement) */		if (!(adev->flags & DMA_AUTOMODE))			dmap->flags &= ~DMA_ACTIVE;		dmap->counts[dmap->qhead] = dmap->fragment_size;		DMAbuf_launch_output(dev, dmap);		finish_output_interrupt(dev, dmap);		return;	}	save_flags(flags);	cli();	dmap->qlen--;	this_fragment = dmap->qhead;	dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;	if (dmap->qhead == 0) {	/* Wrapped */		dmap->byte_counter += dmap->bytes_in_use;		if (dmap->byte_counter >= dmap->max_byte_counter) {	/* Overflow */			long decr = dmap->byte_counter;			dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);			decr -= dmap->byte_counter;			dmap->user_counter -= decr;		}	}	if (!(adev->flags & DMA_AUTOMODE))		dmap->flags &= ~DMA_ACTIVE;			/*	 *	This is  dmap->qlen <= 0 except when closing when	 *	dmap->qlen < 0	 */	 	while (dmap->qlen <= -dmap->closing) {		dmap->underrun_count++;		dmap->qlen++;		if ((dmap->flags & DMA_DIRTY) && dmap->applic_profile != APF_CPUINTENS) {			dmap->flags &= ~DMA_DIRTY;			memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte,			       adev->dmap_out->buffsize);		}		dmap->user_counter += dmap->fragment_size;		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;	}	if (dmap->qlen > 0)		DMAbuf_launch_output(dev, dmap);	restore_flags(flags);	finish_output_interrupt(dev, dmap);}void DMAbuf_outputintr(int dev, int notify_only){	struct audio_operations *adev = audio_devs[dev];	unsigned long flags;	struct dma_buffparms *dmap = adev->dmap_out;	save_flags(flags);	cli();	if (!(dmap->flags & DMA_NODMA)) {		int chan = dmap->dma, pos, n;		unsigned long f;				f=claim_dma_lock();				if(!isa_dma_bridge_buggy)			disable_dma(dmap->dma);		clear_dma_ff(chan);		pos = dmap->bytes_in_use - get_dma_residue(chan);		if(!isa_dma_bridge_buggy)			enable_dma(dmap->dma);		release_dma_lock(f);				pos = pos / dmap->fragment_size;	/* Actual qhead */		if (pos < 0 || pos >= dmap->nbufs)			pos = 0;		n = 0;		while (dmap->qhead != pos && n++ < dmap->nbufs)			do_outputintr(dev, notify_only);	}	else		do_outputintr(dev, notify_only);	restore_flags(flags);}static void do_inputintr(int dev){	struct audio_operations *adev = audio_devs[dev];	struct dma_buffparms *dmap = adev->dmap_in;	if (dmap->raw_buf == NULL) {		printk(KERN_ERR "Sound: Fatal error. Audio interrupt after freeing buffers.\n");		return;	}	if (dmap->mapping_flags & DMA_MAP_MAPPED) {		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;		if (dmap->qtail == 0) {		/* Wrapped */			dmap->byte_counter += dmap->bytes_in_use;			if (dmap->byte_counter >= dmap->max_byte_counter) {	/* Overflow */				long decr = dmap->byte_counter;				dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;				decr -= dmap->byte_counter;				dmap->user_counter -= decr;			}		}		dmap->qlen++;		if (!(adev->flags & DMA_AUTOMODE)) {			if (dmap->needs_reorg)				reorganize_buffers(dev, dmap, 0);			local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use,DMA_MODE_READ);			adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size,					     dmap->fragment_size, 1);			if (adev->d->trigger)				adev->d->trigger(dev, adev->enable_bits * adev->go);		}		dmap->flags |= DMA_ACTIVE;	} else if (dmap->qlen >= (dmap->nbufs - 1)) {		printk(KERN_WARNING "Sound: Recording overrun\n");		dmap->underrun_count++;		/* Just throw away the oldest fragment but keep the engine running */		dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;	} else if (dmap->qlen >= 0 && dmap->qlen < dmap->nbufs) {		dmap->qlen++;		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;		if (dmap->qtail == 0) {		/* Wrapped */			dmap->byte_counter += dmap->bytes_in_use;			if (dmap->byte_counter >= dmap->max_byte_counter) {	/* Overflow */				long decr = dmap->byte_counter;				dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;				decr -= dmap->byte_counter;				dmap->user_counter -= decr;			}		}	}	if (!(adev->flags & DMA_AUTOMODE) || (dmap->flags & DMA_NODMA)) {		local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use, DMA_MODE_READ);		adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size, dmap->fragment_size, 1);		if (adev->d->trigger)			adev->d->trigger(dev,adev->enable_bits * adev->go);	}	dmap->flags |= DMA_ACTIVE;	if (dmap->qlen > 0)	{		wake_up(&adev->in_sleeper);		wake_up(&adev->poll_sleeper);	}}void DMAbuf_inputintr(int dev){	struct audio_operations *adev = audio_devs[dev];	struct dma_buffparms *dmap = adev->dmap_in;	unsigned long flags;	save_flags(flags);	cli();	if (!(dmap->flags & DMA_NODMA)) {		int chan = dmap->dma, pos, n;		unsigned long f;				f=claim_dma_lock();		if(!isa_dma_bridge_buggy)			disable_dma(dmap->dma);		clear_dma_ff(chan);		pos = dmap->bytes_in_use - get_dma_residue(chan);		if(!isa_dma_bridge_buggy)			enable_dma(dmap->dma);		release_dma_lock(f);		pos = pos / dmap->fragment_size;	/* Actual qhead */		if (pos < 0 || pos >= dmap->nbufs)			pos = 0;		n = 0;		while (dmap->qtail != pos && ++n < dmap->nbufs)			do_inputintr(dev);	} else		do_inputintr(dev);	restore_flags(flags);}int DMAbuf_open_dma(int dev){	/*	 *    NOTE!  This routine opens only the primary DMA channel (output).	 */	struct audio_operations *adev = audio_devs[dev];	int err;	if ((err = open_dmap(adev, OPEN_READWRITE, adev->dmap_out)) < 0)		return -EBUSY;	dma_init_buffers(adev->dmap_out);	adev->dmap_out->flags |= DMA_ALLOC_DONE;	adev->dmap_out->fragment_size = adev->dmap_out->buffsize;	if (adev->dmap_out->dma >= 0) {		unsigned long flags;		flags=claim_dma_lock();		clear_dma_ff(adev->dmap_out->dma);		disable_dma(adev->dmap_out->dma);		release_dma_lock(flags);	}	return 0;}void DMAbuf_close_dma(int dev){	close_dmap(audio_devs[dev], audio_devs[dev]->dmap_out);}void DMAbuf_init(int dev, int dma1, int dma2){	struct audio_operations *adev = audio_devs[dev];	/*	 * NOTE! This routine could be called several times.	 */	/* drag in audio_syms.o */	{		extern char audio_syms_symbol;		audio_syms_symbol = 0;	}	if (adev && adev->dmap_out == NULL) {		if (adev->d == NULL)			panic("OSS: audio_devs[%d]->d == NULL\n", dev);		if (adev->parent_dev) {	 /* Use DMA map of the parent dev */			int parent = adev->parent_dev - 1;			adev->dmap_out = audio_devs[parent]->dmap_out;			adev->dmap_in = audio_devs[parent]->dmap_in;		} else {			adev->dmap_out = adev->dmap_in = &adev->dmaps[0];			adev->dmap_out->dma = dma1;			if (adev->flags & DMA_DUPLEX) {				adev->dmap_in = &adev->dmaps[1];				adev->dmap_in->dma = dma2;			}		}		/* Persistent DMA buffers allocated here */		if (sound_dmap_flag == DMAP_KEEP_ON_CLOSE) {			if (adev->dmap_in->raw_buf == NULL)				sound_alloc_dmap(adev->dmap_in);			if (adev->dmap_out->raw_buf == NULL)				sound_alloc_dmap(adev->dmap_out);		}	}}/* No kernel lock - DMAbuf_activate_recording protected by global cli/sti */static unsigned int poll_input(struct file * file, int dev, poll_table *wait){	struct audio_operations *adev = audio_devs[dev];	struct dma_buffparms *dmap = adev->dmap_in;	if (!(adev->open_mode & OPEN_READ))		return 0;	if (dmap->mapping_flags & DMA_MAP_MAPPED) {		if (dmap->qlen)			return POLLIN | POLLRDNORM;		return 0;	}	if (dmap->dma_mode != DMODE_INPUT) {		if (dmap->dma_mode == DMODE_NONE &&		    adev->enable_bits & PCM_ENABLE_INPUT &&		    !dmap->qlen && adev->go) {			unsigned long flags;						save_flags(flags);			cli();			DMAbuf_activate_recording(dev, dmap);			restore_flags(flags);		}		return 0;	}	if (!dmap->qlen)		return 0;	return POLLIN | POLLRDNORM;}static unsigned int poll_output(struct file * file, int dev, poll_table *wait){	struct audio_operations *adev = audio_devs[dev];	struct dma_buffparms *dmap = adev->dmap_out;		if (!(adev->open_mode & OPEN_WRITE))		return 0;	if (dmap->mapping_flags & DMA_MAP_MAPPED) {		if (dmap->qlen)			return POLLOUT | POLLWRNORM;		return 0;	}	if (dmap->dma_mode == DMODE_INPUT)		return 0;	if (dmap->dma_mode == DMODE_NONE)		return POLLOUT | POLLWRNORM;	if (!DMAbuf_space_in_queue(dev))		return 0;	return POLLOUT | POLLWRNORM;}unsigned int DMAbuf_poll(struct file * file, int dev, poll_table *wait){	struct audio_operations *adev = audio_devs[dev];	poll_wait(file, &adev->poll_sleeper, wait);	return poll_input(file, dev, wait) | poll_output(file, dev, wait);}void DMAbuf_deinit(int dev){	struct audio_operations *adev = audio_devs[dev];	/* This routine is called when driver is being unloaded */	if (!adev)		return;	/* Persistent DMA buffers deallocated here */	if (sound_dmap_flag == DMAP_KEEP_ON_CLOSE) {		sound_free_dmap(adev->dmap_out);		if (adev->flags & DMA_DUPLEX)			sound_free_dmap(adev->dmap_in);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -