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