ia64/linux-2.6.18-xen.hg

annotate drivers/char/rio/riotty.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 : riotty.c
ian@0 24 ** SID : 1.3
ian@0 25 ** Last Modified : 11/6/98 10:33:47
ian@0 26 ** Retrieved : 11/6/98 10:33:50
ian@0 27 **
ian@0 28 ** ident @(#)riotty.c 1.3
ian@0 29 **
ian@0 30 ** -----------------------------------------------------------------------------
ian@0 31 */
ian@0 32 #ifdef SCCS_LABELS
ian@0 33 static char *_riotty_c_sccs_ = "@(#)riotty.c 1.3";
ian@0 34 #endif
ian@0 35
ian@0 36
ian@0 37 #define __EXPLICIT_DEF_H__
ian@0 38
ian@0 39 #include <linux/module.h>
ian@0 40 #include <linux/slab.h>
ian@0 41 #include <linux/errno.h>
ian@0 42 #include <linux/tty.h>
ian@0 43 #include <linux/string.h>
ian@0 44 #include <asm/io.h>
ian@0 45 #include <asm/system.h>
ian@0 46 #include <asm/string.h>
ian@0 47 #include <asm/semaphore.h>
ian@0 48 #include <asm/uaccess.h>
ian@0 49
ian@0 50 #include <linux/termios.h>
ian@0 51
ian@0 52 #include <linux/serial.h>
ian@0 53
ian@0 54 #include <linux/generic_serial.h>
ian@0 55
ian@0 56
ian@0 57 #include "linux_compat.h"
ian@0 58 #include "rio_linux.h"
ian@0 59 #include "pkt.h"
ian@0 60 #include "daemon.h"
ian@0 61 #include "rio.h"
ian@0 62 #include "riospace.h"
ian@0 63 #include "cmdpkt.h"
ian@0 64 #include "map.h"
ian@0 65 #include "rup.h"
ian@0 66 #include "port.h"
ian@0 67 #include "riodrvr.h"
ian@0 68 #include "rioinfo.h"
ian@0 69 #include "func.h"
ian@0 70 #include "errors.h"
ian@0 71 #include "pci.h"
ian@0 72
ian@0 73 #include "parmmap.h"
ian@0 74 #include "unixrup.h"
ian@0 75 #include "board.h"
ian@0 76 #include "host.h"
ian@0 77 #include "phb.h"
ian@0 78 #include "link.h"
ian@0 79 #include "cmdblk.h"
ian@0 80 #include "route.h"
ian@0 81 #include "cirrus.h"
ian@0 82 #include "rioioctl.h"
ian@0 83 #include "param.h"
ian@0 84
ian@0 85 static void RIOClearUp(struct Port *PortP);
ian@0 86
ian@0 87 /* Below belongs in func.h */
ian@0 88 int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg);
ian@0 89
ian@0 90
ian@0 91 extern struct rio_info *p;
ian@0 92
ian@0 93
ian@0 94 int riotopen(struct tty_struct *tty, struct file *filp)
ian@0 95 {
ian@0 96 unsigned int SysPort;
ian@0 97 int repeat_this = 250;
ian@0 98 struct Port *PortP; /* pointer to the port structure */
ian@0 99 unsigned long flags;
ian@0 100 int retval = 0;
ian@0 101
ian@0 102 func_enter();
ian@0 103
ian@0 104 /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close
ian@0 105 is going to oops.
ian@0 106 */
ian@0 107 tty->driver_data = NULL;
ian@0 108
ian@0 109 SysPort = rio_minor(tty);
ian@0 110
ian@0 111 if (p->RIOFailed) {
ian@0 112 rio_dprintk(RIO_DEBUG_TTY, "System initialisation failed\n");
ian@0 113 func_exit();
ian@0 114 return -ENXIO;
ian@0 115 }
ian@0 116
ian@0 117 rio_dprintk(RIO_DEBUG_TTY, "port open SysPort %d (mapped:%d)\n", SysPort, p->RIOPortp[SysPort]->Mapped);
ian@0 118
ian@0 119 /*
ian@0 120 ** Validate that we have received a legitimate request.
ian@0 121 ** Currently, just check that we are opening a port on
ian@0 122 ** a host card that actually exists, and that the port
ian@0 123 ** has been mapped onto a host.
ian@0 124 */
ian@0 125 if (SysPort >= RIO_PORTS) { /* out of range ? */
ian@0 126 rio_dprintk(RIO_DEBUG_TTY, "Illegal port number %d\n", SysPort);
ian@0 127 func_exit();
ian@0 128 return -ENXIO;
ian@0 129 }
ian@0 130
ian@0 131 /*
ian@0 132 ** Grab pointer to the port stucture
ian@0 133 */
ian@0 134 PortP = p->RIOPortp[SysPort]; /* Get control struc */
ian@0 135 rio_dprintk(RIO_DEBUG_TTY, "PortP: %p\n", PortP);
ian@0 136 if (!PortP->Mapped) { /* we aren't mapped yet! */
ian@0 137 /*
ian@0 138 ** The system doesn't know which RTA this port
ian@0 139 ** corresponds to.
ian@0 140 */
ian@0 141 rio_dprintk(RIO_DEBUG_TTY, "port not mapped into system\n");
ian@0 142 func_exit();
ian@0 143 return -ENXIO;
ian@0 144 }
ian@0 145
ian@0 146 tty->driver_data = PortP;
ian@0 147
ian@0 148 PortP->gs.tty = tty;
ian@0 149 PortP->gs.count++;
ian@0 150
ian@0 151 rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt);
ian@0 152
ian@0 153 retval = gs_init_port(&PortP->gs);
ian@0 154 if (retval) {
ian@0 155 PortP->gs.count--;
ian@0 156 return -ENXIO;
ian@0 157 }
ian@0 158 /*
ian@0 159 ** If the host hasn't been booted yet, then
ian@0 160 ** fail
ian@0 161 */
ian@0 162 if ((PortP->HostP->Flags & RUN_STATE) != RC_RUNNING) {
ian@0 163 rio_dprintk(RIO_DEBUG_TTY, "Host not running\n");
ian@0 164 func_exit();
ian@0 165 return -ENXIO;
ian@0 166 }
ian@0 167
ian@0 168 /*
ian@0 169 ** If the RTA has not booted yet and the user has choosen to block
ian@0 170 ** until the RTA is present then we must spin here waiting for
ian@0 171 ** the RTA to boot.
ian@0 172 */
ian@0 173 /* I find the above code a bit hairy. I find the below code
ian@0 174 easier to read and shorter. Now, if it works too that would
ian@0 175 be great... -- REW
ian@0 176 */
ian@0 177 rio_dprintk(RIO_DEBUG_TTY, "Checking if RTA has booted... \n");
ian@0 178 while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
ian@0 179 if (!PortP->WaitUntilBooted) {
ian@0 180 rio_dprintk(RIO_DEBUG_TTY, "RTA never booted\n");
ian@0 181 func_exit();
ian@0 182 return -ENXIO;
ian@0 183 }
ian@0 184
ian@0 185 /* Under Linux you'd normally use a wait instead of this
ian@0 186 busy-waiting. I'll stick with the old implementation for
ian@0 187 now. --REW
ian@0 188 */
ian@0 189 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
ian@0 190 rio_dprintk(RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n");
ian@0 191 func_exit();
ian@0 192 return -EINTR;
ian@0 193 }
ian@0 194 if (repeat_this-- <= 0) {
ian@0 195 rio_dprintk(RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
ian@0 196 func_exit();
ian@0 197 return -EIO;
ian@0 198 }
ian@0 199 }
ian@0 200 rio_dprintk(RIO_DEBUG_TTY, "RTA has been booted\n");
ian@0 201 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 202 if (p->RIOHalted) {
ian@0 203 goto bombout;
ian@0 204 }
ian@0 205
ian@0 206 /*
ian@0 207 ** If the port is in the final throws of being closed,
ian@0 208 ** we should wait here (politely), waiting
ian@0 209 ** for it to finish, so that it doesn't close us!
ian@0 210 */
ian@0 211 while ((PortP->State & RIO_CLOSING) && !p->RIOHalted) {
ian@0 212 rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n");
ian@0 213 if (repeat_this-- <= 0) {
ian@0 214 rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
ian@0 215 RIOPreemptiveCmd(p, PortP, FCLOSE);
ian@0 216 retval = -EINTR;
ian@0 217 goto bombout;
ian@0 218 }
ian@0 219 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 220 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
ian@0 221 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 222 retval = -EINTR;
ian@0 223 goto bombout;
ian@0 224 }
ian@0 225 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 226 }
ian@0 227
ian@0 228 if (!PortP->Mapped) {
ian@0 229 rio_dprintk(RIO_DEBUG_TTY, "Port unmapped while closing!\n");
ian@0 230 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 231 retval = -ENXIO;
ian@0 232 func_exit();
ian@0 233 return retval;
ian@0 234 }
ian@0 235
ian@0 236 if (p->RIOHalted) {
ian@0 237 goto bombout;
ian@0 238 }
ian@0 239
ian@0 240 /*
ian@0 241 ** 15.10.1998 ARG - ESIL 0761 part fix
ian@0 242 ** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,
ian@0 243 ** we need to make sure that the flags are clear when the port is opened.
ian@0 244 */
ian@0 245 /* Uh? Suppose I turn these on and then another process opens
ian@0 246 the port again? The flags get cleared! Not good. -- REW */
ian@0 247 if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
ian@0 248 PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW);
ian@0 249 }
ian@0 250
ian@0 251 if (!(PortP->firstOpen)) { /* First time ? */
ian@0 252 rio_dprintk(RIO_DEBUG_TTY, "First open for this port\n");
ian@0 253
ian@0 254
ian@0 255 PortP->firstOpen++;
ian@0 256 PortP->CookMode = 0; /* XXX RIOCookMode(tp); */
ian@0 257 PortP->InUse = NOT_INUSE;
ian@0 258
ian@0 259 /* Tentative fix for bug PR27. Didn't work. */
ian@0 260 /* PortP->gs.xmit_cnt = 0; */
ian@0 261
ian@0 262 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 263
ian@0 264 /* Someone explain to me why this delay/config is
ian@0 265 here. If I read the docs correctly the "open"
ian@0 266 command piggybacks the parameters immediately.
ian@0 267 -- REW */
ian@0 268 RIOParam(PortP, OPEN, 1, OK_TO_SLEEP); /* Open the port */
ian@0 269 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 270
ian@0 271 /*
ian@0 272 ** wait for the port to be not closed.
ian@0 273 */
ian@0 274 while (!(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted) {
ian@0 275 rio_dprintk(RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n", PortP->PortState);
ian@0 276 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 277 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
ian@0 278 rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n");
ian@0 279 RIOPreemptiveCmd(p, PortP, FCLOSE);
ian@0 280 func_exit();
ian@0 281 return -EINTR;
ian@0 282 }
ian@0 283 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 284 }
ian@0 285
ian@0 286 if (p->RIOHalted) {
ian@0 287 retval = -EIO;
ian@0 288 bombout:
ian@0 289 /* RIOClearUp( PortP ); */
ian@0 290 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 291 return retval;
ian@0 292 }
ian@0 293 rio_dprintk(RIO_DEBUG_TTY, "PORT_ISOPEN found\n");
ian@0 294 }
ian@0 295 rio_dprintk(RIO_DEBUG_TTY, "Modem - test for carrier\n");
ian@0 296 /*
ian@0 297 ** ACTION
ian@0 298 ** insert test for carrier here. -- ???
ian@0 299 ** I already see that test here. What's the deal? -- REW
ian@0 300 */
ian@0 301 if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD)) {
ian@0 302 rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
ian@0 303 /*
ian@0 304 tp->tm.c_state |= CARR_ON;
ian@0 305 wakeup((caddr_t) &tp->tm.c_canq);
ian@0 306 */
ian@0 307 PortP->State |= RIO_CARR_ON;
ian@0 308 wake_up_interruptible(&PortP->gs.open_wait);
ian@0 309 } else { /* no carrier - wait for DCD */
ian@0 310 /*
ian@0 311 while (!(PortP->gs.tty->termios->c_state & CARR_ON) &&
ian@0 312 !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )
ian@0 313 */
ian@0 314 while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) {
ian@0 315 rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort);
ian@0 316 /*
ian@0 317 PortP->gs.tty->termios->c_state |= WOPEN;
ian@0 318 */
ian@0 319 PortP->State |= RIO_WOPEN;
ian@0 320 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 321 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
ian@0 322 /*
ian@0 323 ** ACTION: verify that this is a good thing
ian@0 324 ** to do here. -- ???
ian@0 325 ** I think it's OK. -- REW
ian@0 326 */
ian@0 327 rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort);
ian@0 328 RIOPreemptiveCmd(p, PortP, FCLOSE);
ian@0 329 /*
ian@0 330 tp->tm.c_state &= ~WOPEN;
ian@0 331 */
ian@0 332 PortP->State &= ~RIO_WOPEN;
ian@0 333 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 334 func_exit();
ian@0 335 return -EINTR;
ian@0 336 }
ian@0 337 }
ian@0 338 PortP->State &= ~RIO_WOPEN;
ian@0 339 }
ian@0 340 if (p->RIOHalted)
ian@0 341 goto bombout;
ian@0 342 rio_dprintk(RIO_DEBUG_TTY, "Setting RIO_MOPEN\n");
ian@0 343 PortP->State |= RIO_MOPEN;
ian@0 344
ian@0 345 if (p->RIOHalted)
ian@0 346 goto bombout;
ian@0 347
ian@0 348 rio_dprintk(RIO_DEBUG_TTY, "high level open done\n");
ian@0 349
ian@0 350 /*
ian@0 351 ** Count opens for port statistics reporting
ian@0 352 */
ian@0 353 if (PortP->statsGather)
ian@0 354 PortP->opens++;
ian@0 355
ian@0 356 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 357 rio_dprintk(RIO_DEBUG_TTY, "Returning from open\n");
ian@0 358 func_exit();
ian@0 359 return 0;
ian@0 360 }
ian@0 361
ian@0 362 /*
ian@0 363 ** RIOClose the port.
ian@0 364 ** The operating system thinks that this is last close for the device.
ian@0 365 ** As there are two interfaces to the port (Modem and tty), we need to
ian@0 366 ** check that both are closed before we close the device.
ian@0 367 */
ian@0 368 int riotclose(void *ptr)
ian@0 369 {
ian@0 370 struct Port *PortP = ptr; /* pointer to the port structure */
ian@0 371 int deleted = 0;
ian@0 372 int try = -1; /* Disable the timeouts by setting them to -1 */
ian@0 373 int repeat_this = -1; /* Congrats to those having 15 years of
ian@0 374 uptime! (You get to break the driver.) */
ian@0 375 unsigned long end_time;
ian@0 376 struct tty_struct *tty;
ian@0 377 unsigned long flags;
ian@0 378 int rv = 0;
ian@0 379
ian@0 380 rio_dprintk(RIO_DEBUG_TTY, "port close SysPort %d\n", PortP->PortNum);
ian@0 381
ian@0 382 /* PortP = p->RIOPortp[SysPort]; */
ian@0 383 rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP);
ian@0 384 /* tp = PortP->TtyP; *//* Get tty */
ian@0 385 tty = PortP->gs.tty;
ian@0 386 rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty);
ian@0 387
ian@0 388 if (PortP->gs.closing_wait)
ian@0 389 end_time = jiffies + PortP->gs.closing_wait;
ian@0 390 else
ian@0 391 end_time = jiffies + MAX_SCHEDULE_TIMEOUT;
ian@0 392
ian@0 393 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 394
ian@0 395 /*
ian@0 396 ** Setting this flag will make any process trying to open
ian@0 397 ** this port block until we are complete closing it.
ian@0 398 */
ian@0 399 PortP->State |= RIO_CLOSING;
ian@0 400
ian@0 401 if ((PortP->State & RIO_DELETED)) {
ian@0 402 rio_dprintk(RIO_DEBUG_TTY, "Close on deleted RTA\n");
ian@0 403 deleted = 1;
ian@0 404 }
ian@0 405
ian@0 406 if (p->RIOHalted) {
ian@0 407 RIOClearUp(PortP);
ian@0 408 rv = -EIO;
ian@0 409 goto close_end;
ian@0 410 }
ian@0 411
ian@0 412 rio_dprintk(RIO_DEBUG_TTY, "Clear bits\n");
ian@0 413 /*
ian@0 414 ** clear the open bits for this device
ian@0 415 */
ian@0 416 PortP->State &= ~RIO_MOPEN;
ian@0 417 PortP->State &= ~RIO_CARR_ON;
ian@0 418 PortP->ModemState &= ~MSVR1_CD;
ian@0 419 /*
ian@0 420 ** If the device was open as both a Modem and a tty line
ian@0 421 ** then we need to wimp out here, as the port has not really
ian@0 422 ** been finally closed (gee, whizz!) The test here uses the
ian@0 423 ** bit for the OTHER mode of operation, to see if THAT is
ian@0 424 ** still active!
ian@0 425 */
ian@0 426 if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
ian@0 427 /*
ian@0 428 ** The port is still open for the other task -
ian@0 429 ** return, pretending that we are still active.
ian@0 430 */
ian@0 431 rio_dprintk(RIO_DEBUG_TTY, "Channel %d still open !\n", PortP->PortNum);
ian@0 432 PortP->State &= ~RIO_CLOSING;
ian@0 433 if (PortP->firstOpen)
ian@0 434 PortP->firstOpen--;
ian@0 435 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 436 return -EIO;
ian@0 437 }
ian@0 438
ian@0 439 rio_dprintk(RIO_DEBUG_TTY, "Closing down - everything must go!\n");
ian@0 440
ian@0 441 PortP->State &= ~RIO_DYNOROD;
ian@0 442
ian@0 443 /*
ian@0 444 ** This is where we wait for the port
ian@0 445 ** to drain down before closing. Bye-bye....
ian@0 446 ** (We never meant to do this)
ian@0 447 */
ian@0 448 rio_dprintk(RIO_DEBUG_TTY, "Timeout 1 starts\n");
ian@0 449
ian@0 450 if (!deleted)
ian@0 451 while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted && (PortP->TxBufferIn != PortP->TxBufferOut)) {
ian@0 452 if (repeat_this-- <= 0) {
ian@0 453 rv = -EINTR;
ian@0 454 rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
ian@0 455 RIOPreemptiveCmd(p, PortP, FCLOSE);
ian@0 456 goto close_end;
ian@0 457 }
ian@0 458 rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
ian@0 459 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 460 if (RIODelay_ni(PortP, HUNDRED_MS * 10) == RIO_FAIL) {
ian@0 461 rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n");
ian@0 462 rv = -EINTR;
ian@0 463 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 464 goto close_end;
ian@0 465 }
ian@0 466 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 467 }
ian@0 468
ian@0 469 PortP->TxBufferIn = PortP->TxBufferOut = 0;
ian@0 470 repeat_this = 0xff;
ian@0 471
ian@0 472 PortP->InUse = 0;
ian@0 473 if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
ian@0 474 /*
ian@0 475 ** The port has been re-opened for the other task -
ian@0 476 ** return, pretending that we are still active.
ian@0 477 */
ian@0 478 rio_dprintk(RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum);
ian@0 479 PortP->State &= ~RIO_CLOSING;
ian@0 480 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 481 if (PortP->firstOpen)
ian@0 482 PortP->firstOpen--;
ian@0 483 return -EIO;
ian@0 484 }
ian@0 485
ian@0 486 if (p->RIOHalted) {
ian@0 487 RIOClearUp(PortP);
ian@0 488 goto close_end;
ian@0 489 }
ian@0 490
ian@0 491 /* Can't call RIOShortCommand with the port locked. */
ian@0 492 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 493
ian@0 494 if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
ian@0 495 RIOPreemptiveCmd(p, PortP, FCLOSE);
ian@0 496 goto close_end;
ian@0 497 }
ian@0 498
ian@0 499 if (!deleted)
ian@0 500 while (try && (PortP->PortState & PORT_ISOPEN)) {
ian@0 501 try--;
ian@0 502 if (time_after(jiffies, end_time)) {
ian@0 503 rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n");
ian@0 504 RIOPreemptiveCmd(p, PortP, FCLOSE);
ian@0 505 break;
ian@0 506 }
ian@0 507 rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN);
ian@0 508
ian@0 509 if (p->RIOHalted) {
ian@0 510 RIOClearUp(PortP);
ian@0 511 goto close_end;
ian@0 512 }
ian@0 513 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
ian@0 514 rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n");
ian@0 515 RIOPreemptiveCmd(p, PortP, FCLOSE);
ian@0 516 break;
ian@0 517 }
ian@0 518 }
ian@0 519 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 520 rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try);
ian@0 521
ian@0 522 /* RIOPreemptiveCmd(p, PortP, FCLOSE); */
ian@0 523
ian@0 524 /*
ian@0 525 ** 15.10.1998 ARG - ESIL 0761 part fix
ian@0 526 ** 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.
ian@0 527 */
ian@0 528 PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW);
ian@0 529
ian@0 530 /*
ian@0 531 ** Count opens for port statistics reporting
ian@0 532 */
ian@0 533 if (PortP->statsGather)
ian@0 534 PortP->closes++;
ian@0 535
ian@0 536 close_end:
ian@0 537 /* XXX: Why would a "DELETED" flag be reset here? I'd have
ian@0 538 thought that a "deleted" flag means that the port was
ian@0 539 permanently gone, but here we can make it reappear by it
ian@0 540 being in close during the "deletion".
ian@0 541 */
ian@0 542 PortP->State &= ~(RIO_CLOSING | RIO_DELETED);
ian@0 543 if (PortP->firstOpen)
ian@0 544 PortP->firstOpen--;
ian@0 545 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 546 rio_dprintk(RIO_DEBUG_TTY, "Return from close\n");
ian@0 547 return rv;
ian@0 548 }
ian@0 549
ian@0 550
ian@0 551
ian@0 552 static void RIOClearUp(struct Port *PortP)
ian@0 553 {
ian@0 554 rio_dprintk(RIO_DEBUG_TTY, "RIOHalted set\n");
ian@0 555 PortP->Config = 0; /* Direct semaphore */
ian@0 556 PortP->PortState = 0;
ian@0 557 PortP->firstOpen = 0;
ian@0 558 PortP->FlushCmdBodge = 0;
ian@0 559 PortP->ModemState = PortP->CookMode = 0;
ian@0 560 PortP->Mapped = 0;
ian@0 561 PortP->WflushFlag = 0;
ian@0 562 PortP->MagicFlags = 0;
ian@0 563 PortP->RxDataStart = 0;
ian@0 564 PortP->TxBufferIn = 0;
ian@0 565 PortP->TxBufferOut = 0;
ian@0 566 }
ian@0 567
ian@0 568 /*
ian@0 569 ** Put a command onto a port.
ian@0 570 ** The PortPointer, command, length and arg are passed.
ian@0 571 ** The len is the length *inclusive* of the command byte,
ian@0 572 ** and so for a command that takes no data, len==1.
ian@0 573 ** The arg is a single byte, and is only used if len==2.
ian@0 574 ** Other values of len aren't allowed, and will cause
ian@0 575 ** a panic.
ian@0 576 */
ian@0 577 int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg)
ian@0 578 {
ian@0 579 struct PKT __iomem *PacketP;
ian@0 580 int retries = 20; /* at 10 per second -> 2 seconds */
ian@0 581 unsigned long flags;
ian@0 582
ian@0 583 rio_dprintk(RIO_DEBUG_TTY, "entering shortcommand.\n");
ian@0 584
ian@0 585 if (PortP->State & RIO_DELETED) {
ian@0 586 rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
ian@0 587 return RIO_FAIL;
ian@0 588 }
ian@0 589 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 590
ian@0 591 /*
ian@0 592 ** If the port is in use for pre-emptive command, then wait for it to
ian@0 593 ** be free again.
ian@0 594 */
ian@0 595 while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted) {
ian@0 596 rio_dprintk(RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", retries);
ian@0 597 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 598 if (retries-- <= 0) {
ian@0 599 return RIO_FAIL;
ian@0 600 }
ian@0 601 if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) {
ian@0 602 return RIO_FAIL;
ian@0 603 }
ian@0 604 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 605 }
ian@0 606 if (PortP->State & RIO_DELETED) {
ian@0 607 rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
ian@0 608 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 609 return RIO_FAIL;
ian@0 610 }
ian@0 611
ian@0 612 while (!can_add_transmit(&PacketP, PortP) && !p->RIOHalted) {
ian@0 613 rio_dprintk(RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries);
ian@0 614 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 615 if (retries-- <= 0) {
ian@0 616 rio_dprintk(RIO_DEBUG_TTY, "out of tries. Failing\n");
ian@0 617 return RIO_FAIL;
ian@0 618 }
ian@0 619 if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) {
ian@0 620 return RIO_FAIL;
ian@0 621 }
ian@0 622 rio_spin_lock_irqsave(&PortP->portSem, flags);
ian@0 623 }
ian@0 624
ian@0 625 if (p->RIOHalted) {
ian@0 626 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 627 return RIO_FAIL;
ian@0 628 }
ian@0 629
ian@0 630 /*
ian@0 631 ** set the command byte and the argument byte
ian@0 632 */
ian@0 633 writeb(command, &PacketP->data[0]);
ian@0 634
ian@0 635 if (len == 2)
ian@0 636 writeb(arg, &PacketP->data[1]);
ian@0 637
ian@0 638 /*
ian@0 639 ** set the length of the packet and set the command bit.
ian@0 640 */
ian@0 641 writeb(PKT_CMD_BIT | len, &PacketP->len);
ian@0 642
ian@0 643 add_transmit(PortP);
ian@0 644 /*
ian@0 645 ** Count characters transmitted for port statistics reporting
ian@0 646 */
ian@0 647 if (PortP->statsGather)
ian@0 648 PortP->txchars += len;
ian@0 649
ian@0 650 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
ian@0 651 return p->RIOHalted ? RIO_FAIL : ~RIO_FAIL;
ian@0 652 }
ian@0 653
ian@0 654