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