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