ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / char / rio / riotty.c
1 /*
2 ** -----------------------------------------------------------------------------
3 **
4 **  Perle Specialix driver for Linux
5 **  Ported from existing RIO Driver for SCO sources.
6  *
7  *  (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8  *
9  *      This program is free software; you can redistribute it and/or modify
10  *      it under the terms of the GNU General Public License as published by
11  *      the Free Software Foundation; either version 2 of the License, or
12  *      (at your option) any later version.
13  *
14  *      This program is distributed in the hope that it will be useful,
15  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *      GNU General Public License for more details.
18  *
19  *      You should have received a copy of the GNU General Public License
20  *      along with this program; if not, write to the Free Software
21  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 **
23 **      Module          : riotty.c
24 **      SID             : 1.3
25 **      Last Modified   : 11/6/98 10:33:47
26 **      Retrieved       : 11/6/98 10:33:50
27 **
28 **  ident @(#)riotty.c  1.3
29 **
30 ** -----------------------------------------------------------------------------
31 */
32 #ifdef SCCS_LABELS
33 static char *_riotty_c_sccs_ = "@(#)riotty.c    1.3";
34 #endif
35
36
37 #define __EXPLICIT_DEF_H__
38
39 #include <linux/module.h>
40 #include <linux/slab.h>
41 #include <linux/errno.h>
42 #include <linux/tty.h>
43 #include <asm/io.h>
44 #include <asm/system.h>
45 #include <asm/string.h>
46 #include <asm/semaphore.h>
47 #include <asm/uaccess.h>
48
49 #include <linux/termios.h>
50
51 #include <linux/serial.h>
52
53 #include <linux/generic_serial.h>
54
55
56 #include "linux_compat.h"
57 #include "rio_linux.h"
58 #include "typdef.h"
59 #include "pkt.h"
60 #include "daemon.h"
61 #include "rio.h"
62 #include "riospace.h"
63 #include "top.h"
64 #include "cmdpkt.h"
65 #include "map.h"
66 #include "riotypes.h"
67 #include "rup.h"
68 #include "port.h"
69 #include "riodrvr.h"
70 #include "rioinfo.h"
71 #include "func.h"
72 #include "errors.h"
73 #include "pci.h"
74
75 #include "parmmap.h"
76 #include "unixrup.h"
77 #include "board.h"
78 #include "host.h"
79 #include "error.h"
80 #include "phb.h"
81 #include "link.h"
82 #include "cmdblk.h"
83 #include "route.h"
84 #include "control.h"
85 #include "cirrus.h"
86 #include "rioioctl.h"
87 #include "param.h"
88 #include "list.h"
89 #include "sam.h"
90
91 #if 0
92 static void ttyseth_pv(struct Port *, struct ttystatics *, 
93                                 struct termios *sg, int);
94 #endif
95
96 static void RIOClearUp(struct Port *PortP);
97 int RIOShortCommand(struct rio_info *p, struct Port *PortP, 
98                            int command, int len, int arg);
99
100
101 extern int      conv_vb[];      /* now defined in ttymgr.c */
102 extern int      conv_bv[];      /* now defined in ttymgr.c */
103  
104 /*
105 ** 16.09.1998 ARG - Fix to build riotty.k.o for Modular Kernel Support
106 **
107 ** ep.def.h is necessary for Modular Kernel Support
108 ** DO NOT place any kernel 'extern's after this line
109 ** or this source file will not build riotty.k.o
110 */
111 #ifdef uLYNX
112 #include <ep.def.h>
113 #endif
114
115 #ifdef NEED_THIS2
116 static struct old_sgttyb 
117 default_sg = 
118
119         B19200, B19200,                         /* input and output speed */ 
120         'H' - '@',                                      /* erase char */ 
121         -1,                                                     /* 2nd erase char */ 
122         'U' - '@',                                      /* kill char */ 
123         ECHO | CRMOD,                           /* mode */ 
124         'C' - '@',                                      /* interrupt character */ 
125         '\\' - '@',                                     /* quit char */ 
126         'Q' - '@',                                      /* start char */
127         'S' - '@',                                      /* stop char */ 
128         'D' - '@',                                      /* EOF */
129         -1,                                                     /* brk */
130         (LCRTBS | LCRTERA | LCRTKIL | LCTLECH), /* local mode word */ 
131         'Z' - '@',                                      /* process stop */
132         'Y' - '@',                                      /* delayed stop */
133         'R' - '@',                                      /* reprint line */ 
134         'O' - '@',                                      /* flush output */
135         'W' - '@',                                      /* word erase */
136         'V' - '@'                                       /* literal next char */
137 };
138 #endif
139
140
141 extern struct rio_info *p;
142
143
144 int
145 riotopen(struct tty_struct * tty, struct file * filp)
146 {
147         register uint SysPort;
148         int Modem;
149         int repeat_this = 250;
150         struct Port *PortP;              /* pointer to the port structure */
151         unsigned long flags;
152         int retval = 0;
153
154         func_enter ();
155
156         /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close
157            is going to oops.
158         */
159         tty->driver_data = NULL;
160         
161         SysPort = rio_minor(tty);
162         Modem   = rio_ismodem(tty);
163
164         if ( p->RIOFailed ) {
165                 rio_dprintk (RIO_DEBUG_TTY, "System initialisation failed\n");
166                 pseterr(ENXIO);
167                 func_exit ();
168                 return -ENXIO;
169         }
170
171         rio_dprintk (RIO_DEBUG_TTY, "port open SysPort %d (%s) (mapped:%d)\n",
172                SysPort,  Modem ? "Modem" : "tty",
173                                    p->RIOPortp[SysPort]->Mapped);
174
175         /*
176         ** Validate that we have received a legitimate request.
177         ** Currently, just check that we are opening a port on
178         ** a host card that actually exists, and that the port
179         ** has been mapped onto a host.
180         */
181         if (SysPort >= RIO_PORTS) {     /* out of range ? */
182                 rio_dprintk (RIO_DEBUG_TTY, "Illegal port number %d\n",SysPort);
183                 pseterr(ENXIO);
184                 func_exit();
185                 return -ENXIO;
186         }
187
188         /*
189         ** Grab pointer to the port stucture
190         */
191         PortP = p->RIOPortp[SysPort];   /* Get control struc */
192         rio_dprintk (RIO_DEBUG_TTY, "PortP: %p\n", PortP);
193         if ( !PortP->Mapped ) { /* we aren't mapped yet! */
194                 /*
195                 ** The system doesn't know which RTA this port
196                 ** corresponds to.
197                 */
198                 rio_dprintk (RIO_DEBUG_TTY, "port not mapped into system\n");
199                 func_exit ();
200                 pseterr(ENXIO);
201                 return -ENXIO;
202         }
203
204         tty->driver_data = PortP;
205
206         PortP->gs.tty = tty;
207         PortP->gs.count++;
208
209         rio_dprintk (RIO_DEBUG_TTY, "%d bytes in tx buffer\n",
210                                    PortP->gs.xmit_cnt);
211
212         retval = gs_init_port (&PortP->gs);
213         if (retval) {
214                 PortP->gs.count--;
215                 return -ENXIO;
216         }
217         /*
218         ** If the host hasn't been booted yet, then 
219         ** fail
220         */
221         if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) {
222                 rio_dprintk (RIO_DEBUG_TTY, "Host not running\n");
223                 pseterr(ENXIO);
224                 func_exit ();
225                 return -ENXIO;
226         }
227
228         /*
229         ** If the RTA has not booted yet and the user has choosen to block
230         ** until the RTA is present then we must spin here waiting for
231         ** the RTA to boot.
232         */
233 #if 0
234         if (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
235                 if (PortP->WaitUntilBooted) {
236                         rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot\n");
237                         do {
238                                 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
239                                         rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
240                                         func_exit ();
241                                         return -EINTR;
242                                 }
243                                 if (repeat_this -- <= 0) {
244                                         rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
245                                         RIOPreemptiveCmd(p, PortP, FCLOSE ); 
246                                         pseterr(EINTR);
247                                         func_exit ();
248                                         return -EIO;
249                                 }
250                         } while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED));
251                         rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
252                 } else {
253                         rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
254                         pseterr(ENXIO);
255                         func_exit ();
256                         return 0;
257                 }
258         }
259 #else
260         /* I find the above code a bit hairy. I find the below code
261            easier to read and shorter. Now, if it works too that would
262            be great... -- REW 
263         */
264         rio_dprintk (RIO_DEBUG_TTY, "Checking if RTA has booted... \n");
265         while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
266           if (!PortP->WaitUntilBooted) {
267             rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
268             func_exit ();
269             return -ENXIO;
270           }
271
272           /* Under Linux you'd normally use a wait instead of this
273              busy-waiting. I'll stick with the old implementation for
274              now. --REW 
275           */
276           if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
277             rio_dprintk (RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n");
278             func_exit ();
279             return -EINTR;
280           }
281           if (repeat_this -- <= 0) {
282             rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
283             func_exit ();
284             return -EIO;
285           }
286         }
287         rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
288 #endif
289 #if 0
290         tp =  PortP->TtyP;              /* get tty struct */
291 #endif
292         rio_spin_lock_irqsave(&PortP->portSem, flags);
293         if ( p->RIOHalted ) {
294                 goto bombout;
295         }
296 #if 0
297         retval = gs_init_port(&PortP->gs);
298         if (retval){
299                 func_exit ();
300                 return retval;
301         }
302 #endif
303
304         /*
305         ** If the port is in the final throws of being closed,
306         ** we should wait here (politely), waiting
307         ** for it to finish, so that it doesn't close us!
308         */
309         while ( (PortP->State & RIO_CLOSING) && !p->RIOHalted ) {
310                 rio_dprintk (RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n");
311                 if (repeat_this -- <= 0) {
312                         rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
313                         RIOPreemptiveCmd(p, PortP, FCLOSE ); 
314                         retval = -EINTR;
315                         goto bombout;
316                 }
317                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
318                 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
319                         rio_spin_lock_irqsave(&PortP->portSem, flags); 
320                         retval = -EINTR;
321                         goto bombout;
322                 }
323                 rio_spin_lock_irqsave(&PortP->portSem, flags); 
324         }
325
326         if ( !PortP->Mapped ) {
327                 rio_dprintk (RIO_DEBUG_TTY, "Port unmapped while closing!\n");
328                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
329                 retval = -ENXIO;
330                 func_exit ();
331                 return retval;
332         }
333
334         if ( p->RIOHalted ) {
335                 goto bombout;
336         }
337
338 /*
339 ** 15.10.1998 ARG - ESIL 0761 part fix
340 ** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,
341 ** we need to make sure that the flags are clear when the port is opened.
342 */
343         /* Uh? Suppose I turn these on and then another process opens
344            the port again? The flags get cleared! Not good. -- REW */
345         if ( !(PortP->State & (RIO_LOPEN | RIO_MOPEN)) ) {
346                 PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);
347         }
348
349         if (!(PortP->firstOpen)) {      /* First time ? */
350                 rio_dprintk (RIO_DEBUG_TTY, "First open for this port\n");
351         
352
353                 PortP->firstOpen++;
354                 PortP->CookMode = 0; /* XXX RIOCookMode(tp); */
355                 PortP->InUse = NOT_INUSE;
356
357                 /* Tentative fix for bug PR27. Didn't work. */
358                 /* PortP->gs.xmit_cnt = 0; */
359
360                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
361 #ifdef NEED_THIS
362                 ttyseth(PortP, tp, (struct old_sgttyb *)&default_sg);
363 #endif
364
365                 /* Someone explain to me why this delay/config is
366                    here. If I read the docs correctly the "open"
367                    command piggybacks the parameters immediately. 
368                    -- REW */
369                 RIOParam(PortP,OPEN,Modem,OK_TO_SLEEP);         /* Open the port */
370 #if 0
371                 /* This delay of 1 second was annoying. I removed it. -- REW */
372                 RIODelay(PortP, HUNDRED_MS*10);
373                 RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);       /* Config the port */
374 #endif
375                 rio_spin_lock_irqsave(&PortP->portSem, flags);
376
377                 /*
378                 ** wait for the port to be not closed.
379                 */
380                 while ( !(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted ) {
381                         rio_dprintk (RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n",PortP->PortState);
382 /*
383 ** 15.10.1998 ARG - ESIL 0759
384 ** (Part) fix for port being trashed when opened whilst RTA "disconnected"
385 ** Take out the limited wait - now wait for ever or until user
386 ** bangs us out.
387 **
388                         if (repeat_this -- <= 0) {
389                                 rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish timed out.\n"));
390                                 RIOPreemptiveCmd(p, PortP, FCLOSE ); 
391                                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
392                                 return -EINTR;
393                         }
394 **
395 */
396                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
397                         if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
398                                 rio_dprintk (RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n");
399                                 RIOPreemptiveCmd(p, PortP, FCLOSE );
400                                 func_exit ();
401                                 return -EINTR;
402                         }
403                         rio_spin_lock_irqsave(&PortP->portSem, flags);
404                 }
405
406                 if ( p->RIOHalted ) {
407                   retval = -EIO;
408 bombout:
409                   /*                    RIOClearUp( PortP ); */
410                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
411                         return retval;
412                 }
413                 rio_dprintk (RIO_DEBUG_TTY, "PORT_ISOPEN found\n");
414         }
415
416 #ifdef MODEM_SUPPORT 
417         if (Modem) {
418                 rio_dprintk (RIO_DEBUG_TTY, "Modem - test for carrier\n");
419                 /*
420                 ** ACTION
421                 ** insert test for carrier here. -- ???
422                 ** I already see that test here. What's the deal? -- REW
423                 */
424                 if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))
425                 {
426                         rio_dprintk (RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
427                         /*
428                         tp->tm.c_state |= CARR_ON;
429                         wakeup((caddr_t) &tp->tm.c_canq);
430                         */
431                         PortP->State |= RIO_CARR_ON;
432                         wake_up_interruptible (&PortP->gs.open_wait);
433                 }
434                 else /* no carrier - wait for DCD */
435                 {
436                   /*
437                         while (!(PortP->gs.tty->termios->c_state & CARR_ON) && 
438                                !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )
439                   */
440                         while (!(PortP->State & RIO_CARR_ON) && 
441                                !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) {
442
443                                 rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n",SysPort);
444                                 /*
445                                 PortP->gs.tty->termios->c_state |= WOPEN;
446                                 */
447                                 PortP->State |= RIO_WOPEN;
448                                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
449                                 if (RIODelay (PortP, HUNDRED_MS) == RIO_FAIL)
450 #if 0
451                                 if ( sleep((caddr_t)&tp->tm.c_canqo, TTIPRI|PCATCH))
452 #endif
453                                 {
454                                         /*
455                                         ** ACTION: verify that this is a good thing
456                                         ** to do here. -- ???
457                                         ** I think it's OK. -- REW
458                                         */
459                                         rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n",
460                                                SysPort);
461                                         RIOPreemptiveCmd( p, PortP, FCLOSE );
462                                         /*
463                                         tp->tm.c_state &= ~WOPEN;
464                                         */
465                                         PortP->State &= ~RIO_WOPEN;
466                                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
467                                         func_exit ();
468                                         return -EINTR;
469                                 }
470                         }
471                         PortP->State &= ~RIO_WOPEN;
472                 }
473                 if ( p->RIOHalted )
474                         goto bombout;
475                 rio_dprintk (RIO_DEBUG_TTY, "Setting RIO_MOPEN\n");
476                 PortP->State |= RIO_MOPEN;
477         }
478         else
479 #endif
480         {
481                 /*
482                 ** ACTION
483                 ** Direct line open - force carrier (will probably mean
484                 ** that sleeping Modem line fubar)
485                 */
486                 PortP->State |= RIO_LOPEN;
487         }
488
489         if ( p->RIOHalted ) {
490                 goto bombout;
491         }
492
493         rio_dprintk (RIO_DEBUG_TTY, "high level open done\n");
494
495 #ifdef STATS
496         PortP->Stat.OpenCnt++;
497 #endif
498         /*
499         ** Count opens for port statistics reporting
500         */
501         if (PortP->statsGather)
502                 PortP->opens++;
503
504         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
505         rio_dprintk (RIO_DEBUG_TTY, "Returning from open\n");
506         func_exit ();
507         return 0;
508 }
509
510 /*
511 ** RIOClose the port.
512 ** The operating system thinks that this is last close for the device.
513 ** As there are two interfaces to the port (Modem and tty), we need to
514 ** check that both are closed before we close the device.
515 */ 
516 int
517 riotclose(void  *ptr)
518 {
519 #if 0
520         register uint SysPort = dev;
521         struct ttystatics *tp;          /* pointer to our ttystruct */
522 #endif
523         struct Port *PortP =ptr;        /* pointer to the port structure */
524         int deleted = 0;
525         int     try = -1; /* Disable the timeouts by setting them to -1 */
526         int     repeat_this = -1; /* Congrats to those having 15 years of 
527                                      uptime! (You get to break the driver.) */
528         long end_time;
529         struct tty_struct * tty;
530         unsigned long flags;
531         int Modem;
532         int rv =0;
533         
534         rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
535
536         /* PortP = p->RIOPortp[SysPort]; */
537         rio_dprintk (RIO_DEBUG_TTY, "Port is at address 0x%x\n",(int)PortP);
538         /* tp = PortP->TtyP;*/                  /* Get tty */
539         tty = PortP->gs.tty;
540         rio_dprintk (RIO_DEBUG_TTY, "TTY is at address 0x%x\n",(int)tty);
541
542         if (PortP->gs.closing_wait) 
543                 end_time = jiffies + PortP->gs.closing_wait;
544         else 
545                 end_time = jiffies + MAX_SCHEDULE_TIMEOUT;
546
547         Modem = rio_ismodem(tty);
548 #if 0
549         /* What F.CKING cache? Even then, a higly idle multiprocessor,
550            system with large caches this won't work . Better find out when 
551            this doesn't work asap, and fix the cause.  -- REW */
552         
553         RIODelay(PortP, HUNDRED_MS*10); /* To flush the cache */
554 #endif
555         rio_spin_lock_irqsave(&PortP->portSem, flags);
556
557         /*
558         ** Setting this flag will make any process trying to open
559         ** this port block until we are complete closing it.
560         */
561         PortP->State |= RIO_CLOSING;
562
563         if ( (PortP->State & RIO_DELETED) ) {
564                 rio_dprintk (RIO_DEBUG_TTY, "Close on deleted RTA\n");
565                 deleted = 1;
566         }
567         
568         if ( p->RIOHalted ) {
569                 RIOClearUp( PortP );
570                 rv = -EIO;
571                 goto close_end;
572         }
573
574         rio_dprintk (RIO_DEBUG_TTY, "Clear bits\n");
575         /*
576         ** clear the open bits for this device
577         */
578         PortP->State &= (Modem ? ~RIO_MOPEN : ~RIO_LOPEN);
579         PortP->State &= ~RIO_CARR_ON;
580         PortP->ModemState &= ~MSVR1_CD;
581         /*
582         ** If the device was open as both a Modem and a tty line
583         ** then we need to wimp out here, as the port has not really
584         ** been finally closed (gee, whizz!) The test here uses the
585         ** bit for the OTHER mode of operation, to see if THAT is
586         ** still active!
587         */
588         if ( (PortP->State & (RIO_LOPEN|RIO_MOPEN)) ) {
589                 /*
590                 ** The port is still open for the other task -
591                 ** return, pretending that we are still active.
592                 */
593                 rio_dprintk (RIO_DEBUG_TTY, "Channel %d still open !\n",PortP->PortNum);
594                 PortP->State &= ~RIO_CLOSING;
595                 if (PortP->firstOpen)
596                         PortP->firstOpen--;
597                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
598                 return -EIO;
599         }
600
601         rio_dprintk (RIO_DEBUG_TTY, "Closing down - everything must go!\n");
602
603         PortP->State &= ~RIO_DYNOROD;
604
605         /*
606         ** This is where we wait for the port
607         ** to drain down before closing. Bye-bye....
608         ** (We never meant to do this)
609         */
610         rio_dprintk (RIO_DEBUG_TTY, "Timeout 1 starts\n");
611
612         if (!deleted)
613         while ( (PortP->InUse != NOT_INUSE) && !p->RIOHalted && 
614                 (PortP->TxBufferIn != PortP->TxBufferOut) ) {
615                 cprintf("Need to flush the ttyport\n");
616                 if (repeat_this -- <= 0) {
617                         rv = -EINTR;
618                         rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
619                         RIOPreemptiveCmd(p, PortP, FCLOSE ); 
620                         goto close_end;
621                 }
622                 rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
623                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
624                 if (RIODelay_ni(PortP, HUNDRED_MS*10) == RIO_FAIL) {
625                         rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
626                         rv = -EINTR;
627                         rio_spin_lock_irqsave(&PortP->portSem, flags);
628                         goto close_end;
629                 }
630                 rio_spin_lock_irqsave(&PortP->portSem, flags);
631         }
632
633         PortP->TxBufferIn = PortP->TxBufferOut = 0;
634         repeat_this = 0xff;
635
636         PortP->InUse = 0;
637         if ( (PortP->State & (RIO_LOPEN|RIO_MOPEN)) ) {
638                 /*
639                 ** The port has been re-opened for the other task -
640                 ** return, pretending that we are still active.
641                 */
642                 rio_dprintk (RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum);
643                 PortP->State &= ~RIO_CLOSING;
644                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
645                 if (PortP->firstOpen)
646                         PortP->firstOpen--;
647                 return -EIO;
648         }
649
650         if ( p->RIOHalted ) {
651                 RIOClearUp( PortP );
652                 goto close_end;
653         }
654
655         
656
657         /* Can't call RIOShortCommand with the port locked. */
658         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
659
660         if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
661           RIOPreemptiveCmd(p, PortP,FCLOSE);
662           goto close_end;
663         }
664
665         if (!deleted)
666           while (try && (PortP->PortState & PORT_ISOPEN)) {
667                 try--;
668                 if (time_after (jiffies, end_time)) {
669                   rio_dprintk (RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n" );
670                   RIOPreemptiveCmd(p, PortP,FCLOSE);
671                   break;
672                 }
673                 rio_dprintk (RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", 
674                                            PortP->PortState & PORT_ISOPEN);
675
676                 if ( p->RIOHalted ) {
677                         RIOClearUp( PortP );
678                         goto close_end;
679                 }
680                 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
681                         rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
682                         RIOPreemptiveCmd(p, PortP,FCLOSE);
683                         break;
684                 }
685         }
686         rio_spin_lock_irqsave(&PortP->portSem, flags);
687         rio_dprintk (RIO_DEBUG_TTY, "Close: try was %d on completion\n", try );
688  
689         /* RIOPreemptiveCmd(p, PortP, FCLOSE); */
690
691 /*
692 ** 15.10.1998 ARG - ESIL 0761 part fix
693 ** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,** we need to make sure that the flags are clear when the port is opened.
694 */
695         PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);
696
697
698 #ifdef STATS
699         PortP->Stat.CloseCnt++;
700 #endif
701         /*
702         ** Count opens for port statistics reporting
703         */
704         if (PortP->statsGather)
705                 PortP->closes++;
706
707 close_end:
708         /* XXX: Why would a "DELETED" flag be reset here? I'd have
709            thought that a "deleted" flag means that the port was
710            permanently gone, but here we can make it reappear by it
711            being in close during the "deletion".
712         */
713         PortP->State &= ~(RIO_CLOSING|RIO_DELETED);
714         if (PortP->firstOpen)
715                 PortP->firstOpen--;
716         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
717         rio_dprintk (RIO_DEBUG_TTY, "Return from close\n");
718         return rv;
719 }
720
721
722 /*
723 ** decide if we need to use the line discipline.
724 ** This routine can return one of three values:
725 ** COOK_RAW if no processing has to be done by the line discipline or the card
726 ** COOK_WELL if the line discipline must be used to do the processing
727 ** COOK_MEDIUM if the card can do all the processing necessary.
728 */
729 int
730 RIOCookMode(struct ttystatics *tp)
731 {
732         /*
733         ** We can't handle tm.c_mstate != 0 on SCO
734         ** We can't handle mapping
735         ** We can't handle non-ttwrite line disc.
736         ** We can't handle lflag XCASE
737         ** We can handle oflag OPOST & (OCRNL, ONLCR, TAB3)
738         */
739
740 #ifdef CHECK
741         CheckTtyP( tp );
742 #endif
743         if (!(tp->tm.c_oflag & OPOST))  /* No post processing */
744                 return COOK_RAW;        /* Raw mode o/p */
745
746         if ( tp->tm.c_lflag & XCASE )
747                 return COOK_WELL;       /* Use line disc */
748
749         if (tp->tm.c_oflag & ~(OPOST | ONLCR | OCRNL | TAB3 ) )
750                 return COOK_WELL;       /* Use line disc for strange modes */
751
752         if ( tp->tm.c_oflag == OPOST )  /* If only OPOST is set, do RAW */
753                 return COOK_RAW;
754
755         /*
756         ** So, we need to output process!
757         */
758         return COOK_MEDIUM;
759 }
760
761
762 static void
763 RIOClearUp(PortP)
764 struct Port *PortP;
765 {
766         rio_dprintk (RIO_DEBUG_TTY, "RIOHalted set\n");
767         PortP->Config = 0;        /* Direct semaphore */
768         PortP->PortState = 0;
769         PortP->firstOpen = 0;
770         PortP->FlushCmdBodge = 0;
771         PortP->ModemState = PortP->CookMode = 0;
772         PortP->Mapped = 0;
773         PortP->WflushFlag = 0;
774         PortP->MagicFlags       = 0;
775         PortP->RxDataStart = 0;
776         PortP->TxBufferIn = 0;
777         PortP->TxBufferOut = 0;
778 }
779
780 /*
781 ** Put a command onto a port.
782 ** The PortPointer, command, length and arg are passed.
783 ** The len is the length *inclusive* of the command byte,
784 ** and so for a command that takes no data, len==1.
785 ** The arg is a single byte, and is only used if len==2.
786 ** Other values of len aren't allowed, and will cause
787 ** a panic.
788 */
789 int RIOShortCommand(struct rio_info *p, struct Port *PortP,
790                 int command, int len, int arg)
791 {
792         PKT *PacketP;
793         int             retries = 20; /* at 10 per second -> 2 seconds */
794         unsigned long flags;
795
796         rio_dprintk (RIO_DEBUG_TTY, "entering shortcommand.\n");
797 #ifdef CHECK
798         CheckPortP( PortP );
799         if ( len < 1 || len > 2 )
800                 cprintf(("STUPID LENGTH %d\n",len));
801 #endif
802
803         if ( PortP->State & RIO_DELETED ) {
804                 rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
805                 return RIO_FAIL;
806         }
807         rio_spin_lock_irqsave(&PortP->portSem, flags);
808
809         /*
810         ** If the port is in use for pre-emptive command, then wait for it to 
811         ** be free again.
812         */
813         while ( (PortP->InUse != NOT_INUSE) && !p->RIOHalted ) {
814                 rio_dprintk (RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", 
815                                            retries);
816                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
817                 if (retries-- <= 0) {
818                         return RIO_FAIL;
819                 }
820                 if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) {
821                         return RIO_FAIL;
822                 }
823                 rio_spin_lock_irqsave(&PortP->portSem, flags);
824         }
825         if ( PortP->State & RIO_DELETED ) {
826                 rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
827                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
828                 return RIO_FAIL;
829         }
830
831         while ( !can_add_transmit(&PacketP,PortP) && !p->RIOHalted ) {
832                 rio_dprintk (RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries);
833                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
834                 if (retries-- <= 0) {
835                   rio_dprintk (RIO_DEBUG_TTY, "out of tries. Failing\n");
836                         return RIO_FAIL;
837                 }
838                 if ( RIODelay_ni(PortP, HUNDRED_MS)==RIO_FAIL ) {
839                         return RIO_FAIL;
840                 }
841                 rio_spin_lock_irqsave(&PortP->portSem, flags);
842         }
843
844         if ( p->RIOHalted ) {
845                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
846                 return RIO_FAIL;
847         }
848
849         /*
850         ** set the command byte and the argument byte
851         */
852         WBYTE(PacketP->data[0] , command);
853
854         if ( len==2 )
855                 WBYTE(PacketP->data[1] , arg);
856
857         /*
858         ** set the length of the packet and set the command bit.
859         */
860         WBYTE(PacketP->len , PKT_CMD_BIT | len);
861
862         add_transmit(PortP);
863         /*
864         ** Count characters transmitted for port statistics reporting
865         */
866         if (PortP->statsGather)
867                 PortP->txchars += len;
868
869         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
870         return p->RIOHalted ? RIO_FAIL : ~RIO_FAIL;
871 }
872
873
874 #if 0
875 /*
876 ** This is an ioctl interface. This is the twentieth century. You know what
877 ** its all about.
878 */
879 int
880 riotioctl(struct rio_info *p, struct tty_struct *tty, int cmd, caddr_t arg)
881 {
882         register struct         Port *PortP;
883         register struct         ttystatics *tp;
884         int                                     current;
885         int                                     ParamSemIncremented = 0;
886         int                                     old_oflag, old_cflag, old_iflag, changed, oldcook;
887         int                                     i;
888         unsigned char           sio_regs[5];            /* Here be magic */
889         short                           vpix_cflag;
890         short                           divisor;
891         int                                     baud;
892         uint                            SysPort = rio_minor(tty);
893         int                             Modem = rio_ismodem(tty);
894         int                                     ioctl_processed;
895
896         rio_dprintk (RIO_DEBUG_TTY, "port ioctl SysPort %d command 0x%x argument 0x%x %s\n",
897                         SysPort, cmd, arg, Modem?"Modem":"tty") ;
898
899         if ( SysPort >= RIO_PORTS ) {
900                 rio_dprintk (RIO_DEBUG_TTY, "Bad port number %d\n", SysPort);
901                 return -ENXIO;
902         }
903
904         PortP = p->RIOPortp[SysPort];
905         tp = PortP->TtyP;
906
907         rio_spin_lock_irqsave(&PortP->portSem, flags);
908
909 #ifdef STATS
910         PortP->Stat.IoctlCnt++;
911 #endif
912
913         if ( PortP->State & RIO_DELETED ) {
914                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
915                 return -EIO;
916         }
917
918
919         if ( p->RIOHalted ) {
920                 RIOClearUp( PortP );
921                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
922                 return -EIO;
923         }
924
925         /*
926         ** Count ioctls for port statistics reporting
927         */
928         if (PortP->statsGather)
929                 PortP->ioctls++;
930
931         /*
932         ** Specialix RIO Ioctl calls
933         */
934         switch (cmd) {
935
936                 case TCRIOTRIAD:
937                         if ( arg )
938                                 PortP->State |= RIO_TRIAD_MODE;
939                         else
940                                 PortP->State &= ~RIO_TRIAD_MODE;
941                         /*
942                         ** Normally, when istrip is set on a port, a config is
943                         ** sent to the RTA instructing the CD1400 to do the
944                         ** stripping. In TRIAD mode, the interrupt receive routine
945                         ** must do the stripping instead, since it has to detect
946                         ** an 8 bit function key sequence. If istrip is set with
947                         ** TRIAD mode on(off), and 8 bit data is being read by
948                         ** the port, the user then turns TRIAD mode off(on), the RTA
949                         ** must be reconfigured (not) to do the stripping.
950                         ** Hence we call RIOParam here.
951                         */
952                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
953                         RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);       
954                         return 0;
955
956                 case TCRIOTSTATE:
957                         rio_dprintk (RIO_DEBUG_TTY, "tbusy/tstop monitoring %sabled\n",
958                                 arg ? "en" : "dis");
959                         /* MonitorTstate = 0 ;*/
960                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
961                         RIOParam(PortP, CONFIG, Modem, OK_TO_SLEEP);
962                         return 0;
963
964                 case TCRIOSTATE: /* current state of Modem input pins */
965                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE\n");
966                         if (RIOPreemptiveCmd(p, PortP, MGET) == RIO_FAIL)
967                                 rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE command failed\n");
968                         PortP->State |= RIO_BUSY;
969                         current = PortP->ModemState;
970                         if ( copyout((caddr_t)&current, (int)arg,
971                                                         sizeof(current))==COPYFAIL ) {
972                                 rio_dprintk (RIO_DEBUG_TTY, "Copyout failed\n");
973                                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
974                                 pseterr(EFAULT);
975                         }
976                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
977                         return 0;
978
979                 case TCRIOMBIS:         /* Set modem lines */
980                 case TCRIOMBIC:         /* Clear modem lines */
981                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIS/TCRIOMBIC\n");
982                         if (cmd == TCRIOMBIS) {
983                                 uint            state;
984                                 state = (uint)arg;
985                                 PortP->ModemState |= (ushort)state;
986                                 PortP->ModemLines = (ulong) arg;
987                                 if (RIOPreemptiveCmd(p, PortP, MBIS) == RIO_FAIL)
988                                         rio_dprintk (RIO_DEBUG_TTY, 
989                                          "TCRIOMBIS command failed\n");
990                         }
991                         else {
992                                 uint            state;
993
994                                 state = (uint)arg;
995                                 PortP->ModemState &= ~(ushort)state;
996                                 PortP->ModemLines = (ulong) arg;
997                                 if (RIOPreemptiveCmd(p, PortP, MBIC) == RIO_FAIL)
998                                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIC command failed\n");
999                         }
1000                         PortP->State |= RIO_BUSY;
1001                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1002                         return 0;
1003
1004                 case TCRIOXPON: /* set Xprint ON string */
1005                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPON\n");
1006                         if ( copyin((int)arg, (caddr_t)PortP->Xprint.XpOn,
1007                                                 MAX_XP_CTRL_LEN)==COPYFAIL ) {
1008                                 rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
1009                                 PortP->Xprint.XpOn[0] = '\0';
1010                                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1011                                 pseterr(EFAULT);
1012                         }
1013                         PortP->Xprint.XpOn[MAX_XP_CTRL_LEN-1] = '\0';
1014                         PortP->Xprint.XpLen = RIOStrlen(PortP->Xprint.XpOn)+
1015                                                                                                 RIOStrlen(PortP->Xprint.XpOff);
1016                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1017                         return 0;
1018
1019                 case TCRIOXPOFF: /* set Xprint OFF string */
1020                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPOFF\n");
1021                         if ( copyin( (int)arg, (caddr_t)PortP->Xprint.XpOff,
1022                                                 MAX_XP_CTRL_LEN)==COPYFAIL ) {
1023                                 rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
1024                                 PortP->Xprint.XpOff[0] = '\0';
1025                                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1026                                 pseterr(EFAULT);
1027                         }
1028                         PortP->Xprint.XpOff[MAX_XP_CTRL_LEN-1] = '\0';
1029                         PortP->Xprint.XpLen = RIOStrlen(PortP->Xprint.XpOn)+
1030                                                                                 RIOStrlen(PortP->Xprint.XpOff);
1031                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1032                         return 0;
1033
1034                 case TCRIOXPCPS: /* set Xprint CPS string */
1035                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPCPS\n");
1036                         if ( (uint)arg > p->RIOConf.MaxXpCps || 
1037                                         (uint)arg < p->RIOConf.MinXpCps ) {
1038                                 rio_dprintk (RIO_DEBUG_TTY, "%d CPS out of range\n",arg);
1039                                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1040                                 pseterr(EINVAL);
1041                                 return 0;
1042                         }
1043                         PortP->Xprint.XpCps = (uint)arg;
1044                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1045                         return 0;
1046
1047                 case TCRIOXPRINT:
1048                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPRINT\n");
1049                         if ( copyout((caddr_t)&PortP->Xprint, (int)arg,
1050                                         sizeof(struct Xprint))==COPYFAIL ) {
1051                                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1052                                 pseterr(EFAULT);
1053                         }
1054                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1055                         return 0;
1056
1057                 case TCRIOIXANYON:
1058                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYON\n");
1059                         PortP->Config |= RIO_IXANY;
1060                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1061                         return 0;
1062
1063                 case TCRIOIXANYOFF:
1064                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYOFF\n");
1065                         PortP->Config &= ~RIO_IXANY;
1066                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1067                         return 0;
1068
1069                 case TCRIOIXONON:
1070                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONON\n");
1071                         PortP->Config |= RIO_IXON;
1072                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1073                         return 0;
1074
1075                 case TCRIOIXONOFF:
1076                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONOFF\n");
1077                         PortP->Config &= ~RIO_IXON;
1078                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1079                         return 0;
1080
1081 /*
1082 ** 15.10.1998 ARG - ESIL 0761 part fix
1083 ** Added support for CTS and RTS flow control ioctls :
1084 */
1085                 case TCRIOCTSFLOWEN:
1086                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWEN\n");
1087                         PortP->Config |= RIO_CTSFLOW;
1088                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1089                         RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);       
1090                         return 0;
1091
1092                 case TCRIOCTSFLOWDIS:
1093                         rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWDIS\n");
1094                         PortP->Config &= ~RIO_CTSFLOW;
1095                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1096                         RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);       
1097                         return 0;
1098
1099                 case TCRIORTSFLOWEN:
1100                         rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWEN\n");
1101                         PortP->Config |= RIO_RTSFLOW;
1102                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1103                         RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);       
1104                         return 0;
1105
1106                 case TCRIORTSFLOWDIS:
1107                         rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWDIS\n");
1108                         PortP->Config &= ~RIO_RTSFLOW;
1109                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1110                         RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);       
1111                         return 0;
1112
1113 /* end ESIL 0761 part fix */
1114
1115         }
1116
1117
1118         /* Lynx IOCTLS */
1119         switch (cmd) {
1120                 case TIOCSETP:
1121                 case TIOCSETN:
1122                 case OTIOCSETP:
1123                 case OTIOCSETN:
1124                         ioctl_processed++;
1125                         ttyseth(PortP, tp, (struct old_sgttyb *)arg);
1126                         break;
1127                 case TCSETA:
1128                 case TCSETAW:
1129                 case TCSETAF:
1130                         ioctl_processed++;
1131                         rio_dprintk (RIO_DEBUG_TTY, "NON POSIX ioctl\n");
1132                         ttyseth_pv(PortP, tp, (struct termios *)arg, 0);
1133                         break;
1134                 case TCSETAP:   /* posix tcsetattr() */
1135                 case TCSETAWP:  /* posix tcsetattr() */
1136                 case TCSETAFP:  /* posix tcsetattr() */
1137                         rio_dprintk (RIO_DEBUG_TTY, "NON POSIX SYSV ioctl\n");
1138                         ttyseth_pv(PortP, tp, (struct termios *)arg, 1);
1139                         ioctl_processed++;
1140                         break;
1141         }
1142
1143         /*
1144         ** If its any of the commands that require the port to be in the
1145         ** non-busy state wait until all output has drained 
1146         */
1147         if (!ioctl_processed)
1148         switch(cmd) {
1149                 case TCSETAW:
1150                 case TCSETAF:
1151                 case TCSETA:
1152                 case TCSBRK:
1153 #define OLD_POSIX ('x' << 8)
1154 #define OLD_POSIX_SETA (OLD_POSIX | 2)
1155 #define OLD_POSIX_SETAW (OLD_POSIX | 3)
1156 #define OLD_POSIX_SETAF (OLD_POSIX | 4)
1157 #define NEW_POSIX (('i' << 24) | ('X' << 16))
1158 #define NEW_POSIX_SETA (NEW_POSIX | 2)
1159 #define NEW_POSIX_SETAW (NEW_POSIX | 3)
1160 #define NEW_POSIX_SETAF (NEW_POSIX | 4)
1161                 case OLD_POSIX_SETA:
1162                 case OLD_POSIX_SETAW:
1163                 case OLD_POSIX_SETAF:
1164                 case NEW_POSIX_SETA:
1165                 case NEW_POSIX_SETAW:
1166                 case NEW_POSIX_SETAF:
1167 #ifdef TIOCSETP
1168                 case TIOCSETP:
1169 #endif
1170                 case TIOCSETD:
1171                 case TIOCSETN:
1172                         rio_dprintk (RIO_DEBUG_TTY, "wait for non-BUSY, semaphore set\n");
1173                         /*
1174                         ** Wait for drain here, at least as far as the double buffer
1175                         ** being empty.
1176                         */
1177                         /* XXX Does the above comment mean that this has
1178                            still to be implemented? -- REW */
1179                         /* XXX Is the locking OK together with locking
1180                            in txenable? (Deadlock?) -- REW */
1181                         
1182                         RIOTxEnable((char *)PortP);
1183                         break;
1184                 default:
1185                         break;
1186         }
1187
1188         old_cflag = tp->tm.c_cflag;
1189         old_iflag = tp->tm.c_iflag;
1190         old_oflag = tp->tm.c_oflag;
1191         oldcook = PortP->CookMode;
1192
1193         if ( p->RIOHalted ) {
1194                 RIOClearUp( PortP );
1195                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1196                 pseterr(EIO);
1197                 return 0;
1198         }
1199
1200         PortP->FlushCmdBodge = 0;
1201
1202         /*
1203         ** If the port is locked, and it is reconfigured, we want
1204         ** to restore the state of the tty structure so the change is NOT
1205         ** made.
1206         */
1207         if (PortP->Lock) {
1208                 tp->tm.c_iflag = PortP->StoredTty.iflag;
1209                 tp->tm.c_oflag = PortP->StoredTty.oflag;
1210                 tp->tm.c_cflag = PortP->StoredTty.cflag;
1211                 tp->tm.c_lflag = PortP->StoredTty.lflag;
1212                 tp->tm.c_line = PortP->StoredTty.line;
1213                 for (i = 0; i < NCC + 1; i++)
1214                         tp->tm.c_cc[i] = PortP->StoredTty.cc[i];
1215         }
1216         else {
1217                 /*
1218                 ** If the port is set to store the parameters, and it is
1219                 ** reconfigured, we want to save the current tty struct so it
1220                 ** may be restored on the next open.
1221                 */
1222                 if (PortP->Store) {
1223                         PortP->StoredTty.iflag = tp->tm.c_iflag;
1224                         PortP->StoredTty.oflag = tp->tm.c_oflag;
1225                         PortP->StoredTty.cflag = tp->tm.c_cflag;
1226                         PortP->StoredTty.lflag = tp->tm.c_lflag;
1227                         PortP->StoredTty.line = tp->tm.c_line;
1228                         for (i = 0; i < NCC + 1; i++)
1229                                 PortP->StoredTty.cc[i] = tp->tm.c_cc[i];
1230                 }
1231         }
1232
1233         changed = (tp->tm.c_cflag != old_cflag) ||
1234                                 (tp->tm.c_iflag != old_iflag) ||
1235                                 (tp->tm.c_oflag != old_oflag);
1236
1237         PortP->CookMode = RIOCookMode(tp);      /* Set new cooking mode */
1238
1239         rio_dprintk (RIO_DEBUG_TTY, "RIOIoctl changed %d newcook %d oldcook %d\n",
1240                         changed,PortP->CookMode,oldcook);
1241
1242 #ifdef MODEM_SUPPORT
1243         /*
1244         ** kludge to force CARR_ON if CLOCAL set
1245         */
1246         if ((tp->tm.c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))        {
1247                 tp->tm.c_state |= CARR_ON;
1248                 wakeup ((caddr_t)&tp->tm.c_canq);
1249         }
1250 #endif
1251
1252         if ( p->RIOHalted ) {
1253                 RIOClearUp( PortP );
1254                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1255                 pseterr(EIO);
1256                 return 0;
1257         }
1258         /*
1259         ** Re-configure if modes or cooking have changed
1260         */
1261         if (changed || oldcook != PortP->CookMode || (ioctl_processed)) {
1262                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1263                 rio_dprintk (RIO_DEBUG_TTY, "Ioctl changing the PORT settings\n");
1264                 RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);       
1265                 rio_spin_lock_irqsave(&PortP->portSem, flags);
1266         }
1267
1268         if (p->RIOHalted) {
1269                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1270                 RIOClearUp( PortP );
1271                 pseterr(EIO);
1272                 return 0;
1273         }
1274         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1275         return 0;
1276 }
1277
1278 /*
1279         ttyseth -- set hardware dependent tty settings
1280 */
1281 void
1282 ttyseth(PortP, s, sg)
1283 struct Port *           PortP;
1284 struct ttystatics *             s;
1285 struct old_sgttyb *sg;
1286 {
1287         struct old_sgttyb *     tsg;
1288         struct termios *tp = &s->tm;
1289
1290         tsg = &s->sg;
1291
1292         if (sg->sg_flags & (EVENP|ODDP))  {
1293                 tp->c_cflag &= PARENB;
1294                 if (sg->sg_flags & EVENP) {
1295                         if (sg->sg_flags & ODDP) {
1296                                 tp->c_cflag &= V_CS7;
1297                                 tp->c_cflag &= ~PARENB;
1298                         }
1299                         else {
1300                                 tp->c_cflag &= V_CS7;
1301                                 tp->c_cflag &= PARENB;
1302                                 tp->c_cflag &= PARODD;
1303                         }
1304                 }
1305                 else if (sg->sg_flags & ODDP) {
1306                         tp->c_cflag &= V_CS7;
1307                         tp->c_cflag &= PARENB;
1308                         tp->c_cflag &= PARODD;
1309                 }
1310                 else {
1311                         tp->c_cflag &= V_CS7;
1312                         tp->c_cflag &= PARENB;
1313                 }
1314         }
1315 /*
1316  * Use ispeed as the desired speed.  Most implementations don't handle 
1317  * separate input and output speeds very well. If the RIO handles this, 
1318  * I will have to use separate sets of flags to store them in the 
1319  * Port structure.
1320  */
1321         if ( !sg->sg_ospeed )
1322                 sg->sg_ospeed = sg->sg_ispeed;
1323         else
1324                 sg->sg_ispeed = sg->sg_ospeed;
1325         if (sg->sg_ispeed > V_EXTB ) 
1326                 sg->sg_ispeed = V_EXTB;
1327         if (sg->sg_ispeed < V_B0)
1328                 sg->sg_ispeed = V_B0;
1329         *tsg = *sg;
1330    tp->c_cflag = (tp->c_cflag & ~V_CBAUD) | conv_bv[(int)sg->sg_ispeed];
1331 }
1332
1333 /*
1334         ttyseth_pv -- set hardware dependent tty settings using either the
1335                         POSIX termios structure or the System V termio structure.
1336                                 sysv = 0 => (POSIX):     struct termios *sg
1337                                 sysv != 0 => (System V): struct termio *sg
1338 */
1339 static void
1340 ttyseth_pv(PortP, s, sg, sysv)
1341 struct Port *PortP;
1342 struct ttystatics *s;
1343 struct termios *sg;
1344 int sysv;
1345 {
1346     int speed;
1347     unsigned char csize;
1348     unsigned char cread;
1349     unsigned int lcr_flags;
1350     int ps;
1351  
1352     if (sysv) {
1353         /* sg points to a System V termio structure */
1354         csize = ((struct termio *)sg)->c_cflag & CSIZE;
1355         cread = ((struct termio *)sg)->c_cflag & CREAD;
1356         speed = conv_vb[((struct termio *)sg)->c_cflag & V_CBAUD];
1357     }
1358     else {
1359         /* sg points to a POSIX termios structure */
1360         csize = sg->c_cflag & CSIZE;
1361         cread = sg->c_cflag & CREAD;
1362         speed = conv_vb[sg->c_cflag & V_CBAUD];
1363     }
1364     if (s->sg.sg_ispeed != speed || s->sg.sg_ospeed != speed) {
1365         s->sg.sg_ispeed = speed;
1366         s->sg.sg_ospeed = speed;
1367         s->tm.c_cflag = (s->tm.c_cflag & ~V_CBAUD) |
1368                          conv_bv[(int)s->sg.sg_ispeed];
1369     }
1370 }
1371 #endif