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
16int
17diva_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
41int 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
57int diva_data_q_get_max_length(const diva_um_idi_data_queue_t *q)
58{
59	return (q->max_length);
60}
61
62void *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
72void
73diva_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
86const 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
95int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t *q)
96{
97	return (q->length[q->read]);
98}
99
100void 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