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