home *** CD-ROM | disk | FTP | other *** search
- /* asifirst.c
- *
- * The Greenleaf Comm Library
- *
- * Copyright (C) 1985-1990 Greenleaf Software Inc. All Rights Reserved.
- *
- * int asifirst( port, mode, rxlen, txlen)
- * int port; - Port 0..MAX_PORT-1
- * unsigned mode; - Operating Mode (see below)
- * unsigned rxlen; - Length Rx Buffer, bytes MIN_BUF_SIZE..MAX_BUF_SIZE
- * unsigned txlen; - Length Tx Buffer, bytes MIN_BUF_SIZE..MAX_BUF_SIZE
- *
- * "mode" specifies five different kinds of operational parameters.
- * Choose one from each of the following categories. See documentation
- * for further details:
- * 1. Direction (ASIN, ASOUT, ASINOUT)
- * 2. Data Type (BINARY, ASCII)
- * 3. Receive Buffer Width (NORMALRX, WIDETRACKRX)
- *
- * Example:
- * asifirst( port,(ASINOUT | BINARY | NORMALRX ),4000,100 );
- *
- * DESCRIPTION
- * Initializes a data structure that will be used to store the
- * configuration for a port. This function must be called before any
- * other operations can be performed on a communications port.
- *
- * SIDE EFFECTS
- * None.
- *
- * RETURNS
- *
- * Value Meaning
- * ----- -------
- * ASSUCCESS No errors encountered
- * ASNOMEMORY Cannot allocate dynamic memory needed
- * ASINVPORT Requested logical port number too high or too low
- * ASINUSE port has already been setup with asifirst()
- * ASINVBUFSIZE Buffer size is out of range
- * ASNO8250 No 8250 installed at requested i/o address
- *
- * MODIFICATIONS
- *
- * 10-25-85 ""
- * Modified for new structure members, also moved static
- * data items to this file.
- *
- * 03-FEB-1987 11:05:40.33
- * Deleted static int first_time, replaced it with a global variable
- * _asoprt which reflects the total number of open ports. It is
- * initialized to 0, gets incremented on every open and decremented
- * on every close.
- *
- * 04-FEB-1987 16:32:21.71
- * Added code to check _asmask and add its value to the structure
- * member .as_mask if the port has a shared hardware port defined
- * for it. This will enable asishare() to be called before asifirst().
- * Also added global variables for _comvers && _comrev.
- *
- * 25-MAY-1988 15:50:54.29 version 2.20
- * Added code to check _asxorv, and add its value to the structure
- * member .as_xorv if the port has a shared hardware port defined
- * for it. This will enable asinvert() to be called before asifirst().
- * _asxorv is a new global variable set by asinvert.
- *
- * Changed the order of parameters to calloc() per SAR # 84
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "gf.h"
- #define MOD_ASIFIRST 1 /* For conditional in asiports.h */
- #include "asiports.h"
- #include "ibmkeys.h"
-
- /************************************************************************
- * POINTER TO STRUCTURE CONTAINING POINTERS TO STRUCTURES, AND OTHER *
- * THINGS: *
- * *
- * Elements of the array are: ptb = ptr to PORT_TABLE (big) structure *
- * as_shport = status port address *
- * as_shbits = status bitmask *
- * *
- * First time asifirst() is called for any port, the memory is allocated*
- * for this structure, and the address is placed in the code segment. *
- ************************************************************************/
- struct TABLEPORT *as_chnl = NULL;
-
-
- /************************************************************************
- * ABOUT THE ARRAYS BELOW.. *
- * *
- * The arrays in this file define parameters for the 16 possible ports. *
- * Values are hard-coded in here for the first two (0 and 1, or COM1 *
- * and COM2) for Category A (standard IBM-type) hardware. The value *
- * for any port may be changed by calling asisetv() for the port. *
- * Values are transferred from these arrays to the large TABLEPORT *
- * structure (see asiports.h) for the port when asifirst() is called. *
- * *
- * Don't change any of these unless you know what you are doing ! *
- ************************************************************************/
-
-
- /**** BASE I/O ADDRESSES FOR 8250 DEVICES.
- *
- * 0 in an element assures that asifirst() will not let you use that port,
- * it will return ASNO8250 as a security measure.
- *
- * See asisetv() documentation for explanation of "addr8250" argument.
- */
- unsigned as_8250port[MAX_PORT] = {
- 0x3f8,0x2f8,0x3220,0x3228,0x4220,0x4228,0x5220,0x5228,0,0,0,0,0,0,0,0 };
-
-
- /**** INTERRUPT NUMBERS for all ports.
- *
- * See asisetv() documentation for explanation of "intn" argument.
- */
- int as_intnums[MAX_PORT] = {
- 12,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0 };
-
-
- /**** I/O ADDRESSES OF 8259A INTERRUPT CONTROLLER.
- *
- * See asisetv() documentation for explanation of "addr8259" argument.
- *
- */
- unsigned as_8259ports[MAX_PORT] = { 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0,0,0,0,0,0,0,0 };
-
- /**** IRQ (INTERRUPT REQUEST) NUMBERS
- *
- * See asisetv() documentation for explanation of "irq" argument.
- */
- int as_8259irq[MAX_PORT] = { 4,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0 };
-
-
- /**** BREAK SIGNAL DURATION in increments of 55 milliseconds.
- *
- * See asisetv() documentation for explanation of "brkdly" argument.
- */
- int as_brkdly[MAX_PORT] = { 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 };
-
-
- /**** WAIT FOR MODEM SIGNALS (Polled Mode ONLY)
- *
- * See asisetv() documentation for explanation of "wmodem" argument.
- */
- int as_wmodem[MAX_PORT] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-
-
- /**** POLLED MODE WRITE DELAY LIMIT for asputc()
- *
- * See asisetv() documentation for explanation of "wtime" argument.
- */
- int as_wtime[MAX_PORT] = { 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 };
-
-
- /**** POLLED MODE READ DELAY for asgetc()
- *
- * See asisetv() documentation for explanation of "rtime" argument.
- */
- int as_rtime[MAX_PORT] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-
-
- /**** SHARED INTERRUPT HARDWARE - Status Port I/O Address
- *
- * See asisetv() documentation for explanation of "sh_ioad" argument.
- */
- unsigned as_shioad[MAX_PORT] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-
-
- /**** SHARED INTERRUPT HARDWARE - Status Port BitMask
- *
- * See asisetv() documentation for explanation of "sh_bmask" argument.
- */
- unsigned as_shbmask[MAX_PORT] = { 0xff00,0xff00,0xff00,0xff00,0xff00,
- 0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,
- 0xff00,0xff00,0xff00,0xff00,0xff00 };
-
-
- /* DO NOT TOUCH THE FOLLOWING DATA ARRAY FOR ANY REASON.
- *
- */
- char glcprt[]={ 0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,
- 0x43,0x29,0x20,0x31,0x39,0x38,0x35,0x2C,0x20,0x31,0x39,
- 0x38,0x36,0x2C,0x20,0x31,0x39,0x38,0x37,0x2C,0x20,0x31,
- 0x39,0x38,0x38,0x2C,0x20,0x31,0x39,0x38,0x39,0x20,0x47,
- 0x72,0x65,0x65,0x6E,0x6C,0x65,0x61,0x66,0x20,0x53,0x6F,
- 0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x49,0x6E,0x63,0x2E,
- 0x0A,0x20,0x20,0x41,0x6C,0x6C,0x20,0x52,0x69,0x67,0x68,
- 0x74,0x73,0x20,0x52,0x65,0x73,0x65,0x72,0x76,0x65,0x64,
- 0x2E,0x00};
-
-
- /************************************************************************
- * GLOBAL ERROR VARIABLE _aserror *
- * *
- * See "Error Returns" section in documentation for explanation. *
- * This variable may be tested by the application to determine the *
- * cause of an error on the part of most functions in the library. *
- ************************************************************************/
- int _aserror;
- int _asoprt=0;
- int _asmask=0; /* This is set by asishare() */
- int _comvers = COMLIBVERSION, _comrev = COMLIBREVISION;
- int _asxorv=0; /* Set by asinvert() */
-
-
- int GF_CONV asifirst(port,mode,size_rx_buf,size_tx_buf)
- int port;
- unsigned size_tx_buf,size_rx_buf,mode;
- {
- int latch,i,j;
- struct PORT_TABLE *p;
- unsigned rx_alloc;
-
- /********************************************************
- * First time thru for any port, never again: *
- * *
- * 1) Allocate memory for array of structures that will *
- * point to the big structures. *
- * 2) put address of array of structures in code seg. *
- * 3) Initialize pointers to big structures to NULL *
- * 4) Shut down Ctrl-Break checking for rest of pgm. *
- ********************************************************/
- for (j=0,i=0;j < (int)strlen(glcprt);j++)
- i+=(int)glcprt[j];
- if (i!=6648) return (-30);
- if(!_asoprt && !as_chnl) {
- if((as_chnl=(struct TABLEPORT *)
- calloc(1,sizeof( struct TABLEPORT )))==NULL)
- return(ASNOMEMORY);
- _asregister(as_chnl);
- (void) breakchk(OFF);
- #ifdef LATTICE
- onexit((int(*)())_asiexit_routine);
- #else
- atexit(_asiexit_routine);
- #endif
- for (i=0; i<MAX_PORT; i++) {
- as_chnl->tblport[i].ptb = NULL;
- if(as_shioad[i]) {
- as_chnl->tblport[i].as_mask=_asmask;
- as_chnl->tblport[i].as_xorv=_asxorv;
- }
- }
- }
-
- /********************************************************
- * Determine sixe of Tx and Rx buffers *
- ********************************************************/
- if(mode&WIDETRACKRX) {
- if(size_rx_buf > MAX_BUF_SIZE/2)
- return(ASINVBUFSIZE);
- rx_alloc=size_rx_buf*2;
- } else
- rx_alloc=size_rx_buf;
- if (port < 0 || port > MAX_PORT-1)
- return (ASINVPORT);
- if (as_chnl->tblport[port].ptb != NULL)
- return (ASINUSE);
- if (rx_alloc < MIN_BUF_SIZE || size_tx_buf < MIN_BUF_SIZE ||
- rx_alloc > MAX_BUF_SIZE || size_tx_buf > MAX_BUF_SIZE)
- return (ASINVBUFSIZE);
-
-
- /********************************************************
- * Now allocate memory for the port's main parameter *
- * structure. *
- ********************************************************/
- if ((as_chnl->tblport[port].ptb = (struct PORT_TABLE *)
- calloc(1,sizeof (struct PORT_TABLE)))==NULL)
- return (ASNOMEMORY);
- p=as_chnl->tblport[port].ptb;
-
- /********************************************************
- * Transfer shared-hardware i/o addr and bitmask to *
- * the array of structures TABLEPORT *
- * *
- * If the port is NOT on a shared port, then the bitmask*
- * is set with high order 8 bits ones to cause *
- * a non-recognition to occur in the interrupt. *
- ********************************************************/
- as_chnl->tblport[port].as_shport = as_shioad[port];
- if (!as_shioad[port])
- as_shbmask[port] |= 0xff00;
- as_chnl->tblport[port].as_shbits = as_shbmask[port];
-
- /********************************************************
- * Allocate memory for Tx and Rx buffers for the port. *
- ********************************************************/
- if ((p->tx_buffer=calloc(size_tx_buf,1))==NULL) {
- free((char *)p);
- as_chnl->tblport[port].ptb = NULL;
- return (ASNOMEMORY);
- }
- if ((p->rx_buffer=calloc(rx_alloc,1))==NULL) {
- free(p->tx_buffer);
- free((char *)p);
- as_chnl->tblport[port].ptb = NULL;
- return(ASNOMEMORY);
- }
- p->tx_size=size_tx_buf;
- p->rx_size=size_rx_buf;
-
- /* Initialize all port status bits.
- */
- p->chst_bits.rxempty=p->chst_bits.txempty=1;
- p->intrpt_num=as_intnums[port];
- p->base_8250=as_8250port[port];
- p->tx_cell=1;
- if(mode&WIDETRACKRX) {
- p->rx_cell=2;
- p->chmode_bits.is_rxerror=1;
- } else
- p->rx_cell=1;
- if(mode&ASIN)
- p->chmode_bits.is_rxint=ON;
- if(mode&ASOUT)
- p->chmode_bits.is_txint=ON;
- if(mode&ASCII)
- p->chmode_bits.is_ascii=ON;
-
- p->chmode_bits.modem_status_changes_set_alert = ON;
- p->chmode_bits.line_errors_set_alert = ON;
- p->irq_8259=as_8259irq[port];
- p->port_8259=as_8259ports[port];
- p->break_delay=as_brkdly[port];
- p->aswmodem=as_wmodem[port];
- p->aswtime=as_wtime[port];
- p->asrtime=as_rtime[port];
-
-
- /****************************************************************
- * In support of shared-interrupt hardware, check to see *
- * if any other port using this interrupt number has been setup *
- * already. If it has not, the second argument to _asifirst() *
- * will be a 1, in which case it will program the 8259A and *
- * set the interrupt vector. *
- * If one or more other ports setup prior to this with same *
- * interrupt number, then pass a 0 as second arg to _asifirst() *
- * to tell it to avoid vector init and 8259A init. *
- * *
- * If there is another with same int num, check that it also *
- * has same 8259A address and IRQ number. *
- ****************************************************************/
-
- for(latch=1,i=0;i<MAX_PORT;i++) {
- if((i!=port)&&(as_chnl->tblport[i].ptb!=NULL)) {
- if(as_chnl->tblport[i].ptb->intrpt_num==as_intnums[port]) {
- if((as_chnl->tblport[i].ptb->port_8259!=as_8259ports[port])
- ||(as_chnl->tblport[i].ptb->irq_8259!=as_8259irq[port])) {
- free(p->tx_buffer);
- free(p->rx_buffer);
- free((char *)p);
- as_chnl->tblport[port].ptb = NULL;
- return (ASCONFLICT);
- }
- else latch = 0;
- }
- }
- } /* end for */
-
- /****************************************************************
- * If latch = 1 then no other port uses same intr number, so *
- * the 8259A and vector will be initialized. *
- ****************************************************************/
- if((_aserror=_asifirst(port,latch,p))!=ASSUCCESS) {
- free(p->tx_buffer);
- free(p->rx_buffer);
- free((char *)p);
- as_chnl->tblport[port].ptb = NULL;
- return(_aserror);
- }
- ++_asoprt;
- return(ASSUCCESS);
- }
-