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