/* ** RIOClose the port. ** The operating system thinks that this is last close for the device. ** As there are two interfaces to the port (Modem and tty), we need to ** check that both are closed before we close the device. */ int riotclose(void *ptr) { struct Port *PortP = ptr; /* pointer to the port structure */ int deleted = 0; int try = -1; /* Disable the timeouts by setting them to -1 */ int repeat_this = -1; /* Congrats to those having 15 years of uptime! (You get to break the driver.) */ unsigned long end_time; struct tty_struct *tty; unsigned long flags; int rv = 0; rio_dprintk(RIO_DEBUG_TTY, "port close SysPort %d\n", PortP->PortNum); /* PortP = p->RIOPortp[SysPort]; */ rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP); /* tp = PortP->TtyP; *//* Get tty */ tty = PortP->gs.tty; rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty); if (PortP->gs.closing_wait) end_time = jiffies + PortP->gs.closing_wait; else end_time = jiffies + MAX_SCHEDULE_TIMEOUT; rio_spin_lock_irqsave(&PortP->portSem, flags); /* ** Setting this flag will make any process trying to open ** this port block until we are complete closing it. */ PortP->State |= RIO_CLOSING; if ((PortP->State & RIO_DELETED)) { rio_dprintk(RIO_DEBUG_TTY, "Close on deleted RTA\n"); deleted = 1; } if (p->RIOHalted) { RIOClearUp(PortP); rv = -EIO; goto close_end; } rio_dprintk(RIO_DEBUG_TTY, "Clear bits\n"); /* ** clear the open bits for this device */ PortP->State &= ~RIO_MOPEN; PortP->State &= ~RIO_CARR_ON; PortP->ModemState &= ~MSVR1_CD; /* ** If the device was open as both a Modem and a tty line ** then we need to wimp out here, as the port has not really ** been finally closed (gee, whizz!) The test here uses the ** bit for the OTHER mode of operation, to see if THAT is ** still active! */ if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { /* ** The port is still open for the other task - ** return, pretending that we are still active. */ rio_dprintk(RIO_DEBUG_TTY, "Channel %d still open !\n", PortP->PortNum); PortP->State &= ~RIO_CLOSING; if (PortP->firstOpen) PortP->firstOpen--; rio_spin_unlock_irqrestore(&PortP->portSem, flags); return -EIO; } rio_dprintk(RIO_DEBUG_TTY, "Closing down - everything must go!\n"); PortP->State &= ~RIO_DYNOROD; /* ** This is where we wait for the port ** to drain down before closing. Bye-bye.... ** (We never meant to do this) */ rio_dprintk(RIO_DEBUG_TTY, "Timeout 1 starts\n"); if (!deleted) while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted && (PortP->TxBufferIn != PortP->TxBufferOut)) { if (repeat_this-- <= 0) { rv = -EINTR; rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); RIOPreemptiveCmd(p, PortP, FCLOSE); goto close_end; } rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); rio_spin_unlock_irqrestore(&PortP->portSem, flags); if (RIODelay_ni(PortP, HUNDRED_MS * 10) == RIO_FAIL) { rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); rv = -EINTR; rio_spin_lock_irqsave(&PortP->portSem, flags); goto close_end; } rio_spin_lock_irqsave(&PortP->portSem, flags); } PortP->TxBufferIn = PortP->TxBufferOut = 0; repeat_this = 0xff; PortP->InUse = 0; if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { /* ** The port has been re-opened for the other task - ** return, pretending that we are still active. */ rio_dprintk(RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum); PortP->State &= ~RIO_CLOSING; rio_spin_unlock_irqrestore(&PortP->portSem, flags); if (PortP->firstOpen) PortP->firstOpen--; return -EIO; } if (p->RIOHalted) { RIOClearUp(PortP); goto close_end; } /* Can't call RIOShortCommand with the port locked. */ rio_spin_unlock_irqrestore(&PortP->portSem, flags); if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) { RIOPreemptiveCmd(p, PortP, FCLOSE); rio_spin_lock_irqsave(&PortP->portSem, flags); goto close_end; } if (!deleted) while (try && (PortP->PortState & PORT_ISOPEN)) { try--; if (time_after(jiffies, end_time)) { rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n"); RIOPreemptiveCmd(p, PortP, FCLOSE); break; } rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN); if (p->RIOHalted) { RIOClearUp(PortP); rio_spin_lock_irqsave(&PortP->portSem, flags); goto close_end; } if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); RIOPreemptiveCmd(p, PortP, FCLOSE); break; } } rio_spin_lock_irqsave(&PortP->portSem, flags); rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try); /* RIOPreemptiveCmd(p, PortP, FCLOSE); */ /* ** 15.10.1998 ARG - ESIL 0761 part fix ** 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. */ PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); /* ** Count opens for port statistics reporting */ if (PortP->statsGather) PortP->closes++; close_end: /* XXX: Why would a "DELETED" flag be reset here? I'd have thought that a "deleted" flag means that the port was permanently gone, but here we can make it reappear by it being in close during the "deletion". */ PortP->State &= ~(RIO_CLOSING | RIO_DELETED); if (PortP->firstOpen) PortP->firstOpen--; rio_spin_unlock_irqrestore(&PortP->portSem, flags); rio_dprintk(RIO_DEBUG_TTY, "Return from close\n"); return rv; } static void RIOClearUp(struct Port *PortP) { rio_dprintk(RIO_DEBUG_TTY, "RIOHalted set\n"); PortP->Config = 0; /* Direct semaphore */ PortP->PortState = 0; PortP->firstOpen = 0; PortP->FlushCmdBodge = 0; PortP->ModemState = PortP->CookMode = 0; PortP->Mapped = 0; PortP->WflushFlag = 0; PortP->MagicFlags = 0; PortP->RxDataStart = 0; PortP->TxBufferIn = 0; PortP->TxBufferOut = 0; } /* ** Put a command onto a port. ** The PortPointer, command, length and arg are passed. ** The len is the length *inclusive* of the command byte, ** and so for a command that takes no data, len==1. ** The arg is a single byte, and is only used if len==2. ** Other values of len aren't allowed, and will cause ** a panic. */ int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg) { struct PKT __iomem *PacketP; int retries = 20; /* at 10 per second -> 2 seconds */ unsigned long flags; rio_dprintk(RIO_DEBUG_TTY, "entering shortcommand.\n"); if (PortP->State & RIO_DELETED) { rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); return RIO_FAIL; } rio_spin_lock_irqsave(&PortP->portSem, flags); /* ** If the port is in use for pre-emptive command, then wait for it to ** be free again. */ while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted) { rio_dprintk(RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", retries); rio_spin_unlock_irqrestore(&PortP->portSem, flags); if (retries-- <= 0) { return RIO_FAIL; } if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { return RIO_FAIL; } rio_spin_lock_irqsave(&PortP->portSem, flags); } if (PortP->State & RIO_DELETED) { rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); rio_spin_unlock_irqrestore(&PortP->portSem, flags); return RIO_FAIL; } while (!can_add_transmit(&PacketP, PortP) && !p->RIOHalted) { rio_dprintk(RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries); rio_spin_unlock_irqrestore(&PortP->portSem, flags); if (retries-- <= 0) { rio_dprintk(RIO_DEBUG_TTY, "out of tries. Failing\n"); return RIO_FAIL; } if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { return RIO_FAIL; } rio_spin_lock_irqsave(&PortP->portSem, flags); } if (p->RIOHalted) { rio_spin_unlock_irqrestore(&PortP->portSem, flags); return RIO_FAIL; } /* ** set the command byte and the argument byte */ writeb(command, &PacketP->data[0]); if (len == 2) writeb(arg, &PacketP->data[1]); /* ** set the length of the packet and set the command bit. */ writeb(PKT_CMD_BIT | len, &PacketP->len); add_transmit(PortP); /* ** Count characters transmitted for port statistics reporting */ if (PortP->statsGather) PortP->txchars += len; rio_spin_unlock_irqrestore(&PortP->portSem, flags); return p->RIOHalted ? RIO_FAIL : ~RIO_FAIL; }
int riotopen(struct tty_struct *tty, struct file *filp) { unsigned int SysPort; int repeat_this = 250; struct Port *PortP; /* pointer to the port structure */ unsigned long flags; int retval = 0; func_enter(); /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close is going to oops. */ tty->driver_data = NULL; SysPort = rio_minor(tty); if (p->RIOFailed) { rio_dprintk(RIO_DEBUG_TTY, "System initialisation failed\n"); func_exit(); return -ENXIO; } rio_dprintk(RIO_DEBUG_TTY, "port open SysPort %d (mapped:%d)\n", SysPort, p->RIOPortp[SysPort]->Mapped); /* ** Validate that we have received a legitimate request. ** Currently, just check that we are opening a port on ** a host card that actually exists, and that the port ** has been mapped onto a host. */ if (SysPort >= RIO_PORTS) { /* out of range ? */ rio_dprintk(RIO_DEBUG_TTY, "Illegal port number %d\n", SysPort); func_exit(); return -ENXIO; } /* ** Grab pointer to the port stucture */ PortP = p->RIOPortp[SysPort]; /* Get control struc */ rio_dprintk(RIO_DEBUG_TTY, "PortP: %p\n", PortP); if (!PortP->Mapped) { /* we aren't mapped yet! */ /* ** The system doesn't know which RTA this port ** corresponds to. */ rio_dprintk(RIO_DEBUG_TTY, "port not mapped into system\n"); func_exit(); return -ENXIO; } tty->driver_data = PortP; PortP->gs.tty = tty; PortP->gs.count++; rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt); retval = gs_init_port(&PortP->gs); if (retval) { PortP->gs.count--; return -ENXIO; } /* ** If the host hasn't been booted yet, then ** fail */ if ((PortP->HostP->Flags & RUN_STATE) != RC_RUNNING) { rio_dprintk(RIO_DEBUG_TTY, "Host not running\n"); func_exit(); return -ENXIO; } /* ** If the RTA has not booted yet and the user has choosen to block ** until the RTA is present then we must spin here waiting for ** the RTA to boot. */ /* I find the above code a bit hairy. I find the below code easier to read and shorter. Now, if it works too that would be great... -- REW */ rio_dprintk(RIO_DEBUG_TTY, "Checking if RTA has booted... \n"); while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) { if (!PortP->WaitUntilBooted) { rio_dprintk(RIO_DEBUG_TTY, "RTA never booted\n"); func_exit(); return -ENXIO; } /* Under Linux you'd normally use a wait instead of this busy-waiting. I'll stick with the old implementation for now. --REW */ if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { rio_dprintk(RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n"); func_exit(); return -EINTR; } if (repeat_this-- <= 0) { rio_dprintk(RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n"); func_exit(); return -EIO; } } rio_dprintk(RIO_DEBUG_TTY, "RTA has been booted\n"); rio_spin_lock_irqsave(&PortP->portSem, flags); if (p->RIOHalted) { goto bombout; } /* ** If the port is in the final throws of being closed, ** we should wait here (politely), waiting ** for it to finish, so that it doesn't close us! */ while ((PortP->State & RIO_CLOSING) && !p->RIOHalted) { rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n"); if (repeat_this-- <= 0) { rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); RIOPreemptiveCmd(p, PortP, FCLOSE); retval = -EINTR; goto bombout; } rio_spin_unlock_irqrestore(&PortP->portSem, flags); if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { rio_spin_lock_irqsave(&PortP->portSem, flags); retval = -EINTR; goto bombout; } rio_spin_lock_irqsave(&PortP->portSem, flags); } if (!PortP->Mapped) { rio_dprintk(RIO_DEBUG_TTY, "Port unmapped while closing!\n"); rio_spin_unlock_irqrestore(&PortP->portSem, flags); retval = -ENXIO; func_exit(); return retval; } if (p->RIOHalted) { goto bombout; } /* ** 15.10.1998 ARG - ESIL 0761 part fix ** 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. */ /* Uh? Suppose I turn these on and then another process opens the port again? The flags get cleared! Not good. -- REW */ if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); } if (!(PortP->firstOpen)) { /* First time ? */ rio_dprintk(RIO_DEBUG_TTY, "First open for this port\n"); PortP->firstOpen++; PortP->CookMode = 0; /* XXX RIOCookMode(tp); */ PortP->InUse = NOT_INUSE; /* Tentative fix for bug PR27. Didn't work. */ /* PortP->gs.xmit_cnt = 0; */ rio_spin_unlock_irqrestore(&PortP->portSem, flags); /* Someone explain to me why this delay/config is here. If I read the docs correctly the "open" command piggybacks the parameters immediately. -- REW */ RIOParam(PortP, OPEN, 1, OK_TO_SLEEP); /* Open the port */ rio_spin_lock_irqsave(&PortP->portSem, flags); /* ** wait for the port to be not closed. */ while (!(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted) { rio_dprintk(RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n", PortP->PortState); rio_spin_unlock_irqrestore(&PortP->portSem, flags); if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n"); RIOPreemptiveCmd(p, PortP, FCLOSE); func_exit(); return -EINTR; } rio_spin_lock_irqsave(&PortP->portSem, flags); } if (p->RIOHalted) { retval = -EIO; bombout: /* RIOClearUp( PortP ); */ rio_spin_unlock_irqrestore(&PortP->portSem, flags); return retval; } rio_dprintk(RIO_DEBUG_TTY, "PORT_ISOPEN found\n"); } rio_dprintk(RIO_DEBUG_TTY, "Modem - test for carrier\n"); /* ** ACTION ** insert test for carrier here. -- ??? ** I already see that test here. What's the deal? -- REW */ if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD)) { rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort); /* tp->tm.c_state |= CARR_ON; wakeup((caddr_t) &tp->tm.c_canq); */ PortP->State |= RIO_CARR_ON; wake_up_interruptible(&PortP->gs.open_wait); } else { /* no carrier - wait for DCD */ /* while (!(PortP->gs.tty->termios->c_state & CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) */ while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) { rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort); /* PortP->gs.tty->termios->c_state |= WOPEN; */ PortP->State |= RIO_WOPEN; rio_spin_unlock_irqrestore(&PortP->portSem, flags); if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { rio_spin_lock_irqsave(&PortP->portSem, flags); /* ** ACTION: verify that this is a good thing ** to do here. -- ??? ** I think it's OK. -- REW */ rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort); RIOPreemptiveCmd(p, PortP, FCLOSE); /* tp->tm.c_state &= ~WOPEN; */ PortP->State &= ~RIO_WOPEN; rio_spin_unlock_irqrestore(&PortP->portSem, flags); func_exit(); return -EINTR; } rio_spin_lock_irqsave(&PortP->portSem, flags); } PortP->State &= ~RIO_WOPEN; } if (p->RIOHalted) goto bombout; rio_dprintk(RIO_DEBUG_TTY, "Setting RIO_MOPEN\n"); PortP->State |= RIO_MOPEN; if (p->RIOHalted) goto bombout; rio_dprintk(RIO_DEBUG_TTY, "high level open done\n"); /* ** Count opens for port statistics reporting */ if (PortP->statsGather) PortP->opens++; rio_spin_unlock_irqrestore(&PortP->portSem, flags); rio_dprintk(RIO_DEBUG_TTY, "Returning from open\n"); func_exit(); return 0; }
/* ** RIOParam is used to open or configure a port. You pass it a PortP, ** which will have a tty struct attached to it. You also pass a command, ** either OPEN or CONFIG. The port's setup is taken from the t_ fields ** of the tty struct inside the PortP, and the port is either opened ** or re-configured. You must also tell RIOParam if the device is a modem ** device or not (i.e. top bit of minor number set or clear - take special ** care when deciding on this!). ** RIOParam neither flushes nor waits for drain, and is NOT preemptive. ** ** RIOParam assumes it will be called at splrio(), and also assumes ** that CookMode is set correctly in the port structure. ** ** NB. for MPX ** tty lock must NOT have been previously acquired. */ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) { struct tty_struct *TtyP; int retval; struct phb_param __iomem *phb_param_ptr; struct PKT __iomem *PacketP; int res; u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0; u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0; u8 LNext = 0, TxBaud = 0, RxBaud = 0; int retries = 0xff; unsigned long flags; func_enter(); TtyP = PortP->gs.tty; rio_dprintk(RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP); if (!TtyP) { rio_dprintk(RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n"); func_exit(); return RIO_FAIL; } rio_spin_lock_irqsave(&PortP->portSem, flags); if (cmd == RIOC_OPEN) { /* ** If the port is set to store or lock the parameters, and it is ** paramed with OPEN, we want to restore the saved port termio, but ** only if StoredTermio has been saved, i.e. NOT 1st open after reboot. */ } /* ** wait for space */ while (!(res = can_add_transmit(&PacketP, PortP)) || (PortP->InUse != NOT_INUSE)) { if (retries-- <= 0) { break; } if (PortP->InUse != NOT_INUSE) { rio_dprintk(RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n"); } if (!res) { rio_dprintk(RIO_DEBUG_PARAM, "Port has no space on transmit queue\n"); } if (SleepFlag != OK_TO_SLEEP) { rio_spin_unlock_irqrestore(&PortP->portSem, flags); func_exit(); return RIO_FAIL; } rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit\n"); rio_spin_unlock_irqrestore(&PortP->portSem, flags); retval = RIODelay(PortP, HUNDRED_MS); rio_spin_lock_irqsave(&PortP->portSem, flags); if (retval == RIO_FAIL) { rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n"); rio_spin_unlock_irqrestore(&PortP->portSem, flags); func_exit(); return -EINTR; } if (PortP->State & RIO_DELETED) { rio_spin_unlock_irqrestore(&PortP->portSem, flags); func_exit(); return 0; } } if (!res) { rio_spin_unlock_irqrestore(&PortP->portSem, flags); func_exit(); return RIO_FAIL; } rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res); rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP); phb_param_ptr = (struct phb_param __iomem *) PacketP->data; switch (TtyP->termios->c_cflag & CSIZE) { case CS5: { rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n"); Cor1 |= RIOC_COR1_5BITS; break; } case CS6: { rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n"); Cor1 |= RIOC_COR1_6BITS; break; } case CS7: { rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n"); Cor1 |= RIOC_COR1_7BITS; break; } case CS8: { rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n"); Cor1 |= RIOC_COR1_8BITS; break; } } if (TtyP->termios->c_cflag & CSTOPB) { rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n"); Cor1 |= RIOC_COR1_2STOP; } else { rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n"); Cor1 |= RIOC_COR1_1STOP; } if (TtyP->termios->c_cflag & PARENB) { rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n"); Cor1 |= RIOC_COR1_NORMAL; } else { rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n"); Cor1 |= RIOC_COR1_NOP; } if (TtyP->termios->c_cflag & PARODD) { rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n"); Cor1 |= RIOC_COR1_ODD; } else { rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n"); Cor1 |= RIOC_COR1_EVEN; } /* ** COR 2 */ if (TtyP->termios->c_iflag & IXON) { rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n"); Cor2 |= RIOC_COR2_IXON; } else { if (PortP->Config & RIO_IXON) { rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n"); Cor2 |= RIOC_COR2_IXON; } else rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n"); } if (TtyP->termios->c_iflag & IXANY) { if (PortP->Config & RIO_IXANY) { rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n"); Cor2 |= RIOC_COR2_IXANY; } else rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n"); } if (TtyP->termios->c_iflag & IXOFF) { rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n"); Cor2 |= RIOC_COR2_IXOFF; } if (TtyP->termios->c_cflag & HUPCL) { rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n"); Cor2 |= RIOC_COR2_HUPCL; } if (C_CRTSCTS(TtyP)) { rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n"); Cor2 |= RIOC_COR2_CTSFLOW; Cor2 |= RIOC_COR2_RTSFLOW; } else { rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n"); Cor2 &= ~RIOC_COR2_CTSFLOW; Cor2 &= ~RIOC_COR2_RTSFLOW; } if (TtyP->termios->c_cflag & CLOCAL) { rio_dprintk(RIO_DEBUG_PARAM, "Local line\n"); } else { rio_dprintk(RIO_DEBUG_PARAM, "Possible Modem line\n"); } /* ** COR 4 (there is no COR 3) */ if (TtyP->termios->c_iflag & IGNBRK) { rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n"); Cor4 |= RIOC_COR4_IGNBRK; } if (!(TtyP->termios->c_iflag & BRKINT)) { rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n"); Cor4 |= RIOC_COR4_NBRKINT; } else { rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n"); } if (TtyP->termios->c_iflag & INLCR) { rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n"); Cor4 |= RIOC_COR4_INLCR; } if (TtyP->termios->c_iflag & IGNCR) { rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n"); Cor4 |= RIOC_COR4_IGNCR; } if (TtyP->termios->c_iflag & ICRNL) { rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n"); Cor4 |= RIOC_COR4_ICRNL; } if (TtyP->termios->c_iflag & IGNPAR) { rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n"); Cor4 |= RIOC_COR4_IGNPAR; } if (TtyP->termios->c_iflag & PARMRK) { rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n"); Cor4 |= RIOC_COR4_PARMRK; } /* ** Set the RAISEMOD flag to ensure that the modem lines are raised ** on reception of a config packet. ** The download code handles the zero baud condition. */ Cor4 |= RIOC_COR4_RAISEMOD; /* ** COR 5 */ Cor5 = RIOC_COR5_CMOE; /* ** Set to monitor tbusy/tstop (or not). */ if (PortP->MonitorTstate) Cor5 |= RIOC_COR5_TSTATE_ON; else Cor5 |= RIOC_COR5_TSTATE_OFF; /* ** Could set LNE here if you wanted LNext processing. SVR4 will use it. */ if (TtyP->termios->c_iflag & ISTRIP) { rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n"); if (!(PortP->State & RIO_TRIAD_MODE)) { Cor5 |= RIOC_COR5_ISTRIP; } } if (TtyP->termios->c_oflag & ONLCR) { rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n"); if (PortP->CookMode == COOK_MEDIUM) Cor5 |= RIOC_COR5_ONLCR; } if (TtyP->termios->c_oflag & OCRNL) { rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n"); if (PortP->CookMode == COOK_MEDIUM) Cor5 |= RIOC_COR5_OCRNL; } if ((TtyP->termios->c_oflag & TABDLY) == TAB3) { rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n"); if (PortP->CookMode == COOK_MEDIUM) Cor5 |= RIOC_COR5_TAB3; } /* ** Flow control bytes. */ TxXon = TtyP->termios->c_cc[VSTART]; TxXoff = TtyP->termios->c_cc[VSTOP]; RxXon = TtyP->termios->c_cc[VSTART]; RxXoff = TtyP->termios->c_cc[VSTOP]; /* ** LNEXT byte */ LNext = 0; /* ** Baud rate bytes */ rio_dprintk(RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", TtyP->termios->c_cflag, CBAUD); switch (TtyP->termios->c_cflag & CBAUD) { #define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break e(50); e(75); e(110); e(134); e(150); e(200); e(300); e(600); e(1200); e(1800); e(2400); e(4800); e(9600); e(19200); e(38400); e(57600); e(115200); /* e(230400);e(460800); e(921600); */ } rio_dprintk(RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud); /* ** Leftovers */ if (TtyP->termios->c_cflag & CREAD) rio_dprintk(RIO_DEBUG_PARAM, "Enable receiver\n"); #ifdef RCV1EN if (TtyP->termios->c_cflag & RCV1EN) rio_dprintk(RIO_DEBUG_PARAM, "RCV1EN (?)\n"); #endif #ifdef XMT1EN if (TtyP->termios->c_cflag & XMT1EN) rio_dprintk(RIO_DEBUG_PARAM, "XMT1EN (?)\n"); #endif if (TtyP->termios->c_lflag & ISIG) rio_dprintk(RIO_DEBUG_PARAM, "Input character signal generating enabled\n"); if (TtyP->termios->c_lflag & ICANON) rio_dprintk(RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n"); if (TtyP->termios->c_lflag & XCASE) rio_dprintk(RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n"); if (TtyP->termios->c_lflag & ECHO) rio_dprintk(RIO_DEBUG_PARAM, "Enable input echo\n"); if (TtyP->termios->c_lflag & ECHOE) rio_dprintk(RIO_DEBUG_PARAM, "Enable echo erase\n"); if (TtyP->termios->c_lflag & ECHOK) rio_dprintk(RIO_DEBUG_PARAM, "Enable echo kill\n"); if (TtyP->termios->c_lflag & ECHONL) rio_dprintk(RIO_DEBUG_PARAM, "Enable echo newline\n"); if (TtyP->termios->c_lflag & NOFLSH) rio_dprintk(RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n"); #ifdef TOSTOP if (TtyP->termios->c_lflag & TOSTOP) rio_dprintk(RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n"); #endif #ifdef XCLUDE if (TtyP->termios->c_lflag & XCLUDE) rio_dprintk(RIO_DEBUG_PARAM, "Exclusive use of this line\n"); #endif if (TtyP->termios->c_iflag & IUCLC) rio_dprintk(RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n"); if (TtyP->termios->c_oflag & OPOST) rio_dprintk(RIO_DEBUG_PARAM, "Enable output post-processing\n"); if (TtyP->termios->c_oflag & OLCUC) rio_dprintk(RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n"); if (TtyP->termios->c_oflag & ONOCR) rio_dprintk(RIO_DEBUG_PARAM, "No carriage return output at column 0\n"); if (TtyP->termios->c_oflag & ONLRET) rio_dprintk(RIO_DEBUG_PARAM, "Newline performs carriage return function\n"); if (TtyP->termios->c_oflag & OFILL) rio_dprintk(RIO_DEBUG_PARAM, "Use fill characters for delay\n"); if (TtyP->termios->c_oflag & OFDEL) rio_dprintk(RIO_DEBUG_PARAM, "Fill character is DEL\n"); if (TtyP->termios->c_oflag & NLDLY) rio_dprintk(RIO_DEBUG_PARAM, "Newline delay set\n"); if (TtyP->termios->c_oflag & CRDLY) rio_dprintk(RIO_DEBUG_PARAM, "Carriage return delay set\n"); if (TtyP->termios->c_oflag & TABDLY) rio_dprintk(RIO_DEBUG_PARAM, "Tab delay set\n"); /* ** These things are kind of useful in a later life! */ PortP->Cor2Copy = Cor2; if (PortP->State & RIO_DELETED) { rio_spin_unlock_irqrestore(&PortP->portSem, flags); func_exit(); return RIO_FAIL; } /* ** Actually write the info into the packet to be sent */ writeb(cmd, &phb_param_ptr->Cmd); writeb(Cor1, &phb_param_ptr->Cor1); writeb(Cor2, &phb_param_ptr->Cor2); writeb(Cor4, &phb_param_ptr->Cor4); writeb(Cor5, &phb_param_ptr->Cor5); writeb(TxXon, &phb_param_ptr->TxXon); writeb(RxXon, &phb_param_ptr->RxXon); writeb(TxXoff, &phb_param_ptr->TxXoff); writeb(RxXoff, &phb_param_ptr->RxXoff); writeb(LNext, &phb_param_ptr->LNext); writeb(TxBaud, &phb_param_ptr->TxBaud); writeb(RxBaud, &phb_param_ptr->RxBaud); /* ** Set the length/command field */ writeb(12 | PKT_CMD_BIT, &PacketP->len); /* ** The packet is formed - now, whack it off ** to its final destination: */ add_transmit(PortP); /* ** Count characters transmitted for port statistics reporting */ if (PortP->statsGather) PortP->txchars += 12; rio_spin_unlock_irqrestore(&PortP->portSem, flags); rio_dprintk(RIO_DEBUG_PARAM, "add_transmit returned.\n"); /* ** job done. */ func_exit(); return 0; }