7706490f31
Spotted by: Peter Jeremy <PeterJeremy@optushome.com.au>
200 lines
5.2 KiB
C
200 lines
5.2 KiB
C
/*-
|
|
* Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
|
|
* based on work by Slawa Olhovchenkov
|
|
* John Prince <johnp@knight-trosoft.com>
|
|
* Eric Hernes
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
#define W(p) (*(u_int16_t *)(p))
|
|
#define vW(p) (*(u_int16_t volatile *)(p))
|
|
#define D(p) (*(u_int32_t *)(p))
|
|
#define vD(p) (*(u_int32_t volatile *)(p))
|
|
|
|
#define CE_OVERRUN 0
|
|
#define CE_INTERRUPT_BUF_OVERFLOW 1
|
|
#define CE_TTY_BUF_OVERFLOW 2
|
|
#define CE_NTYPES 3
|
|
#define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum])
|
|
|
|
/*#define DIGI_INTERRUPT*/
|
|
|
|
#ifndef DEBUG
|
|
#define DEBUG
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
extern unsigned digi_debug;
|
|
#define DLOG(level, args) if (digi_debug & (level)) device_printf args
|
|
#else
|
|
#define DLOG(level, args)
|
|
#endif
|
|
|
|
|
|
struct digi_softc;
|
|
|
|
/* digiboard port structure */
|
|
struct digi_p {
|
|
struct digi_softc *sc;
|
|
|
|
int status;
|
|
#define ENABLED 1
|
|
#define DIGI_DTR_OFF 2
|
|
#define PAUSE_TX 8
|
|
#define PAUSE_RX 16
|
|
|
|
int opencnt;
|
|
u_short txbufsize;
|
|
u_short rxbufsize;
|
|
volatile struct board_chan *bc;
|
|
struct tty *tp;
|
|
|
|
u_char *txbuf;
|
|
u_char *rxbuf;
|
|
u_char txwin;
|
|
u_char rxwin;
|
|
|
|
u_char pnum; /* port number */
|
|
|
|
u_char modemfake; /* Modem values to be forced */
|
|
u_char mstat;
|
|
u_char modem; /* Force values */
|
|
|
|
/*
|
|
* The high level of the driver never reads status registers directly
|
|
* because there would be too many side effects to handle conveniently.
|
|
* Instead, it reads copies of the registers stored here by the
|
|
* interrupt handler.
|
|
*/
|
|
u_char last_modem_status; /* last MSR read by intr handler */
|
|
u_char prev_modem_status; /* last MSR handled by high level */
|
|
|
|
u_long bytes_in, bytes_out;
|
|
u_int delta_error_counts[CE_NTYPES];
|
|
u_long error_counts;
|
|
|
|
tcflag_t c_iflag; /* hold true IXON/IXOFF/IXANY */
|
|
int lcc, lostcc, lbuf;
|
|
u_char send_ring;
|
|
|
|
unsigned laltpin : 1; /* Alternate pin settings locked */
|
|
unsigned ialtpin : 1; /* Initial alternate pin settings */
|
|
|
|
int cd; /* Depends on the altpin setting */
|
|
int dsr;
|
|
};
|
|
|
|
/*
|
|
* Map TIOCM_* values to digiboard values
|
|
*/
|
|
struct digi_control_signals {
|
|
int rts;
|
|
int cd;
|
|
int dsr;
|
|
int cts;
|
|
int ri;
|
|
int dtr;
|
|
};
|
|
|
|
enum digi_board_status {
|
|
DIGI_STATUS_NOTINIT,
|
|
DIGI_STATUS_ENABLED,
|
|
DIGI_STATUS_DISABLED
|
|
};
|
|
|
|
/* Digiboard per-board structure */
|
|
struct digi_softc {
|
|
/* struct board_info */
|
|
device_t dev;
|
|
|
|
const char *name;
|
|
enum digi_board_status status;
|
|
u_short numports; /* number of ports on card */
|
|
u_int port; /* I/O port */
|
|
u_int wport; /* window select I/O port */
|
|
|
|
struct {
|
|
struct resource *mem;
|
|
int mrid;
|
|
struct resource *irq;
|
|
int irqrid;
|
|
struct resource *io;
|
|
int iorid;
|
|
void *irqHandler;
|
|
int unit;
|
|
struct cdev *ctldev;
|
|
} res;
|
|
|
|
u_char *vmem; /* virtual memory address */
|
|
u_char *memcmd;
|
|
volatile u_char *memevent;
|
|
long pmem; /* physical memory address */
|
|
|
|
struct {
|
|
u_char *data;
|
|
size_t size;
|
|
} bios, fep, link;
|
|
|
|
#ifdef DIGI_INTERRUPT
|
|
struct timeval intr_timestamp;
|
|
#endif
|
|
|
|
struct digi_p *ports; /* pointer to array of port descriptors */
|
|
volatile struct global_data *gdata;
|
|
u_char window; /* saved window */
|
|
int win_size;
|
|
int win_bits;
|
|
int mem_size;
|
|
int mem_seg;
|
|
enum digi_model model;
|
|
const struct digi_control_signals *csigs;
|
|
int opencnt;
|
|
unsigned pcibus : 1; /* On a PCI bus ? */
|
|
|
|
struct callout_handle callout; /* poll timeout handle */
|
|
struct callout_handle inttest; /* int test timeout handle */
|
|
const char *module;
|
|
|
|
u_char *(*setwin)(struct digi_softc *_sc, unsigned _addr);
|
|
void (*hidewin)(struct digi_softc *_sc);
|
|
void (*towin)(struct digi_softc *_sc, int _win);
|
|
#ifdef DEBUG
|
|
int intr_count;
|
|
#endif
|
|
};
|
|
|
|
extern devclass_t digi_devclass;
|
|
|
|
extern const struct digi_control_signals digi_xixe_signals;
|
|
extern const struct digi_control_signals digi_normal_signals;
|
|
|
|
const char *digi_errortxt(int _id);
|
|
int digi_attach(struct digi_softc *);
|
|
int digi_detach(device_t _dev);
|
|
int digi_shutdown(device_t _dev);
|
|
void digi_delay(struct digi_softc *_sc, const char *_txt,
|
|
u_long _timo);
|