ia64/linux-2.6.18-xen.hg

annotate drivers/char/rio/rioparam.c @ 893:f994bfe9b93b

linux/blktap2: reduce TLB flush scope

c/s 885 added very coarse TLB flushing. Since these flushes always
follow single page updates, single page flushes (when available) are
sufficient.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 04 10:32:57 2009 +0100 (2009-06-04)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 ** -----------------------------------------------------------------------------
ian@0 3 **
ian@0 4 ** Perle Specialix driver for Linux
ian@0 5 ** Ported from existing RIO Driver for SCO sources.
ian@0 6 *
ian@0 7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
ian@0 8 *
ian@0 9 * This program is free software; you can redistribute it and/or modify
ian@0 10 * it under the terms of the GNU General Public License as published by
ian@0 11 * the Free Software Foundation; either version 2 of the License, or
ian@0 12 * (at your option) any later version.
ian@0 13 *
ian@0 14 * This program is distributed in the hope that it will be useful,
ian@0 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ian@0 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ian@0 17 * GNU General Public License for more details.
ian@0 18 *
ian@0 19 * You should have received a copy of the GNU General Public License
ian@0 20 * along with this program; if not, write to the Free Software
ian@0 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
ian@0 22 **
ian@0 23 ** Module : rioparam.c
ian@0 24 ** SID : 1.3
ian@0 25 ** Last Modified : 11/6/98 10:33:45
ian@0 26 ** Retrieved : 11/6/98 10:33:50
ian@0 27 **
ian@0 28 ** ident @(#)rioparam.c 1.3
ian@0 29 **
ian@0 30 ** -----------------------------------------------------------------------------
ian@0 31 */
ian@0 32
ian@0 33 #ifdef SCCS_LABELS
ian@0 34 static char *_rioparam_c_sccs_ = "@(#)rioparam.c 1.3";
ian@0 35 #endif
ian@0 36
ian@0 37 #include <linux/module.h>
ian@0 38 #include <linux/slab.h>
ian@0 39 #include <linux/errno.h>
ian@0 40 #include <linux/tty.h>
ian@0 41 #include <asm/io.h>
ian@0 42 #include <asm/system.h>
ian@0 43 #include <asm/string.h>
ian@0 44 #include <asm/semaphore.h>
ian@0 45 #include <asm/uaccess.h>
ian@0 46
ian@0 47 #include <linux/termios.h>
ian@0 48 #include <linux/serial.h>
ian@0 49
ian@0 50 #include <linux/generic_serial.h>
ian@0 51
ian@0 52
ian@0 53 #include "linux_compat.h"
ian@0 54 #include "rio_linux.h"
ian@0 55 #include "pkt.h"
ian@0 56 #include "daemon.h"
ian@0 57 #include "rio.h"
ian@0 58 #include "riospace.h"
ian@0 59 #include "cmdpkt.h"
ian@0 60 #include "map.h"
ian@0 61 #include "rup.h"
ian@0 62 #include "port.h"
ian@0 63 #include "riodrvr.h"
ian@0 64 #include "rioinfo.h"
ian@0 65 #include "func.h"
ian@0 66 #include "errors.h"
ian@0 67 #include "pci.h"
ian@0 68
ian@0 69 #include "parmmap.h"
ian@0 70 #include "unixrup.h"
ian@0 71 #include "board.h"
ian@0 72 #include "host.h"
ian@0 73 #include "phb.h"
ian@0 74 #include "link.h"
ian@0 75 #include "cmdblk.h"
ian@0 76 #include "route.h"
ian@0 77 #include "cirrus.h"
ian@0 78 #include "rioioctl.h"
ian@0 79 #include "param.h"
ian@0 80
ian@0 81
ian@0 82
ian@0 83 /*
ian@0 84 ** The Scam, based on email from jeremyr@bugs.specialix.co.uk....
ian@0 85 **
ian@0 86 ** To send a command on a particular port, you put a packet with the
ian@0 87 ** command bit set onto the port. The command bit is in the len field,
ian@0 88 ** and gets ORed in with the actual byte count.
ian@0 89 **
ian@0 90 ** When you send a packet with the command bit set, then the first
ian@0 91 ** data byte ( data[0] ) is interpretted as the command to execute.
ian@0 92 ** It also governs what data structure overlay should accompany the packet.
ian@0 93 ** Commands are defined in cirrus/cirrus.h
ian@0 94 **
ian@0 95 ** If you want the command to pre-emt data already on the queue for the
ian@0 96 ** port, set the pre-emptive bit in conjunction with the command bit.
ian@0 97 ** It is not defined what will happen if you set the preemptive bit
ian@0 98 ** on a packet that is NOT a command.
ian@0 99 **
ian@0 100 ** Pre-emptive commands should be queued at the head of the queue using
ian@0 101 ** add_start(), whereas normal commands and data are enqueued using
ian@0 102 ** add_end().
ian@0 103 **
ian@0 104 ** Most commands do not use the remaining bytes in the data array. The
ian@0 105 ** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and
ian@0 106 ** OPEN are currently analagous). With these three commands the following
ian@0 107 ** 11 data bytes are all used to pass config information such as baud rate etc.
ian@0 108 ** The fields are also defined in cirrus.h. Some contain straightforward
ian@0 109 ** information such as the transmit XON character. Two contain the transmit and
ian@0 110 ** receive baud rates respectively. For most baud rates there is a direct
ian@0 111 ** mapping between the rates defined in <sys/termio.h> and the byte in the
ian@0 112 ** packet. There are additional (non UNIX-standard) rates defined in
ian@0 113 ** /u/dos/rio/cirrus/h/brates.h.
ian@0 114 **
ian@0 115 ** The rest of the data fields contain approximations to the Cirrus registers
ian@0 116 ** that are used to program number of bits etc. Each registers bit fields is
ian@0 117 ** defined in cirrus.h.
ian@0 118 **
ian@0 119 ** NB. Only use those bits that are defined as being driver specific
ian@0 120 ** or common to the RTA and the driver.
ian@0 121 **
ian@0 122 ** All commands going from RTA->Host will be dealt with by the Host code - you
ian@0 123 ** will never see them. As with the SI there will be three fields to look out
ian@0 124 ** for in each phb (not yet defined - needs defining a.s.a.p).
ian@0 125 **
ian@0 126 ** modem_status - current state of handshake pins.
ian@0 127 **
ian@0 128 ** port_status - current port status - equivalent to hi_stat for SI, indicates
ian@0 129 ** if port is IDLE_OPEN, IDLE_CLOSED etc.
ian@0 130 **
ian@0 131 ** break_status - bit X set if break has been received.
ian@0 132 **
ian@0 133 ** Happy hacking.
ian@0 134 **
ian@0 135 */
ian@0 136
ian@0 137 /*
ian@0 138 ** RIOParam is used to open or configure a port. You pass it a PortP,
ian@0 139 ** which will have a tty struct attached to it. You also pass a command,
ian@0 140 ** either OPEN or CONFIG. The port's setup is taken from the t_ fields
ian@0 141 ** of the tty struct inside the PortP, and the port is either opened
ian@0 142 ** or re-configured. You must also tell RIOParam if the device is a modem
ian@0 143 ** device or not (i.e. top bit of minor number set or clear - take special
ian@0 144 ** care when deciding on this!).
ian@0 145 ** RIOParam neither flushes nor waits for drain, and is NOT preemptive.
ian@0 146 **
ian@0 147 ** RIOParam assumes it will be called at splrio(), and also assumes
ian@0 148 ** that CookMode is set correctly in the port structure.
ian@0 149 **
ian@0 150 ** NB. for MPX
ian@0 151 ** tty lock must NOT have been previously acquired.
ian@0 152 */
ian@0 153 int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
ian@0 154 {
ian@0 155 struct tty_struct *TtyP;
ian@0 156 int retval;
ian@0 157 struct phb_param __iomem *phb_param_ptr;
ian@0 158 struct PKT __iomem *PacketP;
ian@0 159 int res;
ian@0 160 u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0;
ian@0 161 u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0;
ian@0 162 u8 LNext = 0, TxBaud = 0, RxBaud = 0;
ian@0 163 int retries = 0xff;
ian@0 164 unsigned long flags;
ian@0 165
ian@0 166 func_enter();
ian@0 167
ian@0 168 TtyP = PortP->gs.tty;
ian@0 169
ian@0 170 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);
ian@0 171
ian@0 172 if (!TtyP) {
ian@0 173 rio_dprintk(RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n");
ian@0 174
ian@0 175 func_exit();
ian@0 176
ian@0 177 return RIO_FAIL;
ian@0 178 }
ian@0 179 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 180
ian@0 181 if (cmd == OPEN) {
ian@0 182 /*
ian@0 183 ** If the port is set to store or lock the parameters, and it is
ian@0 184 ** paramed with OPEN, we want to restore the saved port termio, but
ian@0 185 ** only if StoredTermio has been saved, i.e. NOT 1st open after reboot.
ian@0 186 */
ian@0 187 }
ian@0 188
ian@0 189 /*
ian@0 190 ** wait for space
ian@0 191 */
ian@0 192 while (!(res = can_add_transmit(&PacketP, PortP)) || (PortP->InUse != NOT_INUSE)) {
ian@0 193 if (retries-- <= 0) {
ian@0 194 break;
ian@0 195 }
ian@0 196 if (PortP->InUse != NOT_INUSE) {
ian@0 197 rio_dprintk(RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n");
ian@0 198 }
ian@0 199
ian@0 200 if (!res) {
ian@0 201 rio_dprintk(RIO_DEBUG_PARAM, "Port has no space on transmit queue\n");
ian@0 202 }
ian@0 203
ian@0 204 if (SleepFlag != OK_TO_SLEEP) {
ian@0 205 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 206 func_exit();
ian@0 207
ian@0 208 return RIO_FAIL;
ian@0 209 }
ian@0 210
ian@0 211 rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit\n");
ian@0 212 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 213 retval = RIODelay(PortP, HUNDRED_MS);
ian@0 214 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 215 if (retval == RIO_FAIL) {
ian@0 216 rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n");
ian@0 217 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 218 func_exit();
ian@0 219 return -EINTR;
ian@0 220 }
ian@0 221 if (PortP->State & RIO_DELETED) {
ian@0 222 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 223 func_exit();
ian@0 224 return 0;
ian@0 225 }
ian@0 226 }
ian@0 227
ian@0 228 if (!res) {
ian@0 229 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 230 func_exit();
ian@0 231
ian@0 232 return RIO_FAIL;
ian@0 233 }
ian@0 234
ian@0 235 rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res);
ian@0 236 rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP);
ian@0 237
ian@0 238 phb_param_ptr = (struct phb_param __iomem *) PacketP->data;
ian@0 239
ian@0 240
ian@0 241 switch (TtyP->termios->c_cflag & CSIZE) {
ian@0 242 case CS5:
ian@0 243 {
ian@0 244 rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n");
ian@0 245 Cor1 |= COR1_5BITS;
ian@0 246 break;
ian@0 247 }
ian@0 248 case CS6:
ian@0 249 {
ian@0 250 rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n");
ian@0 251 Cor1 |= COR1_6BITS;
ian@0 252 break;
ian@0 253 }
ian@0 254 case CS7:
ian@0 255 {
ian@0 256 rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n");
ian@0 257 Cor1 |= COR1_7BITS;
ian@0 258 break;
ian@0 259 }
ian@0 260 case CS8:
ian@0 261 {
ian@0 262 rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n");
ian@0 263 Cor1 |= COR1_8BITS;
ian@0 264 break;
ian@0 265 }
ian@0 266 }
ian@0 267
ian@0 268 if (TtyP->termios->c_cflag & CSTOPB) {
ian@0 269 rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n");
ian@0 270 Cor1 |= COR1_2STOP;
ian@0 271 } else {
ian@0 272 rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n");
ian@0 273 Cor1 |= COR1_1STOP;
ian@0 274 }
ian@0 275
ian@0 276 if (TtyP->termios->c_cflag & PARENB) {
ian@0 277 rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n");
ian@0 278 Cor1 |= COR1_NORMAL;
ian@0 279 } else {
ian@0 280 rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n");
ian@0 281 Cor1 |= COR1_NOP;
ian@0 282 }
ian@0 283 if (TtyP->termios->c_cflag & PARODD) {
ian@0 284 rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n");
ian@0 285 Cor1 |= COR1_ODD;
ian@0 286 } else {
ian@0 287 rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n");
ian@0 288 Cor1 |= COR1_EVEN;
ian@0 289 }
ian@0 290
ian@0 291 /*
ian@0 292 ** COR 2
ian@0 293 */
ian@0 294 if (TtyP->termios->c_iflag & IXON) {
ian@0 295 rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n");
ian@0 296 Cor2 |= COR2_IXON;
ian@0 297 } else {
ian@0 298 if (PortP->Config & RIO_IXON) {
ian@0 299 rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n");
ian@0 300 Cor2 |= COR2_IXON;
ian@0 301 } else
ian@0 302 rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n");
ian@0 303 }
ian@0 304
ian@0 305 if (TtyP->termios->c_iflag & IXANY) {
ian@0 306 if (PortP->Config & RIO_IXANY) {
ian@0 307 rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n");
ian@0 308 Cor2 |= COR2_IXANY;
ian@0 309 } else
ian@0 310 rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n");
ian@0 311 }
ian@0 312
ian@0 313 if (TtyP->termios->c_iflag & IXOFF) {
ian@0 314 rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n");
ian@0 315 Cor2 |= COR2_IXOFF;
ian@0 316 }
ian@0 317
ian@0 318 if (TtyP->termios->c_cflag & HUPCL) {
ian@0 319 rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n");
ian@0 320 Cor2 |= COR2_HUPCL;
ian@0 321 }
ian@0 322
ian@0 323 if (C_CRTSCTS(TtyP)) {
ian@0 324 rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n");
ian@0 325 Cor2 |= COR2_CTSFLOW;
ian@0 326 Cor2 |= COR2_RTSFLOW;
ian@0 327 } else {
ian@0 328 rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n");
ian@0 329 Cor2 &= ~COR2_CTSFLOW;
ian@0 330 Cor2 &= ~COR2_RTSFLOW;
ian@0 331 }
ian@0 332
ian@0 333
ian@0 334 if (TtyP->termios->c_cflag & CLOCAL) {
ian@0 335 rio_dprintk(RIO_DEBUG_PARAM, "Local line\n");
ian@0 336 } else {
ian@0 337 rio_dprintk(RIO_DEBUG_PARAM, "Possible Modem line\n");
ian@0 338 }
ian@0 339
ian@0 340 /*
ian@0 341 ** COR 4 (there is no COR 3)
ian@0 342 */
ian@0 343 if (TtyP->termios->c_iflag & IGNBRK) {
ian@0 344 rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n");
ian@0 345 Cor4 |= COR4_IGNBRK;
ian@0 346 }
ian@0 347 if (!(TtyP->termios->c_iflag & BRKINT)) {
ian@0 348 rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n");
ian@0 349 Cor4 |= COR4_NBRKINT;
ian@0 350 } else {
ian@0 351 rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n");
ian@0 352 }
ian@0 353
ian@0 354 if (TtyP->termios->c_iflag & INLCR) {
ian@0 355 rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n");
ian@0 356 Cor4 |= COR4_INLCR;
ian@0 357 }
ian@0 358
ian@0 359 if (TtyP->termios->c_iflag & IGNCR) {
ian@0 360 rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n");
ian@0 361 Cor4 |= COR4_IGNCR;
ian@0 362 }
ian@0 363
ian@0 364 if (TtyP->termios->c_iflag & ICRNL) {
ian@0 365 rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n");
ian@0 366 Cor4 |= COR4_ICRNL;
ian@0 367 }
ian@0 368 if (TtyP->termios->c_iflag & IGNPAR) {
ian@0 369 rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n");
ian@0 370 Cor4 |= COR4_IGNPAR;
ian@0 371 }
ian@0 372 if (TtyP->termios->c_iflag & PARMRK) {
ian@0 373 rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n");
ian@0 374 Cor4 |= COR4_PARMRK;
ian@0 375 }
ian@0 376
ian@0 377 /*
ian@0 378 ** Set the RAISEMOD flag to ensure that the modem lines are raised
ian@0 379 ** on reception of a config packet.
ian@0 380 ** The download code handles the zero baud condition.
ian@0 381 */
ian@0 382 Cor4 |= COR4_RAISEMOD;
ian@0 383
ian@0 384 /*
ian@0 385 ** COR 5
ian@0 386 */
ian@0 387
ian@0 388 Cor5 = COR5_CMOE;
ian@0 389
ian@0 390 /*
ian@0 391 ** Set to monitor tbusy/tstop (or not).
ian@0 392 */
ian@0 393
ian@0 394 if (PortP->MonitorTstate)
ian@0 395 Cor5 |= COR5_TSTATE_ON;
ian@0 396 else
ian@0 397 Cor5 |= COR5_TSTATE_OFF;
ian@0 398
ian@0 399 /*
ian@0 400 ** Could set LNE here if you wanted LNext processing. SVR4 will use it.
ian@0 401 */
ian@0 402 if (TtyP->termios->c_iflag & ISTRIP) {
ian@0 403 rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n");
ian@0 404 if (!(PortP->State & RIO_TRIAD_MODE)) {
ian@0 405 Cor5 |= COR5_ISTRIP;
ian@0 406 }
ian@0 407 }
ian@0 408
ian@0 409 if (TtyP->termios->c_oflag & ONLCR) {
ian@0 410 rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n");
ian@0 411 if (PortP->CookMode == COOK_MEDIUM)
ian@0 412 Cor5 |= COR5_ONLCR;
ian@0 413 }
ian@0 414 if (TtyP->termios->c_oflag & OCRNL) {
ian@0 415 rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n");
ian@0 416 if (PortP->CookMode == COOK_MEDIUM)
ian@0 417 Cor5 |= COR5_OCRNL;
ian@0 418 }
ian@0 419 if ((TtyP->termios->c_oflag & TABDLY) == TAB3) {
ian@0 420 rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n");
ian@0 421 if (PortP->CookMode == COOK_MEDIUM)
ian@0 422 Cor5 |= COR5_TAB3;
ian@0 423 }
ian@0 424
ian@0 425 /*
ian@0 426 ** Flow control bytes.
ian@0 427 */
ian@0 428 TxXon = TtyP->termios->c_cc[VSTART];
ian@0 429 TxXoff = TtyP->termios->c_cc[VSTOP];
ian@0 430 RxXon = TtyP->termios->c_cc[VSTART];
ian@0 431 RxXoff = TtyP->termios->c_cc[VSTOP];
ian@0 432 /*
ian@0 433 ** LNEXT byte
ian@0 434 */
ian@0 435 LNext = 0;
ian@0 436
ian@0 437 /*
ian@0 438 ** Baud rate bytes
ian@0 439 */
ian@0 440 rio_dprintk(RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", TtyP->termios->c_cflag, CBAUD);
ian@0 441
ian@0 442 switch (TtyP->termios->c_cflag & CBAUD) {
ian@0 443 #define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break
ian@0 444 e(50);
ian@0 445 e(75);
ian@0 446 e(110);
ian@0 447 e(134);
ian@0 448 e(150);
ian@0 449 e(200);
ian@0 450 e(300);
ian@0 451 e(600);
ian@0 452 e(1200);
ian@0 453 e(1800);
ian@0 454 e(2400);
ian@0 455 e(4800);
ian@0 456 e(9600);
ian@0 457 e(19200);
ian@0 458 e(38400);
ian@0 459 e(57600);
ian@0 460 e(115200); /* e(230400);e(460800); e(921600); */
ian@0 461 }
ian@0 462
ian@0 463 rio_dprintk(RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud);
ian@0 464
ian@0 465
ian@0 466 /*
ian@0 467 ** Leftovers
ian@0 468 */
ian@0 469 if (TtyP->termios->c_cflag & CREAD)
ian@0 470 rio_dprintk(RIO_DEBUG_PARAM, "Enable receiver\n");
ian@0 471 #ifdef RCV1EN
ian@0 472 if (TtyP->termios->c_cflag & RCV1EN)
ian@0 473 rio_dprintk(RIO_DEBUG_PARAM, "RCV1EN (?)\n");
ian@0 474 #endif
ian@0 475 #ifdef XMT1EN
ian@0 476 if (TtyP->termios->c_cflag & XMT1EN)
ian@0 477 rio_dprintk(RIO_DEBUG_PARAM, "XMT1EN (?)\n");
ian@0 478 #endif
ian@0 479 if (TtyP->termios->c_lflag & ISIG)
ian@0 480 rio_dprintk(RIO_DEBUG_PARAM, "Input character signal generating enabled\n");
ian@0 481 if (TtyP->termios->c_lflag & ICANON)
ian@0 482 rio_dprintk(RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n");
ian@0 483 if (TtyP->termios->c_lflag & XCASE)
ian@0 484 rio_dprintk(RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n");
ian@0 485 if (TtyP->termios->c_lflag & ECHO)
ian@0 486 rio_dprintk(RIO_DEBUG_PARAM, "Enable input echo\n");
ian@0 487 if (TtyP->termios->c_lflag & ECHOE)
ian@0 488 rio_dprintk(RIO_DEBUG_PARAM, "Enable echo erase\n");
ian@0 489 if (TtyP->termios->c_lflag & ECHOK)
ian@0 490 rio_dprintk(RIO_DEBUG_PARAM, "Enable echo kill\n");
ian@0 491 if (TtyP->termios->c_lflag & ECHONL)
ian@0 492 rio_dprintk(RIO_DEBUG_PARAM, "Enable echo newline\n");
ian@0 493 if (TtyP->termios->c_lflag & NOFLSH)
ian@0 494 rio_dprintk(RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n");
ian@0 495 #ifdef TOSTOP
ian@0 496 if (TtyP->termios->c_lflag & TOSTOP)
ian@0 497 rio_dprintk(RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n");
ian@0 498 #endif
ian@0 499 #ifdef XCLUDE
ian@0 500 if (TtyP->termios->c_lflag & XCLUDE)
ian@0 501 rio_dprintk(RIO_DEBUG_PARAM, "Exclusive use of this line\n");
ian@0 502 #endif
ian@0 503 if (TtyP->termios->c_iflag & IUCLC)
ian@0 504 rio_dprintk(RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n");
ian@0 505 if (TtyP->termios->c_oflag & OPOST)
ian@0 506 rio_dprintk(RIO_DEBUG_PARAM, "Enable output post-processing\n");
ian@0 507 if (TtyP->termios->c_oflag & OLCUC)
ian@0 508 rio_dprintk(RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n");
ian@0 509 if (TtyP->termios->c_oflag & ONOCR)
ian@0 510 rio_dprintk(RIO_DEBUG_PARAM, "No carriage return output at column 0\n");
ian@0 511 if (TtyP->termios->c_oflag & ONLRET)
ian@0 512 rio_dprintk(RIO_DEBUG_PARAM, "Newline performs carriage return function\n");
ian@0 513 if (TtyP->termios->c_oflag & OFILL)
ian@0 514 rio_dprintk(RIO_DEBUG_PARAM, "Use fill characters for delay\n");
ian@0 515 if (TtyP->termios->c_oflag & OFDEL)
ian@0 516 rio_dprintk(RIO_DEBUG_PARAM, "Fill character is DEL\n");
ian@0 517 if (TtyP->termios->c_oflag & NLDLY)
ian@0 518 rio_dprintk(RIO_DEBUG_PARAM, "Newline delay set\n");
ian@0 519 if (TtyP->termios->c_oflag & CRDLY)
ian@0 520 rio_dprintk(RIO_DEBUG_PARAM, "Carriage return delay set\n");
ian@0 521 if (TtyP->termios->c_oflag & TABDLY)
ian@0 522 rio_dprintk(RIO_DEBUG_PARAM, "Tab delay set\n");
ian@0 523 /*
ian@0 524 ** These things are kind of useful in a later life!
ian@0 525 */
ian@0 526 PortP->Cor2Copy = Cor2;
ian@0 527
ian@0 528 if (PortP->State & RIO_DELETED) {
ian@0 529 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 530 func_exit();
ian@0 531
ian@0 532 return RIO_FAIL;
ian@0 533 }
ian@0 534
ian@0 535 /*
ian@0 536 ** Actually write the info into the packet to be sent
ian@0 537 */
ian@0 538 writeb(cmd, &phb_param_ptr->Cmd);
ian@0 539 writeb(Cor1, &phb_param_ptr->Cor1);
ian@0 540 writeb(Cor2, &phb_param_ptr->Cor2);
ian@0 541 writeb(Cor4, &phb_param_ptr->Cor4);
ian@0 542 writeb(Cor5, &phb_param_ptr->Cor5);
ian@0 543 writeb(TxXon, &phb_param_ptr->TxXon);
ian@0 544 writeb(RxXon, &phb_param_ptr->RxXon);
ian@0 545 writeb(TxXoff, &phb_param_ptr->TxXoff);
ian@0 546 writeb(RxXoff, &phb_param_ptr->RxXoff);
ian@0 547 writeb(LNext, &phb_param_ptr->LNext);
ian@0 548 writeb(TxBaud, &phb_param_ptr->TxBaud);
ian@0 549 writeb(RxBaud, &phb_param_ptr->RxBaud);
ian@0 550
ian@0 551 /*
ian@0 552 ** Set the length/command field
ian@0 553 */
ian@0 554 writeb(12 | PKT_CMD_BIT, &PacketP->len);
ian@0 555
ian@0 556 /*
ian@0 557 ** The packet is formed - now, whack it off
ian@0 558 ** to its final destination:
ian@0 559 */
ian@0 560 add_transmit(PortP);
ian@0 561 /*
ian@0 562 ** Count characters transmitted for port statistics reporting
ian@0 563 */
ian@0 564 if (PortP->statsGather)
ian@0 565 PortP->txchars += 12;
ian@0 566
ian@0 567 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 568
ian@0 569 rio_dprintk(RIO_DEBUG_PARAM, "add_transmit returned.\n");
ian@0 570 /*
ian@0 571 ** job done.
ian@0 572 */
ian@0 573 func_exit();
ian@0 574
ian@0 575 return 0;
ian@0 576 }
ian@0 577
ian@0 578
ian@0 579 /*
ian@0 580 ** We can add another packet to a transmit queue if the packet pointer pointed
ian@0 581 ** to by the TxAdd pointer has PKT_IN_USE clear in its address.
ian@0 582 */
ian@0 583 int can_add_transmit(struct PKT __iomem **PktP, struct Port *PortP)
ian@0 584 {
ian@0 585 struct PKT __iomem *tp;
ian@0 586
ian@0 587 *PktP = tp = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd));
ian@0 588
ian@0 589 return !((unsigned long) tp & PKT_IN_USE);
ian@0 590 }
ian@0 591
ian@0 592 /*
ian@0 593 ** To add a packet to the queue, you set the PKT_IN_USE bit in the address,
ian@0 594 ** and then move the TxAdd pointer along one position to point to the next
ian@0 595 ** packet pointer. You must wrap the pointer from the end back to the start.
ian@0 596 */
ian@0 597 void add_transmit(struct Port *PortP)
ian@0 598 {
ian@0 599 if (readw(PortP->TxAdd) & PKT_IN_USE) {
ian@0 600 rio_dprintk(RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!");
ian@0 601 }
ian@0 602 writew(readw(PortP->TxAdd) | PKT_IN_USE, PortP->TxAdd);
ian@0 603 PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart : PortP->TxAdd + 1;
ian@0 604 writew(RIO_OFF(PortP->Caddr, PortP->TxAdd), &PortP->PhbP->tx_add);
ian@0 605 }
ian@0 606
ian@0 607 /****************************************
ian@0 608 * Put a packet onto the end of the
ian@0 609 * free list
ian@0 610 ****************************************/
ian@0 611 void put_free_end(struct Host *HostP, struct PKT __iomem *PktP)
ian@0 612 {
ian@0 613 struct rio_free_list __iomem *tmp_pointer;
ian@0 614 unsigned short old_end, new_end;
ian@0 615 unsigned long flags;
ian@0 616
ian@0 617 rio_spin_lock_irqsave(&HostP->HostLock, flags);
ian@0 618
ian@0 619 /*************************************************
ian@0 620 * Put a packet back onto the back of the free list
ian@0 621 *
ian@0 622 ************************************************/
ian@0 623
ian@0 624 rio_dprintk(RIO_DEBUG_PFE, "put_free_end(PktP=%p)\n", PktP);
ian@0 625
ian@0 626 if ((old_end = readw(&HostP->ParmMapP->free_list_end)) != TPNULL) {
ian@0 627 new_end = RIO_OFF(HostP->Caddr, PktP);
ian@0 628 tmp_pointer = (struct rio_free_list __iomem *) RIO_PTR(HostP->Caddr, old_end);
ian@0 629 writew(new_end, &tmp_pointer->next);
ian@0 630 writew(old_end, &((struct rio_free_list __iomem *) PktP)->prev);
ian@0 631 writew(TPNULL, &((struct rio_free_list __iomem *) PktP)->next);
ian@0 632 writew(new_end, &HostP->ParmMapP->free_list_end);
ian@0 633 } else { /* First packet on the free list this should never happen! */
ian@0 634 rio_dprintk(RIO_DEBUG_PFE, "put_free_end(): This should never happen\n");
ian@0 635 writew(RIO_OFF(HostP->Caddr, PktP), &HostP->ParmMapP->free_list_end);
ian@0 636 tmp_pointer = (struct rio_free_list __iomem *) PktP;
ian@0 637 writew(TPNULL, &tmp_pointer->prev);
ian@0 638 writew(TPNULL, &tmp_pointer->next);
ian@0 639 }
ian@0 640 rio_dprintk(RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock);
ian@0 641 rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
ian@0 642 }
ian@0 643
ian@0 644 /*
ian@0 645 ** can_remove_receive(PktP,P) returns non-zero if PKT_IN_USE is set
ian@0 646 ** for the next packet on the queue. It will also set PktP to point to the
ian@0 647 ** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
ian@0 648 ** then can_remove_receive() returns 0.
ian@0 649 */
ian@0 650 int can_remove_receive(struct PKT __iomem **PktP, struct Port *PortP)
ian@0 651 {
ian@0 652 if (readw(PortP->RxRemove) & PKT_IN_USE) {
ian@0 653 *PktP = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE);
ian@0 654 return 1;
ian@0 655 }
ian@0 656 return 0;
ian@0 657 }
ian@0 658
ian@0 659 /*
ian@0 660 ** To remove a packet from the receive queue you clear its PKT_IN_USE bit,
ian@0 661 ** and then bump the pointers. Once the pointers get to the end, they must
ian@0 662 ** be wrapped back to the start.
ian@0 663 */
ian@0 664 void remove_receive(struct Port *PortP)
ian@0 665 {
ian@0 666 writew(readw(PortP->RxRemove) & ~PKT_IN_USE, PortP->RxRemove);
ian@0 667 PortP->RxRemove = (PortP->RxRemove == PortP->RxEnd) ? PortP->RxStart : PortP->RxRemove + 1;
ian@0 668 writew(RIO_OFF(PortP->Caddr, PortP->RxRemove), &PortP->PhbP->rx_remove);
ian@0 669 }