]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/isa/istallion.c
In ascpoll, return revents, not 0.
[FreeBSD/FreeBSD.git] / sys / i386 / isa / istallion.c
1 /*****************************************************************************/
2
3 /*
4  * istallion.c  -- stallion intelligent multiport serial driver.
5  *
6  * Copyright (c) 1994-1996 Greg Ungerer (gerg@stallion.oz.au).
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Greg Ungerer.
20  * 4. Neither the name of the author nor the names of any co-contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * $FreeBSD$
37  */
38
39 /*****************************************************************************/
40
41 #include "opt_compat.h"
42
43 #define TTYDEFCHARS     1
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/malloc.h>
49 #include <sys/tty.h>
50 #include <sys/conf.h>
51 #include <sys/fcntl.h>
52 #include <sys/uio.h>
53 #include <sys/bus.h>
54 #include <vm/vm.h>
55 #include <vm/pmap.h>
56 #include <i386/isa/isa_device.h>
57 #include <machine/cdk.h>
58 #include <machine/comstats.h>
59
60 #ifndef COMPAT_OLDISA
61 #error "The stli device requires the old isa compatibility shims"
62 #endif
63
64 /*****************************************************************************/
65
66 /*
67  *      Define the version level of the kernel - so we can compile in the
68  *      appropriate bits of code. By default this will compile for a 2.1
69  *      level kernel.
70  */
71 #define VFREEBSD        220
72
73 #if VFREEBSD >= 220
74 #define STATIC          static
75 #else
76 #define STATIC
77 #endif
78
79 /*****************************************************************************/
80
81 /*
82  *      Define different board types. Not all of the following board types
83  *      are supported by this driver. But I will use the standard "assigned"
84  *      board numbers. Currently supported boards are abbreviated as:
85  *      ECP = EasyConnection 8/64, ONB = ONboard, BBY = Brumby and
86  *      STAL = Stallion.
87  */
88 #define BRD_UNKNOWN     0
89 #define BRD_STALLION    1
90 #define BRD_BRUMBY4     2
91 #define BRD_ONBOARD2    3
92 #define BRD_ONBOARD     4
93 #define BRD_BRUMBY8     5
94 #define BRD_BRUMBY16    6
95 #define BRD_ONBOARDE    7
96 #define BRD_ONBOARD32   9
97 #define BRD_ONBOARD2_32 10
98 #define BRD_ONBOARDRS   11
99 #define BRD_EASYIO      20
100 #define BRD_ECH         21
101 #define BRD_ECHMC       22
102 #define BRD_ECP         23
103 #define BRD_ECPE        24
104 #define BRD_ECPMC       25
105 #define BRD_ECHPCI      26
106
107 #define BRD_BRUMBY      BRD_BRUMBY4
108
109 /*****************************************************************************/
110
111 /*
112  *      Define important driver limitations.
113  */
114 #define STL_MAXBRDS             8
115 #define STL_MAXPANELS           4
116 #define STL_PORTSPERPANEL       16
117 #define STL_PORTSPERBRD         64
118
119 #define STL_MAXCHANS            STL_PORTSPERBRD
120
121
122 /*
123  *      Define the important minor number break down bits. These have been
124  *      chosen to be "compatible" with the standard sio driver minor numbers.
125  *      Extra high bits are used to distinguish between boards and also for
126  *      really high port numbers (> 32).
127  */
128 #define STL_CALLOUTDEV  0x80
129 #define STL_CTRLLOCK    0x40
130 #define STL_CTRLINIT    0x20
131 #define STL_CTRLDEV     (STL_CTRLLOCK | STL_CTRLINIT)
132
133 #define STL_MEMDEV      0x07000000
134
135 #define STL_DEFSPEED    TTYDEF_SPEED
136 #define STL_DEFCFLAG    (CS8 | CREAD | HUPCL)
137
138 /*****************************************************************************/
139
140 /*
141  *      Define our local driver identity first. Set up stuff to deal with
142  *      all the local structures required by a serial tty driver.
143  */
144 static char             stli_drvname[] = "stli";
145 static char const       stli_longdrvname[] = "Stallion Multiport Serial Driver";
146 static char const       stli_drvversion[] = "1.0.0";
147
148 static int      stli_nrbrds = 0;
149 static int      stli_doingtimeout = 0;
150
151 static char     *__file__ = /*__FILE__*/ "istallion.c";
152
153 /*
154  *      Define some macros to use to class define boards.
155  */
156 #define BRD_ISA         0x1
157 #define BRD_EISA        0x2
158 #define BRD_MCA         0x4
159 #define BRD_PCI         0x8
160
161 static unsigned char    stli_stliprobed[STL_MAXBRDS];
162
163 /*****************************************************************************/
164
165 /*
166  *      Define a set of structures to hold all the board/panel/port info
167  *      for our ports. These will be dynamically allocated as required at
168  *      driver initialization time.
169  */
170
171 /*
172  *      Port and board structures to hold status info about each object.
173  *      The board structure contains pointers to structures for each port
174  *      connected to it. Panels are not distinguished here, since
175  *      communication with the slave board will always be on a per port
176  *      basis.
177  */
178 typedef struct {
179         struct tty      tty;
180         int             portnr;
181         int             panelnr;
182         int             brdnr;
183         int             ioaddr;
184         int             callout;
185         int             devnr;
186         int             dtrwait;
187         int             dotimestamp;
188         int             waitopens;
189         int             hotchar;
190         int             rc;
191         int             argsize;
192         void            *argp;
193         unsigned int    state;
194         unsigned int    sigs;
195         struct termios  initintios;
196         struct termios  initouttios;
197         struct termios  lockintios;
198         struct termios  lockouttios;
199         struct timeval  timestamp;
200         asysigs_t       asig;
201         unsigned long   addr;
202         unsigned long   rxlost;
203         unsigned long   rxoffset;
204         unsigned long   txoffset;
205         unsigned long   pflag;
206         unsigned int    rxsize;
207         unsigned int    txsize;
208         unsigned char   reqidx;
209         unsigned char   reqbit;
210         unsigned char   portidx;
211         unsigned char   portbit;
212 } stliport_t;
213
214 /*
215  *      Use a structure of function pointers to do board level operations.
216  *      These include, enable/disable, paging shared memory, interrupting, etc.
217  */
218 typedef struct stlibrd {
219         int             brdnr;
220         int             brdtype;
221         int             unitid;
222         int             state;
223         int             nrpanels;
224         int             nrports;
225         int             nrdevs;
226         unsigned int    iobase;
227         unsigned long   paddr;
228         void            *vaddr;
229         int             memsize;
230         int             pagesize;
231         int             hostoffset;
232         int             slaveoffset;
233         int             bitsize;
234         int             confbits;
235         void            (*init)(struct stlibrd *brdp);
236         void            (*enable)(struct stlibrd *brdp);
237         void            (*reenable)(struct stlibrd *brdp);
238         void            (*disable)(struct stlibrd *brdp);
239         void            (*intr)(struct stlibrd *brdp);
240         void            (*reset)(struct stlibrd *brdp);
241         char            *(*getmemptr)(struct stlibrd *brdp,
242                                 unsigned long offset, int line);
243         int             panels[STL_MAXPANELS];
244         int             panelids[STL_MAXPANELS];
245         stliport_t      *ports[STL_PORTSPERBRD];
246 } stlibrd_t;
247
248 static stlibrd_t        *stli_brds[STL_MAXBRDS];
249
250 static int              stli_shared = 0;
251
252 /*
253  *      Keep a local char buffer for processing chars into the LD. We
254  *      do this to avoid copying from the boards shared memory one char
255  *      at a time.
256  */
257 static int              stli_rxtmplen;
258 static stliport_t       *stli_rxtmpport;
259 static char             stli_rxtmpbuf[TTYHOG];
260
261 /*
262  *      Define global stats structures. Not used often, and can be re-used
263  *      for each stats call.
264  */
265 static comstats_t       stli_comstats;
266 static combrd_t         stli_brdstats;
267 static asystats_t       stli_cdkstats;
268
269 /*
270  *      Per board state flags. Used with the state field of the board struct.
271  *      Not really much here... All we need to do is keep track of whether
272  *      the board has been detected, and whether it is actully running a slave
273  *      or not.
274  */
275 #define BST_FOUND       0x1
276 #define BST_STARTED     0x2
277
278 /*
279  *      Define the set of port state flags. These are marked for internal
280  *      state purposes only, usually to do with the state of communications
281  *      with the slave. They need to be updated atomically.
282  */
283 #define ST_INITIALIZING 0x1
284 #define ST_INITIALIZED  0x2
285 #define ST_OPENING      0x4
286 #define ST_CLOSING      0x8
287 #define ST_CMDING       0x10
288 #define ST_RXING        0x20
289 #define ST_TXBUSY       0x40
290 #define ST_DOFLUSHRX    0x80
291 #define ST_DOFLUSHTX    0x100
292 #define ST_DOSIGS       0x200
293 #define ST_GETSIGS      0x400
294 #define ST_DTRWAIT      0x800
295
296 /*
297  *      Define an array of board names as printable strings. Handy for
298  *      referencing boards when printing trace and stuff.
299  */
300 static char     *stli_brdnames[] = {
301         "Unknown",
302         "Stallion",
303         "Brumby",
304         "ONboard-MC",
305         "ONboard",
306         "Brumby",
307         "Brumby",
308         "ONboard-EI",
309         (char *) NULL,
310         "ONboard",
311         "ONboard-MC",
312         "ONboard-MC",
313         (char *) NULL,
314         (char *) NULL,
315         (char *) NULL,
316         (char *) NULL,
317         (char *) NULL,
318         (char *) NULL,
319         (char *) NULL,
320         (char *) NULL,
321         "EasyIO",
322         "EC8/32-AT",
323         "EC8/32-MC",
324         "EC8/64-AT",
325         "EC8/64-EI",
326         "EC8/64-MC",
327         "EC8/32-PCI",
328 };
329
330 /*****************************************************************************/
331
332 /*
333  *      Hardware configuration info for ECP boards. These defines apply
334  *      to the directly accessible io ports of the ECP. There is a set of
335  *      defines for each ECP board type, ISA, EISA and MCA.
336  */
337 #define ECP_IOSIZE      4
338 #define ECP_MEMSIZE     (128 * 1024)
339 #define ECP_ATPAGESIZE  (4 * 1024)
340 #define ECP_EIPAGESIZE  (64 * 1024)
341 #define ECP_MCPAGESIZE  (4 * 1024)
342
343 #define STL_EISAID      0x8c4e
344
345 /*
346  *      Important defines for the ISA class of ECP board.
347  */
348 #define ECP_ATIREG      0
349 #define ECP_ATCONFR     1
350 #define ECP_ATMEMAR     2
351 #define ECP_ATMEMPR     3
352 #define ECP_ATSTOP      0x1
353 #define ECP_ATINTENAB   0x10
354 #define ECP_ATENABLE    0x20
355 #define ECP_ATDISABLE   0x00
356 #define ECP_ATADDRMASK  0x3f000
357 #define ECP_ATADDRSHFT  12
358
359 /*
360  *      Important defines for the EISA class of ECP board.
361  */
362 #define ECP_EIIREG      0
363 #define ECP_EIMEMARL    1
364 #define ECP_EICONFR     2
365 #define ECP_EIMEMARH    3
366 #define ECP_EIENABLE    0x1
367 #define ECP_EIDISABLE   0x0
368 #define ECP_EISTOP      0x4
369 #define ECP_EIEDGE      0x00
370 #define ECP_EILEVEL     0x80
371 #define ECP_EIADDRMASKL 0x00ff0000
372 #define ECP_EIADDRSHFTL 16
373 #define ECP_EIADDRMASKH 0xff000000
374 #define ECP_EIADDRSHFTH 24
375 #define ECP_EIBRDENAB   0xc84
376
377 #define ECP_EISAID      0x4
378
379 /*
380  *      Important defines for the Micro-channel class of ECP board.
381  *      (It has a lot in common with the ISA boards.)
382  */
383 #define ECP_MCIREG      0
384 #define ECP_MCCONFR     1
385 #define ECP_MCSTOP      0x20
386 #define ECP_MCENABLE    0x80
387 #define ECP_MCDISABLE   0x00
388
389 /*
390  *      Hardware configuration info for ONboard and Brumby boards. These
391  *      defines apply to the directly accessible io ports of these boards.
392  */
393 #define ONB_IOSIZE      16
394 #define ONB_MEMSIZE     (64 * 1024)
395 #define ONB_ATPAGESIZE  (64 * 1024)
396 #define ONB_MCPAGESIZE  (64 * 1024)
397 #define ONB_EIMEMSIZE   (128 * 1024)
398 #define ONB_EIPAGESIZE  (64 * 1024)
399
400 /*
401  *      Important defines for the ISA class of ONboard board.
402  */
403 #define ONB_ATIREG      0
404 #define ONB_ATMEMAR     1
405 #define ONB_ATCONFR     2
406 #define ONB_ATSTOP      0x4
407 #define ONB_ATENABLE    0x01
408 #define ONB_ATDISABLE   0x00
409 #define ONB_ATADDRMASK  0xff0000
410 #define ONB_ATADDRSHFT  16
411
412 #define ONB_HIMEMENAB   0x02
413
414 /*
415  *      Important defines for the EISA class of ONboard board.
416  */
417 #define ONB_EIIREG      0
418 #define ONB_EIMEMARL    1
419 #define ONB_EICONFR     2
420 #define ONB_EIMEMARH    3
421 #define ONB_EIENABLE    0x1
422 #define ONB_EIDISABLE   0x0
423 #define ONB_EISTOP      0x4
424 #define ONB_EIEDGE      0x00
425 #define ONB_EILEVEL     0x80
426 #define ONB_EIADDRMASKL 0x00ff0000
427 #define ONB_EIADDRSHFTL 16
428 #define ONB_EIADDRMASKH 0xff000000
429 #define ONB_EIADDRSHFTH 24
430 #define ONB_EIBRDENAB   0xc84
431
432 #define ONB_EISAID      0x1
433
434 /*
435  *      Important defines for the Brumby boards. They are pretty simple,
436  *      there is not much that is programmably configurable.
437  */
438 #define BBY_IOSIZE      16
439 #define BBY_MEMSIZE     (64 * 1024)
440 #define BBY_PAGESIZE    (16 * 1024)
441
442 #define BBY_ATIREG      0
443 #define BBY_ATCONFR     1
444 #define BBY_ATSTOP      0x4
445
446 /*
447  *      Important defines for the Stallion boards. They are pretty simple,
448  *      there is not much that is programmably configurable.
449  */
450 #define STAL_IOSIZE     16
451 #define STAL_MEMSIZE    (64 * 1024)
452 #define STAL_PAGESIZE   (64 * 1024)
453
454 /*
455  *      Define the set of status register values for EasyConnection panels.
456  *      The signature will return with the status value for each panel. From
457  *      this we can determine what is attached to the board - before we have
458  *      actually down loaded any code to it.
459  */
460 #define ECH_PNLSTATUS   2
461 #define ECH_PNL16PORT   0x20
462 #define ECH_PNLIDMASK   0x07
463 #define ECH_PNLINTRPEND 0x80
464
465 /*
466  *      Define some macros to do things to the board. Even those these boards
467  *      are somewhat related there is often significantly different ways of
468  *      doing some operation on it (like enable, paging, reset, etc). So each
469  *      board class has a set of functions which do the commonly required
470  *      operations. The macros below basically just call these functions,
471  *      generally checking for a NULL function - which means that the board
472  *      needs nothing done to it to achieve this operation!
473  */
474 #define EBRDINIT(brdp)                                  \
475         if (brdp->init != NULL)                         \
476                 (* brdp->init)(brdp)
477
478 #define EBRDENABLE(brdp)                                \
479         if (brdp->enable != NULL)                       \
480                 (* brdp->enable)(brdp);
481
482 #define EBRDDISABLE(brdp)                               \
483         if (brdp->disable != NULL)                      \
484                 (* brdp->disable)(brdp);
485
486 #define EBRDINTR(brdp)                                  \
487         if (brdp->intr != NULL)                         \
488                 (* brdp->intr)(brdp);
489
490 #define EBRDRESET(brdp)                                 \
491         if (brdp->reset != NULL)                        \
492                 (* brdp->reset)(brdp);
493
494 #define EBRDGETMEMPTR(brdp,offset)                      \
495         (* brdp->getmemptr)(brdp, offset, __LINE__)
496
497 /*
498  *      Define the maximal baud rate.
499  */
500 #define STL_MAXBAUD     230400
501
502 /*****************************************************************************/
503
504 /*
505  *      Define macros to extract a brd and port number from a minor number.
506  *      This uses the extended minor number range in the upper 2 bytes of
507  *      the device number. This gives us plenty of minor numbers to play
508  *      with...
509  */
510 #define MKDEV2BRD(m)    ((minor(m) & 0x00700000) >> 20)
511 #define MKDEV2PORT(m)   ((minor(m) & 0x1f) | ((minor(m) & 0x00010000) >> 11))
512
513 /*
514  *      Define some handy local macros...
515  */
516 #ifndef MIN
517 #define MIN(a,b)        (((a) <= (b)) ? (a) : (b))
518 #endif
519
520 /*****************************************************************************/
521
522 /*
523  *      Declare all those functions in this driver!  First up is the set of
524  *      externally visible functions.
525  */
526 static int      stliprobe(struct isa_device *idp);
527 static int      stliattach(struct isa_device *idp);
528
529 STATIC  d_open_t        stliopen;
530 STATIC  d_close_t       stliclose;
531 STATIC  d_read_t        stliread;
532 STATIC  d_write_t       stliwrite;
533 STATIC  d_ioctl_t       stliioctl;
534
535 /*
536  *      Internal function prototypes.
537  */
538 static stliport_t *stli_dev2port(dev_t dev);
539 static int      stli_isaprobe(struct isa_device *idp);
540 static int      stli_eisaprobe(struct isa_device *idp);
541 static int      stli_mcaprobe(struct isa_device *idp);
542 static int      stli_brdinit(stlibrd_t *brdp);
543 static int      stli_brdattach(stlibrd_t *brdp);
544 static int      stli_initecp(stlibrd_t *brdp);
545 static int      stli_initonb(stlibrd_t *brdp);
546 static int      stli_initports(stlibrd_t *brdp);
547 static int      stli_startbrd(stlibrd_t *brdp);
548 static void     stli_poll(void *arg);
549 static __inline void    stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp);
550 static __inline int     stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);
551 static __inline void    stli_dodelaycmd(stliport_t *portp,
552                                         volatile cdkctrl_t *cp);
553 static void     stli_mkasysigs(asysigs_t *sp, int dtr, int rts);
554 static long     stli_mktiocm(unsigned long sigvalue);
555 static void     stli_rxprocess(stlibrd_t *brdp, stliport_t *portp);
556 static void     stli_flush(stliport_t *portp, int flag);
557 static void     stli_start(struct tty *tp);
558 static void     stli_stop(struct tty *tp, int rw);
559 static int      stli_param(struct tty *tp, struct termios *tiosp);
560 static void     stli_ttyoptim(stliport_t *portp, struct termios *tiosp);
561 static void     stli_dtrwakeup(void *arg);
562 static int      stli_initopen(stliport_t *portp);
563 static int      stli_shutdownclose(stliport_t *portp);
564 static int      stli_rawopen(stlibrd_t *brdp, stliport_t *portp,
565                         unsigned long arg, int wait);
566 static int      stli_rawclose(stlibrd_t *brdp, stliport_t *portp,
567                         unsigned long arg, int wait);
568 static int      stli_cmdwait(stlibrd_t *brdp, stliport_t *portp,
569                         unsigned long cmd, void *arg, int size, int copyback);
570 static void     stli_sendcmd(stlibrd_t *brdp, stliport_t *portp,
571                         unsigned long cmd, void *arg, int size, int copyback);
572 static void     stli_mkasyport(stliport_t *portp, asyport_t *pp,
573                         struct termios *tiosp);
574 static int      stli_memrw(dev_t dev, struct uio *uiop, int flag);
575 static int      stli_memioctl(dev_t dev, unsigned long cmd, caddr_t data,
576                         int flag, struct proc *p);
577 static int      stli_getbrdstats(caddr_t data);
578 static int      stli_getportstats(stliport_t *portp, caddr_t data);
579 static int      stli_clrportstats(stliport_t *portp, caddr_t data);
580 static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);
581
582 static void     stli_ecpinit(stlibrd_t *brdp);
583 static void     stli_ecpenable(stlibrd_t *brdp);
584 static void     stli_ecpdisable(stlibrd_t *brdp);
585 static void     stli_ecpreset(stlibrd_t *brdp);
586 static char     *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset,
587                         int line);
588 static void     stli_ecpintr(stlibrd_t *brdp);
589 static void     stli_ecpeiinit(stlibrd_t *brdp);
590 static void     stli_ecpeienable(stlibrd_t *brdp);
591 static void     stli_ecpeidisable(stlibrd_t *brdp);
592 static void     stli_ecpeireset(stlibrd_t *brdp);
593 static char     *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset,
594                         int line);
595 static void     stli_ecpmcenable(stlibrd_t *brdp);
596 static void     stli_ecpmcdisable(stlibrd_t *brdp);
597 static void     stli_ecpmcreset(stlibrd_t *brdp);
598 static char     *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset,
599                         int line);
600
601 static void     stli_onbinit(stlibrd_t *brdp);
602 static void     stli_onbenable(stlibrd_t *brdp);
603 static void     stli_onbdisable(stlibrd_t *brdp);
604 static void     stli_onbreset(stlibrd_t *brdp);
605 static char     *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset,
606                         int line);
607 static void     stli_onbeinit(stlibrd_t *brdp);
608 static void     stli_onbeenable(stlibrd_t *brdp);
609 static void     stli_onbedisable(stlibrd_t *brdp);
610 static void     stli_onbereset(stlibrd_t *brdp);
611 static char     *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset,
612                         int line);
613 static void     stli_bbyinit(stlibrd_t *brdp);
614 static void     stli_bbyreset(stlibrd_t *brdp);
615 static char     *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset,
616                         int line);
617 static void     stli_stalinit(stlibrd_t *brdp);
618 static void     stli_stalreset(stlibrd_t *brdp);
619 static char     *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset,
620                         int line);
621
622 /*****************************************************************************/
623
624 /*
625  *      Declare the driver isa structure.
626  */
627 struct isa_driver       stlidriver = {
628         INTR_TYPE_TTY,
629         stliprobe,
630         stliattach,
631         stli_drvname
632 };
633 COMPAT_ISA_DRIVER(stli, stlidriver);
634
635 /*****************************************************************************/
636
637 #if VFREEBSD >= 220
638
639 /*
640  *      FreeBSD-2.2+ kernel linkage.
641  */
642
643 #define CDEV_MAJOR      75
644 static struct cdevsw stli_cdevsw = {
645         /* open */      stliopen,
646         /* close */     stliclose,
647         /* read */      stliread,
648         /* write */     stliwrite,
649         /* ioctl */     stliioctl,
650         /* poll */      ttypoll,
651         /* mmap */      nommap,
652         /* strategy */  nostrategy,
653         /* name */      stli_drvname,
654         /* maj */       CDEV_MAJOR,
655         /* dump */      nodump,
656         /* psize */     nopsize,
657         /* flags */     D_TTY | D_KQFILTER,
658         /* bmaj */      -1,
659         /* kqfilter */  ttykqfilter,
660 };
661
662 #endif
663
664 /*****************************************************************************/
665
666 static stlibrd_t *stli_brdalloc(void)
667 {
668         stlibrd_t       *brdp;
669
670         brdp = (stlibrd_t *) malloc(sizeof(stlibrd_t), M_TTYS, M_NOWAIT|M_ZERO);
671         if (brdp == (stlibrd_t *) NULL) {
672                 printf("STALLION: failed to allocate memory (size=%d)\n",
673                         sizeof(stlibrd_t));
674                 return((stlibrd_t *) NULL);
675         }
676         return(brdp);
677 }
678
679 /*****************************************************************************/
680
681 /*
682  *      Find an available internal board number (unit number). The problem
683  *      is that the same unit numbers can be assigned to different class
684  *      boards - but we only want to maintain one setup board structures.
685  */
686
687 static int stli_findfreeunit(void)
688 {
689         int     i;
690
691         for (i = 0; (i < STL_MAXBRDS); i++)
692                 if (stli_brds[i] == (stlibrd_t *) NULL)
693                         break;
694         return((i >= STL_MAXBRDS) ? -1 : i);
695 }
696
697 /*****************************************************************************/
698
699 /*
700  *      Try and determine the ISA board type. Hopefully the board
701  *      configuration entry will help us out, using the flags field.
702  *      If not, we may ne be able to determine the board type...
703  */
704
705 static int stli_isaprobe(struct isa_device *idp)
706 {
707         int     btype;
708
709 #if DEBUG
710         printf("stli_isaprobe(idp=%x): unit=%d iobase=%x flags=%x\n",
711                 (int) idp, idp->id_unit, idp->id_iobase, idp->id_flags);
712 #endif
713
714         switch (idp->id_flags) {
715         case BRD_STALLION:
716         case BRD_BRUMBY4:
717         case BRD_BRUMBY8:
718         case BRD_BRUMBY16:
719         case BRD_ONBOARD:
720         case BRD_ONBOARD32:
721         case BRD_ECP:
722                 btype = idp->id_flags;
723                 break;
724         default:
725                 btype = 0;
726                 break;
727         }
728         return(btype);
729 }
730
731 /*****************************************************************************/
732
733 /*
734  *      Probe for an EISA board type. We should be able to read the EISA ID,
735  *      that will tell us if a board is present or not...
736  */
737
738 static int stli_eisaprobe(struct isa_device *idp)
739 {
740         int     btype, eid;
741
742 #if DEBUG
743         printf("stli_eisaprobe(idp=%x): unit=%d iobase=%x flags=%x\n",
744                 (int) idp, idp->id_unit, idp->id_iobase, idp->id_flags);
745 #endif
746
747 /*
748  *      Firstly check if this is an EISA system. Do this by probing for
749  *      the system board EISA ID. If this is not an EISA system then
750  *      don't bother going any further!
751  */
752         outb(0xc80, 0xff);
753         if (inb(0xc80) == 0xff)
754                 return(0);
755
756 /*
757  *      Try and read the EISA ID from the board at specified address.
758  *      If one is present it will tell us the board type as well.
759  */
760         outb((idp->id_iobase + 0xc80), 0xff);
761         eid = inb(idp->id_iobase + 0xc80);
762         eid |= inb(idp->id_iobase + 0xc81) << 8;
763         if (eid != STL_EISAID)
764                 return(0);
765
766         btype = 0;
767         eid = inb(idp->id_iobase + 0xc82);
768         if (eid == ECP_EISAID)
769                 btype = BRD_ECPE;
770         else if (eid == ONB_EISAID)
771                 btype = BRD_ONBOARDE;
772
773         outb((idp->id_iobase + 0xc84), 0x1);
774         return(btype);
775 }
776
777 /*****************************************************************************/
778
779 /*
780  *      Probe for an MCA board type. Not really sure how to do this yet,
781  *      so for now just use the supplied flag specifier as board type...
782  */
783
784 static int stli_mcaprobe(struct isa_device *idp)
785 {
786         int     btype;
787
788 #if DEBUG
789         printf("stli_mcaprobe(idp=%x): unit=%d iobase=%x flags=%x\n",
790                 (int) idp, idp->id_unit, idp->id_iobase, idp->id_flags);
791 #endif
792
793         switch (idp->id_flags) {
794         case BRD_ONBOARD2:
795         case BRD_ONBOARD2_32:
796         case BRD_ONBOARDRS:
797         case BRD_ECHMC:
798         case BRD_ECPMC:
799                 btype = idp->id_flags;
800                 break;
801         default:
802                 btype = 0;
803                 break;
804         }
805         return(0);
806 }
807
808 /*****************************************************************************/
809
810 /*
811  *      Probe for a board. This is involved, since we need to enable the
812  *      shared memory region to see if the board is really there or not...
813  */
814
815 static int stliprobe(struct isa_device *idp)
816 {
817         stlibrd_t       *brdp;
818         int             btype, bclass;
819         static int once;
820
821         if (!once++)
822                 cdevsw_add(&stli_cdevsw);
823
824 #if DEBUG
825         printf("stliprobe(idp=%x): unit=%d iobase=%x flags=%x\n", (int) idp,
826                 idp->id_unit, idp->id_iobase, idp->id_flags);
827 #endif
828
829         if (idp->id_unit > STL_MAXBRDS)
830                 return(0);
831
832 /*
833  *      First up determine what bus type of board we might be dealing
834  *      with. It is easy to separate out the ISA from the EISA and MCA
835  *      boards, based on their IO addresses. We may not be able to tell
836  *      the EISA and MCA apart on IO address alone...
837  */
838         bclass = 0;
839         if ((idp->id_iobase > 0) && (idp->id_iobase < 0x400)) {
840                 bclass |= BRD_ISA;
841         } else {
842                 /* ONboard2 range */
843                 if ((idp->id_iobase >= 0x700) && (idp->id_iobase < 0x900))
844                         bclass |= BRD_MCA;
845                 /* EC-MCA ranges */
846                 if ((idp->id_iobase >= 0x7000) && (idp->id_iobase < 0x7400))
847                         bclass |= BRD_MCA;
848                 if ((idp->id_iobase >= 0x8000) && (idp->id_iobase < 0xc000))
849                         bclass |= BRD_MCA;
850                 /* EISA board range */
851                 if ((idp->id_iobase & ~0xf000) == 0)
852                         bclass |= BRD_EISA;
853         }
854
855         if ((bclass == 0) || (idp->id_iobase == 0))
856                 return(0);
857
858 /*
859  *      Based on the board bus type, try and figure out what it might be...
860  */
861         btype = 0;
862         if (bclass & BRD_ISA)
863                 btype = stli_isaprobe(idp);
864         if ((btype == 0) && (bclass & BRD_EISA))
865                 btype = stli_eisaprobe(idp);
866         if ((btype == 0) && (bclass & BRD_MCA))
867                 btype = stli_mcaprobe(idp);
868         if (btype == 0)
869                 return(0);
870
871 /*
872  *      Go ahead and try probing for the shared memory region now.
873  *      This way we will really know if the board is here...
874  */
875         if ((brdp = stli_brdalloc()) == (stlibrd_t *) NULL)
876                 return(0);
877
878         brdp->brdnr = stli_findfreeunit();
879         brdp->brdtype = btype;
880         brdp->unitid = idp->id_unit;
881         brdp->iobase = idp->id_iobase;
882         brdp->vaddr = idp->id_maddr;
883         brdp->paddr = vtophys(idp->id_maddr);
884
885 #if DEBUG
886         printf("%s(%d): btype=%x unit=%d brd=%d io=%x mem=%lx(%p)\n",
887                 __file__, __LINE__, btype, brdp->unitid, brdp->brdnr,
888                 brdp->iobase, brdp->paddr, (void *) brdp->vaddr);
889 #endif
890
891         stli_stliprobed[idp->id_unit] = brdp->brdnr;
892         stli_brdinit(brdp);
893         if ((brdp->state & BST_FOUND) == 0) {
894                 stli_brds[brdp->brdnr] = (stlibrd_t *) NULL;
895                 return(0);
896         }
897         stli_nrbrds++;
898         return(1);
899 }
900
901 /*****************************************************************************/
902
903 /*
904  *      Allocate resources for and initialize a board.
905  */
906
907 static int stliattach(struct isa_device *idp)
908 {
909         stlibrd_t       *brdp;
910         int             brdnr;
911
912 #if DEBUG
913         printf("stliattach(idp=%p): unit=%d iobase=%x\n", (void *) idp,
914                 idp->id_unit, idp->id_iobase);
915 #endif
916
917         brdnr = stli_stliprobed[idp->id_unit];
918         brdp = stli_brds[brdnr];
919         if (brdp == (stlibrd_t *) NULL)
920                 return(0);
921         if (brdp->state & BST_FOUND)
922                 stli_brdattach(brdp);
923         return(1);
924 }
925
926
927 /*****************************************************************************/
928
929 STATIC int stliopen(dev_t dev, int flag, int mode, struct proc *p)
930 {
931         struct tty      *tp;
932         stliport_t      *portp;
933         int             error, callout, x;
934
935 #if DEBUG
936         printf("stliopen(dev=%x,flag=%x,mode=%x,p=%x)\n", (int) dev, flag,
937                 mode, (int) p);
938 #endif
939
940 /*
941  *      Firstly check if the supplied device number is a valid device.
942  */
943         if (minor(dev) & STL_MEMDEV)
944                 return(0);
945
946         portp = stli_dev2port(dev);
947         if (portp == (stliport_t *) NULL)
948                 return(ENXIO);
949         tp = &portp->tty;
950         dev->si_tty = tp;
951         callout = minor(dev) & STL_CALLOUTDEV;
952         error = 0;
953
954         x = spltty();
955
956 stliopen_restart:
957 /*
958  *      Wait here for the DTR drop timeout period to expire.
959  */
960         while (portp->state & ST_DTRWAIT) {
961                 error = tsleep(&portp->dtrwait, (TTIPRI | PCATCH),
962                         "stlidtr", 0);
963                 if (error)
964                         goto stliopen_end;
965         }
966
967 /*
968  *      If the port is in its raw hardware initialization phase, then
969  *      hold up here 'till it is done.
970  */
971         while (portp->state & (ST_INITIALIZING | ST_CLOSING)) {
972                 error = tsleep(&portp->state, (TTIPRI | PCATCH),
973                         "stliraw", 0);
974                 if (error)
975                         goto stliopen_end;
976         }
977
978 /*
979  *      We have a valid device, so now we check if it is already open.
980  *      If not then initialize the port hardware and set up the tty
981  *      struct as required.
982  */
983         if ((tp->t_state & TS_ISOPEN) == 0) {
984                 tp->t_oproc = stli_start;
985                 tp->t_param = stli_param;
986                 tp->t_stop = stli_stop;
987                 tp->t_dev = dev;
988                 tp->t_termios = callout ? portp->initouttios :
989                         portp->initintios;
990                 stli_initopen(portp);
991                 wakeup(&portp->state);
992                 if ((portp->sigs & TIOCM_CD) || callout)
993                         (*linesw[tp->t_line].l_modem)(tp, 1);
994         } else {
995                 if (callout) {
996                         if (portp->callout == 0) {
997                                 error = EBUSY;
998                                 goto stliopen_end;
999                         }
1000                 } else {
1001                         if (portp->callout != 0) {
1002                                 if (flag & O_NONBLOCK) {
1003                                         error = EBUSY;
1004                                         goto stliopen_end;
1005                                 }
1006                                 error = tsleep(&portp->callout,
1007                                         (TTIPRI | PCATCH), "stlicall", 0);
1008                                 if (error)
1009                                         goto stliopen_end;
1010                                 goto stliopen_restart;
1011                         }
1012                 }
1013                 if ((tp->t_state & TS_XCLUDE) &&
1014                     suser(p)) {
1015                         error = EBUSY;
1016                         goto stliopen_end;
1017                 }
1018         }
1019
1020 /*
1021  *      If this port is not the callout device and we do not have carrier
1022  *      then we need to sleep, waiting for it to be asserted.
1023  */
1024         if (((tp->t_state & TS_CARR_ON) == 0) && !callout &&
1025                         ((tp->t_cflag & CLOCAL) == 0) &&
1026                         ((flag & O_NONBLOCK) == 0)) {
1027                 portp->waitopens++;
1028                 error = tsleep(TSA_CARR_ON(tp), (TTIPRI | PCATCH), "stlidcd",0);
1029                 portp->waitopens--;
1030                 if (error)
1031                         goto stliopen_end;
1032                 goto stliopen_restart;
1033         }
1034
1035 /*
1036  *      Open the line discipline.
1037  */
1038         error = (*linesw[tp->t_line].l_open)(dev, tp);
1039         stli_ttyoptim(portp, &tp->t_termios);
1040         if ((tp->t_state & TS_ISOPEN) && callout)
1041                 portp->callout = 1;
1042
1043 /*
1044  *      If for any reason we get to here and the port is not actually
1045  *      open then close of the physical hardware - no point leaving it
1046  *      active when the open failed...
1047  */
1048 stliopen_end:
1049         splx(x);
1050         if (((tp->t_state & TS_ISOPEN) == 0) && (portp->waitopens == 0))
1051                 stli_shutdownclose(portp);
1052
1053         return(error);
1054 }
1055
1056 /*****************************************************************************/
1057
1058 STATIC int stliclose(dev_t dev, int flag, int mode, struct proc *p)
1059 {
1060         struct tty      *tp;
1061         stliport_t      *portp;
1062         int             x;
1063
1064 #if DEBUG
1065         printf("stliclose(dev=%s,flag=%x,mode=%x,p=%p)\n",
1066                 devtoname(dev), flag, mode, (void *) p);
1067 #endif
1068
1069         if (minor(dev) & STL_MEMDEV)
1070                 return(0);
1071
1072         portp = stli_dev2port(dev);
1073         if (portp == (stliport_t *) NULL)
1074                 return(ENXIO);
1075         tp = &portp->tty;
1076
1077         x = spltty();
1078         (*linesw[tp->t_line].l_close)(tp, flag);
1079         stli_ttyoptim(portp, &tp->t_termios);
1080         stli_shutdownclose(portp);
1081         ttyclose(tp);
1082         splx(x);
1083         return(0);
1084 }
1085
1086
1087 STATIC int stliread(dev_t dev, struct uio *uiop, int flag)
1088 {
1089
1090 #if DEBUG
1091         printf("stliread(dev=%s,uiop=%p,flag=%x)\n", devtoname(dev),
1092                 (void *) uiop, flag);
1093 #endif
1094
1095         if (minor(dev) & STL_MEMDEV)
1096                 return(stli_memrw(dev, uiop, flag));
1097         else
1098                 return(ttyread(dev, uiop, flag));
1099 }
1100
1101 /*****************************************************************************/
1102
1103 #if VFREEBSD >= 220
1104
1105 STATIC void stli_stop(struct tty *tp, int rw)
1106 {
1107 #if DEBUG
1108         printf("stli_stop(tp=%x,rw=%x)\n", (int) tp, rw);
1109 #endif
1110
1111         stli_flush((stliport_t *) tp, rw);
1112 }
1113
1114 #else
1115
1116 STATIC int stlistop(struct tty *tp, int rw)
1117 {
1118 #if DEBUG
1119         printf("stlistop(tp=%x,rw=%x)\n", (int) tp, rw);
1120 #endif
1121
1122         stli_flush((stliport_t *) tp, rw);
1123         return(0);
1124 }
1125
1126 #endif
1127
1128 /*****************************************************************************/
1129
1130 STATIC int stliwrite(dev_t dev, struct uio *uiop, int flag)
1131 {
1132 #if DEBUG
1133         printf("stliwrite(dev=%s,uiop=%p,flag=%x)\n", devtoname(dev),
1134                 (void *) uiop, flag);
1135 #endif
1136
1137         if (minor(dev) & STL_MEMDEV)
1138                 return(stli_memrw(dev, uiop, flag));
1139         else
1140                 return(ttywrite(dev, uiop, flag));
1141 }
1142
1143 /*****************************************************************************/
1144
1145 STATIC int stliioctl(dev_t dev, unsigned long cmd, caddr_t data, int flag,
1146                      struct proc *p)
1147 {
1148         struct termios  *newtios, *localtios;
1149         struct tty      *tp;
1150         stlibrd_t       *brdp;
1151         stliport_t      *portp;
1152         long            arg;
1153         int             error, i, x;
1154
1155 #if DEBUG
1156         printf("stliioctl(dev=%s,cmd=%lx,data=%p,flag=%x,p=%p)\n",
1157                 devtoname(dev), cmd, (void *) data, flag, (void *) p);
1158 #endif
1159
1160         if (minor(dev) & STL_MEMDEV)
1161                 return(stli_memioctl(dev, cmd, data, flag, p));
1162
1163         portp = stli_dev2port(dev);
1164         if (portp == (stliport_t *) NULL)
1165                 return(ENODEV);
1166         if ((brdp = stli_brds[portp->brdnr]) == (stlibrd_t *) NULL)
1167                 return(ENODEV);
1168         tp = &portp->tty;
1169         error = 0;
1170         
1171 /*
1172  *      First up handle ioctls on the control devices.
1173  */
1174         if (minor(dev) & STL_CTRLDEV) {
1175                 if ((minor(dev) & STL_CTRLDEV) == STL_CTRLINIT)
1176                         localtios = (minor(dev) & STL_CALLOUTDEV) ?
1177                                 &portp->initouttios : &portp->initintios;
1178                 else if ((minor(dev) & STL_CTRLDEV) == STL_CTRLLOCK)
1179                         localtios = (minor(dev) & STL_CALLOUTDEV) ?
1180                                 &portp->lockouttios : &portp->lockintios;
1181                 else
1182                         return(ENODEV);
1183
1184                 switch (cmd) {
1185                 case TIOCSETA:
1186                         if ((error = suser(p)) == 0)
1187                                 *localtios = *((struct termios *) data);
1188                         break;
1189                 case TIOCGETA:
1190                         *((struct termios *) data) = *localtios;
1191                         break;
1192                 case TIOCGETD:
1193                         *((int *) data) = TTYDISC;
1194                         break;
1195                 case TIOCGWINSZ:
1196                         bzero(data, sizeof(struct winsize));
1197                         break;
1198                 default:
1199                         error = ENOTTY;
1200                         break;
1201                 }
1202                 return(error);
1203         }
1204
1205 /*
1206  *      Deal with 4.3 compatibility issues if we have too...
1207  */
1208 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1209         if (1) {
1210                 struct termios  tios;
1211                 unsigned long   oldcmd;
1212
1213                 tios = tp->t_termios;
1214                 oldcmd = cmd;
1215                 if ((error = ttsetcompat(tp, &cmd, data, &tios)))
1216                         return(error);
1217                 if (cmd != oldcmd)
1218                         data = (caddr_t) &tios;
1219         }
1220 #endif
1221
1222 /*
1223  *      Carry out some pre-cmd processing work first...
1224  *      Hmmm, not so sure we want this, disable for now...
1225  */
1226         if ((cmd == TIOCSETA) || (cmd == TIOCSETAW) || (cmd == TIOCSETAF)) {
1227                 newtios = (struct termios *) data;
1228                 localtios = (minor(dev) & STL_CALLOUTDEV) ? &portp->lockouttios :
1229                          &portp->lockintios;
1230
1231                 newtios->c_iflag = (tp->t_iflag & localtios->c_iflag) |
1232                         (newtios->c_iflag & ~localtios->c_iflag);
1233                 newtios->c_oflag = (tp->t_oflag & localtios->c_oflag) |
1234                         (newtios->c_oflag & ~localtios->c_oflag);
1235                 newtios->c_cflag = (tp->t_cflag & localtios->c_cflag) |
1236                         (newtios->c_cflag & ~localtios->c_cflag);
1237                 newtios->c_lflag = (tp->t_lflag & localtios->c_lflag) |
1238                         (newtios->c_lflag & ~localtios->c_lflag);
1239                 for (i = 0; (i < NCCS); i++) {
1240                         if (localtios->c_cc[i] != 0)
1241                                 newtios->c_cc[i] = tp->t_cc[i];
1242                 }
1243                 if (localtios->c_ispeed != 0)
1244                         newtios->c_ispeed = tp->t_ispeed;
1245                 if (localtios->c_ospeed != 0)
1246                         newtios->c_ospeed = tp->t_ospeed;
1247         }
1248
1249 /*
1250  *      Call the line discipline and the common command processing to
1251  *      process this command (if they can).
1252  */
1253         error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1254         if (error != ENOIOCTL)
1255                 return(error);
1256
1257         x = spltty();
1258         error = ttioctl(tp, cmd, data, flag);
1259         stli_ttyoptim(portp, &tp->t_termios);
1260         if (error != ENOIOCTL) {
1261                 splx(x);
1262                 return(error);
1263         }
1264
1265         error = 0;
1266
1267 /*
1268  *      Process local commands here. These are all commands that only we
1269  *      can take care of (they all rely on actually doing something special
1270  *      to the actual hardware).
1271  */
1272         switch (cmd) {
1273         case TIOCSBRK:
1274                 arg = BREAKON;
1275                 error = stli_cmdwait(brdp, portp, A_BREAK, &arg,
1276                         sizeof(unsigned long), 0);
1277                 break;
1278         case TIOCCBRK:
1279                 arg = BREAKOFF;
1280                 error = stli_cmdwait(brdp, portp, A_BREAK, &arg,
1281                         sizeof(unsigned long), 0);
1282                 break;
1283         case TIOCSDTR:
1284                 stli_mkasysigs(&portp->asig, 1, -1);
1285                 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1286                         sizeof(asysigs_t), 0);
1287                 break;
1288         case TIOCCDTR:
1289                 stli_mkasysigs(&portp->asig, 0, -1);
1290                 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1291                         sizeof(asysigs_t), 0);
1292                 break;
1293         case TIOCMSET:
1294                 i = *((int *) data);
1295                 stli_mkasysigs(&portp->asig, ((i & TIOCM_DTR) ? 1 : 0),
1296                         ((i & TIOCM_RTS) ? 1 : 0));
1297                 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1298                         sizeof(asysigs_t), 0);
1299                 break;
1300         case TIOCMBIS:
1301                 i = *((int *) data);
1302                 stli_mkasysigs(&portp->asig, ((i & TIOCM_DTR) ? 1 : -1),
1303                         ((i & TIOCM_RTS) ? 1 : -1));
1304                 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1305                         sizeof(asysigs_t), 0);
1306                 break;
1307         case TIOCMBIC:
1308                 i = *((int *) data);
1309                 stli_mkasysigs(&portp->asig, ((i & TIOCM_DTR) ? 0 : -1),
1310                         ((i & TIOCM_RTS) ? 0 : -1));
1311                 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1312                         sizeof(asysigs_t), 0);
1313                 break;
1314         case TIOCMGET:
1315                 if ((error = stli_cmdwait(brdp, portp, A_GETSIGNALS,
1316                                 &portp->asig, sizeof(asysigs_t), 1)) < 0)
1317                         break;
1318                 portp->sigs = stli_mktiocm(portp->asig.sigvalue);
1319                 *((int *) data) = (portp->sigs | TIOCM_LE);
1320                 break;
1321         case TIOCMSDTRWAIT:
1322                 if ((error = suser(p)) == 0)
1323                         portp->dtrwait = *((int *) data) * hz / 100;
1324                 break;
1325         case TIOCMGDTRWAIT:
1326                 *((int *) data) = portp->dtrwait * 100 / hz;
1327                 break;
1328         case TIOCTIMESTAMP:
1329                 portp->dotimestamp = 1;
1330                 *((struct timeval *) data) = portp->timestamp;
1331                 break;
1332         default:
1333                 error = ENOTTY;
1334                 break;
1335         }
1336         splx(x);
1337
1338         return(error);
1339 }
1340
1341 /*****************************************************************************/
1342
1343 /*
1344  *      Convert the specified minor device number into a port struct
1345  *      pointer. Return NULL if the device number is not a valid port.
1346  */
1347
1348 STATIC stliport_t *stli_dev2port(dev_t dev)
1349 {
1350         stlibrd_t       *brdp;
1351
1352         brdp = stli_brds[MKDEV2BRD(dev)];
1353         if (brdp == (stlibrd_t *) NULL)
1354                 return((stliport_t *) NULL);
1355         if ((brdp->state & BST_STARTED) == 0)
1356                 return((stliport_t *) NULL);
1357         return(brdp->ports[MKDEV2PORT(dev)]);
1358 }
1359
1360 /*****************************************************************************/
1361
1362 /*
1363  *      Carry out first open operations on a port. This involves a number of
1364  *      commands to be sent to the slave. We need to open the port, set the
1365  *      notification events, set the initial port settings, get and set the
1366  *      initial signal values. We sleep and wait in between each one. But
1367  *      this still all happens pretty quickly.
1368  */
1369
1370 static int stli_initopen(stliport_t *portp)
1371 {
1372         stlibrd_t       *brdp;
1373         asynotify_t     nt;
1374         asyport_t       aport;
1375         int             rc;
1376
1377 #if DEBUG
1378         printf("stli_initopen(portp=%x)\n", (int) portp);
1379 #endif
1380
1381         if ((brdp = stli_brds[portp->brdnr]) == (stlibrd_t *) NULL)
1382                 return(ENXIO);
1383         if (portp->state & ST_INITIALIZED)
1384                 return(0);
1385         portp->state |= ST_INITIALIZED;
1386
1387         if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0)
1388                 return(rc);
1389
1390         bzero(&nt, sizeof(asynotify_t));
1391         nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);
1392         nt.signal = SG_DCD;
1393         if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt,
1394             sizeof(asynotify_t), 0)) < 0)
1395                 return(rc);
1396
1397         stli_mkasyport(portp, &aport, &portp->tty.t_termios);
1398         if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,
1399             sizeof(asyport_t), 0)) < 0)
1400                 return(rc);
1401
1402         portp->state |= ST_GETSIGS;
1403         if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig,
1404             sizeof(asysigs_t), 1)) < 0)
1405                 return(rc);
1406         if (portp->state & ST_GETSIGS) {
1407                 portp->sigs = stli_mktiocm(portp->asig.sigvalue);
1408                 portp->state &= ~ST_GETSIGS;
1409         }
1410
1411         stli_mkasysigs(&portp->asig, 1, 1);
1412         if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1413             sizeof(asysigs_t), 0)) < 0)
1414                 return(rc);
1415
1416         return(0);
1417 }
1418
1419 /*****************************************************************************/
1420
1421 /*
1422  *      Shutdown the hardware of a port.
1423  */
1424
1425 static int stli_shutdownclose(stliport_t *portp)
1426 {
1427         stlibrd_t       *brdp;
1428         struct tty      *tp;
1429         int             x;
1430
1431 #if DEBUG
1432         printf("stli_shutdownclose(portp=%p): brdnr=%d panelnr=%d portnr=%d\n",
1433                 (void *) portp, portp->brdnr, portp->panelnr, portp->portnr);
1434 #endif
1435
1436         if ((brdp = stli_brds[portp->brdnr]) == (stlibrd_t *) NULL)
1437                 return(ENXIO);
1438
1439         tp = &portp->tty;
1440         stli_rawclose(brdp, portp, 0, 0);
1441         stli_flush(portp, (FWRITE | FREAD));
1442         if (tp->t_cflag & HUPCL) {
1443                 x = spltty();
1444                 stli_mkasysigs(&portp->asig, 0, 0);
1445                 if (portp->state & ST_CMDING) {
1446                         portp->state |= ST_DOSIGS;
1447                 } else {
1448                         stli_sendcmd(brdp, portp, A_SETSIGNALS,
1449                                 &portp->asig, sizeof(asysigs_t), 0);
1450                 }
1451                 splx(x);
1452                 if (portp->dtrwait != 0) {
1453                         portp->state |= ST_DTRWAIT;
1454                         timeout(stli_dtrwakeup, portp, portp->dtrwait);
1455                 }
1456         }
1457         portp->callout = 0;
1458         portp->state &= ~ST_INITIALIZED;
1459         wakeup(&portp->callout);
1460         wakeup(TSA_CARR_ON(tp));
1461         return(0);
1462 }
1463
1464 /*****************************************************************************/
1465
1466 /*
1467  *      Clear the DTR waiting flag, and wake up any sleepers waiting for
1468  *      DTR wait period to finish.
1469  */
1470
1471 static void stli_dtrwakeup(void *arg)
1472 {
1473         stliport_t      *portp;
1474
1475         portp = (stliport_t *) arg;
1476         portp->state &= ~ST_DTRWAIT;
1477         wakeup(&portp->dtrwait);
1478 }
1479
1480 /*****************************************************************************/
1481
1482 /*
1483  *      Send an open message to the slave. This will sleep waiting for the
1484  *      acknowledgement, so must have user context. We need to co-ordinate
1485  *      with close events here, since we don't want open and close events
1486  *      to overlap.
1487  */
1488
1489 static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
1490 {
1491         volatile cdkhdr_t       *hdrp;
1492         volatile cdkctrl_t      *cp;
1493         volatile unsigned char  *bits;
1494         int                     rc, x;
1495
1496 #if DEBUG
1497         printf("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp,
1498                 (int) portp, (int) arg, wait);
1499 #endif
1500
1501         x = spltty();
1502
1503 /*
1504  *      Slave is already closing this port. This can happen if a hangup
1505  *      occurs on this port. So we must wait until it is complete. The
1506  *      order of opens and closes may not be preserved across shared
1507  *      memory, so we must wait until it is complete.
1508  */
1509         while (portp->state & ST_CLOSING) {
1510                 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1511                 if (rc) {
1512                         splx(x);
1513                         return(rc);
1514                 }
1515         }
1516
1517 /*
1518  *      Everything is ready now, so write the open message into shared
1519  *      memory. Once the message is in set the service bits to say that
1520  *      this port wants service.
1521  */
1522         EBRDENABLE(brdp);
1523         cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
1524         cp->openarg = arg;
1525         cp->open = 1;
1526         hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1527         bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
1528                 portp->portidx;
1529         *bits |= portp->portbit;
1530         EBRDDISABLE(brdp);
1531
1532         if (wait == 0) {
1533                 splx(x);
1534                 return(0);
1535         }
1536
1537 /*
1538  *      Slave is in action, so now we must wait for the open acknowledgment
1539  *      to come back.
1540  */
1541         rc = 0;
1542         portp->state |= ST_OPENING;
1543         while (portp->state & ST_OPENING) {
1544                 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1545                 if (rc) {
1546                         splx(x);
1547                         return(rc);
1548                 }
1549         }
1550         splx(x);
1551
1552         if ((rc == 0) && (portp->rc != 0))
1553                 rc = EIO;
1554         return(rc);
1555 }
1556
1557 /*****************************************************************************/
1558
1559 /*
1560  *      Send a close message to the slave. Normally this will sleep waiting
1561  *      for the acknowledgement, but if wait parameter is 0 it will not. If
1562  *      wait is true then must have user context (to sleep).
1563  */
1564
1565 static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
1566 {
1567         volatile cdkhdr_t       *hdrp;
1568         volatile cdkctrl_t      *cp;
1569         volatile unsigned char  *bits;
1570         int                     rc, x;
1571
1572 #if DEBUG
1573         printf("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp,
1574                 (int) portp, (int) arg, wait);
1575 #endif
1576
1577         x = spltty();
1578
1579 /*
1580  *      Slave is already closing this port. This can happen if a hangup
1581  *      occurs on this port.
1582  */
1583         if (wait) {
1584                 while (portp->state & ST_CLOSING) {
1585                         rc = tsleep(&portp->state, (TTIPRI | PCATCH),
1586                                 "stliraw", 0);
1587                         if (rc) {
1588                                 splx(x);
1589                                 return(rc);
1590                         }
1591                 }
1592         }
1593
1594 /*
1595  *      Write the close command into shared memory.
1596  */
1597         EBRDENABLE(brdp);
1598         cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
1599         cp->closearg = arg;
1600         cp->close = 1;
1601         hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1602         bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
1603                 portp->portidx;
1604         *bits |= portp->portbit;
1605         EBRDDISABLE(brdp);
1606
1607         portp->state |= ST_CLOSING;
1608         if (wait == 0) {
1609                 splx(x);
1610                 return(0);
1611         }
1612
1613 /*
1614  *      Slave is in action, so now we must wait for the open acknowledgment
1615  *      to come back.
1616  */
1617         rc = 0;
1618         while (portp->state & ST_CLOSING) {
1619                 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1620                 if (rc) {
1621                         splx(x);
1622                         return(rc);
1623                 }
1624         }
1625         splx(x);
1626
1627         if ((rc == 0) && (portp->rc != 0))
1628                 rc = EIO;
1629         return(rc);
1630 }
1631
1632 /*****************************************************************************/
1633
1634 /*
1635  *      Send a command to the slave and wait for the response. This must
1636  *      have user context (it sleeps). This routine is generic in that it
1637  *      can send any type of command. Its purpose is to wait for that command
1638  *      to complete (as opposed to initiating the command then returning).
1639  */
1640
1641 static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
1642 {
1643         int     rc, x;
1644
1645 #if DEBUG
1646         printf("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
1647                 "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
1648                 (int) arg, size, copyback);
1649 #endif
1650
1651         x = spltty();
1652         while (portp->state & ST_CMDING) {
1653                 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1654                 if (rc) {
1655                         splx(x);
1656                         return(rc);
1657                 }
1658         }
1659
1660         stli_sendcmd(brdp, portp, cmd, arg, size, copyback);
1661
1662         while (portp->state & ST_CMDING) {
1663                 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1664                 if (rc) {
1665                         splx(x);
1666                         return(rc);
1667                 }
1668         }
1669         splx(x);
1670
1671         if (portp->rc != 0)
1672                 return(EIO);
1673         return(0);
1674 }
1675
1676 /*****************************************************************************/
1677
1678 /*
1679  *      Start (or continue) the transfer of TX data on this port. If the
1680  *      port is not currently busy then load up the interrupt ring queue
1681  *      buffer and kick of the transmitter. If the port is running low on
1682  *      TX data then refill the ring queue. This routine is also used to
1683  *      activate input flow control!
1684  */
1685
1686 static void stli_start(struct tty *tp)
1687 {
1688         volatile cdkasy_t       *ap;
1689         volatile cdkhdr_t       *hdrp;
1690         volatile unsigned char  *bits;
1691         unsigned char           *shbuf;
1692         stliport_t              *portp;
1693         stlibrd_t               *brdp;
1694         unsigned int            len, stlen, head, tail, size;
1695         int                     count, x;
1696
1697         portp = (stliport_t *) tp;
1698
1699 #if DEBUG
1700         printf("stli_start(tp=%x): brdnr=%d portnr=%d\n", (int) tp, 
1701                 portp->brdnr, portp->portnr);
1702 #endif
1703
1704         x = spltty();
1705
1706 #if VFREEBSD == 205
1707 /*
1708  *      Check if the output cooked clist buffers are near empty, wake up
1709  *      the line discipline to fill it up.
1710  */
1711         if (tp->t_outq.c_cc <= tp->t_lowat) {
1712                 if (tp->t_state & TS_ASLEEP) {
1713                         tp->t_state &= ~TS_ASLEEP;
1714                         wakeup(&tp->t_outq);
1715                 }
1716                 selwakeup(&tp->t_wsel);
1717         }
1718 #endif
1719
1720         if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
1721                 splx(x);
1722                 return;
1723         }
1724
1725 /*
1726  *      Copy data from the clists into the interrupt ring queue. This will
1727  *      require at most 2 copys... What we do is calculate how many chars
1728  *      can fit into the ring queue, and how many can fit in 1 copy. If after
1729  *      the first copy there is still more room then do the second copy. 
1730  */
1731         if (tp->t_outq.c_cc != 0) {
1732                 brdp = stli_brds[portp->brdnr];
1733                 if (brdp == (stlibrd_t *) NULL) {
1734                         splx(x);
1735                         return;
1736                 }
1737
1738                 EBRDENABLE(brdp);
1739                 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
1740                 head = (unsigned int) ap->txq.head;
1741                 tail = (unsigned int) ap->txq.tail;
1742                 if (tail != ((unsigned int) ap->txq.tail))
1743                         tail = (unsigned int) ap->txq.tail;
1744                 size = portp->txsize;
1745                 if (head >= tail) {
1746                         len = size - (head - tail) - 1;
1747                         stlen = size - head;
1748                 } else {
1749                         len = tail - head - 1;
1750                         stlen = len;
1751                 }
1752
1753                 count = 0;
1754                 shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset);
1755
1756                 if (len > 0) {
1757                         stlen = MIN(len, stlen);
1758                         count = q_to_b(&tp->t_outq, (shbuf + head), stlen);
1759                         len -= count;
1760                         head += count;
1761                         if (head >= size) {
1762                                 head = 0;
1763                                 if (len > 0) {
1764                                         stlen = q_to_b(&tp->t_outq, shbuf, len);
1765                                         head += stlen;
1766                                         count += stlen;
1767                                 }
1768                         }
1769                 }
1770
1771                 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
1772                 ap->txq.head = head;
1773                 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1774                 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
1775                         portp->portidx;
1776                 *bits |= portp->portbit;
1777                 portp->state |= ST_TXBUSY;
1778                 tp->t_state |= TS_BUSY;
1779
1780                 EBRDDISABLE(brdp);
1781         }
1782
1783 #if VFREEBSD != 205
1784 /*
1785  *      Do any writer wakeups.
1786  */
1787         ttwwakeup(tp);
1788 #endif
1789
1790         splx(x);
1791 }
1792
1793 /*****************************************************************************/
1794
1795 /*
1796  *      Send a new port configuration to the slave.
1797  */
1798
1799 static int stli_param(struct tty *tp, struct termios *tiosp)
1800 {
1801         stlibrd_t       *brdp;
1802         stliport_t      *portp;
1803         asyport_t       aport;
1804         int             x, rc;
1805
1806         portp = (stliport_t *) tp;
1807         if ((brdp = stli_brds[portp->brdnr]) == (stlibrd_t *) NULL)
1808                 return(ENXIO);
1809
1810         x = spltty();
1811         stli_mkasyport(portp, &aport, tiosp);
1812         /* can we sleep here? */
1813         rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0);
1814         stli_ttyoptim(portp, tiosp);
1815         splx(x);
1816         return(rc);
1817 }
1818
1819 /*****************************************************************************/
1820
1821 /*
1822  *      Flush characters from the lower buffer. We may not have user context
1823  *      so we cannot sleep waiting for it to complete. Also we need to check
1824  *      if there is chars for this port in the TX cook buffer, and flush them
1825  *      as well.
1826  */
1827
1828 static void stli_flush(stliport_t *portp, int flag)
1829 {
1830         stlibrd_t       *brdp;
1831         unsigned long   ftype;
1832         int             x;
1833
1834 #if DEBUG
1835         printf("stli_flush(portp=%x,flag=%x)\n", (int) portp, flag);
1836 #endif
1837
1838         if (portp == (stliport_t *) NULL)
1839                 return;
1840         if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
1841                 return;
1842         brdp = stli_brds[portp->brdnr];
1843         if (brdp == (stlibrd_t *) NULL)
1844                 return;
1845
1846         x = spltty();
1847         if (portp->state & ST_CMDING) {
1848                 portp->state |= (flag & FWRITE) ? ST_DOFLUSHTX : 0;
1849                 portp->state |= (flag & FREAD) ? ST_DOFLUSHRX : 0;
1850         } else {
1851                 ftype = (flag & FWRITE) ? FLUSHTX : 0;
1852                 ftype |= (flag & FREAD) ? FLUSHRX : 0;
1853                 portp->state &= ~(ST_DOFLUSHTX | ST_DOFLUSHRX);
1854                 stli_sendcmd(brdp, portp, A_FLUSH, &ftype,
1855                         sizeof(unsigned long), 0);
1856         }
1857         if ((flag & FREAD) && (stli_rxtmpport == portp))
1858                 stli_rxtmplen = 0;
1859         splx(x);
1860 }
1861
1862 /*****************************************************************************/
1863
1864 /*
1865  *      Generic send command routine. This will send a message to the slave,
1866  *      of the specified type with the specified argument. Must be very
1867  *      carefull of data that will be copied out from shared memory -
1868  *      containing command results. The command completion is all done from
1869  *      a poll routine that does not have user coontext. Therefore you cannot
1870  *      copy back directly into user space, or to the kernel stack of a
1871  *      process. This routine does not sleep, so can be called from anywhere,
1872  *      and must be called with interrupt locks set.
1873  */
1874
1875 static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
1876 {
1877         volatile cdkhdr_t       *hdrp;
1878         volatile cdkctrl_t      *cp;
1879         volatile unsigned char  *bits;
1880
1881 #if DEBUG
1882         printf("stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
1883                 "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
1884                 (int) arg, size, copyback);
1885 #endif
1886
1887         if (portp->state & ST_CMDING) {
1888                 printf("STALLION: command already busy, cmd=%x!\n", (int) cmd);
1889                 return;
1890         }
1891
1892         EBRDENABLE(brdp);
1893         cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
1894         if (size > 0) {
1895                 bcopy(arg, (void *) &(cp->args[0]), size);
1896                 if (copyback) {
1897                         portp->argp = arg;
1898                         portp->argsize = size;
1899                 }
1900         }
1901         cp->status = 0;
1902         cp->cmd = cmd;
1903         hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1904         bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
1905                 portp->portidx;
1906         *bits |= portp->portbit;
1907         portp->state |= ST_CMDING;
1908         EBRDDISABLE(brdp);
1909 }
1910
1911 /*****************************************************************************/
1912
1913 /*
1914  *      Read data from shared memory. This assumes that the shared memory
1915  *      is enabled and that interrupts are off. Basically we just empty out
1916  *      the shared memory buffer into the tty buffer. Must be carefull to
1917  *      handle the case where we fill up the tty buffer, but still have
1918  *      more chars to unload.
1919  */
1920
1921 static void stli_rxprocess(stlibrd_t *brdp, stliport_t *portp)
1922 {
1923         volatile cdkasyrq_t     *rp;
1924         volatile char           *shbuf;
1925         struct tty              *tp;
1926         unsigned int            head, tail, size;
1927         unsigned int            len, stlen, i;
1928         int                     ch;
1929
1930 #if DEBUG
1931         printf("stli_rxprocess(brdp=%x,portp=%d)\n", (int) brdp, (int) portp);
1932 #endif
1933
1934         tp = &portp->tty;
1935         if ((tp->t_state & TS_ISOPEN) == 0) {
1936                 stli_flush(portp, FREAD);
1937                 return;
1938         }
1939         if (tp->t_state & TS_TBLOCK)
1940                 return;
1941
1942         rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
1943         head = (unsigned int) rp->head;
1944         if (head != ((unsigned int) rp->head))
1945                 head = (unsigned int) rp->head;
1946         tail = (unsigned int) rp->tail;
1947         size = portp->rxsize;
1948         if (head >= tail) {
1949                 len = head - tail;
1950                 stlen = len;
1951         } else {
1952                 len = size - (tail - head);
1953                 stlen = size - tail;
1954         }
1955
1956         if (len == 0)
1957                 return;
1958
1959         shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset);
1960
1961 /*
1962  *      If we can bypass normal LD processing then just copy direct
1963  *      from board shared memory into the tty buffers.
1964  */
1965         if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
1966                 if (((tp->t_rawq.c_cc + len) >= TTYHOG) &&
1967                     ((tp->t_cflag & CRTS_IFLOW) || (tp->t_iflag & IXOFF)) &&
1968                     ((tp->t_state & TS_TBLOCK) == 0)) {
1969                         ch = TTYHOG - tp->t_rawq.c_cc - 1;
1970                         len = (ch > 0) ? ch : 0;
1971                         stlen = MIN(stlen, len);
1972                         tp->t_state |= TS_TBLOCK;
1973                 }
1974                 i = b_to_q((char *) (shbuf + tail), stlen, &tp->t_rawq);
1975                 tail += stlen;
1976                 len -= stlen;
1977                 if (tail >= size) {
1978                         tail = 0;
1979                         i += b_to_q((char *) shbuf, len, &tp->t_rawq);
1980                         tail += len;
1981                 }
1982                 portp->rxlost += i;
1983                 ttwakeup(tp);
1984                 rp = &((volatile cdkasy_t *)
1985                         EBRDGETMEMPTR(brdp, portp->addr))->rxq;
1986                 rp->tail = tail;
1987
1988         } else {
1989 /*
1990  *              Copy the data from board shared memory into a local
1991  *              memory buffer. Then feed them from here into the LD.
1992  *              We don't want to go into board shared memory one char
1993  *              at a time, it is too slow...
1994  */
1995                 if (len > TTYHOG) {
1996                         len = TTYHOG - 1;
1997                         stlen = min(len, stlen);
1998                 }
1999                 stli_rxtmpport = portp;
2000                 stli_rxtmplen = len;
2001                 bcopy((char *) (shbuf + tail), &stli_rxtmpbuf[0], stlen);
2002                 len -= stlen;
2003                 if (len > 0)
2004                         bcopy((char *) shbuf, &stli_rxtmpbuf[stlen], len);
2005                 
2006                 for (i = 0; (i < stli_rxtmplen); i++) {
2007                         ch = (unsigned char) stli_rxtmpbuf[i];
2008                         (*linesw[tp->t_line].l_rint)(ch, tp);
2009                 }
2010                 EBRDENABLE(brdp);
2011                 rp = &((volatile cdkasy_t *)
2012                         EBRDGETMEMPTR(brdp, portp->addr))->rxq;
2013                 if (stli_rxtmplen == 0) {
2014                         head = (unsigned int) rp->head;
2015                         if (head != ((unsigned int) rp->head))
2016                                 head = (unsigned int) rp->head;
2017                         tail = head;
2018                 } else {
2019                         tail += i;
2020                         if (tail >= size)
2021                                 tail -= size;
2022                 }
2023                 rp->tail = tail;
2024                 stli_rxtmpport = (stliport_t *) NULL;
2025                 stli_rxtmplen = 0;
2026         }
2027
2028         portp->state |= ST_RXING;
2029 }
2030
2031 /*****************************************************************************/
2032
2033 /*
2034  *      Set up and carry out any delayed commands. There is only a small set
2035  *      of slave commands that can be done "off-level". So it is not too
2036  *      difficult to deal with them as a special case here.
2037  */
2038
2039 static __inline void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp)
2040 {
2041         int     cmd;
2042
2043         if (portp->state & ST_DOSIGS) {
2044                 if ((portp->state & ST_DOFLUSHTX) &&
2045                     (portp->state & ST_DOFLUSHRX))
2046                         cmd = A_SETSIGNALSF;
2047                 else if (portp->state & ST_DOFLUSHTX)
2048                         cmd = A_SETSIGNALSFTX;
2049                 else if (portp->state & ST_DOFLUSHRX)
2050                         cmd = A_SETSIGNALSFRX;
2051                 else
2052                         cmd = A_SETSIGNALS;
2053                 portp->state &= ~(ST_DOFLUSHTX | ST_DOFLUSHRX | ST_DOSIGS);
2054                 bcopy((void *) &portp->asig, (void *) &(cp->args[0]),
2055                         sizeof(asysigs_t));
2056                 cp->status = 0;
2057                 cp->cmd = cmd;
2058                 portp->state |= ST_CMDING;
2059         } else if ((portp->state & ST_DOFLUSHTX) ||
2060             (portp->state & ST_DOFLUSHRX)) {
2061                 cmd = ((portp->state & ST_DOFLUSHTX) ? FLUSHTX : 0);
2062                 cmd |= ((portp->state & ST_DOFLUSHRX) ? FLUSHRX : 0);
2063                 portp->state &= ~(ST_DOFLUSHTX | ST_DOFLUSHRX);
2064                 bcopy((void *) &cmd, (void *) &(cp->args[0]), sizeof(int));
2065                 cp->status = 0;
2066                 cp->cmd = A_FLUSH;
2067                 portp->state |= ST_CMDING;
2068         }
2069 }
2070
2071 /*****************************************************************************/
2072
2073 /*
2074  *      Host command service checking. This handles commands or messages
2075  *      coming from the slave to the host. Must have board shared memory
2076  *      enabled and interrupts off when called. Notice that by servicing the
2077  *      read data last we don't need to change the shared memory pointer
2078  *      during processing (which is a slow IO operation).
2079  *      Return value indicates if this port is still awaiting actions from
2080  *      the slave (like open, command, or even TX data being sent). If 0
2081  *      then port is still busy, otherwise the port request bit flag is
2082  *      returned.
2083  */
2084
2085 static __inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
2086 {
2087         volatile cdkasy_t       *ap;
2088         volatile cdkctrl_t      *cp;
2089         asynotify_t             nt;
2090         unsigned long           oldsigs;
2091         unsigned int            head, tail;
2092         int                     rc, donerx;
2093
2094 #if DEBUG
2095         printf("stli_hostcmd(brdp=%x,portp=%x)\n", (int) brdp, (int) portp);
2096 #endif
2097
2098         ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
2099         cp = &ap->ctrl;
2100
2101 /*
2102  *      Check if we are waiting for an open completion message.
2103  */
2104         if (portp->state & ST_OPENING) {
2105                 rc = (int) cp->openarg;
2106                 if ((cp->open == 0) && (rc != 0)) {
2107                         if (rc > 0)
2108                                 rc--;
2109                         cp->openarg = 0;
2110                         portp->rc = rc;
2111                         portp->state &= ~ST_OPENING;
2112                         wakeup(&portp->state);
2113                 }
2114         }
2115
2116 /*
2117  *      Check if we are waiting for a close completion message.
2118  */
2119         if (portp->state & ST_CLOSING) {
2120                 rc = (int) cp->closearg;
2121                 if ((cp->close == 0) && (rc != 0)) {
2122                         if (rc > 0)
2123                                 rc--;
2124                         cp->closearg = 0;
2125                         portp->rc = rc;
2126                         portp->state &= ~ST_CLOSING;
2127                         wakeup(&portp->state);
2128                 }
2129         }
2130
2131 /*
2132  *      Check if we are waiting for a command completion message. We may
2133  *      need to copy out the command results associated with this command.
2134  */
2135         if (portp->state & ST_CMDING) {
2136                 rc = cp->status;
2137                 if ((cp->cmd == 0) && (rc != 0)) {
2138                         if (rc > 0)
2139                                 rc--;
2140                         if (portp->argp != (void *) NULL) {
2141                                 bcopy((void *) &(cp->args[0]), portp->argp,
2142                                         portp->argsize);
2143                                 portp->argp = (void *) NULL;
2144                         }
2145                         cp->status = 0;
2146                         portp->rc = rc;
2147                         portp->state &= ~ST_CMDING;
2148                         stli_dodelaycmd(portp, cp);
2149                         wakeup(&portp->state);
2150                 }
2151         }
2152
2153 /*
2154  *      Check for any notification messages ready. This includes lots of
2155  *      different types of events - RX chars ready, RX break received,
2156  *      TX data low or empty in the slave, modem signals changed state.
2157  *      Must be extremely carefull if we call to the LD, it may call
2158  *      other routines of ours that will disable the memory...
2159  *      Something else we need to be carefull of is race conditions on
2160  *      marking the TX as empty...
2161  */
2162         donerx = 0;
2163
2164         if (ap->notify) {
2165                 struct tty      *tp;
2166
2167                 nt = ap->changed;
2168                 ap->notify = 0;
2169                 tp = &portp->tty;
2170
2171                 if (nt.signal & SG_DCD) {
2172                         oldsigs = portp->sigs;
2173                         portp->sigs = stli_mktiocm(nt.sigvalue);
2174                         portp->state &= ~ST_GETSIGS;
2175                         (*linesw[tp->t_line].l_modem)(tp,
2176                                 (portp->sigs & TIOCM_CD));
2177                         EBRDENABLE(brdp);
2178                 }
2179                 if (nt.data & DT_RXBUSY) {
2180                         donerx++;
2181                         stli_rxprocess(brdp, portp);
2182                 }
2183                 if (nt.data & DT_RXBREAK) {
2184                         (*linesw[tp->t_line].l_rint)(TTY_BI, tp);
2185                         EBRDENABLE(brdp);
2186                 }
2187                 if (nt.data & DT_TXEMPTY) {
2188                         ap = (volatile cdkasy_t *)
2189                                 EBRDGETMEMPTR(brdp, portp->addr);
2190                         head = (unsigned int) ap->txq.head;
2191                         tail = (unsigned int) ap->txq.tail;
2192                         if (tail != ((unsigned int) ap->txq.tail))
2193                                 tail = (unsigned int) ap->txq.tail;
2194                         head = (head >= tail) ? (head - tail) :
2195                                 portp->txsize - (tail - head);
2196                         if (head == 0) {
2197                                 portp->state &= ~ST_TXBUSY;
2198                                 tp->t_state &= ~TS_BUSY;
2199                         }
2200                 }
2201                 if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {
2202                         (*linesw[tp->t_line].l_start)(tp);
2203                         EBRDENABLE(brdp);
2204                 }
2205         }
2206
2207 /*
2208  *      It might seem odd that we are checking for more RX chars here.
2209  *      But, we need to handle the case where the tty buffer was previously
2210  *      filled, but we had more characters to pass up. The slave will not
2211  *      send any more RX notify messages until the RX buffer has been emptied.
2212  *      But it will leave the service bits on (since the buffer is not empty).
2213  *      So from here we can try to process more RX chars.
2214  */
2215         if ((!donerx) && (portp->state & ST_RXING)) {
2216                 portp->state &= ~ST_RXING;
2217                 stli_rxprocess(brdp, portp);
2218         }
2219
2220         return((portp->state & (ST_OPENING | ST_CLOSING | ST_CMDING |
2221                 ST_TXBUSY | ST_RXING)) ? 0 : 1);
2222 }
2223
2224 /*****************************************************************************/
2225
2226 /*
2227  *      Service all ports on a particular board. Assumes that the boards
2228  *      shared memory is enabled, and that the page pointer is pointed
2229  *      at the cdk header structure.
2230  */
2231
2232 static __inline void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)
2233 {
2234         stliport_t      *portp;
2235         unsigned char   hostbits[(STL_MAXCHANS / 8) + 1];
2236         unsigned char   slavebits[(STL_MAXCHANS / 8) + 1];
2237         unsigned char   *slavep;
2238         int             bitpos, bitat, bitsize;
2239         int             channr, nrdevs, slavebitchange;
2240
2241         bitsize = brdp->bitsize;
2242         nrdevs = brdp->nrdevs;
2243
2244 /*
2245  *      Check if slave wants any service. Basically we try to do as
2246  *      little work as possible here. There are 2 levels of service
2247  *      bits. So if there is nothing to do we bail early. We check
2248  *      8 service bits at a time in the inner loop, so we can bypass
2249  *      the lot if none of them want service.
2250  */
2251         bcopy((((unsigned char *) hdrp) + brdp->hostoffset), &hostbits[0],
2252                 bitsize);
2253
2254         bzero(&slavebits[0], bitsize);
2255         slavebitchange = 0;
2256
2257         for (bitpos = 0; (bitpos < bitsize); bitpos++) {
2258                 if (hostbits[bitpos] == 0)
2259                         continue;
2260                 channr = bitpos * 8;
2261                 bitat = 0x1;
2262                 for (; (channr < nrdevs); channr++, bitat <<=1) {
2263                         if (hostbits[bitpos] & bitat) {
2264                                 portp = brdp->ports[(channr - 1)];
2265                                 if (stli_hostcmd(brdp, portp)) {
2266                                         slavebitchange++;
2267                                         slavebits[bitpos] |= bitat;
2268                                 }
2269                         }
2270                 }
2271         }
2272
2273 /*
2274  *      If any of the ports are no longer busy then update them in the
2275  *      slave request bits. We need to do this after, since a host port
2276  *      service may initiate more slave requests...
2277  */
2278         if (slavebitchange) {
2279                 hdrp = (volatile cdkhdr_t *)
2280                         EBRDGETMEMPTR(brdp, CDK_CDKADDR);
2281                 slavep = ((unsigned char *) hdrp) + brdp->slaveoffset;
2282                 for (bitpos = 0; (bitpos < bitsize); bitpos++) {
2283                         if (slavebits[bitpos])
2284                                 slavep[bitpos] &= ~slavebits[bitpos];
2285                 }
2286         }
2287 }
2288
2289 /*****************************************************************************/
2290
2291 /*
2292  *      Driver poll routine. This routine polls the boards in use and passes
2293  *      messages back up to host when neccesary. This is actually very
2294  *      CPU efficient, since we will always have the kernel poll clock, it
2295  *      adds only a few cycles when idle (since board service can be
2296  *      determined very easily), but when loaded generates no interrupts
2297  *      (with their expensive associated context change).
2298  */
2299
2300 static void stli_poll(void *arg)
2301 {
2302         volatile cdkhdr_t       *hdrp;
2303         stlibrd_t               *brdp;
2304         int                     brdnr, x;
2305
2306         x = spltty();
2307
2308 /*
2309  *      Check each board and do any servicing required.
2310  */
2311         for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {
2312                 brdp = stli_brds[brdnr];
2313                 if (brdp == (stlibrd_t *) NULL)
2314                         continue;
2315                 if ((brdp->state & BST_STARTED) == 0)
2316                         continue;
2317
2318                 EBRDENABLE(brdp);
2319                 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
2320                 if (hdrp->hostreq)
2321                         stli_brdpoll(brdp, hdrp);
2322                 EBRDDISABLE(brdp);
2323         }
2324         splx(x);
2325
2326         timeout(stli_poll, 0, 1);
2327 }
2328
2329 /*****************************************************************************/
2330
2331 /*
2332  *      Translate the termios settings into the port setting structure of
2333  *      the slave.
2334  */
2335
2336 static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)
2337 {
2338 #if DEBUG
2339         printf("stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n", (int) portp,
2340                 (int) pp, (int) tiosp);
2341 #endif
2342
2343         bzero(pp, sizeof(asyport_t));
2344
2345 /*
2346  *      Start of by setting the baud, char size, parity and stop bit info.
2347  */
2348         if (tiosp->c_ispeed == 0)
2349                 tiosp->c_ispeed = tiosp->c_ospeed;
2350         if ((tiosp->c_ospeed < 0) || (tiosp->c_ospeed > STL_MAXBAUD))
2351                 tiosp->c_ospeed = STL_MAXBAUD;
2352         pp->baudout = tiosp->c_ospeed;
2353         pp->baudin = pp->baudout;
2354
2355         switch (tiosp->c_cflag & CSIZE) {
2356         case CS5:
2357                 pp->csize = 5;
2358                 break;
2359         case CS6:
2360                 pp->csize = 6;
2361                 break;
2362         case CS7:
2363                 pp->csize = 7;
2364                 break;
2365         default:
2366                 pp->csize = 8;
2367                 break;
2368         }
2369
2370         if (tiosp->c_cflag & CSTOPB)
2371                 pp->stopbs = PT_STOP2;
2372         else
2373                 pp->stopbs = PT_STOP1;
2374
2375         if (tiosp->c_cflag & PARENB) {
2376                 if (tiosp->c_cflag & PARODD)
2377                         pp->parity = PT_ODDPARITY;
2378                 else
2379                         pp->parity = PT_EVENPARITY;
2380         } else {
2381                 pp->parity = PT_NOPARITY;
2382         }
2383
2384         if (tiosp->c_iflag & ISTRIP)
2385                 pp->iflag |= FI_ISTRIP;
2386
2387 /*
2388  *      Set up any flow control options enabled.
2389  */
2390         if (tiosp->c_iflag & IXON) {
2391                 pp->flow |= F_IXON;
2392                 if (tiosp->c_iflag & IXANY)
2393                         pp->flow |= F_IXANY;
2394         }
2395         if (tiosp->c_iflag & IXOFF)
2396                 pp->flow |= F_IXOFF;
2397         if (tiosp->c_cflag & CCTS_OFLOW)
2398                 pp->flow |= F_CTSFLOW;
2399         if (tiosp->c_cflag & CRTS_IFLOW)
2400                 pp->flow |= F_RTSFLOW;
2401
2402         pp->startin = tiosp->c_cc[VSTART];
2403         pp->stopin = tiosp->c_cc[VSTOP];
2404         pp->startout = tiosp->c_cc[VSTART];
2405         pp->stopout = tiosp->c_cc[VSTOP];
2406
2407 /*
2408  *      Set up the RX char marking mask with those RX error types we must
2409  *      catch. We can get the slave to help us out a little here, it will
2410  *      ignore parity errors and breaks for us, and mark parity errors in
2411  *      the data stream.
2412  */
2413         if (tiosp->c_iflag & IGNPAR)
2414                 pp->iflag |= FI_IGNRXERRS;
2415         if (tiosp->c_iflag & IGNBRK)
2416                 pp->iflag |= FI_IGNBREAK;
2417         if (tiosp->c_iflag & (INPCK | PARMRK))
2418                 pp->iflag |= FI_1MARKRXERRS;
2419
2420 /*
2421  *      Transfer any persistent flags into the asyport structure.
2422  */
2423         pp->pflag = portp->pflag;
2424 }
2425
2426 /*****************************************************************************/
2427
2428 /*
2429  *      Construct a slave signals structure for setting the DTR and RTS
2430  *      signals as specified.
2431  */
2432
2433 static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts)
2434 {
2435 #if DEBUG
2436         printf("stli_mkasysigs(sp=%x,dtr=%d,rts=%d)\n", (int) sp, dtr, rts);
2437 #endif
2438
2439         bzero(sp, sizeof(asysigs_t));
2440         if (dtr >= 0) {
2441                 sp->signal |= SG_DTR;
2442                 sp->sigvalue |= ((dtr > 0) ? SG_DTR : 0);
2443         }
2444         if (rts >= 0) {
2445                 sp->signal |= SG_RTS;
2446                 sp->sigvalue |= ((rts > 0) ? SG_RTS : 0);
2447         }
2448 }
2449
2450 /*****************************************************************************/
2451
2452 /*
2453  *      Convert the signals returned from the slave into a local TIOCM type
2454  *      signals value. We keep them localy in TIOCM format.
2455  */
2456
2457 static long stli_mktiocm(unsigned long sigvalue)
2458 {
2459         long    tiocm;
2460
2461 #if DEBUG
2462         printf("stli_mktiocm(sigvalue=%x)\n", (int) sigvalue);
2463 #endif
2464
2465         tiocm = 0;
2466         tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0);
2467         tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0);
2468         tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0);
2469         tiocm |= ((sigvalue & SG_DSR) ? TIOCM_DSR : 0);
2470         tiocm |= ((sigvalue & SG_DTR) ? TIOCM_DTR : 0);
2471         tiocm |= ((sigvalue & SG_RTS) ? TIOCM_RTS : 0);
2472         return(tiocm);
2473 }
2474
2475 /*****************************************************************************/
2476
2477 /*
2478  *      Enable l_rint processing bypass mode if tty modes allow it.
2479  */
2480
2481 static void stli_ttyoptim(stliport_t *portp, struct termios *tiosp)
2482 {
2483         struct tty      *tp;
2484
2485         tp = &portp->tty;
2486         if (((tiosp->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR)) == 0) &&
2487             (((tiosp->c_iflag & BRKINT) == 0) || (tiosp->c_iflag & IGNBRK)) &&
2488             (((tiosp->c_iflag & PARMRK) == 0) ||
2489                 ((tiosp->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))) &&
2490             ((tiosp->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) ==0) &&
2491             (linesw[tp->t_line].l_rint == ttyinput))
2492                 tp->t_state |= TS_CAN_BYPASS_L_RINT;
2493         else
2494                 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
2495         portp->hotchar = linesw[tp->t_line].l_hotchar;
2496 }
2497
2498 /*****************************************************************************/
2499
2500 /*
2501  *      All panels and ports actually attached have been worked out. All
2502  *      we need to do here is set up the appropriate per port data structures.
2503  */
2504
2505 static int stli_initports(stlibrd_t *brdp)
2506 {
2507         stliport_t      *portp;
2508         int             i, panelnr, panelport;
2509
2510 #if DEBUG
2511         printf("stli_initports(brdp=%x)\n", (int) brdp);
2512 #endif
2513
2514         for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
2515                 portp = (stliport_t *) malloc(sizeof(stliport_t), M_TTYS,
2516                         M_NOWAIT | M_ZERO);
2517                 if (portp == (stliport_t *) NULL) {
2518                         printf("STALLION: failed to allocate port structure\n");
2519                         continue;
2520                 }
2521
2522                 portp->portnr = i;
2523                 portp->brdnr = brdp->brdnr;
2524                 portp->panelnr = panelnr;
2525                 portp->initintios.c_ispeed = STL_DEFSPEED;
2526                 portp->initintios.c_ospeed = STL_DEFSPEED;
2527                 portp->initintios.c_cflag = STL_DEFCFLAG;
2528                 portp->initintios.c_iflag = 0;
2529                 portp->initintios.c_oflag = 0;
2530                 portp->initintios.c_lflag = 0;
2531                 bcopy(&ttydefchars[0], &portp->initintios.c_cc[0],
2532                         sizeof(portp->initintios.c_cc));
2533                 portp->initouttios = portp->initintios;
2534                 portp->dtrwait = 3 * hz;
2535
2536                 panelport++;
2537                 if (panelport >= brdp->panels[panelnr]) {
2538                         panelport = 0;
2539                         panelnr++;
2540                 }
2541                 brdp->ports[i] = portp;
2542         }
2543
2544         return(0);
2545 }
2546
2547 /*****************************************************************************/
2548
2549 /*
2550  *      All the following routines are board specific hardware operations.
2551  */
2552
2553 static void stli_ecpinit(stlibrd_t *brdp)
2554 {
2555         unsigned long   memconf;
2556
2557 #if DEBUG
2558         printf("stli_ecpinit(brdp=%d)\n", (int) brdp);
2559 #endif
2560
2561         outb((brdp->iobase + ECP_ATCONFR), ECP_ATSTOP);
2562         DELAY(10);
2563         outb((brdp->iobase + ECP_ATCONFR), ECP_ATDISABLE);
2564         DELAY(100);
2565
2566         memconf = (brdp->paddr & ECP_ATADDRMASK) >> ECP_ATADDRSHFT;
2567         outb((brdp->iobase + ECP_ATMEMAR), memconf);
2568 }
2569
2570 /*****************************************************************************/
2571
2572 static void stli_ecpenable(stlibrd_t *brdp)
2573 {       
2574 #if DEBUG
2575         printf("stli_ecpenable(brdp=%x)\n", (int) brdp);
2576 #endif
2577         outb((brdp->iobase + ECP_ATCONFR), ECP_ATENABLE);
2578 }
2579
2580 /*****************************************************************************/
2581
2582 static void stli_ecpdisable(stlibrd_t *brdp)
2583 {       
2584 #if DEBUG
2585         printf("stli_ecpdisable(brdp=%x)\n", (int) brdp);
2586 #endif
2587         outb((brdp->iobase + ECP_ATCONFR), ECP_ATDISABLE);
2588 }
2589
2590 /*****************************************************************************/
2591
2592 static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2593 {       
2594         void            *ptr;
2595         unsigned char   val;
2596
2597 #if DEBUG
2598         printf("stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
2599                 (int) offset);
2600 #endif
2601
2602         if (offset > brdp->memsize) {
2603                 printf("STALLION: shared memory pointer=%x out of range at "
2604                         "line=%d(%d), brd=%d\n", (int) offset, line,
2605                         __LINE__, brdp->brdnr);
2606                 ptr = 0;
2607                 val = 0;
2608         } else {
2609                 ptr = (char *) brdp->vaddr + (offset % ECP_ATPAGESIZE);
2610                 val = (unsigned char) (offset / ECP_ATPAGESIZE);
2611         }
2612         outb((brdp->iobase + ECP_ATMEMPR), val);
2613         return(ptr);
2614 }
2615
2616 /*****************************************************************************/
2617
2618 static void stli_ecpreset(stlibrd_t *brdp)
2619 {       
2620 #if DEBUG
2621         printf("stli_ecpreset(brdp=%x)\n", (int) brdp);
2622 #endif
2623
2624         outb((brdp->iobase + ECP_ATCONFR), ECP_ATSTOP);
2625         DELAY(10);
2626         outb((brdp->iobase + ECP_ATCONFR), ECP_ATDISABLE);
2627         DELAY(500);
2628 }
2629
2630 /*****************************************************************************/
2631
2632 static void stli_ecpintr(stlibrd_t *brdp)
2633 {       
2634 #if DEBUG
2635         printf("stli_ecpintr(brdp=%x)\n", (int) brdp);
2636 #endif
2637         outb(brdp->iobase, 0x1);
2638 }
2639
2640 /*****************************************************************************/
2641
2642 /*
2643  *      The following set of functions act on ECP EISA boards.
2644  */
2645
2646 static void stli_ecpeiinit(stlibrd_t *brdp)
2647 {
2648         unsigned long   memconf;
2649
2650 #if DEBUG
2651         printf("stli_ecpeiinit(brdp=%x)\n", (int) brdp);
2652 #endif
2653
2654         outb((brdp->iobase + ECP_EIBRDENAB), 0x1);
2655         outb((brdp->iobase + ECP_EICONFR), ECP_EISTOP);
2656         DELAY(10);
2657         outb((brdp->iobase + ECP_EICONFR), ECP_EIDISABLE);
2658         DELAY(500);
2659
2660         memconf = (brdp->paddr & ECP_EIADDRMASKL) >> ECP_EIADDRSHFTL;
2661         outb((brdp->iobase + ECP_EIMEMARL), memconf);
2662         memconf = (brdp->paddr & ECP_EIADDRMASKH) >> ECP_EIADDRSHFTH;
2663         outb((brdp->iobase + ECP_EIMEMARH), memconf);
2664 }
2665
2666 /*****************************************************************************/
2667
2668 static void stli_ecpeienable(stlibrd_t *brdp)
2669 {       
2670         outb((brdp->iobase + ECP_EICONFR), ECP_EIENABLE);
2671 }
2672
2673 /*****************************************************************************/
2674
2675 static void stli_ecpeidisable(stlibrd_t *brdp)
2676 {       
2677         outb((brdp->iobase + ECP_EICONFR), ECP_EIDISABLE);
2678 }
2679
2680 /*****************************************************************************/
2681
2682 static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2683 {       
2684         void            *ptr;
2685         unsigned char   val;
2686
2687 #if DEBUG
2688         printf("stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n",
2689                 (int) brdp, (int) offset, line);
2690 #endif
2691
2692         if (offset > brdp->memsize) {
2693                 printf("STALLION: shared memory pointer=%x out of range at "
2694                         "line=%d(%d), brd=%d\n", (int) offset, line,
2695                         __LINE__, brdp->brdnr);
2696                 ptr = 0;
2697                 val = 0;
2698         } else {
2699                 ptr = (char *) brdp->vaddr + (offset % ECP_EIPAGESIZE);
2700                 if (offset < ECP_EIPAGESIZE)
2701                         val = ECP_EIENABLE;
2702                 else
2703                         val = ECP_EIENABLE | 0x40;
2704         }
2705         outb((brdp->iobase + ECP_EICONFR), val);
2706         return(ptr);
2707 }
2708
2709 /*****************************************************************************/
2710
2711 static void stli_ecpeireset(stlibrd_t *brdp)
2712 {       
2713         outb((brdp->iobase + ECP_EICONFR), ECP_EISTOP);
2714         DELAY(10);
2715         outb((brdp->iobase + ECP_EICONFR), ECP_EIDISABLE);
2716         DELAY(500);
2717 }
2718
2719 /*****************************************************************************/
2720
2721 /*
2722  *      The following set of functions act on ECP MCA boards.
2723  */
2724
2725 static void stli_ecpmcenable(stlibrd_t *brdp)
2726 {       
2727         outb((brdp->iobase + ECP_MCCONFR), ECP_MCENABLE);
2728 }
2729
2730 /*****************************************************************************/
2731
2732 static void stli_ecpmcdisable(stlibrd_t *brdp)
2733 {       
2734         outb((brdp->iobase + ECP_MCCONFR), ECP_MCDISABLE);
2735 }
2736
2737 /*****************************************************************************/
2738
2739 static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2740 {       
2741         void            *ptr;
2742         unsigned char   val;
2743
2744         if (offset > brdp->memsize) {
2745                 printf("STALLION: shared memory pointer=%x out of range at "
2746                         "line=%d(%d), brd=%d\n", (int) offset, line,
2747                         __LINE__, brdp->brdnr);
2748                 ptr = 0;
2749                 val = 0;
2750         } else {
2751                 ptr = (char *) brdp->vaddr + (offset % ECP_MCPAGESIZE);
2752                 val = ((unsigned char) (offset / ECP_MCPAGESIZE)) | ECP_MCENABLE;
2753         }
2754         outb((brdp->iobase + ECP_MCCONFR), val);
2755         return(ptr);
2756 }
2757
2758 /*****************************************************************************/
2759
2760 static void stli_ecpmcreset(stlibrd_t *brdp)
2761 {       
2762         outb((brdp->iobase + ECP_MCCONFR), ECP_MCSTOP);
2763         DELAY(10);
2764         outb((brdp->iobase + ECP_MCCONFR), ECP_MCDISABLE);
2765         DELAY(500);
2766 }
2767
2768 /*****************************************************************************/
2769
2770 /*
2771  *      The following routines act on ONboards.
2772  */
2773
2774 static void stli_onbinit(stlibrd_t *brdp)
2775 {
2776         unsigned long   memconf;
2777         int             i;
2778
2779 #if DEBUG
2780         printf("stli_onbinit(brdp=%d)\n", (int) brdp);
2781 #endif
2782
2783         outb((brdp->iobase + ONB_ATCONFR), ONB_ATSTOP);
2784         DELAY(10);
2785         outb((brdp->iobase + ONB_ATCONFR), ONB_ATDISABLE);
2786         for (i = 0; (i < 1000); i++)
2787                 DELAY(1000);
2788
2789         memconf = (brdp->paddr & ONB_ATADDRMASK) >> ONB_ATADDRSHFT;
2790         outb((brdp->iobase + ONB_ATMEMAR), memconf);
2791         outb(brdp->iobase, 0x1);
2792         DELAY(1000);
2793 }
2794
2795 /*****************************************************************************/
2796
2797 static void stli_onbenable(stlibrd_t *brdp)
2798 {       
2799 #if DEBUG
2800         printf("stli_onbenable(brdp=%x)\n", (int) brdp);
2801 #endif
2802         outb((brdp->iobase + ONB_ATCONFR), (ONB_ATENABLE | brdp->confbits));
2803 }
2804
2805 /*****************************************************************************/
2806
2807 static void stli_onbdisable(stlibrd_t *brdp)
2808 {       
2809 #if DEBUG
2810         printf("stli_onbdisable(brdp=%x)\n", (int) brdp);
2811 #endif
2812         outb((brdp->iobase + ONB_ATCONFR), (ONB_ATDISABLE | brdp->confbits));
2813 }
2814
2815 /*****************************************************************************/
2816
2817 static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2818 {       
2819         void    *ptr;
2820
2821 #if DEBUG
2822         printf("stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
2823                 (int) offset);
2824 #endif
2825
2826         if (offset > brdp->memsize) {
2827                 printf("STALLION: shared memory pointer=%x out of range at "
2828                         "line=%d(%d), brd=%d\n", (int) offset, line,
2829                         __LINE__, brdp->brdnr);
2830                 ptr = 0;
2831         } else {
2832                 ptr = (char *) brdp->vaddr + (offset % ONB_ATPAGESIZE);
2833         }
2834         return(ptr);
2835 }
2836
2837 /*****************************************************************************/
2838
2839 static void stli_onbreset(stlibrd_t *brdp)
2840 {       
2841         int     i;
2842
2843 #if DEBUG
2844         printf("stli_onbreset(brdp=%x)\n", (int) brdp);
2845 #endif
2846
2847         outb((brdp->iobase + ONB_ATCONFR), ONB_ATSTOP);
2848         DELAY(10);
2849         outb((brdp->iobase + ONB_ATCONFR), ONB_ATDISABLE);
2850         for (i = 0; (i < 1000); i++)
2851                 DELAY(1000);
2852 }
2853
2854 /*****************************************************************************/
2855
2856 /*
2857  *      The following routines act on ONboard EISA.
2858  */
2859
2860 static void stli_onbeinit(stlibrd_t *brdp)
2861 {
2862         unsigned long   memconf;
2863         int             i;
2864
2865 #if DEBUG
2866         printf("stli_onbeinit(brdp=%d)\n", (int) brdp);
2867 #endif
2868
2869         outb((brdp->iobase + ONB_EIBRDENAB), 0x1);
2870         outb((brdp->iobase + ONB_EICONFR), ONB_EISTOP);
2871         DELAY(10);
2872         outb((brdp->iobase + ONB_EICONFR), ONB_EIDISABLE);
2873         for (i = 0; (i < 1000); i++)
2874                 DELAY(1000);
2875
2876         memconf = (brdp->paddr & ONB_EIADDRMASKL) >> ONB_EIADDRSHFTL;
2877         outb((brdp->iobase + ONB_EIMEMARL), memconf);
2878         memconf = (brdp->paddr & ONB_EIADDRMASKH) >> ONB_EIADDRSHFTH;
2879         outb((brdp->iobase + ONB_EIMEMARH), memconf);
2880         outb(brdp->iobase, 0x1);
2881         DELAY(1000);
2882 }
2883
2884 /*****************************************************************************/
2885
2886 static void stli_onbeenable(stlibrd_t *brdp)
2887 {       
2888 #if DEBUG
2889         printf("stli_onbeenable(brdp=%x)\n", (int) brdp);
2890 #endif
2891         outb((brdp->iobase + ONB_EICONFR), ONB_EIENABLE);
2892 }
2893
2894 /*****************************************************************************/
2895
2896 static void stli_onbedisable(stlibrd_t *brdp)
2897 {       
2898 #if DEBUG
2899         printf("stli_onbedisable(brdp=%x)\n", (int) brdp);
2900 #endif
2901         outb((brdp->iobase + ONB_EICONFR), ONB_EIDISABLE);
2902 }
2903
2904 /*****************************************************************************/
2905
2906 static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2907 {       
2908         void            *ptr;
2909         unsigned char   val;
2910
2911 #if DEBUG
2912         printf("stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n", (int) brdp,
2913                 (int) offset, line);
2914 #endif
2915
2916         if (offset > brdp->memsize) {
2917                 printf("STALLION: shared memory pointer=%x out of range at "
2918                         "line=%d(%d), brd=%d\n", (int) offset, line,
2919                         __LINE__, brdp->brdnr);
2920                 ptr = 0;
2921                 val = 0;
2922         } else {
2923                 ptr = (char *) brdp->vaddr + (offset % ONB_EIPAGESIZE);
2924                 if (offset < ONB_EIPAGESIZE)
2925                         val = ONB_EIENABLE;
2926                 else
2927                         val = ONB_EIENABLE | 0x40;
2928         }
2929         outb((brdp->iobase + ONB_EICONFR), val);
2930         return(ptr);
2931 }
2932
2933 /*****************************************************************************/
2934
2935 static void stli_onbereset(stlibrd_t *brdp)
2936 {       
2937         int     i;
2938
2939 #if DEBUG
2940         printf("stli_onbereset(brdp=%x)\n", (int) brdp);
2941 #endif
2942
2943         outb((brdp->iobase + ONB_EICONFR), ONB_EISTOP);
2944         DELAY(10);
2945         outb((brdp->iobase + ONB_EICONFR), ONB_EIDISABLE);
2946         for (i = 0; (i < 1000); i++)
2947                 DELAY(1000);
2948 }
2949
2950 /*****************************************************************************/
2951
2952 /*
2953  *      The following routines act on Brumby boards.
2954  */
2955
2956 static void stli_bbyinit(stlibrd_t *brdp)
2957 {
2958         int     i;
2959
2960 #if DEBUG
2961         printf("stli_bbyinit(brdp=%d)\n", (int) brdp);
2962 #endif
2963
2964         outb((brdp->iobase + BBY_ATCONFR), BBY_ATSTOP);
2965         DELAY(10);
2966         outb((brdp->iobase + BBY_ATCONFR), 0);
2967         for (i = 0; (i < 1000); i++)
2968                 DELAY(1000);
2969         outb(brdp->iobase, 0x1);
2970         DELAY(1000);
2971 }
2972
2973 /*****************************************************************************/
2974
2975 static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2976 {       
2977         void            *ptr;
2978         unsigned char   val;
2979
2980 #if DEBUG
2981         printf("stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
2982                 (int) offset);
2983 #endif
2984
2985         if (offset > brdp->memsize) {
2986                 printf("STALLION: shared memory pointer=%x out of range at "
2987                         "line=%d(%d), brd=%d\n", (int) offset, line,
2988                         __LINE__, brdp->brdnr);
2989                 ptr = 0;
2990                 val = 0;
2991         } else {
2992                 ptr = (char *) brdp->vaddr + (offset % BBY_PAGESIZE);
2993                 val = (unsigned char) (offset / BBY_PAGESIZE);
2994         }
2995         outb((brdp->iobase + BBY_ATCONFR), val);
2996         return(ptr);
2997 }
2998
2999 /*****************************************************************************/
3000
3001 static void stli_bbyreset(stlibrd_t *brdp)
3002 {       
3003         int     i;
3004
3005 #if DEBUG
3006         printf("stli_bbyreset(brdp=%x)\n", (int) brdp);
3007 #endif
3008
3009         outb((brdp->iobase + BBY_ATCONFR), BBY_ATSTOP);
3010         DELAY(10);
3011         outb((brdp->iobase + BBY_ATCONFR), 0);
3012         for (i = 0; (i < 1000); i++)
3013                 DELAY(1000);
3014 }
3015
3016 /*****************************************************************************/
3017
3018 /*
3019  *      The following routines act on original old Stallion boards.
3020  */
3021
3022 static void stli_stalinit(stlibrd_t *brdp)
3023 {
3024         int     i;
3025
3026 #if DEBUG
3027         printf("stli_stalinit(brdp=%d)\n", (int) brdp);
3028 #endif
3029
3030         outb(brdp->iobase, 0x1);
3031         for (i = 0; (i < 1000); i++)
3032                 DELAY(1000);
3033 }
3034
3035 /*****************************************************************************/
3036
3037 static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
3038 {       
3039         void    *ptr;
3040
3041 #if DEBUG
3042         printf("stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
3043                 (int) offset);
3044 #endif
3045
3046         if (offset > brdp->memsize) {
3047                 printf("STALLION: shared memory pointer=%x out of range at "
3048                         "line=%d(%d), brd=%d\n", (int) offset, line,
3049                         __LINE__, brdp->brdnr);
3050                 ptr = 0;
3051         } else {
3052                 ptr = (char *) brdp->vaddr + (offset % STAL_PAGESIZE);
3053         }
3054         return(ptr);
3055 }
3056
3057 /*****************************************************************************/
3058
3059 static void stli_stalreset(stlibrd_t *brdp)
3060 {       
3061         volatile unsigned long  *vecp;
3062         int                     i;
3063
3064 #if DEBUG
3065         printf("stli_stalreset(brdp=%x)\n", (int) brdp);
3066 #endif
3067
3068         vecp = (volatile unsigned long *) ((char *) brdp->vaddr + 0x30);
3069         *vecp = 0xffff0000;
3070         outb(brdp->iobase, 0);
3071         for (i = 0; (i < 1000); i++)
3072                 DELAY(1000);
3073 }
3074
3075 /*****************************************************************************/
3076
3077 /*
3078  *      Try to find an ECP board and initialize it. This handles only ECP
3079  *      board types.
3080  */
3081
3082 static int stli_initecp(stlibrd_t *brdp)
3083 {
3084         cdkecpsig_t     sig;
3085         cdkecpsig_t     *sigsp;
3086         unsigned int    status, nxtid;
3087         int             panelnr;
3088
3089 #if DEBUG
3090         printf("stli_initecp(brdp=%x)\n", (int) brdp);
3091 #endif
3092
3093 /*
3094  *      Do a basic sanity check on the IO and memory addresses.
3095  */
3096         if ((brdp->iobase == 0) || (brdp->paddr == 0))
3097                 return(EINVAL);
3098
3099 /*
3100  *      Based on the specific board type setup the common vars to access
3101  *      and enable shared memory. Set all board specific information now
3102  *      as well.
3103  */
3104         switch (brdp->brdtype) {
3105         case BRD_ECP:
3106                 brdp->memsize = ECP_MEMSIZE;
3107                 brdp->pagesize = ECP_ATPAGESIZE;
3108                 brdp->init = stli_ecpinit;
3109                 brdp->enable = stli_ecpenable;
3110                 brdp->reenable = stli_ecpenable;
3111                 brdp->disable = stli_ecpdisable;
3112                 brdp->getmemptr = stli_ecpgetmemptr;
3113                 brdp->intr = stli_ecpintr;
3114                 brdp->reset = stli_ecpreset;
3115                 break;
3116
3117         case BRD_ECPE:
3118                 brdp->memsize = ECP_MEMSIZE;
3119                 brdp->pagesize = ECP_EIPAGESIZE;
3120                 brdp->init = stli_ecpeiinit;
3121                 brdp->enable = stli_ecpeienable;
3122                 brdp->reenable = stli_ecpeienable;
3123                 brdp->disable = stli_ecpeidisable;
3124                 brdp->getmemptr = stli_ecpeigetmemptr;
3125                 brdp->intr = stli_ecpintr;
3126                 brdp->reset = stli_ecpeireset;
3127                 break;
3128
3129         case BRD_ECPMC:
3130                 brdp->memsize = ECP_MEMSIZE;
3131                 brdp->pagesize = ECP_MCPAGESIZE;
3132                 brdp->init = NULL;
3133                 brdp->enable = stli_ecpmcenable;
3134                 brdp->reenable = stli_ecpmcenable;
3135                 brdp->disable = stli_ecpmcdisable;
3136                 brdp->getmemptr = stli_ecpmcgetmemptr;
3137                 brdp->intr = stli_ecpintr;
3138                 brdp->reset = stli_ecpmcreset;
3139                 break;
3140
3141         default:
3142                 return(EINVAL);
3143         }
3144
3145 /*
3146  *      The per-board operations structure is all setup, so now lets go
3147  *      and get the board operational. Firstly initialize board configuration
3148  *      registers.
3149  */
3150         EBRDINIT(brdp);
3151
3152 /*
3153  *      Now that all specific code is set up, enable the shared memory and
3154  *      look for the a signature area that will tell us exactly what board
3155  *      this is, and what it is connected to it.
3156  */
3157         EBRDENABLE(brdp);
3158         sigsp = (cdkecpsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
3159         bcopy(sigsp, &sig, sizeof(cdkecpsig_t));
3160         EBRDDISABLE(brdp);
3161
3162 #if 0
3163         printf("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",
3164                 __file__, __LINE__, (int) sig.magic, sig.romver,
3165                 sig.panelid[0], (int) sig.panelid[1], (int) sig.panelid[2],
3166                 (int) sig.panelid[3], (int) sig.panelid[4],
3167                 (int) sig.panelid[5], (int) sig.panelid[6],
3168                 (int) sig.panelid[7]);
3169 #endif
3170
3171         if (sig.magic != ECP_MAGIC)
3172                 return(ENXIO);
3173
3174 /*
3175  *      Scan through the signature looking at the panels connected to the
3176  *      board. Calculate the total number of ports as we go.
3177  */
3178         for (panelnr = 0, nxtid = 0; (panelnr < STL_MAXPANELS); panelnr++) {
3179                 status = sig.panelid[nxtid];
3180                 if ((status & ECH_PNLIDMASK) != nxtid)
3181                         break;
3182                 brdp->panelids[panelnr] = status;
3183                 if (status & ECH_PNL16PORT) {
3184                         brdp->panels[panelnr] = 16;
3185                         brdp->nrports += 16;
3186                         nxtid += 2;
3187                 } else {
3188                         brdp->panels[panelnr] = 8;
3189                         brdp->nrports += 8;
3190                         nxtid++;
3191                 }
3192                 brdp->nrpanels++;
3193         }
3194
3195         brdp->state |= BST_FOUND;
3196         return(0);
3197 }
3198
3199 /*****************************************************************************/
3200
3201 /*
3202  *      Try to find an ONboard, Brumby or Stallion board and initialize it.
3203  *      This handles only these board types.
3204  */
3205
3206 static int stli_initonb(stlibrd_t *brdp)
3207 {
3208         cdkonbsig_t     sig;
3209         cdkonbsig_t     *sigsp;
3210         int             i;
3211
3212 #if DEBUG
3213         printf("stli_initonb(brdp=%x)\n", (int) brdp);
3214 #endif
3215
3216 /*
3217  *      Do a basic sanity check on the IO and memory addresses.
3218  */
3219         if ((brdp->iobase == 0) || (brdp->paddr == 0))
3220                 return(EINVAL);
3221
3222 /*
3223  *      Based on the specific board type setup the common vars to access
3224  *      and enable shared memory. Set all board specific information now
3225  *      as well.
3226  */
3227         switch (brdp->brdtype) {
3228         case BRD_ONBOARD:
3229         case BRD_ONBOARD32:
3230         case BRD_ONBOARD2:
3231         case BRD_ONBOARD2_32:
3232         case BRD_ONBOARDRS:
3233                 brdp->memsize = ONB_MEMSIZE;
3234                 brdp->pagesize = ONB_ATPAGESIZE;
3235                 brdp->init = stli_onbinit;
3236                 brdp->enable = stli_onbenable;
3237                 brdp->reenable = stli_onbenable;
3238                 brdp->disable = stli_onbdisable;
3239                 brdp->getmemptr = stli_onbgetmemptr;
3240                 brdp->intr = stli_ecpintr;
3241                 brdp->reset = stli_onbreset;
3242                 brdp->confbits = (brdp->paddr > 0x100000) ? ONB_HIMEMENAB : 0;
3243                 break;
3244
3245         case BRD_ONBOARDE:
3246                 brdp->memsize = ONB_EIMEMSIZE;
3247                 brdp->pagesize = ONB_EIPAGESIZE;
3248                 brdp->init = stli_onbeinit;
3249                 brdp->enable = stli_onbeenable;
3250                 brdp->reenable = stli_onbeenable;
3251                 brdp->disable = stli_onbedisable;
3252                 brdp->getmemptr = stli_onbegetmemptr;
3253                 brdp->intr = stli_ecpintr;
3254                 brdp->reset = stli_onbereset;
3255                 break;
3256
3257         case BRD_BRUMBY4:
3258         case BRD_BRUMBY8:
3259         case BRD_BRUMBY16:
3260                 brdp->memsize = BBY_MEMSIZE;
3261                 brdp->pagesize = BBY_PAGESIZE;
3262                 brdp->init = stli_bbyinit;
3263                 brdp->enable = NULL;
3264                 brdp->reenable = NULL;
3265                 brdp->disable = NULL;
3266                 brdp->getmemptr = stli_bbygetmemptr;
3267                 brdp->intr = stli_ecpintr;
3268                 brdp->reset = stli_bbyreset;
3269                 break;
3270
3271         case BRD_STALLION:
3272                 brdp->memsize = STAL_MEMSIZE;
3273                 brdp->pagesize = STAL_PAGESIZE;
3274                 brdp->init = stli_stalinit;
3275                 brdp->enable = NULL;
3276                 brdp->reenable = NULL;
3277                 brdp->disable = NULL;
3278                 brdp->getmemptr = stli_stalgetmemptr;
3279                 brdp->intr = stli_ecpintr;
3280                 brdp->reset = stli_stalreset;
3281                 break;
3282
3283         default:
3284                 return(EINVAL);
3285         }
3286
3287 /*
3288  *      The per-board operations structure is all setup, so now lets go
3289  *      and get the board operational. Firstly initialize board configuration
3290  *      registers.
3291  */
3292         EBRDINIT(brdp);
3293
3294 /*
3295  *      Now that all specific code is set up, enable the shared memory and
3296  *      look for the a signature area that will tell us exactly what board
3297  *      this is, and how many ports.
3298  */
3299         EBRDENABLE(brdp);
3300         sigsp = (cdkonbsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
3301         bcopy(sigsp, &sig, sizeof(cdkonbsig_t));
3302         EBRDDISABLE(brdp);
3303
3304 #if 0
3305         printf("%s(%d): sig-> magic=%x:%x:%x:%x romver=%x amask=%x:%x:%x\n",
3306                 __file__, __LINE__, sig.magic0, sig.magic1, sig.magic2,
3307                 sig.magic3, sig.romver, sig.amask0, sig.amask1, sig.amask2);
3308 #endif
3309
3310         if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) ||
3311             (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))
3312                 return(ENXIO);
3313
3314 /*
3315  *      Scan through the signature alive mask and calculate how many ports
3316  *      there are on this board.
3317  */
3318         brdp->nrpanels = 1;
3319         if (sig.amask1) {
3320                 brdp->nrports = 32;
3321         } else {
3322                 for (i = 0; (i < 16); i++) {
3323                         if (((sig.amask0 << i) & 0x8000) == 0)
3324                                 break;
3325                 }
3326                 brdp->nrports = i;
3327         }
3328         brdp->panels[0] = brdp->nrports;
3329
3330         brdp->state |= BST_FOUND;
3331         return(0);
3332 }
3333
3334 /*****************************************************************************/
3335
3336 /*
3337  *      Start up a running board. This routine is only called after the
3338  *      code has been down loaded to the board and is operational. It will
3339  *      read in the memory map, and get the show on the road...
3340  */
3341
3342 static int stli_startbrd(stlibrd_t *brdp)
3343 {
3344         volatile cdkhdr_t       *hdrp;
3345         volatile cdkmem_t       *memp;
3346         volatile cdkasy_t       *ap;
3347         stliport_t              *portp;
3348         int                     portnr, nrdevs, i, rc, x;
3349
3350 #if DEBUG
3351         printf("stli_startbrd(brdp=%x)\n", (int) brdp);
3352 #endif
3353
3354         rc = 0;
3355
3356         x = spltty();
3357         EBRDENABLE(brdp);
3358         hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
3359         nrdevs = hdrp->nrdevs;
3360
3361 #if 0
3362         printf("%s(%d): CDK version %d.%d.%d --> nrdevs=%d memp=%x hostp=%x "
3363                 "slavep=%x\n", __file__, __LINE__, hdrp->ver_release,
3364                 hdrp->ver_modification, hdrp->ver_fix, nrdevs,
3365                 (int) hdrp->memp, (int) hdrp->hostp, (int) hdrp->slavep);
3366 #endif
3367
3368         if (nrdevs < (brdp->nrports + 1)) {
3369                 printf("STALLION: slave failed to allocate memory for all "
3370                         "devices, devices=%d\n", nrdevs);
3371                 brdp->nrports = nrdevs - 1;
3372         }
3373         brdp->nrdevs = nrdevs;
3374         brdp->hostoffset = hdrp->hostp - CDK_CDKADDR;
3375         brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR;
3376         brdp->bitsize = (nrdevs + 7) / 8;
3377         memp = (volatile cdkmem_t *) (void *) (uintptr_t) hdrp->memp;
3378         if (((uintptr_t) (void *) memp) > brdp->memsize) {
3379                 printf("STALLION: corrupted shared memory region?\n");
3380                 rc = EIO;
3381                 goto stli_donestartup;
3382         }
3383         memp = (volatile cdkmem_t *) EBRDGETMEMPTR(brdp,
3384                                                    (uintptr_t) (void *) memp);
3385         if (memp->dtype != TYP_ASYNCTRL) {
3386                 printf("STALLION: no slave control device found\n");
3387                 rc = EIO;
3388                 goto stli_donestartup;
3389         }
3390         memp++;
3391
3392 /*
3393  *      Cycle through memory allocation of each port. We are guaranteed to
3394  *      have all ports inside the first page of slave window, so no need to
3395  *      change pages while reading memory map.
3396  */
3397         for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) {
3398                 if (memp->dtype != TYP_ASYNC)
3399                         break;
3400                 portp = brdp->ports[portnr];
3401                 if (portp == (stliport_t *) NULL)
3402                         break;
3403                 portp->devnr = i;
3404                 portp->addr = memp->offset;
3405                 portp->reqidx = (unsigned char) (i * 8 / nrdevs);
3406                 portp->reqbit = (unsigned char) (0x1 << portp->reqidx);
3407                 portp->portidx = (unsigned char) (i / 8);
3408                 portp->portbit = (unsigned char) (0x1 << (i % 8));
3409         }
3410
3411         hdrp->slavereq = 0xff;
3412
3413 /*
3414  *      For each port setup a local copy of the RX and TX buffer offsets
3415  *      and sizes. We do this separate from the above, because we need to
3416  *      move the shared memory page...
3417  */
3418         for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) {
3419                 portp = brdp->ports[portnr];
3420                 if (portp == (stliport_t *) NULL)
3421                         break;
3422                 if (portp->addr == 0)
3423                         break;
3424                 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
3425                 if (ap != (volatile cdkasy_t *) NULL) {
3426                         portp->rxsize = ap->rxq.size;
3427                         portp->txsize = ap->txq.size;
3428                         portp->rxoffset = ap->rxq.offset;
3429                         portp->txoffset = ap->txq.offset;
3430                 }
3431         }
3432
3433 stli_donestartup:
3434         EBRDDISABLE(brdp);
3435         splx(x);
3436
3437         if (rc == 0)
3438                 brdp->state |= BST_STARTED;
3439
3440         if (stli_doingtimeout == 0) {
3441                 timeout(stli_poll, 0, 1);
3442                 stli_doingtimeout++;
3443         }
3444
3445         return(rc);
3446 }
3447
3448 /*****************************************************************************/
3449
3450 /*
3451  *      Probe and initialize the specified board.
3452  */
3453
3454 static int stli_brdinit(stlibrd_t *brdp)
3455 {
3456 #if DEBUG
3457         printf("stli_brdinit(brdp=%x)\n", (int) brdp);
3458 #endif
3459
3460         stli_brds[brdp->brdnr] = brdp;
3461
3462         switch (brdp->brdtype) {
3463         case BRD_ECP:
3464         case BRD_ECPE:
3465         case BRD_ECPMC:
3466                 stli_initecp(brdp);
3467                 break;
3468         case BRD_ONBOARD:
3469         case BRD_ONBOARDE:
3470         case BRD_ONBOARD2:
3471         case BRD_ONBOARD32:
3472         case BRD_ONBOARD2_32:
3473         case BRD_ONBOARDRS:
3474         case BRD_BRUMBY4:
3475         case BRD_BRUMBY8:
3476         case BRD_BRUMBY16:
3477         case BRD_STALLION:
3478                 stli_initonb(brdp);
3479                 break;
3480         case BRD_EASYIO:
3481         case BRD_ECH:
3482         case BRD_ECHMC:
3483         case BRD_ECHPCI:
3484                 printf("STALLION: %s board type not supported in this driver\n",
3485                         stli_brdnames[brdp->brdtype]);
3486                 return(ENODEV);
3487         default:
3488                 printf("STALLION: unit=%d is unknown board type=%d\n",
3489                         brdp->brdnr, brdp->brdtype);
3490                 return(ENODEV);
3491         }
3492         return(0);
3493 }
3494
3495 /*****************************************************************************/
3496
3497 /*
3498  *      Finish off the remaining initialization for a board.
3499  */
3500
3501 static int stli_brdattach(stlibrd_t *brdp)
3502 {
3503 #if DEBUG
3504         printf("stli_brdattach(brdp=%x)\n", (int) brdp);
3505 #endif
3506
3507 #if 0
3508         if ((brdp->state & BST_FOUND) == 0) {
3509                 printf("STALLION: %s board not found, unit=%d io=%x mem=%x\n",
3510                         stli_brdnames[brdp->brdtype], brdp->brdnr,
3511                         brdp->iobase, (int) brdp->paddr);
3512                 return(ENXIO);
3513         }
3514 #endif
3515
3516         stli_initports(brdp);
3517         printf("stli%d: %s (driver version %s), unit=%d nrpanels=%d "
3518                 "nrports=%d\n", brdp->unitid, stli_brdnames[brdp->brdtype],
3519                 stli_drvversion, brdp->brdnr, brdp->nrpanels, brdp->nrports);
3520         return(0);
3521 }
3522
3523 /*****************************************************************************/
3524
3525 /*
3526  *      Check for possible shared memory sharing between boards.
3527  *      FIX: need to start this optimization somewhere...
3528  */
3529
3530 #ifdef notdef
3531 static int stli_chksharemem()
3532 {
3533         stlibrd_t       *brdp, *nxtbrdp;
3534         int             i, j;
3535
3536 #if DEBUG
3537         printf("stli_chksharemem()\n");
3538 #endif
3539
3540 /*
3541  *      All found boards are initialized. Now for a little optimization, if
3542  *      no boards are sharing the "shared memory" regions then we can just
3543  *      leave them all enabled. This is in fact the usual case.
3544  */
3545         stli_shared = 0;
3546         if (stli_nrbrds > 1) {
3547                 for (i = 0; (i < stli_nrbrds); i++) {
3548                         brdp = stli_brds[i];
3549                         if (brdp == (stlibrd_t *) NULL)
3550                                 continue;
3551                         for (j = i + 1; (j < stli_nrbrds); j++) {
3552                                 nxtbrdp = stli_brds[j];
3553                                 if (nxtbrdp == (stlibrd_t *) NULL)
3554                                         continue;
3555                                 if ((brdp->paddr >= nxtbrdp->paddr) &&
3556                                     (brdp->paddr <= (nxtbrdp->paddr +
3557                                     nxtbrdp->memsize - 1))) {
3558                                         stli_shared++;
3559                                         break;
3560                                 }
3561                         }
3562                 }
3563         }
3564
3565         if (stli_shared == 0) {
3566                 for (i = 0; (i < stli_nrbrds); i++) {
3567                         brdp = stli_brds[i];
3568                         if (brdp == (stlibrd_t *) NULL)
3569                                 continue;
3570                         if (brdp->state & BST_FOUND) {
3571                                 EBRDENABLE(brdp);
3572                                 brdp->enable = NULL;
3573                                 brdp->disable = NULL;
3574                         }
3575                 }
3576         }
3577
3578         return(0);
3579 }
3580 #endif /* notdef */
3581
3582 /*****************************************************************************/
3583
3584 /*
3585  *      Return the board stats structure to user app.
3586  */
3587
3588 static int stli_getbrdstats(caddr_t data)
3589 {
3590         stlibrd_t       *brdp;
3591         int             i;
3592
3593 #if DEBUG
3594         printf("stli_getbrdstats(data=%p)\n", (void *) data);
3595 #endif
3596
3597         stli_brdstats = *((combrd_t *) data);
3598         if (stli_brdstats.brd >= STL_MAXBRDS)
3599                 return(-ENODEV);
3600         brdp = stli_brds[stli_brdstats.brd];
3601         if (brdp == (stlibrd_t *) NULL)
3602                 return(-ENODEV);
3603
3604         bzero(&stli_brdstats, sizeof(combrd_t));
3605         stli_brdstats.brd = brdp->brdnr;
3606         stli_brdstats.type = brdp->brdtype;
3607         stli_brdstats.hwid = 0;
3608         stli_brdstats.state = brdp->state;
3609         stli_brdstats.ioaddr = brdp->iobase;
3610         stli_brdstats.memaddr = brdp->paddr;
3611         stli_brdstats.nrpanels = brdp->nrpanels;
3612         stli_brdstats.nrports = brdp->nrports;
3613         for (i = 0; (i < brdp->nrpanels); i++) {
3614                 stli_brdstats.panels[i].panel = i;
3615                 stli_brdstats.panels[i].hwid = brdp->panelids[i];
3616                 stli_brdstats.panels[i].nrports = brdp->panels[i];
3617         }
3618
3619         *((combrd_t *) data) = stli_brdstats;
3620         return(0);
3621 }
3622
3623 /*****************************************************************************/
3624
3625 /*
3626  *      Resolve the referenced port number into a port struct pointer.
3627  */
3628
3629 static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)
3630 {
3631         stlibrd_t       *brdp;
3632         int             i;
3633
3634         if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
3635                 return((stliport_t *) NULL);
3636         brdp = stli_brds[brdnr];
3637         if (brdp == (stlibrd_t *) NULL)
3638                 return((stliport_t *) NULL);
3639         for (i = 0; (i < panelnr); i++)
3640                 portnr += brdp->panels[i];
3641         if ((portnr < 0) || (portnr >= brdp->nrports))
3642                 return((stliport_t *) NULL);
3643         return(brdp->ports[portnr]);
3644 }
3645
3646 /*****************************************************************************/
3647
3648 /*
3649  *      Return the port stats structure to user app. A NULL port struct
3650  *      pointer passed in means that we need to find out from the app
3651  *      what port to get stats for (used through board control device).
3652  */
3653
3654 static int stli_getportstats(stliport_t *portp, caddr_t data)
3655 {
3656         stlibrd_t       *brdp;
3657         int             rc;
3658
3659         if (portp == (stliport_t *) NULL) {
3660                 stli_comstats = *((comstats_t *) data);
3661                 portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
3662                         stli_comstats.port);
3663                 if (portp == (stliport_t *) NULL)
3664                         return(-ENODEV);
3665         }
3666
3667         brdp = stli_brds[portp->brdnr];
3668         if (brdp == (stlibrd_t *) NULL)
3669                 return(-ENODEV);
3670
3671         if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, &stli_cdkstats,
3672                         sizeof(asystats_t), 1)) < 0)
3673                 return(rc);
3674
3675         stli_comstats.brd = portp->brdnr;
3676         stli_comstats.panel = portp->panelnr;
3677         stli_comstats.port = portp->portnr;
3678         stli_comstats.state = portp->state;
3679         /*stli_comstats.flags = portp->flags;*/
3680         stli_comstats.ttystate = portp->tty.t_state;
3681         stli_comstats.cflags = portp->tty.t_cflag;
3682         stli_comstats.iflags = portp->tty.t_iflag;
3683         stli_comstats.oflags = portp->tty.t_oflag;
3684         stli_comstats.lflags = portp->tty.t_lflag;
3685
3686         stli_comstats.txtotal = stli_cdkstats.txchars;
3687         stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover;
3688         stli_comstats.txbuffered = stli_cdkstats.txringq;
3689         stli_comstats.rxbuffered = stli_cdkstats.rxringq;
3690         stli_comstats.rxoverrun = stli_cdkstats.overruns;
3691         stli_comstats.rxparity = stli_cdkstats.parity;
3692         stli_comstats.rxframing = stli_cdkstats.framing;
3693         stli_comstats.rxlost = stli_cdkstats.ringover + portp->rxlost;
3694         stli_comstats.rxbreaks = stli_cdkstats.rxbreaks;
3695         stli_comstats.txbreaks = stli_cdkstats.txbreaks;
3696         stli_comstats.txxon = stli_cdkstats.txstart;
3697         stli_comstats.txxoff = stli_cdkstats.txstop;
3698         stli_comstats.rxxon = stli_cdkstats.rxstart;
3699         stli_comstats.rxxoff = stli_cdkstats.rxstop;
3700         stli_comstats.rxrtsoff = stli_cdkstats.rtscnt / 2;
3701         stli_comstats.rxrtson = stli_cdkstats.rtscnt - stli_comstats.rxrtsoff;
3702         stli_comstats.modem = stli_cdkstats.dcdcnt;
3703         stli_comstats.hwid = stli_cdkstats.hwid;
3704         stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);
3705
3706         *((comstats_t *) data) = stli_comstats;;
3707         return(0);
3708 }
3709
3710 /*****************************************************************************/
3711
3712 /*
3713  *      Clear the port stats structure. We also return it zeroed out...
3714  */
3715
3716 static int stli_clrportstats(stliport_t *portp, caddr_t data)
3717 {
3718         stlibrd_t       *brdp;
3719         int             rc;
3720
3721         if (portp == (stliport_t *) NULL) {
3722                 stli_comstats = *((comstats_t *) data);
3723                 portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
3724                         stli_comstats.port);
3725                 if (portp == (stliport_t *) NULL)
3726                         return(-ENODEV);
3727         }
3728
3729         brdp = stli_brds[portp->brdnr];
3730         if (brdp == (stlibrd_t *) NULL)
3731                 return(-ENODEV);
3732
3733         if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, 0, 0, 0)) < 0)
3734                 return(rc);
3735
3736         portp->rxlost = 0;
3737         bzero(&stli_comstats, sizeof(comstats_t));
3738         stli_comstats.brd = portp->brdnr;
3739         stli_comstats.panel = portp->panelnr;
3740         stli_comstats.port = portp->portnr;
3741
3742         *((comstats_t *) data) = stli_comstats;;
3743         return(0);
3744 }
3745
3746 /*****************************************************************************/
3747
3748 /*
3749  *      Code to handle an "staliomem" read and write operations. This device
3750  *      is the contents of the board shared memory. It is used for down
3751  *      loading the slave image (and debugging :-)
3752  */
3753
3754 STATIC int stli_memrw(dev_t dev, struct uio *uiop, int flag)
3755 {
3756         stlibrd_t       *brdp;
3757         void            *memptr;
3758         int             brdnr, size, n, error, x;
3759
3760 #if DEBUG
3761         printf("stli_memrw(dev=%x,uiop=%x,flag=%x)\n", (int) dev,
3762                 (int) uiop, flag);
3763 #endif
3764
3765         brdnr = minor(dev) & 0x7;
3766         brdp = stli_brds[brdnr];
3767         if (brdp == (stlibrd_t *) NULL)
3768                 return(ENODEV);
3769         if (brdp->state == 0)
3770                 return(ENODEV);
3771
3772         if (uiop->uio_offset >= brdp->memsize)
3773                 return(0);
3774
3775         error = 0;
3776         size = brdp->memsize - uiop->uio_offset;
3777
3778         x = spltty();
3779         EBRDENABLE(brdp);
3780         while (size > 0) {
3781                 memptr = (void *) EBRDGETMEMPTR(brdp, uiop->uio_offset);
3782                 n = MIN(size, (brdp->pagesize -
3783                         (((unsigned long) uiop->uio_offset) % brdp->pagesize)));
3784                 error = uiomove(memptr, n, uiop);
3785                 if ((uiop->uio_resid == 0) || error)
3786                         break;
3787         }
3788         EBRDDISABLE(brdp);
3789         splx(x);
3790
3791         return(error);
3792 }
3793
3794 /*****************************************************************************/
3795
3796 /*
3797  *      The "staliomem" device is also required to do some special operations
3798  *      on the board. We need to be able to send an interrupt to the board,
3799  *      reset it, and start/stop it.
3800  */
3801
3802 static int stli_memioctl(dev_t dev, unsigned long cmd, caddr_t data, int flag,
3803                          struct proc *p)
3804 {
3805         stlibrd_t       *brdp;
3806         int             brdnr, rc;
3807
3808 #if DEBUG
3809         printf("stli_memioctl(dev=%s,cmd=%lx,data=%p,flag=%x)\n",
3810                 devtoname(dev), cmd, (void *) data, flag);
3811 #endif
3812
3813         brdnr = minor(dev) & 0x7;
3814         brdp = stli_brds[brdnr];
3815         if (brdp == (stlibrd_t *) NULL)
3816                 return(ENODEV);
3817         if (brdp->state == 0)
3818                 return(ENODEV);
3819
3820         rc = 0;
3821
3822         switch (cmd) {
3823         case STL_BINTR:
3824                 EBRDINTR(brdp);
3825                 break;
3826         case STL_BSTART:
3827                 rc = stli_startbrd(brdp);
3828                 break;
3829         case STL_BSTOP:
3830                 brdp->state &= ~BST_STARTED;
3831                 break;
3832         case STL_BRESET:
3833                 brdp->state &= ~BST_STARTED;
3834                 EBRDRESET(brdp);
3835                 if (stli_shared == 0) {
3836                         if (brdp->reenable != NULL)
3837                                 (* brdp->reenable)(brdp);
3838                 }
3839                 break;
3840         case COM_GETPORTSTATS:
3841                 rc = stli_getportstats((stliport_t *) NULL, data);
3842                 break;
3843         case COM_CLRPORTSTATS:
3844                 rc = stli_clrportstats((stliport_t *) NULL, data);
3845                 break;
3846         case COM_GETBRDSTATS:
3847                 rc = stli_getbrdstats(data);
3848                 break;
3849         default:
3850                 rc = ENOTTY;
3851                 break;
3852         }
3853
3854         return(rc);
3855 }
3856
3857 /*****************************************************************************/