ghd_dma.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* free dma handle and controller handle allocated in ghd_dmaget()
*/
void
{
gcmdp->cmd_totxfer = 0;
}
}
int
int dma_flags,
int (*callback)(),
void (*sg_func)())
{
#if defined(__sparc)
int sg_size = 1;
#else
#endif
int status;
int num_segs = 0;
int single_seg = TRUE;
GDBG_DMA(("ghd_dmaget: start: gcmdp 0x%p lim 0x%p h 0x%p w 0x%p\n",
(void *)gcmdp->cmd_dmawin));
goto new_handle;
goto nextwin;
do {
&gcmdp->cmd_dmaseg);
switch (status) {
case DDI_SUCCESS:
break;
case DDI_DMA_DONE:
if (num_segs == 0) {
/* start the next window */
goto nextwin;
}
return (TRUE);
default:
return (FALSE);
}
&cookie);
/*
* Can't do the transfer in a single segment,
*/
single_seg = FALSE;
}
/* call the controller specific S/G function */
/* take care of the loop-bookkeeping */
single_seg = FALSE;
num_segs++;
return (TRUE);
/*
* First time, need to establish the handle.
*/
&gcmdp->cmd_dma_handle);
GDBG_DMA(("ghd_dmaget: setup: gcmdp 0x%p status %d\n",
switch (status) {
case DDI_DMA_MAPOK:
case DDI_DMA_PARTIAL_MAP:
/* enable first call to ddi_dma_nextwin */
break;
case DDI_DMA_NORESOURCES:
return (FALSE);
case DDI_DMA_TOOBIG:
return (FALSE);
case DDI_DMA_NOMAPPING:
default:
return (FALSE);
}
/*
* get the next window
*/
&gcmdp->cmd_dmawin);
GDBG_DMA(("ghd_dmaget: nextwin: gcmdp 0x%p status %d\n",
switch (status) {
case DDI_SUCCESS:
break;
case DDI_DMA_DONE:
return (FALSE);
default:
return (FALSE);
}
goto nextseg;
}