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