1 /*****************************************************************************/
4 * istallion.c -- stallion intelligent multiport serial driver.
6 * Copyright (c) 1994-1996 Greg Ungerer (gerg@stallion.oz.au).
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
39 /*****************************************************************************/
41 #include "opt_compat.h"
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/malloc.h>
51 #include <sys/fcntl.h>
56 #include <i386/isa/isa_device.h>
57 #include <machine/cdk.h>
58 #include <machine/comstats.h>
61 #error "The stli device requires the old isa compatibility shims"
64 /*****************************************************************************/
67 * Define the version level of the kernel - so we can compile in the
68 * appropriate bits of code. By default this will compile for a 2.1
79 /*****************************************************************************/
82 * Define different board types. Not all of the following board types
83 * are supported by this driver. But I will use the standard "assigned"
84 * board numbers. Currently supported boards are abbreviated as:
85 * ECP = EasyConnection 8/64, ONB = ONboard, BBY = Brumby and
89 #define BRD_STALLION 1
91 #define BRD_ONBOARD2 3
94 #define BRD_BRUMBY16 6
95 #define BRD_ONBOARDE 7
96 #define BRD_ONBOARD32 9
97 #define BRD_ONBOARD2_32 10
98 #define BRD_ONBOARDRS 11
105 #define BRD_ECHPCI 26
107 #define BRD_BRUMBY BRD_BRUMBY4
109 /*****************************************************************************/
112 * Define important driver limitations.
114 #define STL_MAXBRDS 8
115 #define STL_MAXPANELS 4
116 #define STL_PORTSPERPANEL 16
117 #define STL_PORTSPERBRD 64
119 #define STL_MAXCHANS STL_PORTSPERBRD
123 * Define the important minor number break down bits. These have been
124 * chosen to be "compatible" with the standard sio driver minor numbers.
125 * Extra high bits are used to distinguish between boards and also for
126 * really high port numbers (> 32).
128 #define STL_CALLOUTDEV 0x80
129 #define STL_CTRLLOCK 0x40
130 #define STL_CTRLINIT 0x20
131 #define STL_CTRLDEV (STL_CTRLLOCK | STL_CTRLINIT)
133 #define STL_MEMDEV 0x07000000
135 #define STL_DEFSPEED TTYDEF_SPEED
136 #define STL_DEFCFLAG (CS8 | CREAD | HUPCL)
138 /*****************************************************************************/
141 * Define our local driver identity first. Set up stuff to deal with
142 * all the local structures required by a serial tty driver.
144 static char stli_drvname[] = "stli";
145 static char const stli_longdrvname[] = "Stallion Multiport Serial Driver";
146 static char const stli_drvversion[] = "1.0.0";
148 static int stli_nrbrds = 0;
149 static int stli_doingtimeout = 0;
151 static char *__file__ = /*__FILE__*/ "istallion.c";
154 * Define some macros to use to class define boards.
161 static unsigned char stli_stliprobed[STL_MAXBRDS];
163 /*****************************************************************************/
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.
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
195 struct termios initintios;
196 struct termios initouttios;
197 struct termios lockintios;
198 struct termios lockouttios;
199 struct timeval timestamp;
202 unsigned long rxlost;
203 unsigned long rxoffset;
204 unsigned long txoffset;
208 unsigned char reqidx;
209 unsigned char reqbit;
210 unsigned char portidx;
211 unsigned char portbit;
215 * Use a structure of function pointers to do board level operations.
216 * These include, enable/disable, paging shared memory, interrupting, etc.
218 typedef struct stlibrd {
235 void (*init)(struct stlibrd *brdp);
236 void (*enable)(struct stlibrd *brdp);
237 void (*reenable)(struct stlibrd *brdp);
238 void (*disable)(struct stlibrd *brdp);
239 void (*intr)(struct stlibrd *brdp);
240 void (*reset)(struct stlibrd *brdp);
241 char *(*getmemptr)(struct stlibrd *brdp,
242 unsigned long offset, int line);
243 int panels[STL_MAXPANELS];
244 int panelids[STL_MAXPANELS];
245 stliport_t *ports[STL_PORTSPERBRD];
248 static stlibrd_t *stli_brds[STL_MAXBRDS];
250 static int stli_shared = 0;
253 * Keep a local char buffer for processing chars into the LD. We
254 * do this to avoid copying from the boards shared memory one char
257 static int stli_rxtmplen;
258 static stliport_t *stli_rxtmpport;
259 static char stli_rxtmpbuf[TTYHOG];
262 * Define global stats structures. Not used often, and can be re-used
263 * for each stats call.
265 static comstats_t stli_comstats;
266 static combrd_t stli_brdstats;
267 static asystats_t stli_cdkstats;
270 * Per board state flags. Used with the state field of the board struct.
271 * Not really much here... All we need to do is keep track of whether
272 * the board has been detected, and whether it is actully running a slave
275 #define BST_FOUND 0x1
276 #define BST_STARTED 0x2
279 * Define the set of port state flags. These are marked for internal
280 * state purposes only, usually to do with the state of communications
281 * with the slave. They need to be updated atomically.
283 #define ST_INITIALIZING 0x1
284 #define ST_INITIALIZED 0x2
285 #define ST_OPENING 0x4
286 #define ST_CLOSING 0x8
287 #define ST_CMDING 0x10
288 #define ST_RXING 0x20
289 #define ST_TXBUSY 0x40
290 #define ST_DOFLUSHRX 0x80
291 #define ST_DOFLUSHTX 0x100
292 #define ST_DOSIGS 0x200
293 #define ST_GETSIGS 0x400
294 #define ST_DTRWAIT 0x800
297 * Define an array of board names as printable strings. Handy for
298 * referencing boards when printing trace and stuff.
300 static char *stli_brdnames[] = {
330 /*****************************************************************************/
333 * Hardware configuration info for ECP boards. These defines apply
334 * to the directly accessible io ports of the ECP. There is a set of
335 * defines for each ECP board type, ISA, EISA and MCA.
338 #define ECP_MEMSIZE (128 * 1024)
339 #define ECP_ATPAGESIZE (4 * 1024)
340 #define ECP_EIPAGESIZE (64 * 1024)
341 #define ECP_MCPAGESIZE (4 * 1024)
343 #define STL_EISAID 0x8c4e
346 * Important defines for the ISA class of ECP board.
349 #define ECP_ATCONFR 1
350 #define ECP_ATMEMAR 2
351 #define ECP_ATMEMPR 3
352 #define ECP_ATSTOP 0x1
353 #define ECP_ATINTENAB 0x10
354 #define ECP_ATENABLE 0x20
355 #define ECP_ATDISABLE 0x00
356 #define ECP_ATADDRMASK 0x3f000
357 #define ECP_ATADDRSHFT 12
360 * Important defines for the EISA class of ECP board.
363 #define ECP_EIMEMARL 1
364 #define ECP_EICONFR 2
365 #define ECP_EIMEMARH 3
366 #define ECP_EIENABLE 0x1
367 #define ECP_EIDISABLE 0x0
368 #define ECP_EISTOP 0x4
369 #define ECP_EIEDGE 0x00
370 #define ECP_EILEVEL 0x80
371 #define ECP_EIADDRMASKL 0x00ff0000
372 #define ECP_EIADDRSHFTL 16
373 #define ECP_EIADDRMASKH 0xff000000
374 #define ECP_EIADDRSHFTH 24
375 #define ECP_EIBRDENAB 0xc84
377 #define ECP_EISAID 0x4
380 * Important defines for the Micro-channel class of ECP board.
381 * (It has a lot in common with the ISA boards.)
384 #define ECP_MCCONFR 1
385 #define ECP_MCSTOP 0x20
386 #define ECP_MCENABLE 0x80
387 #define ECP_MCDISABLE 0x00
390 * Hardware configuration info for ONboard and Brumby boards. These
391 * defines apply to the directly accessible io ports of these boards.
393 #define ONB_IOSIZE 16
394 #define ONB_MEMSIZE (64 * 1024)
395 #define ONB_ATPAGESIZE (64 * 1024)
396 #define ONB_MCPAGESIZE (64 * 1024)
397 #define ONB_EIMEMSIZE (128 * 1024)
398 #define ONB_EIPAGESIZE (64 * 1024)
401 * Important defines for the ISA class of ONboard board.
404 #define ONB_ATMEMAR 1
405 #define ONB_ATCONFR 2
406 #define ONB_ATSTOP 0x4
407 #define ONB_ATENABLE 0x01
408 #define ONB_ATDISABLE 0x00
409 #define ONB_ATADDRMASK 0xff0000
410 #define ONB_ATADDRSHFT 16
412 #define ONB_HIMEMENAB 0x02
415 * Important defines for the EISA class of ONboard board.
418 #define ONB_EIMEMARL 1
419 #define ONB_EICONFR 2
420 #define ONB_EIMEMARH 3
421 #define ONB_EIENABLE 0x1
422 #define ONB_EIDISABLE 0x0
423 #define ONB_EISTOP 0x4
424 #define ONB_EIEDGE 0x00
425 #define ONB_EILEVEL 0x80
426 #define ONB_EIADDRMASKL 0x00ff0000
427 #define ONB_EIADDRSHFTL 16
428 #define ONB_EIADDRMASKH 0xff000000
429 #define ONB_EIADDRSHFTH 24
430 #define ONB_EIBRDENAB 0xc84
432 #define ONB_EISAID 0x1
435 * Important defines for the Brumby boards. They are pretty simple,
436 * there is not much that is programmably configurable.
438 #define BBY_IOSIZE 16
439 #define BBY_MEMSIZE (64 * 1024)
440 #define BBY_PAGESIZE (16 * 1024)
443 #define BBY_ATCONFR 1
444 #define BBY_ATSTOP 0x4
447 * Important defines for the Stallion boards. They are pretty simple,
448 * there is not much that is programmably configurable.
450 #define STAL_IOSIZE 16
451 #define STAL_MEMSIZE (64 * 1024)
452 #define STAL_PAGESIZE (64 * 1024)
455 * Define the set of status register values for EasyConnection panels.
456 * The signature will return with the status value for each panel. From
457 * this we can determine what is attached to the board - before we have
458 * actually down loaded any code to it.
460 #define ECH_PNLSTATUS 2
461 #define ECH_PNL16PORT 0x20
462 #define ECH_PNLIDMASK 0x07
463 #define ECH_PNLINTRPEND 0x80
466 * Define some macros to do things to the board. Even those these boards
467 * are somewhat related there is often significantly different ways of
468 * doing some operation on it (like enable, paging, reset, etc). So each
469 * board class has a set of functions which do the commonly required
470 * operations. The macros below basically just call these functions,
471 * generally checking for a NULL function - which means that the board
472 * needs nothing done to it to achieve this operation!
474 #define EBRDINIT(brdp) \
475 if (brdp->init != NULL) \
478 #define EBRDENABLE(brdp) \
479 if (brdp->enable != NULL) \
480 (* brdp->enable)(brdp);
482 #define EBRDDISABLE(brdp) \
483 if (brdp->disable != NULL) \
484 (* brdp->disable)(brdp);
486 #define EBRDINTR(brdp) \
487 if (brdp->intr != NULL) \
488 (* brdp->intr)(brdp);
490 #define EBRDRESET(brdp) \
491 if (brdp->reset != NULL) \
492 (* brdp->reset)(brdp);
494 #define EBRDGETMEMPTR(brdp,offset) \
495 (* brdp->getmemptr)(brdp, offset, __LINE__)
498 * Define the maximal baud rate.
500 #define STL_MAXBAUD 230400
502 /*****************************************************************************/
505 * Define macros to extract a brd and port number from a minor number.
506 * This uses the extended minor number range in the upper 2 bytes of
507 * the device number. This gives us plenty of minor numbers to play
510 #define MKDEV2BRD(m) ((minor(m) & 0x00700000) >> 20)
511 #define MKDEV2PORT(m) ((minor(m) & 0x1f) | ((minor(m) & 0x00010000) >> 11))
514 * Define some handy local macros...
517 #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
520 /*****************************************************************************/
523 * Declare all those functions in this driver! First up is the set of
524 * externally visible functions.
526 static int stliprobe(struct isa_device *idp);
527 static int stliattach(struct isa_device *idp);
529 STATIC d_open_t stliopen;
530 STATIC d_close_t stliclose;
531 STATIC d_read_t stliread;
532 STATIC d_write_t stliwrite;
533 STATIC d_ioctl_t stliioctl;
536 * Internal function prototypes.
538 static stliport_t *stli_dev2port(dev_t dev);
539 static int stli_isaprobe(struct isa_device *idp);
540 static int stli_eisaprobe(struct isa_device *idp);
541 static int stli_mcaprobe(struct isa_device *idp);
542 static int stli_brdinit(stlibrd_t *brdp);
543 static int stli_brdattach(stlibrd_t *brdp);
544 static int stli_initecp(stlibrd_t *brdp);
545 static int stli_initonb(stlibrd_t *brdp);
546 static int stli_initports(stlibrd_t *brdp);
547 static int stli_startbrd(stlibrd_t *brdp);
548 static void stli_poll(void *arg);
549 static __inline void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp);
550 static __inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);
551 static __inline void stli_dodelaycmd(stliport_t *portp,
552 volatile cdkctrl_t *cp);
553 static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts);
554 static long stli_mktiocm(unsigned long sigvalue);
555 static void stli_rxprocess(stlibrd_t *brdp, stliport_t *portp);
556 static void stli_flush(stliport_t *portp, int flag);
557 static void stli_start(struct tty *tp);
558 static void stli_stop(struct tty *tp, int rw);
559 static int stli_param(struct tty *tp, struct termios *tiosp);
560 static void stli_ttyoptim(stliport_t *portp, struct termios *tiosp);
561 static void stli_dtrwakeup(void *arg);
562 static int stli_initopen(stliport_t *portp);
563 static int stli_shutdownclose(stliport_t *portp);
564 static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp,
565 unsigned long arg, int wait);
566 static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp,
567 unsigned long arg, int wait);
568 static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp,
569 unsigned long cmd, void *arg, int size, int copyback);
570 static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp,
571 unsigned long cmd, void *arg, int size, int copyback);
572 static void stli_mkasyport(stliport_t *portp, asyport_t *pp,
573 struct termios *tiosp);
574 static int stli_memrw(dev_t dev, struct uio *uiop, int flag);
575 static int stli_memioctl(dev_t dev, unsigned long cmd, caddr_t data,
576 int flag, struct proc *p);
577 static int stli_getbrdstats(caddr_t data);
578 static int stli_getportstats(stliport_t *portp, caddr_t data);
579 static int stli_clrportstats(stliport_t *portp, caddr_t data);
580 static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);
582 static void stli_ecpinit(stlibrd_t *brdp);
583 static void stli_ecpenable(stlibrd_t *brdp);
584 static void stli_ecpdisable(stlibrd_t *brdp);
585 static void stli_ecpreset(stlibrd_t *brdp);
586 static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset,
588 static void stli_ecpintr(stlibrd_t *brdp);
589 static void stli_ecpeiinit(stlibrd_t *brdp);
590 static void stli_ecpeienable(stlibrd_t *brdp);
591 static void stli_ecpeidisable(stlibrd_t *brdp);
592 static void stli_ecpeireset(stlibrd_t *brdp);
593 static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset,
595 static void stli_ecpmcenable(stlibrd_t *brdp);
596 static void stli_ecpmcdisable(stlibrd_t *brdp);
597 static void stli_ecpmcreset(stlibrd_t *brdp);
598 static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset,
601 static void stli_onbinit(stlibrd_t *brdp);
602 static void stli_onbenable(stlibrd_t *brdp);
603 static void stli_onbdisable(stlibrd_t *brdp);
604 static void stli_onbreset(stlibrd_t *brdp);
605 static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset,
607 static void stli_onbeinit(stlibrd_t *brdp);
608 static void stli_onbeenable(stlibrd_t *brdp);
609 static void stli_onbedisable(stlibrd_t *brdp);
610 static void stli_onbereset(stlibrd_t *brdp);
611 static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset,
613 static void stli_bbyinit(stlibrd_t *brdp);
614 static void stli_bbyreset(stlibrd_t *brdp);
615 static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset,
617 static void stli_stalinit(stlibrd_t *brdp);
618 static void stli_stalreset(stlibrd_t *brdp);
619 static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset,
622 /*****************************************************************************/
625 * Declare the driver isa structure.
627 struct isa_driver stlidriver = {
633 COMPAT_ISA_DRIVER(stli, stlidriver);
635 /*****************************************************************************/
640 * FreeBSD-2.2+ kernel linkage.
643 #define CDEV_MAJOR 75
644 static struct cdevsw stli_cdevsw = {
646 /* close */ stliclose,
648 /* write */ stliwrite,
649 /* ioctl */ stliioctl,
652 /* strategy */ nostrategy,
653 /* name */ stli_drvname,
654 /* maj */ CDEV_MAJOR,
657 /* flags */ D_TTY | D_KQFILTER,
659 /* kqfilter */ ttykqfilter,
664 /*****************************************************************************/
666 static stlibrd_t *stli_brdalloc(void)
670 brdp = (stlibrd_t *) malloc(sizeof(stlibrd_t), M_TTYS, M_NOWAIT|M_ZERO);
671 if (brdp == (stlibrd_t *) NULL) {
672 printf("STALLION: failed to allocate memory (size=%d)\n",
674 return((stlibrd_t *) NULL);
679 /*****************************************************************************/
682 * Find an available internal board number (unit number). The problem
683 * is that the same unit numbers can be assigned to different class
684 * boards - but we only want to maintain one setup board structures.
687 static int stli_findfreeunit(void)
691 for (i = 0; (i < STL_MAXBRDS); i++)
692 if (stli_brds[i] == (stlibrd_t *) NULL)
694 return((i >= STL_MAXBRDS) ? -1 : i);
697 /*****************************************************************************/
700 * Try and determine the ISA board type. Hopefully the board
701 * configuration entry will help us out, using the flags field.
702 * If not, we may ne be able to determine the board type...
705 static int stli_isaprobe(struct isa_device *idp)
710 printf("stli_isaprobe(idp=%x): unit=%d iobase=%x flags=%x\n",
711 (int) idp, idp->id_unit, idp->id_iobase, idp->id_flags);
714 switch (idp->id_flags) {
722 btype = idp->id_flags;
731 /*****************************************************************************/
734 * Probe for an EISA board type. We should be able to read the EISA ID,
735 * that will tell us if a board is present or not...
738 static int stli_eisaprobe(struct isa_device *idp)
743 printf("stli_eisaprobe(idp=%x): unit=%d iobase=%x flags=%x\n",
744 (int) idp, idp->id_unit, idp->id_iobase, idp->id_flags);
748 * Firstly check if this is an EISA system. Do this by probing for
749 * the system board EISA ID. If this is not an EISA system then
750 * don't bother going any further!
753 if (inb(0xc80) == 0xff)
757 * Try and read the EISA ID from the board at specified address.
758 * If one is present it will tell us the board type as well.
760 outb((idp->id_iobase + 0xc80), 0xff);
761 eid = inb(idp->id_iobase + 0xc80);
762 eid |= inb(idp->id_iobase + 0xc81) << 8;
763 if (eid != STL_EISAID)
767 eid = inb(idp->id_iobase + 0xc82);
768 if (eid == ECP_EISAID)
770 else if (eid == ONB_EISAID)
771 btype = BRD_ONBOARDE;
773 outb((idp->id_iobase + 0xc84), 0x1);
777 /*****************************************************************************/
780 * Probe for an MCA board type. Not really sure how to do this yet,
781 * so for now just use the supplied flag specifier as board type...
784 static int stli_mcaprobe(struct isa_device *idp)
789 printf("stli_mcaprobe(idp=%x): unit=%d iobase=%x flags=%x\n",
790 (int) idp, idp->id_unit, idp->id_iobase, idp->id_flags);
793 switch (idp->id_flags) {
795 case BRD_ONBOARD2_32:
799 btype = idp->id_flags;
808 /*****************************************************************************/
811 * Probe for a board. This is involved, since we need to enable the
812 * shared memory region to see if the board is really there or not...
815 static int stliprobe(struct isa_device *idp)
822 cdevsw_add(&stli_cdevsw);
825 printf("stliprobe(idp=%x): unit=%d iobase=%x flags=%x\n", (int) idp,
826 idp->id_unit, idp->id_iobase, idp->id_flags);
829 if (idp->id_unit > STL_MAXBRDS)
833 * First up determine what bus type of board we might be dealing
834 * with. It is easy to separate out the ISA from the EISA and MCA
835 * boards, based on their IO addresses. We may not be able to tell
836 * the EISA and MCA apart on IO address alone...
839 if ((idp->id_iobase > 0) && (idp->id_iobase < 0x400)) {
843 if ((idp->id_iobase >= 0x700) && (idp->id_iobase < 0x900))
846 if ((idp->id_iobase >= 0x7000) && (idp->id_iobase < 0x7400))
848 if ((idp->id_iobase >= 0x8000) && (idp->id_iobase < 0xc000))
850 /* EISA board range */
851 if ((idp->id_iobase & ~0xf000) == 0)
855 if ((bclass == 0) || (idp->id_iobase == 0))
859 * Based on the board bus type, try and figure out what it might be...
862 if (bclass & BRD_ISA)
863 btype = stli_isaprobe(idp);
864 if ((btype == 0) && (bclass & BRD_EISA))
865 btype = stli_eisaprobe(idp);
866 if ((btype == 0) && (bclass & BRD_MCA))
867 btype = stli_mcaprobe(idp);
872 * Go ahead and try probing for the shared memory region now.
873 * This way we will really know if the board is here...
875 if ((brdp = stli_brdalloc()) == (stlibrd_t *) NULL)
878 brdp->brdnr = stli_findfreeunit();
879 brdp->brdtype = btype;
880 brdp->unitid = idp->id_unit;
881 brdp->iobase = idp->id_iobase;
882 brdp->vaddr = idp->id_maddr;
883 brdp->paddr = vtophys(idp->id_maddr);
886 printf("%s(%d): btype=%x unit=%d brd=%d io=%x mem=%lx(%p)\n",
887 __file__, __LINE__, btype, brdp->unitid, brdp->brdnr,
888 brdp->iobase, brdp->paddr, (void *) brdp->vaddr);
891 stli_stliprobed[idp->id_unit] = brdp->brdnr;
893 if ((brdp->state & BST_FOUND) == 0) {
894 stli_brds[brdp->brdnr] = (stlibrd_t *) NULL;
901 /*****************************************************************************/
904 * Allocate resources for and initialize a board.
907 static int stliattach(struct isa_device *idp)
913 printf("stliattach(idp=%p): unit=%d iobase=%x\n", (void *) idp,
914 idp->id_unit, idp->id_iobase);
917 brdnr = stli_stliprobed[idp->id_unit];
918 brdp = stli_brds[brdnr];
919 if (brdp == (stlibrd_t *) NULL)
921 if (brdp->state & BST_FOUND)
922 stli_brdattach(brdp);
927 /*****************************************************************************/
929 STATIC int stliopen(dev_t dev, int flag, int mode, struct proc *p)
933 int error, callout, x;
936 printf("stliopen(dev=%x,flag=%x,mode=%x,p=%x)\n", (int) dev, flag,
941 * Firstly check if the supplied device number is a valid device.
943 if (minor(dev) & STL_MEMDEV)
946 portp = stli_dev2port(dev);
947 if (portp == (stliport_t *) NULL)
951 callout = minor(dev) & STL_CALLOUTDEV;
958 * Wait here for the DTR drop timeout period to expire.
960 while (portp->state & ST_DTRWAIT) {
961 error = tsleep(&portp->dtrwait, (TTIPRI | PCATCH),
968 * If the port is in its raw hardware initialization phase, then
969 * hold up here 'till it is done.
971 while (portp->state & (ST_INITIALIZING | ST_CLOSING)) {
972 error = tsleep(&portp->state, (TTIPRI | PCATCH),
979 * We have a valid device, so now we check if it is already open.
980 * If not then initialize the port hardware and set up the tty
981 * struct as required.
983 if ((tp->t_state & TS_ISOPEN) == 0) {
984 tp->t_oproc = stli_start;
985 tp->t_param = stli_param;
986 tp->t_stop = stli_stop;
988 tp->t_termios = callout ? portp->initouttios :
990 stli_initopen(portp);
991 wakeup(&portp->state);
992 if ((portp->sigs & TIOCM_CD) || callout)
993 (*linesw[tp->t_line].l_modem)(tp, 1);
996 if (portp->callout == 0) {
1001 if (portp->callout != 0) {
1002 if (flag & O_NONBLOCK) {
1006 error = tsleep(&portp->callout,
1007 (TTIPRI | PCATCH), "stlicall", 0);
1010 goto stliopen_restart;
1013 if ((tp->t_state & TS_XCLUDE) &&
1021 * If this port is not the callout device and we do not have carrier
1022 * then we need to sleep, waiting for it to be asserted.
1024 if (((tp->t_state & TS_CARR_ON) == 0) && !callout &&
1025 ((tp->t_cflag & CLOCAL) == 0) &&
1026 ((flag & O_NONBLOCK) == 0)) {
1028 error = tsleep(TSA_CARR_ON(tp), (TTIPRI | PCATCH), "stlidcd",0);
1032 goto stliopen_restart;
1036 * Open the line discipline.
1038 error = (*linesw[tp->t_line].l_open)(dev, tp);
1039 stli_ttyoptim(portp, &tp->t_termios);
1040 if ((tp->t_state & TS_ISOPEN) && callout)
1044 * If for any reason we get to here and the port is not actually
1045 * open then close of the physical hardware - no point leaving it
1046 * active when the open failed...
1050 if (((tp->t_state & TS_ISOPEN) == 0) && (portp->waitopens == 0))
1051 stli_shutdownclose(portp);
1056 /*****************************************************************************/
1058 STATIC int stliclose(dev_t dev, int flag, int mode, struct proc *p)
1065 printf("stliclose(dev=%s,flag=%x,mode=%x,p=%p)\n",
1066 devtoname(dev), flag, mode, (void *) p);
1069 if (minor(dev) & STL_MEMDEV)
1072 portp = stli_dev2port(dev);
1073 if (portp == (stliport_t *) NULL)
1078 (*linesw[tp->t_line].l_close)(tp, flag);
1079 stli_ttyoptim(portp, &tp->t_termios);
1080 stli_shutdownclose(portp);
1087 STATIC int stliread(dev_t dev, struct uio *uiop, int flag)
1091 printf("stliread(dev=%s,uiop=%p,flag=%x)\n", devtoname(dev),
1092 (void *) uiop, flag);
1095 if (minor(dev) & STL_MEMDEV)
1096 return(stli_memrw(dev, uiop, flag));
1098 return(ttyread(dev, uiop, flag));
1101 /*****************************************************************************/
1105 STATIC void stli_stop(struct tty *tp, int rw)
1108 printf("stli_stop(tp=%x,rw=%x)\n", (int) tp, rw);
1111 stli_flush((stliport_t *) tp, rw);
1116 STATIC int stlistop(struct tty *tp, int rw)
1119 printf("stlistop(tp=%x,rw=%x)\n", (int) tp, rw);
1122 stli_flush((stliport_t *) tp, rw);
1128 /*****************************************************************************/
1130 STATIC int stliwrite(dev_t dev, struct uio *uiop, int flag)
1133 printf("stliwrite(dev=%s,uiop=%p,flag=%x)\n", devtoname(dev),
1134 (void *) uiop, flag);
1137 if (minor(dev) & STL_MEMDEV)
1138 return(stli_memrw(dev, uiop, flag));
1140 return(ttywrite(dev, uiop, flag));
1143 /*****************************************************************************/
1145 STATIC int stliioctl(dev_t dev, unsigned long cmd, caddr_t data, int flag,
1148 struct termios *newtios, *localtios;
1156 printf("stliioctl(dev=%s,cmd=%lx,data=%p,flag=%x,p=%p)\n",
1157 devtoname(dev), cmd, (void *) data, flag, (void *) p);
1160 if (minor(dev) & STL_MEMDEV)
1161 return(stli_memioctl(dev, cmd, data, flag, p));
1163 portp = stli_dev2port(dev);
1164 if (portp == (stliport_t *) NULL)
1166 if ((brdp = stli_brds[portp->brdnr]) == (stlibrd_t *) NULL)
1172 * First up handle ioctls on the control devices.
1174 if (minor(dev) & STL_CTRLDEV) {
1175 if ((minor(dev) & STL_CTRLDEV) == STL_CTRLINIT)
1176 localtios = (minor(dev) & STL_CALLOUTDEV) ?
1177 &portp->initouttios : &portp->initintios;
1178 else if ((minor(dev) & STL_CTRLDEV) == STL_CTRLLOCK)
1179 localtios = (minor(dev) & STL_CALLOUTDEV) ?
1180 &portp->lockouttios : &portp->lockintios;
1186 if ((error = suser(p)) == 0)
1187 *localtios = *((struct termios *) data);
1190 *((struct termios *) data) = *localtios;
1193 *((int *) data) = TTYDISC;
1196 bzero(data, sizeof(struct winsize));
1206 * Deal with 4.3 compatibility issues if we have too...
1208 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1210 struct termios tios;
1211 unsigned long oldcmd;
1213 tios = tp->t_termios;
1215 if ((error = ttsetcompat(tp, &cmd, data, &tios)))
1218 data = (caddr_t) &tios;
1223 * Carry out some pre-cmd processing work first...
1224 * Hmmm, not so sure we want this, disable for now...
1226 if ((cmd == TIOCSETA) || (cmd == TIOCSETAW) || (cmd == TIOCSETAF)) {
1227 newtios = (struct termios *) data;
1228 localtios = (minor(dev) & STL_CALLOUTDEV) ? &portp->lockouttios :
1231 newtios->c_iflag = (tp->t_iflag & localtios->c_iflag) |
1232 (newtios->c_iflag & ~localtios->c_iflag);
1233 newtios->c_oflag = (tp->t_oflag & localtios->c_oflag) |
1234 (newtios->c_oflag & ~localtios->c_oflag);
1235 newtios->c_cflag = (tp->t_cflag & localtios->c_cflag) |
1236 (newtios->c_cflag & ~localtios->c_cflag);
1237 newtios->c_lflag = (tp->t_lflag & localtios->c_lflag) |
1238 (newtios->c_lflag & ~localtios->c_lflag);
1239 for (i = 0; (i < NCCS); i++) {
1240 if (localtios->c_cc[i] != 0)
1241 newtios->c_cc[i] = tp->t_cc[i];
1243 if (localtios->c_ispeed != 0)
1244 newtios->c_ispeed = tp->t_ispeed;
1245 if (localtios->c_ospeed != 0)
1246 newtios->c_ospeed = tp->t_ospeed;
1250 * Call the line discipline and the common command processing to
1251 * process this command (if they can).
1253 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1254 if (error != ENOIOCTL)
1258 error = ttioctl(tp, cmd, data, flag);
1259 stli_ttyoptim(portp, &tp->t_termios);
1260 if (error != ENOIOCTL) {
1268 * Process local commands here. These are all commands that only we
1269 * can take care of (they all rely on actually doing something special
1270 * to the actual hardware).
1275 error = stli_cmdwait(brdp, portp, A_BREAK, &arg,
1276 sizeof(unsigned long), 0);
1280 error = stli_cmdwait(brdp, portp, A_BREAK, &arg,
1281 sizeof(unsigned long), 0);
1284 stli_mkasysigs(&portp->asig, 1, -1);
1285 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1286 sizeof(asysigs_t), 0);
1289 stli_mkasysigs(&portp->asig, 0, -1);
1290 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1291 sizeof(asysigs_t), 0);
1294 i = *((int *) data);
1295 stli_mkasysigs(&portp->asig, ((i & TIOCM_DTR) ? 1 : 0),
1296 ((i & TIOCM_RTS) ? 1 : 0));
1297 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1298 sizeof(asysigs_t), 0);
1301 i = *((int *) data);
1302 stli_mkasysigs(&portp->asig, ((i & TIOCM_DTR) ? 1 : -1),
1303 ((i & TIOCM_RTS) ? 1 : -1));
1304 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1305 sizeof(asysigs_t), 0);
1308 i = *((int *) data);
1309 stli_mkasysigs(&portp->asig, ((i & TIOCM_DTR) ? 0 : -1),
1310 ((i & TIOCM_RTS) ? 0 : -1));
1311 error = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1312 sizeof(asysigs_t), 0);
1315 if ((error = stli_cmdwait(brdp, portp, A_GETSIGNALS,
1316 &portp->asig, sizeof(asysigs_t), 1)) < 0)
1318 portp->sigs = stli_mktiocm(portp->asig.sigvalue);
1319 *((int *) data) = (portp->sigs | TIOCM_LE);
1322 if ((error = suser(p)) == 0)
1323 portp->dtrwait = *((int *) data) * hz / 100;
1326 *((int *) data) = portp->dtrwait * 100 / hz;
1329 portp->dotimestamp = 1;
1330 *((struct timeval *) data) = portp->timestamp;
1341 /*****************************************************************************/
1344 * Convert the specified minor device number into a port struct
1345 * pointer. Return NULL if the device number is not a valid port.
1348 STATIC stliport_t *stli_dev2port(dev_t dev)
1352 brdp = stli_brds[MKDEV2BRD(dev)];
1353 if (brdp == (stlibrd_t *) NULL)
1354 return((stliport_t *) NULL);
1355 if ((brdp->state & BST_STARTED) == 0)
1356 return((stliport_t *) NULL);
1357 return(brdp->ports[MKDEV2PORT(dev)]);
1360 /*****************************************************************************/
1363 * Carry out first open operations on a port. This involves a number of
1364 * commands to be sent to the slave. We need to open the port, set the
1365 * notification events, set the initial port settings, get and set the
1366 * initial signal values. We sleep and wait in between each one. But
1367 * this still all happens pretty quickly.
1370 static int stli_initopen(stliport_t *portp)
1378 printf("stli_initopen(portp=%x)\n", (int) portp);
1381 if ((brdp = stli_brds[portp->brdnr]) == (stlibrd_t *) NULL)
1383 if (portp->state & ST_INITIALIZED)
1385 portp->state |= ST_INITIALIZED;
1387 if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0)
1390 bzero(&nt, sizeof(asynotify_t));
1391 nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);
1393 if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt,
1394 sizeof(asynotify_t), 0)) < 0)
1397 stli_mkasyport(portp, &aport, &portp->tty.t_termios);
1398 if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,
1399 sizeof(asyport_t), 0)) < 0)
1402 portp->state |= ST_GETSIGS;
1403 if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig,
1404 sizeof(asysigs_t), 1)) < 0)
1406 if (portp->state & ST_GETSIGS) {
1407 portp->sigs = stli_mktiocm(portp->asig.sigvalue);
1408 portp->state &= ~ST_GETSIGS;
1411 stli_mkasysigs(&portp->asig, 1, 1);
1412 if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1413 sizeof(asysigs_t), 0)) < 0)
1419 /*****************************************************************************/
1422 * Shutdown the hardware of a port.
1425 static int stli_shutdownclose(stliport_t *portp)
1432 printf("stli_shutdownclose(portp=%p): brdnr=%d panelnr=%d portnr=%d\n",
1433 (void *) portp, portp->brdnr, portp->panelnr, portp->portnr);
1436 if ((brdp = stli_brds[portp->brdnr]) == (stlibrd_t *) NULL)
1440 stli_rawclose(brdp, portp, 0, 0);
1441 stli_flush(portp, (FWRITE | FREAD));
1442 if (tp->t_cflag & HUPCL) {
1444 stli_mkasysigs(&portp->asig, 0, 0);
1445 if (portp->state & ST_CMDING) {
1446 portp->state |= ST_DOSIGS;
1448 stli_sendcmd(brdp, portp, A_SETSIGNALS,
1449 &portp->asig, sizeof(asysigs_t), 0);
1452 if (portp->dtrwait != 0) {
1453 portp->state |= ST_DTRWAIT;
1454 timeout(stli_dtrwakeup, portp, portp->dtrwait);
1458 portp->state &= ~ST_INITIALIZED;
1459 wakeup(&portp->callout);
1460 wakeup(TSA_CARR_ON(tp));
1464 /*****************************************************************************/
1467 * Clear the DTR waiting flag, and wake up any sleepers waiting for
1468 * DTR wait period to finish.
1471 static void stli_dtrwakeup(void *arg)
1475 portp = (stliport_t *) arg;
1476 portp->state &= ~ST_DTRWAIT;
1477 wakeup(&portp->dtrwait);
1480 /*****************************************************************************/
1483 * Send an open message to the slave. This will sleep waiting for the
1484 * acknowledgement, so must have user context. We need to co-ordinate
1485 * with close events here, since we don't want open and close events
1489 static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
1491 volatile cdkhdr_t *hdrp;
1492 volatile cdkctrl_t *cp;
1493 volatile unsigned char *bits;
1497 printf("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp,
1498 (int) portp, (int) arg, wait);
1504 * Slave is already closing this port. This can happen if a hangup
1505 * occurs on this port. So we must wait until it is complete. The
1506 * order of opens and closes may not be preserved across shared
1507 * memory, so we must wait until it is complete.
1509 while (portp->state & ST_CLOSING) {
1510 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1518 * Everything is ready now, so write the open message into shared
1519 * memory. Once the message is in set the service bits to say that
1520 * this port wants service.
1523 cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
1526 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1527 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
1529 *bits |= portp->portbit;
1538 * Slave is in action, so now we must wait for the open acknowledgment
1542 portp->state |= ST_OPENING;
1543 while (portp->state & ST_OPENING) {
1544 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1552 if ((rc == 0) && (portp->rc != 0))
1557 /*****************************************************************************/
1560 * Send a close message to the slave. Normally this will sleep waiting
1561 * for the acknowledgement, but if wait parameter is 0 it will not. If
1562 * wait is true then must have user context (to sleep).
1565 static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
1567 volatile cdkhdr_t *hdrp;
1568 volatile cdkctrl_t *cp;
1569 volatile unsigned char *bits;
1573 printf("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp,
1574 (int) portp, (int) arg, wait);
1580 * Slave is already closing this port. This can happen if a hangup
1581 * occurs on this port.
1584 while (portp->state & ST_CLOSING) {
1585 rc = tsleep(&portp->state, (TTIPRI | PCATCH),
1595 * Write the close command into shared memory.
1598 cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
1601 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1602 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
1604 *bits |= portp->portbit;
1607 portp->state |= ST_CLOSING;
1614 * Slave is in action, so now we must wait for the open acknowledgment
1618 while (portp->state & ST_CLOSING) {
1619 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1627 if ((rc == 0) && (portp->rc != 0))
1632 /*****************************************************************************/
1635 * Send a command to the slave and wait for the response. This must
1636 * have user context (it sleeps). This routine is generic in that it
1637 * can send any type of command. Its purpose is to wait for that command
1638 * to complete (as opposed to initiating the command then returning).
1641 static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
1646 printf("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
1647 "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
1648 (int) arg, size, copyback);
1652 while (portp->state & ST_CMDING) {
1653 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1660 stli_sendcmd(brdp, portp, cmd, arg, size, copyback);
1662 while (portp->state & ST_CMDING) {
1663 rc = tsleep(&portp->state, (TTIPRI | PCATCH), "stliraw", 0);
1676 /*****************************************************************************/
1679 * Start (or continue) the transfer of TX data on this port. If the
1680 * port is not currently busy then load up the interrupt ring queue
1681 * buffer and kick of the transmitter. If the port is running low on
1682 * TX data then refill the ring queue. This routine is also used to
1683 * activate input flow control!
1686 static void stli_start(struct tty *tp)
1688 volatile cdkasy_t *ap;
1689 volatile cdkhdr_t *hdrp;
1690 volatile unsigned char *bits;
1691 unsigned char *shbuf;
1694 unsigned int len, stlen, head, tail, size;
1697 portp = (stliport_t *) tp;
1700 printf("stli_start(tp=%x): brdnr=%d portnr=%d\n", (int) tp,
1701 portp->brdnr, portp->portnr);
1708 * Check if the output cooked clist buffers are near empty, wake up
1709 * the line discipline to fill it up.
1711 if (tp->t_outq.c_cc <= tp->t_lowat) {
1712 if (tp->t_state & TS_ASLEEP) {
1713 tp->t_state &= ~TS_ASLEEP;
1714 wakeup(&tp->t_outq);
1716 selwakeup(&tp->t_wsel);
1720 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
1726 * Copy data from the clists into the interrupt ring queue. This will
1727 * require at most 2 copys... What we do is calculate how many chars
1728 * can fit into the ring queue, and how many can fit in 1 copy. If after
1729 * the first copy there is still more room then do the second copy.
1731 if (tp->t_outq.c_cc != 0) {
1732 brdp = stli_brds[portp->brdnr];
1733 if (brdp == (stlibrd_t *) NULL) {
1739 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
1740 head = (unsigned int) ap->txq.head;
1741 tail = (unsigned int) ap->txq.tail;
1742 if (tail != ((unsigned int) ap->txq.tail))
1743 tail = (unsigned int) ap->txq.tail;
1744 size = portp->txsize;
1746 len = size - (head - tail) - 1;
1747 stlen = size - head;
1749 len = tail - head - 1;
1754 shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset);
1757 stlen = MIN(len, stlen);
1758 count = q_to_b(&tp->t_outq, (shbuf + head), stlen);
1764 stlen = q_to_b(&tp->t_outq, shbuf, len);
1771 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
1772 ap->txq.head = head;
1773 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1774 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
1776 *bits |= portp->portbit;
1777 portp->state |= ST_TXBUSY;
1778 tp->t_state |= TS_BUSY;
1785 * Do any writer wakeups.
1793 /*****************************************************************************/
1796 * Send a new port configuration to the slave.
1799 static int stli_param(struct tty *tp, struct termios *tiosp)
1806 portp = (stliport_t *) tp;
1807 if ((brdp = stli_brds[portp->brdnr]) == (stlibrd_t *) NULL)
1811 stli_mkasyport(portp, &aport, tiosp);
1812 /* can we sleep here? */
1813 rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0);
1814 stli_ttyoptim(portp, tiosp);
1819 /*****************************************************************************/
1822 * Flush characters from the lower buffer. We may not have user context
1823 * so we cannot sleep waiting for it to complete. Also we need to check
1824 * if there is chars for this port in the TX cook buffer, and flush them
1828 static void stli_flush(stliport_t *portp, int flag)
1831 unsigned long ftype;
1835 printf("stli_flush(portp=%x,flag=%x)\n", (int) portp, flag);
1838 if (portp == (stliport_t *) NULL)
1840 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
1842 brdp = stli_brds[portp->brdnr];
1843 if (brdp == (stlibrd_t *) NULL)
1847 if (portp->state & ST_CMDING) {
1848 portp->state |= (flag & FWRITE) ? ST_DOFLUSHTX : 0;
1849 portp->state |= (flag & FREAD) ? ST_DOFLUSHRX : 0;
1851 ftype = (flag & FWRITE) ? FLUSHTX : 0;
1852 ftype |= (flag & FREAD) ? FLUSHRX : 0;
1853 portp->state &= ~(ST_DOFLUSHTX | ST_DOFLUSHRX);
1854 stli_sendcmd(brdp, portp, A_FLUSH, &ftype,
1855 sizeof(unsigned long), 0);
1857 if ((flag & FREAD) && (stli_rxtmpport == portp))
1862 /*****************************************************************************/
1865 * Generic send command routine. This will send a message to the slave,
1866 * of the specified type with the specified argument. Must be very
1867 * carefull of data that will be copied out from shared memory -
1868 * containing command results. The command completion is all done from
1869 * a poll routine that does not have user coontext. Therefore you cannot
1870 * copy back directly into user space, or to the kernel stack of a
1871 * process. This routine does not sleep, so can be called from anywhere,
1872 * and must be called with interrupt locks set.
1875 static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
1877 volatile cdkhdr_t *hdrp;
1878 volatile cdkctrl_t *cp;
1879 volatile unsigned char *bits;
1882 printf("stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
1883 "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
1884 (int) arg, size, copyback);
1887 if (portp->state & ST_CMDING) {
1888 printf("STALLION: command already busy, cmd=%x!\n", (int) cmd);
1893 cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
1895 bcopy(arg, (void *) &(cp->args[0]), size);
1898 portp->argsize = size;
1903 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1904 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
1906 *bits |= portp->portbit;
1907 portp->state |= ST_CMDING;
1911 /*****************************************************************************/
1914 * Read data from shared memory. This assumes that the shared memory
1915 * is enabled and that interrupts are off. Basically we just empty out
1916 * the shared memory buffer into the tty buffer. Must be carefull to
1917 * handle the case where we fill up the tty buffer, but still have
1918 * more chars to unload.
1921 static void stli_rxprocess(stlibrd_t *brdp, stliport_t *portp)
1923 volatile cdkasyrq_t *rp;
1924 volatile char *shbuf;
1926 unsigned int head, tail, size;
1927 unsigned int len, stlen, i;
1931 printf("stli_rxprocess(brdp=%x,portp=%d)\n", (int) brdp, (int) portp);
1935 if ((tp->t_state & TS_ISOPEN) == 0) {
1936 stli_flush(portp, FREAD);
1939 if (tp->t_state & TS_TBLOCK)
1942 rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
1943 head = (unsigned int) rp->head;
1944 if (head != ((unsigned int) rp->head))
1945 head = (unsigned int) rp->head;
1946 tail = (unsigned int) rp->tail;
1947 size = portp->rxsize;
1952 len = size - (tail - head);
1953 stlen = size - tail;
1959 shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset);
1962 * If we can bypass normal LD processing then just copy direct
1963 * from board shared memory into the tty buffers.
1965 if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
1966 if (((tp->t_rawq.c_cc + len) >= TTYHOG) &&
1967 ((tp->t_cflag & CRTS_IFLOW) || (tp->t_iflag & IXOFF)) &&
1968 ((tp->t_state & TS_TBLOCK) == 0)) {
1969 ch = TTYHOG - tp->t_rawq.c_cc - 1;
1970 len = (ch > 0) ? ch : 0;
1971 stlen = MIN(stlen, len);
1972 tp->t_state |= TS_TBLOCK;
1974 i = b_to_q((char *) (shbuf + tail), stlen, &tp->t_rawq);
1979 i += b_to_q((char *) shbuf, len, &tp->t_rawq);
1984 rp = &((volatile cdkasy_t *)
1985 EBRDGETMEMPTR(brdp, portp->addr))->rxq;
1990 * Copy the data from board shared memory into a local
1991 * memory buffer. Then feed them from here into the LD.
1992 * We don't want to go into board shared memory one char
1993 * at a time, it is too slow...
1997 stlen = min(len, stlen);
1999 stli_rxtmpport = portp;
2000 stli_rxtmplen = len;
2001 bcopy((char *) (shbuf + tail), &stli_rxtmpbuf[0], stlen);
2004 bcopy((char *) shbuf, &stli_rxtmpbuf[stlen], len);
2006 for (i = 0; (i < stli_rxtmplen); i++) {
2007 ch = (unsigned char) stli_rxtmpbuf[i];
2008 (*linesw[tp->t_line].l_rint)(ch, tp);
2011 rp = &((volatile cdkasy_t *)
2012 EBRDGETMEMPTR(brdp, portp->addr))->rxq;
2013 if (stli_rxtmplen == 0) {
2014 head = (unsigned int) rp->head;
2015 if (head != ((unsigned int) rp->head))
2016 head = (unsigned int) rp->head;
2024 stli_rxtmpport = (stliport_t *) NULL;
2028 portp->state |= ST_RXING;
2031 /*****************************************************************************/
2034 * Set up and carry out any delayed commands. There is only a small set
2035 * of slave commands that can be done "off-level". So it is not too
2036 * difficult to deal with them as a special case here.
2039 static __inline void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp)
2043 if (portp->state & ST_DOSIGS) {
2044 if ((portp->state & ST_DOFLUSHTX) &&
2045 (portp->state & ST_DOFLUSHRX))
2046 cmd = A_SETSIGNALSF;
2047 else if (portp->state & ST_DOFLUSHTX)
2048 cmd = A_SETSIGNALSFTX;
2049 else if (portp->state & ST_DOFLUSHRX)
2050 cmd = A_SETSIGNALSFRX;
2053 portp->state &= ~(ST_DOFLUSHTX | ST_DOFLUSHRX | ST_DOSIGS);
2054 bcopy((void *) &portp->asig, (void *) &(cp->args[0]),
2058 portp->state |= ST_CMDING;
2059 } else if ((portp->state & ST_DOFLUSHTX) ||
2060 (portp->state & ST_DOFLUSHRX)) {
2061 cmd = ((portp->state & ST_DOFLUSHTX) ? FLUSHTX : 0);
2062 cmd |= ((portp->state & ST_DOFLUSHRX) ? FLUSHRX : 0);
2063 portp->state &= ~(ST_DOFLUSHTX | ST_DOFLUSHRX);
2064 bcopy((void *) &cmd, (void *) &(cp->args[0]), sizeof(int));
2067 portp->state |= ST_CMDING;
2071 /*****************************************************************************/
2074 * Host command service checking. This handles commands or messages
2075 * coming from the slave to the host. Must have board shared memory
2076 * enabled and interrupts off when called. Notice that by servicing the
2077 * read data last we don't need to change the shared memory pointer
2078 * during processing (which is a slow IO operation).
2079 * Return value indicates if this port is still awaiting actions from
2080 * the slave (like open, command, or even TX data being sent). If 0
2081 * then port is still busy, otherwise the port request bit flag is
2085 static __inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
2087 volatile cdkasy_t *ap;
2088 volatile cdkctrl_t *cp;
2090 unsigned long oldsigs;
2091 unsigned int head, tail;
2095 printf("stli_hostcmd(brdp=%x,portp=%x)\n", (int) brdp, (int) portp);
2098 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
2102 * Check if we are waiting for an open completion message.
2104 if (portp->state & ST_OPENING) {
2105 rc = (int) cp->openarg;
2106 if ((cp->open == 0) && (rc != 0)) {
2111 portp->state &= ~ST_OPENING;
2112 wakeup(&portp->state);
2117 * Check if we are waiting for a close completion message.
2119 if (portp->state & ST_CLOSING) {
2120 rc = (int) cp->closearg;
2121 if ((cp->close == 0) && (rc != 0)) {
2126 portp->state &= ~ST_CLOSING;
2127 wakeup(&portp->state);
2132 * Check if we are waiting for a command completion message. We may
2133 * need to copy out the command results associated with this command.
2135 if (portp->state & ST_CMDING) {
2137 if ((cp->cmd == 0) && (rc != 0)) {
2140 if (portp->argp != (void *) NULL) {
2141 bcopy((void *) &(cp->args[0]), portp->argp,
2143 portp->argp = (void *) NULL;
2147 portp->state &= ~ST_CMDING;
2148 stli_dodelaycmd(portp, cp);
2149 wakeup(&portp->state);
2154 * Check for any notification messages ready. This includes lots of
2155 * different types of events - RX chars ready, RX break received,
2156 * TX data low or empty in the slave, modem signals changed state.
2157 * Must be extremely carefull if we call to the LD, it may call
2158 * other routines of ours that will disable the memory...
2159 * Something else we need to be carefull of is race conditions on
2160 * marking the TX as empty...
2171 if (nt.signal & SG_DCD) {
2172 oldsigs = portp->sigs;
2173 portp->sigs = stli_mktiocm(nt.sigvalue);
2174 portp->state &= ~ST_GETSIGS;
2175 (*linesw[tp->t_line].l_modem)(tp,
2176 (portp->sigs & TIOCM_CD));
2179 if (nt.data & DT_RXBUSY) {
2181 stli_rxprocess(brdp, portp);
2183 if (nt.data & DT_RXBREAK) {
2184 (*linesw[tp->t_line].l_rint)(TTY_BI, tp);
2187 if (nt.data & DT_TXEMPTY) {
2188 ap = (volatile cdkasy_t *)
2189 EBRDGETMEMPTR(brdp, portp->addr);
2190 head = (unsigned int) ap->txq.head;
2191 tail = (unsigned int) ap->txq.tail;
2192 if (tail != ((unsigned int) ap->txq.tail))
2193 tail = (unsigned int) ap->txq.tail;
2194 head = (head >= tail) ? (head - tail) :
2195 portp->txsize - (tail - head);
2197 portp->state &= ~ST_TXBUSY;
2198 tp->t_state &= ~TS_BUSY;
2201 if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {
2202 (*linesw[tp->t_line].l_start)(tp);
2208 * It might seem odd that we are checking for more RX chars here.
2209 * But, we need to handle the case where the tty buffer was previously
2210 * filled, but we had more characters to pass up. The slave will not
2211 * send any more RX notify messages until the RX buffer has been emptied.
2212 * But it will leave the service bits on (since the buffer is not empty).
2213 * So from here we can try to process more RX chars.
2215 if ((!donerx) && (portp->state & ST_RXING)) {
2216 portp->state &= ~ST_RXING;
2217 stli_rxprocess(brdp, portp);
2220 return((portp->state & (ST_OPENING | ST_CLOSING | ST_CMDING |
2221 ST_TXBUSY | ST_RXING)) ? 0 : 1);
2224 /*****************************************************************************/
2227 * Service all ports on a particular board. Assumes that the boards
2228 * shared memory is enabled, and that the page pointer is pointed
2229 * at the cdk header structure.
2232 static __inline void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)
2235 unsigned char hostbits[(STL_MAXCHANS / 8) + 1];
2236 unsigned char slavebits[(STL_MAXCHANS / 8) + 1];
2237 unsigned char *slavep;
2238 int bitpos, bitat, bitsize;
2239 int channr, nrdevs, slavebitchange;
2241 bitsize = brdp->bitsize;
2242 nrdevs = brdp->nrdevs;
2245 * Check if slave wants any service. Basically we try to do as
2246 * little work as possible here. There are 2 levels of service
2247 * bits. So if there is nothing to do we bail early. We check
2248 * 8 service bits at a time in the inner loop, so we can bypass
2249 * the lot if none of them want service.
2251 bcopy((((unsigned char *) hdrp) + brdp->hostoffset), &hostbits[0],
2254 bzero(&slavebits[0], bitsize);
2257 for (bitpos = 0; (bitpos < bitsize); bitpos++) {
2258 if (hostbits[bitpos] == 0)
2260 channr = bitpos * 8;
2262 for (; (channr < nrdevs); channr++, bitat <<=1) {
2263 if (hostbits[bitpos] & bitat) {
2264 portp = brdp->ports[(channr - 1)];
2265 if (stli_hostcmd(brdp, portp)) {
2267 slavebits[bitpos] |= bitat;
2274 * If any of the ports are no longer busy then update them in the
2275 * slave request bits. We need to do this after, since a host port
2276 * service may initiate more slave requests...
2278 if (slavebitchange) {
2279 hdrp = (volatile cdkhdr_t *)
2280 EBRDGETMEMPTR(brdp, CDK_CDKADDR);
2281 slavep = ((unsigned char *) hdrp) + brdp->slaveoffset;
2282 for (bitpos = 0; (bitpos < bitsize); bitpos++) {
2283 if (slavebits[bitpos])
2284 slavep[bitpos] &= ~slavebits[bitpos];
2289 /*****************************************************************************/
2292 * Driver poll routine. This routine polls the boards in use and passes
2293 * messages back up to host when neccesary. This is actually very
2294 * CPU efficient, since we will always have the kernel poll clock, it
2295 * adds only a few cycles when idle (since board service can be
2296 * determined very easily), but when loaded generates no interrupts
2297 * (with their expensive associated context change).
2300 static void stli_poll(void *arg)
2302 volatile cdkhdr_t *hdrp;
2309 * Check each board and do any servicing required.
2311 for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {
2312 brdp = stli_brds[brdnr];
2313 if (brdp == (stlibrd_t *) NULL)
2315 if ((brdp->state & BST_STARTED) == 0)
2319 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
2321 stli_brdpoll(brdp, hdrp);
2326 timeout(stli_poll, 0, 1);
2329 /*****************************************************************************/
2332 * Translate the termios settings into the port setting structure of
2336 static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)
2339 printf("stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n", (int) portp,
2340 (int) pp, (int) tiosp);
2343 bzero(pp, sizeof(asyport_t));
2346 * Start of by setting the baud, char size, parity and stop bit info.
2348 if (tiosp->c_ispeed == 0)
2349 tiosp->c_ispeed = tiosp->c_ospeed;
2350 if ((tiosp->c_ospeed < 0) || (tiosp->c_ospeed > STL_MAXBAUD))
2351 tiosp->c_ospeed = STL_MAXBAUD;
2352 pp->baudout = tiosp->c_ospeed;
2353 pp->baudin = pp->baudout;
2355 switch (tiosp->c_cflag & CSIZE) {
2370 if (tiosp->c_cflag & CSTOPB)
2371 pp->stopbs = PT_STOP2;
2373 pp->stopbs = PT_STOP1;
2375 if (tiosp->c_cflag & PARENB) {
2376 if (tiosp->c_cflag & PARODD)
2377 pp->parity = PT_ODDPARITY;
2379 pp->parity = PT_EVENPARITY;
2381 pp->parity = PT_NOPARITY;
2384 if (tiosp->c_iflag & ISTRIP)
2385 pp->iflag |= FI_ISTRIP;
2388 * Set up any flow control options enabled.
2390 if (tiosp->c_iflag & IXON) {
2392 if (tiosp->c_iflag & IXANY)
2393 pp->flow |= F_IXANY;
2395 if (tiosp->c_iflag & IXOFF)
2396 pp->flow |= F_IXOFF;
2397 if (tiosp->c_cflag & CCTS_OFLOW)
2398 pp->flow |= F_CTSFLOW;
2399 if (tiosp->c_cflag & CRTS_IFLOW)
2400 pp->flow |= F_RTSFLOW;
2402 pp->startin = tiosp->c_cc[VSTART];
2403 pp->stopin = tiosp->c_cc[VSTOP];
2404 pp->startout = tiosp->c_cc[VSTART];
2405 pp->stopout = tiosp->c_cc[VSTOP];
2408 * Set up the RX char marking mask with those RX error types we must
2409 * catch. We can get the slave to help us out a little here, it will
2410 * ignore parity errors and breaks for us, and mark parity errors in
2413 if (tiosp->c_iflag & IGNPAR)
2414 pp->iflag |= FI_IGNRXERRS;
2415 if (tiosp->c_iflag & IGNBRK)
2416 pp->iflag |= FI_IGNBREAK;
2417 if (tiosp->c_iflag & (INPCK | PARMRK))
2418 pp->iflag |= FI_1MARKRXERRS;
2421 * Transfer any persistent flags into the asyport structure.
2423 pp->pflag = portp->pflag;
2426 /*****************************************************************************/
2429 * Construct a slave signals structure for setting the DTR and RTS
2430 * signals as specified.
2433 static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts)
2436 printf("stli_mkasysigs(sp=%x,dtr=%d,rts=%d)\n", (int) sp, dtr, rts);
2439 bzero(sp, sizeof(asysigs_t));
2441 sp->signal |= SG_DTR;
2442 sp->sigvalue |= ((dtr > 0) ? SG_DTR : 0);
2445 sp->signal |= SG_RTS;
2446 sp->sigvalue |= ((rts > 0) ? SG_RTS : 0);
2450 /*****************************************************************************/
2453 * Convert the signals returned from the slave into a local TIOCM type
2454 * signals value. We keep them localy in TIOCM format.
2457 static long stli_mktiocm(unsigned long sigvalue)
2462 printf("stli_mktiocm(sigvalue=%x)\n", (int) sigvalue);
2466 tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0);
2467 tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0);
2468 tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0);
2469 tiocm |= ((sigvalue & SG_DSR) ? TIOCM_DSR : 0);
2470 tiocm |= ((sigvalue & SG_DTR) ? TIOCM_DTR : 0);
2471 tiocm |= ((sigvalue & SG_RTS) ? TIOCM_RTS : 0);
2475 /*****************************************************************************/
2478 * Enable l_rint processing bypass mode if tty modes allow it.
2481 static void stli_ttyoptim(stliport_t *portp, struct termios *tiosp)
2486 if (((tiosp->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR)) == 0) &&
2487 (((tiosp->c_iflag & BRKINT) == 0) || (tiosp->c_iflag & IGNBRK)) &&
2488 (((tiosp->c_iflag & PARMRK) == 0) ||
2489 ((tiosp->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))) &&
2490 ((tiosp->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) ==0) &&
2491 (linesw[tp->t_line].l_rint == ttyinput))
2492 tp->t_state |= TS_CAN_BYPASS_L_RINT;
2494 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
2495 portp->hotchar = linesw[tp->t_line].l_hotchar;
2498 /*****************************************************************************/
2501 * All panels and ports actually attached have been worked out. All
2502 * we need to do here is set up the appropriate per port data structures.
2505 static int stli_initports(stlibrd_t *brdp)
2508 int i, panelnr, panelport;
2511 printf("stli_initports(brdp=%x)\n", (int) brdp);
2514 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
2515 portp = (stliport_t *) malloc(sizeof(stliport_t), M_TTYS,
2517 if (portp == (stliport_t *) NULL) {
2518 printf("STALLION: failed to allocate port structure\n");
2523 portp->brdnr = brdp->brdnr;
2524 portp->panelnr = panelnr;
2525 portp->initintios.c_ispeed = STL_DEFSPEED;
2526 portp->initintios.c_ospeed = STL_DEFSPEED;
2527 portp->initintios.c_cflag = STL_DEFCFLAG;
2528 portp->initintios.c_iflag = 0;
2529 portp->initintios.c_oflag = 0;
2530 portp->initintios.c_lflag = 0;
2531 bcopy(&ttydefchars[0], &portp->initintios.c_cc[0],
2532 sizeof(portp->initintios.c_cc));
2533 portp->initouttios = portp->initintios;
2534 portp->dtrwait = 3 * hz;
2537 if (panelport >= brdp->panels[panelnr]) {
2541 brdp->ports[i] = portp;
2547 /*****************************************************************************/
2550 * All the following routines are board specific hardware operations.
2553 static void stli_ecpinit(stlibrd_t *brdp)
2555 unsigned long memconf;
2558 printf("stli_ecpinit(brdp=%d)\n", (int) brdp);
2561 outb((brdp->iobase + ECP_ATCONFR), ECP_ATSTOP);
2563 outb((brdp->iobase + ECP_ATCONFR), ECP_ATDISABLE);
2566 memconf = (brdp->paddr & ECP_ATADDRMASK) >> ECP_ATADDRSHFT;
2567 outb((brdp->iobase + ECP_ATMEMAR), memconf);
2570 /*****************************************************************************/
2572 static void stli_ecpenable(stlibrd_t *brdp)
2575 printf("stli_ecpenable(brdp=%x)\n", (int) brdp);
2577 outb((brdp->iobase + ECP_ATCONFR), ECP_ATENABLE);
2580 /*****************************************************************************/
2582 static void stli_ecpdisable(stlibrd_t *brdp)
2585 printf("stli_ecpdisable(brdp=%x)\n", (int) brdp);
2587 outb((brdp->iobase + ECP_ATCONFR), ECP_ATDISABLE);
2590 /*****************************************************************************/
2592 static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2598 printf("stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
2602 if (offset > brdp->memsize) {
2603 printf("STALLION: shared memory pointer=%x out of range at "
2604 "line=%d(%d), brd=%d\n", (int) offset, line,
2605 __LINE__, brdp->brdnr);
2609 ptr = (char *) brdp->vaddr + (offset % ECP_ATPAGESIZE);
2610 val = (unsigned char) (offset / ECP_ATPAGESIZE);
2612 outb((brdp->iobase + ECP_ATMEMPR), val);
2616 /*****************************************************************************/
2618 static void stli_ecpreset(stlibrd_t *brdp)
2621 printf("stli_ecpreset(brdp=%x)\n", (int) brdp);
2624 outb((brdp->iobase + ECP_ATCONFR), ECP_ATSTOP);
2626 outb((brdp->iobase + ECP_ATCONFR), ECP_ATDISABLE);
2630 /*****************************************************************************/
2632 static void stli_ecpintr(stlibrd_t *brdp)
2635 printf("stli_ecpintr(brdp=%x)\n", (int) brdp);
2637 outb(brdp->iobase, 0x1);
2640 /*****************************************************************************/
2643 * The following set of functions act on ECP EISA boards.
2646 static void stli_ecpeiinit(stlibrd_t *brdp)
2648 unsigned long memconf;
2651 printf("stli_ecpeiinit(brdp=%x)\n", (int) brdp);
2654 outb((brdp->iobase + ECP_EIBRDENAB), 0x1);
2655 outb((brdp->iobase + ECP_EICONFR), ECP_EISTOP);
2657 outb((brdp->iobase + ECP_EICONFR), ECP_EIDISABLE);
2660 memconf = (brdp->paddr & ECP_EIADDRMASKL) >> ECP_EIADDRSHFTL;
2661 outb((brdp->iobase + ECP_EIMEMARL), memconf);
2662 memconf = (brdp->paddr & ECP_EIADDRMASKH) >> ECP_EIADDRSHFTH;
2663 outb((brdp->iobase + ECP_EIMEMARH), memconf);
2666 /*****************************************************************************/
2668 static void stli_ecpeienable(stlibrd_t *brdp)
2670 outb((brdp->iobase + ECP_EICONFR), ECP_EIENABLE);
2673 /*****************************************************************************/
2675 static void stli_ecpeidisable(stlibrd_t *brdp)
2677 outb((brdp->iobase + ECP_EICONFR), ECP_EIDISABLE);
2680 /*****************************************************************************/
2682 static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2688 printf("stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n",
2689 (int) brdp, (int) offset, line);
2692 if (offset > brdp->memsize) {
2693 printf("STALLION: shared memory pointer=%x out of range at "
2694 "line=%d(%d), brd=%d\n", (int) offset, line,
2695 __LINE__, brdp->brdnr);
2699 ptr = (char *) brdp->vaddr + (offset % ECP_EIPAGESIZE);
2700 if (offset < ECP_EIPAGESIZE)
2703 val = ECP_EIENABLE | 0x40;
2705 outb((brdp->iobase + ECP_EICONFR), val);
2709 /*****************************************************************************/
2711 static void stli_ecpeireset(stlibrd_t *brdp)
2713 outb((brdp->iobase + ECP_EICONFR), ECP_EISTOP);
2715 outb((brdp->iobase + ECP_EICONFR), ECP_EIDISABLE);
2719 /*****************************************************************************/
2722 * The following set of functions act on ECP MCA boards.
2725 static void stli_ecpmcenable(stlibrd_t *brdp)
2727 outb((brdp->iobase + ECP_MCCONFR), ECP_MCENABLE);
2730 /*****************************************************************************/
2732 static void stli_ecpmcdisable(stlibrd_t *brdp)
2734 outb((brdp->iobase + ECP_MCCONFR), ECP_MCDISABLE);
2737 /*****************************************************************************/
2739 static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2744 if (offset > brdp->memsize) {
2745 printf("STALLION: shared memory pointer=%x out of range at "
2746 "line=%d(%d), brd=%d\n", (int) offset, line,
2747 __LINE__, brdp->brdnr);
2751 ptr = (char *) brdp->vaddr + (offset % ECP_MCPAGESIZE);
2752 val = ((unsigned char) (offset / ECP_MCPAGESIZE)) | ECP_MCENABLE;
2754 outb((brdp->iobase + ECP_MCCONFR), val);
2758 /*****************************************************************************/
2760 static void stli_ecpmcreset(stlibrd_t *brdp)
2762 outb((brdp->iobase + ECP_MCCONFR), ECP_MCSTOP);
2764 outb((brdp->iobase + ECP_MCCONFR), ECP_MCDISABLE);
2768 /*****************************************************************************/
2771 * The following routines act on ONboards.
2774 static void stli_onbinit(stlibrd_t *brdp)
2776 unsigned long memconf;
2780 printf("stli_onbinit(brdp=%d)\n", (int) brdp);
2783 outb((brdp->iobase + ONB_ATCONFR), ONB_ATSTOP);
2785 outb((brdp->iobase + ONB_ATCONFR), ONB_ATDISABLE);
2786 for (i = 0; (i < 1000); i++)
2789 memconf = (brdp->paddr & ONB_ATADDRMASK) >> ONB_ATADDRSHFT;
2790 outb((brdp->iobase + ONB_ATMEMAR), memconf);
2791 outb(brdp->iobase, 0x1);
2795 /*****************************************************************************/
2797 static void stli_onbenable(stlibrd_t *brdp)
2800 printf("stli_onbenable(brdp=%x)\n", (int) brdp);
2802 outb((brdp->iobase + ONB_ATCONFR), (ONB_ATENABLE | brdp->confbits));
2805 /*****************************************************************************/
2807 static void stli_onbdisable(stlibrd_t *brdp)
2810 printf("stli_onbdisable(brdp=%x)\n", (int) brdp);
2812 outb((brdp->iobase + ONB_ATCONFR), (ONB_ATDISABLE | brdp->confbits));
2815 /*****************************************************************************/
2817 static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2822 printf("stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
2826 if (offset > brdp->memsize) {
2827 printf("STALLION: shared memory pointer=%x out of range at "
2828 "line=%d(%d), brd=%d\n", (int) offset, line,
2829 __LINE__, brdp->brdnr);
2832 ptr = (char *) brdp->vaddr + (offset % ONB_ATPAGESIZE);
2837 /*****************************************************************************/
2839 static void stli_onbreset(stlibrd_t *brdp)
2844 printf("stli_onbreset(brdp=%x)\n", (int) brdp);
2847 outb((brdp->iobase + ONB_ATCONFR), ONB_ATSTOP);
2849 outb((brdp->iobase + ONB_ATCONFR), ONB_ATDISABLE);
2850 for (i = 0; (i < 1000); i++)
2854 /*****************************************************************************/
2857 * The following routines act on ONboard EISA.
2860 static void stli_onbeinit(stlibrd_t *brdp)
2862 unsigned long memconf;
2866 printf("stli_onbeinit(brdp=%d)\n", (int) brdp);
2869 outb((brdp->iobase + ONB_EIBRDENAB), 0x1);
2870 outb((brdp->iobase + ONB_EICONFR), ONB_EISTOP);
2872 outb((brdp->iobase + ONB_EICONFR), ONB_EIDISABLE);
2873 for (i = 0; (i < 1000); i++)
2876 memconf = (brdp->paddr & ONB_EIADDRMASKL) >> ONB_EIADDRSHFTL;
2877 outb((brdp->iobase + ONB_EIMEMARL), memconf);
2878 memconf = (brdp->paddr & ONB_EIADDRMASKH) >> ONB_EIADDRSHFTH;
2879 outb((brdp->iobase + ONB_EIMEMARH), memconf);
2880 outb(brdp->iobase, 0x1);
2884 /*****************************************************************************/
2886 static void stli_onbeenable(stlibrd_t *brdp)
2889 printf("stli_onbeenable(brdp=%x)\n", (int) brdp);
2891 outb((brdp->iobase + ONB_EICONFR), ONB_EIENABLE);
2894 /*****************************************************************************/
2896 static void stli_onbedisable(stlibrd_t *brdp)
2899 printf("stli_onbedisable(brdp=%x)\n", (int) brdp);
2901 outb((brdp->iobase + ONB_EICONFR), ONB_EIDISABLE);
2904 /*****************************************************************************/
2906 static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2912 printf("stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n", (int) brdp,
2913 (int) offset, line);
2916 if (offset > brdp->memsize) {
2917 printf("STALLION: shared memory pointer=%x out of range at "
2918 "line=%d(%d), brd=%d\n", (int) offset, line,
2919 __LINE__, brdp->brdnr);
2923 ptr = (char *) brdp->vaddr + (offset % ONB_EIPAGESIZE);
2924 if (offset < ONB_EIPAGESIZE)
2927 val = ONB_EIENABLE | 0x40;
2929 outb((brdp->iobase + ONB_EICONFR), val);
2933 /*****************************************************************************/
2935 static void stli_onbereset(stlibrd_t *brdp)
2940 printf("stli_onbereset(brdp=%x)\n", (int) brdp);
2943 outb((brdp->iobase + ONB_EICONFR), ONB_EISTOP);
2945 outb((brdp->iobase + ONB_EICONFR), ONB_EIDISABLE);
2946 for (i = 0; (i < 1000); i++)
2950 /*****************************************************************************/
2953 * The following routines act on Brumby boards.
2956 static void stli_bbyinit(stlibrd_t *brdp)
2961 printf("stli_bbyinit(brdp=%d)\n", (int) brdp);
2964 outb((brdp->iobase + BBY_ATCONFR), BBY_ATSTOP);
2966 outb((brdp->iobase + BBY_ATCONFR), 0);
2967 for (i = 0; (i < 1000); i++)
2969 outb(brdp->iobase, 0x1);
2973 /*****************************************************************************/
2975 static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2981 printf("stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
2985 if (offset > brdp->memsize) {
2986 printf("STALLION: shared memory pointer=%x out of range at "
2987 "line=%d(%d), brd=%d\n", (int) offset, line,
2988 __LINE__, brdp->brdnr);
2992 ptr = (char *) brdp->vaddr + (offset % BBY_PAGESIZE);
2993 val = (unsigned char) (offset / BBY_PAGESIZE);
2995 outb((brdp->iobase + BBY_ATCONFR), val);
2999 /*****************************************************************************/
3001 static void stli_bbyreset(stlibrd_t *brdp)
3006 printf("stli_bbyreset(brdp=%x)\n", (int) brdp);
3009 outb((brdp->iobase + BBY_ATCONFR), BBY_ATSTOP);
3011 outb((brdp->iobase + BBY_ATCONFR), 0);
3012 for (i = 0; (i < 1000); i++)
3016 /*****************************************************************************/
3019 * The following routines act on original old Stallion boards.
3022 static void stli_stalinit(stlibrd_t *brdp)
3027 printf("stli_stalinit(brdp=%d)\n", (int) brdp);
3030 outb(brdp->iobase, 0x1);
3031 for (i = 0; (i < 1000); i++)
3035 /*****************************************************************************/
3037 static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
3042 printf("stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
3046 if (offset > brdp->memsize) {
3047 printf("STALLION: shared memory pointer=%x out of range at "
3048 "line=%d(%d), brd=%d\n", (int) offset, line,
3049 __LINE__, brdp->brdnr);
3052 ptr = (char *) brdp->vaddr + (offset % STAL_PAGESIZE);
3057 /*****************************************************************************/
3059 static void stli_stalreset(stlibrd_t *brdp)
3061 volatile unsigned long *vecp;
3065 printf("stli_stalreset(brdp=%x)\n", (int) brdp);
3068 vecp = (volatile unsigned long *) ((char *) brdp->vaddr + 0x30);
3070 outb(brdp->iobase, 0);
3071 for (i = 0; (i < 1000); i++)
3075 /*****************************************************************************/
3078 * Try to find an ECP board and initialize it. This handles only ECP
3082 static int stli_initecp(stlibrd_t *brdp)
3086 unsigned int status, nxtid;
3090 printf("stli_initecp(brdp=%x)\n", (int) brdp);
3094 * Do a basic sanity check on the IO and memory addresses.
3096 if ((brdp->iobase == 0) || (brdp->paddr == 0))
3100 * Based on the specific board type setup the common vars to access
3101 * and enable shared memory. Set all board specific information now
3104 switch (brdp->brdtype) {
3106 brdp->memsize = ECP_MEMSIZE;
3107 brdp->pagesize = ECP_ATPAGESIZE;
3108 brdp->init = stli_ecpinit;
3109 brdp->enable = stli_ecpenable;
3110 brdp->reenable = stli_ecpenable;
3111 brdp->disable = stli_ecpdisable;
3112 brdp->getmemptr = stli_ecpgetmemptr;
3113 brdp->intr = stli_ecpintr;
3114 brdp->reset = stli_ecpreset;
3118 brdp->memsize = ECP_MEMSIZE;
3119 brdp->pagesize = ECP_EIPAGESIZE;
3120 brdp->init = stli_ecpeiinit;
3121 brdp->enable = stli_ecpeienable;
3122 brdp->reenable = stli_ecpeienable;
3123 brdp->disable = stli_ecpeidisable;
3124 brdp->getmemptr = stli_ecpeigetmemptr;
3125 brdp->intr = stli_ecpintr;
3126 brdp->reset = stli_ecpeireset;
3130 brdp->memsize = ECP_MEMSIZE;
3131 brdp->pagesize = ECP_MCPAGESIZE;
3133 brdp->enable = stli_ecpmcenable;
3134 brdp->reenable = stli_ecpmcenable;
3135 brdp->disable = stli_ecpmcdisable;
3136 brdp->getmemptr = stli_ecpmcgetmemptr;
3137 brdp->intr = stli_ecpintr;
3138 brdp->reset = stli_ecpmcreset;
3146 * The per-board operations structure is all setup, so now lets go
3147 * and get the board operational. Firstly initialize board configuration
3153 * Now that all specific code is set up, enable the shared memory and
3154 * look for the a signature area that will tell us exactly what board
3155 * this is, and what it is connected to it.
3158 sigsp = (cdkecpsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
3159 bcopy(sigsp, &sig, sizeof(cdkecpsig_t));
3163 printf("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",
3164 __file__, __LINE__, (int) sig.magic, sig.romver,
3165 sig.panelid[0], (int) sig.panelid[1], (int) sig.panelid[2],
3166 (int) sig.panelid[3], (int) sig.panelid[4],
3167 (int) sig.panelid[5], (int) sig.panelid[6],
3168 (int) sig.panelid[7]);
3171 if (sig.magic != ECP_MAGIC)
3175 * Scan through the signature looking at the panels connected to the
3176 * board. Calculate the total number of ports as we go.
3178 for (panelnr = 0, nxtid = 0; (panelnr < STL_MAXPANELS); panelnr++) {
3179 status = sig.panelid[nxtid];
3180 if ((status & ECH_PNLIDMASK) != nxtid)
3182 brdp->panelids[panelnr] = status;
3183 if (status & ECH_PNL16PORT) {
3184 brdp->panels[panelnr] = 16;
3185 brdp->nrports += 16;
3188 brdp->panels[panelnr] = 8;
3195 brdp->state |= BST_FOUND;
3199 /*****************************************************************************/
3202 * Try to find an ONboard, Brumby or Stallion board and initialize it.
3203 * This handles only these board types.
3206 static int stli_initonb(stlibrd_t *brdp)
3213 printf("stli_initonb(brdp=%x)\n", (int) brdp);
3217 * Do a basic sanity check on the IO and memory addresses.
3219 if ((brdp->iobase == 0) || (brdp->paddr == 0))
3223 * Based on the specific board type setup the common vars to access
3224 * and enable shared memory. Set all board specific information now
3227 switch (brdp->brdtype) {
3231 case BRD_ONBOARD2_32:
3233 brdp->memsize = ONB_MEMSIZE;
3234 brdp->pagesize = ONB_ATPAGESIZE;
3235 brdp->init = stli_onbinit;
3236 brdp->enable = stli_onbenable;
3237 brdp->reenable = stli_onbenable;
3238 brdp->disable = stli_onbdisable;
3239 brdp->getmemptr = stli_onbgetmemptr;
3240 brdp->intr = stli_ecpintr;
3241 brdp->reset = stli_onbreset;
3242 brdp->confbits = (brdp->paddr > 0x100000) ? ONB_HIMEMENAB : 0;
3246 brdp->memsize = ONB_EIMEMSIZE;
3247 brdp->pagesize = ONB_EIPAGESIZE;
3248 brdp->init = stli_onbeinit;
3249 brdp->enable = stli_onbeenable;
3250 brdp->reenable = stli_onbeenable;
3251 brdp->disable = stli_onbedisable;
3252 brdp->getmemptr = stli_onbegetmemptr;
3253 brdp->intr = stli_ecpintr;
3254 brdp->reset = stli_onbereset;
3260 brdp->memsize = BBY_MEMSIZE;
3261 brdp->pagesize = BBY_PAGESIZE;
3262 brdp->init = stli_bbyinit;
3263 brdp->enable = NULL;
3264 brdp->reenable = NULL;
3265 brdp->disable = NULL;
3266 brdp->getmemptr = stli_bbygetmemptr;
3267 brdp->intr = stli_ecpintr;
3268 brdp->reset = stli_bbyreset;
3272 brdp->memsize = STAL_MEMSIZE;
3273 brdp->pagesize = STAL_PAGESIZE;
3274 brdp->init = stli_stalinit;
3275 brdp->enable = NULL;
3276 brdp->reenable = NULL;
3277 brdp->disable = NULL;
3278 brdp->getmemptr = stli_stalgetmemptr;
3279 brdp->intr = stli_ecpintr;
3280 brdp->reset = stli_stalreset;
3288 * The per-board operations structure is all setup, so now lets go
3289 * and get the board operational. Firstly initialize board configuration
3295 * Now that all specific code is set up, enable the shared memory and
3296 * look for the a signature area that will tell us exactly what board
3297 * this is, and how many ports.
3300 sigsp = (cdkonbsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
3301 bcopy(sigsp, &sig, sizeof(cdkonbsig_t));
3305 printf("%s(%d): sig-> magic=%x:%x:%x:%x romver=%x amask=%x:%x:%x\n",
3306 __file__, __LINE__, sig.magic0, sig.magic1, sig.magic2,
3307 sig.magic3, sig.romver, sig.amask0, sig.amask1, sig.amask2);
3310 if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) ||
3311 (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))
3315 * Scan through the signature alive mask and calculate how many ports
3316 * there are on this board.
3322 for (i = 0; (i < 16); i++) {
3323 if (((sig.amask0 << i) & 0x8000) == 0)
3328 brdp->panels[0] = brdp->nrports;
3330 brdp->state |= BST_FOUND;
3334 /*****************************************************************************/
3337 * Start up a running board. This routine is only called after the
3338 * code has been down loaded to the board and is operational. It will
3339 * read in the memory map, and get the show on the road...
3342 static int stli_startbrd(stlibrd_t *brdp)
3344 volatile cdkhdr_t *hdrp;
3345 volatile cdkmem_t *memp;
3346 volatile cdkasy_t *ap;
3348 int portnr, nrdevs, i, rc, x;
3351 printf("stli_startbrd(brdp=%x)\n", (int) brdp);
3358 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
3359 nrdevs = hdrp->nrdevs;
3362 printf("%s(%d): CDK version %d.%d.%d --> nrdevs=%d memp=%x hostp=%x "
3363 "slavep=%x\n", __file__, __LINE__, hdrp->ver_release,
3364 hdrp->ver_modification, hdrp->ver_fix, nrdevs,
3365 (int) hdrp->memp, (int) hdrp->hostp, (int) hdrp->slavep);
3368 if (nrdevs < (brdp->nrports + 1)) {
3369 printf("STALLION: slave failed to allocate memory for all "
3370 "devices, devices=%d\n", nrdevs);
3371 brdp->nrports = nrdevs - 1;
3373 brdp->nrdevs = nrdevs;
3374 brdp->hostoffset = hdrp->hostp - CDK_CDKADDR;
3375 brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR;
3376 brdp->bitsize = (nrdevs + 7) / 8;
3377 memp = (volatile cdkmem_t *) (void *) (uintptr_t) hdrp->memp;
3378 if (((uintptr_t) (void *) memp) > brdp->memsize) {
3379 printf("STALLION: corrupted shared memory region?\n");
3381 goto stli_donestartup;
3383 memp = (volatile cdkmem_t *) EBRDGETMEMPTR(brdp,
3384 (uintptr_t) (void *) memp);
3385 if (memp->dtype != TYP_ASYNCTRL) {
3386 printf("STALLION: no slave control device found\n");
3388 goto stli_donestartup;
3393 * Cycle through memory allocation of each port. We are guaranteed to
3394 * have all ports inside the first page of slave window, so no need to
3395 * change pages while reading memory map.
3397 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) {
3398 if (memp->dtype != TYP_ASYNC)
3400 portp = brdp->ports[portnr];
3401 if (portp == (stliport_t *) NULL)
3404 portp->addr = memp->offset;
3405 portp->reqidx = (unsigned char) (i * 8 / nrdevs);
3406 portp->reqbit = (unsigned char) (0x1 << portp->reqidx);
3407 portp->portidx = (unsigned char) (i / 8);
3408 portp->portbit = (unsigned char) (0x1 << (i % 8));
3411 hdrp->slavereq = 0xff;
3414 * For each port setup a local copy of the RX and TX buffer offsets
3415 * and sizes. We do this separate from the above, because we need to
3416 * move the shared memory page...
3418 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) {
3419 portp = brdp->ports[portnr];
3420 if (portp == (stliport_t *) NULL)
3422 if (portp->addr == 0)
3424 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
3425 if (ap != (volatile cdkasy_t *) NULL) {
3426 portp->rxsize = ap->rxq.size;
3427 portp->txsize = ap->txq.size;
3428 portp->rxoffset = ap->rxq.offset;
3429 portp->txoffset = ap->txq.offset;
3438 brdp->state |= BST_STARTED;
3440 if (stli_doingtimeout == 0) {
3441 timeout(stli_poll, 0, 1);
3442 stli_doingtimeout++;
3448 /*****************************************************************************/
3451 * Probe and initialize the specified board.
3454 static int stli_brdinit(stlibrd_t *brdp)
3457 printf("stli_brdinit(brdp=%x)\n", (int) brdp);
3460 stli_brds[brdp->brdnr] = brdp;
3462 switch (brdp->brdtype) {
3472 case BRD_ONBOARD2_32:
3484 printf("STALLION: %s board type not supported in this driver\n",
3485 stli_brdnames[brdp->brdtype]);
3488 printf("STALLION: unit=%d is unknown board type=%d\n",
3489 brdp->brdnr, brdp->brdtype);
3495 /*****************************************************************************/
3498 * Finish off the remaining initialization for a board.
3501 static int stli_brdattach(stlibrd_t *brdp)
3504 printf("stli_brdattach(brdp=%x)\n", (int) brdp);
3508 if ((brdp->state & BST_FOUND) == 0) {
3509 printf("STALLION: %s board not found, unit=%d io=%x mem=%x\n",
3510 stli_brdnames[brdp->brdtype], brdp->brdnr,
3511 brdp->iobase, (int) brdp->paddr);
3516 stli_initports(brdp);
3517 printf("stli%d: %s (driver version %s), unit=%d nrpanels=%d "
3518 "nrports=%d\n", brdp->unitid, stli_brdnames[brdp->brdtype],
3519 stli_drvversion, brdp->brdnr, brdp->nrpanels, brdp->nrports);
3523 /*****************************************************************************/
3526 * Check for possible shared memory sharing between boards.
3527 * FIX: need to start this optimization somewhere...
3531 static int stli_chksharemem()
3533 stlibrd_t *brdp, *nxtbrdp;
3537 printf("stli_chksharemem()\n");
3541 * All found boards are initialized. Now for a little optimization, if
3542 * no boards are sharing the "shared memory" regions then we can just
3543 * leave them all enabled. This is in fact the usual case.
3546 if (stli_nrbrds > 1) {
3547 for (i = 0; (i < stli_nrbrds); i++) {
3548 brdp = stli_brds[i];
3549 if (brdp == (stlibrd_t *) NULL)
3551 for (j = i + 1; (j < stli_nrbrds); j++) {
3552 nxtbrdp = stli_brds[j];
3553 if (nxtbrdp == (stlibrd_t *) NULL)
3555 if ((brdp->paddr >= nxtbrdp->paddr) &&
3556 (brdp->paddr <= (nxtbrdp->paddr +
3557 nxtbrdp->memsize - 1))) {
3565 if (stli_shared == 0) {
3566 for (i = 0; (i < stli_nrbrds); i++) {
3567 brdp = stli_brds[i];
3568 if (brdp == (stlibrd_t *) NULL)
3570 if (brdp->state & BST_FOUND) {
3572 brdp->enable = NULL;
3573 brdp->disable = NULL;
3582 /*****************************************************************************/
3585 * Return the board stats structure to user app.
3588 static int stli_getbrdstats(caddr_t data)
3594 printf("stli_getbrdstats(data=%p)\n", (void *) data);
3597 stli_brdstats = *((combrd_t *) data);
3598 if (stli_brdstats.brd >= STL_MAXBRDS)
3600 brdp = stli_brds[stli_brdstats.brd];
3601 if (brdp == (stlibrd_t *) NULL)
3604 bzero(&stli_brdstats, sizeof(combrd_t));
3605 stli_brdstats.brd = brdp->brdnr;
3606 stli_brdstats.type = brdp->brdtype;
3607 stli_brdstats.hwid = 0;
3608 stli_brdstats.state = brdp->state;
3609 stli_brdstats.ioaddr = brdp->iobase;
3610 stli_brdstats.memaddr = brdp->paddr;
3611 stli_brdstats.nrpanels = brdp->nrpanels;
3612 stli_brdstats.nrports = brdp->nrports;
3613 for (i = 0; (i < brdp->nrpanels); i++) {
3614 stli_brdstats.panels[i].panel = i;
3615 stli_brdstats.panels[i].hwid = brdp->panelids[i];
3616 stli_brdstats.panels[i].nrports = brdp->panels[i];
3619 *((combrd_t *) data) = stli_brdstats;
3623 /*****************************************************************************/
3626 * Resolve the referenced port number into a port struct pointer.
3629 static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)
3634 if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
3635 return((stliport_t *) NULL);
3636 brdp = stli_brds[brdnr];
3637 if (brdp == (stlibrd_t *) NULL)
3638 return((stliport_t *) NULL);
3639 for (i = 0; (i < panelnr); i++)
3640 portnr += brdp->panels[i];
3641 if ((portnr < 0) || (portnr >= brdp->nrports))
3642 return((stliport_t *) NULL);
3643 return(brdp->ports[portnr]);
3646 /*****************************************************************************/
3649 * Return the port stats structure to user app. A NULL port struct
3650 * pointer passed in means that we need to find out from the app
3651 * what port to get stats for (used through board control device).
3654 static int stli_getportstats(stliport_t *portp, caddr_t data)
3659 if (portp == (stliport_t *) NULL) {
3660 stli_comstats = *((comstats_t *) data);
3661 portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
3662 stli_comstats.port);
3663 if (portp == (stliport_t *) NULL)
3667 brdp = stli_brds[portp->brdnr];
3668 if (brdp == (stlibrd_t *) NULL)
3671 if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, &stli_cdkstats,
3672 sizeof(asystats_t), 1)) < 0)
3675 stli_comstats.brd = portp->brdnr;
3676 stli_comstats.panel = portp->panelnr;
3677 stli_comstats.port = portp->portnr;
3678 stli_comstats.state = portp->state;
3679 /*stli_comstats.flags = portp->flags;*/
3680 stli_comstats.ttystate = portp->tty.t_state;
3681 stli_comstats.cflags = portp->tty.t_cflag;
3682 stli_comstats.iflags = portp->tty.t_iflag;
3683 stli_comstats.oflags = portp->tty.t_oflag;
3684 stli_comstats.lflags = portp->tty.t_lflag;
3686 stli_comstats.txtotal = stli_cdkstats.txchars;
3687 stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover;
3688 stli_comstats.txbuffered = stli_cdkstats.txringq;
3689 stli_comstats.rxbuffered = stli_cdkstats.rxringq;
3690 stli_comstats.rxoverrun = stli_cdkstats.overruns;
3691 stli_comstats.rxparity = stli_cdkstats.parity;
3692 stli_comstats.rxframing = stli_cdkstats.framing;
3693 stli_comstats.rxlost = stli_cdkstats.ringover + portp->rxlost;
3694 stli_comstats.rxbreaks = stli_cdkstats.rxbreaks;
3695 stli_comstats.txbreaks = stli_cdkstats.txbreaks;
3696 stli_comstats.txxon = stli_cdkstats.txstart;
3697 stli_comstats.txxoff = stli_cdkstats.txstop;
3698 stli_comstats.rxxon = stli_cdkstats.rxstart;
3699 stli_comstats.rxxoff = stli_cdkstats.rxstop;
3700 stli_comstats.rxrtsoff = stli_cdkstats.rtscnt / 2;
3701 stli_comstats.rxrtson = stli_cdkstats.rtscnt - stli_comstats.rxrtsoff;
3702 stli_comstats.modem = stli_cdkstats.dcdcnt;
3703 stli_comstats.hwid = stli_cdkstats.hwid;
3704 stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);
3706 *((comstats_t *) data) = stli_comstats;;
3710 /*****************************************************************************/
3713 * Clear the port stats structure. We also return it zeroed out...
3716 static int stli_clrportstats(stliport_t *portp, caddr_t data)
3721 if (portp == (stliport_t *) NULL) {
3722 stli_comstats = *((comstats_t *) data);
3723 portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
3724 stli_comstats.port);
3725 if (portp == (stliport_t *) NULL)
3729 brdp = stli_brds[portp->brdnr];
3730 if (brdp == (stlibrd_t *) NULL)
3733 if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, 0, 0, 0)) < 0)
3737 bzero(&stli_comstats, sizeof(comstats_t));
3738 stli_comstats.brd = portp->brdnr;
3739 stli_comstats.panel = portp->panelnr;
3740 stli_comstats.port = portp->portnr;
3742 *((comstats_t *) data) = stli_comstats;;
3746 /*****************************************************************************/
3749 * Code to handle an "staliomem" read and write operations. This device
3750 * is the contents of the board shared memory. It is used for down
3751 * loading the slave image (and debugging :-)
3754 STATIC int stli_memrw(dev_t dev, struct uio *uiop, int flag)
3758 int brdnr, size, n, error, x;
3761 printf("stli_memrw(dev=%x,uiop=%x,flag=%x)\n", (int) dev,
3765 brdnr = minor(dev) & 0x7;
3766 brdp = stli_brds[brdnr];
3767 if (brdp == (stlibrd_t *) NULL)
3769 if (brdp->state == 0)
3772 if (uiop->uio_offset >= brdp->memsize)
3776 size = brdp->memsize - uiop->uio_offset;
3781 memptr = (void *) EBRDGETMEMPTR(brdp, uiop->uio_offset);
3782 n = MIN(size, (brdp->pagesize -
3783 (((unsigned long) uiop->uio_offset) % brdp->pagesize)));
3784 error = uiomove(memptr, n, uiop);
3785 if ((uiop->uio_resid == 0) || error)
3794 /*****************************************************************************/
3797 * The "staliomem" device is also required to do some special operations
3798 * on the board. We need to be able to send an interrupt to the board,
3799 * reset it, and start/stop it.
3802 static int stli_memioctl(dev_t dev, unsigned long cmd, caddr_t data, int flag,
3809 printf("stli_memioctl(dev=%s,cmd=%lx,data=%p,flag=%x)\n",
3810 devtoname(dev), cmd, (void *) data, flag);
3813 brdnr = minor(dev) & 0x7;
3814 brdp = stli_brds[brdnr];
3815 if (brdp == (stlibrd_t *) NULL)
3817 if (brdp->state == 0)
3827 rc = stli_startbrd(brdp);
3830 brdp->state &= ~BST_STARTED;
3833 brdp->state &= ~BST_STARTED;
3835 if (stli_shared == 0) {
3836 if (brdp->reenable != NULL)
3837 (* brdp->reenable)(brdp);
3840 case COM_GETPORTSTATS:
3841 rc = stli_getportstats((stliport_t *) NULL, data);
3843 case COM_CLRPORTSTATS:
3844 rc = stli_clrportstats((stliport_t *) NULL, data);
3846 case COM_GETBRDSTATS:
3847 rc = stli_getbrdstats(data);
3857 /*****************************************************************************/