PageRenderTime 59ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/release/src/linux/linux/drivers/char/mux.c

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