FreeBSD/sys/x86/isa/isa_dma.c
/*
 * Setup a DMA channel's bounce buffer.
 */
Setup a DMA channel's bounce buffer.
Setup a DMA channel ' s bounce buffer .
int
isa_dma_init(int chan, u_int bouncebufsize, int flag)
{
	void *buf;
	int contig;
#ifdef DIAGNOSTIC
	if (chan & ~VALID_DMA_MASK)
		panic("isa_dma_init: channel out of range");
#endif
	buf = malloc(bouncebufsize, M_DEVBUF, flag);
	if (buf != NULL) {
		if (isa_dmarangecheck(buf, bouncebufsize, chan) != 0) {
			free(buf, M_DEVBUF);
			buf = NULL;
		}
		contig = 0;
	}
	if (buf == NULL) {
		buf = contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful,
			   1ul, chan & 4 ? 0x20000ul : 0x10000ul);
		contig = 1;
	}
	if (buf == NULL)
		return (ENOMEM);
	mtx_lock(&isa_dma_lock);
	if (dma_bouncebuf[chan] != NULL) {
		if (contig)
			contigfree(buf, bouncebufsize, M_DEVBUF);
		else
			free(buf, M_DEVBUF);
		mtx_unlock(&isa_dma_lock);
		return (0);
	}
	dma_bouncebufsize[chan] = bouncebufsize;
	dma_bouncebuf[chan] = buf;
	mtx_unlock(&isa_dma_lock);
	return (0);
}
int isa_dma_init ( int chan , u_int bouncebufsize , int flag ) { void * buf ; int contig ; #ifdef DIAGNOSTIC if ( chan & ~ VALID_DMA_MASK ) panic ( " " ) ; #endif buf = malloc ( bouncebufsize , M_DEVBUF , flag ) ; if ( buf != NULL ) { if ( isa_dmarangecheck ( buf , bouncebufsize , chan ) != 0 ) { free ( buf , M_DEVBUF ) ; buf = NULL ; } contig = 0 ; } if ( buf == NULL ) { buf = contigmalloc ( bouncebufsize , M_DEVBUF , flag , 0ul , 0xfffffful , 1ul , chan & 4 ? 0x20000ul : 0x10000ul ) ; contig = 1 ; } if ( buf == NULL ) return ( ENOMEM ) ; mtx_lock ( & isa_dma_lock ) ; if ( dma_bouncebuf [ chan ] != NULL ) { if ( contig ) contigfree ( buf , bouncebufsize , M_DEVBUF ) ; else free ( buf , M_DEVBUF ) ; mtx_unlock ( & isa_dma_lock ) ; return ( 0 ) ; } dma_bouncebufsize [ chan ] = bouncebufsize ; dma_bouncebuf [ chan ] = buf ; mtx_unlock ( & isa_dma_lock ) ; return ( 0 ) ; }
Setup a DMA channel's bounce buffer.
Setup a DMA channel ' s bounce buffer .
/* Try malloc() first.  It works better if it works. */ /*
	 * If a DMA channel is shared, both drivers have to call isa_dma_init
	 * since they don't know that the other driver will do it.
	 * Just return if we're already set up good.
	 * XXX: this only works if they agree on the bouncebuf size.  This
	 * XXX: is typically the case since they are multiple instances of
	 * XXX: the same driver.
	 */