1 /*- 2 * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org> 3 * based on work by Slawa Olhovchenkov 4 * John Prince <johnp@knight-trosoft.com> 5 * Eric Hernes 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #define W(p) (*(u_int16_t *)(p)) 33 #define vW(p) (*(u_int16_t volatile *)(p)) 34 #define D(p) (*(u_int32_t *)(p)) 35 #define vD(p) (*(u_int32_t volatile *)(p)) 36 37 #define CE_OVERRUN 0 38 #define CE_INTERRUPT_BUF_OVERFLOW 1 39 #define CE_TTY_BUF_OVERFLOW 2 40 #define CE_NTYPES 3 41 #define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum]) 42 43 /*#define DIGI_INTERRUPT*/ 44 45 #ifndef DEBUG 46 #define DEBUG 47 #endif 48 49 #ifdef DEBUG 50 extern unsigned digi_debug; 51 #define DLOG(level, args) if (digi_debug & (level)) device_printf args 52 #else 53 #define DLOG(level, args) 54 #endif 55 56 57 struct digi_softc; 58 59 /* digiboard port structure */ 60 struct digi_p { 61 struct digi_softc *sc; 62 63 int status; 64 #define ENABLED 1 65 #define DIGI_DTR_OFF 2 66 #define PAUSE_TX 8 67 #define PAUSE_RX 16 68 69 int opencnt; 70 u_short txbufsize; 71 u_short rxbufsize; 72 volatile struct board_chan *bc; 73 struct tty *tp; 74 75 u_char *txbuf; 76 u_char *rxbuf; 77 u_char txwin; 78 u_char rxwin; 79 80 u_char pnum; /* port number */ 81 82 u_char modemfake; /* Modem values to be forced */ 83 u_char mstat; 84 u_char modem; /* Force values */ 85 86 /* 87 * The high level of the driver never reads status registers directly 88 * because there would be too many side effects to handle conveniently. 89 * Instead, it reads copies of the registers stored here by the 90 * interrupt handler. 91 */ 92 u_char last_modem_status; /* last MSR read by intr handler */ 93 u_char prev_modem_status; /* last MSR handled by high level */ 94 95 u_long bytes_in, bytes_out; 96 u_int delta_error_counts[CE_NTYPES]; 97 u_long error_counts; 98 99 tcflag_t c_iflag; /* hold true IXON/IXOFF/IXANY */ 100 int lcc, lostcc, lbuf; 101 u_char send_ring; 102 103 unsigned laltpin : 1; /* Alternate pin settings locked */ 104 unsigned ialtpin : 1; /* Initial alternate pin settings */ 105 106 int cd; /* Depends on the altpin setting */ 107 int dsr; 108 }; 109 110 /* 111 * Map TIOCM_* values to digiboard values 112 */ 113 struct digi_control_signals { 114 int rts; 115 int cd; 116 int dsr; 117 int cts; 118 int ri; 119 int dtr; 120 }; 121 122 enum digi_board_status { 123 DIGI_STATUS_NOTINIT, 124 DIGI_STATUS_ENABLED, 125 DIGI_STATUS_DISABLED 126 }; 127 128 /* Digiboard per-board structure */ 129 struct digi_softc { 130 /* struct board_info */ 131 device_t dev; 132 133 const char *name; 134 enum digi_board_status status; 135 u_short numports; /* number of ports on card */ 136 u_int port; /* I/O port */ 137 u_int wport; /* window select I/O port */ 138 139 struct { 140 struct resource *mem; 141 int mrid; 142 struct resource *irq; 143 int irqrid; 144 struct resource *io; 145 int iorid; 146 void *irqHandler; 147 int unit; 148 struct cdev *ctldev; 149 } res; 150 151 u_char *vmem; /* virtual memory address */ 152 u_char *memcmd; 153 volatile u_char *memevent; 154 long pmem; /* physical memory address */ 155 156 struct { 157 u_char *data; 158 size_t size; 159 } bios, fep, link; 160 161 #ifdef DIGI_INTERRUPT 162 struct timeval intr_timestamp; 163 #endif 164 165 struct digi_p *ports; /* pointer to array of port descriptors */ 166 volatile struct global_data *gdata; 167 u_char window; /* saved window */ 168 int win_size; 169 int win_bits; 170 int mem_size; 171 int mem_seg; 172 enum digi_model model; 173 const struct digi_control_signals *csigs; 174 int opencnt; 175 unsigned pcibus : 1; /* On a PCI bus ? */ 176 177 struct callout_handle callout; /* poll timeout handle */ 178 struct callout_handle inttest; /* int test timeout handle */ 179 const char *module; 180 181 u_char *(*setwin)(struct digi_softc *_sc, unsigned _addr); 182 void (*hidewin)(struct digi_softc *_sc); 183 void (*towin)(struct digi_softc *_sc, int _win); 184 #ifdef DEBUG 185 int intr_count; 186 #endif 187 }; 188 189 extern devclass_t digi_devclass; 190 191 extern const struct digi_control_signals digi_xixe_signals; 192 extern const struct digi_control_signals digi_normal_signals; 193 194 const char *digi_errortxt(int _id); 195 int digi_attach(struct digi_softc *); 196 int digi_detach(device_t _dev); 197 int digi_shutdown(device_t _dev); 198 void digi_delay(struct digi_softc *_sc, const char *_txt, 199 u_long _timo); 200