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