File:  [DragonFly] / src / sys / dev / serial / stli / istallion.c
Revision 1.11: download - view: text, annotated - select for diffs
Wed May 19 22:52:50 2004 UTC (10 years, 4 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
Device layer rollup commit.

* cdevsw_add() is now required.  cdevsw_add() and cdevsw_remove() may specify
  a mask/match indicating the range of supported minor numbers.  Multiple
  cdevsw_add()'s using the same major number, but distinctly different
  ranges, may be issued.  All devices that failed to call cdevsw_add() before
  now do.

* cdevsw_remove() now automatically marks all devices within its supported
  range as being destroyed.

* vnode->v_rdev is no longer resolved when the vnode is created.  Instead,
  only v_udev (a newly added field) is resolved.  v_rdev is resolved when
  the vnode is opened and cleared on the last close.

* A great deal of code was making rather dubious assumptions with regards
  to the validity of devices associated with vnodes, primarily due to
  the persistence of a device structure due to being indexed by (major, minor)
  instead of by (cdevsw, major, minor).  In particular, if you run a program
  which connects to a USB device and then you pull the USB device and plug
  it back in, the vnode subsystem will continue to believe that the device
  is open when, in fact, it isn't (because it was destroyed and recreated).

  In particular, note that all the VFS mount procedures now check devices
  via v_udev instead of v_rdev prior to calling VOP_OPEN(), since v_rdev
  is NULL prior to the first open.

* The disk layer's device interaction has been rewritten.  The disk layer
  (i.e. the slice and disklabel management layer) no longer overloads
  its data onto the device structure representing the underlying physical
  disk.  Instead, the disk layer uses the new cdevsw_add() functionality
  to register its own cdevsw using the underlying device's major number,
  and simply does NOT register the underlying device's cdevsw.  No
  confusion is created because the device hash is now based on
  (cdevsw,major,minor) rather then (major,minor).

  NOTE: This also means that underlying raw disk devices may use the entire
  device minor number instead of having to reserve the bits used by the disk
  layer, and also means that can we (theoretically) stack a fully
  disklabel-supported 'disk' on top of any block device.

* The new reference counting scheme prevents this by associating a device
  with a cdevsw and disconnecting the device from its cdevsw when the cdevsw
  is removed.  Additionally, all udev2dev() lookups run through the cdevsw
  mask/match and only successfully find devices still associated with an
  active cdevsw.

* Major work on MFS:  MFS no longer shortcuts vnode and device creation.  It
  now creates a real vnode and a real device and implements real open and
  close VOPs.  Additionally, due to the disk layer changes, MFS is no longer
  limited to 255 mounts.  The new limit is 16 million.  Since MFS creates a
  real device node, mount_mfs will now create a real /dev/mfs<PID> device
  that can be read from userland (e.g. so you can dump an MFS filesystem).

* BUF AND DEVICE STRATEGY changes.  The struct buf contains a b_dev field.
  In order to properly handle stacked devices we now require that the b_dev
  field be initialized before the device strategy routine is called.  This
  required some additional work in various VFS implementations.  To enforce
  this requirement, biodone() now sets b_dev to NODEV.  The new disk layer
  will adjust b_dev before forwarding a request to the actual physical
  device.

* A bug in the ISO CD boot sequence which resulted in a panic has been fixed.

Testing by: lots of people, but David Rhodus found the most aggregious bugs.

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