1 /*
2 ** mux.c:
3 ** MUX console for the NOVA and K-Class systems.
4 **
5 ** (c) Copyright 2002 Ryan Bradetich
6 ** (c) Copyright 2002 Hewlett-Packard Company
7 **
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 2 of the License, or
11 ** (at your option) any later version.
12 **
13 **
14 ** This Driver used Christoph Plattner's pdc_console.c as a driver
15 ** template.
16 **
17 ** This Driver currently only supports the console (port 0) on the MUX.
18 ** Additional work will be needed on this driver to enable the full
19 ** functionality of the MUX.
20 **
21 */
22
23 static char *mux_drv_version = "0.1";
24
25 #include <linux/config.h>
26 #include <linux/version.h>
27
28 #undef SERIAL_PARANOIA_CHECK
29 #define CONFIG_SERIAL_NOPAUSE_IO
30 #define SERIAL_DO_RESTART
31
32 #include <linux/module.h>
33 #include <linux/serial.h>
34 #include <linux/serialP.h>
35 #include <linux/tty.h>
36 #include <linux/slab.h>
37 #include <linux/init.h>
38 #include <linux/delay.h>
39 #include <asm/uaccess.h>
40
41 #ifdef CONFIG_MAGIC_SYSRQ
42 #include <linux/sysrq.h>
43 static unsigned long break_pressed;
44 #endif
45
46 #ifdef CONFIG_GSC
47 #include <asm/gsc.h>
48 #endif
49
50 static unsigned long hpa;
51
52 #define MUX_OFFSET 0x800
53 #define MUX_LINE_OFFSET 0x80
54
55 #define MUX_FIFO_SIZE 255
56 #define MUX_MIN_FREE_SIZE 32
57
58 #define MUX_FIFO_DRAIN_DELAY 1
59 #define MUX_POLL_DELAY (30 * HZ / 1000)
60
61 #define IO_COMMAND_REG_OFFSET 0x30
62 #define IO_STATUS_REG_OFFSET 0x34
63 #define IO_DATA_REG_OFFSET 0x3c
64 #define IO_DCOUNT_REG_OFFSET 0x40
65 #define IO_UCOUNT_REG_OFFSET 0x44
66 #define IO_FIFOS_REG_OFFSET 0x48
67
68 #define MUX_EOFIFO(status) ((status & 0xF000) == 0xF000)
69 #define MUX_STATUS(status) ((status & 0xF000) == 0x8000)
70 #define MUX_BREAK(status) ((status & 0xF000) == 0x2000)
71
72 static int mux_drv_refcount; /* = 0 */
73 static struct tty_driver mux_drv_driver;
74 static struct async_struct *mux_drv_info;
75 static struct timer_list mux_drv_timer;
76
77 #define NR_PORTS 1
78 static struct tty_struct *mux_drv_table[NR_PORTS];
79 static struct termios *mux_drv_termios[NR_PORTS];
80 static struct termios *mux_drv_termios_locked[NR_PORTS];
81
82 /**
83 * mux_read_fifo - Read chars from the mux fifo.
84 * @info: Ptr to the async structure.
85 *
86 * This reads all available data from the mux's fifo and pushes
87 * the data to the tty layer.
88 */
89 static void
mux_read_fifo(struct async_struct * info)90 mux_read_fifo(struct async_struct *info)
91 {
92 int data;
93 struct tty_struct *tty = info->tty;
94
95 while(1) {
96 data = __raw_readl((unsigned long)info->iomem_base
97 + IO_DATA_REG_OFFSET);
98
99 if (MUX_STATUS(data))
100 continue;
101
102 if (MUX_EOFIFO(data))
103 break;
104
105 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
106 continue;
107
108 *tty->flip.char_buf_ptr = data & 0xffu;
109 *tty->flip.flag_buf_ptr = 0;
110
111 #ifdef CONFIG_MAGIC_SYSRQ
112 if (MUX_BREAK(data) && !break_pressed) {
113 break_pressed = jiffies;
114 continue;
115 }
116
117 if(MUX_BREAK(data)) {
118 *tty->flip.flag_buf_ptr = TTY_BREAK;
119 }
120
121 if(break_pressed) {
122 if(time_before(jiffies, break_pressed + HZ * 5)) {
123 handle_sysrq(data & 0xffu, NULL, NULL, NULL);
124 break_pressed = 0;
125 continue;
126 }
127 break_pressed = 0;
128 }
129 #endif
130
131 tty->flip.flag_buf_ptr++;
132 tty->flip.char_buf_ptr++;
133 tty->flip.count++;
134 }
135
136 tty_flip_buffer_push(tty);
137 }
138
139
140 /**
141 * mux_drv_poll - Mux poll function.
142 * @unused: Unused variable
143 *
144 * This function periodically polls the Mux to check for new data.
145 */
146 static void
mux_drv_poll(unsigned long unused)147 mux_drv_poll(unsigned long unused)
148 {
149 struct async_struct *info = mux_drv_info;
150
151 if(info && info->tty && mux_drv_refcount) {
152 mux_read_fifo(info);
153 info->last_active = jiffies;
154 }
155
156 mod_timer(&mux_drv_timer, jiffies + MUX_POLL_DELAY);
157 }
158
159 /**
160 * mux_chars_in_buffer - Returns the number of chars present in the outbound fifo.
161 * @tty: Ptr to the tty structure.
162 *
163 * This function returns the number of chars sitting in the outbound fifo.
164 * [Note: This function is required for the normal_poll function in
165 * drivers/char/n_tty.c].
166 */
167 static int
mux_chars_in_buffer(struct tty_struct * tty)168 mux_chars_in_buffer(struct tty_struct *tty)
169 {
170 struct async_struct *info = (struct async_struct *)tty->driver_data;
171 return __raw_readl((unsigned long)info->iomem_base
172 + IO_DCOUNT_REG_OFFSET);
173 }
174
175 /**
176 * mux_flush_buffer - Pause until the fifo is empty.
177 * @tty: Ptr to the tty structure.
178 *
179 * Since the mux fifo is self draining, this function just
180 * waits until the fifo has completely drained.
181 */
182 static void
mux_flush_buffer(struct tty_struct * tty)183 mux_flush_buffer(struct tty_struct *tty)
184 {
185 while(mux_chars_in_buffer(tty))
186 mdelay(MUX_FIFO_DRAIN_DELAY);
187 }
188
189 /**
190 * mux_write_room - How much room is left in the fifo.
191 * @tty: Ptr to the tty structure.
192 *
193 * This function returns how much room is in the fifo for
194 * writing.
195 */
196 static int
mux_write_room(struct tty_struct * tty)197 mux_write_room(struct tty_struct *tty)
198 {
199 int room = mux_chars_in_buffer(tty);
200 if(room > MUX_FIFO_SIZE)
201 return 0;
202
203 return MUX_FIFO_SIZE - room;
204 }
205
206 /**
207 * mux_write - Write chars to the mux fifo.
208 * @tty: Ptr to the tty structure.
209 * @from_user: Is the buffer from user space?
210 * @buf: The buffer to write to the mux fifo.
211 * @count: The number of chars to write to the mux fifo.
212 *
213 * This function writes the data from buf to the mux fifo.
214 * [Note: we need the mux_flush_buffer() at the end of the
215 * function, otherwise the system will wait for LONG_MAX
216 * if the fifo is not empty when the TCSETSW ioctl is called.]
217 */
218 static int
mux_write(struct tty_struct * tty,int from_user,const unsigned char * buf,int count)219 mux_write(struct tty_struct *tty, int from_user,
220 const unsigned char *buf, int count)
221 {
222 int size, len, ret = count;
223 char buffer[MUX_FIFO_SIZE], *buf_p;
224 unsigned long iomem_base =
225 (unsigned long)((struct async_struct *)tty->driver_data)->iomem_base;
226
227 while (count) {
228 size = mux_write_room(tty);
229 len = (size < count) ? size : count;
230
231 if (from_user) {
232 copy_from_user(buffer, buf, len);
233 buf_p = buffer;
234 } else {
235 buf_p = (char *)buf;
236 }
237
238 count -= len;
239 buf += len;
240
241 if(size < MUX_MIN_FREE_SIZE)
242 mux_flush_buffer(tty);
243
244 while(len--) {
245 __raw_writel(*buf_p++, iomem_base + IO_DATA_REG_OFFSET);
246 }
247 }
248
249 mux_flush_buffer(tty);
250 return ret;
251 }
252
253 /**
254 * mux_break - Turn break handling on or off.
255 * @tty: Ptr to the tty structure.
256 * @break_state: break value.
257 *
258 * This function must be defined because the send_break() in
259 * drivers/char/tty_io.c requires it. Currently the Serial Mux
260 * does nothing when this function is called.
261 */
262 static void
mux_break(struct tty_struct * tty,int break_state)263 mux_break(struct tty_struct *tty, int break_state)
264 {
265 }
266
267 /**
268 * get_serial_info - Return the serial structure to userspace.
269 * @info: Ptr to the async structure.
270 * @retinfo: Ptr to the users space buffer.
271 *
272 * Fill in this serial structure and return it to userspace.
273 */
274 static int
get_serial_info(struct async_struct * info,struct serial_struct * retinfo)275 get_serial_info(struct async_struct *info,
276 struct serial_struct *retinfo)
277 {
278 struct serial_struct tmp;
279
280 if (!retinfo)
281 return -EFAULT;
282
283 memset(&tmp, 0, sizeof(tmp));
284 tmp.line = info->line;
285 tmp.port = info->line;
286 tmp.flags = info->flags;
287 tmp.close_delay = info->close_delay;
288 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
289 }
290
291 /**
292 * get_modem_info - Return the modem control and status signals to userspace.
293 * @info: Ptr to the async structure.
294 * @value: The return buffer.
295 *
296 * The Serial MUX driver always returns these values to userspace:
297 * Data Terminal Ready, Carrier Detect, Clear To Send,
298 * Request To Send.
299 *
300 */
301 static int
get_modem_info(struct async_struct * info,unsigned int * value)302 get_modem_info(struct async_struct *info, unsigned int *value)
303 {
304 unsigned int result = TIOCM_DTR|TIOCM_CAR|TIOCM_CTS|TIOCM_RTS;
305 return copy_to_user(value, &result, sizeof(int)) ? -EFAULT : 0;
306 }
307
308 /**
309 * get_lsr_info - Return line status register info to userspace.
310 * @info: Ptr to the async structure.
311 * @value: The return buffer.
312 *
313 * The Serial MUX driver always returns empty transmitter to userspace.
314 */
315 static int
get_lsr_info(struct async_struct * info,unsigned int * value)316 get_lsr_info(struct async_struct *info, unsigned int *value)
317 {
318 unsigned int result = TIOCSER_TEMT;
319 return copy_to_user(value, &result, sizeof(int)) ? -EFAULT : 0;
320 }
321
322 /**
323 * mux_ioctl - Handle driver specific ioctl commands.
324 * @tty: Ptr to the tty structure.
325 * @file: Unused.
326 * @cmd: The ioctl number.
327 * @arg: The ioctl argument.
328 *
329 * This function handles ioctls specific to the Serial MUX driver,
330 * or ioctls that need driver specific information.
331 *
332 */
333 static int
mux_ioctl(struct tty_struct * tty,struct file * file,unsigned int cmd,unsigned long arg)334 mux_ioctl(struct tty_struct *tty, struct file *file,
335 unsigned int cmd, unsigned long arg)
336 {
337 struct async_struct *info = (struct async_struct *) tty->driver_data;
338
339 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
340 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
341 (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
342 if (tty->flags & (1 << TTY_IO_ERROR))
343 return -EIO;
344 }
345
346 switch (cmd) {
347 case TIOCMGET:
348 return get_modem_info(info, (unsigned int *) arg);
349
350 case TIOCMBIS:
351 case TIOCMBIC:
352 case TIOCMSET:
353 return 0;
354
355 case TIOCGSERIAL:
356 return get_serial_info(info, (struct serial_struct *) arg);
357
358 case TIOCSSERIAL:
359 return 0;
360
361 case TIOCSERCONFIG:
362 return 0;
363
364 case TIOCSERGETLSR:
365 return get_lsr_info(info, (unsigned int *) arg);
366
367 case TIOCSERGSTRUCT:
368 if (copy_to_user((struct async_struct *) arg,
369 info, sizeof (struct async_struct)))
370 return -EFAULT;
371 return 0;
372
373 case TIOCMIWAIT:
374 return 0;
375
376 case TIOCGICOUNT:
377 return 0;
378
379 case TIOCSERGWILD:
380 case TIOCSERSWILD:
381 /* "setserial -W" is called in Debian boot */
382 printk("TIOCSER?WILD ioctl obsolete, ignored.\n");
383 return 0;
384
385 default:
386 return -ENOIOCTLCMD;
387 }
388 return 0;
389 }
390
391 /**
392 * mux_close - Close the serial mux driver.
393 * @tty: Ptr to the tty structure.
394 * @filp: Unused.
395 *
396 * This routine is called when the serial port gets closed. First, we
397 * wait for the last remaining data to be sent. Then, we unlink its
398 * async structure from the interrupt chain if necessary, and we free
399 * that IRQ if nothing is left in the chain.
400 */
401 static void
mux_close(struct tty_struct * tty,struct file * filp)402 mux_close(struct tty_struct *tty, struct file *filp)
403 {
404 struct async_struct *info = (struct async_struct *) tty->driver_data;
405
406 mux_drv_refcount--;
407 if (mux_drv_refcount > 0)
408 return;
409
410 info->flags |= ASYNC_CLOSING;
411
412 /*
413 * Save the termios structure, since this port may have
414 * separate termios for callout and dialin.
415 */
416 if (info->flags & ASYNC_NORMAL_ACTIVE)
417 info->state->normal_termios = *tty->termios;
418 if (info->flags & ASYNC_CALLOUT_ACTIVE)
419 info->state->callout_termios = *tty->termios;
420
421 /*
422 * At this point we stop accepting input. To do this, we
423 * disable the receive line status interrupts, and tell the
424 * interrupt driver to stop checking the data ready bit in the
425 * line status register.
426 */
427
428 /* XXX CP: make mask for receive !!! */
429
430 if (tty->driver.flush_buffer)
431 tty->driver.flush_buffer(tty);
432 tty_ldisc_flush(tty);
433 tty->closing = 0;
434 info->event = 0;
435 info->tty = 0;
436 mux_drv_info = NULL;
437 if (info->blocked_open) {
438 if (info->close_delay) {
439 set_current_state(TASK_INTERRUPTIBLE);
440 schedule_timeout(info->close_delay);
441 }
442 wake_up_interruptible(&info->open_wait);
443 }
444 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE |
445 ASYNC_CLOSING);
446 wake_up_interruptible(&info->close_wait);
447 MOD_DEC_USE_COUNT;
448 }
449
450 /**
451 * get_async_struct - Get the async structure.
452 * @line: Minor number of the tty device.
453 * @ret_info: Ptr to the newly allocated async structure.
454 *
455 * Allocate and return an async structure for the specified
456 * tty device line.
457 */
458 static int
get_async_struct(int line,struct async_struct ** ret_info)459 get_async_struct(int line, struct async_struct **ret_info)
460 {
461 struct async_struct *info;
462
463 info = kmalloc(sizeof (struct async_struct), GFP_KERNEL);
464 if (!info) {
465 return -ENOMEM;
466 }
467 memset(info, 0, sizeof (struct async_struct));
468 init_waitqueue_head(&info->open_wait);
469 init_waitqueue_head(&info->close_wait);
470 init_waitqueue_head(&info->delta_msr_wait);
471 info->magic = SERIAL_MAGIC;
472 info->port = 0;
473 info->flags = 0;
474 info->io_type = 0;
475 info->iomem_base = (void *)(hpa + MUX_OFFSET);
476 info->iomem_reg_shift = 0;
477 info->xmit_fifo_size = MUX_FIFO_SIZE;
478 info->line = line;
479 info->tqueue.routine = NULL;
480 info->tqueue.data = info;
481 info->state = NULL;
482 *ret_info = info;
483 return 0;
484 }
485
486 /**
487 * mux_open - Open the serial mux driver.
488 * @tty: Ptr to the tty structure.
489 * @filp: Unused.
490 *
491 * This routine is called whenever a serial port is opened. It
492 * enables interrupts for a serial port, linking in its async structure
493 * into the IRQ chain. It also performs the serial-specific
494 * initialization for the tty structure.
495 */
496 static int
mux_open(struct tty_struct * tty,struct file * filp)497 mux_open(struct tty_struct *tty, struct file *filp)
498 {
499 struct async_struct *info;
500 int retval, line;
501
502 MOD_INC_USE_COUNT;
503 line = MINOR(tty->device) - tty->driver.minor_start;
504 if ((line < 0) || (line >= NR_PORTS)) {
505 MOD_DEC_USE_COUNT;
506 return -ENODEV;
507 }
508 retval = get_async_struct(line, &info);
509 if (retval) {
510 MOD_DEC_USE_COUNT;
511 return retval;
512 }
513
514 tty->driver_data = info;
515 info->tty = tty;
516 mux_drv_info = info;
517 info->tty->low_latency = 0;
518 info->session = current->session;
519 info->pgrp = current->pgrp;
520 mux_drv_refcount++;
521 return 0;
522 }
523
524 /**
525 * mux_probe - Determine if the Serial Mux should claim this device.
526 * @dev: The parisc device.
527 *
528 * Deterimine if the Sserial Mux should claim this chip (return 0)
529 * or not (return 1).
530 */
531 static int __init
mux_probe(struct parisc_device * dev)532 mux_probe(struct parisc_device *dev)
533 {
534 if(hpa) {
535 printk(KERN_INFO "Serial MUX driver already registered, skipping additonal MUXes for now.\n");
536 return 1;
537 }
538
539 init_timer(&mux_drv_timer);
540 mux_drv_timer.function = mux_drv_poll;
541 mod_timer(&mux_drv_timer, jiffies + MUX_POLL_DELAY);
542
543 hpa = dev->hpa;
544 printk(KERN_INFO "Serial MUX driver version %s at 0x%lx\n",
545 mux_drv_version, hpa);
546
547 /* Initialize the tty_driver structure */
548
549 memset(&mux_drv_driver, 0, sizeof (struct tty_driver));
550 mux_drv_driver.magic = TTY_DRIVER_MAGIC;
551 mux_drv_driver.driver_name = "Serial MUX driver";
552 #ifdef CONFIG_DEVFS_FS
553 mux_drv_driver.name = "ttb/%d";
554 #else
555 mux_drv_driver.name = "ttyB";
556 #endif
557 mux_drv_driver.major = MUX_MAJOR;
558 mux_drv_driver.minor_start = 0;
559 mux_drv_driver.num = NR_PORTS;
560 mux_drv_driver.type = TTY_DRIVER_TYPE_SERIAL;
561 mux_drv_driver.subtype = SERIAL_TYPE_NORMAL;
562 mux_drv_driver.init_termios = tty_std_termios;
563 mux_drv_driver.init_termios.c_cflag =
564 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
565 mux_drv_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
566 mux_drv_driver.refcount = &mux_drv_refcount;
567 mux_drv_driver.table = mux_drv_table;
568 mux_drv_driver.termios = mux_drv_termios;
569 mux_drv_driver.termios_locked = mux_drv_termios_locked;
570
571 mux_drv_driver.open = mux_open;
572 mux_drv_driver.close = mux_close;
573 mux_drv_driver.write = mux_write;
574 mux_drv_driver.put_char = NULL;
575 mux_drv_driver.flush_chars = NULL;
576 mux_drv_driver.write_room = mux_write_room;
577 mux_drv_driver.chars_in_buffer = mux_chars_in_buffer;
578 mux_drv_driver.flush_buffer = mux_flush_buffer;
579 mux_drv_driver.ioctl = mux_ioctl;
580 mux_drv_driver.throttle = NULL;
581 mux_drv_driver.unthrottle = NULL;
582 mux_drv_driver.set_termios = NULL;
583 mux_drv_driver.stop = NULL;
584 mux_drv_driver.start = NULL;
585 mux_drv_driver.hangup = NULL;
586 mux_drv_driver.break_ctl = mux_break;
587 mux_drv_driver.send_xchar = NULL;
588 mux_drv_driver.wait_until_sent = NULL;
589 mux_drv_driver.read_proc = NULL;
590
591 if (tty_register_driver(&mux_drv_driver))
592 panic("Could not register the serial MUX driver\n");
593
594 return 0;
595 }
596
597 static struct parisc_device_id mux_tbl[] = {
598 { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D },
599 { 0, }
600 };
601
602 MODULE_DEVICE_TABLE(parisc, mux_tbl);
603
604 static struct parisc_driver mux_driver = {
605 name: "Serial MUX driver",
606 id_table: mux_tbl,
607 probe: mux_probe,
608 };
609
610 /**
611 * mux_init - Serial MUX initalization procedure.
612 *
613 * Register the Serial MUX driver.
614 */
mux_init(void)615 static int __init mux_init(void)
616 {
617 return register_parisc_driver(&mux_driver);
618 }
619
620 /**
621 * mux_exit - Serial MUX cleanup procedure.
622 *
623 * Unregister the Serial MUX driver from the tty layer.
624 */
mux_exit(void)625 static void __exit mux_exit(void)
626 {
627 int status = tty_unregister_driver(&mux_drv_driver);
628 if(status) {
629 printk("MUX: failed to unregister the Serial MUX driver (%d)\n", status);
630 }
631 }
632
633 module_init(mux_init);
634 module_exit(mux_exit);
635 MODULE_DESCRIPTION("Serial MUX driver");
636 MODULE_AUTHOR("Ryan Bradetich");
637 MODULE_LICENSE("GPL");
638