File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #include <inttypes.h>
0051 #include <stdint.h>
0052 #include <stdlib.h>
0053 #include <stdio.h>
0054 #include <string.h>
0055
0056 #define DEBUG
0057 #include <bsp/VMEDMA.h>
0058 #include <bsp/bspVmeDmaList.h>
0059 #include "bspVmeDmaListP.h"
0060
0061
0062 typedef struct VMEDmaListNodeRec_ {
0063 VMEDmaListNode p, n;
0064 DmaDescriptor d;
0065 void *usrData;
0066 VMEDmaListClass class;
0067 } VMEDmaListNodeRec;
0068
0069 #define LCHUNK 10
0070
0071 #ifdef DEBUG
0072 static void
0073 lprint(VMEDmaListNode d)
0074 {
0075 printf("n 0x%08" PRIu32", p: 0x%08" PRIu32 ", n: 0x%08" PRIu32 " d: 0x%08" PRIu32 "\n",
0076 (uint32_t)d, (uint32_t)d->p, (uint32_t)d->n, (uint32_t)d->d);
0077 }
0078 #endif
0079
0080 static VMEDmaListNode
0081 lalloc(VMEDmaListClass pc)
0082 {
0083 VMEDmaListNode rval;
0084 int i;
0085
0086 if ( !pc->freeList ) {
0087
0088 pc->freeList = calloc( (LCHUNK), sizeof(*pc->freeList));
0089
0090 if ( ! (pc->freeList) ) {
0091 return 0;
0092 }
0093
0094
0095 for (i=0; i<(LCHUNK)-1; i++) {
0096 pc->freeList[i].n = &pc->freeList[i+1];
0097 pc->freeList[i].class = pc;
0098 }
0099 pc->freeList[i].n = 0;
0100 pc->freeList[i].class = pc;
0101
0102
0103 if ( pc->desc_alloc ) {
0104 for (i=0; i<(LCHUNK); i++) {
0105 if ( ! (pc->freeList[i].d = pc->desc_alloc()) ) {
0106 int j;
0107 if ( pc->desc_free ) {
0108 for (j=0; j<i; j++)
0109 pc->desc_free(pc->freeList[i].d);
0110 }
0111 free(pc->freeList);
0112 pc->freeList = 0;
0113 return 0;
0114 }
0115 }
0116 } else {
0117 int blksize;
0118 uint32_t algnmsk = pc->desc_align - 1;
0119 char *memptr;
0120
0121
0122 pc->desc_free = 0;
0123
0124 blksize = (pc->desc_size + algnmsk) & ~algnmsk;
0125
0126 if ( ! (memptr = malloc(blksize*(LCHUNK) + pc->desc_align - 1)) ) {
0127 free(pc->freeList);
0128 pc->freeList = 0;
0129 return 0;
0130 }
0131
0132
0133 memptr = (char*)( ((uint32_t)memptr + algnmsk) & ~ algnmsk );
0134
0135 for ( i = 0; i<(LCHUNK); i++, memptr+=blksize ) {
0136 memset(memptr, 0, blksize);
0137 pc->freeList[i].d = (DmaDescriptor)memptr;
0138 }
0139 }
0140 }
0141 rval = pc->freeList;
0142 pc->freeList = pc->freeList->n;
0143 rval->n = rval->p = 0;
0144 return rval;
0145 }
0146
0147 static int
0148 lfree(VMEDmaListNode d)
0149 {
0150 if ( d->p || d->n )
0151 return -1;
0152 d->n = d->class->freeList;
0153 d->class->freeList = d;
0154 return 0;
0155 }
0156
0157 static int
0158 lenq(VMEDmaListNode a, VMEDmaListNode d)
0159 {
0160 if ( a ) {
0161
0162 if ( d->n || d->p )
0163 return -1;
0164 if ( (d->n = a->n) )
0165 a->n->p = d;
0166 d->p = a;
0167 a->n = d;
0168 } else {
0169
0170 if ( d->n )
0171 d->n->p = d->p;
0172 if ( d->p )
0173 d->p->n = d->n;
0174 d->n = d->p = 0;
0175 }
0176 return 0;
0177 }
0178
0179
0180 int
0181 BSP_VMEDmaListDescriptorStartTool(volatile void *controller, int channel, VMEDmaListNode n)
0182 {
0183 if ( !n )
0184 return -1;
0185 return n->class->desc_start(controller, channel, n->d);
0186 }
0187
0188 VMEDmaListNode
0189 BSP_VMEDmaListDescriptorSetupTool(
0190 VMEDmaListNode n,
0191 uint32_t attr_mask,
0192 uint32_t xfer_mode,
0193 uint32_t pci_addr,
0194 uint32_t vme_addr,
0195 uint32_t n_bytes)
0196 {
0197 if ( !n )
0198 return 0;
0199
0200 if ( n->class->desc_setup(n->d, attr_mask, xfer_mode, pci_addr, vme_addr, n_bytes) ) {
0201 return 0;
0202 }
0203
0204 return n;
0205 }
0206
0207 VMEDmaListNode
0208 BSP_VMEDmaListDescriptorNewTool(
0209 VMEDmaListClass pc,
0210 uint32_t attr_mask,
0211 uint32_t xfer_mode,
0212 uint32_t pci_addr,
0213 uint32_t vme_addr,
0214 uint32_t n_bytes)
0215 {
0216 VMEDmaListNode n;
0217
0218 if ( !(n=lalloc(pc)) )
0219 return 0;
0220
0221 if ( n->class->desc_init )
0222 n->class->desc_init(n->d);
0223
0224 if ( n->class->desc_setup(n->d, attr_mask, xfer_mode, pci_addr, vme_addr, n_bytes) ) {
0225 BSP_VMEDmaListDescriptorDestroy(n);
0226 return 0;
0227 }
0228 return n;
0229 }
0230
0231 int
0232 BSP_VMEDmaListDescriptorDestroy(BSP_VMEDmaListDescriptor p)
0233 {
0234 VMEDmaListNode d = p;
0235 return lfree(d);
0236 }
0237
0238 int
0239 BSP_VMEDmaListDestroy(BSP_VMEDmaListDescriptor p)
0240 {
0241 VMEDmaListNode d = p;
0242 VMEDmaListNode n;
0243 while (d) {
0244 n = d->n;
0245 if ( BSP_VMEDmaListDescriptorEnq(0, d) ||
0246 BSP_VMEDmaListDescriptorDestroy(d) )
0247 return -1;
0248 d = n;
0249 }
0250 return 0;
0251 }
0252
0253 int
0254 BSP_VMEDmaListDescriptorEnq(BSP_VMEDmaListDescriptor p, BSP_VMEDmaListDescriptor q)
0255 {
0256 VMEDmaListNode anchor = p;
0257 VMEDmaListNode d = q;
0258 DmaDescriptorSetNxt setnxt = d->class->desc_setnxt;
0259
0260 if ( !anchor ) {
0261
0262 if ( d->p )
0263 setnxt(d->p->d, d->n ? d->n->d : 0);
0264
0265 setnxt(d->d, 0);
0266 } else {
0267 if ( d->class != anchor->class )
0268 return -1;
0269 }
0270 if ( lenq(anchor, d) )
0271 return -1;
0272
0273 if ( anchor ) {
0274 setnxt(d->d, d->n ? d->n->d : 0);
0275 setnxt(anchor->d, d->d);
0276 }
0277 return 0;
0278 }
0279
0280 BSP_VMEDmaListDescriptor
0281 BSP_VMEDmaListDescriptorNext(BSP_VMEDmaListDescriptor p)
0282 {
0283 VMEDmaListNode d = p;
0284 return d->n;
0285 }
0286
0287 BSP_VMEDmaListDescriptor
0288 BSP_VMEDmaListDescriptorPrev(BSP_VMEDmaListDescriptor p)
0289 {
0290 VMEDmaListNode d = p;
0291 return d->p;
0292 }
0293
0294 void
0295 BSP_VMEDmaListDescriptorSetUsr(BSP_VMEDmaListDescriptor p, void *usrData)
0296 {
0297 VMEDmaListNode d = p;
0298 d->usrData = usrData;
0299 }
0300
0301 void *
0302 BSP_VMEDmaListDescriptorGetUsr(BSP_VMEDmaListDescriptor p)
0303 {
0304 VMEDmaListNode d = p;
0305 return d->usrData;
0306 }
0307
0308 int
0309 BSP_VMEDmaListRefresh(BSP_VMEDmaListDescriptor p)
0310 {
0311 VMEDmaListNode anchor = p;
0312 DmaDescriptorRefr desc_refr;
0313 VMEDmaListNode n;
0314 if ( (desc_refr = anchor->class->desc_refr) ) {
0315 for ( n = anchor; n; n = n->n ) {
0316 desc_refr(n->d);
0317 }
0318 }
0319 return 0;
0320 }
0321
0322 #ifdef DEBUG
0323 void
0324 BSP_VMEDmaListDump(BSP_VMEDmaListDescriptor p)
0325 {
0326 VMEDmaListNode d = p;
0327 while (d) {
0328 printf("----------\n");
0329 lprint(d);
0330 if (d->class->desc_dump)
0331 d->class->desc_dump(d->d);
0332 d = d->n;
0333 }
0334 }
0335 #endif