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