diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 17:39:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 17:39:20 -0500 |
commit | 56b85f32d530d09d6805488ad00775d4e0e3baab (patch) | |
tree | e7fbe69e338ef775d3b2dd822aa915d259b4bc94 /drivers/tty | |
parent | 3e5b08cbbf78bedd316904ab0cf3b27119433ee5 (diff) | |
parent | 568389c257fa7d74ce36c2f78bad31965fded4cf (diff) |
Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (36 commits)
serial: apbuart: Fixup apbuart_console_init()
TTY: Add tty ioctl to figure device node of the system console.
tty: add 'active' sysfs attribute to tty0 and console device
drivers: serial: apbuart: Handle OF failures gracefully
Serial: Avoid unbalanced IRQ wake disable during resume
tty: fix typos/errors in tty_driver.h comments
pch_uart : fix warnings for 64bit compile
8250: fix uninitialized FIFOs
ip2: fix compiler warning on ip2main_pci_tbl
specialix: fix compiler warning on specialix_pci_tbl
rocket: fix compiler warning on rocket_pci_ids
8250: add a UPIO_DWAPB32 for 32 bit accesses
8250: use container_of() instead of casting
serial: omap-serial: Add support for kernel debugger
serial: fix pch_uart kconfig & build
drivers: char: hvc: add arm JTAG DCC console support
RS485 documentation: add 16C950 UART description
serial: ifx6x60: fix memory leak
serial: ifx6x60: free IRQ on error
Serial: EG20T: add PCH_UART driver
...
Fixed up conflicts in drivers/serial/apbuart.c with evil merge that
makes the code look fairly sane (unlike either side).
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/n_gsm.c | 213 | ||||
-rw-r--r-- | drivers/tty/tty_io.c | 52 | ||||
-rw-r--r-- | drivers/tty/vt/vt.c | 23 |
3 files changed, 197 insertions, 91 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index c5f8e5bda2b2..44b8412a04e8 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * | 19 | * |
20 | * TO DO: | 20 | * TO DO: |
21 | * Mostly done: ioctls for setting modes/timing | 21 | * Mostly done: ioctls for setting modes/timing |
22 | * Partly done: hooks so you can pull off frames to non tty devs | 22 | * Partly done: hooks so you can pull off frames to non tty devs |
23 | * Restart DLCI 0 when it closes ? | 23 | * Restart DLCI 0 when it closes ? |
24 | * Test basic encoding | 24 | * Test basic encoding |
25 | * Improve the tx engine | 25 | * Improve the tx engine |
@@ -73,8 +73,10 @@ module_param(debug, int, 0600); | |||
73 | #define T2 (2 * HZ) | 73 | #define T2 (2 * HZ) |
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | /* Semi-arbitary buffer size limits. 0710 is normally run with 32-64 byte | 76 | /* |
77 | limits so this is plenty */ | 77 | * Semi-arbitary buffer size limits. 0710 is normally run with 32-64 byte |
78 | * limits so this is plenty | ||
79 | */ | ||
78 | #define MAX_MRU 512 | 80 | #define MAX_MRU 512 |
79 | #define MAX_MTU 512 | 81 | #define MAX_MTU 512 |
80 | 82 | ||
@@ -184,6 +186,9 @@ struct gsm_mux { | |||
184 | #define GSM_DATA 5 | 186 | #define GSM_DATA 5 |
185 | #define GSM_FCS 6 | 187 | #define GSM_FCS 6 |
186 | #define GSM_OVERRUN 7 | 188 | #define GSM_OVERRUN 7 |
189 | #define GSM_LEN0 8 | ||
190 | #define GSM_LEN1 9 | ||
191 | #define GSM_SSOF 10 | ||
187 | unsigned int len; | 192 | unsigned int len; |
188 | unsigned int address; | 193 | unsigned int address; |
189 | unsigned int count; | 194 | unsigned int count; |
@@ -191,6 +196,7 @@ struct gsm_mux { | |||
191 | int encoding; | 196 | int encoding; |
192 | u8 control; | 197 | u8 control; |
193 | u8 fcs; | 198 | u8 fcs; |
199 | u8 received_fcs; | ||
194 | u8 *txframe; /* TX framing buffer */ | 200 | u8 *txframe; /* TX framing buffer */ |
195 | 201 | ||
196 | /* Methods for the receiver side */ | 202 | /* Methods for the receiver side */ |
@@ -286,7 +292,7 @@ static spinlock_t gsm_mux_lock; | |||
286 | #define MDM_DV 0x40 | 292 | #define MDM_DV 0x40 |
287 | 293 | ||
288 | #define GSM0_SOF 0xF9 | 294 | #define GSM0_SOF 0xF9 |
289 | #define GSM1_SOF 0x7E | 295 | #define GSM1_SOF 0x7E |
290 | #define GSM1_ESCAPE 0x7D | 296 | #define GSM1_ESCAPE 0x7D |
291 | #define GSM1_ESCAPE_BITS 0x20 | 297 | #define GSM1_ESCAPE_BITS 0x20 |
292 | #define XON 0x11 | 298 | #define XON 0x11 |
@@ -429,61 +435,63 @@ static void gsm_print_packet(const char *hdr, int addr, int cr, | |||
429 | if (!(debug & 1)) | 435 | if (!(debug & 1)) |
430 | return; | 436 | return; |
431 | 437 | ||
432 | printk(KERN_INFO "%s %d) %c: ", hdr, addr, "RC"[cr]); | 438 | pr_info("%s %d) %c: ", hdr, addr, "RC"[cr]); |
433 | 439 | ||
434 | switch (control & ~PF) { | 440 | switch (control & ~PF) { |
435 | case SABM: | 441 | case SABM: |
436 | printk(KERN_CONT "SABM"); | 442 | pr_cont("SABM"); |
437 | break; | 443 | break; |
438 | case UA: | 444 | case UA: |
439 | printk(KERN_CONT "UA"); | 445 | pr_cont("UA"); |
440 | break; | 446 | break; |
441 | case DISC: | 447 | case DISC: |
442 | printk(KERN_CONT "DISC"); | 448 | pr_cont("DISC"); |
443 | break; | 449 | break; |
444 | case DM: | 450 | case DM: |
445 | printk(KERN_CONT "DM"); | 451 | pr_cont("DM"); |
446 | break; | 452 | break; |
447 | case UI: | 453 | case UI: |
448 | printk(KERN_CONT "UI"); | 454 | pr_cont("UI"); |
449 | break; | 455 | break; |
450 | case UIH: | 456 | case UIH: |
451 | printk(KERN_CONT "UIH"); | 457 | pr_cont("UIH"); |
452 | break; | 458 | break; |
453 | default: | 459 | default: |
454 | if (!(control & 0x01)) { | 460 | if (!(control & 0x01)) { |
455 | printk(KERN_CONT "I N(S)%d N(R)%d", | 461 | pr_cont("I N(S)%d N(R)%d", |
456 | (control & 0x0E) >> 1, (control & 0xE)>> 5); | 462 | (control & 0x0E) >> 1, (control & 0xE) >> 5); |
457 | } else switch (control & 0x0F) { | 463 | } else switch (control & 0x0F) { |
458 | case RR: | 464 | case RR: |
459 | printk("RR(%d)", (control & 0xE0) >> 5); | 465 | pr_cont("RR(%d)", (control & 0xE0) >> 5); |
460 | break; | 466 | break; |
461 | case RNR: | 467 | case RNR: |
462 | printk("RNR(%d)", (control & 0xE0) >> 5); | 468 | pr_cont("RNR(%d)", (control & 0xE0) >> 5); |
463 | break; | 469 | break; |
464 | case REJ: | 470 | case REJ: |
465 | printk("REJ(%d)", (control & 0xE0) >> 5); | 471 | pr_cont("REJ(%d)", (control & 0xE0) >> 5); |
466 | break; | 472 | break; |
467 | default: | 473 | default: |
468 | printk(KERN_CONT "[%02X]", control); | 474 | pr_cont("[%02X]", control); |
469 | } | 475 | } |
470 | } | 476 | } |
471 | 477 | ||
472 | if (control & PF) | 478 | if (control & PF) |
473 | printk(KERN_CONT "(P)"); | 479 | pr_cont("(P)"); |
474 | else | 480 | else |
475 | printk(KERN_CONT "(F)"); | 481 | pr_cont("(F)"); |
476 | 482 | ||
477 | if (dlen) { | 483 | if (dlen) { |
478 | int ct = 0; | 484 | int ct = 0; |
479 | while (dlen--) { | 485 | while (dlen--) { |
480 | if (ct % 8 == 0) | 486 | if (ct % 8 == 0) { |
481 | printk(KERN_CONT "\n "); | 487 | pr_cont("\n"); |
482 | printk(KERN_CONT "%02X ", *data++); | 488 | pr_debug(" "); |
489 | } | ||
490 | pr_cont("%02X ", *data++); | ||
483 | ct++; | 491 | ct++; |
484 | } | 492 | } |
485 | } | 493 | } |
486 | printk(KERN_CONT "\n"); | 494 | pr_cont("\n"); |
487 | } | 495 | } |
488 | 496 | ||
489 | 497 | ||
@@ -522,11 +530,13 @@ static void hex_packet(const unsigned char *p, int len) | |||
522 | { | 530 | { |
523 | int i; | 531 | int i; |
524 | for (i = 0; i < len; i++) { | 532 | for (i = 0; i < len; i++) { |
525 | if (i && (i % 16) == 0) | 533 | if (i && (i % 16) == 0) { |
526 | printk("\n"); | 534 | pr_cont("\n"); |
527 | printk("%02X ", *p++); | 535 | pr_debug(""); |
536 | } | ||
537 | pr_cont("%02X ", *p++); | ||
528 | } | 538 | } |
529 | printk("\n"); | 539 | pr_cont("\n"); |
530 | } | 540 | } |
531 | 541 | ||
532 | /** | 542 | /** |
@@ -676,7 +686,7 @@ static void gsm_data_kick(struct gsm_mux *gsm) | |||
676 | } | 686 | } |
677 | 687 | ||
678 | if (debug & 4) { | 688 | if (debug & 4) { |
679 | printk("gsm_data_kick: \n"); | 689 | pr_debug("gsm_data_kick:\n"); |
680 | hex_packet(gsm->txframe, len); | 690 | hex_packet(gsm->txframe, len); |
681 | } | 691 | } |
682 | 692 | ||
@@ -1231,7 +1241,7 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command, | |||
1231 | } | 1241 | } |
1232 | 1242 | ||
1233 | /** | 1243 | /** |
1234 | * gsm_control_transmit - send control packet | 1244 | * gsm_control_transmit - send control packet |
1235 | * @gsm: gsm mux | 1245 | * @gsm: gsm mux |
1236 | * @ctrl: frame to send | 1246 | * @ctrl: frame to send |
1237 | * | 1247 | * |
@@ -1361,7 +1371,7 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) | |||
1361 | { | 1371 | { |
1362 | del_timer(&dlci->t1); | 1372 | del_timer(&dlci->t1); |
1363 | if (debug & 8) | 1373 | if (debug & 8) |
1364 | printk("DLCI %d goes closed.\n", dlci->addr); | 1374 | pr_debug("DLCI %d goes closed.\n", dlci->addr); |
1365 | dlci->state = DLCI_CLOSED; | 1375 | dlci->state = DLCI_CLOSED; |
1366 | if (dlci->addr != 0) { | 1376 | if (dlci->addr != 0) { |
1367 | struct tty_struct *tty = tty_port_tty_get(&dlci->port); | 1377 | struct tty_struct *tty = tty_port_tty_get(&dlci->port); |
@@ -1392,7 +1402,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) | |||
1392 | /* This will let a tty open continue */ | 1402 | /* This will let a tty open continue */ |
1393 | dlci->state = DLCI_OPEN; | 1403 | dlci->state = DLCI_OPEN; |
1394 | if (debug & 8) | 1404 | if (debug & 8) |
1395 | printk("DLCI %d goes open.\n", dlci->addr); | 1405 | pr_debug("DLCI %d goes open.\n", dlci->addr); |
1396 | wake_up(&dlci->gsm->event); | 1406 | wake_up(&dlci->gsm->event); |
1397 | } | 1407 | } |
1398 | 1408 | ||
@@ -1494,29 +1504,29 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len) | |||
1494 | unsigned int modem = 0; | 1504 | unsigned int modem = 0; |
1495 | 1505 | ||
1496 | if (debug & 16) | 1506 | if (debug & 16) |
1497 | printk("%d bytes for tty %p\n", len, tty); | 1507 | pr_debug("%d bytes for tty %p\n", len, tty); |
1498 | if (tty) { | 1508 | if (tty) { |
1499 | switch (dlci->adaption) { | 1509 | switch (dlci->adaption) { |
1500 | /* Unsupported types */ | 1510 | /* Unsupported types */ |
1501 | /* Packetised interruptible data */ | 1511 | /* Packetised interruptible data */ |
1502 | case 4: | 1512 | case 4: |
1503 | break; | 1513 | break; |
1504 | /* Packetised uininterruptible voice/data */ | 1514 | /* Packetised uininterruptible voice/data */ |
1505 | case 3: | 1515 | case 3: |
1506 | break; | 1516 | break; |
1507 | /* Asynchronous serial with line state in each frame */ | 1517 | /* Asynchronous serial with line state in each frame */ |
1508 | case 2: | 1518 | case 2: |
1509 | while (gsm_read_ea(&modem, *data++) == 0) { | 1519 | while (gsm_read_ea(&modem, *data++) == 0) { |
1510 | len--; | 1520 | len--; |
1511 | if (len == 0) | 1521 | if (len == 0) |
1512 | return; | 1522 | return; |
1513 | } | 1523 | } |
1514 | gsm_process_modem(tty, dlci, modem); | 1524 | gsm_process_modem(tty, dlci, modem); |
1515 | /* Line state will go via DLCI 0 controls only */ | 1525 | /* Line state will go via DLCI 0 controls only */ |
1516 | case 1: | 1526 | case 1: |
1517 | default: | 1527 | default: |
1518 | tty_insert_flip_string(tty, data, len); | 1528 | tty_insert_flip_string(tty, data, len); |
1519 | tty_flip_buffer_push(tty); | 1529 | tty_flip_buffer_push(tty); |
1520 | } | 1530 | } |
1521 | tty_kref_put(tty); | 1531 | tty_kref_put(tty); |
1522 | } | 1532 | } |
@@ -1625,7 +1635,6 @@ static void gsm_dlci_free(struct gsm_dlci *dlci) | |||
1625 | kfree(dlci); | 1635 | kfree(dlci); |
1626 | } | 1636 | } |
1627 | 1637 | ||
1628 | |||
1629 | /* | 1638 | /* |
1630 | * LAPBish link layer logic | 1639 | * LAPBish link layer logic |
1631 | */ | 1640 | */ |
@@ -1650,10 +1659,12 @@ static void gsm_queue(struct gsm_mux *gsm) | |||
1650 | 1659 | ||
1651 | if ((gsm->control & ~PF) == UI) | 1660 | if ((gsm->control & ~PF) == UI) |
1652 | gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len); | 1661 | gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len); |
1662 | /* generate final CRC with received FCS */ | ||
1663 | gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs); | ||
1653 | if (gsm->fcs != GOOD_FCS) { | 1664 | if (gsm->fcs != GOOD_FCS) { |
1654 | gsm->bad_fcs++; | 1665 | gsm->bad_fcs++; |
1655 | if (debug & 4) | 1666 | if (debug & 4) |
1656 | printk("BAD FCS %02x\n", gsm->fcs); | 1667 | pr_debug("BAD FCS %02x\n", gsm->fcs); |
1657 | return; | 1668 | return; |
1658 | } | 1669 | } |
1659 | address = gsm->address >> 1; | 1670 | address = gsm->address >> 1; |
@@ -1748,6 +1759,8 @@ invalid: | |||
1748 | 1759 | ||
1749 | static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) | 1760 | static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) |
1750 | { | 1761 | { |
1762 | unsigned int len; | ||
1763 | |||
1751 | switch (gsm->state) { | 1764 | switch (gsm->state) { |
1752 | case GSM_SEARCH: /* SOF marker */ | 1765 | case GSM_SEARCH: /* SOF marker */ |
1753 | if (c == GSM0_SOF) { | 1766 | if (c == GSM0_SOF) { |
@@ -1756,8 +1769,8 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) | |||
1756 | gsm->len = 0; | 1769 | gsm->len = 0; |
1757 | gsm->fcs = INIT_FCS; | 1770 | gsm->fcs = INIT_FCS; |
1758 | } | 1771 | } |
1759 | break; /* Address EA */ | 1772 | break; |
1760 | case GSM_ADDRESS: | 1773 | case GSM_ADDRESS: /* Address EA */ |
1761 | gsm->fcs = gsm_fcs_add(gsm->fcs, c); | 1774 | gsm->fcs = gsm_fcs_add(gsm->fcs, c); |
1762 | if (gsm_read_ea(&gsm->address, c)) | 1775 | if (gsm_read_ea(&gsm->address, c)) |
1763 | gsm->state = GSM_CONTROL; | 1776 | gsm->state = GSM_CONTROL; |
@@ -1765,9 +1778,9 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) | |||
1765 | case GSM_CONTROL: /* Control Byte */ | 1778 | case GSM_CONTROL: /* Control Byte */ |
1766 | gsm->fcs = gsm_fcs_add(gsm->fcs, c); | 1779 | gsm->fcs = gsm_fcs_add(gsm->fcs, c); |
1767 | gsm->control = c; | 1780 | gsm->control = c; |
1768 | gsm->state = GSM_LEN; | 1781 | gsm->state = GSM_LEN0; |
1769 | break; | 1782 | break; |
1770 | case GSM_LEN: /* Length EA */ | 1783 | case GSM_LEN0: /* Length EA */ |
1771 | gsm->fcs = gsm_fcs_add(gsm->fcs, c); | 1784 | gsm->fcs = gsm_fcs_add(gsm->fcs, c); |
1772 | if (gsm_read_ea(&gsm->len, c)) { | 1785 | if (gsm_read_ea(&gsm->len, c)) { |
1773 | if (gsm->len > gsm->mru) { | 1786 | if (gsm->len > gsm->mru) { |
@@ -1776,8 +1789,28 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) | |||
1776 | break; | 1789 | break; |
1777 | } | 1790 | } |
1778 | gsm->count = 0; | 1791 | gsm->count = 0; |
1779 | gsm->state = GSM_DATA; | 1792 | if (!gsm->len) |
1793 | gsm->state = GSM_FCS; | ||
1794 | else | ||
1795 | gsm->state = GSM_DATA; | ||
1796 | break; | ||
1797 | } | ||
1798 | gsm->state = GSM_LEN1; | ||
1799 | break; | ||
1800 | case GSM_LEN1: | ||
1801 | gsm->fcs = gsm_fcs_add(gsm->fcs, c); | ||
1802 | len = c; | ||
1803 | gsm->len |= len << 7; | ||
1804 | if (gsm->len > gsm->mru) { | ||
1805 | gsm->bad_size++; | ||
1806 | gsm->state = GSM_SEARCH; | ||
1807 | break; | ||
1780 | } | 1808 | } |
1809 | gsm->count = 0; | ||
1810 | if (!gsm->len) | ||
1811 | gsm->state = GSM_FCS; | ||
1812 | else | ||
1813 | gsm->state = GSM_DATA; | ||
1781 | break; | 1814 | break; |
1782 | case GSM_DATA: /* Data */ | 1815 | case GSM_DATA: /* Data */ |
1783 | gsm->buf[gsm->count++] = c; | 1816 | gsm->buf[gsm->count++] = c; |
@@ -1785,16 +1818,25 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) | |||
1785 | gsm->state = GSM_FCS; | 1818 | gsm->state = GSM_FCS; |
1786 | break; | 1819 | break; |
1787 | case GSM_FCS: /* FCS follows the packet */ | 1820 | case GSM_FCS: /* FCS follows the packet */ |
1788 | gsm->fcs = c; | 1821 | gsm->received_fcs = c; |
1822 | if (c == GSM0_SOF) { | ||
1823 | gsm->state = GSM_SEARCH; | ||
1824 | break; | ||
1825 | } | ||
1789 | gsm_queue(gsm); | 1826 | gsm_queue(gsm); |
1790 | /* And then back for the next frame */ | 1827 | gsm->state = GSM_SSOF; |
1791 | gsm->state = GSM_SEARCH; | 1828 | break; |
1829 | case GSM_SSOF: | ||
1830 | if (c == GSM0_SOF) { | ||
1831 | gsm->state = GSM_SEARCH; | ||
1832 | break; | ||
1833 | } | ||
1792 | break; | 1834 | break; |
1793 | } | 1835 | } |
1794 | } | 1836 | } |
1795 | 1837 | ||
1796 | /** | 1838 | /** |
1797 | * gsm0_receive - perform processing for non-transparency | 1839 | * gsm1_receive - perform processing for non-transparency |
1798 | * @gsm: gsm data for this ldisc instance | 1840 | * @gsm: gsm data for this ldisc instance |
1799 | * @c: character | 1841 | * @c: character |
1800 | * | 1842 | * |
@@ -1856,7 +1898,7 @@ static void gsm1_receive(struct gsm_mux *gsm, unsigned char c) | |||
1856 | gsm->state = GSM_DATA; | 1898 | gsm->state = GSM_DATA; |
1857 | break; | 1899 | break; |
1858 | case GSM_DATA: /* Data */ | 1900 | case GSM_DATA: /* Data */ |
1859 | if (gsm->count > gsm->mru ) { /* Allow one for the FCS */ | 1901 | if (gsm->count > gsm->mru) { /* Allow one for the FCS */ |
1860 | gsm->state = GSM_OVERRUN; | 1902 | gsm->state = GSM_OVERRUN; |
1861 | gsm->bad_size++; | 1903 | gsm->bad_size++; |
1862 | } else | 1904 | } else |
@@ -2034,9 +2076,6 @@ struct gsm_mux *gsm_alloc_mux(void) | |||
2034 | } | 2076 | } |
2035 | EXPORT_SYMBOL_GPL(gsm_alloc_mux); | 2077 | EXPORT_SYMBOL_GPL(gsm_alloc_mux); |
2036 | 2078 | ||
2037 | |||
2038 | |||
2039 | |||
2040 | /** | 2079 | /** |
2041 | * gsmld_output - write to link | 2080 | * gsmld_output - write to link |
2042 | * @gsm: our mux | 2081 | * @gsm: our mux |
@@ -2054,7 +2093,7 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len) | |||
2054 | return -ENOSPC; | 2093 | return -ENOSPC; |
2055 | } | 2094 | } |
2056 | if (debug & 4) { | 2095 | if (debug & 4) { |
2057 | printk("-->%d bytes out\n", len); | 2096 | pr_debug("-->%d bytes out\n", len); |
2058 | hex_packet(data, len); | 2097 | hex_packet(data, len); |
2059 | } | 2098 | } |
2060 | gsm->tty->ops->write(gsm->tty, data, len); | 2099 | gsm->tty->ops->write(gsm->tty, data, len); |
@@ -2111,7 +2150,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
2111 | char flags; | 2150 | char flags; |
2112 | 2151 | ||
2113 | if (debug & 4) { | 2152 | if (debug & 4) { |
2114 | printk("Inbytes %dd\n", count); | 2153 | pr_debug("Inbytes %dd\n", count); |
2115 | hex_packet(cp, count); | 2154 | hex_packet(cp, count); |
2116 | } | 2155 | } |
2117 | 2156 | ||
@@ -2128,7 +2167,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
2128 | gsm->error(gsm, *dp, flags); | 2167 | gsm->error(gsm, *dp, flags); |
2129 | break; | 2168 | break; |
2130 | default: | 2169 | default: |
2131 | printk(KERN_ERR "%s: unknown flag %d\n", | 2170 | WARN_ONCE("%s: unknown flag %d\n", |
2132 | tty_name(tty, buf), flags); | 2171 | tty_name(tty, buf), flags); |
2133 | break; | 2172 | break; |
2134 | } | 2173 | } |
@@ -2323,7 +2362,7 @@ static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm, | |||
2323 | int need_restart = 0; | 2362 | int need_restart = 0; |
2324 | 2363 | ||
2325 | /* Stuff we don't support yet - UI or I frame transport, windowing */ | 2364 | /* Stuff we don't support yet - UI or I frame transport, windowing */ |
2326 | if ((c->adaption !=1 && c->adaption != 2) || c->k) | 2365 | if ((c->adaption != 1 && c->adaption != 2) || c->k) |
2327 | return -EOPNOTSUPP; | 2366 | return -EOPNOTSUPP; |
2328 | /* Check the MRU/MTU range looks sane */ | 2367 | /* Check the MRU/MTU range looks sane */ |
2329 | if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8) | 2368 | if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8) |
@@ -2418,7 +2457,7 @@ static int gsmld_ioctl(struct tty_struct *tty, struct file *file, | |||
2418 | c.i = 1; | 2457 | c.i = 1; |
2419 | else | 2458 | else |
2420 | c.i = 2; | 2459 | c.i = 2; |
2421 | printk("Ftype %d i %d\n", gsm->ftype, c.i); | 2460 | pr_debug("Ftype %d i %d\n", gsm->ftype, c.i); |
2422 | c.mru = gsm->mru; | 2461 | c.mru = gsm->mru; |
2423 | c.mtu = gsm->mtu; | 2462 | c.mtu = gsm->mtu; |
2424 | c.k = 0; | 2463 | c.k = 0; |
@@ -2712,14 +2751,15 @@ static int __init gsm_init(void) | |||
2712 | /* Fill in our line protocol discipline, and register it */ | 2751 | /* Fill in our line protocol discipline, and register it */ |
2713 | int status = tty_register_ldisc(N_GSM0710, &tty_ldisc_packet); | 2752 | int status = tty_register_ldisc(N_GSM0710, &tty_ldisc_packet); |
2714 | if (status != 0) { | 2753 | if (status != 0) { |
2715 | printk(KERN_ERR "n_gsm: can't register line discipline (err = %d)\n", status); | 2754 | pr_err("n_gsm: can't register line discipline (err = %d)\n", |
2755 | status); | ||
2716 | return status; | 2756 | return status; |
2717 | } | 2757 | } |
2718 | 2758 | ||
2719 | gsm_tty_driver = alloc_tty_driver(256); | 2759 | gsm_tty_driver = alloc_tty_driver(256); |
2720 | if (!gsm_tty_driver) { | 2760 | if (!gsm_tty_driver) { |
2721 | tty_unregister_ldisc(N_GSM0710); | 2761 | tty_unregister_ldisc(N_GSM0710); |
2722 | printk(KERN_ERR "gsm_init: tty allocation failed.\n"); | 2762 | pr_err("gsm_init: tty allocation failed.\n"); |
2723 | return -EINVAL; | 2763 | return -EINVAL; |
2724 | } | 2764 | } |
2725 | gsm_tty_driver->owner = THIS_MODULE; | 2765 | gsm_tty_driver->owner = THIS_MODULE; |
@@ -2730,7 +2770,7 @@ static int __init gsm_init(void) | |||
2730 | gsm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | 2770 | gsm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; |
2731 | gsm_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 2771 | gsm_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
2732 | gsm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | 2772 | gsm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV |
2733 | | TTY_DRIVER_HARDWARE_BREAK; | 2773 | | TTY_DRIVER_HARDWARE_BREAK; |
2734 | gsm_tty_driver->init_termios = tty_std_termios; | 2774 | gsm_tty_driver->init_termios = tty_std_termios; |
2735 | /* Fixme */ | 2775 | /* Fixme */ |
2736 | gsm_tty_driver->init_termios.c_lflag &= ~ECHO; | 2776 | gsm_tty_driver->init_termios.c_lflag &= ~ECHO; |
@@ -2741,10 +2781,11 @@ static int __init gsm_init(void) | |||
2741 | if (tty_register_driver(gsm_tty_driver)) { | 2781 | if (tty_register_driver(gsm_tty_driver)) { |
2742 | put_tty_driver(gsm_tty_driver); | 2782 | put_tty_driver(gsm_tty_driver); |
2743 | tty_unregister_ldisc(N_GSM0710); | 2783 | tty_unregister_ldisc(N_GSM0710); |
2744 | printk(KERN_ERR "gsm_init: tty registration failed.\n"); | 2784 | pr_err("gsm_init: tty registration failed.\n"); |
2745 | return -EBUSY; | 2785 | return -EBUSY; |
2746 | } | 2786 | } |
2747 | printk(KERN_INFO "gsm_init: loaded as %d,%d.\n", gsm_tty_driver->major, gsm_tty_driver->minor_start); | 2787 | pr_debug("gsm_init: loaded as %d,%d.\n", |
2788 | gsm_tty_driver->major, gsm_tty_driver->minor_start); | ||
2748 | return 0; | 2789 | return 0; |
2749 | } | 2790 | } |
2750 | 2791 | ||
@@ -2752,10 +2793,10 @@ static void __exit gsm_exit(void) | |||
2752 | { | 2793 | { |
2753 | int status = tty_unregister_ldisc(N_GSM0710); | 2794 | int status = tty_unregister_ldisc(N_GSM0710); |
2754 | if (status != 0) | 2795 | if (status != 0) |
2755 | printk(KERN_ERR "n_gsm: can't unregister line discipline (err = %d)\n", status); | 2796 | pr_err("n_gsm: can't unregister line discipline (err = %d)\n", |
2797 | status); | ||
2756 | tty_unregister_driver(gsm_tty_driver); | 2798 | tty_unregister_driver(gsm_tty_driver); |
2757 | put_tty_driver(gsm_tty_driver); | 2799 | put_tty_driver(gsm_tty_driver); |
2758 | printk(KERN_INFO "gsm_init: unloaded.\n"); | ||
2759 | } | 2800 | } |
2760 | 2801 | ||
2761 | module_init(gsm_init); | 2802 | module_init(gsm_init); |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 35480dd57a30..464d09d97873 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -2627,6 +2627,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2627 | return put_user(tty->ldisc->ops->num, (int __user *)p); | 2627 | return put_user(tty->ldisc->ops->num, (int __user *)p); |
2628 | case TIOCSETD: | 2628 | case TIOCSETD: |
2629 | return tiocsetd(tty, p); | 2629 | return tiocsetd(tty, p); |
2630 | case TIOCGDEV: | ||
2631 | { | ||
2632 | unsigned int ret = new_encode_dev(tty_devnum(real_tty)); | ||
2633 | return put_user(ret, (unsigned int __user *)p); | ||
2634 | } | ||
2630 | /* | 2635 | /* |
2631 | * Break handling | 2636 | * Break handling |
2632 | */ | 2637 | */ |
@@ -3241,9 +3246,45 @@ static int __init tty_class_init(void) | |||
3241 | postcore_initcall(tty_class_init); | 3246 | postcore_initcall(tty_class_init); |
3242 | 3247 | ||
3243 | /* 3/2004 jmc: why do these devices exist? */ | 3248 | /* 3/2004 jmc: why do these devices exist? */ |
3244 | |||
3245 | static struct cdev tty_cdev, console_cdev; | 3249 | static struct cdev tty_cdev, console_cdev; |
3246 | 3250 | ||
3251 | static ssize_t show_cons_active(struct device *dev, | ||
3252 | struct device_attribute *attr, char *buf) | ||
3253 | { | ||
3254 | struct console *cs[16]; | ||
3255 | int i = 0; | ||
3256 | struct console *c; | ||
3257 | ssize_t count = 0; | ||
3258 | |||
3259 | acquire_console_sem(); | ||
3260 | for (c = console_drivers; c; c = c->next) { | ||
3261 | if (!c->device) | ||
3262 | continue; | ||
3263 | if (!c->write) | ||
3264 | continue; | ||
3265 | if ((c->flags & CON_ENABLED) == 0) | ||
3266 | continue; | ||
3267 | cs[i++] = c; | ||
3268 | if (i >= ARRAY_SIZE(cs)) | ||
3269 | break; | ||
3270 | } | ||
3271 | while (i--) | ||
3272 | count += sprintf(buf + count, "%s%d%c", | ||
3273 | cs[i]->name, cs[i]->index, i ? ' ':'\n'); | ||
3274 | release_console_sem(); | ||
3275 | |||
3276 | return count; | ||
3277 | } | ||
3278 | static DEVICE_ATTR(active, S_IRUGO, show_cons_active, NULL); | ||
3279 | |||
3280 | static struct device *consdev; | ||
3281 | |||
3282 | void console_sysfs_notify(void) | ||
3283 | { | ||
3284 | if (consdev) | ||
3285 | sysfs_notify(&consdev->kobj, NULL, "active"); | ||
3286 | } | ||
3287 | |||
3247 | /* | 3288 | /* |
3248 | * Ok, now we can initialize the rest of the tty devices and can count | 3289 | * Ok, now we can initialize the rest of the tty devices and can count |
3249 | * on memory allocations, interrupts etc.. | 3290 | * on memory allocations, interrupts etc.. |
@@ -3254,15 +3295,18 @@ int __init tty_init(void) | |||
3254 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || | 3295 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || |
3255 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) | 3296 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) |
3256 | panic("Couldn't register /dev/tty driver\n"); | 3297 | panic("Couldn't register /dev/tty driver\n"); |
3257 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, | 3298 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); |
3258 | "tty"); | ||
3259 | 3299 | ||
3260 | cdev_init(&console_cdev, &console_fops); | 3300 | cdev_init(&console_cdev, &console_fops); |
3261 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || | 3301 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || |
3262 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) | 3302 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) |
3263 | panic("Couldn't register /dev/console driver\n"); | 3303 | panic("Couldn't register /dev/console driver\n"); |
3264 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, | 3304 | consdev = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, |
3265 | "console"); | 3305 | "console"); |
3306 | if (IS_ERR(consdev)) | ||
3307 | consdev = NULL; | ||
3308 | else | ||
3309 | device_create_file(consdev, &dev_attr_active); | ||
3266 | 3310 | ||
3267 | #ifdef CONFIG_VT | 3311 | #ifdef CONFIG_VT |
3268 | vty_init(&console_fops); | 3312 | vty_init(&console_fops); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index a8ec48ed14d9..76407eca9ab0 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -236,6 +236,14 @@ enum { | |||
236 | }; | 236 | }; |
237 | 237 | ||
238 | /* | 238 | /* |
239 | * /sys/class/tty/tty0/ | ||
240 | * | ||
241 | * the attribute 'active' contains the name of the current vc | ||
242 | * console and it supports poll() to detect vc switches | ||
243 | */ | ||
244 | static struct device *tty0dev; | ||
245 | |||
246 | /* | ||
239 | * Notifier list for console events. | 247 | * Notifier list for console events. |
240 | */ | 248 | */ |
241 | static ATOMIC_NOTIFIER_HEAD(vt_notifier_list); | 249 | static ATOMIC_NOTIFIER_HEAD(vt_notifier_list); |
@@ -688,6 +696,8 @@ void redraw_screen(struct vc_data *vc, int is_switch) | |||
688 | save_screen(old_vc); | 696 | save_screen(old_vc); |
689 | set_origin(old_vc); | 697 | set_origin(old_vc); |
690 | } | 698 | } |
699 | if (tty0dev) | ||
700 | sysfs_notify(&tty0dev->kobj, NULL, "active"); | ||
691 | } else { | 701 | } else { |
692 | hide_cursor(vc); | 702 | hide_cursor(vc); |
693 | redraw = 1; | 703 | redraw = 1; |
@@ -2967,13 +2977,24 @@ static const struct tty_operations con_ops = { | |||
2967 | 2977 | ||
2968 | static struct cdev vc0_cdev; | 2978 | static struct cdev vc0_cdev; |
2969 | 2979 | ||
2980 | static ssize_t show_tty_active(struct device *dev, | ||
2981 | struct device_attribute *attr, char *buf) | ||
2982 | { | ||
2983 | return sprintf(buf, "tty%d\n", fg_console + 1); | ||
2984 | } | ||
2985 | static DEVICE_ATTR(active, S_IRUGO, show_tty_active, NULL); | ||
2986 | |||
2970 | int __init vty_init(const struct file_operations *console_fops) | 2987 | int __init vty_init(const struct file_operations *console_fops) |
2971 | { | 2988 | { |
2972 | cdev_init(&vc0_cdev, console_fops); | 2989 | cdev_init(&vc0_cdev, console_fops); |
2973 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || | 2990 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || |
2974 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) | 2991 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) |
2975 | panic("Couldn't register /dev/tty0 driver\n"); | 2992 | panic("Couldn't register /dev/tty0 driver\n"); |
2976 | device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); | 2993 | tty0dev = device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); |
2994 | if (IS_ERR(tty0dev)) | ||
2995 | tty0dev = NULL; | ||
2996 | else | ||
2997 | device_create_file(tty0dev, &dev_attr_active); | ||
2977 | 2998 | ||
2978 | vcs_init(); | 2999 | vcs_init(); |
2979 | 3000 | ||