diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:02:30 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:02:30 +0000 |
commit | 76cb841cb886eef6b3bee341a2266c76578724ad (patch) | |
tree | f5892e5ba6cc11949952a6ce4ecbe6d516d6ce58 /drivers/isdn/hardware/eicon/istream.c | |
parent | Initial commit. (diff) | |
download | linux-76cb841cb886eef6b3bee341a2266c76578724ad.tar.xz linux-76cb841cb886eef6b3bee341a2266c76578724ad.zip |
Adding upstream version 4.19.249.upstream/4.19.249
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/isdn/hardware/eicon/istream.c')
-rw-r--r-- | drivers/isdn/hardware/eicon/istream.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c new file mode 100644 index 000000000..045bda5c8 --- /dev/null +++ b/drivers/isdn/hardware/eicon/istream.c @@ -0,0 +1,226 @@ + +/* + * + Copyright (c) Eicon Networks, 2002. + * + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. + * + Eicon File Revision : 2.1 + * + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + * + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + * + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include "platform.h" +#if defined(DIVA_ISTREAM) /* { */ +#include "pc.h" +#include "pr_pc.h" +#include "di_defs.h" +#include "divasync.h" +#include "di.h" +#if !defined USE_EXTENDED_DEBUGS +#include "dimaint.h" +#else +#define dprintf +#endif +#include "dfifo.h" +int diva_istream_write(void *context, + int Id, + void *data, + int length, + int final, + byte usr1, + byte usr2); +int diva_istream_read(void *context, + int Id, + void *data, + int max_length, + int *final, + byte *usr1, + byte *usr2); +/* ------------------------------------------------------------------- + Does provide iStream interface to the client + ------------------------------------------------------------------- */ +void diva_xdi_provide_istream_info(ADAPTER *a, + diva_xdi_stream_interface_t *pi) { + pi->provided_service = 0; +} +/* ------------------------------------------------------------------ + Does write the data from caller's buffer to the card's + stream interface. + If synchronous service was requested, then function + does return amount of data written to stream. + 'final' does indicate that piece of data to be written is + final part of frame (necessary only by structured datatransfer) + return 0 if zero lengh packet was written + return -1 if stream is full + ------------------------------------------------------------------ */ +int diva_istream_write(void *context, + int Id, + void *data, + int length, + int final, + byte usr1, + byte usr2) { + ADAPTER *a = (ADAPTER *)context; + int written = 0, to_write = -1; + char tmp[4]; + byte *data_ptr = (byte *)data; + for (;;) { + a->ram_in_dw(a, +#ifdef PLATFORM_GT_32BIT + ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]), +#else + (void *)(a->tx_stream[Id] + a->tx_pos[Id]), +#endif + (dword *)&tmp[0], + 1); + if (tmp[0] & DIVA_DFIFO_READY) { /* No free blocks more */ + if (to_write < 0) + return (-1); /* was not able to write */ + break; /* only part of message was written */ + } + to_write = min(length, DIVA_DFIFO_DATA_SZ); + if (to_write) { + a->ram_out_buffer(a, +#ifdef PLATFORM_GT_32BIT + ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id] + 4), +#else + (void *)(a->tx_stream[Id] + a->tx_pos[Id] + 4), +#endif + data_ptr, + (word)to_write); + length -= to_write; + written += to_write; + data_ptr += to_write; + } + tmp[1] = (char)to_write; + tmp[0] = (tmp[0] & DIVA_DFIFO_WRAP) | + DIVA_DFIFO_READY | + ((!length && final) ? DIVA_DFIFO_LAST : 0); + if (tmp[0] & DIVA_DFIFO_LAST) { + tmp[2] = usr1; + tmp[3] = usr2; + } + a->ram_out_dw(a, +#ifdef PLATFORM_GT_32BIT + ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]), +#else + (void *)(a->tx_stream[Id] + a->tx_pos[Id]), +#endif + (dword *)&tmp[0], + 1); + if (tmp[0] & DIVA_DFIFO_WRAP) { + a->tx_pos[Id] = 0; + } else { + a->tx_pos[Id] += DIVA_DFIFO_STEP; + } + if (!length) { + break; + } + } + return (written); +} +/* ------------------------------------------------------------------- + In case of SYNCRONOUS service: + Does write data from stream in caller's buffer. + Does return amount of data written to buffer + Final flag is set on return if last part of structured frame + was received + return 0 if zero packet was received + return -1 if stream is empty + return -2 if read buffer does not profide sufficient space + to accommodate entire segment + max_length should be at least 68 bytes + ------------------------------------------------------------------- */ +int diva_istream_read(void *context, + int Id, + void *data, + int max_length, + int *final, + byte *usr1, + byte *usr2) { + ADAPTER *a = (ADAPTER *)context; + int read = 0, to_read = -1; + char tmp[4]; + byte *data_ptr = (byte *)data; + *final = 0; + for (;;) { + a->ram_in_dw(a, +#ifdef PLATFORM_GT_32BIT + ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]), +#else + (void *)(a->rx_stream[Id] + a->rx_pos[Id]), +#endif + (dword *)&tmp[0], + 1); + if (tmp[1] > max_length) { + if (to_read < 0) + return (-2); /* was not able to read */ + break; + } + if (!(tmp[0] & DIVA_DFIFO_READY)) { + if (to_read < 0) + return (-1); /* was not able to read */ + break; + } + to_read = min(max_length, (int)tmp[1]); + if (to_read) { + a->ram_in_buffer(a, +#ifdef PLATFORM_GT_32BIT + ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id] + 4), +#else + (void *)(a->rx_stream[Id] + a->rx_pos[Id] + 4), +#endif + data_ptr, + (word)to_read); + max_length -= to_read; + read += to_read; + data_ptr += to_read; + } + if (tmp[0] & DIVA_DFIFO_LAST) { + *final = 1; + } + tmp[0] &= DIVA_DFIFO_WRAP; + a->ram_out_dw(a, +#ifdef PLATFORM_GT_32BIT + ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]), +#else + (void *)(a->rx_stream[Id] + a->rx_pos[Id]), +#endif + (dword *)&tmp[0], + 1); + if (tmp[0] & DIVA_DFIFO_WRAP) { + a->rx_pos[Id] = 0; + } else { + a->rx_pos[Id] += DIVA_DFIFO_STEP; + } + if (*final) { + if (usr1) + *usr1 = tmp[2]; + if (usr2) + *usr2 = tmp[3]; + break; + } + } + return (read); +} +/* --------------------------------------------------------------------- + Does check if one of streams had caused interrupt and does + wake up corresponding application + --------------------------------------------------------------------- */ +void pr_stream(ADAPTER *a) { +} +#endif /* } */ |