1 /* $Id: dqueue.c,v 1.5 2003/04/12 21:40:49 schindler Exp $
2  *
3  * Driver for Eicon DIVA Server ISDN cards.
4  * User Mode IDI Interface
5  *
6  * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7  * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8  *
9  * This software may be used and distributed according to the terms
10  * of the GNU General Public License, incorporated herein by reference.
11  */
12 
13 #include "platform.h"
14 #include "dqueue.h"
15 
16 int
diva_data_q_init(diva_um_idi_data_queue_t * q,int max_length,int max_segments)17 diva_data_q_init(diva_um_idi_data_queue_t *q,
18 		 int max_length, int max_segments)
19 {
20 	int i;
21 
22 	q->max_length = max_length;
23 	q->segments = max_segments;
24 
25 	for (i = 0; i < q->segments; i++) {
26 		q->data[i] = NULL;
27 		q->length[i] = 0;
28 	}
29 	q->read = q->write = q->count = q->segment_pending = 0;
30 
31 	for (i = 0; i < q->segments; i++) {
32 		if (!(q->data[i] = diva_os_malloc(0, q->max_length))) {
33 			diva_data_q_finit(q);
34 			return (-1);
35 		}
36 	}
37 
38 	return (0);
39 }
40 
diva_data_q_finit(diva_um_idi_data_queue_t * q)41 int diva_data_q_finit(diva_um_idi_data_queue_t *q)
42 {
43 	int i;
44 
45 	for (i = 0; i < q->segments; i++) {
46 		if (q->data[i]) {
47 			diva_os_free(0, q->data[i]);
48 		}
49 		q->data[i] = NULL;
50 		q->length[i] = 0;
51 	}
52 	q->read = q->write = q->count = q->segment_pending = 0;
53 
54 	return (0);
55 }
56 
diva_data_q_get_max_length(const diva_um_idi_data_queue_t * q)57 int diva_data_q_get_max_length(const diva_um_idi_data_queue_t *q)
58 {
59 	return (q->max_length);
60 }
61 
diva_data_q_get_segment4write(diva_um_idi_data_queue_t * q)62 void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t *q)
63 {
64 	if ((!q->segment_pending) && (q->count < q->segments)) {
65 		q->segment_pending = 1;
66 		return (q->data[q->write]);
67 	}
68 
69 	return NULL;
70 }
71 
72 void
diva_data_q_ack_segment4write(diva_um_idi_data_queue_t * q,int length)73 diva_data_q_ack_segment4write(diva_um_idi_data_queue_t *q, int length)
74 {
75 	if (q->segment_pending) {
76 		q->length[q->write] = length;
77 		q->count++;
78 		q->write++;
79 		if (q->write >= q->segments) {
80 			q->write = 0;
81 		}
82 		q->segment_pending = 0;
83 	}
84 }
85 
diva_data_q_get_segment4read(const diva_um_idi_data_queue_t * q)86 const void *diva_data_q_get_segment4read(const diva_um_idi_data_queue_t *
87 					 q)
88 {
89 	if (q->count) {
90 		return (q->data[q->read]);
91 	}
92 	return NULL;
93 }
94 
diva_data_q_get_segment_length(const diva_um_idi_data_queue_t * q)95 int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t *q)
96 {
97 	return (q->length[q->read]);
98 }
99 
diva_data_q_ack_segment4read(diva_um_idi_data_queue_t * q)100 void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t *q)
101 {
102 	if (q->count) {
103 		q->length[q->read] = 0;
104 		q->count--;
105 		q->read++;
106 		if (q->read >= q->segments) {
107 			q->read = 0;
108 		}
109 	}
110 }
111