| /* | |
| * | |
| 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 /* } */ |