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