]> rtime.felk.cvut.cz Git - can-usb1.git/blob - ulan/host/ul_drv/ul_drv/ul_mem.c
Initializing repo
[can-usb1.git] / ulan / host / ul_drv / ul_drv / ul_mem.c
1 /*******************************************************************
2   uLan Communication - uL_DRV - multiplatform uLan driver
3
4   ul_mem.c      - uLan memory management and linked lists
5
6   (C) Copyright 1996-2004 by Pavel Pisa - project originator
7         http://cmp.felk.cvut.cz/~pisa
8   (C) Copyright 1996-2004 PiKRON Ltd.
9         http://www.pikron.com
10   (C) Copyright 2002-2004 Petr Smolik
11   
12
13   The uLan driver project can be used and distributed 
14   in compliance with any of next licenses
15    - GPL - GNU Public License
16      See file COPYING for details.
17    - LGPL - Lesser GNU Public License
18    - MPL - Mozilla Public License
19    - and other licenses added by project originator
20
21   Code can be modified and re-distributed under any combination
22   of the above listed licenses. If contributor does not agree with
23   some of the licenses, he/she can delete appropriate line.
24   WARNING: if you delete all lines, you are not allowed to
25   distribute code or sources in any form.
26  *******************************************************************/
27
28 /*******************************************************************/
29 /* uLan memory management and bidirectional linked lists */
30
31 int ul_mem_init(ul_drv *udrv, int req_size)
32 {
33   void **pptr;
34   ul_mem_blk *bptr;
35   pptr=(void **)(udrv->mem_ptr=MALLOC(req_size+2*sizeof(void*)));
36   if(!pptr) return -1;
37   *(pptr++)=0;
38   *(pptr++)=(void *)req_size;
39   udrv->free_blk=bptr=(ul_mem_blk *)pptr;
40   udrv->free_blk_cnt=1;
41
42   while((req_size-=sizeof(ul_mem_blk))>=sizeof(ul_mem_blk))
43   {
44     bptr->next=bptr+1;
45     bptr++;
46     udrv->free_blk_cnt++;
47   }; 
48   bptr->next=NULL;
49   udrv->prep_bll.first=udrv->prep_bll.last=NULL;
50   udrv->prep_bll.cnt=0;
51   udrv->prep_bll.udrv=udrv; 
52   udrv->work_bll.first=udrv->work_bll.last=NULL;
53   udrv->work_bll.cnt=0;
54   udrv->work_bll.udrv=udrv; 
55   udrv->proc_bll.first=udrv->proc_bll.last=NULL;
56   udrv->proc_bll.cnt=0;
57   udrv->proc_bll.udrv=udrv;
58   udrv->opan_bll.first=udrv->opan_bll.last=NULL;
59   udrv->opan_bll.cnt=0;
60   udrv->opan_bll.udrv=udrv;
61   udrv->con_message=NULL;
62
63   return 0;
64 };
65
66 int ul_mem_done(ul_drv *udrv)
67 {
68   void *ptr;
69   if(udrv->mem_ptr)
70   { ptr=*(void **)udrv->mem_ptr;
71     FREE(udrv->mem_ptr);
72     udrv->mem_ptr=0;
73   };
74   return 0;
75 };
76
77 /*** Insert frame blk on list bll ***/
78 void ul_bll_ins(ul_blk_bll *bll, ul_mem_blk *blk)
79 {
80   UL_DRV_LOCK_FINI
81   /* ul_drv *udrv=bll->udrv; */
82   UL_BLK_HEAD(blk).bll=bll;
83   /* UL_BLK_HEAD(blk).next=NULL; */
84   /* UL_BLK_HEAD(blk).ref_cnt=1; */
85   /* UL_BLK_HEAD(blk).flg|=UL_BFL_LOCK; */
86   UL_DRV_LOCK;
87   if((UL_BLK_HEAD(blk).prev=bll->last)!=NULL)
88     UL_BLK_HEAD(bll->last).next=blk;
89   else bll->first=blk;
90   bll->last=blk;
91   bll->cnt++;
92   UL_DRV_UNLOCK;
93 };
94
95 /*** Remove frame blk from its bll ***/
96 void ul_bll_del(ul_mem_blk *blk)
97 {
98   UL_DRV_LOCK_FINI
99   ul_blk_bll *bll;
100   ul_mem_blk *p;
101   bll=UL_BLK_HEAD(blk).bll;
102   UL_DRV_LOCK;
103   bll->cnt--;
104
105   if((p=UL_BLK_HEAD(blk).next)!=NULL) 
106   { UL_BLK_HEAD(p).prev=UL_BLK_HEAD(blk).prev;
107     UL_BLK_HEAD(blk).next=NULL;
108   }else bll->last=UL_BLK_HEAD(blk).prev;
109
110   if((p=UL_BLK_HEAD(blk).prev)!=NULL) 
111   { UL_BLK_HEAD(p).next=UL_BLK_HEAD(blk).next;
112     UL_BLK_HEAD(blk).prev=NULL;
113   }else bll->first=UL_BLK_HEAD(blk).next;
114
115   UL_BLK_HEAD(blk).bll=NULL;
116   UL_DRV_UNLOCK;
117 };
118
119 /*** Move one message starting at beg_blk to list new_bll ***/
120 void ul_bll_move_mes(ul_blk_bll *new_bll, ul_mem_blk *beg_blk)
121 {
122   UL_DRV_LOCK_FINI
123   /* ul_drv *udrv=bll->udrv; */
124   ul_mem_blk *end_blk;
125   int         cnt_blk=1;
126   ul_blk_bll *old_bll;
127   ul_mem_blk *p;
128
129   if(beg_blk==NULL) return;
130   end_blk=beg_blk;
131   while((UL_BLK_HEAD(end_blk).flg&UL_BFL_TAIL)&&UL_BLK_HEAD(end_blk).next)
132     { end_blk=UL_BLK_HEAD(end_blk).next; cnt_blk++; };
133   UL_BLK_HEAD(end_blk).flg&=~UL_BFL_TAIL;
134
135   UL_DRV_LOCK;
136   if((old_bll=UL_BLK_HEAD(beg_blk).bll)!=NULL)
137   {
138     old_bll->cnt-=cnt_blk;
139     if((p=UL_BLK_HEAD(beg_blk).prev)!=NULL)
140     { UL_BLK_HEAD(p).next=UL_BLK_HEAD(end_blk).next;
141       UL_BLK_HEAD(beg_blk).prev=NULL;
142     } else old_bll->first=UL_BLK_HEAD(end_blk).next;
143     if((p=UL_BLK_HEAD(end_blk).next)!=NULL)
144     { UL_BLK_HEAD(p).prev=UL_BLK_HEAD(beg_blk).prev;
145       UL_BLK_HEAD(end_blk).next=NULL;
146     } else old_bll->last=UL_BLK_HEAD(beg_blk).prev;
147   };
148   UL_DRV_UNLOCK;
149
150   p=beg_blk;
151   do UL_BLK_HEAD(p).bll=new_bll; 
152   while ((p=UL_BLK_HEAD(p).next)!=NULL);
153
154   if(new_bll)
155   {
156     UL_DRV_LOCK;
157     if((UL_BLK_HEAD(beg_blk).prev=new_bll->last)!=NULL)
158       UL_BLK_HEAD(new_bll->last).next=beg_blk;
159     else new_bll->first=beg_blk;
160     new_bll->last=end_blk;
161     new_bll->cnt+=cnt_blk;
162     UL_DRV_UNLOCK;
163   };
164 };
165
166 void ul_free_mes(ul_drv *udrv,ul_mem_blk *beg_blk)
167 {
168   ul_mem_blk *blk, *next_blk;
169   if(beg_blk==NULL) return;
170   ul_bll_move_mes(NULL,beg_blk);
171   do {
172     next_blk=beg_blk;
173     beg_blk=UL_BLK_HEAD(beg_blk).next;
174     do {
175       blk=next_blk;
176       next_blk=blk->next;
177       ul_free_blk(udrv,blk);
178     } while(next_blk!=NULL);
179   } while(beg_blk!=NULL);
180 };
181
182 /*** Free one message starting at beg_blk ***/
183 INLINE void ul_bll_free_mes(ul_mem_blk *beg_blk)
184 {
185   if(beg_blk==NULL) return;
186   ul_free_mes(UL_BLK_HEAD(beg_blk).bll->udrv,beg_blk);
187 };
188
189 ul_mem_blk *ul_new_frame_head(ul_drv *udrv, uchar dadr,
190                          uchar sadr, uchar cmd,  unsigned flg)
191 { ul_mem_blk *blk;
192   blk=ul_alloc_blk(udrv);
193   if(blk==NULL) return NULL;
194   UL_BLK_HEAD(blk).prev=NULL;
195   UL_BLK_HEAD(blk).next=NULL;
196   UL_BLK_HEAD(blk).bll=NULL;
197   UL_BLK_HEAD(blk).retry_cnt=0;
198   UL_BLK_HEAD(blk).ref_cnt=0;
199   UL_BLK_HEAD(blk).flg=flg;
200   UL_BLK_HEAD(blk).len=0;
201   UL_BLK_HEAD(blk).cmd=cmd;
202   UL_BLK_HEAD(blk).dadr=dadr;
203   UL_BLK_HEAD(blk).sadr=sadr;
204   UL_BLK_HEAD(blk).stamp=0;
205   return blk;
206 };
207
208 void ul_tail_frame_head(ul_mem_blk *beg_blk, ul_mem_blk *blk)
209 {
210   while(UL_BLK_HEAD(beg_blk).next!=NULL) 
211     beg_blk=UL_BLK_HEAD(beg_blk).next;
212   UL_BLK_HEAD(beg_blk).next=blk;
213   UL_BLK_HEAD(blk).prev=beg_blk;
214   UL_BLK_HEAD(beg_blk).flg|=UL_BFL_TAIL;
215 };
216
217 unsigned ul_gen_stamp(void)
218 {
219   UL_DRV_LOCK_FINI
220   static unsigned ul_stamp_cnt=0; 
221   unsigned stamp;
222   UL_DRV_LOCK;
223   ul_stamp_cnt++;
224   ul_stamp_cnt&=0x7fffffff;
225   if(!ul_stamp_cnt)ul_stamp_cnt++;
226   stamp=ul_stamp_cnt;
227   UL_DRV_UNLOCK;
228   return stamp; 
229 };
230
231 int ul_inc_ref_cnt(ul_mem_blk *mes)
232 {
233   int cnt;
234   UL_DRV_LOCK_FINI
235   UL_DRV_LOCK;
236   UL_BLK_HEAD(mes).ref_cnt++;
237   cnt=UL_BLK_HEAD(mes).ref_cnt;
238   UL_DRV_UNLOCK;
239   return cnt;
240 };
241
242 int ul_dec_ref_cnt(ul_mem_blk *mes)
243 {
244   int cnt;
245   UL_DRV_LOCK_FINI
246   UL_DRV_LOCK;
247   if(UL_BLK_HEAD(mes).ref_cnt)UL_BLK_HEAD(mes).ref_cnt--;
248   cnt=UL_BLK_HEAD(mes).ref_cnt;
249   UL_DRV_UNLOCK;
250   if(!cnt)ul_bll_free_mes(mes);
251   return cnt;
252 };