Advertisement
Guest User

Untitled

a guest
Aug 19th, 2017
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.16 KB | None | 0 0
  1. /*
  2. * Tiny TTY driver
  3. *
  4. * Copyright (C) 2002 Greg Kroah-Hartman (greg@kroah.com)
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; version 2 of the License.
  9. *
  10. * This driver shows how to create a minimal serial driver using the 2.5
  11. * kernel's serial driver layer. It does not rely on any backing hardware, but
  12. * creates a timer that emulates data being received from some kind of
  13. * hardware.
  14. *
  15. * Compiled this driver with:
  16.  
  17. CFLAGS = -Wall -O2 -fomit-frame-pointer -DMODULE -D__KERNEL__
  18. IDIR = /path/to/linux-2.5/include/goes/here
  19.  
  20. tiny_serial.o::tiny_serial.c
  21. $(CC) $(CFLAGS) -I$(IDIR) -c -o $@ $<
  22. */
  23.  
  24. #include <linux/kernel.h>
  25. #include <linux/errno.h>
  26. #include <linux/init.h>
  27. #include <linux/slab.h>
  28. #include <linux/tty.h>
  29. #include <linux/tty_flip.h>
  30. #include <linux/serial.h>
  31. #include <linux/serial_core.h>
  32. #include <linux/module.h>
  33.  
  34.  
  35. #define DRIVER_VERSION "v1.0"
  36. #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
  37. #define DRIVER_DESC "Tiny serial driver"
  38.  
  39. /* Module information */
  40. MODULE_AUTHOR( DRIVER_AUTHOR );
  41. MODULE_DESCRIPTION( DRIVER_DESC );
  42. MODULE_LICENSE("GPL");
  43.  
  44. #define DELAY_TIME HZ * 2 /* 2 seconds per character */
  45. #define TINY_DATA_CHARACTER 't'
  46.  
  47. #define TINY_SERIAL_MAJOR 240 /* experimental range */
  48. #define TINY_SERIAL_MINORS 1 /* only have one minor */
  49. #define UART_NR 1 /* only use one port */
  50.  
  51. #define TINY_SERIAL_NAME "ttytiny"
  52.  
  53. #define MY_NAME TINY_SERIAL_NAME
  54.  
  55. #define dbg(fmt, arg...) \
  56. do { \
  57. if (debug) \
  58. printk (KERN_DEBUG "%s: %s: " fmt "\n", \
  59. MY_NAME , __FUNCTION__ , ## arg); \
  60. } while (0)
  61. #define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , MY_NAME , ## arg)
  62. #define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , MY_NAME , ## arg)
  63. #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , MY_NAME , ## arg)
  64.  
  65.  
  66. static int debug;
  67. MODULE_PARM(debug, "i");
  68. MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
  69.  
  70. static struct timer_list *timer;
  71.  
  72. static void tiny_stop_tx(struct uart_port *port, unsigned int tty_stop)
  73. {
  74. dbg ();
  75. }
  76.  
  77. static void tiny_stop_rx(struct uart_port *port)
  78. {
  79. dbg ();
  80. }
  81.  
  82. static void tiny_enable_ms(struct uart_port *port)
  83. {
  84. dbg ();
  85. }
  86.  
  87. static void tiny_tx_chars(struct uart_port *port)
  88. {
  89. struct circ_buf *xmit = &port->info->xmit;
  90. int count;
  91.  
  92. dbg ();
  93. if (port->x_char) {
  94. dbg ("wrote %2x", port->x_char);
  95. port->icount.tx++;
  96. port->x_char = 0;
  97. return;
  98. }
  99. if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
  100. tiny_stop_tx(port, 0);
  101. return;
  102. }
  103.  
  104. count = port->fifosize >> 1;
  105. do {
  106. dbg ("wrote %2x", xmit->buf[xmit->tail]);
  107. xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
  108. port->icount.tx++;
  109. if (uart_circ_empty(xmit))
  110. break;
  111. } while (--count > 0);
  112.  
  113. if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
  114. uart_event(port, EVT_WRITE_WAKEUP);
  115.  
  116. if (uart_circ_empty(xmit))
  117. tiny_stop_tx(port, 0);
  118. }
  119.  
  120. static void tiny_start_tx(struct uart_port *port, unsigned int tty_start)
  121. {
  122. dbg ();
  123. }
  124.  
  125. static void tiny_timer (unsigned long data)
  126. {
  127. struct uart_port *port;
  128. struct tty_struct *tty;
  129.  
  130. dbg ();
  131.  
  132. port = (struct uart_port *)data;
  133. if (!port)
  134. return;
  135. if (!port->info)
  136. return;
  137. tty = port->info->tty;
  138. if (!tty)
  139. return;
  140.  
  141. /* add one character to the tty port */
  142. /* this doesn't actually push the data through unless tty->low_latency is set */
  143. tty_insert_flip_char(tty, TINY_DATA_CHARACTER, 0);
  144.  
  145. tty_flip_buffer_push(tty);
  146.  
  147. /* resubmit the timer again */
  148. timer->expires = jiffies + DELAY_TIME;
  149. add_timer (timer);
  150.  
  151. /* see if we have any data to transmit */
  152. tiny_tx_chars(port);
  153. }
  154.  
  155. static unsigned int tiny_tx_empty(struct uart_port *port)
  156. {
  157. return 0;
  158. }
  159.  
  160. static unsigned int tiny_get_mctrl(struct uart_port *port)
  161. {
  162. return 0;
  163. }
  164.  
  165. static void tiny_set_mctrl(struct uart_port *port, unsigned int mctrl)
  166. {
  167. }
  168.  
  169. static void tiny_break_ctl(struct uart_port *port, int break_state)
  170. {
  171. }
  172.  
  173. static void
  174. tiny_change_speed(struct uart_port *port, unsigned int cflag,
  175. unsigned int iflag, unsigned int quot)
  176. {
  177. /* get the byte size */
  178. switch (cflag & CSIZE) {
  179. case CS5:
  180. dbg ("data bits = 5");
  181. break;
  182. case CS6:
  183. dbg ("data bits = 6");
  184. break;
  185. case CS7:
  186. dbg ("data bits = 7");
  187. break;
  188. default: // CS8
  189. dbg ("data bits = 8");
  190. break;
  191. }
  192.  
  193. /* determine the parity */
  194. if (cflag & PARENB)
  195. if (cflag & PARODD)
  196. dbg (" - parity = odd\n");
  197. else
  198. dbg (" - parity = even\n");
  199. else
  200. dbg (" - parity = none\n");
  201.  
  202. /* figure out the stop bits requested */
  203. if (cflag & CSTOPB)
  204. dbg (" - stop bits = 2\n");
  205. else
  206. dbg (" - stop bits = 1\n");
  207.  
  208. /* figure out the flow control settings */
  209. if (cflag & CRTSCTS)
  210. dbg (" - RTS/CTS is enabled\n");
  211. else
  212. dbg (" - RTS/CTS is disabled\n");
  213.  
  214. /* Set baud rate */
  215. //UART_PUT_DIV_LO(port, (quot & 0xff));
  216. //UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
  217. }
  218.  
  219. static int tiny_startup(struct uart_port *port)
  220. {
  221. /* this is the first time this port is opened */
  222. /* do any hardware initialization needed here */
  223.  
  224. /* create our timer and submit it */
  225. if (!timer) {
  226. timer = kmalloc (sizeof (*timer), GFP_KERNEL);
  227. if (!timer)
  228. return -ENOMEM;
  229. }
  230. timer->data = (unsigned long )port;
  231. timer->expires = jiffies + DELAY_TIME;
  232. timer->function = tiny_timer;
  233. add_timer (timer);
  234. return 0;
  235. }
  236.  
  237. static void tiny_shutdown(struct uart_port *port)
  238. {
  239. /* The port is being closed by the last user. */
  240. /* Do any hardware specific stuff here */
  241.  
  242. /* shut down our timer */
  243. del_timer (timer);
  244. }
  245.  
  246. static const char *tiny_type(struct uart_port *port)
  247. {
  248. return "tinytty";
  249. }
  250.  
  251. static void tiny_release_port(struct uart_port *port)
  252. {
  253.  
  254. }
  255.  
  256. static int tiny_request_port(struct uart_port *port)
  257. {
  258. return 0;
  259. }
  260.  
  261. static void tiny_config_port(struct uart_port *port, int flags)
  262. {
  263. }
  264.  
  265. static int tiny_verify_port(struct uart_port *port, struct serial_struct *ser)
  266. {
  267. return 0;
  268. }
  269.  
  270. static struct uart_ops tiny_ops = {
  271. .tx_empty = tiny_tx_empty,
  272. .set_mctrl = tiny_set_mctrl,
  273. .get_mctrl = tiny_get_mctrl,
  274. .stop_tx = tiny_stop_tx,
  275. .start_tx = tiny_start_tx,
  276. .stop_rx = tiny_stop_rx,
  277. .enable_ms = tiny_enable_ms,
  278. .break_ctl = tiny_break_ctl,
  279. .startup = tiny_startup,
  280. .shutdown = tiny_shutdown,
  281. .change_speed = tiny_change_speed,
  282. .type = tiny_type,
  283. .release_port = tiny_release_port,
  284. .request_port = tiny_request_port,
  285. .config_port = tiny_config_port,
  286. .verify_port = tiny_verify_port,
  287. };
  288.  
  289. static struct uart_port tiny_port = {
  290. .ops = &tiny_ops,
  291. };
  292.  
  293. static struct uart_driver tiny_reg = {
  294. .owner = THIS_MODULE,
  295. .driver_name = TINY_SERIAL_NAME,
  296. .dev_name = TINY_SERIAL_NAME,
  297. .major = TINY_SERIAL_MAJOR,
  298. .minor = TINY_SERIAL_MINORS,
  299. .nr = UART_NR,
  300. };
  301.  
  302.  
  303. static int __init tiny_init(void)
  304. {
  305. int result;
  306.  
  307. info ("Tiny serial driver");
  308.  
  309. result = uart_register_driver(&tiny_reg);
  310. if (result)
  311. return result;
  312.  
  313. result = uart_add_one_port(&tiny_reg, &tiny_port);
  314. if (result)
  315. uart_unregister_driver(&tiny_reg);
  316.  
  317. return result;
  318. }
  319.  
  320. module_init (tiny_init);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement