1/*
2 * Simulated Serial Driver (fake serial)
3 *
4 * This driver is mostly used for bringup purposes and will go away.
5 * It has a strong dependency on the system console. All outputs
6 * are rerouted to the same facility as the one used by printk which, in our
7 * case means sys_sim.c console (goes via the simulator). The code hereafter
8 * is completely leveraged from the serial.c driver.
9 *
10 * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co
11 *	Stephane Eranian <eranian@hpl.hp.com>
12 *	David Mosberger-Tang <davidm@hpl.hp.com>
13 *
14 * 02/04/00 D. Mosberger	Merged in serial.c bug fixes in rs_close().
15 * 02/25/00 D. Mosberger	Synced up with 2.3.99pre-5 version of serial.c.
16 * 07/30/02 D. Mosberger	Replace sti()/cli() with explicit spinlocks & local irq masking
17 */
18
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/sched.h>
22#include <linux/tty.h>
23#include <linux/tty_flip.h>
24#include <linux/major.h>
25#include <linux/fcntl.h>
26#include <linux/mm.h>
27#include <linux/slab.h>
28#include <linux/capability.h>
29#include <linux/console.h>
30#include <linux/module.h>
31#include <linux/serial.h>
32#include <linux/serialP.h>
33#include <linux/sysrq.h>
34
35#include <asm/irq.h>
36#include <asm/hw_irq.h>
37#include <asm/uaccess.h>
38
39#ifdef CONFIG_KDB
40# include <linux/kdb.h>
41#endif
42
43#undef SIMSERIAL_DEBUG	/* define this to get some debug information */
44
45#define KEYBOARD_INTR	3	/* must match with simulator! */
46
47#define NR_PORTS	1	/* only one port for now */
48
49#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : IRQF_DISABLED)
50
51#define SSC_GETCHAR	21
52
53extern long ia64_ssc (long, long, long, long, int);
54extern void ia64_ssc_connect_irq (long intr, long irq);
55
56static char *serial_name = "SimSerial driver";
57static char *serial_version = "0.6";
58
59/*
60 * This has been extracted from asm/serial.h. We need one eventually but
61 * I don't know exactly what we're going to put in it so just fake one
62 * for now.
63 */
64#define BASE_BAUD ( 1843200 / 16 )
65
66#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
67
68/*
69 * Most of the values here are meaningless to this particular driver.
70 * However some values must be preserved for the code (leveraged from serial.c
71 * to work correctly).
72 * port must not be 0
73 * type must not be UNKNOWN
74 * So I picked arbitrary (guess from where?) values instead
75 */
76static struct serial_state rs_table[NR_PORTS]={
77  /* UART CLK   PORT IRQ     FLAGS        */
78  { 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 }  /* ttyS0 */
79};
80
81/*
82 * Just for the fun of it !
83 */
84static struct serial_uart_config uart_config[] = {
85	{ "unknown", 1, 0 },
86	{ "8250", 1, 0 },
87	{ "16450", 1, 0 },
88	{ "16550", 1, 0 },
89	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
90	{ "cirrus", 1, 0 },
91	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },
92	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
93		  UART_STARTECH },
94	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
95	{ NULL, 0}
96};
97
98struct tty_driver *hp_simserial_driver;
99
100static struct async_struct *IRQ_ports[NR_IRQS];
101
102static struct console *console;
103
104static unsigned char *tmp_buf;
105
106extern struct console *console_drivers; /* from kernel/printk.c */
107
108/*
109 * ------------------------------------------------------------
110 * rs_stop() and rs_start()
111 *
112 * This routines are called before setting or resetting tty->stopped.
113 * They enable or disable transmitter interrupts, as necessary.
114 * ------------------------------------------------------------
115 */
116static void rs_stop(struct tty_struct *tty)
117{
118#ifdef SIMSERIAL_DEBUG
119	printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
120		tty->stopped, tty->hw_stopped, tty->flow_stopped);
121#endif
122
123}
124
125static void rs_start(struct tty_struct *tty)
126{
127#ifdef SIMSERIAL_DEBUG
128	printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
129		tty->stopped, tty->hw_stopped, tty->flow_stopped);
130#endif
131}
132
133static  void receive_chars(struct tty_struct *tty)
134{
135	unsigned char ch;
136	static unsigned char seen_esc = 0;
137
138	while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) {
139		if ( ch == 27 && seen_esc == 0 ) {
140			seen_esc = 1;
141			continue;
142		} else {
143			if ( seen_esc==1 && ch == 'O' ) {
144				seen_esc = 2;
145				continue;
146			} else if ( seen_esc == 2 ) {
147				if ( ch == 'P' ) /* F1 */
148					show_state();
149#ifdef CONFIG_MAGIC_SYSRQ
150				if ( ch == 'S' ) { /* F4 */
151					do
152						ch = ia64_ssc(0, 0, 0, 0,
153							      SSC_GETCHAR);
154					while (!ch);
155					handle_sysrq(ch, NULL);
156				}
157#endif
158				seen_esc = 0;
159				continue;
160			}
161		}
162		seen_esc = 0;
163
164		if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0)
165			break;
166	}
167	tty_flip_buffer_push(tty);
168}
169
170/*
171 * This is the serial driver's interrupt routine for a single port
172 */
173static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
174{
175	struct async_struct * info;
176
177	/*
178	 * I don't know exactly why they don't use the dev_id opaque data
179	 * pointer instead of this extra lookup table
180	 */
181	info = IRQ_ports[irq];
182	if (!info || !info->tty) {
183		printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info);
184		return IRQ_NONE;
185	}
186	/*
187	 * pretty simple in our case, because we only get interrupts
188	 * on inbound traffic
189	 */
190	receive_chars(info->tty);
191	return IRQ_HANDLED;
192}
193
194/*
195 * -------------------------------------------------------------------
196 * Here ends the serial interrupt routines.
197 * -------------------------------------------------------------------
198 */
199
200
201static void do_softint(struct work_struct *private_)
202{
203	printk(KERN_ERR "simserial: do_softint called\n");
204}
205
206static void rs_put_char(struct tty_struct *tty, unsigned char ch)
207{
208	struct async_struct *info = (struct async_struct *)tty->driver_data;
209	unsigned long flags;
210
211	if (!tty || !info->xmit.buf) return;
212
213	local_irq_save(flags);
214	if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) {
215		local_irq_restore(flags);
216		return;
217	}
218	info->xmit.buf[info->xmit.head] = ch;
219	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
220	local_irq_restore(flags);
221}
222
223static void transmit_chars(struct async_struct *info, int *intr_done)
224{
225	int count;
226	unsigned long flags;
227
228
229	local_irq_save(flags);
230
231	if (info->x_char) {
232		char c = info->x_char;
233
234		console->write(console, &c, 1);
235
236		info->state->icount.tx++;
237		info->x_char = 0;
238
239		goto out;
240	}
241
242	if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) {
243#ifdef SIMSERIAL_DEBUG
244		printk("transmit_chars: head=%d, tail=%d, stopped=%d\n",
245		       info->xmit.head, info->xmit.tail, info->tty->stopped);
246#endif
247		goto out;
248	}
249	/*
250	 * We removed the loop and try to do it in to chunks. We need
251	 * 2 operations maximum because it's a ring buffer.
252	 *
253	 * First from current to tail if possible.
254	 * Then from the beginning of the buffer until necessary
255	 */
256
257	count = min(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
258		    SERIAL_XMIT_SIZE - info->xmit.tail);
259	console->write(console, info->xmit.buf+info->xmit.tail, count);
260
261	info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1);
262
263	/*
264	 * We have more at the beginning of the buffer
265	 */
266	count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
267	if (count) {
268		console->write(console, info->xmit.buf, count);
269		info->xmit.tail += count;
270	}
271out:
272	local_irq_restore(flags);
273}
274
275static void rs_flush_chars(struct tty_struct *tty)
276{
277	struct async_struct *info = (struct async_struct *)tty->driver_data;
278
279	if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped ||
280	    !info->xmit.buf)
281		return;
282
283	transmit_chars(info, NULL);
284}
285
286
287static int rs_write(struct tty_struct * tty,
288		    const unsigned char *buf, int count)
289{
290	int	c, ret = 0;
291	struct async_struct *info = (struct async_struct *)tty->driver_data;
292	unsigned long flags;
293
294	if (!tty || !info->xmit.buf || !tmp_buf) return 0;
295
296	local_irq_save(flags);
297	while (1) {
298		c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
299		if (count < c)
300			c = count;
301		if (c <= 0) {
302			break;
303		}
304		memcpy(info->xmit.buf + info->xmit.head, buf, c);
305		info->xmit.head = ((info->xmit.head + c) &
306				   (SERIAL_XMIT_SIZE-1));
307		buf += c;
308		count -= c;
309		ret += c;
310	}
311	local_irq_restore(flags);
312	/*
313	 * Hey, we transmit directly from here in our case
314	 */
315	if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE)
316	    && !tty->stopped && !tty->hw_stopped) {
317		transmit_chars(info, NULL);
318	}
319	return ret;
320}
321
322static int rs_write_room(struct tty_struct *tty)
323{
324	struct async_struct *info = (struct async_struct *)tty->driver_data;
325
326	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
327}
328
329static int rs_chars_in_buffer(struct tty_struct *tty)
330{
331	struct async_struct *info = (struct async_struct *)tty->driver_data;
332
333	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
334}
335
336static void rs_flush_buffer(struct tty_struct *tty)
337{
338	struct async_struct *info = (struct async_struct *)tty->driver_data;
339	unsigned long flags;
340
341	local_irq_save(flags);
342	info->xmit.head = info->xmit.tail = 0;
343	local_irq_restore(flags);
344
345	wake_up_interruptible(&tty->write_wait);
346
347	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
348	    tty->ldisc.write_wakeup)
349		(tty->ldisc.write_wakeup)(tty);
350}
351
352/*
353 * This function is used to send a high-priority XON/XOFF character to
354 * the device
355 */
356static void rs_send_xchar(struct tty_struct *tty, char ch)
357{
358	struct async_struct *info = (struct async_struct *)tty->driver_data;
359
360	info->x_char = ch;
361	if (ch) {
362		/*
363		 * I guess we could call console->write() directly but
364		 * let's do that for now.
365		 */
366		transmit_chars(info, NULL);
367	}
368}
369
370/*
371 * ------------------------------------------------------------
372 * rs_throttle()
373 *
374 * This routine is called by the upper-layer tty layer to signal that
375 * incoming characters should be throttled.
376 * ------------------------------------------------------------
377 */
378static void rs_throttle(struct tty_struct * tty)
379{
380	if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty));
381
382	printk(KERN_INFO "simrs_throttle called\n");
383}
384
385static void rs_unthrottle(struct tty_struct * tty)
386{
387	struct async_struct *info = (struct async_struct *)tty->driver_data;
388
389	if (I_IXOFF(tty)) {
390		if (info->x_char)
391			info->x_char = 0;
392		else
393			rs_send_xchar(tty, START_CHAR(tty));
394	}
395	printk(KERN_INFO "simrs_unthrottle called\n");
396}
397
398/*
399 * rs_break() --- routine which turns the break handling on or off
400 */
401static void rs_break(struct tty_struct *tty, int break_state)
402{
403}
404
405static int rs_ioctl(struct tty_struct *tty, struct file * file,
406		    unsigned int cmd, unsigned long arg)
407{
408	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
409	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
410	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
411		if (tty->flags & (1 << TTY_IO_ERROR))
412		    return -EIO;
413	}
414
415	switch (cmd) {
416		case TIOCMGET:
417			printk(KERN_INFO "rs_ioctl: TIOCMGET called\n");
418			return -EINVAL;
419		case TIOCMBIS:
420		case TIOCMBIC:
421		case TIOCMSET:
422			printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n");
423			return -EINVAL;
424		case TIOCGSERIAL:
425			printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n");
426			return 0;
427		case TIOCSSERIAL:
428			printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n");
429			return 0;
430		case TIOCSERCONFIG:
431			printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n");
432			return -EINVAL;
433
434		case TIOCSERGETLSR: /* Get line status register */
435			printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n");
436			return  -EINVAL;
437
438		case TIOCSERGSTRUCT:
439			printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n");
440			return 0;
441
442		/*
443		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
444		 * - mask passed in arg for lines of interest
445		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
446		 * Caller should use TIOCGICOUNT to see which one it was
447		 */
448		case TIOCMIWAIT:
449			printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n");
450			return 0;
451		/*
452		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
453		 * Return: write counters to the user passed counter struct
454		 * NB: both 1->0 and 0->1 transitions are counted except for
455		 *     RI where only 0->1 is counted.
456		 */
457		case TIOCGICOUNT:
458			printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n");
459			return 0;
460
461		case TIOCSERGWILD:
462		case TIOCSERSWILD:
463			/* "setserial -W" is called in Debian boot */
464			printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n");
465			return 0;
466
467		default:
468			return -ENOIOCTLCMD;
469		}
470	return 0;
471}
472
473#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
474
475static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
476{
477	unsigned int cflag = tty->termios->c_cflag;
478
479	if (   (cflag == old_termios->c_cflag)
480	    && (   RELEVANT_IFLAG(tty->termios->c_iflag)
481		== RELEVANT_IFLAG(old_termios->c_iflag)))
482	  return;
483
484
485	/* Handle turning off CRTSCTS */
486	if ((old_termios->c_cflag & CRTSCTS) &&
487	    !(tty->termios->c_cflag & CRTSCTS)) {
488		tty->hw_stopped = 0;
489		rs_start(tty);
490	}
491}
492/*
493 * This routine will shutdown a serial port; interrupts are disabled, and
494 * DTR is dropped if the hangup on close termio flag is on.
495 */
496static void shutdown(struct async_struct * info)
497{
498	unsigned long	flags;
499	struct serial_state *state;
500	int		retval;
501
502	if (!(info->flags & ASYNC_INITIALIZED)) return;
503
504	state = info->state;
505
506#ifdef SIMSERIAL_DEBUG
507	printk("Shutting down serial port %d (irq %d)....", info->line,
508	       state->irq);
509#endif
510
511	local_irq_save(flags);
512	{
513		/*
514		 * First unlink the serial port from the IRQ chain...
515		 */
516		if (info->next_port)
517			info->next_port->prev_port = info->prev_port;
518		if (info->prev_port)
519			info->prev_port->next_port = info->next_port;
520		else
521			IRQ_ports[state->irq] = info->next_port;
522
523		/*
524		 * Free the IRQ, if necessary
525		 */
526		if (state->irq && (!IRQ_ports[state->irq] ||
527				   !IRQ_ports[state->irq]->next_port)) {
528			if (IRQ_ports[state->irq]) {
529				free_irq(state->irq, NULL);
530				retval = request_irq(state->irq, rs_interrupt_single,
531						     IRQ_T(info), "serial", NULL);
532
533				if (retval)
534					printk(KERN_ERR "serial shutdown: request_irq: error %d"
535					       "  Couldn't reacquire IRQ.\n", retval);
536			} else
537				free_irq(state->irq, NULL);
538		}
539
540		if (info->xmit.buf) {
541			free_page((unsigned long) info->xmit.buf);
542			info->xmit.buf = NULL;
543		}
544
545		if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
546
547		info->flags &= ~ASYNC_INITIALIZED;
548	}
549	local_irq_restore(flags);
550}
551
552/*
553 * ------------------------------------------------------------
554 * rs_close()
555 *
556 * This routine is called when the serial port gets closed.  First, we
557 * wait for the last remaining data to be sent.  Then, we unlink its
558 * async structure from the interrupt chain if necessary, and we free
559 * that IRQ if nothing is left in the chain.
560 * ------------------------------------------------------------
561 */
562static void rs_close(struct tty_struct *tty, struct file * filp)
563{
564	struct async_struct * info = (struct async_struct *)tty->driver_data;
565	struct serial_state *state;
566	unsigned long flags;
567
568	if (!info ) return;
569
570	state = info->state;
571
572	local_irq_save(flags);
573	if (tty_hung_up_p(filp)) {
574#ifdef SIMSERIAL_DEBUG
575		printk("rs_close: hung_up\n");
576#endif
577		local_irq_restore(flags);
578		return;
579	}
580#ifdef SIMSERIAL_DEBUG
581	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
582#endif
583	if ((tty->count == 1) && (state->count != 1)) {
584		/*
585		 * Uh, oh.  tty->count is 1, which means that the tty
586		 * structure will be freed.  state->count should always
587		 * be one in these conditions.  If it's greater than
588		 * one, we've got real problems, since it means the
589		 * serial port won't be shutdown.
590		 */
591		printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, "
592		       "state->count is %d\n", state->count);
593		state->count = 1;
594	}
595	if (--state->count < 0) {
596		printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
597		       info->line, state->count);
598		state->count = 0;
599	}
600	if (state->count) {
601		local_irq_restore(flags);
602		return;
603	}
604	info->flags |= ASYNC_CLOSING;
605	local_irq_restore(flags);
606
607	/*
608	 * Now we wait for the transmit buffer to clear; and we notify
609	 * the line discipline to only process XON/XOFF characters.
610	 */
611	shutdown(info);
612	if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty);
613	if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
614	info->event = 0;
615	info->tty = NULL;
616	if (info->blocked_open) {
617		if (info->close_delay)
618			schedule_timeout_interruptible(info->close_delay);
619		wake_up_interruptible(&info->open_wait);
620	}
621	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
622	wake_up_interruptible(&info->close_wait);
623}
624
625/*
626 * rs_wait_until_sent() --- wait until the transmitter is empty
627 */
628static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
629{
630}
631
632
633/*
634 * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
635 */
636static void rs_hangup(struct tty_struct *tty)
637{
638	struct async_struct * info = (struct async_struct *)tty->driver_data;
639	struct serial_state *state = info->state;
640
641#ifdef SIMSERIAL_DEBUG
642	printk("rs_hangup: called\n");
643#endif
644
645	state = info->state;
646
647	rs_flush_buffer(tty);
648	if (info->flags & ASYNC_CLOSING)
649		return;
650	shutdown(info);
651
652	info->event = 0;
653	state->count = 0;
654	info->flags &= ~ASYNC_NORMAL_ACTIVE;
655	info->tty = NULL;
656	wake_up_interruptible(&info->open_wait);
657}
658
659
660static int get_async_struct(int line, struct async_struct **ret_info)
661{
662	struct async_struct *info;
663	struct serial_state *sstate;
664
665	sstate = rs_table + line;
666	sstate->count++;
667	if (sstate->info) {
668		*ret_info = sstate->info;
669		return 0;
670	}
671	info = kzalloc(sizeof(struct async_struct), GFP_KERNEL);
672	if (!info) {
673		sstate->count--;
674		return -ENOMEM;
675	}
676	init_waitqueue_head(&info->open_wait);
677	init_waitqueue_head(&info->close_wait);
678	init_waitqueue_head(&info->delta_msr_wait);
679	info->magic = SERIAL_MAGIC;
680	info->port = sstate->port;
681	info->flags = sstate->flags;
682	info->xmit_fifo_size = sstate->xmit_fifo_size;
683	info->line = line;
684	INIT_WORK(&info->work, do_softint);
685	info->state = sstate;
686	if (sstate->info) {
687		kfree(info);
688		*ret_info = sstate->info;
689		return 0;
690	}
691	*ret_info = sstate->info = info;
692	return 0;
693}
694
695static int
696startup(struct async_struct *info)
697{
698	unsigned long flags;
699	int	retval=0;
700	irq_handler_t handler;
701	struct serial_state *state= info->state;
702	unsigned long page;
703
704	page = get_zeroed_page(GFP_KERNEL);
705	if (!page)
706		return -ENOMEM;
707
708	local_irq_save(flags);
709
710	if (info->flags & ASYNC_INITIALIZED) {
711		free_page(page);
712		goto errout;
713	}
714
715	if (!state->port || !state->type) {
716		if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
717		free_page(page);
718		goto errout;
719	}
720	if (info->xmit.buf)
721		free_page(page);
722	else
723		info->xmit.buf = (unsigned char *) page;
724
725#ifdef SIMSERIAL_DEBUG
726	printk("startup: ttys%d (irq %d)...", info->line, state->irq);
727#endif
728
729	/*
730	 * Allocate the IRQ if necessary
731	 */
732	if (state->irq && (!IRQ_ports[state->irq] ||
733			  !IRQ_ports[state->irq]->next_port)) {
734		if (IRQ_ports[state->irq]) {
735			retval = -EBUSY;
736			goto errout;
737		} else
738			handler = rs_interrupt_single;
739
740		retval = request_irq(state->irq, handler, IRQ_T(info), "simserial", NULL);
741		if (retval) {
742			if (capable(CAP_SYS_ADMIN)) {
743				if (info->tty)
744					set_bit(TTY_IO_ERROR,
745						&info->tty->flags);
746				retval = 0;
747			}
748			goto errout;
749		}
750	}
751
752	/*
753	 * Insert serial port into IRQ chain.
754	 */
755	info->prev_port = NULL;
756	info->next_port = IRQ_ports[state->irq];
757	if (info->next_port)
758		info->next_port->prev_port = info;
759	IRQ_ports[state->irq] = info;
760
761	if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags);
762
763	info->xmit.head = info->xmit.tail = 0;
764
765
766	/*
767	 * Set up the tty->alt_speed kludge
768	 */
769	if (info->tty) {
770		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
771			info->tty->alt_speed = 57600;
772		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
773			info->tty->alt_speed = 115200;
774		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
775			info->tty->alt_speed = 230400;
776		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
777			info->tty->alt_speed = 460800;
778	}
779
780	info->flags |= ASYNC_INITIALIZED;
781	local_irq_restore(flags);
782	return 0;
783
784errout:
785	local_irq_restore(flags);
786	return retval;
787}
788
789
790/*
791 * This routine is called whenever a serial port is opened.  It
792 * enables interrupts for a serial port, linking in its async structure into
793 * the IRQ chain.   It also performs the serial-specific
794 * initialization for the tty structure.
795 */
796static int rs_open(struct tty_struct *tty, struct file * filp)
797{
798	struct async_struct	*info;
799	int			retval, line;
800	unsigned long		page;
801
802	line = tty->index;
803	if ((line < 0) || (line >= NR_PORTS))
804		return -ENODEV;
805	retval = get_async_struct(line, &info);
806	if (retval)
807		return retval;
808	tty->driver_data = info;
809	info->tty = tty;
810
811#ifdef SIMSERIAL_DEBUG
812	printk("rs_open %s, count = %d\n", tty->name, info->state->count);
813#endif
814	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
815
816	if (!tmp_buf) {
817		page = get_zeroed_page(GFP_KERNEL);
818		if (!page)
819			return -ENOMEM;
820		if (tmp_buf)
821			free_page(page);
822		else
823			tmp_buf = (unsigned char *) page;
824	}
825
826	/*
827	 * If the port is the middle of closing, bail out now
828	 */
829	if (tty_hung_up_p(filp) ||
830	    (info->flags & ASYNC_CLOSING)) {
831		if (info->flags & ASYNC_CLOSING)
832			interruptible_sleep_on(&info->close_wait);
833#ifdef SERIAL_DO_RESTART
834		return ((info->flags & ASYNC_HUP_NOTIFY) ?
835			-EAGAIN : -ERESTARTSYS);
836#else
837		return -EAGAIN;
838#endif
839	}
840
841	/*
842	 * Start up serial port
843	 */
844	retval = startup(info);
845	if (retval) {
846		return retval;
847	}
848
849	/*
850	 * figure out which console to use (should be one already)
851	 */
852	console = console_drivers;
853	while (console) {
854		if ((console->flags & CON_ENABLED) && console->write) break;
855		console = console->next;
856	}
857
858#ifdef SIMSERIAL_DEBUG
859	printk("rs_open ttys%d successful\n", info->line);
860#endif
861	return 0;
862}
863
864/*
865 * /proc fs routines....
866 */
867
868static inline int line_info(char *buf, struct serial_state *state)
869{
870	return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n",
871		       state->line, uart_config[state->type].name,
872		       state->port, state->irq);
873}
874
875static int rs_read_proc(char *page, char **start, off_t off, int count,
876		 int *eof, void *data)
877{
878	int i, len = 0, l;
879	off_t	begin = 0;
880
881	len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version);
882	for (i = 0; i < NR_PORTS && len < 4000; i++) {
883		l = line_info(page + len, &rs_table[i]);
884		len += l;
885		if (len+begin > off+count)
886			goto done;
887		if (len+begin < off) {
888			begin += len;
889			len = 0;
890		}
891	}
892	*eof = 1;
893done:
894	if (off >= len+begin)
895		return 0;
896	*start = page + (begin-off);
897	return ((count < begin+len-off) ? count : begin+len-off);
898}
899
900/*
901 * ---------------------------------------------------------------------
902 * rs_init() and friends
903 *
904 * rs_init() is called at boot-time to initialize the serial driver.
905 * ---------------------------------------------------------------------
906 */
907
908/*
909 * This routine prints out the appropriate serial driver version
910 * number, and identifies which options were configured into this
911 * driver.
912 */
913static inline void show_serial_version(void)
914{
915	printk(KERN_INFO "%s version %s with", serial_name, serial_version);
916	printk(KERN_INFO " no serial options enabled\n");
917}
918
919static const struct tty_operations hp_ops = {
920	.open = rs_open,
921	.close = rs_close,
922	.write = rs_write,
923	.put_char = rs_put_char,
924	.flush_chars = rs_flush_chars,
925	.write_room = rs_write_room,
926	.chars_in_buffer = rs_chars_in_buffer,
927	.flush_buffer = rs_flush_buffer,
928	.ioctl = rs_ioctl,
929	.throttle = rs_throttle,
930	.unthrottle = rs_unthrottle,
931	.send_xchar = rs_send_xchar,
932	.set_termios = rs_set_termios,
933	.stop = rs_stop,
934	.start = rs_start,
935	.hangup = rs_hangup,
936	.break_ctl = rs_break,
937	.wait_until_sent = rs_wait_until_sent,
938	.read_proc = rs_read_proc,
939};
940
941/*
942 * The serial driver boot-time initialization code!
943 */
944static int __init
945simrs_init (void)
946{
947	int			i, rc;
948	struct serial_state	*state;
949
950	if (!ia64_platform_is("hpsim"))
951		return -ENODEV;
952
953	hp_simserial_driver = alloc_tty_driver(1);
954	if (!hp_simserial_driver)
955		return -ENOMEM;
956
957	show_serial_version();
958
959	/* Initialize the tty_driver structure */
960
961	hp_simserial_driver->owner = THIS_MODULE;
962	hp_simserial_driver->driver_name = "simserial";
963	hp_simserial_driver->name = "ttyS";
964	hp_simserial_driver->major = TTY_MAJOR;
965	hp_simserial_driver->minor_start = 64;
966	hp_simserial_driver->type = TTY_DRIVER_TYPE_SERIAL;
967	hp_simserial_driver->subtype = SERIAL_TYPE_NORMAL;
968	hp_simserial_driver->init_termios = tty_std_termios;
969	hp_simserial_driver->init_termios.c_cflag =
970		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
971	hp_simserial_driver->flags = TTY_DRIVER_REAL_RAW;
972	tty_set_operations(hp_simserial_driver, &hp_ops);
973
974	/*
975	 * Let's have a little bit of fun !
976	 */
977	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
978
979		if (state->type == PORT_UNKNOWN) continue;
980
981		if (!state->irq) {
982			if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
983				panic("%s: out of interrupt vectors!\n",
984				      __FUNCTION__);
985			state->irq = rc;
986			ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
987		}
988
989		printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n",
990		       state->line,
991		       state->port, state->irq,
992		       uart_config[state->type].name);
993	}
994
995	if (tty_register_driver(hp_simserial_driver))
996		panic("Couldn't register simserial driver\n");
997
998	return 0;
999}
1000
1001#ifndef MODULE
1002__initcall(simrs_init);
1003#endif
1004