PageRenderTime 59ms CodeModel.GetById 11ms app.highlight 41ms RepoModel.GetById 1ms app.codeStats 1ms

/drivers/char/generic_serial.c

https://bitbucket.org/evzijst/gittest
C | 1001 lines | 659 code | 217 blank | 125 comment | 170 complexity | 63190dd0adf5556bdefa55dd4f347f28 MD5 | raw file
   1/*
   2 *  generic_serial.c
   3 *
   4 *  Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl
   5 *
   6 *  written for the SX serial driver.
   7 *     Contains the code that should be shared over all the serial drivers.
   8 *
   9 *  Credit for the idea to do it this way might go to Alan Cox. 
  10 *
  11 *
  12 *  Version 0.1 -- December, 1998. Initial version.
  13 *  Version 0.2 -- March, 1999.    Some more routines. Bugfixes. Etc.
  14 *  Version 0.5 -- August, 1999.   Some more fixes. Reformat for Linus.
  15 *
  16 *  BitWizard is actively maintaining this file. We sometimes find
  17 *  that someone submitted changes to this file. We really appreciate
  18 *  your help, but please submit changes through us. We're doing our
  19 *  best to be responsive.  -- REW
  20 * */
  21
  22#include <linux/module.h>
  23#include <linux/kernel.h>
  24#include <linux/tty.h>
  25#include <linux/serial.h>
  26#include <linux/mm.h>
  27#include <linux/generic_serial.h>
  28#include <linux/interrupt.h>
  29#include <linux/tty_flip.h>
  30#include <linux/delay.h>
  31#include <asm/semaphore.h>
  32#include <asm/uaccess.h>
  33
  34#define DEBUG 
  35
  36static char *                  tmp_buf; 
  37static DECLARE_MUTEX(tmp_buf_sem);
  38
  39static int gs_debug;
  40
  41#ifdef DEBUG
  42#define gs_dprintk(f, str...) if (gs_debug & f) printk (str)
  43#else
  44#define gs_dprintk(f, str...) /* nothing */
  45#endif
  46
  47#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __FUNCTION__)
  48#define func_exit()  gs_dprintk (GS_DEBUG_FLOW, "gs: exit  %s\n", __FUNCTION__)
  49#define NEW_WRITE_LOCKING 1
  50#if NEW_WRITE_LOCKING
  51#define DECL      /* Nothing */
  52#define LOCKIT    down (& port->port_write_sem);
  53#define RELEASEIT up (&port->port_write_sem);
  54#else
  55#define DECL      unsigned long flags;
  56#define LOCKIT    save_flags (flags);cli ()
  57#define RELEASEIT restore_flags (flags)
  58#endif
  59
  60#define RS_EVENT_WRITE_WAKEUP	1
  61
  62module_param(gs_debug, int, 0644);
  63
  64
  65void gs_put_char(struct tty_struct * tty, unsigned char ch)
  66{
  67	struct gs_port *port;
  68	DECL
  69
  70	func_enter (); 
  71
  72	if (!tty) return;
  73
  74	port = tty->driver_data;
  75
  76	if (!port) return;
  77
  78	if (! (port->flags & ASYNC_INITIALIZED)) return;
  79
  80	/* Take a lock on the serial tranmit buffer! */
  81	LOCKIT;
  82
  83	if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
  84		/* Sorry, buffer is full, drop character. Update statistics???? -- REW */
  85		RELEASEIT;
  86		return;
  87	}
  88
  89	port->xmit_buf[port->xmit_head++] = ch;
  90	port->xmit_head &= SERIAL_XMIT_SIZE - 1;
  91	port->xmit_cnt++;  /* Characters in buffer */
  92
  93	RELEASEIT;
  94	func_exit ();
  95}
  96
  97
  98#ifdef NEW_WRITE_LOCKING
  99
 100/*
 101> Problems to take into account are:
 102>       -1- Interrupts that empty part of the buffer.
 103>       -2- page faults on the access to userspace. 
 104>       -3- Other processes that are also trying to do a "write". 
 105*/
 106
 107int gs_write(struct tty_struct * tty, 
 108                    const unsigned char *buf, int count)
 109{
 110	struct gs_port *port;
 111	int c, total = 0;
 112	int t;
 113
 114	func_enter ();
 115
 116	if (!tty) return 0;
 117
 118	port = tty->driver_data;
 119
 120	if (!port) return 0;
 121
 122	if (! (port->flags & ASYNC_INITIALIZED))
 123		return 0;
 124
 125	/* get exclusive "write" access to this port (problem 3) */
 126	/* This is not a spinlock because we can have a disk access (page 
 127		 fault) in copy_from_user */
 128	down (& port->port_write_sem);
 129
 130	while (1) {
 131
 132		c = count;
 133 
 134		/* This is safe because we "OWN" the "head". Noone else can 
 135		   change the "head": we own the port_write_sem. */
 136		/* Don't overrun the end of the buffer */
 137		t = SERIAL_XMIT_SIZE - port->xmit_head;
 138		if (t < c) c = t;
 139 
 140		/* This is safe because the xmit_cnt can only decrease. This 
 141		   would increase "t", so we might copy too little chars. */
 142		/* Don't copy past the "head" of the buffer */
 143		t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt;
 144		if (t < c) c = t;
 145 
 146		/* Can't copy more? break out! */
 147		if (c <= 0) break;
 148
 149		memcpy (port->xmit_buf + port->xmit_head, buf, c);
 150
 151		port -> xmit_cnt += c;
 152		port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1);
 153		buf += c;
 154		count -= c;
 155		total += c;
 156	}
 157	up (& port->port_write_sem);
 158
 159	gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n", 
 160	            (port->flags & GS_TX_INTEN)?"enabled": "disabled"); 
 161
 162	if (port->xmit_cnt && 
 163	    !tty->stopped && 
 164	    !tty->hw_stopped &&
 165	    !(port->flags & GS_TX_INTEN)) {
 166		port->flags |= GS_TX_INTEN;
 167		port->rd->enable_tx_interrupts (port);
 168	}
 169	func_exit ();
 170	return total;
 171}
 172#else
 173/*
 174> Problems to take into account are:
 175>       -1- Interrupts that empty part of the buffer.
 176>       -2- page faults on the access to userspace. 
 177>       -3- Other processes that are also trying to do a "write". 
 178*/
 179
 180int gs_write(struct tty_struct * tty,
 181                    const unsigned char *buf, int count)
 182{
 183	struct gs_port *port;
 184	int c, total = 0;
 185	int t;
 186	unsigned long flags;
 187
 188	func_enter ();
 189
 190	/* The standard serial driver returns 0 in this case. 
 191	   That sounds to me as "No error, I just didn't get to writing any
 192	   bytes. Feel free to try again." 
 193	   The "official" way to write n bytes from buf is:
 194
 195		 for (nwritten = 0;nwritten < n;nwritten += rv) {
 196			 rv = write (fd, buf+nwritten, n-nwritten);
 197			 if (rv < 0) break; // Error: bail out. //
 198		 } 
 199
 200	   which will loop endlessly in this case. The manual page for write
 201	   agrees with me. In practise almost everybody writes 
 202	   "write (fd, buf,n);" but some people might have had to deal with 
 203	   incomplete writes in the past and correctly implemented it by now... 
 204	 */
 205
 206	if (!tty) return -EIO;
 207
 208	port = tty->driver_data;
 209	if (!port || !port->xmit_buf || !tmp_buf)
 210		return -EIO;
 211
 212	local_save_flags(flags);
 213	while (1) {
 214		cli();
 215		c = count;
 216
 217		/* This is safe because we "OWN" the "head". Noone else can 
 218		   change the "head": we own the port_write_sem. */
 219		/* Don't overrun the end of the buffer */
 220		t = SERIAL_XMIT_SIZE - port->xmit_head;
 221		if (t < c) c = t;
 222
 223		/* This is safe because the xmit_cnt can only decrease. This 
 224		   would increase "t", so we might copy too little chars. */
 225		/* Don't copy past the "head" of the buffer */
 226		t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt;
 227		if (t < c) c = t;
 228
 229		/* Can't copy more? break out! */
 230		if (c <= 0) {
 231			local_restore_flags(flags);
 232			break;
 233		}
 234		memcpy(port->xmit_buf + port->xmit_head, buf, c);
 235		port->xmit_head = ((port->xmit_head + c) &
 236		                   (SERIAL_XMIT_SIZE-1));
 237		port->xmit_cnt += c;
 238		local_restore_flags(flags);
 239		buf += c;
 240		count -= c;
 241		total += c;
 242	}
 243
 244	if (port->xmit_cnt && 
 245	    !tty->stopped && 
 246	    !tty->hw_stopped &&
 247	    !(port->flags & GS_TX_INTEN)) {
 248		port->flags |= GS_TX_INTEN;
 249		port->rd->enable_tx_interrupts (port);
 250	}
 251	func_exit ();
 252	return total;
 253}
 254
 255#endif
 256
 257
 258
 259int gs_write_room(struct tty_struct * tty)
 260{
 261	struct gs_port *port = tty->driver_data;
 262	int ret;
 263
 264	func_enter ();
 265	ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
 266	if (ret < 0)
 267		ret = 0;
 268	func_exit ();
 269	return ret;
 270}
 271
 272
 273int gs_chars_in_buffer(struct tty_struct *tty)
 274{
 275	struct gs_port *port = tty->driver_data;
 276	func_enter ();
 277
 278	func_exit ();
 279	return port->xmit_cnt;
 280}
 281
 282
 283static int gs_real_chars_in_buffer(struct tty_struct *tty)
 284{
 285	struct gs_port *port;
 286	func_enter ();
 287
 288	if (!tty) return 0;
 289	port = tty->driver_data;
 290
 291	if (!port->rd) return 0;
 292	if (!port->rd->chars_in_buffer) return 0;
 293
 294	func_exit ();
 295	return port->xmit_cnt + port->rd->chars_in_buffer (port);
 296}
 297
 298
 299static int gs_wait_tx_flushed (void * ptr, unsigned long timeout) 
 300{
 301	struct gs_port *port = ptr;
 302	unsigned long end_jiffies;
 303	int jiffies_to_transmit, charsleft = 0, rv = 0;
 304	int rcib;
 305
 306	func_enter();
 307
 308	gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port);
 309	if (port) {
 310		gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n", 
 311		port->xmit_cnt, port->xmit_buf, port->tty);
 312	}
 313
 314	if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
 315		gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n");
 316		func_exit();
 317		return -EINVAL;  /* This is an error which we don't know how to handle. */
 318	}
 319
 320	rcib = gs_real_chars_in_buffer(port->tty);
 321
 322	if(rcib <= 0) {
 323		gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
 324		func_exit();
 325		return rv;
 326	}
 327	/* stop trying: now + twice the time it would normally take +  seconds */
 328	if (timeout == 0) timeout = MAX_SCHEDULE_TIMEOUT;
 329	end_jiffies  = jiffies; 
 330	if (timeout !=  MAX_SCHEDULE_TIMEOUT)
 331		end_jiffies += port->baud?(2 * rcib * 10 * HZ / port->baud):0;
 332	end_jiffies += timeout;
 333
 334	gs_dprintk (GS_DEBUG_FLUSH, "now=%lx, end=%lx (%ld).\n", 
 335		    jiffies, end_jiffies, end_jiffies-jiffies); 
 336
 337	/* the expression is actually jiffies < end_jiffies, but that won't
 338	   work around the wraparound. Tricky eh? */
 339	while ((charsleft = gs_real_chars_in_buffer (port->tty)) &&
 340	        time_after (end_jiffies, jiffies)) {
 341		/* Units check: 
 342		   chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies!
 343		   check! */
 344
 345		charsleft += 16; /* Allow 16 chars more to be transmitted ... */
 346		jiffies_to_transmit = port->baud?(1 + charsleft * 10 * HZ / port->baud):0;
 347		/*                                ^^^ Round up.... */
 348		if (jiffies_to_transmit <= 0) jiffies_to_transmit = 1;
 349
 350		gs_dprintk (GS_DEBUG_FLUSH, "Expect to finish in %d jiffies "
 351			    "(%d chars).\n", jiffies_to_transmit, charsleft); 
 352
 353		msleep_interruptible(jiffies_to_msecs(jiffies_to_transmit));
 354		if (signal_pending (current)) {
 355			gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: "); 
 356			rv = -EINTR;
 357			break;
 358		}
 359	}
 360
 361	gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft); 
 362	set_current_state (TASK_RUNNING);
 363
 364	func_exit();
 365	return rv;
 366}
 367
 368
 369
 370void gs_flush_buffer(struct tty_struct *tty)
 371{
 372	struct gs_port *port;
 373	unsigned long flags;
 374
 375	func_enter ();
 376
 377	if (!tty) return;
 378
 379	port = tty->driver_data;
 380
 381	if (!port) return;
 382
 383	/* XXX Would the write semaphore do? */
 384	spin_lock_irqsave (&port->driver_lock, flags);
 385	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 386	spin_unlock_irqrestore (&port->driver_lock, flags);
 387
 388	wake_up_interruptible(&tty->write_wait);
 389	tty_wakeup(tty);
 390	func_exit ();
 391}
 392
 393
 394void gs_flush_chars(struct tty_struct * tty)
 395{
 396	struct gs_port *port;
 397
 398	func_enter ();
 399
 400	if (!tty) return;
 401
 402	port = tty->driver_data;
 403
 404	if (!port) return;
 405
 406	if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
 407	    !port->xmit_buf) {
 408		func_exit ();
 409		return;
 410	}
 411
 412	/* Beats me -- REW */
 413	port->flags |= GS_TX_INTEN;
 414	port->rd->enable_tx_interrupts (port);
 415	func_exit ();
 416}
 417
 418
 419void gs_stop(struct tty_struct * tty)
 420{
 421	struct gs_port *port;
 422
 423	func_enter ();
 424
 425	if (!tty) return;
 426
 427	port = tty->driver_data;
 428
 429	if (!port) return;
 430
 431	if (port->xmit_cnt && 
 432	    port->xmit_buf && 
 433	    (port->flags & GS_TX_INTEN) ) {
 434		port->flags &= ~GS_TX_INTEN;
 435		port->rd->disable_tx_interrupts (port);
 436	}
 437	func_exit ();
 438}
 439
 440
 441void gs_start(struct tty_struct * tty)
 442{
 443	struct gs_port *port;
 444
 445	if (!tty) return;
 446
 447	port = tty->driver_data;
 448
 449	if (!port) return;
 450
 451	if (port->xmit_cnt && 
 452	    port->xmit_buf && 
 453	    !(port->flags & GS_TX_INTEN) ) {
 454		port->flags |= GS_TX_INTEN;
 455		port->rd->enable_tx_interrupts (port);
 456	}
 457	func_exit ();
 458}
 459
 460
 461static void gs_shutdown_port (struct gs_port *port)
 462{
 463	unsigned long flags;
 464
 465	func_enter();
 466	
 467	if (!port) return;
 468	
 469	if (!(port->flags & ASYNC_INITIALIZED))
 470		return;
 471
 472	spin_lock_irqsave(&port->driver_lock, flags);
 473
 474	if (port->xmit_buf) {
 475		free_page((unsigned long) port->xmit_buf);
 476		port->xmit_buf = NULL;
 477	}
 478
 479	if (port->tty)
 480		set_bit(TTY_IO_ERROR, &port->tty->flags);
 481
 482	port->rd->shutdown_port (port);
 483
 484	port->flags &= ~ASYNC_INITIALIZED;
 485	spin_unlock_irqrestore(&port->driver_lock, flags);
 486
 487	func_exit();
 488}
 489
 490
 491void gs_hangup(struct tty_struct *tty)
 492{
 493	struct gs_port   *port;
 494
 495	func_enter ();
 496
 497	if (!tty) return;
 498
 499	port = tty->driver_data;
 500	tty = port->tty;
 501	if (!tty) 
 502		return;
 503
 504	gs_shutdown_port (port);
 505	port->flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE);
 506	port->tty = NULL;
 507	port->count = 0;
 508
 509	wake_up_interruptible(&port->open_wait);
 510	func_exit ();
 511}
 512
 513
 514int gs_block_til_ready(void *port_, struct file * filp)
 515{
 516	struct gs_port *port = port_;
 517	DECLARE_WAITQUEUE(wait, current);
 518	int    retval;
 519	int    do_clocal = 0;
 520	int    CD;
 521	struct tty_struct *tty;
 522	unsigned long flags;
 523
 524	func_enter ();
 525
 526	if (!port) return 0;
 527
 528	tty = port->tty;
 529
 530	if (!tty) return 0;
 531
 532	gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); 
 533	/*
 534	 * If the device is in the middle of being closed, then block
 535	 * until it's done, and then try again.
 536	 */
 537	if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
 538		interruptible_sleep_on(&port->close_wait);
 539		if (port->flags & ASYNC_HUP_NOTIFY)
 540			return -EAGAIN;
 541		else
 542			return -ERESTARTSYS;
 543	}
 544
 545	gs_dprintk (GS_DEBUG_BTR, "after hung up\n"); 
 546
 547	/*
 548	 * If non-blocking mode is set, or the port is not enabled,
 549	 * then make the check up front and then exit.
 550	 */
 551	if ((filp->f_flags & O_NONBLOCK) ||
 552	    (tty->flags & (1 << TTY_IO_ERROR))) {
 553		port->flags |= ASYNC_NORMAL_ACTIVE;
 554		return 0;
 555	}
 556
 557	gs_dprintk (GS_DEBUG_BTR, "after nonblock\n"); 
 558 
 559	if (C_CLOCAL(tty))
 560		do_clocal = 1;
 561
 562	/*
 563	 * Block waiting for the carrier detect and the line to become
 564	 * free (i.e., not in use by the callout).  While we are in
 565	 * this loop, port->count is dropped by one, so that
 566	 * rs_close() knows when to free things.  We restore it upon
 567	 * exit, either normal or abnormal.
 568	 */
 569	retval = 0;
 570
 571	add_wait_queue(&port->open_wait, &wait);
 572
 573	gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); 
 574	spin_lock_irqsave(&port->driver_lock, flags);
 575	if (!tty_hung_up_p(filp)) {
 576		port->count--;
 577	}
 578	spin_unlock_irqrestore(&port->driver_lock, flags);
 579	port->blocked_open++;
 580	while (1) {
 581		CD = port->rd->get_CD (port);
 582		gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD);
 583		set_current_state (TASK_INTERRUPTIBLE);
 584		if (tty_hung_up_p(filp) ||
 585		    !(port->flags & ASYNC_INITIALIZED)) {
 586			if (port->flags & ASYNC_HUP_NOTIFY)
 587				retval = -EAGAIN;
 588			else
 589				retval = -ERESTARTSYS;
 590			break;
 591		}
 592		if (!(port->flags & ASYNC_CLOSING) &&
 593		    (do_clocal || CD))
 594			break;
 595		gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", 
 596		(int)signal_pending (current), *(long*)(&current->blocked)); 
 597		if (signal_pending(current)) {
 598			retval = -ERESTARTSYS;
 599			break;
 600		}
 601		schedule();
 602	}
 603	gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n",
 604		    port->blocked_open);
 605	set_current_state (TASK_RUNNING);
 606	remove_wait_queue(&port->open_wait, &wait);
 607	if (!tty_hung_up_p(filp)) {
 608		port->count++;
 609	}
 610	port->blocked_open--;
 611	if (retval)
 612		return retval;
 613
 614	port->flags |= ASYNC_NORMAL_ACTIVE;
 615	func_exit ();
 616	return 0;
 617}			 
 618
 619
 620void gs_close(struct tty_struct * tty, struct file * filp)
 621{
 622	unsigned long flags;
 623	struct gs_port *port;
 624	
 625	func_enter ();
 626
 627	if (!tty) return;
 628
 629	port = (struct gs_port *) tty->driver_data;
 630
 631	if (!port) return;
 632
 633	if (!port->tty) {
 634		/* This seems to happen when this is called from vhangup. */
 635		gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->tty is NULL\n");
 636		port->tty = tty;
 637	}
 638
 639	spin_lock_irqsave(&port->driver_lock, flags);
 640
 641	if (tty_hung_up_p(filp)) {
 642		spin_unlock_irqrestore(&port->driver_lock, flags);
 643		if (port->rd->hungup)
 644			port->rd->hungup (port);
 645		func_exit ();
 646		return;
 647	}
 648
 649	if ((tty->count == 1) && (port->count != 1)) {
 650		printk(KERN_ERR "gs: gs_close port %p: bad port count;"
 651		       " tty->count is 1, port count is %d\n", port, port->count);
 652		port->count = 1;
 653	}
 654	if (--port->count < 0) {
 655		printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->count);
 656		port->count = 0;
 657	}
 658
 659	if (port->count) {
 660		gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->count);
 661		spin_unlock_irqrestore(&port->driver_lock, flags);
 662		func_exit ();
 663		return;
 664	}
 665	port->flags |= ASYNC_CLOSING;
 666
 667	/*
 668	 * Now we wait for the transmit buffer to clear; and we notify 
 669	 * the line discipline to only process XON/XOFF characters.
 670	 */
 671	tty->closing = 1;
 672	/* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
 673	   tty_wait_until_sent(tty, port->closing_wait); */
 674
 675	/*
 676	 * At this point we stop accepting input.  To do this, we
 677	 * disable the receive line status interrupts, and tell the
 678	 * interrupt driver to stop checking the data ready bit in the
 679	 * line status register.
 680	 */
 681
 682	port->rd->disable_rx_interrupts (port);
 683	spin_unlock_irqrestore(&port->driver_lock, flags);
 684
 685	/* close has no way of returning "EINTR", so discard return value */
 686	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
 687		gs_wait_tx_flushed (port, port->closing_wait);
 688
 689	port->flags &= ~GS_ACTIVE;
 690
 691	if (tty->driver->flush_buffer)
 692		tty->driver->flush_buffer(tty);
 693
 694	tty_ldisc_flush(tty);
 695	tty->closing = 0;
 696
 697	port->event = 0;
 698	port->rd->close (port);
 699	port->rd->shutdown_port (port);
 700	port->tty = NULL;
 701
 702	if (port->blocked_open) {
 703		if (port->close_delay) {
 704			spin_unlock_irqrestore(&port->driver_lock, flags);
 705			msleep_interruptible(jiffies_to_msecs(port->close_delay));
 706			spin_lock_irqsave(&port->driver_lock, flags);
 707		}
 708		wake_up_interruptible(&port->open_wait);
 709	}
 710	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED);
 711	wake_up_interruptible(&port->close_wait);
 712
 713	func_exit ();
 714}
 715
 716
 717static unsigned int     gs_baudrates[] = {
 718  0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 719  9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
 720};
 721
 722
 723void gs_set_termios (struct tty_struct * tty, 
 724                     struct termios * old_termios)
 725{
 726	struct gs_port *port;
 727	int baudrate, tmp, rv;
 728	struct termios *tiosp;
 729
 730	func_enter();
 731
 732	if (!tty) return;
 733
 734	port = tty->driver_data;
 735
 736	if (!port) return;
 737	if (!port->tty) {
 738		/* This seems to happen when this is called after gs_close. */
 739		gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->tty is NULL\n");
 740		port->tty = tty;
 741	}
 742
 743
 744	tiosp = tty->termios;
 745
 746	if (gs_debug & GS_DEBUG_TERMIOS) {
 747		gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
 748	}
 749
 750#if 0
 751	/* This is an optimization that is only allowed for dumb cards */
 752	/* Smart cards require knowledge of iflags and oflags too: that 
 753	   might change hardware cooking mode.... */
 754#endif
 755	if (old_termios) {
 756		if(   (tiosp->c_iflag == old_termios->c_iflag)
 757		   && (tiosp->c_oflag == old_termios->c_oflag)
 758		   && (tiosp->c_cflag == old_termios->c_cflag)
 759		   && (tiosp->c_lflag == old_termios->c_lflag)
 760		   && (tiosp->c_line  == old_termios->c_line)
 761		   && (memcmp(tiosp->c_cc, old_termios->c_cc, NCC) == 0)) {
 762			gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: optimized away\n");
 763			return /* 0 */;
 764		}
 765	} else 
 766		gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: no old_termios: "
 767		           "no optimization\n");
 768
 769	if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) {
 770		if(tiosp->c_iflag != old_termios->c_iflag)  printk("c_iflag changed\n");
 771		if(tiosp->c_oflag != old_termios->c_oflag)  printk("c_oflag changed\n");
 772		if(tiosp->c_cflag != old_termios->c_cflag)  printk("c_cflag changed\n");
 773		if(tiosp->c_lflag != old_termios->c_lflag)  printk("c_lflag changed\n");
 774		if(tiosp->c_line  != old_termios->c_line)   printk("c_line changed\n");
 775		if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n");
 776	}
 777
 778	baudrate = tiosp->c_cflag & CBAUD;
 779	if (baudrate & CBAUDEX) {
 780		baudrate &= ~CBAUDEX;
 781		if ((baudrate < 1) || (baudrate > 4))
 782			tiosp->c_cflag &= ~CBAUDEX;
 783		else
 784			baudrate += 15;
 785	}
 786
 787	baudrate = gs_baudrates[baudrate];
 788	if ((tiosp->c_cflag & CBAUD) == B38400) {
 789		if (     (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 790			baudrate = 57600;
 791		else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 792			baudrate = 115200;
 793		else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
 794			baudrate = 230400;
 795		else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
 796			baudrate = 460800;
 797		else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
 798			baudrate = (port->baud_base / port->custom_divisor);
 799	}
 800
 801	/* I recommend using THIS instead of the mess in termios (and
 802	   duplicating the above code). Next we should create a clean
 803	   interface towards this variable. If your card supports arbitrary
 804	   baud rates, (e.g. CD1400 or 16550 based cards) then everything
 805	   will be very easy..... */
 806	port->baud = baudrate;
 807
 808	/* Two timer ticks seems enough to wakeup something like SLIP driver */
 809	/* Baudrate/10 is cps. Divide by HZ to get chars per tick. */
 810	tmp = (baudrate / 10 / HZ) * 2;			 
 811
 812	if (tmp <                 0) tmp = 0;
 813	if (tmp >= SERIAL_XMIT_SIZE) tmp = SERIAL_XMIT_SIZE-1;
 814
 815	port->wakeup_chars = tmp;
 816
 817	/* We should really wait for the characters to be all sent before
 818	   changing the settings. -- CAL */
 819	rv = gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT);
 820	if (rv < 0) return /* rv */;
 821
 822	rv = port->rd->set_real_termios(port);
 823	if (rv < 0) return /* rv */;
 824
 825	if ((!old_termios || 
 826	     (old_termios->c_cflag & CRTSCTS)) &&
 827	    !(      tiosp->c_cflag & CRTSCTS)) {
 828		tty->stopped = 0;
 829		gs_start(tty);
 830	}
 831
 832#ifdef tytso_patch_94Nov25_1726
 833	/* This "makes sense", Why is it commented out? */
 834
 835	if (!(old_termios->c_cflag & CLOCAL) &&
 836	    (tty->termios->c_cflag & CLOCAL))
 837		wake_up_interruptible(&port->gs.open_wait);
 838#endif
 839
 840	func_exit();
 841	return /* 0 */;
 842}
 843
 844
 845
 846/* Must be called with interrupts enabled */
 847int gs_init_port(struct gs_port *port)
 848{
 849	unsigned long flags;
 850	unsigned long page;
 851
 852	func_enter ();
 853
 854        if (!tmp_buf) {
 855		page = get_zeroed_page(GFP_KERNEL);
 856		spin_lock_irqsave (&port->driver_lock, flags); /* Don't expect this to make a difference. */
 857		if (tmp_buf)
 858			free_page(page);
 859		else
 860			tmp_buf = (unsigned char *) page;
 861		spin_unlock_irqrestore (&port->driver_lock, flags);
 862		if (!tmp_buf) {
 863			func_exit ();
 864			return -ENOMEM;
 865		}
 866	}
 867
 868	if (port->flags & ASYNC_INITIALIZED) {
 869		func_exit ();
 870		return 0;
 871	}
 872	if (!port->xmit_buf) {
 873		/* We may sleep in get_zeroed_page() */
 874		unsigned long tmp;
 875
 876		tmp = get_zeroed_page(GFP_KERNEL);
 877		spin_lock_irqsave (&port->driver_lock, flags);
 878		if (port->xmit_buf) 
 879			free_page (tmp);
 880		else
 881			port->xmit_buf = (unsigned char *) tmp;
 882		spin_unlock_irqrestore(&port->driver_lock, flags);
 883		if (!port->xmit_buf) {
 884			func_exit ();
 885			return -ENOMEM;
 886		}
 887	}
 888
 889	spin_lock_irqsave (&port->driver_lock, flags);
 890	if (port->tty) 
 891		clear_bit(TTY_IO_ERROR, &port->tty->flags);
 892	init_MUTEX(&port->port_write_sem);
 893	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 894	spin_unlock_irqrestore(&port->driver_lock, flags);
 895	gs_set_termios(port->tty, NULL);
 896	spin_lock_irqsave (&port->driver_lock, flags);
 897	port->flags |= ASYNC_INITIALIZED;
 898	port->flags &= ~GS_TX_INTEN;
 899
 900	spin_unlock_irqrestore(&port->driver_lock, flags);
 901	func_exit ();
 902	return 0;
 903}
 904
 905
 906int gs_setserial(struct gs_port *port, struct serial_struct __user *sp)
 907{
 908	struct serial_struct sio;
 909
 910	if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
 911		return(-EFAULT);
 912
 913	if (!capable(CAP_SYS_ADMIN)) {
 914		if ((sio.baud_base != port->baud_base) ||
 915		    (sio.close_delay != port->close_delay) ||
 916		    ((sio.flags & ~ASYNC_USR_MASK) !=
 917		     (port->flags & ~ASYNC_USR_MASK)))
 918			return(-EPERM);
 919	} 
 920
 921	port->flags = (port->flags & ~ASYNC_USR_MASK) |
 922		(sio.flags & ASYNC_USR_MASK);
 923  
 924	port->baud_base = sio.baud_base;
 925	port->close_delay = sio.close_delay;
 926	port->closing_wait = sio.closing_wait;
 927	port->custom_divisor = sio.custom_divisor;
 928
 929	gs_set_termios (port->tty, NULL);
 930
 931	return 0;
 932}
 933
 934
 935/*****************************************************************************/
 936
 937/*
 938 *      Generate the serial struct info.
 939 */
 940
 941int gs_getserial(struct gs_port *port, struct serial_struct __user *sp)
 942{
 943	struct serial_struct    sio;
 944
 945	memset(&sio, 0, sizeof(struct serial_struct));
 946	sio.flags = port->flags;
 947	sio.baud_base = port->baud_base;
 948	sio.close_delay = port->close_delay;
 949	sio.closing_wait = port->closing_wait;
 950	sio.custom_divisor = port->custom_divisor;
 951	sio.hub6 = 0;
 952
 953	/* If you want you can override these. */
 954	sio.type = PORT_UNKNOWN;
 955	sio.xmit_fifo_size = -1;
 956	sio.line = -1;
 957	sio.port = -1;
 958	sio.irq = -1;
 959
 960	if (port->rd->getserial)
 961		port->rd->getserial (port, &sio);
 962
 963	if (copy_to_user(sp, &sio, sizeof(struct serial_struct)))
 964		return -EFAULT;
 965	return 0;
 966
 967}
 968
 969
 970void gs_got_break(struct gs_port *port)
 971{
 972	func_enter ();
 973
 974	tty_insert_flip_char(port->tty, 0, TTY_BREAK);
 975	tty_schedule_flip(port->tty);
 976	if (port->flags & ASYNC_SAK) {
 977		do_SAK (port->tty);
 978	}
 979
 980	func_exit ();
 981}
 982
 983
 984EXPORT_SYMBOL(gs_put_char);
 985EXPORT_SYMBOL(gs_write);
 986EXPORT_SYMBOL(gs_write_room);
 987EXPORT_SYMBOL(gs_chars_in_buffer);
 988EXPORT_SYMBOL(gs_flush_buffer);
 989EXPORT_SYMBOL(gs_flush_chars);
 990EXPORT_SYMBOL(gs_stop);
 991EXPORT_SYMBOL(gs_start);
 992EXPORT_SYMBOL(gs_hangup);
 993EXPORT_SYMBOL(gs_block_til_ready);
 994EXPORT_SYMBOL(gs_close);
 995EXPORT_SYMBOL(gs_set_termios);
 996EXPORT_SYMBOL(gs_init_port);
 997EXPORT_SYMBOL(gs_setserial);
 998EXPORT_SYMBOL(gs_getserial);
 999EXPORT_SYMBOL(gs_got_break);
1000
1001MODULE_LICENSE("GPL");