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