linux/drivers/isdn/hardware/eicon/istream.c
<<
>>
Prefs
   1
   2/*
   3 *
   4 Copyright (c) Eicon Networks, 2002.
   5 *
   6 This source file is supplied for the use with
   7 Eicon Networks range of DIVA Server Adapters.
   8 *
   9 Eicon File Revision :    2.1
  10 *
  11 This program is free software; you can redistribute it and/or modify
  12 it under the terms of the GNU General Public License as published by
  13 the Free Software Foundation; either version 2, or (at your option)
  14 any later version.
  15 *
  16 This program is distributed in the hope that it will be useful,
  17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
  18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  19 See the GNU General Public License for more details.
  20 *
  21 You should have received a copy of the GNU General Public License
  22 along with this program; if not, write to the Free Software
  23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24 *
  25 */
  26#include "platform.h"
  27#if defined(DIVA_ISTREAM) /* { */
  28#include "pc.h"
  29#include "pr_pc.h"
  30#include "di_defs.h"
  31#include "divasync.h"
  32#include "di.h"
  33#if !defined USE_EXTENDED_DEBUGS
  34#include "dimaint.h"
  35#else
  36#define dprintf
  37#endif
  38#include "dfifo.h"
  39int diva_istream_write(void *context,
  40                       int   Id,
  41                       void *data,
  42                       int length,
  43                       int final,
  44                       byte usr1,
  45                       byte usr2);
  46int diva_istream_read(void *context,
  47                      int Id,
  48                      void *data,
  49                      int max_length,
  50                      int *final,
  51                      byte *usr1,
  52                      byte *usr2);
  53/* -------------------------------------------------------------------
  54   Does provide iStream interface to the client
  55   ------------------------------------------------------------------- */
  56void diva_xdi_provide_istream_info(ADAPTER *a,
  57                                   diva_xdi_stream_interface_t *pi) {
  58        pi->provided_service = 0;
  59}
  60/* ------------------------------------------------------------------
  61   Does write the data from caller's buffer to the card's
  62   stream interface.
  63   If synchronous service was requested, then function
  64   does return amount of data written to stream.
  65   'final' does indicate that piece of data to be written is
  66   final part of frame (necessary only by structured datatransfer)
  67   return  0 if zero lengh packet was written
  68   return -1 if stream is full
  69   ------------------------------------------------------------------ */
  70int diva_istream_write(void *context,
  71                       int Id,
  72                       void *data,
  73                       int length,
  74                       int final,
  75                       byte usr1,
  76                       byte usr2) {
  77        ADAPTER *a = (ADAPTER *)context;
  78        int written = 0, to_write = -1;
  79        char tmp[4];
  80        byte *data_ptr = (byte *)data;
  81        for (;;) {
  82                a->ram_in_dw(a,
  83#ifdef PLATFORM_GT_32BIT
  84                              ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
  85#else
  86                              (void *)(a->tx_stream[Id] + a->tx_pos[Id]),
  87#endif
  88                              (dword *)&tmp[0],
  89                              1);
  90                if (tmp[0] & DIVA_DFIFO_READY) { /* No free blocks more */
  91                        if (to_write < 0)
  92                                return (-1); /* was not able to write       */
  93                        break;     /* only part of message was written */
  94                }
  95                to_write = min(length, DIVA_DFIFO_DATA_SZ);
  96                if (to_write) {
  97                        a->ram_out_buffer(a,
  98#ifdef PLATFORM_GT_32BIT
  99                                           ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id] + 4),
 100#else
 101                                           (void *)(a->tx_stream[Id] + a->tx_pos[Id] + 4),
 102#endif
 103                                           data_ptr,
 104                                           (word)to_write);
 105                        length  -= to_write;
 106                        written  += to_write;
 107                        data_ptr += to_write;
 108                }
 109                tmp[1] = (char)to_write;
 110                tmp[0] = (tmp[0] & DIVA_DFIFO_WRAP) |
 111                        DIVA_DFIFO_READY |
 112                        ((!length && final) ? DIVA_DFIFO_LAST : 0);
 113                if (tmp[0] & DIVA_DFIFO_LAST) {
 114                        tmp[2] = usr1;
 115                        tmp[3] = usr2;
 116                }
 117                a->ram_out_dw(a,
 118#ifdef PLATFORM_GT_32BIT
 119                               ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
 120#else
 121                               (void *)(a->tx_stream[Id] + a->tx_pos[Id]),
 122#endif
 123                               (dword *)&tmp[0],
 124                               1);
 125                if (tmp[0] & DIVA_DFIFO_WRAP) {
 126                        a->tx_pos[Id]  = 0;
 127                } else {
 128                        a->tx_pos[Id] += DIVA_DFIFO_STEP;
 129                }
 130                if (!length) {
 131                        break;
 132                }
 133        }
 134        return (written);
 135}
 136/* -------------------------------------------------------------------
 137   In case of SYNCRONOUS service:
 138   Does write data from stream in caller's buffer.
 139   Does return amount of data written to buffer
 140   Final flag is set on return if last part of structured frame
 141   was received
 142   return 0  if zero packet was received
 143   return -1 if stream is empty
 144   return -2 if read buffer does not profide sufficient space
 145   to accommodate entire segment
 146   max_length should be at least 68 bytes
 147   ------------------------------------------------------------------- */
 148int diva_istream_read(void *context,
 149                      int Id,
 150                      void *data,
 151                      int max_length,
 152                      int *final,
 153                      byte *usr1,
 154                      byte *usr2) {
 155        ADAPTER *a = (ADAPTER *)context;
 156        int read = 0, to_read = -1;
 157        char tmp[4];
 158        byte *data_ptr = (byte *)data;
 159        *final = 0;
 160        for (;;) {
 161                a->ram_in_dw(a,
 162#ifdef PLATFORM_GT_32BIT
 163                              ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
 164#else
 165                              (void *)(a->rx_stream[Id] + a->rx_pos[Id]),
 166#endif
 167                              (dword *)&tmp[0],
 168                              1);
 169                if (tmp[1] > max_length) {
 170                        if (to_read < 0)
 171                                return (-2); /* was not able to read */
 172                        break;
 173                }
 174                if (!(tmp[0] & DIVA_DFIFO_READY)) {
 175                        if (to_read < 0)
 176                                return (-1); /* was not able to read */
 177                        break;
 178                }
 179                to_read = min(max_length, (int)tmp[1]);
 180                if (to_read) {
 181                        a->ram_in_buffer(a,
 182#ifdef PLATFORM_GT_32BIT
 183                                         ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id] + 4),
 184#else
 185                                         (void *)(a->rx_stream[Id] + a->rx_pos[Id] + 4),
 186#endif
 187                                         data_ptr,
 188                                         (word)to_read);
 189                        max_length -= to_read;
 190                        read     += to_read;
 191                        data_ptr  += to_read;
 192                }
 193                if (tmp[0] & DIVA_DFIFO_LAST) {
 194                        *final = 1;
 195                }
 196                tmp[0] &= DIVA_DFIFO_WRAP;
 197                a->ram_out_dw(a,
 198#ifdef PLATFORM_GT_32BIT
 199                              ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
 200#else
 201                              (void *)(a->rx_stream[Id] + a->rx_pos[Id]),
 202#endif
 203                              (dword *)&tmp[0],
 204                              1);
 205                if (tmp[0] & DIVA_DFIFO_WRAP) {
 206                        a->rx_pos[Id]  = 0;
 207                } else {
 208                        a->rx_pos[Id] += DIVA_DFIFO_STEP;
 209                }
 210                if (*final) {
 211                        if (usr1)
 212                                *usr1 = tmp[2];
 213                        if (usr2)
 214                                *usr2 = tmp[3];
 215                        break;
 216                }
 217        }
 218        return (read);
 219}
 220/* ---------------------------------------------------------------------
 221   Does check if one of streams had caused interrupt and does
 222   wake up corresponding application
 223   --------------------------------------------------------------------- */
 224void pr_stream(ADAPTER *a) {
 225}
 226#endif /* } */
 227