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