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