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