home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $Source: WB_2.1:homes/rkr/prog/sercli/src/RCS/ser_supp.h,v $
- ** $Author: rkr $
- ** $Revision: 1.6 $
- ** $Locker: rkr $
- ** $State: Exp $
- ** $Date: 1993/06/16 23:32:41 $
- **
- ** sercli (an Amiga .device <-> FIFO interface tool)
- ** Copyright (C) 1993 Richard Rauch
- **
- ** See /doc/sercli.doc and /COPYING for use and distribution license.
- **
- */
-
- #include <devices/serial.h>
- #include <utility/tagitem.h>
-
- #include <lists.h> /*** DICE specific; based on Amiga Lists ***/
-
- #include "defs.h"
- #include "errors.h"
-
- /*
- ** Some typedefs...
- **
- */
- typedef struct IOExtSer IOExtSer;
- typedef struct IORequest IORequest;
-
-
- /*
- ** A {struct ser_buckt_s} and a {ser_bucket_t} are synonymous.
- **
- ** A {ser_bucket_t} consisits of
- ** - serial i/o request struct
- ** - buffer size
- ** - buffer pointer
- **
- ** - list node
- ** - pointer to itself
- **
- ** The last two elements form, implicitly, a {ser_bucket_keeper_t}.
- **
- ** Serial 'buckets' are linked together through their list nodes. Since
- ** they must be tracked while they are pending, and since a variable
- ** number of writes may be pending, they must be linked through some other
- ** mechanism than what we could otherwise 'borrow' from their serial i/o
- ** request structure.
- **
- ** Thus, two different lists exist,
- ** - one of pending writes ('in use' buckets)
- ** - one of completed writes ('free' buckets)
- **
- ** These are are perhaps best thought of as lists of {ser_bucket_keeper_t}
- ** entities; when they are fetched, their corresponding {ser_bucket_t} may
- ** be found through their {.sbk_alter_ego}
- **
- ** (This is the _same_ pointer as found in {ser_bucket_t.b_self}).
- **
- **
- ** This is a relatively efficient way of handling things, albeit a little
- ** confusing.
- **
- ** (NOTE to self, + CLARIFICATION: Instead of keeping the {sbk_alter_ego}
- ** ptr, it may be preferable to subtract {offsetof (ser_bucket_t, b_link)}
- ** from any given (valid) {ser_bucket_keeper_t *}; this would let us
- ** dispense with the "superfluous" pointer, and should be more efficient.
- ** It may also be clearer. This would achieve the same net effect as the
- ** current dereferencing through {sbk_alter_ego}.)
- **
- */
- typedef struct ser_bucket_s
- {
- IOExtSer b_ior;
- ULONG b_size;
- char *b_buf;
- Node b_link; /*** Ooo, ick, Chief..! BLink! ***/
- struct ser_bucket_s *b_self;
- } ser_bucket_t;
-
-
- typedef struct
- {
- Node sbk_link;
- ser_bucket_t *sbk_alter_ego;
- } ser_bucket_keeper_t;
-
-
-
- /*
- ** The next few chunks represent an unfulfilled plan; I've been busy with
- ** other stuff... IGNORE (for now) through {serial_tag_t}
- **
- */
-
- /*
- ** The following 3 new definitions represent a change of philosophy for
- ** the serial support: The idea endorsed is still one of
- ** application-friendliness, but for the sake of generality, the serial
- ** routines will adopt a pointer-to-structure based configuration/control
- ** method (a'la OpenWindow() ), and will cease calling exit() under any
- ** conditions.
- **
- ** The configuration, as I presently see it, is to take place using
- ** TagItem arrays. This is NOT fixed in stone; I may yet decide to do
- ** something like:
- **
- ** typedef struct
- ** {
- ** int bps; // BPS desired value
- ** int set_bps; // Boolean: use {bps}, or use default
- ** //
- ** int data_bits; // Read/Write bits desired
- ** int set_data_bits; // Boolean: Use {data_bits}?
- **
- ** ...
- **
- ** } new_serial_t;
- **
- ** Either way, however, the main thing is that open_ser() will soon take a
- ** {new_serial_t *}, while all other serial functions I've written will
- ** take a {serial_t *}.
- **
- **
- ** These structures are not in use as of this writing, but should be
- ** before, or shortly after, I move serial.c into a seperate .lib.
- **
- ** ---rkr (4-Dec-91).
- **
- */
-
- /*
- ** Like {struct NewWindow}, {new_serial_t} is a "resource request"
- ** description.
- **
- ** A {new_serial_t *} is to be passed to open_ser();
- **
- ** {attributes} should be maintained by the caller. If {attributes} is
- ** non-NULL, the caller is to be responsible for cleaning it up; any
- ** serial routines that can use {attributes} may assume that {attributes}
- ** is meaningful (and try to use it) if you don't put NULL in there when
- ** not in use.
- **
- ** Note that {name, unit} may be removed at a later date, and made instead
- ** a part of the {attributes} list. If they do, the {name, unit} fields
- ** would be preserved somewhere else, pro'ly, to keep things on an even
- ** keel. However, since {name, unit} are _required_ fields by
- ** OpenDevice(), one might as well toss them in here.
- **
- */
- typedef struct
- {
- struct TagItem *attributes; /*** Desired attributes ***/
- ULONG num_attributes; /*** How many in array... ***/
- char *name; /*** E.g., "serial.device" ***/
- ULONG unit; /*** Device unit number ***/
- } new_serial_t;
-
-
- /*
- ** {serial_t} is analogous to {struct Window}.
- **
- ** A {serial_t *} is to be returned by open_ser(), and passed to
- ** close_ser().
- **
- ** The members should not be touched.
- **
- ** Exception: {new_ser} should only be touched to change the {attributes}
- ** for setting the serial params.
- **
- */
- typedef struct
- {
- new_serial_t new_ser; /*** Configure + name/unit number ***/
-
- IOExtSer read_req; /*** Synch. read request ***/
- IOExtSer write_req; /*** Synch. write request ***/
- List idle_buckets; /*** List of idle buckets ***/
- List pending_writes; /*** List of pending write buckets ***/
- MsgPort read_reply_port; /*** Read request reply port ***/
- MsgPort write_reply_port; /*** Write request reply port ***/
-
- int bps; /*** Current Bits Per Second ***/
- int data_bits; /*** Current (read|write) bits ***/
- int exclusive; /*** Current shared/exclusive mode ***/
- int parity; /*** Current parity (none/odd/even) ***/
- int rad_boogie; /*** Current RAD_BOOGIE mode on/off ***/
- int rts_cts; /*** Current RTS/CTS (7wire mode) ***/
- int stop_bits; /*** Current stop bits ***/
- int xon_xoff; /*** Current xon/xoff status ***/
- } serial_t;
-
-
- /*
- ** The set_<symbol> tags are part of {struct TagItem} entities to be
- ** planted into the {new_serial_t.attributes} array. (Not quite as
- ** efficient as it could be, but easily expandable...)
- **
- ** Each set_<symbol>, below, corresponds to a <symbol> in {serial_t},
- ** above.
- **
- ** (My understanding from reading the comments in <utility/tagitem.h> is
- ** that {TAG_USER} is a flag, and no valid tag should consist of just the
- ** TAG_USER bit w/o any other bits set. Presumably, if this were passed
- ** to some system function, it would `ignore' the {TAG_USER} `qualifier'
- ** flag and think it had a {TAG_DONE} tag...)
- **
- */
- typedef enum
- {
- set_bps = TAG_USER + 1,
- set_data_bits,
- set_exclusive,
- set_parity,
- set_rad_boogie,
- set_rts_cts,
- set_stop_bits,
- set_xon_xoff,
- } serial_tag_t;
-
-
-
- /*
- ** Some globals
- **
- ** About the {ser_bucket_list} and {ser_writes_p_list} Lists:
- **
- ** ** {ser_writes_p_list} is used so we know how many outstanding asynch
- ** CMD_WRITE requests we have.
- **
- ** ** {ser_bucket_list} is used to store a list of available buffers/reqs
- ** that have been recycled after an asynch CMD_WRITE has completed.
- **
- */
- extern BYTE io_error_ser;
-
- extern IOExtSer *ser_read_req;
- extern IOExtSer *ser_write_req;
-
- extern List *ser_bucket_list;
- extern List *ser_writes_p_list; /*** SERial WRITES Pending LIST ***/
-
- extern MsgPort *ser_read_reply_port;
- extern MsgPort *ser_write_reply_port;
-
- extern ULONG ser_dev; /*** flag ***/
- extern ULONG ser_read_reply_mask;
- extern ULONG ser_write_reply_mask;
-
-
- char *read_ser_line (char *buf, ULONG max_len);
-
- IOExtSer *query_ser (void);
-
- void clear_write_replies (void);
- void close_ser (void);
- void open_ser (void); /*** controlled by config ***/
- void read_ser_asynch (char *buf, ULONG size);
- void write_ser_asynch (char *buf, ULONG size);
-
- ULONG ser_chars_pending (void);
- ULONG set_ser_soft (void); /*** controlled by config ***/
- ULONG synch_read_ser_req (void);
- ULONG synch_write_ser_req (void);
- ULONG write_ser (char *str, ULONG len);
- ULONG write_ser_str (char *str);
-
-