drivers/comedi/drivers/comedi_isadma.c

Source file repositories/reference/linux-study-clean/drivers/comedi/drivers/comedi_isadma.c

File Facts

System
Linux kernel
Corpus path
drivers/comedi/drivers/comedi_isadma.c
Extension
.c
Size
6143 bytes
Lines
248
Domain
Driver Families
Bucket
drivers/comedi
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (new_residue == residue) {
			stalled++;
			if (stalled > 10)
				break;
		} else {
			residue = new_residue;
			stalled = 0;
		}
	}
	return residue;
}
EXPORT_SYMBOL_GPL(comedi_isadma_disable_on_sample);

/**
 * comedi_isadma_poll - poll the current DMA transfer
 * @dma:	the ISA DMA to poll
 *
 * Returns the position (in bytes) of the current DMA transfer.
 */
unsigned int comedi_isadma_poll(struct comedi_isadma *dma)
{
	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
	unsigned long flags;
	unsigned int result;
	unsigned int result1;

	flags = claim_dma_lock();
	clear_dma_ff(desc->chan);
	if (!isa_dma_bridge_buggy)
		disable_dma(desc->chan);
	result = get_dma_residue(desc->chan);
	/*
	 * Read the counter again and choose higher value in order to
	 * avoid reading during counter lower byte roll over if the
	 * isa_dma_bridge_buggy is set.
	 */
	result1 = get_dma_residue(desc->chan);
	if (!isa_dma_bridge_buggy)
		enable_dma(desc->chan);
	release_dma_lock(flags);

	if (result < result1)
		result = result1;
	if (result >= desc->size || result == 0)
		return 0;
	return desc->size - result;
}
EXPORT_SYMBOL_GPL(comedi_isadma_poll);

/**
 * comedi_isadma_set_mode - set the ISA DMA transfer direction
 * @desc:	the ISA DMA cookie to set
 * @dma_dir:	the DMA direction
 */
void comedi_isadma_set_mode(struct comedi_isadma_desc *desc, char dma_dir)
{
	desc->mode = (dma_dir == COMEDI_ISADMA_READ) ? DMA_MODE_READ
						     : DMA_MODE_WRITE;
}
EXPORT_SYMBOL_GPL(comedi_isadma_set_mode);

/**
 * comedi_isadma_alloc - allocate and initialize the ISA DMA
 * @dev:	comedi_device struct
 * @n_desc:	the number of cookies to allocate
 * @dma_chan1:	DMA channel for the first cookie
 * @dma_chan2:	DMA channel for the second cookie
 * @maxsize:	the size of the buffer to allocate for each cookie
 * @dma_dir:	the DMA direction
 *
 * Returns the allocated and initialized ISA DMA or NULL if anything fails.
 */
struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev,
					  int n_desc, unsigned int dma_chan1,
					  unsigned int dma_chan2,
					  unsigned int maxsize, char dma_dir)
{
	struct comedi_isadma *dma = NULL;
	struct comedi_isadma_desc *desc;
	unsigned int dma_chans[2];
	int i;

	if (n_desc < 1 || n_desc > 2)
		goto no_dma;

	dma = kzalloc_flex(*dma, desc, n_desc);
	if (!dma)
		goto no_dma;

	dma->n_desc = n_desc;

Annotation

Implementation Notes