Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | |
475be4d8 | 17 | diva_data_q_init(diva_um_idi_data_queue_t *q, |
1da177e4 LT |
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 | ||
475be4d8 | 41 | int diva_data_q_finit(diva_um_idi_data_queue_t *q) |
1da177e4 LT |
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 | ||
475be4d8 | 57 | int diva_data_q_get_max_length(const diva_um_idi_data_queue_t *q) |
1da177e4 LT |
58 | { |
59 | return (q->max_length); | |
60 | } | |
61 | ||
475be4d8 | 62 | void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t *q) |
1da177e4 LT |
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 | |
475be4d8 | 73 | diva_data_q_ack_segment4write(diva_um_idi_data_queue_t *q, int length) |
1da177e4 LT |
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 | ||
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 | ||
475be4d8 | 95 | int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t *q) |
1da177e4 LT |
96 | { |
97 | return (q->length[q->read]); | |
98 | } | |
99 | ||
475be4d8 | 100 | void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t *q) |
1da177e4 LT |
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 | } |