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