linux/drivers/isdn/hardware/eicon/dqueue.c
<<
>>
Prefs
   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