00001 /**********************************************************/ 00002 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00003 /* 00004 Copyright: 1993 - Grupo de Voz (DAET) ETSII/IT-Bilbao 00005 00006 Nombre fuente................ DMABUFF.C 00007 Nombre paquete............... - 00008 Lenguaje fuente.............. C (Borland C/C++ 3.1) 00009 Estado....................... Completado 00010 Dependencia Hard/OS.......... DMA 00011 Codigo condicional........... - 00012 00013 Codificacion................. Borja Etxebarria 00014 00015 Version dd/mm/aa Autor Proposito de la edicion 00016 ------- -------- -------- ----------------------- 00017 1.0.2 07/09/95 Borja valor de STEP y 'while' en vez de 'for' 00018 1.0.1 06/04/95 Borja diferente {extra} y STEP 00019 1.0.0 20/02/94 Borja Codificacion inicial 00020 00021 ======================== Contenido ======================== 00022 Reserva de buffer DMA sin derrochar mucho espacio. 00023 .................... 00024 Intelligent DMA buffer memory allocation to save memory. 00025 =========================================================== 00026 */ 00027 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00028 /**********************************************************/ 00029 00030 #include <stdlib.h> 00031 00032 #include "xalloc.h" 00033 #include "lmem.h" 00034 #include "dmabuff.h" 00035 00036 /**********************************************************/ 00037 /* Reserva un buffer con xmalloc() (usar xfree() para liberarlo) y 00038 {devuelve} un puntero a el, o NULL si no se puede reservar correctamente. 00039 En buffer cumplira que por lo menos hay {nbytes} utilizables en el para 00040 hacer operaciones DMA; el buffer no cruzara una pagina de {kbpage}kb 00041 (generalmente 64 o 128 kb), estara alineado a {align} bytes, y sera de 00042 multiplicidad {granularity}. Usar fixmem() definida en LMEM.C para 00043 obtener el buffer a utilizar dentro de este buffer que se reserva. 00044 En {allocbytes} se devuelve el numero de bytes reservados (se puede 00045 enviar NULL si no interesa. El valor devuelto en {allocbytes} sera 00046 en general mayor que {nbytes}. 00047 .................... 00048 This function allocates a memory buffer using xmalloc() so you must 00049 use xfree() to free it. The function {returns} a pointer to the 00050 allocated buffer, or NULL if it can not be allocated correctly. 00051 The buffer will have {nbytes} or more bytes usable for DMA operations, 00052 i.e, it will not cross a memory page of {kbpage} kbytes (send 64 for 00053 DMA8 and 128 for DMA16), it will be memory-aligned to {align} bytes, 00054 and it will have {granularity} multiplicity (i.e, the number of usable 00055 bytes will at least be a multipe of {granularity}). 00056 00057 You should use fixmem() (defined in LMEM.C) to get the actual dma 00058 buffer from the memory block returned by this function. 00059 The function returns the actual allocated memory in {allocbytes} 00060 and {allocbytes} will be greater or equal than {nbytes}. If you are 00061 not interested in this value, you can send NULL in {allocbytes} */ 00062 00063 pfVOID dmabuff_malloc( UINT32 nbytes, UINT16 kbpage, UINT32 align, 00064 UINT32 granularity, UINT32 * allocbytes ) 00065 { 00066 #define STEP 16 00067 pfVOID bptr, tptr; 00068 UINT32 tbytes, ubytes; 00069 UINT16 i; 00070 UINT32 extra; 00071 00072 tptr = NULL; 00073 extra = 0; 00074 if (align > extra) 00075 extra = align; 00076 if (granularity > extra) 00077 extra = granularity; 00078 00079 tbytes = nbytes + extra; 00080 bptr = xmalloc(tbytes); 00081 00082 if (allocbytes) 00083 *allocbytes = tbytes; 00084 00085 i = 0; 00086 do { 00087 if (bptr) { 00088 fixmem(bptr, nbytes, kbpage, align, granularity, NULL, &ubytes); 00089 if (ubytes >= nbytes) 00090 break; 00091 } 00092 else 00093 break; 00094 xfree(bptr); 00095 bptr = NULL; 00096 if (tptr) 00097 xfree(tptr); 00098 i++; 00099 tptr = xmalloc((UINT32)i * STEP); 00100 bptr = xmalloc(tbytes); 00101 } while (tptr); 00102 00103 if (tptr) 00104 xfree(tptr); 00105 if (bptr) { 00106 fixmem(bptr, nbytes, kbpage, align, granularity, NULL, &ubytes); 00107 if (ubytes >= nbytes) 00108 return bptr; 00109 xfree(bptr); 00110 } 00111 00112 return NULL; 00113 #undef STEP 00114 } 00115 00116 /**********************************************************/