diff options
108 files changed, 2886 insertions, 4405 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 3d2d0c29f027..cc8093c15cf5 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -287,14 +287,6 @@ Who: Glauber Costa <gcosta@redhat.com> | |||
287 | 287 | ||
288 | --------------------------- | 288 | --------------------------- |
289 | 289 | ||
290 | What: old style serial driver for ColdFire (CONFIG_SERIAL_COLDFIRE) | ||
291 | When: 2.6.28 | ||
292 | Why: This driver still uses the old interface and has been replaced | ||
293 | by CONFIG_SERIAL_MCF. | ||
294 | Who: Sebastian Siewior <sebastian@breakpoint.cc> | ||
295 | |||
296 | --------------------------- | ||
297 | |||
298 | What: /sys/o2cb symlink | 290 | What: /sys/o2cb symlink |
299 | When: January 2010 | 291 | When: January 2010 |
300 | Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb | 292 | Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb |
diff --git a/MAINTAINERS b/MAINTAINERS index 6ba3ee822838..74b808205312 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2797,15 +2797,6 @@ L: linux-mtd@lists.infradead.org | |||
2797 | T: git git://git.infradead.org/mtd-2.6.git | 2797 | T: git git://git.infradead.org/mtd-2.6.git |
2798 | S: Maintained | 2798 | S: Maintained |
2799 | 2799 | ||
2800 | MEI MN10300/AM33 PORT | ||
2801 | P: David Howells | ||
2802 | M: dhowells@redhat.com | ||
2803 | P: Koichi Yasutake | ||
2804 | M: yasutake.koichi@jp.panasonic.com | ||
2805 | L: linux-am33-list@redhat.com (moderated for non-subscribers) | ||
2806 | W: ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/ | ||
2807 | S: Maintained | ||
2808 | |||
2809 | MICROTEK X6 SCANNER | 2800 | MICROTEK X6 SCANNER |
2810 | P: Oliver Neukum | 2801 | P: Oliver Neukum |
2811 | M: oliver@neukum.name | 2802 | M: oliver@neukum.name |
@@ -3170,6 +3161,15 @@ M: olof@lixom.net | |||
3170 | L: i2c@lm-sensors.org | 3161 | L: i2c@lm-sensors.org |
3171 | S: Maintained | 3162 | S: Maintained |
3172 | 3163 | ||
3164 | PANASONIC MN10300/AM33 PORT | ||
3165 | P: David Howells | ||
3166 | M: dhowells@redhat.com | ||
3167 | P: Koichi Yasutake | ||
3168 | M: yasutake.koichi@jp.panasonic.com | ||
3169 | L: linux-am33-list@redhat.com (moderated for non-subscribers) | ||
3170 | W: ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/ | ||
3171 | S: Maintained | ||
3172 | |||
3173 | PARALLEL PORT SUPPORT | 3173 | PARALLEL PORT SUPPORT |
3174 | L: linux-parport@lists.infradead.org (subscribers-only) | 3174 | L: linux-parport@lists.infradead.org (subscribers-only) |
3175 | S: Orphan | 3175 | S: Orphan |
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 93229b3d6e3e..339293d677cc 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c | |||
@@ -117,15 +117,14 @@ int request_dma(unsigned int channel, char *device_id) | |||
117 | 117 | ||
118 | #ifdef CONFIG_BF54x | 118 | #ifdef CONFIG_BF54x |
119 | if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) { | 119 | if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) { |
120 | if (strncmp(device_id, "BFIN_UART", 9) == 0) { | 120 | unsigned int per_map; |
121 | dma_ch[channel].regs->peripheral_map &= 0x0FFF; | 121 | per_map = dma_ch[channel].regs->peripheral_map & 0xFFF; |
122 | dma_ch[channel].regs->peripheral_map |= | 122 | if (strncmp(device_id, "BFIN_UART", 9) == 0) |
123 | dma_ch[channel].regs->peripheral_map = per_map | | ||
123 | ((channel - CH_UART2_RX + 0xC)<<12); | 124 | ((channel - CH_UART2_RX + 0xC)<<12); |
124 | } else { | 125 | else |
125 | dma_ch[channel].regs->peripheral_map &= 0x0FFF; | 126 | dma_ch[channel].regs->peripheral_map = per_map | |
126 | dma_ch[channel].regs->peripheral_map |= | ||
127 | ((channel - CH_UART2_RX + 0x6)<<12); | 127 | ((channel - CH_UART2_RX + 0x6)<<12); |
128 | } | ||
129 | } | 128 | } |
130 | #endif | 129 | #endif |
131 | 130 | ||
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h index 2526b6ed6faa..75722d6008b0 100644 --- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h | |||
@@ -78,6 +78,9 @@ | |||
78 | # define CONFIG_UART1_RTS_PIN -1 | 78 | # define CONFIG_UART1_RTS_PIN -1 |
79 | # endif | 79 | # endif |
80 | #endif | 80 | #endif |
81 | |||
82 | #define BFIN_UART_TX_FIFO_SIZE 2 | ||
83 | |||
81 | /* | 84 | /* |
82 | * The pin configuration is different from schematic | 85 | * The pin configuration is different from schematic |
83 | */ | 86 | */ |
@@ -119,7 +122,6 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) | |||
119 | bfin_write16(uart->port.membase + OFFSET_LSR, -1); | 122 | bfin_write16(uart->port.membase + OFFSET_LSR, -1); |
120 | } | 123 | } |
121 | 124 | ||
122 | struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; | ||
123 | struct bfin_serial_res { | 125 | struct bfin_serial_res { |
124 | unsigned long uart_base_addr; | 126 | unsigned long uart_base_addr; |
125 | int uart_irq; | 127 | int uart_irq; |
@@ -164,8 +166,6 @@ struct bfin_serial_res bfin_serial_resource[] = { | |||
164 | #endif | 166 | #endif |
165 | }; | 167 | }; |
166 | 168 | ||
167 | int nr_ports = ARRAY_SIZE(bfin_serial_resource); | ||
168 | |||
169 | #define DRIVER_NAME "bfin-uart" | 169 | #define DRIVER_NAME "bfin-uart" |
170 | 170 | ||
171 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) | 171 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) |
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h index ebf592b59aab..815bfe5dd1a9 100644 --- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h | |||
@@ -69,6 +69,8 @@ | |||
69 | # endif | 69 | # endif |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | #define BFIN_UART_TX_FIFO_SIZE 2 | ||
73 | |||
72 | struct bfin_serial_port { | 74 | struct bfin_serial_port { |
73 | struct uart_port port; | 75 | struct uart_port port; |
74 | unsigned int old_status; | 76 | unsigned int old_status; |
@@ -111,7 +113,6 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) | |||
111 | bfin_write16(uart->port.membase + OFFSET_LSR, -1); | 113 | bfin_write16(uart->port.membase + OFFSET_LSR, -1); |
112 | } | 114 | } |
113 | 115 | ||
114 | struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; | ||
115 | struct bfin_serial_res { | 116 | struct bfin_serial_res { |
116 | unsigned long uart_base_addr; | 117 | unsigned long uart_base_addr; |
117 | int uart_irq; | 118 | int uart_irq; |
@@ -142,7 +143,6 @@ struct bfin_serial_res bfin_serial_resource[] = { | |||
142 | 143 | ||
143 | #define DRIVER_NAME "bfin-uart" | 144 | #define DRIVER_NAME "bfin-uart" |
144 | 145 | ||
145 | int nr_ports = BFIN_UART_NR_PORTS; | ||
146 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) | 146 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) |
147 | { | 147 | { |
148 | 148 | ||
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h index 1bf56ffa22f9..b3f87e1d16a2 100644 --- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h | |||
@@ -78,6 +78,9 @@ | |||
78 | # define CONFIG_UART1_RTS_PIN -1 | 78 | # define CONFIG_UART1_RTS_PIN -1 |
79 | # endif | 79 | # endif |
80 | #endif | 80 | #endif |
81 | |||
82 | #define BFIN_UART_TX_FIFO_SIZE 2 | ||
83 | |||
81 | /* | 84 | /* |
82 | * The pin configuration is different from schematic | 85 | * The pin configuration is different from schematic |
83 | */ | 86 | */ |
@@ -119,7 +122,6 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) | |||
119 | bfin_write16(uart->port.membase + OFFSET_LSR, -1); | 122 | bfin_write16(uart->port.membase + OFFSET_LSR, -1); |
120 | } | 123 | } |
121 | 124 | ||
122 | struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; | ||
123 | struct bfin_serial_res { | 125 | struct bfin_serial_res { |
124 | unsigned long uart_base_addr; | 126 | unsigned long uart_base_addr; |
125 | int uart_irq; | 127 | int uart_irq; |
@@ -164,8 +166,6 @@ struct bfin_serial_res bfin_serial_resource[] = { | |||
164 | #endif | 166 | #endif |
165 | }; | 167 | }; |
166 | 168 | ||
167 | int nr_ports = ARRAY_SIZE(bfin_serial_resource); | ||
168 | |||
169 | #define DRIVER_NAME "bfin-uart" | 169 | #define DRIVER_NAME "bfin-uart" |
170 | 170 | ||
171 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) | 171 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) |
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h index 5e29446a8e03..e4cf35e7ab9f 100644 --- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h | |||
@@ -82,6 +82,9 @@ | |||
82 | # define CONFIG_UART1_RTS_PIN -1 | 82 | # define CONFIG_UART1_RTS_PIN -1 |
83 | # endif | 83 | # endif |
84 | #endif | 84 | #endif |
85 | |||
86 | #define BFIN_UART_TX_FIFO_SIZE 2 | ||
87 | |||
85 | /* | 88 | /* |
86 | * The pin configuration is different from schematic | 89 | * The pin configuration is different from schematic |
87 | */ | 90 | */ |
@@ -105,7 +108,6 @@ struct bfin_serial_port { | |||
105 | #endif | 108 | #endif |
106 | }; | 109 | }; |
107 | 110 | ||
108 | struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; | ||
109 | struct bfin_serial_res { | 111 | struct bfin_serial_res { |
110 | unsigned long uart_base_addr; | 112 | unsigned long uart_base_addr; |
111 | int uart_irq; | 113 | int uart_irq; |
@@ -170,8 +172,6 @@ struct bfin_serial_res bfin_serial_resource[] = { | |||
170 | #endif | 172 | #endif |
171 | }; | 173 | }; |
172 | 174 | ||
173 | int nr_ports = ARRAY_SIZE(bfin_serial_resource); | ||
174 | |||
175 | #define DRIVER_NAME "bfin-uart" | 175 | #define DRIVER_NAME "bfin-uart" |
176 | 176 | ||
177 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) | 177 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) |
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h index 8aa02780e642..e0ce0c1843d4 100644 --- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h | |||
@@ -69,6 +69,8 @@ | |||
69 | # endif | 69 | # endif |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | #define BFIN_UART_TX_FIFO_SIZE 2 | ||
73 | |||
72 | struct bfin_serial_port { | 74 | struct bfin_serial_port { |
73 | struct uart_port port; | 75 | struct uart_port port; |
74 | unsigned int old_status; | 76 | unsigned int old_status; |
@@ -111,7 +113,6 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) | |||
111 | bfin_write16(uart->port.membase + OFFSET_LSR, -1); | 113 | bfin_write16(uart->port.membase + OFFSET_LSR, -1); |
112 | } | 114 | } |
113 | 115 | ||
114 | struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; | ||
115 | struct bfin_serial_res { | 116 | struct bfin_serial_res { |
116 | unsigned long uart_base_addr; | 117 | unsigned long uart_base_addr; |
117 | int uart_irq; | 118 | int uart_irq; |
@@ -142,7 +143,6 @@ struct bfin_serial_res bfin_serial_resource[] = { | |||
142 | 143 | ||
143 | #define DRIVER_NAME "bfin-uart" | 144 | #define DRIVER_NAME "bfin-uart" |
144 | 145 | ||
145 | int nr_ports = BFIN_UART_NR_PORTS; | ||
146 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) | 146 | static void bfin_serial_hw_init(struct bfin_serial_port *uart) |
147 | { | 147 | { |
148 | 148 | ||
diff --git a/arch/sparc/include/asm/serial.h b/arch/sparc/include/asm/serial.h new file mode 100644 index 000000000000..f90d61c28059 --- /dev/null +++ b/arch/sparc/include/asm/serial.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __SPARC_SERIAL_H | ||
2 | #define __SPARC_SERIAL_H | ||
3 | |||
4 | #define BASE_BAUD ( 1843200 / 16 ) | ||
5 | |||
6 | #endif /* __SPARC_SERIAL_H */ | ||
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index d741f35d7b3a..14a102e877d6 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -275,6 +275,8 @@ int line_ioctl(struct tty_struct *tty, struct file * file, | |||
275 | case TIOCGLTC: | 275 | case TIOCGLTC: |
276 | case TIOCSLTC: | 276 | case TIOCSLTC: |
277 | #endif | 277 | #endif |
278 | /* Note: these are out of date as we now have TCGETS2 etc but this | ||
279 | whole lot should probably go away */ | ||
278 | case TCGETS: | 280 | case TCGETS: |
279 | case TCSETSF: | 281 | case TCSETSF: |
280 | case TCSETSW: | 282 | case TCSETSW: |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 8dfcf77cb717..4426bb552bd9 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -484,7 +484,7 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, | |||
484 | return -EUNATCH; | 484 | return -EUNATCH; |
485 | 485 | ||
486 | default: | 486 | default: |
487 | err = n_tty_ioctl(tty, file, cmd, arg); | 487 | err = n_tty_ioctl_helper(tty, file, cmd, arg); |
488 | break; | 488 | break; |
489 | }; | 489 | }; |
490 | 490 | ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index caff85149b9d..700ff9679457 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -350,7 +350,7 @@ config STALDRV | |||
350 | 350 | ||
351 | config STALLION | 351 | config STALLION |
352 | tristate "Stallion EasyIO or EC8/32 support" | 352 | tristate "Stallion EasyIO or EC8/32 support" |
353 | depends on STALDRV && BROKEN_ON_SMP && (ISA || EISA || PCI) | 353 | depends on STALDRV && (ISA || EISA || PCI) |
354 | help | 354 | help |
355 | If you have an EasyIO or EasyConnection 8/32 multiport Stallion | 355 | If you have an EasyIO or EasyConnection 8/32 multiport Stallion |
356 | card, then this is for you; say Y. Make sure to read | 356 | card, then this is for you; say Y. Make sure to read |
@@ -361,7 +361,7 @@ config STALLION | |||
361 | 361 | ||
362 | config ISTALLION | 362 | config ISTALLION |
363 | tristate "Stallion EC8/64, ONboard, Brumby support" | 363 | tristate "Stallion EC8/64, ONboard, Brumby support" |
364 | depends on STALDRV && BROKEN_ON_SMP && (ISA || EISA || PCI) | 364 | depends on STALDRV && (ISA || EISA || PCI) |
365 | help | 365 | help |
366 | If you have an EasyConnection 8/64, ONboard, Brumby or Stallion | 366 | If you have an EasyConnection 8/64, ONboard, Brumby or Stallion |
367 | serial multiport card, say Y here. Make sure to read | 367 | serial multiport card, say Y here. Make sure to read |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 6850f6da7576..1a4247dccac4 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -7,7 +7,7 @@ | |||
7 | # | 7 | # |
8 | FONTMAPFILE = cp437.uni | 8 | FONTMAPFILE = cp437.uni |
9 | 9 | ||
10 | obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o | 10 | obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o |
11 | 11 | ||
12 | obj-$(CONFIG_LEGACY_PTYS) += pty.o | 12 | obj-$(CONFIG_LEGACY_PTYS) += pty.o |
13 | obj-$(CONFIG_UNIX98_PTYS) += pty.o | 13 | obj-$(CONFIG_UNIX98_PTYS) += pty.o |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 6e763e3f5a81..98821f97583c 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -837,9 +837,6 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch) | |||
837 | struct async_struct *info; | 837 | struct async_struct *info; |
838 | unsigned long flags; | 838 | unsigned long flags; |
839 | 839 | ||
840 | if (!tty) | ||
841 | return 0; | ||
842 | |||
843 | info = tty->driver_data; | 840 | info = tty->driver_data; |
844 | 841 | ||
845 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) | 842 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) |
@@ -892,9 +889,6 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count | |||
892 | struct async_struct *info; | 889 | struct async_struct *info; |
893 | unsigned long flags; | 890 | unsigned long flags; |
894 | 891 | ||
895 | if (!tty) | ||
896 | return 0; | ||
897 | |||
898 | info = tty->driver_data; | 892 | info = tty->driver_data; |
899 | 893 | ||
900 | if (serial_paranoia_check(info, tty->name, "rs_write")) | 894 | if (serial_paranoia_check(info, tty->name, "rs_write")) |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 31d08b641f5b..b899d9182c7d 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -712,8 +712,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un | |||
712 | 712 | ||
713 | IndexCard = adgl->num_card-1; | 713 | IndexCard = adgl->num_card-1; |
714 | 714 | ||
715 | if(cmd != 0 && cmd != 6 && | 715 | if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { |
716 | ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { | ||
717 | static int warncount = 10; | 716 | static int warncount = 10; |
718 | if (warncount) { | 717 | if (warncount) { |
719 | printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1); | 718 | printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1); |
@@ -832,8 +831,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un | |||
832 | } | 831 | } |
833 | break; | 832 | break; |
834 | default: | 833 | default: |
835 | printk(KERN_INFO "APPLICOM driver ioctl, unknown function code %d\n",cmd) ; | 834 | ret = -ENOTTY; |
836 | ret = -EINVAL; | ||
837 | break; | 835 | break; |
838 | } | 836 | } |
839 | Dummy = readb(apbs[IndexCard].RamIO + VERS); | 837 | Dummy = readb(apbs[IndexCard].RamIO + VERS); |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index fe6d774fe2e4..5e5b1dc1a0a7 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -4993,12 +4993,14 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
4993 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | 4993 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
4994 | card_name = "Cyclom-Y"; | 4994 | card_name = "Cyclom-Y"; |
4995 | 4995 | ||
4996 | addr0 = pci_iomap(pdev, 0, CyPCI_Yctl); | 4996 | addr0 = ioremap_nocache(pci_resource_start(pdev, 0), |
4997 | CyPCI_Yctl); | ||
4997 | if (addr0 == NULL) { | 4998 | if (addr0 == NULL) { |
4998 | dev_err(&pdev->dev, "can't remap ctl region\n"); | 4999 | dev_err(&pdev->dev, "can't remap ctl region\n"); |
4999 | goto err_reg; | 5000 | goto err_reg; |
5000 | } | 5001 | } |
5001 | addr2 = pci_iomap(pdev, 2, CyPCI_Ywin); | 5002 | addr2 = ioremap_nocache(pci_resource_start(pdev, 2), |
5003 | CyPCI_Ywin); | ||
5002 | if (addr2 == NULL) { | 5004 | if (addr2 == NULL) { |
5003 | dev_err(&pdev->dev, "can't remap base region\n"); | 5005 | dev_err(&pdev->dev, "can't remap base region\n"); |
5004 | goto err_unmap; | 5006 | goto err_unmap; |
@@ -5013,7 +5015,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
5013 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { | 5015 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { |
5014 | struct RUNTIME_9060 __iomem *ctl_addr; | 5016 | struct RUNTIME_9060 __iomem *ctl_addr; |
5015 | 5017 | ||
5016 | ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl); | 5018 | ctl_addr = addr0 = ioremap_nocache(pci_resource_start(pdev, 0), |
5019 | CyPCI_Zctl); | ||
5017 | if (addr0 == NULL) { | 5020 | if (addr0 == NULL) { |
5018 | dev_err(&pdev->dev, "can't remap ctl region\n"); | 5021 | dev_err(&pdev->dev, "can't remap ctl region\n"); |
5019 | goto err_reg; | 5022 | goto err_reg; |
@@ -5026,8 +5029,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
5026 | 5029 | ||
5027 | mailbox = (u32)readl(&ctl_addr->mail_box_0); | 5030 | mailbox = (u32)readl(&ctl_addr->mail_box_0); |
5028 | 5031 | ||
5029 | addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ? | 5032 | addr2 = ioremap_nocache(pci_resource_start(pdev, 2), |
5030 | CyPCI_Ze_win : CyPCI_Zwin); | 5033 | mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin); |
5031 | if (addr2 == NULL) { | 5034 | if (addr2 == NULL) { |
5032 | dev_err(&pdev->dev, "can't remap base region\n"); | 5035 | dev_err(&pdev->dev, "can't remap base region\n"); |
5033 | goto err_unmap; | 5036 | goto err_unmap; |
@@ -5159,9 +5162,9 @@ err_null: | |||
5159 | cy_card[card_no].base_addr = NULL; | 5162 | cy_card[card_no].base_addr = NULL; |
5160 | free_irq(irq, &cy_card[card_no]); | 5163 | free_irq(irq, &cy_card[card_no]); |
5161 | err_unmap: | 5164 | err_unmap: |
5162 | pci_iounmap(pdev, addr0); | 5165 | iounmap(addr0); |
5163 | if (addr2) | 5166 | if (addr2) |
5164 | pci_iounmap(pdev, addr2); | 5167 | iounmap(addr2); |
5165 | err_reg: | 5168 | err_reg: |
5166 | pci_release_regions(pdev); | 5169 | pci_release_regions(pdev); |
5167 | err_dis: | 5170 | err_dis: |
@@ -5186,9 +5189,9 @@ static void __devexit cy_pci_remove(struct pci_dev *pdev) | |||
5186 | cy_writew(cinfo->ctl_addr + 0x68, | 5189 | cy_writew(cinfo->ctl_addr + 0x68, |
5187 | readw(cinfo->ctl_addr + 0x68) & ~0x0900); | 5190 | readw(cinfo->ctl_addr + 0x68) & ~0x0900); |
5188 | 5191 | ||
5189 | pci_iounmap(pdev, cinfo->base_addr); | 5192 | iounmap(cinfo->base_addr); |
5190 | if (cinfo->ctl_addr) | 5193 | if (cinfo->ctl_addr) |
5191 | pci_iounmap(pdev, cinfo->ctl_addr); | 5194 | iounmap(cinfo->ctl_addr); |
5192 | if (cinfo->irq | 5195 | if (cinfo->irq |
5193 | #ifndef CONFIG_CYZ_INTR | 5196 | #ifndef CONFIG_CYZ_INTR |
5194 | && !IS_CYC_Z(*cinfo) | 5197 | && !IS_CYC_Z(*cinfo) |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 456e4ede049f..4998b2761e8f 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -1376,6 +1376,7 @@ static void post_fep_init(unsigned int crd) | |||
1376 | unsigned long flags; | 1376 | unsigned long flags; |
1377 | u16 tseg, rseg; | 1377 | u16 tseg, rseg; |
1378 | 1378 | ||
1379 | tty_port_init(&ch->port); | ||
1379 | ch->brdchan = bc; | 1380 | ch->brdchan = bc; |
1380 | ch->mailbox = gd; | 1381 | ch->mailbox = gd; |
1381 | INIT_WORK(&ch->tqueue, do_softint); | 1382 | INIT_WORK(&ch->tqueue, do_softint); |
@@ -1510,10 +1511,6 @@ static void post_fep_init(unsigned int crd) | |||
1510 | ch->fepstopca = 0; | 1511 | ch->fepstopca = 0; |
1511 | 1512 | ||
1512 | ch->close_delay = 50; | 1513 | ch->close_delay = 50; |
1513 | ch->port.count = 0; | ||
1514 | ch->port.blocked_open = 0; | ||
1515 | init_waitqueue_head(&ch->port.open_wait); | ||
1516 | init_waitqueue_head(&ch->port.close_wait); | ||
1517 | 1514 | ||
1518 | spin_unlock_irqrestore(&epca_lock, flags); | 1515 | spin_unlock_irqrestore(&epca_lock, flags); |
1519 | } | 1516 | } |
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index 19d3afb0e50c..c6090f84a2e4 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c | |||
@@ -54,8 +54,6 @@ int gs_put_char(struct tty_struct * tty, unsigned char ch) | |||
54 | 54 | ||
55 | func_enter (); | 55 | func_enter (); |
56 | 56 | ||
57 | if (!tty) return 0; | ||
58 | |||
59 | port = tty->driver_data; | 57 | port = tty->driver_data; |
60 | 58 | ||
61 | if (!port) return 0; | 59 | if (!port) return 0; |
@@ -97,8 +95,6 @@ int gs_write(struct tty_struct * tty, | |||
97 | 95 | ||
98 | func_enter (); | 96 | func_enter (); |
99 | 97 | ||
100 | if (!tty) return 0; | ||
101 | |||
102 | port = tty->driver_data; | 98 | port = tty->driver_data; |
103 | 99 | ||
104 | if (!port) return 0; | 100 | if (!port) return 0; |
@@ -185,7 +181,6 @@ static int gs_real_chars_in_buffer(struct tty_struct *tty) | |||
185 | struct gs_port *port; | 181 | struct gs_port *port; |
186 | func_enter (); | 182 | func_enter (); |
187 | 183 | ||
188 | if (!tty) return 0; | ||
189 | port = tty->driver_data; | 184 | port = tty->driver_data; |
190 | 185 | ||
191 | if (!port->rd) return 0; | 186 | if (!port->rd) return 0; |
@@ -274,8 +269,6 @@ void gs_flush_buffer(struct tty_struct *tty) | |||
274 | 269 | ||
275 | func_enter (); | 270 | func_enter (); |
276 | 271 | ||
277 | if (!tty) return; | ||
278 | |||
279 | port = tty->driver_data; | 272 | port = tty->driver_data; |
280 | 273 | ||
281 | if (!port) return; | 274 | if (!port) return; |
@@ -296,8 +289,6 @@ void gs_flush_chars(struct tty_struct * tty) | |||
296 | 289 | ||
297 | func_enter (); | 290 | func_enter (); |
298 | 291 | ||
299 | if (!tty) return; | ||
300 | |||
301 | port = tty->driver_data; | 292 | port = tty->driver_data; |
302 | 293 | ||
303 | if (!port) return; | 294 | if (!port) return; |
@@ -321,8 +312,6 @@ void gs_stop(struct tty_struct * tty) | |||
321 | 312 | ||
322 | func_enter (); | 313 | func_enter (); |
323 | 314 | ||
324 | if (!tty) return; | ||
325 | |||
326 | port = tty->driver_data; | 315 | port = tty->driver_data; |
327 | 316 | ||
328 | if (!port) return; | 317 | if (!port) return; |
@@ -341,8 +330,6 @@ void gs_start(struct tty_struct * tty) | |||
341 | { | 330 | { |
342 | struct gs_port *port; | 331 | struct gs_port *port; |
343 | 332 | ||
344 | if (!tty) return; | ||
345 | |||
346 | port = tty->driver_data; | 333 | port = tty->driver_data; |
347 | 334 | ||
348 | if (!port) return; | 335 | if (!port) return; |
@@ -393,8 +380,6 @@ void gs_hangup(struct tty_struct *tty) | |||
393 | 380 | ||
394 | func_enter (); | 381 | func_enter (); |
395 | 382 | ||
396 | if (!tty) return; | ||
397 | |||
398 | port = tty->driver_data; | 383 | port = tty->driver_data; |
399 | tty = port->port.tty; | 384 | tty = port->port.tty; |
400 | if (!tty) | 385 | if (!tty) |
@@ -426,8 +411,6 @@ int gs_block_til_ready(void *port_, struct file * filp) | |||
426 | 411 | ||
427 | tty = port->port.tty; | 412 | tty = port->port.tty; |
428 | 413 | ||
429 | if (!tty) return 0; | ||
430 | |||
431 | gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); | 414 | gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); |
432 | /* | 415 | /* |
433 | * If the device is in the middle of being closed, then block | 416 | * If the device is in the middle of being closed, then block |
@@ -523,8 +506,6 @@ void gs_close(struct tty_struct * tty, struct file * filp) | |||
523 | 506 | ||
524 | func_enter (); | 507 | func_enter (); |
525 | 508 | ||
526 | if (!tty) return; | ||
527 | |||
528 | port = (struct gs_port *) tty->driver_data; | 509 | port = (struct gs_port *) tty->driver_data; |
529 | 510 | ||
530 | if (!port) return; | 511 | if (!port) return; |
@@ -621,8 +602,6 @@ void gs_set_termios (struct tty_struct * tty, | |||
621 | 602 | ||
622 | func_enter(); | 603 | func_enter(); |
623 | 604 | ||
624 | if (!tty) return; | ||
625 | |||
626 | port = tty->driver_data; | 605 | port = tty->driver_data; |
627 | 606 | ||
628 | if (!port) return; | 607 | if (!port) return; |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index fd64137b1ab9..ec7aded0a2df 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -819,11 +819,11 @@ static int hvc_init(void) | |||
819 | hvc_driver = drv; | 819 | hvc_driver = drv; |
820 | return 0; | 820 | return 0; |
821 | 821 | ||
822 | put_tty: | ||
823 | put_tty_driver(hvc_driver); | ||
824 | stop_thread: | 822 | stop_thread: |
825 | kthread_stop(hvc_task); | 823 | kthread_stop(hvc_task); |
826 | hvc_task = NULL; | 824 | hvc_task = NULL; |
825 | put_tty: | ||
826 | put_tty_driver(drv); | ||
827 | out: | 827 | out: |
828 | return err; | 828 | return err; |
829 | } | 829 | } |
diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile index 939618f62fe1..bc397d92b499 100644 --- a/drivers/char/ip2/Makefile +++ b/drivers/char/ip2/Makefile | |||
@@ -4,5 +4,5 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_COMPUTONE) += ip2.o | 5 | obj-$(CONFIG_COMPUTONE) += ip2.o |
6 | 6 | ||
7 | ip2-objs := ip2base.o ip2main.o | 7 | ip2-objs := ip2main.o |
8 | 8 | ||
diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c index 3601017f58cf..29db44de399f 100644 --- a/drivers/char/ip2/i2ellis.c +++ b/drivers/char/ip2/i2ellis.c | |||
@@ -69,38 +69,6 @@ static DEFINE_RWLOCK(Dl_spinlock); | |||
69 | //======================================================= | 69 | //======================================================= |
70 | 70 | ||
71 | //****************************************************************************** | 71 | //****************************************************************************** |
72 | // Function: iiEllisInit() | ||
73 | // Parameters: None | ||
74 | // | ||
75 | // Returns: Nothing | ||
76 | // | ||
77 | // Description: | ||
78 | // | ||
79 | // This routine performs any required initialization of the iiEllis subsystem. | ||
80 | // | ||
81 | //****************************************************************************** | ||
82 | static void | ||
83 | iiEllisInit(void) | ||
84 | { | ||
85 | } | ||
86 | |||
87 | //****************************************************************************** | ||
88 | // Function: iiEllisCleanup() | ||
89 | // Parameters: None | ||
90 | // | ||
91 | // Returns: Nothing | ||
92 | // | ||
93 | // Description: | ||
94 | // | ||
95 | // This routine performs any required cleanup of the iiEllis subsystem. | ||
96 | // | ||
97 | //****************************************************************************** | ||
98 | static void | ||
99 | iiEllisCleanup(void) | ||
100 | { | ||
101 | } | ||
102 | |||
103 | //****************************************************************************** | ||
104 | // Function: iiSetAddress(pB, address, delay) | 72 | // Function: iiSetAddress(pB, address, delay) |
105 | // Parameters: pB - pointer to the board structure | 73 | // Parameters: pB - pointer to the board structure |
106 | // address - the purported I/O address of the board | 74 | // address - the purported I/O address of the board |
diff --git a/drivers/char/ip2/i2ellis.h b/drivers/char/ip2/i2ellis.h index c88a64e527aa..fb6df2456018 100644 --- a/drivers/char/ip2/i2ellis.h +++ b/drivers/char/ip2/i2ellis.h | |||
@@ -511,7 +511,6 @@ typedef void (*delayFunc_t)(unsigned int); | |||
511 | // | 511 | // |
512 | // Initialization of a board & structure is in four (five!) parts: | 512 | // Initialization of a board & structure is in four (five!) parts: |
513 | // | 513 | // |
514 | // 0) iiEllisInit() - Initialize iiEllis subsystem. | ||
515 | // 1) iiSetAddress() - Define the board address & delay function for a board. | 514 | // 1) iiSetAddress() - Define the board address & delay function for a board. |
516 | // 2) iiReset() - Reset the board (provided it exists) | 515 | // 2) iiReset() - Reset the board (provided it exists) |
517 | // -- Note you may do this to several boards -- | 516 | // -- Note you may do this to several boards -- |
@@ -523,7 +522,6 @@ typedef void (*delayFunc_t)(unsigned int); | |||
523 | // loadware. To change loadware, you must begin again with step 2, resetting | 522 | // loadware. To change loadware, you must begin again with step 2, resetting |
524 | // the board again (step 1 not needed). | 523 | // the board again (step 1 not needed). |
525 | 524 | ||
526 | static void iiEllisInit(void); | ||
527 | static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t ); | 525 | static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t ); |
528 | static int iiReset(i2eBordStrPtr); | 526 | static int iiReset(i2eBordStrPtr); |
529 | static int iiResetDelay(i2eBordStrPtr); | 527 | static int iiResetDelay(i2eBordStrPtr); |
diff --git a/drivers/char/ip2/ip2base.c b/drivers/char/ip2/ip2base.c deleted file mode 100644 index 8155e247c04b..000000000000 --- a/drivers/char/ip2/ip2base.c +++ /dev/null | |||
@@ -1,108 +0,0 @@ | |||
1 | // ip2.c | ||
2 | // This is a dummy module to make the firmware available when needed | ||
3 | // and allows it to be unloaded when not. Rumor is the __initdata | ||
4 | // macro doesn't always works on all platforms so we use this kludge. | ||
5 | // If not compiled as a module it just makes fip_firm avaliable then | ||
6 | // __initdata should work as advertized | ||
7 | // | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/wait.h> | ||
12 | |||
13 | #ifndef __init | ||
14 | #define __init | ||
15 | #endif | ||
16 | #ifndef __initfunc | ||
17 | #define __initfunc(a) a | ||
18 | #endif | ||
19 | #ifndef __initdata | ||
20 | #define __initdata | ||
21 | #endif | ||
22 | |||
23 | #include "ip2types.h" | ||
24 | |||
25 | int | ||
26 | ip2_loadmain(int *, int *); // ref into ip2main.c | ||
27 | |||
28 | /* Note: Add compiled in defaults to these arrays, not to the structure | ||
29 | in ip2.h any longer. That structure WILL get overridden | ||
30 | by these values, or command line values, or insmod values!!! =mhw= | ||
31 | */ | ||
32 | static int io[IP2_MAX_BOARDS]= { 0, 0, 0, 0 }; | ||
33 | static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; | ||
34 | |||
35 | static int poll_only = 0; | ||
36 | |||
37 | MODULE_AUTHOR("Doug McNash"); | ||
38 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); | ||
39 | module_param_array(irq, int, NULL, 0); | ||
40 | MODULE_PARM_DESC(irq,"Interrupts for IntelliPort Cards"); | ||
41 | module_param_array(io, int, NULL, 0); | ||
42 | MODULE_PARM_DESC(io,"I/O ports for IntelliPort Cards"); | ||
43 | module_param(poll_only, bool, 0); | ||
44 | MODULE_PARM_DESC(poll_only,"Do not use card interrupts"); | ||
45 | |||
46 | |||
47 | static int __init ip2_init(void) | ||
48 | { | ||
49 | if( poll_only ) { | ||
50 | /* Hard lock the interrupts to zero */ | ||
51 | irq[0] = irq[1] = irq[2] = irq[3] = 0; | ||
52 | } | ||
53 | |||
54 | return ip2_loadmain(io, irq); | ||
55 | } | ||
56 | module_init(ip2_init); | ||
57 | |||
58 | MODULE_LICENSE("GPL"); | ||
59 | |||
60 | #ifndef MODULE | ||
61 | /****************************************************************************** | ||
62 | * ip2_setup: | ||
63 | * str: kernel command line string | ||
64 | * | ||
65 | * Can't autoprobe the boards so user must specify configuration on | ||
66 | * kernel command line. Sane people build it modular but the others | ||
67 | * come here. | ||
68 | * | ||
69 | * Alternating pairs of io,irq for up to 4 boards. | ||
70 | * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 | ||
71 | * | ||
72 | * io=0 => No board | ||
73 | * io=1 => PCI | ||
74 | * io=2 => EISA | ||
75 | * else => ISA I/O address | ||
76 | * | ||
77 | * irq=0 or invalid for ISA will revert to polling mode | ||
78 | * | ||
79 | * Any value = -1, do not overwrite compiled in value. | ||
80 | * | ||
81 | ******************************************************************************/ | ||
82 | static int __init ip2_setup(char *str) | ||
83 | { | ||
84 | int ints[10]; /* 4 boards, 2 parameters + 2 */ | ||
85 | int i, j; | ||
86 | |||
87 | str = get_options (str, ARRAY_SIZE(ints), ints); | ||
88 | |||
89 | for( i = 0, j = 1; i < 4; i++ ) { | ||
90 | if( j > ints[0] ) { | ||
91 | break; | ||
92 | } | ||
93 | if( ints[j] >= 0 ) { | ||
94 | io[i] = ints[j]; | ||
95 | } | ||
96 | j++; | ||
97 | if( j > ints[0] ) { | ||
98 | break; | ||
99 | } | ||
100 | if( ints[j] >= 0 ) { | ||
101 | irq[i] = ints[j]; | ||
102 | } | ||
103 | j++; | ||
104 | } | ||
105 | return 1; | ||
106 | } | ||
107 | __setup("ip2=", ip2_setup); | ||
108 | #endif /* !MODULE */ | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 689f9dcd3b86..6774572d3759 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -150,15 +150,12 @@ static int ip2_read_proc(char *, char **, off_t, int, int *, void * ); | |||
150 | /*************/ | 150 | /*************/ |
151 | 151 | ||
152 | /* String constants to identify ourselves */ | 152 | /* String constants to identify ourselves */ |
153 | static char *pcName = "Computone IntelliPort Plus multiport driver"; | 153 | static const char pcName[] = "Computone IntelliPort Plus multiport driver"; |
154 | static char *pcVersion = "1.2.14"; | 154 | static const char pcVersion[] = "1.2.14"; |
155 | 155 | ||
156 | /* String constants for port names */ | 156 | /* String constants for port names */ |
157 | static char *pcDriver_name = "ip2"; | 157 | static const char pcDriver_name[] = "ip2"; |
158 | static char *pcIpl = "ip2ipl"; | 158 | static const char pcIpl[] = "ip2ipl"; |
159 | |||
160 | // cheezy kludge or genius - you decide? | ||
161 | int ip2_loadmain(int *, int *); | ||
162 | 159 | ||
163 | /***********************/ | 160 | /***********************/ |
164 | /* Function Prototypes */ | 161 | /* Function Prototypes */ |
@@ -240,8 +237,8 @@ static const struct file_operations ip2_ipl = { | |||
240 | .open = ip2_ipl_open, | 237 | .open = ip2_ipl_open, |
241 | }; | 238 | }; |
242 | 239 | ||
243 | static unsigned long irq_counter = 0; | 240 | static unsigned long irq_counter; |
244 | static unsigned long bh_counter = 0; | 241 | static unsigned long bh_counter; |
245 | 242 | ||
246 | // Use immediate queue to service interrupts | 243 | // Use immediate queue to service interrupts |
247 | #define USE_IQI | 244 | #define USE_IQI |
@@ -252,7 +249,6 @@ static unsigned long bh_counter = 0; | |||
252 | */ | 249 | */ |
253 | #define POLL_TIMEOUT (jiffies + 1) | 250 | #define POLL_TIMEOUT (jiffies + 1) |
254 | static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); | 251 | static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); |
255 | static char TimerOn; | ||
256 | 252 | ||
257 | #ifdef IP2DEBUG_TRACE | 253 | #ifdef IP2DEBUG_TRACE |
258 | /* Trace (debug) buffer data */ | 254 | /* Trace (debug) buffer data */ |
@@ -268,8 +264,8 @@ static int tracewrap; | |||
268 | /**********/ | 264 | /**********/ |
269 | 265 | ||
270 | #if defined(MODULE) && defined(IP2DEBUG_OPEN) | 266 | #if defined(MODULE) && defined(IP2DEBUG_OPEN) |
271 | #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \ | 267 | #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \ |
272 | tty->name,(pCh->flags),ip2_tty_driver->refcount, \ | 268 | tty->name,(pCh->flags), \ |
273 | tty->count,/*GET_USE_COUNT(module)*/0,s) | 269 | tty->count,/*GET_USE_COUNT(module)*/0,s) |
274 | #else | 270 | #else |
275 | #define DBG_CNT(s) | 271 | #define DBG_CNT(s) |
@@ -287,8 +283,9 @@ static int tracewrap; | |||
287 | 283 | ||
288 | MODULE_AUTHOR("Doug McNash"); | 284 | MODULE_AUTHOR("Doug McNash"); |
289 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); | 285 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); |
286 | MODULE_LICENSE("GPL"); | ||
290 | 287 | ||
291 | static int poll_only = 0; | 288 | static int poll_only; |
292 | 289 | ||
293 | static int Eisa_irq; | 290 | static int Eisa_irq; |
294 | static int Eisa_slot; | 291 | static int Eisa_slot; |
@@ -297,34 +294,46 @@ static int iindx; | |||
297 | static char rirqs[IP2_MAX_BOARDS]; | 294 | static char rirqs[IP2_MAX_BOARDS]; |
298 | static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; | 295 | static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; |
299 | 296 | ||
297 | /* Note: Add compiled in defaults to these arrays, not to the structure | ||
298 | in ip2.h any longer. That structure WILL get overridden | ||
299 | by these values, or command line values, or insmod values!!! =mhw= | ||
300 | */ | ||
301 | static int io[IP2_MAX_BOARDS]; | ||
302 | static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; | ||
303 | |||
304 | MODULE_AUTHOR("Doug McNash"); | ||
305 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); | ||
306 | module_param_array(irq, int, NULL, 0); | ||
307 | MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards"); | ||
308 | module_param_array(io, int, NULL, 0); | ||
309 | MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards"); | ||
310 | module_param(poll_only, bool, 0); | ||
311 | MODULE_PARM_DESC(poll_only, "Do not use card interrupts"); | ||
312 | |||
300 | /* for sysfs class support */ | 313 | /* for sysfs class support */ |
301 | static struct class *ip2_class; | 314 | static struct class *ip2_class; |
302 | 315 | ||
303 | // Some functions to keep track of what irq's we have | 316 | /* Some functions to keep track of what irqs we have */ |
304 | 317 | ||
305 | static int | 318 | static int __init is_valid_irq(int irq) |
306 | is_valid_irq(int irq) | ||
307 | { | 319 | { |
308 | int *i = Valid_Irqs; | 320 | int *i = Valid_Irqs; |
309 | 321 | ||
310 | while ((*i != 0) && (*i != irq)) { | 322 | while (*i != 0 && *i != irq) |
311 | i++; | 323 | i++; |
312 | } | 324 | |
313 | return (*i); | 325 | return *i; |
314 | } | 326 | } |
315 | 327 | ||
316 | static void | 328 | static void __init mark_requested_irq(char irq) |
317 | mark_requested_irq( char irq ) | ||
318 | { | 329 | { |
319 | rirqs[iindx++] = irq; | 330 | rirqs[iindx++] = irq; |
320 | } | 331 | } |
321 | 332 | ||
322 | #ifdef MODULE | 333 | static int __exit clear_requested_irq(char irq) |
323 | static int | ||
324 | clear_requested_irq( char irq ) | ||
325 | { | 334 | { |
326 | int i; | 335 | int i; |
327 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 336 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
328 | if (rirqs[i] == irq) { | 337 | if (rirqs[i] == irq) { |
329 | rirqs[i] = 0; | 338 | rirqs[i] = 0; |
330 | return 1; | 339 | return 1; |
@@ -332,17 +341,15 @@ clear_requested_irq( char irq ) | |||
332 | } | 341 | } |
333 | return 0; | 342 | return 0; |
334 | } | 343 | } |
335 | #endif | ||
336 | 344 | ||
337 | static int | 345 | static int have_requested_irq(char irq) |
338 | have_requested_irq( char irq ) | ||
339 | { | 346 | { |
340 | // array init to zeros so 0 irq will not be requested as a side effect | 347 | /* array init to zeros so 0 irq will not be requested as a side |
348 | * effect */ | ||
341 | int i; | 349 | int i; |
342 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 350 | for (i = 0; i < IP2_MAX_BOARDS; ++i) |
343 | if (rirqs[i] == irq) | 351 | if (rirqs[i] == irq) |
344 | return 1; | 352 | return 1; |
345 | } | ||
346 | return 0; | 353 | return 0; |
347 | } | 354 | } |
348 | 355 | ||
@@ -361,53 +368,45 @@ have_requested_irq( char irq ) | |||
361 | /* handle subsequent installations of the driver. All memory allocated by the */ | 368 | /* handle subsequent installations of the driver. All memory allocated by the */ |
362 | /* driver should be returned since it may be unloaded from memory. */ | 369 | /* driver should be returned since it may be unloaded from memory. */ |
363 | /******************************************************************************/ | 370 | /******************************************************************************/ |
364 | #ifdef MODULE | 371 | static void __exit ip2_cleanup_module(void) |
365 | void __exit | ||
366 | ip2_cleanup_module(void) | ||
367 | { | 372 | { |
368 | int err; | 373 | int err; |
369 | int i; | 374 | int i; |
370 | 375 | ||
371 | #ifdef IP2DEBUG_INIT | 376 | del_timer_sync(&PollTimer); |
372 | printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion ); | ||
373 | #endif | ||
374 | /* Stop poll timer if we had one. */ | ||
375 | if ( TimerOn ) { | ||
376 | del_timer ( &PollTimer ); | ||
377 | TimerOn = 0; | ||
378 | } | ||
379 | 377 | ||
380 | /* Reset the boards we have. */ | 378 | /* Reset the boards we have. */ |
381 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 379 | for (i = 0; i < IP2_MAX_BOARDS; i++) |
382 | if ( i2BoardPtrTable[i] ) { | 380 | if (i2BoardPtrTable[i]) |
383 | iiReset( i2BoardPtrTable[i] ); | 381 | iiReset(i2BoardPtrTable[i]); |
384 | } | ||
385 | } | ||
386 | 382 | ||
387 | /* The following is done at most once, if any boards were installed. */ | 383 | /* The following is done at most once, if any boards were installed. */ |
388 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 384 | for (i = 0; i < IP2_MAX_BOARDS; i++) { |
389 | if ( i2BoardPtrTable[i] ) { | 385 | if (i2BoardPtrTable[i]) { |
390 | iiResetDelay( i2BoardPtrTable[i] ); | 386 | iiResetDelay(i2BoardPtrTable[i]); |
391 | /* free io addresses and Tibet */ | 387 | /* free io addresses and Tibet */ |
392 | release_region( ip2config.addr[i], 8 ); | 388 | release_region(ip2config.addr[i], 8); |
393 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); | 389 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); |
394 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); | 390 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, |
391 | 4 * i + 1)); | ||
395 | } | 392 | } |
396 | /* Disable and remove interrupt handler. */ | 393 | /* Disable and remove interrupt handler. */ |
397 | if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { | 394 | if (ip2config.irq[i] > 0 && |
398 | free_irq ( ip2config.irq[i], (void *)&pcName); | 395 | have_requested_irq(ip2config.irq[i])) { |
399 | clear_requested_irq( ip2config.irq[i]); | 396 | free_irq(ip2config.irq[i], (void *)&pcName); |
397 | clear_requested_irq(ip2config.irq[i]); | ||
400 | } | 398 | } |
401 | } | 399 | } |
402 | class_destroy(ip2_class); | 400 | class_destroy(ip2_class); |
403 | if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) { | 401 | err = tty_unregister_driver(ip2_tty_driver); |
404 | printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); | 402 | if (err) |
405 | } | 403 | printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", |
404 | err); | ||
406 | put_tty_driver(ip2_tty_driver); | 405 | put_tty_driver(ip2_tty_driver); |
407 | unregister_chrdev(IP2_IPL_MAJOR, pcIpl); | 406 | unregister_chrdev(IP2_IPL_MAJOR, pcIpl); |
408 | remove_proc_entry("ip2mem", NULL); | 407 | remove_proc_entry("ip2mem", NULL); |
409 | 408 | ||
410 | // free memory | 409 | /* free memory */ |
411 | for (i = 0; i < IP2_MAX_BOARDS; i++) { | 410 | for (i = 0; i < IP2_MAX_BOARDS; i++) { |
412 | void *pB; | 411 | void *pB; |
413 | #ifdef CONFIG_PCI | 412 | #ifdef CONFIG_PCI |
@@ -417,24 +416,18 @@ ip2_cleanup_module(void) | |||
417 | ip2config.pci_dev[i] = NULL; | 416 | ip2config.pci_dev[i] = NULL; |
418 | } | 417 | } |
419 | #endif | 418 | #endif |
420 | if ((pB = i2BoardPtrTable[i]) != 0 ) { | 419 | pB = i2BoardPtrTable[i]; |
421 | kfree ( pB ); | 420 | if (pB != NULL) { |
421 | kfree(pB); | ||
422 | i2BoardPtrTable[i] = NULL; | 422 | i2BoardPtrTable[i] = NULL; |
423 | } | 423 | } |
424 | if ((DevTableMem[i]) != NULL ) { | 424 | if (DevTableMem[i] != NULL) { |
425 | kfree ( DevTableMem[i] ); | 425 | kfree(DevTableMem[i]); |
426 | DevTableMem[i] = NULL; | 426 | DevTableMem[i] = NULL; |
427 | } | 427 | } |
428 | } | 428 | } |
429 | |||
430 | /* Cleanup the iiEllis subsystem. */ | ||
431 | iiEllisCleanup(); | ||
432 | #ifdef IP2DEBUG_INIT | ||
433 | printk (KERN_DEBUG "IP2 Unloaded\n" ); | ||
434 | #endif | ||
435 | } | 429 | } |
436 | module_exit(ip2_cleanup_module); | 430 | module_exit(ip2_cleanup_module); |
437 | #endif /* MODULE */ | ||
438 | 431 | ||
439 | static const struct tty_operations ip2_ops = { | 432 | static const struct tty_operations ip2_ops = { |
440 | .open = ip2_open, | 433 | .open = ip2_open, |
@@ -494,139 +487,168 @@ static const struct firmware *ip2_request_firmware(void) | |||
494 | return fw; | 487 | return fw; |
495 | } | 488 | } |
496 | 489 | ||
497 | int | 490 | #ifndef MODULE |
498 | ip2_loadmain(int *iop, int *irqp) | 491 | /****************************************************************************** |
492 | * ip2_setup: | ||
493 | * str: kernel command line string | ||
494 | * | ||
495 | * Can't autoprobe the boards so user must specify configuration on | ||
496 | * kernel command line. Sane people build it modular but the others | ||
497 | * come here. | ||
498 | * | ||
499 | * Alternating pairs of io,irq for up to 4 boards. | ||
500 | * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 | ||
501 | * | ||
502 | * io=0 => No board | ||
503 | * io=1 => PCI | ||
504 | * io=2 => EISA | ||
505 | * else => ISA I/O address | ||
506 | * | ||
507 | * irq=0 or invalid for ISA will revert to polling mode | ||
508 | * | ||
509 | * Any value = -1, do not overwrite compiled in value. | ||
510 | * | ||
511 | ******************************************************************************/ | ||
512 | static int __init ip2_setup(char *str) | ||
513 | { | ||
514 | int j, ints[10]; /* 4 boards, 2 parameters + 2 */ | ||
515 | unsigned int i; | ||
516 | |||
517 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
518 | |||
519 | for (i = 0, j = 1; i < 4; i++) { | ||
520 | if (j > ints[0]) | ||
521 | break; | ||
522 | if (ints[j] >= 0) | ||
523 | io[i] = ints[j]; | ||
524 | j++; | ||
525 | if (j > ints[0]) | ||
526 | break; | ||
527 | if (ints[j] >= 0) | ||
528 | irq[i] = ints[j]; | ||
529 | j++; | ||
530 | } | ||
531 | return 1; | ||
532 | } | ||
533 | __setup("ip2=", ip2_setup); | ||
534 | #endif /* !MODULE */ | ||
535 | |||
536 | static int __init ip2_loadmain(void) | ||
499 | { | 537 | { |
500 | int i, j, box; | 538 | int i, j, box; |
501 | int err = 0; | 539 | int err = 0; |
502 | static int loaded; | ||
503 | i2eBordStrPtr pB = NULL; | 540 | i2eBordStrPtr pB = NULL; |
504 | int rc = -1; | 541 | int rc = -1; |
505 | static struct pci_dev *pci_dev_i = NULL; | 542 | struct pci_dev *pdev = NULL; |
506 | const struct firmware *fw = NULL; | 543 | const struct firmware *fw = NULL; |
507 | 544 | ||
508 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); | 545 | if (poll_only) { |
546 | /* Hard lock the interrupts to zero */ | ||
547 | irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; | ||
548 | } | ||
549 | |||
550 | ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0); | ||
509 | 551 | ||
510 | /* process command line arguments to modprobe or | 552 | /* process command line arguments to modprobe or |
511 | insmod i.e. iop & irqp */ | 553 | insmod i.e. iop & irqp */ |
512 | /* irqp and iop should ALWAYS be specified now... But we check | 554 | /* irqp and iop should ALWAYS be specified now... But we check |
513 | them individually just to be sure, anyways... */ | 555 | them individually just to be sure, anyways... */ |
514 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 556 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
515 | if (iop) { | 557 | ip2config.addr[i] = io[i]; |
516 | ip2config.addr[i] = iop[i]; | 558 | if (irq[i] >= 0) |
517 | if (irqp) { | 559 | ip2config.irq[i] = irq[i]; |
518 | if( irqp[i] >= 0 ) { | 560 | else |
519 | ip2config.irq[i] = irqp[i]; | 561 | ip2config.irq[i] = 0; |
520 | } else { | 562 | /* This is a little bit of a hack. If poll_only=1 on command |
521 | ip2config.irq[i] = 0; | 563 | line back in ip2.c OR all IRQs on all specified boards are |
522 | } | 564 | explicitly set to 0, then drop to poll only mode and override |
523 | // This is a little bit of a hack. If poll_only=1 on command | 565 | PCI or EISA interrupts. This superceeds the old hack of |
524 | // line back in ip2.c OR all IRQs on all specified boards are | 566 | triggering if all interrupts were zero (like da default). |
525 | // explicitly set to 0, then drop to poll only mode and override | 567 | Still a hack but less prone to random acts of terrorism. |
526 | // PCI or EISA interrupts. This superceeds the old hack of | 568 | |
527 | // triggering if all interrupts were zero (like da default). | 569 | What we really should do, now that the IRQ default is set |
528 | // Still a hack but less prone to random acts of terrorism. | 570 | to -1, is to use 0 as a hard coded, do not probe. |
529 | // | 571 | |
530 | // What we really should do, now that the IRQ default is set | 572 | /\/\|=mhw=|\/\/ |
531 | // to -1, is to use 0 as a hard coded, do not probe. | 573 | */ |
532 | // | 574 | poll_only |= irq[i]; |
533 | // /\/\|=mhw=|\/\/ | ||
534 | poll_only |= irqp[i]; | ||
535 | } | ||
536 | } | ||
537 | } | 575 | } |
538 | poll_only = !poll_only; | 576 | poll_only = !poll_only; |
539 | 577 | ||
540 | /* Announce our presence */ | 578 | /* Announce our presence */ |
541 | printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); | 579 | printk(KERN_INFO "%s version %s\n", pcName, pcVersion); |
542 | |||
543 | // ip2 can be unloaded and reloaded for no good reason | ||
544 | // we can't let that happen here or bad things happen | ||
545 | // second load hoses board but not system - fixme later | ||
546 | if (loaded) { | ||
547 | printk( KERN_INFO "Still loaded\n" ); | ||
548 | return 0; | ||
549 | } | ||
550 | loaded++; | ||
551 | 580 | ||
552 | ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); | 581 | ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); |
553 | if (!ip2_tty_driver) | 582 | if (!ip2_tty_driver) |
554 | return -ENOMEM; | 583 | return -ENOMEM; |
555 | 584 | ||
556 | /* Initialise the iiEllis subsystem. */ | ||
557 | iiEllisInit(); | ||
558 | |||
559 | /* Initialize arrays. */ | ||
560 | memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable ); | ||
561 | memset( DevTable, 0, sizeof DevTable ); | ||
562 | |||
563 | /* Initialise all the boards we can find (up to the maximum). */ | 585 | /* Initialise all the boards we can find (up to the maximum). */ |
564 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 586 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
565 | switch ( ip2config.addr[i] ) { | 587 | switch (ip2config.addr[i]) { |
566 | case 0: /* skip this slot even if card is present */ | 588 | case 0: /* skip this slot even if card is present */ |
567 | break; | 589 | break; |
568 | default: /* ISA */ | 590 | default: /* ISA */ |
569 | /* ISA address must be specified */ | 591 | /* ISA address must be specified */ |
570 | if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) { | 592 | if (ip2config.addr[i] < 0x100 || |
571 | printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n", | 593 | ip2config.addr[i] > 0x3f8) { |
572 | i, ip2config.addr[i] ); | 594 | printk(KERN_ERR "IP2: Bad ISA board %d " |
595 | "address %x\n", i, | ||
596 | ip2config.addr[i]); | ||
573 | ip2config.addr[i] = 0; | 597 | ip2config.addr[i] = 0; |
574 | } else { | 598 | break; |
575 | ip2config.type[i] = ISA; | 599 | } |
576 | 600 | ip2config.type[i] = ISA; | |
577 | /* Check for valid irq argument, set for polling if invalid */ | 601 | |
578 | if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) { | 602 | /* Check for valid irq argument, set for polling if |
579 | printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]); | 603 | * invalid */ |
580 | ip2config.irq[i] = 0;// 0 is polling and is valid in that sense | 604 | if (ip2config.irq[i] && |
581 | } | 605 | !is_valid_irq(ip2config.irq[i])) { |
606 | printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n", | ||
607 | ip2config.irq[i]); | ||
608 | /* 0 is polling and is valid in that sense */ | ||
609 | ip2config.irq[i] = 0; | ||
582 | } | 610 | } |
583 | break; | 611 | break; |
584 | case PCI: | 612 | case PCI: |
585 | #ifdef CONFIG_PCI | 613 | #ifdef CONFIG_PCI |
586 | { | 614 | { |
587 | int status; | 615 | u32 addr; |
616 | int status; | ||
588 | 617 | ||
589 | pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE, | 618 | pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE, |
590 | PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); | 619 | PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev); |
591 | if (pci_dev_i != NULL) { | 620 | if (pdev == NULL) { |
592 | unsigned int addr; | 621 | ip2config.addr[i] = 0; |
593 | 622 | printk(KERN_ERR "IP2: PCI board %d not " | |
594 | if (pci_enable_device(pci_dev_i)) { | 623 | "found\n", i); |
595 | printk( KERN_ERR "IP2: can't enable PCI device at %s\n", | 624 | break; |
596 | pci_name(pci_dev_i)); | 625 | } |
597 | break; | ||
598 | } | ||
599 | ip2config.type[i] = PCI; | ||
600 | ip2config.pci_dev[i] = pci_dev_get(pci_dev_i); | ||
601 | status = | ||
602 | pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr); | ||
603 | if ( addr & 1 ) { | ||
604 | ip2config.addr[i]=(USHORT)(addr&0xfffe); | ||
605 | } else { | ||
606 | printk( KERN_ERR "IP2: PCI I/O address error\n"); | ||
607 | } | ||
608 | 626 | ||
609 | // If the PCI BIOS assigned it, lets try and use it. If we | 627 | if (pci_enable_device(pdev)) { |
610 | // can't acquire it or it screws up, deal with it then. | 628 | dev_err(&pdev->dev, "can't enable device\n"); |
611 | 629 | break; | |
612 | // if (!is_valid_irq(pci_irq)) { | ||
613 | // printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq); | ||
614 | // pci_irq = 0; | ||
615 | // } | ||
616 | ip2config.irq[i] = pci_dev_i->irq; | ||
617 | } else { // ann error | ||
618 | ip2config.addr[i] = 0; | ||
619 | printk(KERN_ERR "IP2: PCI board %d not found\n", i); | ||
620 | } | ||
621 | } | 630 | } |
631 | ip2config.type[i] = PCI; | ||
632 | ip2config.pci_dev[i] = pci_dev_get(pdev); | ||
633 | status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, | ||
634 | &addr); | ||
635 | if (addr & 1) | ||
636 | ip2config.addr[i] = (USHORT)(addr & 0xfffe); | ||
637 | else | ||
638 | dev_err(&pdev->dev, "I/O address error\n"); | ||
639 | |||
640 | ip2config.irq[i] = pdev->irq; | ||
641 | } | ||
622 | #else | 642 | #else |
623 | printk( KERN_ERR "IP2: PCI card specified but PCI support not\n"); | 643 | printk(KERN_ERR "IP2: PCI card specified but PCI " |
624 | printk( KERN_ERR "IP2: configured in this kernel.\n"); | 644 | "support not enabled.\n"); |
625 | printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n"); | 645 | printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI " |
646 | "defined!\n"); | ||
626 | #endif /* CONFIG_PCI */ | 647 | #endif /* CONFIG_PCI */ |
627 | break; | 648 | break; |
628 | case EISA: | 649 | case EISA: |
629 | if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) { | 650 | ip2config.addr[i] = find_eisa_board(Eisa_slot + 1); |
651 | if (ip2config.addr[i] != 0) { | ||
630 | /* Eisa_irq set as side effect, boo */ | 652 | /* Eisa_irq set as side effect, boo */ |
631 | ip2config.type[i] = EISA; | 653 | ip2config.type[i] = EISA; |
632 | } | 654 | } |
@@ -634,31 +656,32 @@ ip2_loadmain(int *iop, int *irqp) | |||
634 | break; | 656 | break; |
635 | } /* switch */ | 657 | } /* switch */ |
636 | } /* for */ | 658 | } /* for */ |
637 | if (pci_dev_i) | 659 | pci_dev_put(pdev); |
638 | pci_dev_put(pci_dev_i); | ||
639 | 660 | ||
640 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 661 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
641 | if ( ip2config.addr[i] ) { | 662 | if (ip2config.addr[i]) { |
642 | pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); | 663 | pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); |
643 | if (pB) { | 664 | if (pB) { |
644 | i2BoardPtrTable[i] = pB; | 665 | i2BoardPtrTable[i] = pB; |
645 | iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer ); | 666 | iiSetAddress(pB, ip2config.addr[i], |
646 | iiReset( pB ); | 667 | ii2DelayTimer); |
647 | } else { | 668 | iiReset(pB); |
648 | printk(KERN_ERR "IP2: board memory allocation error\n"); | 669 | } else |
649 | } | 670 | printk(KERN_ERR "IP2: board memory allocation " |
671 | "error\n"); | ||
650 | } | 672 | } |
651 | } | 673 | } |
652 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 674 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
653 | if ( ( pB = i2BoardPtrTable[i] ) != NULL ) { | 675 | pB = i2BoardPtrTable[i]; |
654 | iiResetDelay( pB ); | 676 | if (pB != NULL) { |
677 | iiResetDelay(pB); | ||
655 | break; | 678 | break; |
656 | } | 679 | } |
657 | } | 680 | } |
658 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 681 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
659 | /* We don't want to request the firmware unless we have at | 682 | /* We don't want to request the firmware unless we have at |
660 | least one board */ | 683 | least one board */ |
661 | if ( i2BoardPtrTable[i] != NULL ) { | 684 | if (i2BoardPtrTable[i] != NULL) { |
662 | if (!fw) | 685 | if (!fw) |
663 | fw = ip2_request_firmware(); | 686 | fw = ip2_request_firmware(); |
664 | if (!fw) | 687 | if (!fw) |
@@ -669,7 +692,7 @@ ip2_loadmain(int *iop, int *irqp) | |||
669 | if (fw) | 692 | if (fw) |
670 | release_firmware(fw); | 693 | release_firmware(fw); |
671 | 694 | ||
672 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); | 695 | ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0); |
673 | 696 | ||
674 | ip2_tty_driver->owner = THIS_MODULE; | 697 | ip2_tty_driver->owner = THIS_MODULE; |
675 | ip2_tty_driver->name = "ttyF"; | 698 | ip2_tty_driver->name = "ttyF"; |
@@ -680,20 +703,23 @@ ip2_loadmain(int *iop, int *irqp) | |||
680 | ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 703 | ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
681 | ip2_tty_driver->init_termios = tty_std_termios; | 704 | ip2_tty_driver->init_termios = tty_std_termios; |
682 | ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; | 705 | ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; |
683 | ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 706 | ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | |
707 | TTY_DRIVER_DYNAMIC_DEV; | ||
684 | tty_set_operations(ip2_tty_driver, &ip2_ops); | 708 | tty_set_operations(ip2_tty_driver, &ip2_ops); |
685 | 709 | ||
686 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 ); | 710 | ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0); |
687 | 711 | ||
688 | /* Register the tty devices. */ | 712 | err = tty_register_driver(ip2_tty_driver); |
689 | if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) { | 713 | if (err) { |
690 | printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err); | 714 | printk(KERN_ERR "IP2: failed to register tty driver\n"); |
691 | put_tty_driver(ip2_tty_driver); | 715 | put_tty_driver(ip2_tty_driver); |
692 | return -EINVAL; | 716 | return err; /* leaking resources */ |
693 | } else | 717 | } |
694 | /* Register the IPL driver. */ | 718 | |
695 | if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) { | 719 | err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl); |
696 | printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err ); | 720 | if (err) { |
721 | printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", | ||
722 | err); | ||
697 | } else { | 723 | } else { |
698 | /* create the sysfs class */ | 724 | /* create the sysfs class */ |
699 | ip2_class = class_create(THIS_MODULE, "ip2"); | 725 | ip2_class = class_create(THIS_MODULE, "ip2"); |
@@ -705,84 +731,86 @@ ip2_loadmain(int *iop, int *irqp) | |||
705 | /* Register the read_procmem thing */ | 731 | /* Register the read_procmem thing */ |
706 | if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { | 732 | if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { |
707 | printk(KERN_ERR "IP2: failed to register read_procmem\n"); | 733 | printk(KERN_ERR "IP2: failed to register read_procmem\n"); |
708 | } else { | 734 | return -EIO; /* leaking resources */ |
735 | } | ||
709 | 736 | ||
710 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 ); | 737 | ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0); |
711 | /* Register the interrupt handler or poll handler, depending upon the | 738 | /* Register the interrupt handler or poll handler, depending upon the |
712 | * specified interrupt. | 739 | * specified interrupt. |
713 | */ | 740 | */ |
714 | 741 | ||
715 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 742 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
716 | if ( 0 == ip2config.addr[i] ) { | 743 | if (ip2config.addr[i] == 0) |
717 | continue; | 744 | continue; |
718 | } | ||
719 | 745 | ||
720 | if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { | 746 | pB = i2BoardPtrTable[i]; |
721 | device_create_drvdata(ip2_class, NULL, | 747 | if (pB != NULL) { |
722 | MKDEV(IP2_IPL_MAJOR, 4 * i), | 748 | device_create_drvdata(ip2_class, NULL, |
723 | NULL, "ipl%d", i); | 749 | MKDEV(IP2_IPL_MAJOR, 4 * i), |
724 | device_create_drvdata(ip2_class, NULL, | 750 | NULL, "ipl%d", i); |
725 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), | 751 | device_create_drvdata(ip2_class, NULL, |
726 | NULL, "stat%d", i); | 752 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), |
727 | 753 | NULL, "stat%d", i); | |
728 | for ( box = 0; box < ABS_MAX_BOXES; ++box ) | 754 | |
729 | { | 755 | for (box = 0; box < ABS_MAX_BOXES; box++) |
730 | for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) | 756 | for (j = 0; j < ABS_BIGGEST_BOX; j++) |
731 | { | 757 | if (pB->i2eChannelMap[box] & (1 << j)) |
732 | if ( pB->i2eChannelMap[box] & (1 << j) ) | 758 | tty_register_device( |
733 | { | 759 | ip2_tty_driver, |
734 | tty_register_device(ip2_tty_driver, | 760 | j + ABS_BIGGEST_BOX * |
735 | j + ABS_BIGGEST_BOX * | 761 | (box+i*ABS_MAX_BOXES), |
736 | (box+i*ABS_MAX_BOXES), NULL); | 762 | NULL); |
737 | } | 763 | } |
738 | } | ||
739 | } | ||
740 | } | ||
741 | 764 | ||
742 | if (poll_only) { | 765 | if (poll_only) { |
743 | // Poll only forces driver to only use polling and | 766 | /* Poll only forces driver to only use polling and |
744 | // to ignore the probed PCI or EISA interrupts. | 767 | to ignore the probed PCI or EISA interrupts. */ |
745 | ip2config.irq[i] = CIR_POLL; | 768 | ip2config.irq[i] = CIR_POLL; |
746 | } | 769 | } |
747 | if ( ip2config.irq[i] == CIR_POLL ) { | 770 | if (ip2config.irq[i] == CIR_POLL) { |
748 | retry: | 771 | retry: |
749 | if (!TimerOn) { | 772 | if (!timer_pending(&PollTimer)) { |
750 | PollTimer.expires = POLL_TIMEOUT; | 773 | mod_timer(&PollTimer, POLL_TIMEOUT); |
751 | add_timer ( &PollTimer ); | 774 | printk(KERN_INFO "IP2: polling\n"); |
752 | TimerOn = 1; | ||
753 | printk( KERN_INFO "IP2: polling\n"); | ||
754 | } | ||
755 | } else { | ||
756 | if (have_requested_irq(ip2config.irq[i])) | ||
757 | continue; | ||
758 | rc = request_irq( ip2config.irq[i], ip2_interrupt, | ||
759 | IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), | ||
760 | pcName, i2BoardPtrTable[i]); | ||
761 | if (rc) { | ||
762 | printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc); | ||
763 | ip2config.irq[i] = CIR_POLL; | ||
764 | printk( KERN_INFO "IP2: Polling %ld/sec.\n", | ||
765 | (POLL_TIMEOUT - jiffies)); | ||
766 | goto retry; | ||
767 | } | ||
768 | mark_requested_irq(ip2config.irq[i]); | ||
769 | /* Initialise the interrupt handler bottom half (aka slih). */ | ||
770 | } | 775 | } |
771 | } | 776 | } else { |
772 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 777 | if (have_requested_irq(ip2config.irq[i])) |
773 | if ( i2BoardPtrTable[i] ) { | 778 | continue; |
774 | set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */ | 779 | rc = request_irq(ip2config.irq[i], ip2_interrupt, |
780 | IP2_SA_FLAGS | | ||
781 | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), | ||
782 | pcName, i2BoardPtrTable[i]); | ||
783 | if (rc) { | ||
784 | printk(KERN_ERR "IP2: request_irq failed: " | ||
785 | "error %d\n", rc); | ||
786 | ip2config.irq[i] = CIR_POLL; | ||
787 | printk(KERN_INFO "IP2: Polling %ld/sec.\n", | ||
788 | (POLL_TIMEOUT - jiffies)); | ||
789 | goto retry; | ||
775 | } | 790 | } |
791 | mark_requested_irq(ip2config.irq[i]); | ||
792 | /* Initialise the interrupt handler bottom half | ||
793 | * (aka slih). */ | ||
776 | } | 794 | } |
777 | } | 795 | } |
778 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 ); | 796 | |
779 | goto out; | 797 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
798 | if (i2BoardPtrTable[i]) { | ||
799 | /* set and enable board interrupt */ | ||
800 | set_irq(i, ip2config.irq[i]); | ||
801 | } | ||
802 | } | ||
803 | |||
804 | ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0); | ||
805 | |||
806 | return 0; | ||
780 | 807 | ||
781 | out_chrdev: | 808 | out_chrdev: |
782 | unregister_chrdev(IP2_IPL_MAJOR, "ip2"); | 809 | unregister_chrdev(IP2_IPL_MAJOR, "ip2"); |
783 | out: | 810 | /* unregister and put tty here */ |
784 | return err; | 811 | return err; |
785 | } | 812 | } |
813 | module_init(ip2_loadmain); | ||
786 | 814 | ||
787 | /******************************************************************************/ | 815 | /******************************************************************************/ |
788 | /* Function: ip2_init_board() */ | 816 | /* Function: ip2_init_board() */ |
@@ -1199,9 +1227,8 @@ ip2_polled_interrupt(void) | |||
1199 | { | 1227 | { |
1200 | int i; | 1228 | int i; |
1201 | i2eBordStrPtr pB; | 1229 | i2eBordStrPtr pB; |
1202 | const int irq = 0; | ||
1203 | 1230 | ||
1204 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq ); | 1231 | ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0); |
1205 | 1232 | ||
1206 | /* Service just the boards on the list using this irq */ | 1233 | /* Service just the boards on the list using this irq */ |
1207 | for( i = 0; i < i2nBoards; ++i ) { | 1234 | for( i = 0; i < i2nBoards; ++i ) { |
@@ -1210,9 +1237,8 @@ ip2_polled_interrupt(void) | |||
1210 | // Only process those boards which match our IRQ. | 1237 | // Only process those boards which match our IRQ. |
1211 | // IRQ = 0 for polled boards, we won't poll "IRQ" boards | 1238 | // IRQ = 0 for polled boards, we won't poll "IRQ" boards |
1212 | 1239 | ||
1213 | if ( pB && (pB->i2eUsingIrq == irq) ) { | 1240 | if (pB && pB->i2eUsingIrq == 0) |
1214 | ip2_irq_work(pB); | 1241 | ip2_irq_work(pB); |
1215 | } | ||
1216 | } | 1242 | } |
1217 | 1243 | ||
1218 | ++irq_counter; | 1244 | ++irq_counter; |
@@ -1250,16 +1276,12 @@ ip2_poll(unsigned long arg) | |||
1250 | { | 1276 | { |
1251 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); | 1277 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); |
1252 | 1278 | ||
1253 | TimerOn = 0; // it's the truth but not checked in service | ||
1254 | |||
1255 | // Just polled boards, IRQ = 0 will hit all non-interrupt boards. | 1279 | // Just polled boards, IRQ = 0 will hit all non-interrupt boards. |
1256 | // It will NOT poll boards handled by hard interrupts. | 1280 | // It will NOT poll boards handled by hard interrupts. |
1257 | // The issue of queued BH interrupts is handled in ip2_interrupt(). | 1281 | // The issue of queued BH interrupts is handled in ip2_interrupt(). |
1258 | ip2_polled_interrupt(); | 1282 | ip2_polled_interrupt(); |
1259 | 1283 | ||
1260 | PollTimer.expires = POLL_TIMEOUT; | 1284 | mod_timer(&PollTimer, POLL_TIMEOUT); |
1261 | add_timer( &PollTimer ); | ||
1262 | TimerOn = 1; | ||
1263 | 1285 | ||
1264 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); | 1286 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); |
1265 | } | 1287 | } |
@@ -2871,7 +2893,7 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) | |||
2871 | case 13: | 2893 | case 13: |
2872 | switch ( cmd ) { | 2894 | switch ( cmd ) { |
2873 | case 64: /* Driver - ip2stat */ | 2895 | case 64: /* Driver - ip2stat */ |
2874 | rc = put_user(ip2_tty_driver->refcount, pIndex++ ); | 2896 | rc = put_user(-1, pIndex++ ); |
2875 | rc = put_user(irq_counter, pIndex++ ); | 2897 | rc = put_user(irq_counter, pIndex++ ); |
2876 | rc = put_user(bh_counter, pIndex++ ); | 2898 | rc = put_user(bh_counter, pIndex++ ); |
2877 | break; | 2899 | break; |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 8f7cc190b62d..7d30ee1d3fca 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -421,17 +421,16 @@ static void isicom_tx(unsigned long _data) | |||
421 | if (retries >= 100) | 421 | if (retries >= 100) |
422 | goto unlock; | 422 | goto unlock; |
423 | 423 | ||
424 | tty = tty_port_tty_get(&port->port); | ||
425 | if (tty == NULL) | ||
426 | goto put_unlock; | ||
427 | |||
424 | for (; count > 0; count--, port++) { | 428 | for (; count > 0; count--, port++) { |
425 | /* port not active or tx disabled to force flow control */ | 429 | /* port not active or tx disabled to force flow control */ |
426 | if (!(port->port.flags & ASYNC_INITIALIZED) || | 430 | if (!(port->port.flags & ASYNC_INITIALIZED) || |
427 | !(port->status & ISI_TXOK)) | 431 | !(port->status & ISI_TXOK)) |
428 | continue; | 432 | continue; |
429 | 433 | ||
430 | tty = port->port.tty; | ||
431 | |||
432 | if (tty == NULL) | ||
433 | continue; | ||
434 | |||
435 | txcount = min_t(short, TX_SIZE, port->xmit_cnt); | 434 | txcount = min_t(short, TX_SIZE, port->xmit_cnt); |
436 | if (txcount <= 0 || tty->stopped || tty->hw_stopped) | 435 | if (txcount <= 0 || tty->stopped || tty->hw_stopped) |
437 | continue; | 436 | continue; |
@@ -489,6 +488,8 @@ static void isicom_tx(unsigned long _data) | |||
489 | tty_wakeup(tty); | 488 | tty_wakeup(tty); |
490 | } | 489 | } |
491 | 490 | ||
491 | put_unlock: | ||
492 | tty_kref_put(tty); | ||
492 | unlock: | 493 | unlock: |
493 | spin_unlock_irqrestore(&isi_card[card].card_lock, flags); | 494 | spin_unlock_irqrestore(&isi_card[card].card_lock, flags); |
494 | /* schedule another tx for hopefully in about 10ms */ | 495 | /* schedule another tx for hopefully in about 10ms */ |
@@ -547,7 +548,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
547 | return IRQ_HANDLED; | 548 | return IRQ_HANDLED; |
548 | } | 549 | } |
549 | 550 | ||
550 | tty = port->port.tty; | 551 | tty = tty_port_tty_get(&port->port); |
551 | if (tty == NULL) { | 552 | if (tty == NULL) { |
552 | word_count = byte_count >> 1; | 553 | word_count = byte_count >> 1; |
553 | while (byte_count > 1) { | 554 | while (byte_count > 1) { |
@@ -588,7 +589,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
588 | } | 589 | } |
589 | 590 | ||
590 | if (port->port.flags & ASYNC_CTS_FLOW) { | 591 | if (port->port.flags & ASYNC_CTS_FLOW) { |
591 | if (port->port.tty->hw_stopped) { | 592 | if (tty->hw_stopped) { |
592 | if (header & ISI_CTS) { | 593 | if (header & ISI_CTS) { |
593 | port->port.tty->hw_stopped = 0; | 594 | port->port.tty->hw_stopped = 0; |
594 | /* start tx ing */ | 595 | /* start tx ing */ |
@@ -597,7 +598,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
597 | tty_wakeup(tty); | 598 | tty_wakeup(tty); |
598 | } | 599 | } |
599 | } else if (!(header & ISI_CTS)) { | 600 | } else if (!(header & ISI_CTS)) { |
600 | port->port.tty->hw_stopped = 1; | 601 | tty->hw_stopped = 1; |
601 | /* stop tx ing */ | 602 | /* stop tx ing */ |
602 | port->status &= ~(ISI_TXOK | ISI_CTS); | 603 | port->status &= ~(ISI_TXOK | ISI_CTS); |
603 | } | 604 | } |
@@ -660,24 +661,21 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
660 | } | 661 | } |
661 | outw(0x0000, base+0x04); /* enable interrupts */ | 662 | outw(0x0000, base+0x04); /* enable interrupts */ |
662 | spin_unlock(&card->card_lock); | 663 | spin_unlock(&card->card_lock); |
664 | tty_kref_put(tty); | ||
663 | 665 | ||
664 | return IRQ_HANDLED; | 666 | return IRQ_HANDLED; |
665 | } | 667 | } |
666 | 668 | ||
667 | static void isicom_config_port(struct isi_port *port) | 669 | static void isicom_config_port(struct tty_struct *tty) |
668 | { | 670 | { |
671 | struct isi_port *port = tty->driver_data; | ||
669 | struct isi_board *card = port->card; | 672 | struct isi_board *card = port->card; |
670 | struct tty_struct *tty; | ||
671 | unsigned long baud; | 673 | unsigned long baud; |
672 | unsigned long base = card->base; | 674 | unsigned long base = card->base; |
673 | u16 channel_setup, channel = port->channel, | 675 | u16 channel_setup, channel = port->channel, |
674 | shift_count = card->shift_count; | 676 | shift_count = card->shift_count; |
675 | unsigned char flow_ctrl; | 677 | unsigned char flow_ctrl; |
676 | 678 | ||
677 | tty = port->port.tty; | ||
678 | |||
679 | if (tty == NULL) | ||
680 | return; | ||
681 | /* FIXME: Switch to new tty baud API */ | 679 | /* FIXME: Switch to new tty baud API */ |
682 | baud = C_BAUD(tty); | 680 | baud = C_BAUD(tty); |
683 | if (baud & CBAUDEX) { | 681 | if (baud & CBAUDEX) { |
@@ -690,7 +688,7 @@ static void isicom_config_port(struct isi_port *port) | |||
690 | 688 | ||
691 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ | 689 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ |
692 | if (baud < 1 || baud > 4) | 690 | if (baud < 1 || baud > 4) |
693 | port->port.tty->termios->c_cflag &= ~CBAUDEX; | 691 | tty->termios->c_cflag &= ~CBAUDEX; |
694 | else | 692 | else |
695 | baud += 15; | 693 | baud += 15; |
696 | } | 694 | } |
@@ -797,8 +795,9 @@ static inline void isicom_setup_board(struct isi_board *bp) | |||
797 | spin_unlock_irqrestore(&bp->card_lock, flags); | 795 | spin_unlock_irqrestore(&bp->card_lock, flags); |
798 | } | 796 | } |
799 | 797 | ||
800 | static int isicom_setup_port(struct isi_port *port) | 798 | static int isicom_setup_port(struct tty_struct *tty) |
801 | { | 799 | { |
800 | struct isi_port *port = tty->driver_data; | ||
802 | struct isi_board *card = port->card; | 801 | struct isi_board *card = port->card; |
803 | unsigned long flags; | 802 | unsigned long flags; |
804 | 803 | ||
@@ -808,8 +807,7 @@ static int isicom_setup_port(struct isi_port *port) | |||
808 | return -ENOMEM; | 807 | return -ENOMEM; |
809 | 808 | ||
810 | spin_lock_irqsave(&card->card_lock, flags); | 809 | spin_lock_irqsave(&card->card_lock, flags); |
811 | if (port->port.tty) | 810 | clear_bit(TTY_IO_ERROR, &tty->flags); |
812 | clear_bit(TTY_IO_ERROR, &port->port.tty->flags); | ||
813 | if (port->port.count == 1) | 811 | if (port->port.count == 1) |
814 | card->count++; | 812 | card->count++; |
815 | 813 | ||
@@ -823,7 +821,7 @@ static int isicom_setup_port(struct isi_port *port) | |||
823 | InterruptTheCard(card->base); | 821 | InterruptTheCard(card->base); |
824 | } | 822 | } |
825 | 823 | ||
826 | isicom_config_port(port); | 824 | isicom_config_port(tty); |
827 | port->port.flags |= ASYNC_INITIALIZED; | 825 | port->port.flags |= ASYNC_INITIALIZED; |
828 | spin_unlock_irqrestore(&card->card_lock, flags); | 826 | spin_unlock_irqrestore(&card->card_lock, flags); |
829 | 827 | ||
@@ -934,8 +932,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) | |||
934 | 932 | ||
935 | port->port.count++; | 933 | port->port.count++; |
936 | tty->driver_data = port; | 934 | tty->driver_data = port; |
937 | port->port.tty = tty; | 935 | tty_port_tty_set(&port->port, tty); |
938 | error = isicom_setup_port(port); | 936 | error = isicom_setup_port(tty); |
939 | if (error == 0) | 937 | if (error == 0) |
940 | error = block_til_ready(tty, filp, port); | 938 | error = block_til_ready(tty, filp, port); |
941 | return error; | 939 | return error; |
@@ -955,15 +953,17 @@ static void isicom_shutdown_port(struct isi_port *port) | |||
955 | struct isi_board *card = port->card; | 953 | struct isi_board *card = port->card; |
956 | struct tty_struct *tty; | 954 | struct tty_struct *tty; |
957 | 955 | ||
958 | tty = port->port.tty; | 956 | tty = tty_port_tty_get(&port->port); |
959 | 957 | ||
960 | if (!(port->port.flags & ASYNC_INITIALIZED)) | 958 | if (!(port->port.flags & ASYNC_INITIALIZED)) { |
959 | tty_kref_put(tty); | ||
961 | return; | 960 | return; |
961 | } | ||
962 | 962 | ||
963 | tty_port_free_xmit_buf(&port->port); | 963 | tty_port_free_xmit_buf(&port->port); |
964 | port->port.flags &= ~ASYNC_INITIALIZED; | 964 | port->port.flags &= ~ASYNC_INITIALIZED; |
965 | /* 3rd October 2000 : Vinayak P Risbud */ | 965 | /* 3rd October 2000 : Vinayak P Risbud */ |
966 | port->port.tty = NULL; | 966 | tty_port_tty_set(&port->port, NULL); |
967 | 967 | ||
968 | /*Fix done by Anil .S on 30-04-2001 | 968 | /*Fix done by Anil .S on 30-04-2001 |
969 | remote login through isi port has dtr toggle problem | 969 | remote login through isi port has dtr toggle problem |
@@ -1243,9 +1243,10 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file, | |||
1243 | return 0; | 1243 | return 0; |
1244 | } | 1244 | } |
1245 | 1245 | ||
1246 | static int isicom_set_serial_info(struct isi_port *port, | 1246 | static int isicom_set_serial_info(struct tty_struct *tty, |
1247 | struct serial_struct __user *info) | 1247 | struct serial_struct __user *info) |
1248 | { | 1248 | { |
1249 | struct isi_port *port = tty->driver_data; | ||
1249 | struct serial_struct newinfo; | 1250 | struct serial_struct newinfo; |
1250 | int reconfig_port; | 1251 | int reconfig_port; |
1251 | 1252 | ||
@@ -1276,7 +1277,7 @@ static int isicom_set_serial_info(struct isi_port *port, | |||
1276 | if (reconfig_port) { | 1277 | if (reconfig_port) { |
1277 | unsigned long flags; | 1278 | unsigned long flags; |
1278 | spin_lock_irqsave(&port->card->card_lock, flags); | 1279 | spin_lock_irqsave(&port->card->card_lock, flags); |
1279 | isicom_config_port(port); | 1280 | isicom_config_port(tty); |
1280 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1281 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1281 | } | 1282 | } |
1282 | unlock_kernel(); | 1283 | unlock_kernel(); |
@@ -1318,7 +1319,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp, | |||
1318 | return isicom_get_serial_info(port, argp); | 1319 | return isicom_get_serial_info(port, argp); |
1319 | 1320 | ||
1320 | case TIOCSSERIAL: | 1321 | case TIOCSSERIAL: |
1321 | return isicom_set_serial_info(port, argp); | 1322 | return isicom_set_serial_info(tty, argp); |
1322 | 1323 | ||
1323 | default: | 1324 | default: |
1324 | return -ENOIOCTLCMD; | 1325 | return -ENOIOCTLCMD; |
@@ -1341,7 +1342,7 @@ static void isicom_set_termios(struct tty_struct *tty, | |||
1341 | return; | 1342 | return; |
1342 | 1343 | ||
1343 | spin_lock_irqsave(&port->card->card_lock, flags); | 1344 | spin_lock_irqsave(&port->card->card_lock, flags); |
1344 | isicom_config_port(port); | 1345 | isicom_config_port(tty); |
1345 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1346 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1346 | 1347 | ||
1347 | if ((old_termios->c_cflag & CRTSCTS) && | 1348 | if ((old_termios->c_cflag & CRTSCTS) && |
@@ -1419,7 +1420,7 @@ static void isicom_hangup(struct tty_struct *tty) | |||
1419 | 1420 | ||
1420 | port->port.count = 0; | 1421 | port->port.count = 0; |
1421 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1422 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1422 | port->port.tty = NULL; | 1423 | tty_port_tty_set(&port->port, NULL); |
1423 | wake_up_interruptible(&port->port.open_wait); | 1424 | wake_up_interruptible(&port->port.open_wait); |
1424 | } | 1425 | } |
1425 | 1426 | ||
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 843a2afaf204..505d7a1f6b8c 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -623,24 +623,25 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
623 | static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); | 623 | static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); |
624 | static void stli_poll(unsigned long arg); | 624 | static void stli_poll(unsigned long arg); |
625 | static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); | 625 | static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); |
626 | static int stli_initopen(struct stlibrd *brdp, struct stliport *portp); | 626 | static int stli_initopen(struct tty_struct *tty, struct stlibrd *brdp, struct stliport *portp); |
627 | static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); | 627 | static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); |
628 | static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); | 628 | static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); |
629 | static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp); | 629 | static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, |
630 | static int stli_setport(struct stliport *portp); | 630 | struct stliport *portp, struct file *filp); |
631 | static int stli_setport(struct tty_struct *tty); | ||
631 | static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); | 632 | static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); |
632 | static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); | 633 | static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); |
633 | static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); | 634 | static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); |
634 | static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); | 635 | static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); |
635 | static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); | 636 | static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); |
636 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); | 637 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); |
637 | static long stli_mktiocm(unsigned long sigvalue); | 638 | static long stli_mktiocm(unsigned long sigvalue); |
638 | static void stli_read(struct stlibrd *brdp, struct stliport *portp); | 639 | static void stli_read(struct stlibrd *brdp, struct stliport *portp); |
639 | static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); | 640 | static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); |
640 | static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp); | 641 | static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp); |
641 | static int stli_getbrdstats(combrd_t __user *bp); | 642 | static int stli_getbrdstats(combrd_t __user *bp); |
642 | static int stli_getportstats(struct stliport *portp, comstats_t __user *cp); | 643 | static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, comstats_t __user *cp); |
643 | static int stli_portcmdstats(struct stliport *portp); | 644 | static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp); |
644 | static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); | 645 | static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); |
645 | static int stli_getportstruct(struct stliport __user *arg); | 646 | static int stli_getportstruct(struct stliport __user *arg); |
646 | static int stli_getbrdstruct(struct stlibrd __user *arg); | 647 | static int stli_getbrdstruct(struct stlibrd __user *arg); |
@@ -731,12 +732,16 @@ static void stli_cleanup_ports(struct stlibrd *brdp) | |||
731 | { | 732 | { |
732 | struct stliport *portp; | 733 | struct stliport *portp; |
733 | unsigned int j; | 734 | unsigned int j; |
735 | struct tty_struct *tty; | ||
734 | 736 | ||
735 | for (j = 0; j < STL_MAXPORTS; j++) { | 737 | for (j = 0; j < STL_MAXPORTS; j++) { |
736 | portp = brdp->ports[j]; | 738 | portp = brdp->ports[j]; |
737 | if (portp != NULL) { | 739 | if (portp != NULL) { |
738 | if (portp->port.tty != NULL) | 740 | tty = tty_port_tty_get(&portp->port); |
739 | tty_hangup(portp->port.tty); | 741 | if (tty != NULL) { |
742 | tty_hangup(tty); | ||
743 | tty_kref_put(tty); | ||
744 | } | ||
740 | kfree(portp); | 745 | kfree(portp); |
741 | } | 746 | } |
742 | } | 747 | } |
@@ -824,7 +829,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
824 | * requires several commands to the board we will need to wait for any | 829 | * requires several commands to the board we will need to wait for any |
825 | * other open that is already initializing the port. | 830 | * other open that is already initializing the port. |
826 | */ | 831 | */ |
827 | portp->port.tty = tty; | 832 | tty_port_tty_set(&portp->port, tty); |
828 | tty->driver_data = portp; | 833 | tty->driver_data = portp; |
829 | portp->port.count++; | 834 | portp->port.count++; |
830 | 835 | ||
@@ -835,7 +840,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
835 | 840 | ||
836 | if ((portp->port.flags & ASYNC_INITIALIZED) == 0) { | 841 | if ((portp->port.flags & ASYNC_INITIALIZED) == 0) { |
837 | set_bit(ST_INITIALIZING, &portp->state); | 842 | set_bit(ST_INITIALIZING, &portp->state); |
838 | if ((rc = stli_initopen(brdp, portp)) >= 0) { | 843 | if ((rc = stli_initopen(tty, brdp, portp)) >= 0) { |
839 | portp->port.flags |= ASYNC_INITIALIZED; | 844 | portp->port.flags |= ASYNC_INITIALIZED; |
840 | clear_bit(TTY_IO_ERROR, &tty->flags); | 845 | clear_bit(TTY_IO_ERROR, &tty->flags); |
841 | } | 846 | } |
@@ -864,7 +869,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
864 | * then also we might have to wait for carrier. | 869 | * then also we might have to wait for carrier. |
865 | */ | 870 | */ |
866 | if (!(filp->f_flags & O_NONBLOCK)) { | 871 | if (!(filp->f_flags & O_NONBLOCK)) { |
867 | if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) | 872 | if ((rc = stli_waitcarrier(tty, brdp, portp, filp)) != 0) |
868 | return rc; | 873 | return rc; |
869 | } | 874 | } |
870 | portp->port.flags |= ASYNC_NORMAL_ACTIVE; | 875 | portp->port.flags |= ASYNC_NORMAL_ACTIVE; |
@@ -930,7 +935,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
930 | stli_flushbuffer(tty); | 935 | stli_flushbuffer(tty); |
931 | 936 | ||
932 | tty->closing = 0; | 937 | tty->closing = 0; |
933 | portp->port.tty = NULL; | 938 | tty_port_tty_set(&portp->port, NULL); |
934 | 939 | ||
935 | if (portp->openwaitcnt) { | 940 | if (portp->openwaitcnt) { |
936 | if (portp->close_delay) | 941 | if (portp->close_delay) |
@@ -952,9 +957,9 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
952 | * this still all happens pretty quickly. | 957 | * this still all happens pretty quickly. |
953 | */ | 958 | */ |
954 | 959 | ||
955 | static int stli_initopen(struct stlibrd *brdp, struct stliport *portp) | 960 | static int stli_initopen(struct tty_struct *tty, |
961 | struct stlibrd *brdp, struct stliport *portp) | ||
956 | { | 962 | { |
957 | struct tty_struct *tty; | ||
958 | asynotify_t nt; | 963 | asynotify_t nt; |
959 | asyport_t aport; | 964 | asyport_t aport; |
960 | int rc; | 965 | int rc; |
@@ -969,10 +974,7 @@ static int stli_initopen(struct stlibrd *brdp, struct stliport *portp) | |||
969 | sizeof(asynotify_t), 0)) < 0) | 974 | sizeof(asynotify_t), 0)) < 0) |
970 | return rc; | 975 | return rc; |
971 | 976 | ||
972 | tty = portp->port.tty; | 977 | stli_mkasyport(tty, portp, &aport, tty->termios); |
973 | if (tty == NULL) | ||
974 | return -ENODEV; | ||
975 | stli_mkasyport(portp, &aport, tty->termios); | ||
976 | if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, | 978 | if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, |
977 | sizeof(asyport_t), 0)) < 0) | 979 | sizeof(asyport_t), 0)) < 0) |
978 | return rc; | 980 | return rc; |
@@ -1161,22 +1163,21 @@ static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned l | |||
1161 | * waiting for the command to complete - so must have user context. | 1163 | * waiting for the command to complete - so must have user context. |
1162 | */ | 1164 | */ |
1163 | 1165 | ||
1164 | static int stli_setport(struct stliport *portp) | 1166 | static int stli_setport(struct tty_struct *tty) |
1165 | { | 1167 | { |
1168 | struct stliport *portp = tty->driver_data; | ||
1166 | struct stlibrd *brdp; | 1169 | struct stlibrd *brdp; |
1167 | asyport_t aport; | 1170 | asyport_t aport; |
1168 | 1171 | ||
1169 | if (portp == NULL) | 1172 | if (portp == NULL) |
1170 | return -ENODEV; | 1173 | return -ENODEV; |
1171 | if (portp->port.tty == NULL) | ||
1172 | return -ENODEV; | ||
1173 | if (portp->brdnr >= stli_nrbrds) | 1174 | if (portp->brdnr >= stli_nrbrds) |
1174 | return -ENODEV; | 1175 | return -ENODEV; |
1175 | brdp = stli_brds[portp->brdnr]; | 1176 | brdp = stli_brds[portp->brdnr]; |
1176 | if (brdp == NULL) | 1177 | if (brdp == NULL) |
1177 | return -ENODEV; | 1178 | return -ENODEV; |
1178 | 1179 | ||
1179 | stli_mkasyport(portp, &aport, portp->port.tty->termios); | 1180 | stli_mkasyport(tty, portp, &aport, tty->termios); |
1180 | return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); | 1181 | return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); |
1181 | } | 1182 | } |
1182 | 1183 | ||
@@ -1187,7 +1188,8 @@ static int stli_setport(struct stliport *portp) | |||
1187 | * maybe because if we are clocal then we don't need to wait... | 1188 | * maybe because if we are clocal then we don't need to wait... |
1188 | */ | 1189 | */ |
1189 | 1190 | ||
1190 | static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp) | 1191 | static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, |
1192 | struct stliport *portp, struct file *filp) | ||
1191 | { | 1193 | { |
1192 | unsigned long flags; | 1194 | unsigned long flags; |
1193 | int rc, doclocal; | 1195 | int rc, doclocal; |
@@ -1195,7 +1197,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct | |||
1195 | rc = 0; | 1197 | rc = 0; |
1196 | doclocal = 0; | 1198 | doclocal = 0; |
1197 | 1199 | ||
1198 | if (portp->port.tty->termios->c_cflag & CLOCAL) | 1200 | if (tty->termios->c_cflag & CLOCAL) |
1199 | doclocal++; | 1201 | doclocal++; |
1200 | 1202 | ||
1201 | spin_lock_irqsave(&stli_lock, flags); | 1203 | spin_lock_irqsave(&stli_lock, flags); |
@@ -1373,8 +1375,6 @@ static void stli_flushchars(struct tty_struct *tty) | |||
1373 | stli_txcookrealsize = 0; | 1375 | stli_txcookrealsize = 0; |
1374 | stli_txcooktty = NULL; | 1376 | stli_txcooktty = NULL; |
1375 | 1377 | ||
1376 | if (tty == NULL) | ||
1377 | return; | ||
1378 | if (cooktty == NULL) | 1378 | if (cooktty == NULL) |
1379 | return; | 1379 | return; |
1380 | if (tty != cooktty) | 1380 | if (tty != cooktty) |
@@ -1572,10 +1572,11 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s | |||
1572 | * just quietly ignore any requests to change irq, etc. | 1572 | * just quietly ignore any requests to change irq, etc. |
1573 | */ | 1573 | */ |
1574 | 1574 | ||
1575 | static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp) | 1575 | static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp) |
1576 | { | 1576 | { |
1577 | struct serial_struct sio; | 1577 | struct serial_struct sio; |
1578 | int rc; | 1578 | int rc; |
1579 | struct stliport *portp = tty->driver_data; | ||
1579 | 1580 | ||
1580 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) | 1581 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) |
1581 | return -EFAULT; | 1582 | return -EFAULT; |
@@ -1594,7 +1595,7 @@ static int stli_setserial(struct stliport *portp, struct serial_struct __user *s | |||
1594 | portp->closing_wait = sio.closing_wait; | 1595 | portp->closing_wait = sio.closing_wait; |
1595 | portp->custom_divisor = sio.custom_divisor; | 1596 | portp->custom_divisor = sio.custom_divisor; |
1596 | 1597 | ||
1597 | if ((rc = stli_setport(portp)) < 0) | 1598 | if ((rc = stli_setport(tty)) < 0) |
1598 | return rc; | 1599 | return rc; |
1599 | return 0; | 1600 | return 0; |
1600 | } | 1601 | } |
@@ -1685,17 +1686,17 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm | |||
1685 | rc = stli_getserial(portp, argp); | 1686 | rc = stli_getserial(portp, argp); |
1686 | break; | 1687 | break; |
1687 | case TIOCSSERIAL: | 1688 | case TIOCSSERIAL: |
1688 | rc = stli_setserial(portp, argp); | 1689 | rc = stli_setserial(tty, argp); |
1689 | break; | 1690 | break; |
1690 | case STL_GETPFLAG: | 1691 | case STL_GETPFLAG: |
1691 | rc = put_user(portp->pflag, (unsigned __user *)argp); | 1692 | rc = put_user(portp->pflag, (unsigned __user *)argp); |
1692 | break; | 1693 | break; |
1693 | case STL_SETPFLAG: | 1694 | case STL_SETPFLAG: |
1694 | if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0) | 1695 | if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0) |
1695 | stli_setport(portp); | 1696 | stli_setport(tty); |
1696 | break; | 1697 | break; |
1697 | case COM_GETPORTSTATS: | 1698 | case COM_GETPORTSTATS: |
1698 | rc = stli_getportstats(portp, argp); | 1699 | rc = stli_getportstats(tty, portp, argp); |
1699 | break; | 1700 | break; |
1700 | case COM_CLRPORTSTATS: | 1701 | case COM_CLRPORTSTATS: |
1701 | rc = stli_clrportstats(portp, argp); | 1702 | rc = stli_clrportstats(portp, argp); |
@@ -1729,8 +1730,6 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old) | |||
1729 | struct ktermios *tiosp; | 1730 | struct ktermios *tiosp; |
1730 | asyport_t aport; | 1731 | asyport_t aport; |
1731 | 1732 | ||
1732 | if (tty == NULL) | ||
1733 | return; | ||
1734 | portp = tty->driver_data; | 1733 | portp = tty->driver_data; |
1735 | if (portp == NULL) | 1734 | if (portp == NULL) |
1736 | return; | 1735 | return; |
@@ -1742,7 +1741,7 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old) | |||
1742 | 1741 | ||
1743 | tiosp = tty->termios; | 1742 | tiosp = tty->termios; |
1744 | 1743 | ||
1745 | stli_mkasyport(portp, &aport, tiosp); | 1744 | stli_mkasyport(tty, portp, &aport, tiosp); |
1746 | stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0); | 1745 | stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0); |
1747 | stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1); | 1746 | stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1); |
1748 | stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, | 1747 | stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, |
@@ -1854,7 +1853,7 @@ static void stli_hangup(struct tty_struct *tty) | |||
1854 | clear_bit(ST_TXBUSY, &portp->state); | 1853 | clear_bit(ST_TXBUSY, &portp->state); |
1855 | clear_bit(ST_RXSTOP, &portp->state); | 1854 | clear_bit(ST_RXSTOP, &portp->state); |
1856 | set_bit(TTY_IO_ERROR, &tty->flags); | 1855 | set_bit(TTY_IO_ERROR, &tty->flags); |
1857 | portp->port.tty = NULL; | 1856 | tty_port_tty_set(&portp->port, NULL); |
1858 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1857 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1859 | portp->port.count = 0; | 1858 | portp->port.count = 0; |
1860 | spin_unlock_irqrestore(&stli_lock, flags); | 1859 | spin_unlock_irqrestore(&stli_lock, flags); |
@@ -1935,8 +1934,6 @@ static void stli_waituntilsent(struct tty_struct *tty, int timeout) | |||
1935 | struct stliport *portp; | 1934 | struct stliport *portp; |
1936 | unsigned long tend; | 1935 | unsigned long tend; |
1937 | 1936 | ||
1938 | if (tty == NULL) | ||
1939 | return; | ||
1940 | portp = tty->driver_data; | 1937 | portp = tty->driver_data; |
1941 | if (portp == NULL) | 1938 | if (portp == NULL) |
1942 | return; | 1939 | return; |
@@ -1998,7 +1995,7 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn | |||
1998 | char *sp, *uart; | 1995 | char *sp, *uart; |
1999 | int rc, cnt; | 1996 | int rc, cnt; |
2000 | 1997 | ||
2001 | rc = stli_portcmdstats(portp); | 1998 | rc = stli_portcmdstats(NULL, portp); |
2002 | 1999 | ||
2003 | uart = "UNKNOWN"; | 2000 | uart = "UNKNOWN"; |
2004 | if (brdp->state & BST_STARTED) { | 2001 | if (brdp->state & BST_STARTED) { |
@@ -2188,7 +2185,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp) | |||
2188 | 2185 | ||
2189 | if (test_bit(ST_RXSTOP, &portp->state)) | 2186 | if (test_bit(ST_RXSTOP, &portp->state)) |
2190 | return; | 2187 | return; |
2191 | tty = portp->port.tty; | 2188 | tty = tty_port_tty_get(&portp->port); |
2192 | if (tty == NULL) | 2189 | if (tty == NULL) |
2193 | return; | 2190 | return; |
2194 | 2191 | ||
@@ -2230,6 +2227,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp) | |||
2230 | set_bit(ST_RXING, &portp->state); | 2227 | set_bit(ST_RXING, &portp->state); |
2231 | 2228 | ||
2232 | tty_schedule_flip(tty); | 2229 | tty_schedule_flip(tty); |
2230 | tty_kref_put(tty); | ||
2233 | } | 2231 | } |
2234 | 2232 | ||
2235 | /*****************************************************************************/ | 2233 | /*****************************************************************************/ |
@@ -2362,7 +2360,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) | |||
2362 | if (ap->notify) { | 2360 | if (ap->notify) { |
2363 | nt = ap->changed; | 2361 | nt = ap->changed; |
2364 | ap->notify = 0; | 2362 | ap->notify = 0; |
2365 | tty = portp->port.tty; | 2363 | tty = tty_port_tty_get(&portp->port); |
2366 | 2364 | ||
2367 | if (nt.signal & SG_DCD) { | 2365 | if (nt.signal & SG_DCD) { |
2368 | oldsigs = portp->sigs; | 2366 | oldsigs = portp->sigs; |
@@ -2399,6 +2397,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) | |||
2399 | tty_schedule_flip(tty); | 2397 | tty_schedule_flip(tty); |
2400 | } | 2398 | } |
2401 | } | 2399 | } |
2400 | tty_kref_put(tty); | ||
2402 | 2401 | ||
2403 | if (nt.data & DT_RXBUSY) { | 2402 | if (nt.data & DT_RXBUSY) { |
2404 | donerx++; | 2403 | donerx++; |
@@ -2535,14 +2534,15 @@ static void stli_poll(unsigned long arg) | |||
2535 | * the slave. | 2534 | * the slave. |
2536 | */ | 2535 | */ |
2537 | 2536 | ||
2538 | static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp) | 2537 | static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, |
2538 | asyport_t *pp, struct ktermios *tiosp) | ||
2539 | { | 2539 | { |
2540 | memset(pp, 0, sizeof(asyport_t)); | 2540 | memset(pp, 0, sizeof(asyport_t)); |
2541 | 2541 | ||
2542 | /* | 2542 | /* |
2543 | * Start of by setting the baud, char size, parity and stop bit info. | 2543 | * Start of by setting the baud, char size, parity and stop bit info. |
2544 | */ | 2544 | */ |
2545 | pp->baudout = tty_get_baud_rate(portp->port.tty); | 2545 | pp->baudout = tty_get_baud_rate(tty); |
2546 | if ((tiosp->c_cflag & CBAUD) == B38400) { | 2546 | if ((tiosp->c_cflag & CBAUD) == B38400) { |
2547 | if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 2547 | if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
2548 | pp->baudout = 57600; | 2548 | pp->baudout = 57600; |
@@ -2695,7 +2695,7 @@ static int stli_initports(struct stlibrd *brdp) | |||
2695 | printk("STALLION: failed to allocate port structure\n"); | 2695 | printk("STALLION: failed to allocate port structure\n"); |
2696 | continue; | 2696 | continue; |
2697 | } | 2697 | } |
2698 | 2698 | tty_port_init(&portp->port); | |
2699 | portp->magic = STLI_PORTMAGIC; | 2699 | portp->magic = STLI_PORTMAGIC; |
2700 | portp->portnr = i; | 2700 | portp->portnr = i; |
2701 | portp->brdnr = brdp->brdnr; | 2701 | portp->brdnr = brdp->brdnr; |
@@ -4220,7 +4220,7 @@ static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, | |||
4220 | * what port to get stats for (used through board control device). | 4220 | * what port to get stats for (used through board control device). |
4221 | */ | 4221 | */ |
4222 | 4222 | ||
4223 | static int stli_portcmdstats(struct stliport *portp) | 4223 | static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) |
4224 | { | 4224 | { |
4225 | unsigned long flags; | 4225 | unsigned long flags; |
4226 | struct stlibrd *brdp; | 4226 | struct stlibrd *brdp; |
@@ -4249,15 +4249,15 @@ static int stli_portcmdstats(struct stliport *portp) | |||
4249 | stli_comstats.flags = portp->port.flags; | 4249 | stli_comstats.flags = portp->port.flags; |
4250 | 4250 | ||
4251 | spin_lock_irqsave(&brd_lock, flags); | 4251 | spin_lock_irqsave(&brd_lock, flags); |
4252 | if (portp->port.tty != NULL) { | 4252 | if (tty != NULL) { |
4253 | if (portp->port.tty->driver_data == portp) { | 4253 | if (portp->port.tty == tty) { |
4254 | stli_comstats.ttystate = portp->port.tty->flags; | 4254 | stli_comstats.ttystate = tty->flags; |
4255 | stli_comstats.rxbuffered = -1; | 4255 | stli_comstats.rxbuffered = -1; |
4256 | if (portp->port.tty->termios != NULL) { | 4256 | if (tty->termios != NULL) { |
4257 | stli_comstats.cflags = portp->port.tty->termios->c_cflag; | 4257 | stli_comstats.cflags = tty->termios->c_cflag; |
4258 | stli_comstats.iflags = portp->port.tty->termios->c_iflag; | 4258 | stli_comstats.iflags = tty->termios->c_iflag; |
4259 | stli_comstats.oflags = portp->port.tty->termios->c_oflag; | 4259 | stli_comstats.oflags = tty->termios->c_oflag; |
4260 | stli_comstats.lflags = portp->port.tty->termios->c_lflag; | 4260 | stli_comstats.lflags = tty->termios->c_lflag; |
4261 | } | 4261 | } |
4262 | } | 4262 | } |
4263 | } | 4263 | } |
@@ -4294,7 +4294,8 @@ static int stli_portcmdstats(struct stliport *portp) | |||
4294 | * what port to get stats for (used through board control device). | 4294 | * what port to get stats for (used through board control device). |
4295 | */ | 4295 | */ |
4296 | 4296 | ||
4297 | static int stli_getportstats(struct stliport *portp, comstats_t __user *cp) | 4297 | static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, |
4298 | comstats_t __user *cp) | ||
4298 | { | 4299 | { |
4299 | struct stlibrd *brdp; | 4300 | struct stlibrd *brdp; |
4300 | int rc; | 4301 | int rc; |
@@ -4312,7 +4313,7 @@ static int stli_getportstats(struct stliport *portp, comstats_t __user *cp) | |||
4312 | if (!brdp) | 4313 | if (!brdp) |
4313 | return -ENODEV; | 4314 | return -ENODEV; |
4314 | 4315 | ||
4315 | if ((rc = stli_portcmdstats(portp)) < 0) | 4316 | if ((rc = stli_portcmdstats(tty, portp)) < 0) |
4316 | return rc; | 4317 | return rc; |
4317 | 4318 | ||
4318 | return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ? | 4319 | return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ? |
@@ -4427,7 +4428,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
4427 | 4428 | ||
4428 | switch (cmd) { | 4429 | switch (cmd) { |
4429 | case COM_GETPORTSTATS: | 4430 | case COM_GETPORTSTATS: |
4430 | rc = stli_getportstats(NULL, argp); | 4431 | rc = stli_getportstats(NULL, NULL, argp); |
4431 | done++; | 4432 | done++; |
4432 | break; | 4433 | break; |
4433 | case COM_CLRPORTSTATS: | 4434 | case COM_CLRPORTSTATS: |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index d3d7864e0c1e..5df4003ad873 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -205,7 +205,7 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, | |||
205 | static void moxa_poll(unsigned long); | 205 | static void moxa_poll(unsigned long); |
206 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); | 206 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); |
207 | static void moxa_setup_empty_event(struct tty_struct *); | 207 | static void moxa_setup_empty_event(struct tty_struct *); |
208 | static void moxa_shut_down(struct moxa_port *); | 208 | static void moxa_shut_down(struct tty_struct *); |
209 | /* | 209 | /* |
210 | * moxa board interface functions: | 210 | * moxa board interface functions: |
211 | */ | 211 | */ |
@@ -217,7 +217,7 @@ static void MoxaPortLineCtrl(struct moxa_port *, int, int); | |||
217 | static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); | 217 | static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); |
218 | static int MoxaPortLineStatus(struct moxa_port *); | 218 | static int MoxaPortLineStatus(struct moxa_port *); |
219 | static void MoxaPortFlushData(struct moxa_port *, int); | 219 | static void MoxaPortFlushData(struct moxa_port *, int); |
220 | static int MoxaPortWriteData(struct moxa_port *, const unsigned char *, int); | 220 | static int MoxaPortWriteData(struct tty_struct *, const unsigned char *, int); |
221 | static int MoxaPortReadData(struct moxa_port *); | 221 | static int MoxaPortReadData(struct moxa_port *); |
222 | static int MoxaPortTxQueue(struct moxa_port *); | 222 | static int MoxaPortTxQueue(struct moxa_port *); |
223 | static int MoxaPortRxQueue(struct moxa_port *); | 223 | static int MoxaPortRxQueue(struct moxa_port *); |
@@ -332,6 +332,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
332 | for (i = 0; i < MAX_BOARDS; i++) { | 332 | for (i = 0; i < MAX_BOARDS; i++) { |
333 | p = moxa_boards[i].ports; | 333 | p = moxa_boards[i].ports; |
334 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { | 334 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { |
335 | struct tty_struct *ttyp; | ||
335 | memset(&tmp, 0, sizeof(tmp)); | 336 | memset(&tmp, 0, sizeof(tmp)); |
336 | if (!moxa_boards[i].ready) | 337 | if (!moxa_boards[i].ready) |
337 | goto copy; | 338 | goto copy; |
@@ -344,10 +345,12 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
344 | if (status & 4) | 345 | if (status & 4) |
345 | tmp.dcd = 1; | 346 | tmp.dcd = 1; |
346 | 347 | ||
347 | if (!p->port.tty || !p->port.tty->termios) | 348 | ttyp = tty_port_tty_get(&p->port); |
349 | if (!ttyp || !ttyp->termios) | ||
348 | tmp.cflag = p->cflag; | 350 | tmp.cflag = p->cflag; |
349 | else | 351 | else |
350 | tmp.cflag = p->port.tty->termios->c_cflag; | 352 | tmp.cflag = ttyp->termios->c_cflag; |
353 | tty_kref_put(tty); | ||
351 | copy: | 354 | copy: |
352 | if (copy_to_user(argm, &tmp, sizeof(tmp))) { | 355 | if (copy_to_user(argm, &tmp, sizeof(tmp))) { |
353 | mutex_unlock(&moxa_openlock); | 356 | mutex_unlock(&moxa_openlock); |
@@ -880,8 +883,14 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) | |||
880 | 883 | ||
881 | /* pci hot-un-plug support */ | 884 | /* pci hot-un-plug support */ |
882 | for (a = 0; a < brd->numPorts; a++) | 885 | for (a = 0; a < brd->numPorts; a++) |
883 | if (brd->ports[a].port.flags & ASYNC_INITIALIZED) | 886 | if (brd->ports[a].port.flags & ASYNC_INITIALIZED) { |
884 | tty_hangup(brd->ports[a].port.tty); | 887 | struct tty_struct *tty = tty_port_tty_get( |
888 | &brd->ports[a].port); | ||
889 | if (tty) { | ||
890 | tty_hangup(tty); | ||
891 | tty_kref_put(tty); | ||
892 | } | ||
893 | } | ||
885 | while (1) { | 894 | while (1) { |
886 | opened = 0; | 895 | opened = 0; |
887 | for (a = 0; a < brd->numPorts; a++) | 896 | for (a = 0; a < brd->numPorts; a++) |
@@ -1096,13 +1105,14 @@ static void __exit moxa_exit(void) | |||
1096 | module_init(moxa_init); | 1105 | module_init(moxa_init); |
1097 | module_exit(moxa_exit); | 1106 | module_exit(moxa_exit); |
1098 | 1107 | ||
1099 | static void moxa_close_port(struct moxa_port *ch) | 1108 | static void moxa_close_port(struct tty_struct *tty) |
1100 | { | 1109 | { |
1101 | moxa_shut_down(ch); | 1110 | struct moxa_port *ch = tty->driver_data; |
1111 | moxa_shut_down(tty); | ||
1102 | MoxaPortFlushData(ch, 2); | 1112 | MoxaPortFlushData(ch, 2); |
1103 | ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1113 | ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1104 | ch->port.tty->driver_data = NULL; | 1114 | tty->driver_data = NULL; |
1105 | ch->port.tty = NULL; | 1115 | tty_port_tty_set(&ch->port, NULL); |
1106 | } | 1116 | } |
1107 | 1117 | ||
1108 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, | 1118 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, |
@@ -1161,7 +1171,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1161 | ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; | 1171 | ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; |
1162 | ch->port.count++; | 1172 | ch->port.count++; |
1163 | tty->driver_data = ch; | 1173 | tty->driver_data = ch; |
1164 | ch->port.tty = tty; | 1174 | tty_port_tty_set(&ch->port, tty); |
1165 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { | 1175 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { |
1166 | ch->statusflags = 0; | 1176 | ch->statusflags = 0; |
1167 | moxa_set_tty_param(tty, tty->termios); | 1177 | moxa_set_tty_param(tty, tty->termios); |
@@ -1179,7 +1189,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1179 | if (retval) { | 1189 | if (retval) { |
1180 | if (ch->port.count) /* 0 means already hung up... */ | 1190 | if (ch->port.count) /* 0 means already hung up... */ |
1181 | if (--ch->port.count == 0) | 1191 | if (--ch->port.count == 0) |
1182 | moxa_close_port(ch); | 1192 | moxa_close_port(tty); |
1183 | } else | 1193 | } else |
1184 | ch->port.flags |= ASYNC_NORMAL_ACTIVE; | 1194 | ch->port.flags |= ASYNC_NORMAL_ACTIVE; |
1185 | mutex_unlock(&moxa_openlock); | 1195 | mutex_unlock(&moxa_openlock); |
@@ -1219,7 +1229,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
1219 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ | 1229 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ |
1220 | } | 1230 | } |
1221 | 1231 | ||
1222 | moxa_close_port(ch); | 1232 | moxa_close_port(tty); |
1223 | unlock: | 1233 | unlock: |
1224 | mutex_unlock(&moxa_openlock); | 1234 | mutex_unlock(&moxa_openlock); |
1225 | } | 1235 | } |
@@ -1234,7 +1244,7 @@ static int moxa_write(struct tty_struct *tty, | |||
1234 | return 0; | 1244 | return 0; |
1235 | 1245 | ||
1236 | spin_lock_bh(&moxa_lock); | 1246 | spin_lock_bh(&moxa_lock); |
1237 | len = MoxaPortWriteData(ch, buf, count); | 1247 | len = MoxaPortWriteData(tty, buf, count); |
1238 | spin_unlock_bh(&moxa_lock); | 1248 | spin_unlock_bh(&moxa_lock); |
1239 | 1249 | ||
1240 | ch->statusflags |= LOWWAIT; | 1250 | ch->statusflags |= LOWWAIT; |
@@ -1409,7 +1419,7 @@ static void moxa_hangup(struct tty_struct *tty) | |||
1409 | return; | 1419 | return; |
1410 | } | 1420 | } |
1411 | ch->port.count = 0; | 1421 | ch->port.count = 0; |
1412 | moxa_close_port(ch); | 1422 | moxa_close_port(tty); |
1413 | mutex_unlock(&moxa_openlock); | 1423 | mutex_unlock(&moxa_openlock); |
1414 | 1424 | ||
1415 | wake_up_interruptible(&ch->port.open_wait); | 1425 | wake_up_interruptible(&ch->port.open_wait); |
@@ -1417,11 +1427,14 @@ static void moxa_hangup(struct tty_struct *tty) | |||
1417 | 1427 | ||
1418 | static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) | 1428 | static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) |
1419 | { | 1429 | { |
1430 | struct tty_struct *tty; | ||
1420 | dcd = !!dcd; | 1431 | dcd = !!dcd; |
1421 | 1432 | ||
1422 | if (dcd != p->DCDState && p->port.tty && C_CLOCAL(p->port.tty)) { | 1433 | if (dcd != p->DCDState) { |
1423 | if (!dcd) | 1434 | tty = tty_port_tty_get(&p->port); |
1424 | tty_hangup(p->port.tty); | 1435 | if (tty && C_CLOCAL(tty) && !dcd) |
1436 | tty_hangup(tty); | ||
1437 | tty_kref_put(tty); | ||
1425 | } | 1438 | } |
1426 | p->DCDState = dcd; | 1439 | p->DCDState = dcd; |
1427 | } | 1440 | } |
@@ -1429,7 +1442,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) | |||
1429 | static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | 1442 | static int moxa_poll_port(struct moxa_port *p, unsigned int handle, |
1430 | u16 __iomem *ip) | 1443 | u16 __iomem *ip) |
1431 | { | 1444 | { |
1432 | struct tty_struct *tty = p->port.tty; | 1445 | struct tty_struct *tty = tty_port_tty_get(&p->port); |
1433 | void __iomem *ofsAddr; | 1446 | void __iomem *ofsAddr; |
1434 | unsigned int inited = p->port.flags & ASYNC_INITIALIZED; | 1447 | unsigned int inited = p->port.flags & ASYNC_INITIALIZED; |
1435 | u16 intr; | 1448 | u16 intr; |
@@ -1476,6 +1489,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | |||
1476 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 1489 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
1477 | tty_schedule_flip(tty); | 1490 | tty_schedule_flip(tty); |
1478 | } | 1491 | } |
1492 | tty_kref_put(tty); | ||
1479 | 1493 | ||
1480 | if (intr & IntrLine) | 1494 | if (intr & IntrLine) |
1481 | moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); | 1495 | moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); |
@@ -1560,9 +1574,9 @@ static void moxa_setup_empty_event(struct tty_struct *tty) | |||
1560 | spin_unlock_bh(&moxa_lock); | 1574 | spin_unlock_bh(&moxa_lock); |
1561 | } | 1575 | } |
1562 | 1576 | ||
1563 | static void moxa_shut_down(struct moxa_port *ch) | 1577 | static void moxa_shut_down(struct tty_struct *tty) |
1564 | { | 1578 | { |
1565 | struct tty_struct *tp = ch->port.tty; | 1579 | struct moxa_port *ch = tty->driver_data; |
1566 | 1580 | ||
1567 | if (!(ch->port.flags & ASYNC_INITIALIZED)) | 1581 | if (!(ch->port.flags & ASYNC_INITIALIZED)) |
1568 | return; | 1582 | return; |
@@ -1572,7 +1586,7 @@ static void moxa_shut_down(struct moxa_port *ch) | |||
1572 | /* | 1586 | /* |
1573 | * If we're a modem control device and HUPCL is on, drop RTS & DTR. | 1587 | * If we're a modem control device and HUPCL is on, drop RTS & DTR. |
1574 | */ | 1588 | */ |
1575 | if (C_HUPCL(tp)) | 1589 | if (C_HUPCL(tty)) |
1576 | MoxaPortLineCtrl(ch, 0, 0); | 1590 | MoxaPortLineCtrl(ch, 0, 0); |
1577 | 1591 | ||
1578 | spin_lock_bh(&moxa_lock); | 1592 | spin_lock_bh(&moxa_lock); |
@@ -1953,9 +1967,10 @@ static int MoxaPortLineStatus(struct moxa_port *port) | |||
1953 | return val; | 1967 | return val; |
1954 | } | 1968 | } |
1955 | 1969 | ||
1956 | static int MoxaPortWriteData(struct moxa_port *port, | 1970 | static int MoxaPortWriteData(struct tty_struct *tty, |
1957 | const unsigned char *buffer, int len) | 1971 | const unsigned char *buffer, int len) |
1958 | { | 1972 | { |
1973 | struct moxa_port *port = tty->driver_data; | ||
1959 | void __iomem *baseAddr, *ofsAddr, *ofs; | 1974 | void __iomem *baseAddr, *ofsAddr, *ofs; |
1960 | unsigned int c, total; | 1975 | unsigned int c, total; |
1961 | u16 head, tail, tx_mask, spage, epage; | 1976 | u16 head, tail, tx_mask, spage, epage; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index b638403e8e9c..8beef50f95a0 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -610,15 +610,13 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | |||
610 | return 0; | 610 | return 0; |
611 | } | 611 | } |
612 | 612 | ||
613 | static int mxser_set_baud(struct mxser_port *info, long newspd) | 613 | static int mxser_set_baud(struct tty_struct *tty, long newspd) |
614 | { | 614 | { |
615 | struct mxser_port *info = tty->driver_data; | ||
615 | int quot = 0, baud; | 616 | int quot = 0, baud; |
616 | unsigned char cval; | 617 | unsigned char cval; |
617 | 618 | ||
618 | if (!info->port.tty || !info->port.tty->termios) | 619 | if (!info->ioaddr) |
619 | return -1; | ||
620 | |||
621 | if (!(info->ioaddr)) | ||
622 | return -1; | 620 | return -1; |
623 | 621 | ||
624 | if (newspd > info->max_baud) | 622 | if (newspd > info->max_baud) |
@@ -626,13 +624,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
626 | 624 | ||
627 | if (newspd == 134) { | 625 | if (newspd == 134) { |
628 | quot = 2 * info->baud_base / 269; | 626 | quot = 2 * info->baud_base / 269; |
629 | tty_encode_baud_rate(info->port.tty, 134, 134); | 627 | tty_encode_baud_rate(tty, 134, 134); |
630 | } else if (newspd) { | 628 | } else if (newspd) { |
631 | quot = info->baud_base / newspd; | 629 | quot = info->baud_base / newspd; |
632 | if (quot == 0) | 630 | if (quot == 0) |
633 | quot = 1; | 631 | quot = 1; |
634 | baud = info->baud_base/quot; | 632 | baud = info->baud_base/quot; |
635 | tty_encode_baud_rate(info->port.tty, baud, baud); | 633 | tty_encode_baud_rate(tty, baud, baud); |
636 | } else { | 634 | } else { |
637 | quot = 0; | 635 | quot = 0; |
638 | } | 636 | } |
@@ -658,7 +656,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
658 | outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ | 656 | outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ |
659 | 657 | ||
660 | #ifdef BOTHER | 658 | #ifdef BOTHER |
661 | if (C_BAUD(info->port.tty) == BOTHER) { | 659 | if (C_BAUD(tty) == BOTHER) { |
662 | quot = info->baud_base % newspd; | 660 | quot = info->baud_base % newspd; |
663 | quot *= 8; | 661 | quot *= 8; |
664 | if (quot % newspd > newspd / 2) { | 662 | if (quot % newspd > newspd / 2) { |
@@ -679,21 +677,20 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
679 | * This routine is called to set the UART divisor registers to match | 677 | * This routine is called to set the UART divisor registers to match |
680 | * the specified baud rate for a serial port. | 678 | * the specified baud rate for a serial port. |
681 | */ | 679 | */ |
682 | static int mxser_change_speed(struct mxser_port *info, | 680 | static int mxser_change_speed(struct tty_struct *tty, |
683 | struct ktermios *old_termios) | 681 | struct ktermios *old_termios) |
684 | { | 682 | { |
683 | struct mxser_port *info = tty->driver_data; | ||
685 | unsigned cflag, cval, fcr; | 684 | unsigned cflag, cval, fcr; |
686 | int ret = 0; | 685 | int ret = 0; |
687 | unsigned char status; | 686 | unsigned char status; |
688 | 687 | ||
689 | if (!info->port.tty || !info->port.tty->termios) | 688 | cflag = tty->termios->c_cflag; |
690 | return ret; | 689 | if (!info->ioaddr) |
691 | cflag = info->port.tty->termios->c_cflag; | ||
692 | if (!(info->ioaddr)) | ||
693 | return ret; | 690 | return ret; |
694 | 691 | ||
695 | if (mxser_set_baud_method[info->port.tty->index] == 0) | 692 | if (mxser_set_baud_method[tty->index] == 0) |
696 | mxser_set_baud(info, tty_get_baud_rate(info->port.tty)); | 693 | mxser_set_baud(tty, tty_get_baud_rate(tty)); |
697 | 694 | ||
698 | /* byte size and parity */ | 695 | /* byte size and parity */ |
699 | switch (cflag & CSIZE) { | 696 | switch (cflag & CSIZE) { |
@@ -762,9 +759,9 @@ static int mxser_change_speed(struct mxser_port *info, | |||
762 | info->MCR |= UART_MCR_AFE; | 759 | info->MCR |= UART_MCR_AFE; |
763 | } else { | 760 | } else { |
764 | status = inb(info->ioaddr + UART_MSR); | 761 | status = inb(info->ioaddr + UART_MSR); |
765 | if (info->port.tty->hw_stopped) { | 762 | if (tty->hw_stopped) { |
766 | if (status & UART_MSR_CTS) { | 763 | if (status & UART_MSR_CTS) { |
767 | info->port.tty->hw_stopped = 0; | 764 | tty->hw_stopped = 0; |
768 | if (info->type != PORT_16550A && | 765 | if (info->type != PORT_16550A && |
769 | !info->board->chip_flag) { | 766 | !info->board->chip_flag) { |
770 | outb(info->IER & ~UART_IER_THRI, | 767 | outb(info->IER & ~UART_IER_THRI, |
@@ -774,11 +771,11 @@ static int mxser_change_speed(struct mxser_port *info, | |||
774 | outb(info->IER, info->ioaddr + | 771 | outb(info->IER, info->ioaddr + |
775 | UART_IER); | 772 | UART_IER); |
776 | } | 773 | } |
777 | tty_wakeup(info->port.tty); | 774 | tty_wakeup(tty); |
778 | } | 775 | } |
779 | } else { | 776 | } else { |
780 | if (!(status & UART_MSR_CTS)) { | 777 | if (!(status & UART_MSR_CTS)) { |
781 | info->port.tty->hw_stopped = 1; | 778 | tty->hw_stopped = 1; |
782 | if ((info->type != PORT_16550A) && | 779 | if ((info->type != PORT_16550A) && |
783 | (!info->board->chip_flag)) { | 780 | (!info->board->chip_flag)) { |
784 | info->IER &= ~UART_IER_THRI; | 781 | info->IER &= ~UART_IER_THRI; |
@@ -804,21 +801,21 @@ static int mxser_change_speed(struct mxser_port *info, | |||
804 | * Set up parity check flag | 801 | * Set up parity check flag |
805 | */ | 802 | */ |
806 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | 803 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; |
807 | if (I_INPCK(info->port.tty)) | 804 | if (I_INPCK(tty)) |
808 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | 805 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; |
809 | if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) | 806 | if (I_BRKINT(tty) || I_PARMRK(tty)) |
810 | info->read_status_mask |= UART_LSR_BI; | 807 | info->read_status_mask |= UART_LSR_BI; |
811 | 808 | ||
812 | info->ignore_status_mask = 0; | 809 | info->ignore_status_mask = 0; |
813 | 810 | ||
814 | if (I_IGNBRK(info->port.tty)) { | 811 | if (I_IGNBRK(tty)) { |
815 | info->ignore_status_mask |= UART_LSR_BI; | 812 | info->ignore_status_mask |= UART_LSR_BI; |
816 | info->read_status_mask |= UART_LSR_BI; | 813 | info->read_status_mask |= UART_LSR_BI; |
817 | /* | 814 | /* |
818 | * If we're ignore parity and break indicators, ignore | 815 | * If we're ignore parity and break indicators, ignore |
819 | * overruns too. (For real raw support). | 816 | * overruns too. (For real raw support). |
820 | */ | 817 | */ |
821 | if (I_IGNPAR(info->port.tty)) { | 818 | if (I_IGNPAR(tty)) { |
822 | info->ignore_status_mask |= | 819 | info->ignore_status_mask |= |
823 | UART_LSR_OE | | 820 | UART_LSR_OE | |
824 | UART_LSR_PE | | 821 | UART_LSR_PE | |
@@ -830,16 +827,16 @@ static int mxser_change_speed(struct mxser_port *info, | |||
830 | } | 827 | } |
831 | } | 828 | } |
832 | if (info->board->chip_flag) { | 829 | if (info->board->chip_flag) { |
833 | mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty)); | 830 | mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty)); |
834 | mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty)); | 831 | mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty)); |
835 | if (I_IXON(info->port.tty)) { | 832 | if (I_IXON(tty)) { |
836 | mxser_enable_must_rx_software_flow_control( | 833 | mxser_enable_must_rx_software_flow_control( |
837 | info->ioaddr); | 834 | info->ioaddr); |
838 | } else { | 835 | } else { |
839 | mxser_disable_must_rx_software_flow_control( | 836 | mxser_disable_must_rx_software_flow_control( |
840 | info->ioaddr); | 837 | info->ioaddr); |
841 | } | 838 | } |
842 | if (I_IXOFF(info->port.tty)) { | 839 | if (I_IXOFF(tty)) { |
843 | mxser_enable_must_tx_software_flow_control( | 840 | mxser_enable_must_tx_software_flow_control( |
844 | info->ioaddr); | 841 | info->ioaddr); |
845 | } else { | 842 | } else { |
@@ -855,7 +852,8 @@ static int mxser_change_speed(struct mxser_port *info, | |||
855 | return ret; | 852 | return ret; |
856 | } | 853 | } |
857 | 854 | ||
858 | static void mxser_check_modem_status(struct mxser_port *port, int status) | 855 | static void mxser_check_modem_status(struct tty_struct *tty, |
856 | struct mxser_port *port, int status) | ||
859 | { | 857 | { |
860 | /* update input line counters */ | 858 | /* update input line counters */ |
861 | if (status & UART_MSR_TERI) | 859 | if (status & UART_MSR_TERI) |
@@ -874,10 +872,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
874 | wake_up_interruptible(&port->port.open_wait); | 872 | wake_up_interruptible(&port->port.open_wait); |
875 | } | 873 | } |
876 | 874 | ||
875 | tty = tty_port_tty_get(&port->port); | ||
877 | if (port->port.flags & ASYNC_CTS_FLOW) { | 876 | if (port->port.flags & ASYNC_CTS_FLOW) { |
878 | if (port->port.tty->hw_stopped) { | 877 | if (tty->hw_stopped) { |
879 | if (status & UART_MSR_CTS) { | 878 | if (status & UART_MSR_CTS) { |
880 | port->port.tty->hw_stopped = 0; | 879 | tty->hw_stopped = 0; |
881 | 880 | ||
882 | if ((port->type != PORT_16550A) && | 881 | if ((port->type != PORT_16550A) && |
883 | (!port->board->chip_flag)) { | 882 | (!port->board->chip_flag)) { |
@@ -887,11 +886,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
887 | outb(port->IER, port->ioaddr + | 886 | outb(port->IER, port->ioaddr + |
888 | UART_IER); | 887 | UART_IER); |
889 | } | 888 | } |
890 | tty_wakeup(port->port.tty); | 889 | tty_wakeup(tty); |
891 | } | 890 | } |
892 | } else { | 891 | } else { |
893 | if (!(status & UART_MSR_CTS)) { | 892 | if (!(status & UART_MSR_CTS)) { |
894 | port->port.tty->hw_stopped = 1; | 893 | tty->hw_stopped = 1; |
895 | if (port->type != PORT_16550A && | 894 | if (port->type != PORT_16550A && |
896 | !port->board->chip_flag) { | 895 | !port->board->chip_flag) { |
897 | port->IER &= ~UART_IER_THRI; | 896 | port->IER &= ~UART_IER_THRI; |
@@ -903,8 +902,9 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
903 | } | 902 | } |
904 | } | 903 | } |
905 | 904 | ||
906 | static int mxser_startup(struct mxser_port *info) | 905 | static int mxser_startup(struct tty_struct *tty) |
907 | { | 906 | { |
907 | struct mxser_port *info = tty->driver_data; | ||
908 | unsigned long page; | 908 | unsigned long page; |
909 | unsigned long flags; | 909 | unsigned long flags; |
910 | 910 | ||
@@ -921,8 +921,7 @@ static int mxser_startup(struct mxser_port *info) | |||
921 | } | 921 | } |
922 | 922 | ||
923 | if (!info->ioaddr || !info->type) { | 923 | if (!info->ioaddr || !info->type) { |
924 | if (info->port.tty) | 924 | set_bit(TTY_IO_ERROR, &tty->flags); |
925 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
926 | free_page(page); | 925 | free_page(page); |
927 | spin_unlock_irqrestore(&info->slock, flags); | 926 | spin_unlock_irqrestore(&info->slock, flags); |
928 | return 0; | 927 | return 0; |
@@ -952,8 +951,8 @@ static int mxser_startup(struct mxser_port *info) | |||
952 | if (inb(info->ioaddr + UART_LSR) == 0xff) { | 951 | if (inb(info->ioaddr + UART_LSR) == 0xff) { |
953 | spin_unlock_irqrestore(&info->slock, flags); | 952 | spin_unlock_irqrestore(&info->slock, flags); |
954 | if (capable(CAP_SYS_ADMIN)) { | 953 | if (capable(CAP_SYS_ADMIN)) { |
955 | if (info->port.tty) | 954 | if (tty) |
956 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 955 | set_bit(TTY_IO_ERROR, &tty->flags); |
957 | return 0; | 956 | return 0; |
958 | } else | 957 | } else |
959 | return -ENODEV; | 958 | return -ENODEV; |
@@ -991,14 +990,13 @@ static int mxser_startup(struct mxser_port *info) | |||
991 | (void) inb(info->ioaddr + UART_IIR); | 990 | (void) inb(info->ioaddr + UART_IIR); |
992 | (void) inb(info->ioaddr + UART_MSR); | 991 | (void) inb(info->ioaddr + UART_MSR); |
993 | 992 | ||
994 | if (info->port.tty) | 993 | clear_bit(TTY_IO_ERROR, &tty->flags); |
995 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
996 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 994 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
997 | 995 | ||
998 | /* | 996 | /* |
999 | * and set the speed of the serial port | 997 | * and set the speed of the serial port |
1000 | */ | 998 | */ |
1001 | mxser_change_speed(info, NULL); | 999 | mxser_change_speed(tty, NULL); |
1002 | info->port.flags |= ASYNC_INITIALIZED; | 1000 | info->port.flags |= ASYNC_INITIALIZED; |
1003 | spin_unlock_irqrestore(&info->slock, flags); | 1001 | spin_unlock_irqrestore(&info->slock, flags); |
1004 | 1002 | ||
@@ -1009,8 +1007,9 @@ static int mxser_startup(struct mxser_port *info) | |||
1009 | * This routine will shutdown a serial port; interrupts maybe disabled, and | 1007 | * This routine will shutdown a serial port; interrupts maybe disabled, and |
1010 | * DTR is dropped if the hangup on close termio flag is on. | 1008 | * DTR is dropped if the hangup on close termio flag is on. |
1011 | */ | 1009 | */ |
1012 | static void mxser_shutdown(struct mxser_port *info) | 1010 | static void mxser_shutdown(struct tty_struct *tty) |
1013 | { | 1011 | { |
1012 | struct mxser_port *info = tty->driver_data; | ||
1014 | unsigned long flags; | 1013 | unsigned long flags; |
1015 | 1014 | ||
1016 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 1015 | if (!(info->port.flags & ASYNC_INITIALIZED)) |
@@ -1035,7 +1034,7 @@ static void mxser_shutdown(struct mxser_port *info) | |||
1035 | info->IER = 0; | 1034 | info->IER = 0; |
1036 | outb(0x00, info->ioaddr + UART_IER); | 1035 | outb(0x00, info->ioaddr + UART_IER); |
1037 | 1036 | ||
1038 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) | 1037 | if (tty->termios->c_cflag & HUPCL) |
1039 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); | 1038 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); |
1040 | outb(info->MCR, info->ioaddr + UART_MCR); | 1039 | outb(info->MCR, info->ioaddr + UART_MCR); |
1041 | 1040 | ||
@@ -1051,8 +1050,7 @@ static void mxser_shutdown(struct mxser_port *info) | |||
1051 | /* read data port to reset things */ | 1050 | /* read data port to reset things */ |
1052 | (void) inb(info->ioaddr + UART_RX); | 1051 | (void) inb(info->ioaddr + UART_RX); |
1053 | 1052 | ||
1054 | if (info->port.tty) | 1053 | set_bit(TTY_IO_ERROR, &tty->flags); |
1055 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
1056 | 1054 | ||
1057 | info->port.flags &= ~ASYNC_INITIALIZED; | 1055 | info->port.flags &= ~ASYNC_INITIALIZED; |
1058 | 1056 | ||
@@ -1084,14 +1082,14 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
1084 | return -ENODEV; | 1082 | return -ENODEV; |
1085 | 1083 | ||
1086 | tty->driver_data = info; | 1084 | tty->driver_data = info; |
1087 | info->port.tty = tty; | 1085 | tty_port_tty_set(&info->port, tty); |
1088 | /* | 1086 | /* |
1089 | * Start up serial port | 1087 | * Start up serial port |
1090 | */ | 1088 | */ |
1091 | spin_lock_irqsave(&info->slock, flags); | 1089 | spin_lock_irqsave(&info->slock, flags); |
1092 | info->port.count++; | 1090 | info->port.count++; |
1093 | spin_unlock_irqrestore(&info->slock, flags); | 1091 | spin_unlock_irqrestore(&info->slock, flags); |
1094 | retval = mxser_startup(info); | 1092 | retval = mxser_startup(tty); |
1095 | if (retval) | 1093 | if (retval) |
1096 | return retval; | 1094 | return retval; |
1097 | 1095 | ||
@@ -1209,13 +1207,13 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1209 | break; | 1207 | break; |
1210 | } | 1208 | } |
1211 | } | 1209 | } |
1212 | mxser_shutdown(info); | 1210 | mxser_shutdown(tty); |
1213 | 1211 | ||
1214 | mxser_flush_buffer(tty); | 1212 | mxser_flush_buffer(tty); |
1215 | tty_ldisc_flush(tty); | 1213 | tty_ldisc_flush(tty); |
1216 | 1214 | ||
1217 | tty->closing = 0; | 1215 | tty->closing = 0; |
1218 | info->port.tty = NULL; | 1216 | tty_port_tty_set(&info->port, NULL); |
1219 | if (info->port.blocked_open) { | 1217 | if (info->port.blocked_open) { |
1220 | if (info->port.close_delay) | 1218 | if (info->port.close_delay) |
1221 | schedule_timeout_interruptible(info->port.close_delay); | 1219 | schedule_timeout_interruptible(info->port.close_delay); |
@@ -1337,12 +1335,13 @@ static int mxser_chars_in_buffer(struct tty_struct *tty) | |||
1337 | * friends of mxser_ioctl() | 1335 | * friends of mxser_ioctl() |
1338 | * ------------------------------------------------------------ | 1336 | * ------------------------------------------------------------ |
1339 | */ | 1337 | */ |
1340 | static int mxser_get_serial_info(struct mxser_port *info, | 1338 | static int mxser_get_serial_info(struct tty_struct *tty, |
1341 | struct serial_struct __user *retinfo) | 1339 | struct serial_struct __user *retinfo) |
1342 | { | 1340 | { |
1341 | struct mxser_port *info = tty->driver_data; | ||
1343 | struct serial_struct tmp = { | 1342 | struct serial_struct tmp = { |
1344 | .type = info->type, | 1343 | .type = info->type, |
1345 | .line = info->port.tty->index, | 1344 | .line = tty->index, |
1346 | .port = info->ioaddr, | 1345 | .port = info->ioaddr, |
1347 | .irq = info->board->irq, | 1346 | .irq = info->board->irq, |
1348 | .flags = info->port.flags, | 1347 | .flags = info->port.flags, |
@@ -1357,9 +1356,10 @@ static int mxser_get_serial_info(struct mxser_port *info, | |||
1357 | return 0; | 1356 | return 0; |
1358 | } | 1357 | } |
1359 | 1358 | ||
1360 | static int mxser_set_serial_info(struct mxser_port *info, | 1359 | static int mxser_set_serial_info(struct tty_struct *tty, |
1361 | struct serial_struct __user *new_info) | 1360 | struct serial_struct __user *new_info) |
1362 | { | 1361 | { |
1362 | struct mxser_port *info = tty->driver_data; | ||
1363 | struct serial_struct new_serial; | 1363 | struct serial_struct new_serial; |
1364 | speed_t baud; | 1364 | speed_t baud; |
1365 | unsigned long sl_flags; | 1365 | unsigned long sl_flags; |
@@ -1393,14 +1393,14 @@ static int mxser_set_serial_info(struct mxser_port *info, | |||
1393 | (new_serial.flags & ASYNC_FLAGS)); | 1393 | (new_serial.flags & ASYNC_FLAGS)); |
1394 | info->port.close_delay = new_serial.close_delay * HZ / 100; | 1394 | info->port.close_delay = new_serial.close_delay * HZ / 100; |
1395 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; | 1395 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; |
1396 | info->port.tty->low_latency = | 1396 | tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) |
1397 | (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1397 | ? 1 : 0; |
1398 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && | 1398 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && |
1399 | (new_serial.baud_base != info->baud_base || | 1399 | (new_serial.baud_base != info->baud_base || |
1400 | new_serial.custom_divisor != | 1400 | new_serial.custom_divisor != |
1401 | info->custom_divisor)) { | 1401 | info->custom_divisor)) { |
1402 | baud = new_serial.baud_base / new_serial.custom_divisor; | 1402 | baud = new_serial.baud_base / new_serial.custom_divisor; |
1403 | tty_encode_baud_rate(info->port.tty, baud, baud); | 1403 | tty_encode_baud_rate(tty, baud, baud); |
1404 | } | 1404 | } |
1405 | } | 1405 | } |
1406 | 1406 | ||
@@ -1411,11 +1411,11 @@ static int mxser_set_serial_info(struct mxser_port *info, | |||
1411 | if (info->port.flags & ASYNC_INITIALIZED) { | 1411 | if (info->port.flags & ASYNC_INITIALIZED) { |
1412 | if (flags != (info->port.flags & ASYNC_SPD_MASK)) { | 1412 | if (flags != (info->port.flags & ASYNC_SPD_MASK)) { |
1413 | spin_lock_irqsave(&info->slock, sl_flags); | 1413 | spin_lock_irqsave(&info->slock, sl_flags); |
1414 | mxser_change_speed(info, NULL); | 1414 | mxser_change_speed(tty, NULL); |
1415 | spin_unlock_irqrestore(&info->slock, sl_flags); | 1415 | spin_unlock_irqrestore(&info->slock, sl_flags); |
1416 | } | 1416 | } |
1417 | } else | 1417 | } else |
1418 | retval = mxser_startup(info); | 1418 | retval = mxser_startup(tty); |
1419 | 1419 | ||
1420 | return retval; | 1420 | return retval; |
1421 | } | 1421 | } |
@@ -1461,7 +1461,7 @@ static int mxser_tiocmget(struct tty_struct *tty, struct file *file) | |||
1461 | spin_lock_irqsave(&info->slock, flags); | 1461 | spin_lock_irqsave(&info->slock, flags); |
1462 | status = inb(info->ioaddr + UART_MSR); | 1462 | status = inb(info->ioaddr + UART_MSR); |
1463 | if (status & UART_MSR_ANY_DELTA) | 1463 | if (status & UART_MSR_ANY_DELTA) |
1464 | mxser_check_modem_status(info, status); | 1464 | mxser_check_modem_status(tty, info, status); |
1465 | spin_unlock_irqrestore(&info->slock, flags); | 1465 | spin_unlock_irqrestore(&info->slock, flags); |
1466 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | | 1466 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | |
1467 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | | 1467 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | |
@@ -1606,6 +1606,7 @@ static int __init mxser_read_register(int port, unsigned short *regs) | |||
1606 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | 1606 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) |
1607 | { | 1607 | { |
1608 | struct mxser_port *port; | 1608 | struct mxser_port *port; |
1609 | struct tty_struct *tty; | ||
1609 | int result, status; | 1610 | int result, status; |
1610 | unsigned int i, j; | 1611 | unsigned int i, j; |
1611 | int ret = 0; | 1612 | int ret = 0; |
@@ -1643,12 +1644,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1643 | 1644 | ||
1644 | if (!port->ioaddr) | 1645 | if (!port->ioaddr) |
1645 | goto copy; | 1646 | goto copy; |
1647 | |||
1648 | tty = tty_port_tty_get(&port->port); | ||
1646 | 1649 | ||
1647 | if (!port->port.tty || !port->port.tty->termios) | 1650 | if (!tty || !tty->termios) |
1648 | ms.cflag = port->normal_termios.c_cflag; | 1651 | ms.cflag = port->normal_termios.c_cflag; |
1649 | else | 1652 | else |
1650 | ms.cflag = port->port.tty->termios->c_cflag; | 1653 | ms.cflag = tty->termios->c_cflag; |
1651 | 1654 | tty_kref_put(tty); | |
1652 | status = inb(port->ioaddr + UART_MSR); | 1655 | status = inb(port->ioaddr + UART_MSR); |
1653 | if (status & UART_MSR_DCD) | 1656 | if (status & UART_MSR_DCD) |
1654 | ms.dcd = 1; | 1657 | ms.dcd = 1; |
@@ -1704,15 +1707,18 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1704 | me->up_txcnt[p] = port->mon_data.up_txcnt; | 1707 | me->up_txcnt[p] = port->mon_data.up_txcnt; |
1705 | me->modem_status[p] = | 1708 | me->modem_status[p] = |
1706 | port->mon_data.modem_status; | 1709 | port->mon_data.modem_status; |
1707 | me->baudrate[p] = tty_get_baud_rate(port->port.tty); | 1710 | tty = tty_port_tty_get(&port->port); |
1708 | 1711 | ||
1709 | if (!port->port.tty || !port->port.tty->termios) { | 1712 | if (!tty || !tty->termios) { |
1710 | cflag = port->normal_termios.c_cflag; | 1713 | cflag = port->normal_termios.c_cflag; |
1711 | iflag = port->normal_termios.c_iflag; | 1714 | iflag = port->normal_termios.c_iflag; |
1715 | me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios); | ||
1712 | } else { | 1716 | } else { |
1713 | cflag = port->port.tty->termios->c_cflag; | 1717 | cflag = tty->termios->c_cflag; |
1714 | iflag = port->port.tty->termios->c_iflag; | 1718 | iflag = tty->termios->c_iflag; |
1719 | me->baudrate[p] = tty_get_baud_rate(tty); | ||
1715 | } | 1720 | } |
1721 | tty_kref_put(tty); | ||
1716 | 1722 | ||
1717 | me->databits[p] = cflag & CSIZE; | 1723 | me->databits[p] = cflag & CSIZE; |
1718 | me->stopbits[p] = cflag & CSTOPB; | 1724 | me->stopbits[p] = cflag & CSTOPB; |
@@ -1822,12 +1828,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1822 | switch (cmd) { | 1828 | switch (cmd) { |
1823 | case TIOCGSERIAL: | 1829 | case TIOCGSERIAL: |
1824 | lock_kernel(); | 1830 | lock_kernel(); |
1825 | retval = mxser_get_serial_info(info, argp); | 1831 | retval = mxser_get_serial_info(tty, argp); |
1826 | unlock_kernel(); | 1832 | unlock_kernel(); |
1827 | return retval; | 1833 | return retval; |
1828 | case TIOCSSERIAL: | 1834 | case TIOCSSERIAL: |
1829 | lock_kernel(); | 1835 | lock_kernel(); |
1830 | retval = mxser_set_serial_info(info, argp); | 1836 | retval = mxser_set_serial_info(tty, argp); |
1831 | unlock_kernel(); | 1837 | unlock_kernel(); |
1832 | return retval; | 1838 | return retval; |
1833 | case TIOCSERGETLSR: /* Get line status register */ | 1839 | case TIOCSERGETLSR: /* Get line status register */ |
@@ -1896,7 +1902,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1896 | 1902 | ||
1897 | lock_kernel(); | 1903 | lock_kernel(); |
1898 | status = mxser_get_msr(info->ioaddr, 1, tty->index); | 1904 | status = mxser_get_msr(info->ioaddr, 1, tty->index); |
1899 | mxser_check_modem_status(info, status); | 1905 | mxser_check_modem_status(tty, info, status); |
1900 | 1906 | ||
1901 | mcr = inb(info->ioaddr + UART_MCR); | 1907 | mcr = inb(info->ioaddr + UART_MCR); |
1902 | if (mcr & MOXA_MUST_MCR_XON_FLAG) | 1908 | if (mcr & MOXA_MUST_MCR_XON_FLAG) |
@@ -1909,7 +1915,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1909 | else | 1915 | else |
1910 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; | 1916 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; |
1911 | 1917 | ||
1912 | if (info->port.tty->hw_stopped) | 1918 | if (tty->hw_stopped) |
1913 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; | 1919 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; |
1914 | else | 1920 | else |
1915 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; | 1921 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; |
@@ -1958,7 +1964,7 @@ static void mxser_stoprx(struct tty_struct *tty) | |||
1958 | } | 1964 | } |
1959 | } | 1965 | } |
1960 | 1966 | ||
1961 | if (info->port.tty->termios->c_cflag & CRTSCTS) { | 1967 | if (tty->termios->c_cflag & CRTSCTS) { |
1962 | info->MCR &= ~UART_MCR_RTS; | 1968 | info->MCR &= ~UART_MCR_RTS; |
1963 | outb(info->MCR, info->ioaddr + UART_MCR); | 1969 | outb(info->MCR, info->ioaddr + UART_MCR); |
1964 | } | 1970 | } |
@@ -1995,7 +2001,7 @@ static void mxser_unthrottle(struct tty_struct *tty) | |||
1995 | } | 2001 | } |
1996 | } | 2002 | } |
1997 | 2003 | ||
1998 | if (info->port.tty->termios->c_cflag & CRTSCTS) { | 2004 | if (tty->termios->c_cflag & CRTSCTS) { |
1999 | info->MCR |= UART_MCR_RTS; | 2005 | info->MCR |= UART_MCR_RTS; |
2000 | outb(info->MCR, info->ioaddr + UART_MCR); | 2006 | outb(info->MCR, info->ioaddr + UART_MCR); |
2001 | } | 2007 | } |
@@ -2040,7 +2046,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi | |||
2040 | unsigned long flags; | 2046 | unsigned long flags; |
2041 | 2047 | ||
2042 | spin_lock_irqsave(&info->slock, flags); | 2048 | spin_lock_irqsave(&info->slock, flags); |
2043 | mxser_change_speed(info, old_termios); | 2049 | mxser_change_speed(tty, old_termios); |
2044 | spin_unlock_irqrestore(&info->slock, flags); | 2050 | spin_unlock_irqrestore(&info->slock, flags); |
2045 | 2051 | ||
2046 | if ((old_termios->c_cflag & CRTSCTS) && | 2052 | if ((old_termios->c_cflag & CRTSCTS) && |
@@ -2138,10 +2144,10 @@ static void mxser_hangup(struct tty_struct *tty) | |||
2138 | struct mxser_port *info = tty->driver_data; | 2144 | struct mxser_port *info = tty->driver_data; |
2139 | 2145 | ||
2140 | mxser_flush_buffer(tty); | 2146 | mxser_flush_buffer(tty); |
2141 | mxser_shutdown(info); | 2147 | mxser_shutdown(tty); |
2142 | info->port.count = 0; | 2148 | info->port.count = 0; |
2143 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 2149 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
2144 | info->port.tty = NULL; | 2150 | tty_port_tty_set(&info->port, NULL); |
2145 | wake_up_interruptible(&info->port.open_wait); | 2151 | wake_up_interruptible(&info->port.open_wait); |
2146 | } | 2152 | } |
2147 | 2153 | ||
@@ -2164,9 +2170,9 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) | |||
2164 | return 0; | 2170 | return 0; |
2165 | } | 2171 | } |
2166 | 2172 | ||
2167 | static void mxser_receive_chars(struct mxser_port *port, int *status) | 2173 | static void mxser_receive_chars(struct tty_struct *tty, |
2174 | struct mxser_port *port, int *status) | ||
2168 | { | 2175 | { |
2169 | struct tty_struct *tty = port->port.tty; | ||
2170 | unsigned char ch, gdl; | 2176 | unsigned char ch, gdl; |
2171 | int ignored = 0; | 2177 | int ignored = 0; |
2172 | int cnt = 0; | 2178 | int cnt = 0; |
@@ -2174,9 +2180,8 @@ static void mxser_receive_chars(struct mxser_port *port, int *status) | |||
2174 | int max = 256; | 2180 | int max = 256; |
2175 | 2181 | ||
2176 | recv_room = tty->receive_room; | 2182 | recv_room = tty->receive_room; |
2177 | if ((recv_room == 0) && (!port->ldisc_stop_rx)) | 2183 | if (recv_room == 0 && !port->ldisc_stop_rx) |
2178 | mxser_stoprx(tty); | 2184 | mxser_stoprx(tty); |
2179 | |||
2180 | if (port->board->chip_flag != MOXA_OTHER_UART) { | 2185 | if (port->board->chip_flag != MOXA_OTHER_UART) { |
2181 | 2186 | ||
2182 | if (*status & UART_LSR_SPECIAL) | 2187 | if (*status & UART_LSR_SPECIAL) |
@@ -2253,7 +2258,7 @@ intr_old: | |||
2253 | } while (*status & UART_LSR_DR); | 2258 | } while (*status & UART_LSR_DR); |
2254 | 2259 | ||
2255 | end_intr: | 2260 | end_intr: |
2256 | mxvar_log.rxcnt[port->port.tty->index] += cnt; | 2261 | mxvar_log.rxcnt[tty->index] += cnt; |
2257 | port->mon_data.rxcnt += cnt; | 2262 | port->mon_data.rxcnt += cnt; |
2258 | port->mon_data.up_rxcnt += cnt; | 2263 | port->mon_data.up_rxcnt += cnt; |
2259 | 2264 | ||
@@ -2267,14 +2272,14 @@ end_intr: | |||
2267 | spin_lock(&port->slock); | 2272 | spin_lock(&port->slock); |
2268 | } | 2273 | } |
2269 | 2274 | ||
2270 | static void mxser_transmit_chars(struct mxser_port *port) | 2275 | static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port) |
2271 | { | 2276 | { |
2272 | int count, cnt; | 2277 | int count, cnt; |
2273 | 2278 | ||
2274 | if (port->x_char) { | 2279 | if (port->x_char) { |
2275 | outb(port->x_char, port->ioaddr + UART_TX); | 2280 | outb(port->x_char, port->ioaddr + UART_TX); |
2276 | port->x_char = 0; | 2281 | port->x_char = 0; |
2277 | mxvar_log.txcnt[port->port.tty->index]++; | 2282 | mxvar_log.txcnt[tty->index]++; |
2278 | port->mon_data.txcnt++; | 2283 | port->mon_data.txcnt++; |
2279 | port->mon_data.up_txcnt++; | 2284 | port->mon_data.up_txcnt++; |
2280 | port->icount.tx++; | 2285 | port->icount.tx++; |
@@ -2284,8 +2289,8 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2284 | if (port->port.xmit_buf == NULL) | 2289 | if (port->port.xmit_buf == NULL) |
2285 | return; | 2290 | return; |
2286 | 2291 | ||
2287 | if ((port->xmit_cnt <= 0) || port->port.tty->stopped || | 2292 | if (port->xmit_cnt <= 0 || tty->stopped || |
2288 | (port->port.tty->hw_stopped && | 2293 | (tty->hw_stopped && |
2289 | (port->type != PORT_16550A) && | 2294 | (port->type != PORT_16550A) && |
2290 | (!port->board->chip_flag))) { | 2295 | (!port->board->chip_flag))) { |
2291 | port->IER &= ~UART_IER_THRI; | 2296 | port->IER &= ~UART_IER_THRI; |
@@ -2302,14 +2307,14 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2302 | if (--port->xmit_cnt <= 0) | 2307 | if (--port->xmit_cnt <= 0) |
2303 | break; | 2308 | break; |
2304 | } while (--count > 0); | 2309 | } while (--count > 0); |
2305 | mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt); | 2310 | mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt); |
2306 | 2311 | ||
2307 | port->mon_data.txcnt += (cnt - port->xmit_cnt); | 2312 | port->mon_data.txcnt += (cnt - port->xmit_cnt); |
2308 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); | 2313 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); |
2309 | port->icount.tx += (cnt - port->xmit_cnt); | 2314 | port->icount.tx += (cnt - port->xmit_cnt); |
2310 | 2315 | ||
2311 | if (port->xmit_cnt < WAKEUP_CHARS) | 2316 | if (port->xmit_cnt < WAKEUP_CHARS && tty) |
2312 | tty_wakeup(port->port.tty); | 2317 | tty_wakeup(tty); |
2313 | 2318 | ||
2314 | if (port->xmit_cnt <= 0) { | 2319 | if (port->xmit_cnt <= 0) { |
2315 | port->IER &= ~UART_IER_THRI; | 2320 | port->IER &= ~UART_IER_THRI; |
@@ -2328,6 +2333,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2328 | int max, irqbits, bits, msr; | 2333 | int max, irqbits, bits, msr; |
2329 | unsigned int int_cnt, pass_counter = 0; | 2334 | unsigned int int_cnt, pass_counter = 0; |
2330 | int handled = IRQ_NONE; | 2335 | int handled = IRQ_NONE; |
2336 | struct tty_struct *tty; | ||
2331 | 2337 | ||
2332 | for (i = 0; i < MXSER_BOARDS; i++) | 2338 | for (i = 0; i < MXSER_BOARDS; i++) |
2333 | if (dev_id == &mxser_boards[i]) { | 2339 | if (dev_id == &mxser_boards[i]) { |
@@ -2360,13 +2366,15 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2360 | if (iir & UART_IIR_NO_INT) | 2366 | if (iir & UART_IIR_NO_INT) |
2361 | break; | 2367 | break; |
2362 | iir &= MOXA_MUST_IIR_MASK; | 2368 | iir &= MOXA_MUST_IIR_MASK; |
2363 | if (!port->port.tty || | 2369 | tty = tty_port_tty_get(&port->port); |
2370 | if (!tty || | ||
2364 | (port->port.flags & ASYNC_CLOSING) || | 2371 | (port->port.flags & ASYNC_CLOSING) || |
2365 | !(port->port.flags & | 2372 | !(port->port.flags & |
2366 | ASYNC_INITIALIZED)) { | 2373 | ASYNC_INITIALIZED)) { |
2367 | status = inb(port->ioaddr + UART_LSR); | 2374 | status = inb(port->ioaddr + UART_LSR); |
2368 | outb(0x27, port->ioaddr + UART_FCR); | 2375 | outb(0x27, port->ioaddr + UART_FCR); |
2369 | inb(port->ioaddr + UART_MSR); | 2376 | inb(port->ioaddr + UART_MSR); |
2377 | tty_kref_put(tty); | ||
2370 | break; | 2378 | break; |
2371 | } | 2379 | } |
2372 | 2380 | ||
@@ -2387,27 +2395,28 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2387 | iir == MOXA_MUST_IIR_RDA || | 2395 | iir == MOXA_MUST_IIR_RDA || |
2388 | iir == MOXA_MUST_IIR_RTO || | 2396 | iir == MOXA_MUST_IIR_RTO || |
2389 | iir == MOXA_MUST_IIR_LSR) | 2397 | iir == MOXA_MUST_IIR_LSR) |
2390 | mxser_receive_chars(port, | 2398 | mxser_receive_chars(tty, port, |
2391 | &status); | 2399 | &status); |
2392 | 2400 | ||
2393 | } else { | 2401 | } else { |
2394 | status &= port->read_status_mask; | 2402 | status &= port->read_status_mask; |
2395 | if (status & UART_LSR_DR) | 2403 | if (status & UART_LSR_DR) |
2396 | mxser_receive_chars(port, | 2404 | mxser_receive_chars(tty, port, |
2397 | &status); | 2405 | &status); |
2398 | } | 2406 | } |
2399 | msr = inb(port->ioaddr + UART_MSR); | 2407 | msr = inb(port->ioaddr + UART_MSR); |
2400 | if (msr & UART_MSR_ANY_DELTA) | 2408 | if (msr & UART_MSR_ANY_DELTA) |
2401 | mxser_check_modem_status(port, msr); | 2409 | mxser_check_modem_status(tty, port, msr); |
2402 | 2410 | ||
2403 | if (port->board->chip_flag) { | 2411 | if (port->board->chip_flag) { |
2404 | if (iir == 0x02 && (status & | 2412 | if (iir == 0x02 && (status & |
2405 | UART_LSR_THRE)) | 2413 | UART_LSR_THRE)) |
2406 | mxser_transmit_chars(port); | 2414 | mxser_transmit_chars(tty, port); |
2407 | } else { | 2415 | } else { |
2408 | if (status & UART_LSR_THRE) | 2416 | if (status & UART_LSR_THRE) |
2409 | mxser_transmit_chars(port); | 2417 | mxser_transmit_chars(tty, port); |
2410 | } | 2418 | } |
2419 | tty_kref_put(tty); | ||
2411 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); | 2420 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); |
2412 | spin_unlock(&port->slock); | 2421 | spin_unlock(&port->slock); |
2413 | } | 2422 | } |
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index 69ec6399c714..bacb3e2872ae 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -764,7 +764,7 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
764 | break; | 764 | break; |
765 | 765 | ||
766 | default: | 766 | default: |
767 | error = n_tty_ioctl (tty, file, cmd, arg); | 767 | error = n_tty_ioctl_helper(tty, file, cmd, arg); |
768 | break; | 768 | break; |
769 | } | 769 | } |
770 | return error; | 770 | return error; |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index ae377aa473ba..4a8215a89ad3 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -372,14 +372,8 @@ static void remove_from_rx_queue(struct r3964_info *pInfo, | |||
372 | static void put_char(struct r3964_info *pInfo, unsigned char ch) | 372 | static void put_char(struct r3964_info *pInfo, unsigned char ch) |
373 | { | 373 | { |
374 | struct tty_struct *tty = pInfo->tty; | 374 | struct tty_struct *tty = pInfo->tty; |
375 | |||
376 | if (tty == NULL) | ||
377 | return; | ||
378 | |||
379 | /* FIXME: put_char should not be called from an IRQ */ | 375 | /* FIXME: put_char should not be called from an IRQ */ |
380 | if (tty->ops->put_char) { | 376 | tty_put_char(tty, ch); |
381 | tty->ops->put_char(tty, ch); | ||
382 | } | ||
383 | pInfo->bcc ^= ch; | 377 | pInfo->bcc ^= ch; |
384 | } | 378 | } |
385 | 379 | ||
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 708c2b1dbe51..efbfe9612658 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * | 26 | * |
27 | * 2002/03/18 Implemented n_tty_wakeup to send SIGIO POLL_OUTs to | 27 | * 2002/03/18 Implemented n_tty_wakeup to send SIGIO POLL_OUTs to |
28 | * waiting writing processes-Sapan Bhatia <sapan@corewars.org>. | 28 | * waiting writing processes-Sapan Bhatia <sapan@corewars.org>. |
29 | * Also fixed a bug in BLOCKING mode where write_chan returns | 29 | * Also fixed a bug in BLOCKING mode where n_tty_write returns |
30 | * EAGAIN | 30 | * EAGAIN |
31 | */ | 31 | */ |
32 | 32 | ||
@@ -99,6 +99,7 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
99 | 99 | ||
100 | static void n_tty_set_room(struct tty_struct *tty) | 100 | static void n_tty_set_room(struct tty_struct *tty) |
101 | { | 101 | { |
102 | /* tty->read_cnt is not read locked ? */ | ||
102 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | 103 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; |
103 | 104 | ||
104 | /* | 105 | /* |
@@ -121,6 +122,16 @@ static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | |||
121 | } | 122 | } |
122 | } | 123 | } |
123 | 124 | ||
125 | /** | ||
126 | * put_tty_queue - add character to tty | ||
127 | * @c: character | ||
128 | * @tty: tty device | ||
129 | * | ||
130 | * Add a character to the tty read_buf queue. This is done under the | ||
131 | * read_lock to serialize character addition and also to protect us | ||
132 | * against parallel reads or flushes | ||
133 | */ | ||
134 | |||
124 | static void put_tty_queue(unsigned char c, struct tty_struct *tty) | 135 | static void put_tty_queue(unsigned char c, struct tty_struct *tty) |
125 | { | 136 | { |
126 | unsigned long flags; | 137 | unsigned long flags; |
@@ -137,14 +148,11 @@ static void put_tty_queue(unsigned char c, struct tty_struct *tty) | |||
137 | * check_unthrottle - allow new receive data | 148 | * check_unthrottle - allow new receive data |
138 | * @tty; tty device | 149 | * @tty; tty device |
139 | * | 150 | * |
140 | * Check whether to call the driver.unthrottle function. | 151 | * Check whether to call the driver unthrottle functions |
141 | * We test the TTY_THROTTLED bit first so that it always | 152 | * |
142 | * indicates the current state. The decision about whether | ||
143 | * it is worth allowing more input has been taken by the caller. | ||
144 | * Can sleep, may be called under the atomic_read_lock mutex but | 153 | * Can sleep, may be called under the atomic_read_lock mutex but |
145 | * this is not guaranteed. | 154 | * this is not guaranteed. |
146 | */ | 155 | */ |
147 | |||
148 | static void check_unthrottle(struct tty_struct *tty) | 156 | static void check_unthrottle(struct tty_struct *tty) |
149 | { | 157 | { |
150 | if (tty->count) | 158 | if (tty->count) |
@@ -158,6 +166,8 @@ static void check_unthrottle(struct tty_struct *tty) | |||
158 | * Reset the read buffer counters, clear the flags, | 166 | * Reset the read buffer counters, clear the flags, |
159 | * and make sure the driver is unthrottled. Called | 167 | * and make sure the driver is unthrottled. Called |
160 | * from n_tty_open() and n_tty_flush_buffer(). | 168 | * from n_tty_open() and n_tty_flush_buffer(). |
169 | * | ||
170 | * Locking: tty_read_lock for read fields. | ||
161 | */ | 171 | */ |
162 | static void reset_buffer_flags(struct tty_struct *tty) | 172 | static void reset_buffer_flags(struct tty_struct *tty) |
163 | { | 173 | { |
@@ -181,7 +191,7 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
181 | * at hangup) or when the N_TTY line discipline internally has to | 191 | * at hangup) or when the N_TTY line discipline internally has to |
182 | * clean the pending queue (for example some signals). | 192 | * clean the pending queue (for example some signals). |
183 | * | 193 | * |
184 | * Locking: ctrl_lock | 194 | * Locking: ctrl_lock, read_lock. |
185 | */ | 195 | */ |
186 | 196 | ||
187 | static void n_tty_flush_buffer(struct tty_struct *tty) | 197 | static void n_tty_flush_buffer(struct tty_struct *tty) |
@@ -207,6 +217,8 @@ static void n_tty_flush_buffer(struct tty_struct *tty) | |||
207 | * | 217 | * |
208 | * Report the number of characters buffered to be delivered to user | 218 | * Report the number of characters buffered to be delivered to user |
209 | * at this instant in time. | 219 | * at this instant in time. |
220 | * | ||
221 | * Locking: read_lock | ||
210 | */ | 222 | */ |
211 | 223 | ||
212 | static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) | 224 | static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) |
@@ -346,7 +358,7 @@ static int opost(unsigned char c, struct tty_struct *tty) | |||
346 | * the simple cases normally found and helps to generate blocks of | 358 | * the simple cases normally found and helps to generate blocks of |
347 | * symbols for the console driver and thus improve performance. | 359 | * symbols for the console driver and thus improve performance. |
348 | * | 360 | * |
349 | * Called from write_chan under the tty layer write lock. Relies | 361 | * Called from n_tty_write under the tty layer write lock. Relies |
350 | * on lock_kernel for the tty->column state. | 362 | * on lock_kernel for the tty->column state. |
351 | */ | 363 | */ |
352 | 364 | ||
@@ -410,6 +422,8 @@ break_out: | |||
410 | * | 422 | * |
411 | * Echo user input back onto the screen. This must be called only when | 423 | * Echo user input back onto the screen. This must be called only when |
412 | * L_ECHO(tty) is true. Called from the driver receive_buf path. | 424 | * L_ECHO(tty) is true. Called from the driver receive_buf path. |
425 | * | ||
426 | * Relies on BKL for tty column locking | ||
413 | */ | 427 | */ |
414 | 428 | ||
415 | static void echo_char(unsigned char c, struct tty_struct *tty) | 429 | static void echo_char(unsigned char c, struct tty_struct *tty) |
@@ -422,6 +436,12 @@ static void echo_char(unsigned char c, struct tty_struct *tty) | |||
422 | opost(c, tty); | 436 | opost(c, tty); |
423 | } | 437 | } |
424 | 438 | ||
439 | /** | ||
440 | * finsh_erasing - complete erase | ||
441 | * @tty: tty doing the erase | ||
442 | * | ||
443 | * Relies on BKL for tty column locking | ||
444 | */ | ||
425 | static inline void finish_erasing(struct tty_struct *tty) | 445 | static inline void finish_erasing(struct tty_struct *tty) |
426 | { | 446 | { |
427 | if (tty->erasing) { | 447 | if (tty->erasing) { |
@@ -439,6 +459,8 @@ static inline void finish_erasing(struct tty_struct *tty) | |||
439 | * Perform erase and necessary output when an erase character is | 459 | * Perform erase and necessary output when an erase character is |
440 | * present in the stream from the driver layer. Handles the complexities | 460 | * present in the stream from the driver layer. Handles the complexities |
441 | * of UTF-8 multibyte symbols. | 461 | * of UTF-8 multibyte symbols. |
462 | * | ||
463 | * Locking: read_lock for tty buffers, BKL for column/erasing state | ||
442 | */ | 464 | */ |
443 | 465 | ||
444 | static void eraser(unsigned char c, struct tty_struct *tty) | 466 | static void eraser(unsigned char c, struct tty_struct *tty) |
@@ -447,6 +469,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
447 | int head, seen_alnums, cnt; | 469 | int head, seen_alnums, cnt; |
448 | unsigned long flags; | 470 | unsigned long flags; |
449 | 471 | ||
472 | /* FIXME: locking needed ? */ | ||
450 | if (tty->read_head == tty->canon_head) { | 473 | if (tty->read_head == tty->canon_head) { |
451 | /* opost('\a', tty); */ /* what do you think? */ | 474 | /* opost('\a', tty); */ /* what do you think? */ |
452 | return; | 475 | return; |
@@ -481,6 +504,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
481 | } | 504 | } |
482 | 505 | ||
483 | seen_alnums = 0; | 506 | seen_alnums = 0; |
507 | /* FIXME: Locking ?? */ | ||
484 | while (tty->read_head != tty->canon_head) { | 508 | while (tty->read_head != tty->canon_head) { |
485 | head = tty->read_head; | 509 | head = tty->read_head; |
486 | 510 | ||
@@ -583,6 +607,8 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
583 | * may caus terminal flushing to take place according to the termios | 607 | * may caus terminal flushing to take place according to the termios |
584 | * settings and character used. Called from the driver receive_buf | 608 | * settings and character used. Called from the driver receive_buf |
585 | * path so serialized. | 609 | * path so serialized. |
610 | * | ||
611 | * Locking: ctrl_lock, read_lock (both via flush buffer) | ||
586 | */ | 612 | */ |
587 | 613 | ||
588 | static inline void isig(int sig, struct tty_struct *tty, int flush) | 614 | static inline void isig(int sig, struct tty_struct *tty, int flush) |
@@ -1007,12 +1033,26 @@ int is_ignored(int sig) | |||
1007 | * and is protected from re-entry by the tty layer. The user is | 1033 | * and is protected from re-entry by the tty layer. The user is |
1008 | * guaranteed that this function will not be re-entered or in progress | 1034 | * guaranteed that this function will not be re-entered or in progress |
1009 | * when the ldisc is closed. | 1035 | * when the ldisc is closed. |
1036 | * | ||
1037 | * Locking: Caller holds tty->termios_mutex | ||
1010 | */ | 1038 | */ |
1011 | 1039 | ||
1012 | static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | 1040 | static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) |
1013 | { | 1041 | { |
1014 | if (!tty) | 1042 | int canon_change = 1; |
1015 | return; | 1043 | BUG_ON(!tty); |
1044 | |||
1045 | if (old) | ||
1046 | canon_change = (old->c_lflag ^ tty->termios->c_lflag) & ICANON; | ||
1047 | if (canon_change) { | ||
1048 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | ||
1049 | tty->canon_head = tty->read_tail; | ||
1050 | tty->canon_data = 0; | ||
1051 | tty->erasing = 0; | ||
1052 | } | ||
1053 | |||
1054 | if (canon_change && !L_ICANON(tty) && tty->read_cnt) | ||
1055 | wake_up_interruptible(&tty->read_wait); | ||
1016 | 1056 | ||
1017 | tty->icanon = (L_ICANON(tty) != 0); | 1057 | tty->icanon = (L_ICANON(tty) != 0); |
1018 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { | 1058 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { |
@@ -1143,7 +1183,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) | |||
1143 | * @b: user data | 1183 | * @b: user data |
1144 | * @nr: size of data | 1184 | * @nr: size of data |
1145 | * | 1185 | * |
1146 | * Helper function to speed up read_chan. It is only called when | 1186 | * Helper function to speed up n_tty_read. It is only called when |
1147 | * ICANON is off; it copies characters straight from the tty queue to | 1187 | * ICANON is off; it copies characters straight from the tty queue to |
1148 | * user space directly. It can be profitably called twice; once to | 1188 | * user space directly. It can be profitably called twice; once to |
1149 | * drain the space from the tail pointer to the (physical) end of the | 1189 | * drain the space from the tail pointer to the (physical) end of the |
@@ -1210,7 +1250,7 @@ static int job_control(struct tty_struct *tty, struct file *file) | |||
1210 | if (file->f_op->write != redirected_tty_write && | 1250 | if (file->f_op->write != redirected_tty_write && |
1211 | current->signal->tty == tty) { | 1251 | current->signal->tty == tty) { |
1212 | if (!tty->pgrp) | 1252 | if (!tty->pgrp) |
1213 | printk(KERN_ERR "read_chan: no tty->pgrp!\n"); | 1253 | printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); |
1214 | else if (task_pgrp(current) != tty->pgrp) { | 1254 | else if (task_pgrp(current) != tty->pgrp) { |
1215 | if (is_ignored(SIGTTIN) || | 1255 | if (is_ignored(SIGTTIN) || |
1216 | is_current_pgrp_orphaned()) | 1256 | is_current_pgrp_orphaned()) |
@@ -1225,7 +1265,7 @@ static int job_control(struct tty_struct *tty, struct file *file) | |||
1225 | 1265 | ||
1226 | 1266 | ||
1227 | /** | 1267 | /** |
1228 | * read_chan - read function for tty | 1268 | * n_tty_read - read function for tty |
1229 | * @tty: tty device | 1269 | * @tty: tty device |
1230 | * @file: file object | 1270 | * @file: file object |
1231 | * @buf: userspace buffer pointer | 1271 | * @buf: userspace buffer pointer |
@@ -1239,7 +1279,7 @@ static int job_control(struct tty_struct *tty, struct file *file) | |||
1239 | * This code must be sure never to sleep through a hangup. | 1279 | * This code must be sure never to sleep through a hangup. |
1240 | */ | 1280 | */ |
1241 | 1281 | ||
1242 | static ssize_t read_chan(struct tty_struct *tty, struct file *file, | 1282 | static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, |
1243 | unsigned char __user *buf, size_t nr) | 1283 | unsigned char __user *buf, size_t nr) |
1244 | { | 1284 | { |
1245 | unsigned char __user *b = buf; | 1285 | unsigned char __user *b = buf; |
@@ -1254,10 +1294,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, | |||
1254 | 1294 | ||
1255 | do_it_again: | 1295 | do_it_again: |
1256 | 1296 | ||
1257 | if (!tty->read_buf) { | 1297 | BUG_ON(!tty->read_buf); |
1258 | printk(KERN_ERR "n_tty_read_chan: read_buf == NULL?!?\n"); | ||
1259 | return -EIO; | ||
1260 | } | ||
1261 | 1298 | ||
1262 | c = job_control(tty, file); | 1299 | c = job_control(tty, file); |
1263 | if (c < 0) | 1300 | if (c < 0) |
@@ -1444,7 +1481,7 @@ do_it_again: | |||
1444 | } | 1481 | } |
1445 | 1482 | ||
1446 | /** | 1483 | /** |
1447 | * write_chan - write function for tty | 1484 | * n_tty_write - write function for tty |
1448 | * @tty: tty device | 1485 | * @tty: tty device |
1449 | * @file: file object | 1486 | * @file: file object |
1450 | * @buf: userspace buffer pointer | 1487 | * @buf: userspace buffer pointer |
@@ -1458,7 +1495,7 @@ do_it_again: | |||
1458 | * This code must be sure never to sleep through a hangup. | 1495 | * This code must be sure never to sleep through a hangup. |
1459 | */ | 1496 | */ |
1460 | 1497 | ||
1461 | static ssize_t write_chan(struct tty_struct *tty, struct file *file, | 1498 | static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, |
1462 | const unsigned char *buf, size_t nr) | 1499 | const unsigned char *buf, size_t nr) |
1463 | { | 1500 | { |
1464 | const unsigned char *b = buf; | 1501 | const unsigned char *b = buf; |
@@ -1532,7 +1569,7 @@ break_out: | |||
1532 | } | 1569 | } |
1533 | 1570 | ||
1534 | /** | 1571 | /** |
1535 | * normal_poll - poll method for N_TTY | 1572 | * n_tty_poll - poll method for N_TTY |
1536 | * @tty: terminal device | 1573 | * @tty: terminal device |
1537 | * @file: file accessing it | 1574 | * @file: file accessing it |
1538 | * @wait: poll table | 1575 | * @wait: poll table |
@@ -1545,7 +1582,7 @@ break_out: | |||
1545 | * Called without the kernel lock held - fine | 1582 | * Called without the kernel lock held - fine |
1546 | */ | 1583 | */ |
1547 | 1584 | ||
1548 | static unsigned int normal_poll(struct tty_struct *tty, struct file *file, | 1585 | static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, |
1549 | poll_table *wait) | 1586 | poll_table *wait) |
1550 | { | 1587 | { |
1551 | unsigned int mask = 0; | 1588 | unsigned int mask = 0; |
@@ -1573,6 +1610,44 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file, | |||
1573 | return mask; | 1610 | return mask; |
1574 | } | 1611 | } |
1575 | 1612 | ||
1613 | static unsigned long inq_canon(struct tty_struct *tty) | ||
1614 | { | ||
1615 | int nr, head, tail; | ||
1616 | |||
1617 | if (!tty->canon_data) | ||
1618 | return 0; | ||
1619 | head = tty->canon_head; | ||
1620 | tail = tty->read_tail; | ||
1621 | nr = (head - tail) & (N_TTY_BUF_SIZE-1); | ||
1622 | /* Skip EOF-chars.. */ | ||
1623 | while (head != tail) { | ||
1624 | if (test_bit(tail, tty->read_flags) && | ||
1625 | tty->read_buf[tail] == __DISABLED_CHAR) | ||
1626 | nr--; | ||
1627 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | ||
1628 | } | ||
1629 | return nr; | ||
1630 | } | ||
1631 | |||
1632 | static int n_tty_ioctl(struct tty_struct *tty, struct file *file, | ||
1633 | unsigned int cmd, unsigned long arg) | ||
1634 | { | ||
1635 | int retval; | ||
1636 | |||
1637 | switch (cmd) { | ||
1638 | case TIOCOUTQ: | ||
1639 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); | ||
1640 | case TIOCINQ: | ||
1641 | /* FIXME: Locking */ | ||
1642 | retval = tty->read_cnt; | ||
1643 | if (L_ICANON(tty)) | ||
1644 | retval = inq_canon(tty); | ||
1645 | return put_user(retval, (unsigned int __user *) arg); | ||
1646 | default: | ||
1647 | return n_tty_ioctl_helper(tty, file, cmd, arg); | ||
1648 | } | ||
1649 | } | ||
1650 | |||
1576 | struct tty_ldisc_ops tty_ldisc_N_TTY = { | 1651 | struct tty_ldisc_ops tty_ldisc_N_TTY = { |
1577 | .magic = TTY_LDISC_MAGIC, | 1652 | .magic = TTY_LDISC_MAGIC, |
1578 | .name = "n_tty", | 1653 | .name = "n_tty", |
@@ -1580,11 +1655,11 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { | |||
1580 | .close = n_tty_close, | 1655 | .close = n_tty_close, |
1581 | .flush_buffer = n_tty_flush_buffer, | 1656 | .flush_buffer = n_tty_flush_buffer, |
1582 | .chars_in_buffer = n_tty_chars_in_buffer, | 1657 | .chars_in_buffer = n_tty_chars_in_buffer, |
1583 | .read = read_chan, | 1658 | .read = n_tty_read, |
1584 | .write = write_chan, | 1659 | .write = n_tty_write, |
1585 | .ioctl = n_tty_ioctl, | 1660 | .ioctl = n_tty_ioctl, |
1586 | .set_termios = n_tty_set_termios, | 1661 | .set_termios = n_tty_set_termios, |
1587 | .poll = normal_poll, | 1662 | .poll = n_tty_poll, |
1588 | .receive_buf = n_tty_receive_buf, | 1663 | .receive_buf = n_tty_receive_buf, |
1589 | .write_wakeup = n_tty_write_wakeup | 1664 | .write_wakeup = n_tty_write_wakeup |
1590 | }; | 1665 | }; |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 66a0f931c66c..9a34a1935283 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -1599,7 +1599,10 @@ static int ntty_open(struct tty_struct *tty, struct file *file) | |||
1599 | return 0; | 1599 | return 0; |
1600 | } | 1600 | } |
1601 | 1601 | ||
1602 | /* Called when the userspace process close the tty, /dev/noz*. */ | 1602 | /* Called when the userspace process close the tty, /dev/noz*. Also |
1603 | called immediately if ntty_open fails in which case tty->driver_data | ||
1604 | will be NULL an we exit by the first return */ | ||
1605 | |||
1603 | static void ntty_close(struct tty_struct *tty, struct file *file) | 1606 | static void ntty_close(struct tty_struct *tty, struct file *file) |
1604 | { | 1607 | { |
1605 | struct nozomi *dc = get_dc_by_tty(tty); | 1608 | struct nozomi *dc = get_dc_by_tty(tty); |
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 3a23e7694d55..569f2f7743a7 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c | |||
@@ -276,6 +276,7 @@ static int ipw_write_room(struct tty_struct *linux_tty) | |||
276 | struct ipw_tty *tty = linux_tty->driver_data; | 276 | struct ipw_tty *tty = linux_tty->driver_data; |
277 | int room; | 277 | int room; |
278 | 278 | ||
279 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
279 | if (!tty) | 280 | if (!tty) |
280 | return -ENODEV; | 281 | return -ENODEV; |
281 | 282 | ||
@@ -397,6 +398,7 @@ static int set_control_lines(struct ipw_tty *tty, unsigned int set, | |||
397 | static int ipw_tiocmget(struct tty_struct *linux_tty, struct file *file) | 398 | static int ipw_tiocmget(struct tty_struct *linux_tty, struct file *file) |
398 | { | 399 | { |
399 | struct ipw_tty *tty = linux_tty->driver_data; | 400 | struct ipw_tty *tty = linux_tty->driver_data; |
401 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
400 | 402 | ||
401 | if (!tty) | 403 | if (!tty) |
402 | return -ENODEV; | 404 | return -ENODEV; |
@@ -412,6 +414,7 @@ ipw_tiocmset(struct tty_struct *linux_tty, struct file *file, | |||
412 | unsigned int set, unsigned int clear) | 414 | unsigned int set, unsigned int clear) |
413 | { | 415 | { |
414 | struct ipw_tty *tty = linux_tty->driver_data; | 416 | struct ipw_tty *tty = linux_tty->driver_data; |
417 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
415 | 418 | ||
416 | if (!tty) | 419 | if (!tty) |
417 | return -ENODEV; | 420 | return -ENODEV; |
@@ -433,6 +436,8 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
433 | if (!tty->open_count) | 436 | if (!tty->open_count) |
434 | return -EINVAL; | 437 | return -EINVAL; |
435 | 438 | ||
439 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
440 | |||
436 | switch (cmd) { | 441 | switch (cmd) { |
437 | case TIOCGSERIAL: | 442 | case TIOCGSERIAL: |
438 | return ipwireless_get_serial_info(tty, (void __user *) arg); | 443 | return ipwireless_get_serial_info(tty, (void __user *) arg); |
@@ -467,13 +472,6 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
467 | } | 472 | } |
468 | return 0; | 473 | return 0; |
469 | 474 | ||
470 | case TCGETS: | ||
471 | case TCGETA: | ||
472 | return n_tty_ioctl(linux_tty, file, cmd, arg); | ||
473 | |||
474 | case TCFLSH: | ||
475 | return n_tty_ioctl(linux_tty, file, cmd, arg); | ||
476 | |||
477 | case FIONREAD: | 475 | case FIONREAD: |
478 | { | 476 | { |
479 | int val = 0; | 477 | int val = 0; |
@@ -482,10 +480,11 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
482 | return -EFAULT; | 480 | return -EFAULT; |
483 | } | 481 | } |
484 | return 0; | 482 | return 0; |
483 | case TCFLSH: | ||
484 | return tty_perform_flush(linux_tty, arg); | ||
485 | } | 485 | } |
486 | } | 486 | } |
487 | 487 | return tty_mode_ioctl(linux_tty, file, cmd , arg); | |
488 | return -ENOIOCTLCMD; | ||
489 | } | 488 | } |
490 | 489 | ||
491 | static int add_tty(dev_node_t *nodesp, int j, | 490 | static int add_tty(dev_node_t *nodesp, int j, |
@@ -588,6 +587,8 @@ void ipwireless_tty_free(struct ipw_tty *tty) | |||
588 | tty_hangup(ttyj->linux_tty); | 587 | tty_hangup(ttyj->linux_tty); |
589 | /* Wait till the tty_hangup has completed */ | 588 | /* Wait till the tty_hangup has completed */ |
590 | flush_scheduled_work(); | 589 | flush_scheduled_work(); |
590 | /* FIXME: Exactly how is the tty object locked here | ||
591 | against a parallel ioctl etc */ | ||
591 | mutex_lock(&ttyj->ipw_tty_mutex); | 592 | mutex_lock(&ttyj->ipw_tty_mutex); |
592 | } | 593 | } |
593 | while (ttyj->open_count) | 594 | while (ttyj->open_count) |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 76b27932d229..6d4582712b1f 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -8,10 +8,12 @@ | |||
8 | * Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to | 8 | * Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to |
9 | * waiting writers -- Sapan Bhatia <sapan@corewars.org> | 9 | * waiting writers -- Sapan Bhatia <sapan@corewars.org> |
10 | * | 10 | * |
11 | * | 11 | * When reading this code see also fs/devpts. In particular note that the |
12 | * driver_data field is used by the devpts side as a binding to the devpts | ||
13 | * inode. | ||
12 | */ | 14 | */ |
13 | 15 | ||
14 | #include <linux/module.h> /* For EXPORT_SYMBOL */ | 16 | #include <linux/module.h> |
15 | 17 | ||
16 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
17 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
@@ -23,26 +25,25 @@ | |||
23 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
24 | #include <linux/init.h> | 26 | #include <linux/init.h> |
25 | #include <linux/sysctl.h> | 27 | #include <linux/sysctl.h> |
26 | 28 | #include <linux/device.h> | |
27 | #include <asm/uaccess.h> | 29 | #include <linux/uaccess.h> |
28 | #include <asm/system.h> | ||
29 | #include <linux/bitops.h> | 30 | #include <linux/bitops.h> |
30 | #include <linux/devpts_fs.h> | 31 | #include <linux/devpts_fs.h> |
31 | 32 | ||
33 | #include <asm/system.h> | ||
34 | |||
32 | /* These are global because they are accessed in tty_io.c */ | 35 | /* These are global because they are accessed in tty_io.c */ |
33 | #ifdef CONFIG_UNIX98_PTYS | 36 | #ifdef CONFIG_UNIX98_PTYS |
34 | struct tty_driver *ptm_driver; | 37 | struct tty_driver *ptm_driver; |
35 | static struct tty_driver *pts_driver; | 38 | static struct tty_driver *pts_driver; |
36 | #endif | 39 | #endif |
37 | 40 | ||
38 | static void pty_close(struct tty_struct * tty, struct file * filp) | 41 | static void pty_close(struct tty_struct *tty, struct file *filp) |
39 | { | 42 | { |
40 | if (!tty) | 43 | BUG_ON(!tty); |
41 | return; | 44 | if (tty->driver->subtype == PTY_TYPE_MASTER) |
42 | if (tty->driver->subtype == PTY_TYPE_MASTER) { | 45 | WARN_ON(tty->count > 1); |
43 | if (tty->count > 1) | 46 | else { |
44 | printk("master pty_close: count = %d!!\n", tty->count); | ||
45 | } else { | ||
46 | if (tty->count > 2) | 47 | if (tty->count > 2) |
47 | return; | 48 | return; |
48 | } | 49 | } |
@@ -59,7 +60,7 @@ static void pty_close(struct tty_struct * tty, struct file * filp) | |||
59 | set_bit(TTY_OTHER_CLOSED, &tty->flags); | 60 | set_bit(TTY_OTHER_CLOSED, &tty->flags); |
60 | #ifdef CONFIG_UNIX98_PTYS | 61 | #ifdef CONFIG_UNIX98_PTYS |
61 | if (tty->driver == ptm_driver) | 62 | if (tty->driver == ptm_driver) |
62 | devpts_pty_kill(tty->index); | 63 | devpts_pty_kill(tty->link); |
63 | #endif | 64 | #endif |
64 | tty_vhangup(tty->link); | 65 | tty_vhangup(tty->link); |
65 | } | 66 | } |
@@ -69,13 +70,13 @@ static void pty_close(struct tty_struct * tty, struct file * filp) | |||
69 | * The unthrottle routine is called by the line discipline to signal | 70 | * The unthrottle routine is called by the line discipline to signal |
70 | * that it can receive more characters. For PTY's, the TTY_THROTTLED | 71 | * that it can receive more characters. For PTY's, the TTY_THROTTLED |
71 | * flag is always set, to force the line discipline to always call the | 72 | * flag is always set, to force the line discipline to always call the |
72 | * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE | 73 | * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE |
73 | * characters in the queue. This is necessary since each time this | 74 | * characters in the queue. This is necessary since each time this |
74 | * happens, we need to wake up any sleeping processes that could be | 75 | * happens, we need to wake up any sleeping processes that could be |
75 | * (1) trying to send data to the pty, or (2) waiting in wait_until_sent() | 76 | * (1) trying to send data to the pty, or (2) waiting in wait_until_sent() |
76 | * for the pty buffer to be drained. | 77 | * for the pty buffer to be drained. |
77 | */ | 78 | */ |
78 | static void pty_unthrottle(struct tty_struct * tty) | 79 | static void pty_unthrottle(struct tty_struct *tty) |
79 | { | 80 | { |
80 | struct tty_struct *o_tty = tty->link; | 81 | struct tty_struct *o_tty = tty->link; |
81 | 82 | ||
@@ -87,7 +88,7 @@ static void pty_unthrottle(struct tty_struct * tty) | |||
87 | } | 88 | } |
88 | 89 | ||
89 | /* | 90 | /* |
90 | * WSH 05/24/97: modified to | 91 | * WSH 05/24/97: modified to |
91 | * (1) use space in tty->flip instead of a shared temp buffer | 92 | * (1) use space in tty->flip instead of a shared temp buffer |
92 | * The flip buffers aren't being used for a pty, so there's lots | 93 | * The flip buffers aren't being used for a pty, so there's lots |
93 | * of space available. The buffer is protected by a per-pty | 94 | * of space available. The buffer is protected by a per-pty |
@@ -100,7 +101,8 @@ static void pty_unthrottle(struct tty_struct * tty) | |||
100 | * not our partners. We can't just take the other one blindly without | 101 | * not our partners. We can't just take the other one blindly without |
101 | * risking deadlocks. | 102 | * risking deadlocks. |
102 | */ | 103 | */ |
103 | static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) | 104 | static int pty_write(struct tty_struct *tty, const unsigned char *buf, |
105 | int count) | ||
104 | { | 106 | { |
105 | struct tty_struct *to = tty->link; | 107 | struct tty_struct *to = tty->link; |
106 | int c; | 108 | int c; |
@@ -112,7 +114,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun | |||
112 | if (c > count) | 114 | if (c > count) |
113 | c = count; | 115 | c = count; |
114 | to->ldisc.ops->receive_buf(to, buf, NULL, c); | 116 | to->ldisc.ops->receive_buf(to, buf, NULL, c); |
115 | 117 | ||
116 | return c; | 118 | return c; |
117 | } | 119 | } |
118 | 120 | ||
@@ -128,17 +130,17 @@ static int pty_write_room(struct tty_struct *tty) | |||
128 | 130 | ||
129 | /* | 131 | /* |
130 | * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior | 132 | * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior |
131 | * The chars_in_buffer() value is used by the ldisc select() function | 133 | * The chars_in_buffer() value is used by the ldisc select() function |
132 | * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256). | 134 | * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256). |
133 | * The pty driver chars_in_buffer() Master/Slave must behave differently: | 135 | * The pty driver chars_in_buffer() Master/Slave must behave differently: |
134 | * | 136 | * |
135 | * The Master side needs to allow typed-ahead commands to accumulate | 137 | * The Master side needs to allow typed-ahead commands to accumulate |
136 | * while being canonicalized, so we report "our buffer" as empty until | 138 | * while being canonicalized, so we report "our buffer" as empty until |
137 | * some threshold is reached, and then report the count. (Any count > | 139 | * some threshold is reached, and then report the count. (Any count > |
138 | * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock | 140 | * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock |
139 | * the count returned must be 0 if no canonical data is available to be | 141 | * the count returned must be 0 if no canonical data is available to be |
140 | * read. (The N_TTY ldisc.chars_in_buffer now knows this.) | 142 | * read. (The N_TTY ldisc.chars_in_buffer now knows this.) |
141 | * | 143 | * |
142 | * The Slave side passes all characters in raw mode to the Master side's | 144 | * The Slave side passes all characters in raw mode to the Master side's |
143 | * buffer where they can be read immediately, so in this case we can | 145 | * buffer where they can be read immediately, so in this case we can |
144 | * return the true count in the buffer. | 146 | * return the true count in the buffer. |
@@ -155,21 +157,22 @@ static int pty_chars_in_buffer(struct tty_struct *tty) | |||
155 | /* The ldisc must report 0 if no characters available to be read */ | 157 | /* The ldisc must report 0 if no characters available to be read */ |
156 | count = to->ldisc.ops->chars_in_buffer(to); | 158 | count = to->ldisc.ops->chars_in_buffer(to); |
157 | 159 | ||
158 | if (tty->driver->subtype == PTY_TYPE_SLAVE) return count; | 160 | if (tty->driver->subtype == PTY_TYPE_SLAVE) |
161 | return count; | ||
159 | 162 | ||
160 | /* Master side driver ... if the other side's read buffer is less than | 163 | /* Master side driver ... if the other side's read buffer is less than |
161 | * half full, return 0 to allow writers to proceed; otherwise return | 164 | * half full, return 0 to allow writers to proceed; otherwise return |
162 | * the count. This leaves a comfortable margin to avoid overflow, | 165 | * the count. This leaves a comfortable margin to avoid overflow, |
163 | * and still allows half a buffer's worth of typed-ahead commands. | 166 | * and still allows half a buffer's worth of typed-ahead commands. |
164 | */ | 167 | */ |
165 | return ((count < N_TTY_BUF_SIZE/2) ? 0 : count); | 168 | return (count < N_TTY_BUF_SIZE/2) ? 0 : count; |
166 | } | 169 | } |
167 | 170 | ||
168 | /* Set the lock flag on a pty */ | 171 | /* Set the lock flag on a pty */ |
169 | static int pty_set_lock(struct tty_struct *tty, int __user * arg) | 172 | static int pty_set_lock(struct tty_struct *tty, int __user *arg) |
170 | { | 173 | { |
171 | int val; | 174 | int val; |
172 | if (get_user(val,arg)) | 175 | if (get_user(val, arg)) |
173 | return -EFAULT; | 176 | return -EFAULT; |
174 | if (val) | 177 | if (val) |
175 | set_bit(TTY_PTY_LOCK, &tty->flags); | 178 | set_bit(TTY_PTY_LOCK, &tty->flags); |
@@ -182,13 +185,13 @@ static void pty_flush_buffer(struct tty_struct *tty) | |||
182 | { | 185 | { |
183 | struct tty_struct *to = tty->link; | 186 | struct tty_struct *to = tty->link; |
184 | unsigned long flags; | 187 | unsigned long flags; |
185 | 188 | ||
186 | if (!to) | 189 | if (!to) |
187 | return; | 190 | return; |
188 | 191 | ||
189 | if (to->ldisc.ops->flush_buffer) | 192 | if (to->ldisc.ops->flush_buffer) |
190 | to->ldisc.ops->flush_buffer(to); | 193 | to->ldisc.ops->flush_buffer(to); |
191 | 194 | ||
192 | if (to->packet) { | 195 | if (to->packet) { |
193 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 196 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
194 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; | 197 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; |
@@ -197,7 +200,7 @@ static void pty_flush_buffer(struct tty_struct *tty) | |||
197 | } | 200 | } |
198 | } | 201 | } |
199 | 202 | ||
200 | static int pty_open(struct tty_struct *tty, struct file * filp) | 203 | static int pty_open(struct tty_struct *tty, struct file *filp) |
201 | { | 204 | { |
202 | int retval = -ENODEV; | 205 | int retval = -ENODEV; |
203 | 206 | ||
@@ -220,13 +223,65 @@ out: | |||
220 | return retval; | 223 | return retval; |
221 | } | 224 | } |
222 | 225 | ||
223 | static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | 226 | static void pty_set_termios(struct tty_struct *tty, |
227 | struct ktermios *old_termios) | ||
228 | { | ||
229 | tty->termios->c_cflag &= ~(CSIZE | PARENB); | ||
230 | tty->termios->c_cflag |= (CS8 | CREAD); | ||
231 | } | ||
232 | |||
233 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
224 | { | 234 | { |
225 | tty->termios->c_cflag &= ~(CSIZE | PARENB); | 235 | struct tty_struct *o_tty; |
226 | tty->termios->c_cflag |= (CS8 | CREAD); | 236 | int idx = tty->index; |
237 | int retval; | ||
238 | |||
239 | o_tty = alloc_tty_struct(); | ||
240 | if (!o_tty) | ||
241 | return -ENOMEM; | ||
242 | if (!try_module_get(driver->other->owner)) { | ||
243 | /* This cannot in fact currently happen */ | ||
244 | free_tty_struct(o_tty); | ||
245 | return -ENOMEM; | ||
246 | } | ||
247 | initialize_tty_struct(o_tty, driver->other, idx); | ||
248 | |||
249 | /* We always use new tty termios data so we can do this | ||
250 | the easy way .. */ | ||
251 | retval = tty_init_termios(tty); | ||
252 | if (retval) | ||
253 | goto free_mem_out; | ||
254 | |||
255 | retval = tty_init_termios(o_tty); | ||
256 | if (retval) { | ||
257 | tty_free_termios(tty); | ||
258 | goto free_mem_out; | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * Everything allocated ... set up the o_tty structure. | ||
263 | */ | ||
264 | driver->other->ttys[idx] = o_tty; | ||
265 | tty_driver_kref_get(driver->other); | ||
266 | if (driver->subtype == PTY_TYPE_MASTER) | ||
267 | o_tty->count++; | ||
268 | /* Establish the links in both directions */ | ||
269 | tty->link = o_tty; | ||
270 | o_tty->link = tty; | ||
271 | |||
272 | tty_driver_kref_get(driver); | ||
273 | tty->count++; | ||
274 | driver->ttys[idx] = tty; | ||
275 | return 0; | ||
276 | free_mem_out: | ||
277 | module_put(o_tty->driver->owner); | ||
278 | free_tty_struct(o_tty); | ||
279 | return -ENOMEM; | ||
227 | } | 280 | } |
228 | 281 | ||
282 | |||
229 | static const struct tty_operations pty_ops = { | 283 | static const struct tty_operations pty_ops = { |
284 | .install = pty_install, | ||
230 | .open = pty_open, | 285 | .open = pty_open, |
231 | .close = pty_close, | 286 | .close = pty_close, |
232 | .write = pty_write, | 287 | .write = pty_write, |
@@ -329,8 +384,11 @@ static inline void legacy_pty_init(void) { } | |||
329 | * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. | 384 | * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. |
330 | */ | 385 | */ |
331 | int pty_limit = NR_UNIX98_PTY_DEFAULT; | 386 | int pty_limit = NR_UNIX98_PTY_DEFAULT; |
332 | static int pty_limit_min = 0; | 387 | static int pty_limit_min; |
333 | static int pty_limit_max = NR_UNIX98_PTY_MAX; | 388 | static int pty_limit_max = NR_UNIX98_PTY_MAX; |
389 | static int pty_count; | ||
390 | |||
391 | static struct cdev ptmx_cdev; | ||
334 | 392 | ||
335 | static struct ctl_table pty_table[] = { | 393 | static struct ctl_table pty_table[] = { |
336 | { | 394 | { |
@@ -348,6 +406,7 @@ static struct ctl_table pty_table[] = { | |||
348 | .procname = "nr", | 406 | .procname = "nr", |
349 | .maxlen = sizeof(int), | 407 | .maxlen = sizeof(int), |
350 | .mode = 0444, | 408 | .mode = 0444, |
409 | .data = &pty_count, | ||
351 | .proc_handler = &proc_dointvec, | 410 | .proc_handler = &proc_dointvec, |
352 | }, { | 411 | }, { |
353 | .ctl_name = 0 | 412 | .ctl_name = 0 |
@@ -388,7 +447,127 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, | |||
388 | return -ENOIOCTLCMD; | 447 | return -ENOIOCTLCMD; |
389 | } | 448 | } |
390 | 449 | ||
450 | /** | ||
451 | * ptm_unix98_lookup - find a pty master | ||
452 | * @driver: ptm driver | ||
453 | * @idx: tty index | ||
454 | * | ||
455 | * Look up a pty master device. Called under the tty_mutex for now. | ||
456 | * This provides our locking. | ||
457 | */ | ||
458 | |||
459 | static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, | ||
460 | struct inode *ptm_inode, int idx) | ||
461 | { | ||
462 | struct tty_struct *tty = devpts_get_tty(ptm_inode, idx); | ||
463 | if (tty) | ||
464 | tty = tty->link; | ||
465 | return tty; | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * pts_unix98_lookup - find a pty slave | ||
470 | * @driver: pts driver | ||
471 | * @idx: tty index | ||
472 | * | ||
473 | * Look up a pty master device. Called under the tty_mutex for now. | ||
474 | * This provides our locking. | ||
475 | */ | ||
476 | |||
477 | static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, | ||
478 | struct inode *pts_inode, int idx) | ||
479 | { | ||
480 | struct tty_struct *tty = devpts_get_tty(pts_inode, idx); | ||
481 | /* Master must be open before slave */ | ||
482 | if (!tty) | ||
483 | return ERR_PTR(-EIO); | ||
484 | return tty; | ||
485 | } | ||
486 | |||
487 | static void pty_unix98_shutdown(struct tty_struct *tty) | ||
488 | { | ||
489 | /* We have our own method as we don't use the tty index */ | ||
490 | kfree(tty->termios); | ||
491 | } | ||
492 | |||
493 | /* We have no need to install and remove our tty objects as devpts does all | ||
494 | the work for us */ | ||
495 | |||
496 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | ||
497 | { | ||
498 | struct tty_struct *o_tty; | ||
499 | int idx = tty->index; | ||
500 | |||
501 | o_tty = alloc_tty_struct(); | ||
502 | if (!o_tty) | ||
503 | return -ENOMEM; | ||
504 | if (!try_module_get(driver->other->owner)) { | ||
505 | /* This cannot in fact currently happen */ | ||
506 | free_tty_struct(o_tty); | ||
507 | return -ENOMEM; | ||
508 | } | ||
509 | initialize_tty_struct(o_tty, driver->other, idx); | ||
510 | |||
511 | tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
512 | if (tty->termios == NULL) | ||
513 | goto free_mem_out; | ||
514 | *tty->termios = driver->init_termios; | ||
515 | tty->termios_locked = tty->termios + 1; | ||
516 | |||
517 | o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
518 | if (o_tty->termios == NULL) | ||
519 | goto free_mem_out; | ||
520 | *o_tty->termios = driver->other->init_termios; | ||
521 | o_tty->termios_locked = o_tty->termios + 1; | ||
522 | |||
523 | tty_driver_kref_get(driver->other); | ||
524 | if (driver->subtype == PTY_TYPE_MASTER) | ||
525 | o_tty->count++; | ||
526 | /* Establish the links in both directions */ | ||
527 | tty->link = o_tty; | ||
528 | o_tty->link = tty; | ||
529 | /* | ||
530 | * All structures have been allocated, so now we install them. | ||
531 | * Failures after this point use release_tty to clean up, so | ||
532 | * there's no need to null out the local pointers. | ||
533 | */ | ||
534 | tty_driver_kref_get(driver); | ||
535 | tty->count++; | ||
536 | pty_count++; | ||
537 | return 0; | ||
538 | free_mem_out: | ||
539 | kfree(o_tty->termios); | ||
540 | module_put(o_tty->driver->owner); | ||
541 | free_tty_struct(o_tty); | ||
542 | kfree(tty->termios); | ||
543 | return -ENOMEM; | ||
544 | } | ||
545 | |||
546 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
547 | { | ||
548 | pty_count--; | ||
549 | } | ||
550 | |||
551 | static const struct tty_operations ptm_unix98_ops = { | ||
552 | .lookup = ptm_unix98_lookup, | ||
553 | .install = pty_unix98_install, | ||
554 | .remove = pty_unix98_remove, | ||
555 | .open = pty_open, | ||
556 | .close = pty_close, | ||
557 | .write = pty_write, | ||
558 | .write_room = pty_write_room, | ||
559 | .flush_buffer = pty_flush_buffer, | ||
560 | .chars_in_buffer = pty_chars_in_buffer, | ||
561 | .unthrottle = pty_unthrottle, | ||
562 | .set_termios = pty_set_termios, | ||
563 | .ioctl = pty_unix98_ioctl, | ||
564 | .shutdown = pty_unix98_shutdown | ||
565 | }; | ||
566 | |||
391 | static const struct tty_operations pty_unix98_ops = { | 567 | static const struct tty_operations pty_unix98_ops = { |
568 | .lookup = pts_unix98_lookup, | ||
569 | .install = pty_unix98_install, | ||
570 | .remove = pty_unix98_remove, | ||
392 | .open = pty_open, | 571 | .open = pty_open, |
393 | .close = pty_close, | 572 | .close = pty_close, |
394 | .write = pty_write, | 573 | .write = pty_write, |
@@ -397,9 +576,73 @@ static const struct tty_operations pty_unix98_ops = { | |||
397 | .chars_in_buffer = pty_chars_in_buffer, | 576 | .chars_in_buffer = pty_chars_in_buffer, |
398 | .unthrottle = pty_unthrottle, | 577 | .unthrottle = pty_unthrottle, |
399 | .set_termios = pty_set_termios, | 578 | .set_termios = pty_set_termios, |
400 | .ioctl = pty_unix98_ioctl | 579 | .shutdown = pty_unix98_shutdown |
401 | }; | 580 | }; |
402 | 581 | ||
582 | /** | ||
583 | * ptmx_open - open a unix 98 pty master | ||
584 | * @inode: inode of device file | ||
585 | * @filp: file pointer to tty | ||
586 | * | ||
587 | * Allocate a unix98 pty master device from the ptmx driver. | ||
588 | * | ||
589 | * Locking: tty_mutex protects the init_dev work. tty->count should | ||
590 | * protect the rest. | ||
591 | * allocated_ptys_lock handles the list of free pty numbers | ||
592 | */ | ||
593 | |||
594 | static int __ptmx_open(struct inode *inode, struct file *filp) | ||
595 | { | ||
596 | struct tty_struct *tty; | ||
597 | int retval; | ||
598 | int index; | ||
599 | |||
600 | nonseekable_open(inode, filp); | ||
601 | |||
602 | /* find a device that is not in use. */ | ||
603 | index = devpts_new_index(inode); | ||
604 | if (index < 0) | ||
605 | return index; | ||
606 | |||
607 | mutex_lock(&tty_mutex); | ||
608 | tty = tty_init_dev(ptm_driver, index, 1); | ||
609 | mutex_unlock(&tty_mutex); | ||
610 | |||
611 | if (IS_ERR(tty)) { | ||
612 | retval = PTR_ERR(tty); | ||
613 | goto out; | ||
614 | } | ||
615 | |||
616 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | ||
617 | filp->private_data = tty; | ||
618 | file_move(filp, &tty->tty_files); | ||
619 | |||
620 | retval = devpts_pty_new(inode, tty->link); | ||
621 | if (retval) | ||
622 | goto out1; | ||
623 | |||
624 | retval = ptm_driver->ops->open(tty, filp); | ||
625 | if (!retval) | ||
626 | return 0; | ||
627 | out1: | ||
628 | tty_release_dev(filp); | ||
629 | return retval; | ||
630 | out: | ||
631 | devpts_kill_index(inode, index); | ||
632 | return retval; | ||
633 | } | ||
634 | |||
635 | static int ptmx_open(struct inode *inode, struct file *filp) | ||
636 | { | ||
637 | int ret; | ||
638 | |||
639 | lock_kernel(); | ||
640 | ret = __ptmx_open(inode, filp); | ||
641 | unlock_kernel(); | ||
642 | return ret; | ||
643 | } | ||
644 | |||
645 | static struct file_operations ptmx_fops; | ||
403 | 646 | ||
404 | static void __init unix98_pty_init(void) | 647 | static void __init unix98_pty_init(void) |
405 | { | 648 | { |
@@ -427,7 +670,7 @@ static void __init unix98_pty_init(void) | |||
427 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 670 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
428 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | 671 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
429 | ptm_driver->other = pts_driver; | 672 | ptm_driver->other = pts_driver; |
430 | tty_set_operations(ptm_driver, &pty_unix98_ops); | 673 | tty_set_operations(ptm_driver, &ptm_unix98_ops); |
431 | 674 | ||
432 | pts_driver->owner = THIS_MODULE; | 675 | pts_driver->owner = THIS_MODULE; |
433 | pts_driver->driver_name = "pty_slave"; | 676 | pts_driver->driver_name = "pty_slave"; |
@@ -443,16 +686,26 @@ static void __init unix98_pty_init(void) | |||
443 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 686 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
444 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | 687 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
445 | pts_driver->other = ptm_driver; | 688 | pts_driver->other = ptm_driver; |
446 | tty_set_operations(pts_driver, &pty_ops); | 689 | tty_set_operations(pts_driver, &pty_unix98_ops); |
447 | 690 | ||
448 | if (tty_register_driver(ptm_driver)) | 691 | if (tty_register_driver(ptm_driver)) |
449 | panic("Couldn't register Unix98 ptm driver"); | 692 | panic("Couldn't register Unix98 ptm driver"); |
450 | if (tty_register_driver(pts_driver)) | 693 | if (tty_register_driver(pts_driver)) |
451 | panic("Couldn't register Unix98 pts driver"); | 694 | panic("Couldn't register Unix98 pts driver"); |
452 | 695 | ||
453 | pty_table[1].data = &ptm_driver->refcount; | ||
454 | register_sysctl_table(pty_root_table); | 696 | register_sysctl_table(pty_root_table); |
697 | |||
698 | /* Now create the /dev/ptmx special device */ | ||
699 | tty_default_fops(&ptmx_fops); | ||
700 | ptmx_fops.open = ptmx_open; | ||
701 | |||
702 | cdev_init(&ptmx_cdev, &ptmx_fops); | ||
703 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || | ||
704 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) | ||
705 | panic("Couldn't register /dev/ptmx driver\n"); | ||
706 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); | ||
455 | } | 707 | } |
708 | |||
456 | #else | 709 | #else |
457 | static inline void unix98_pty_init(void) { } | 710 | static inline void unix98_pty_init(void) { } |
458 | #endif | 711 | #endif |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 19db1eb87c26..8b8f07a7f505 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -405,9 +405,9 @@ static unsigned int stl_baudrates[] = { | |||
405 | 405 | ||
406 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); | 406 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); |
407 | static int stl_brdinit(struct stlbrd *brdp); | 407 | static int stl_brdinit(struct stlbrd *brdp); |
408 | static int stl_getportstats(struct stlport *portp, comstats_t __user *cp); | 408 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); |
409 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); | 409 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); |
410 | static int stl_waitcarrier(struct stlport *portp, struct file *filp); | 410 | static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, struct file *filp); |
411 | 411 | ||
412 | /* | 412 | /* |
413 | * CD1400 uart specific handling functions. | 413 | * CD1400 uart specific handling functions. |
@@ -612,8 +612,9 @@ static struct class *stallion_class; | |||
612 | static void stl_cd_change(struct stlport *portp) | 612 | static void stl_cd_change(struct stlport *portp) |
613 | { | 613 | { |
614 | unsigned int oldsigs = portp->sigs; | 614 | unsigned int oldsigs = portp->sigs; |
615 | struct tty_struct *tty = tty_port_tty_get(&portp->port); | ||
615 | 616 | ||
616 | if (!portp->port.tty) | 617 | if (!tty) |
617 | return; | 618 | return; |
618 | 619 | ||
619 | portp->sigs = stl_getsignals(portp); | 620 | portp->sigs = stl_getsignals(portp); |
@@ -623,7 +624,8 @@ static void stl_cd_change(struct stlport *portp) | |||
623 | 624 | ||
624 | if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) | 625 | if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) |
625 | if (portp->port.flags & ASYNC_CHECK_CD) | 626 | if (portp->port.flags & ASYNC_CHECK_CD) |
626 | tty_hangup(portp->port.tty); | 627 | tty_hangup(tty); |
628 | tty_kref_put(tty); | ||
627 | } | 629 | } |
628 | 630 | ||
629 | /* | 631 | /* |
@@ -734,7 +736,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
734 | * On the first open of the device setup the port hardware, and | 736 | * On the first open of the device setup the port hardware, and |
735 | * initialize the per port data structure. | 737 | * initialize the per port data structure. |
736 | */ | 738 | */ |
737 | portp->port.tty = tty; | 739 | tty_port_tty_set(&portp->port, tty); |
738 | tty->driver_data = portp; | 740 | tty->driver_data = portp; |
739 | portp->port.count++; | 741 | portp->port.count++; |
740 | 742 | ||
@@ -774,7 +776,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
774 | * then also we might have to wait for carrier. | 776 | * then also we might have to wait for carrier. |
775 | */ | 777 | */ |
776 | if (!(filp->f_flags & O_NONBLOCK)) | 778 | if (!(filp->f_flags & O_NONBLOCK)) |
777 | if ((rc = stl_waitcarrier(portp, filp)) != 0) | 779 | if ((rc = stl_waitcarrier(tty, portp, filp)) != 0) |
778 | return rc; | 780 | return rc; |
779 | 781 | ||
780 | portp->port.flags |= ASYNC_NORMAL_ACTIVE; | 782 | portp->port.flags |= ASYNC_NORMAL_ACTIVE; |
@@ -789,7 +791,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
789 | * maybe because if we are clocal then we don't need to wait... | 791 | * maybe because if we are clocal then we don't need to wait... |
790 | */ | 792 | */ |
791 | 793 | ||
792 | static int stl_waitcarrier(struct stlport *portp, struct file *filp) | 794 | static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, |
795 | struct file *filp) | ||
793 | { | 796 | { |
794 | unsigned long flags; | 797 | unsigned long flags; |
795 | int rc, doclocal; | 798 | int rc, doclocal; |
@@ -801,7 +804,7 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp) | |||
801 | 804 | ||
802 | spin_lock_irqsave(&stallion_lock, flags); | 805 | spin_lock_irqsave(&stallion_lock, flags); |
803 | 806 | ||
804 | if (portp->port.tty->termios->c_cflag & CLOCAL) | 807 | if (tty->termios->c_cflag & CLOCAL) |
805 | doclocal++; | 808 | doclocal++; |
806 | 809 | ||
807 | portp->openwaitcnt++; | 810 | portp->openwaitcnt++; |
@@ -846,8 +849,6 @@ static void stl_flushbuffer(struct tty_struct *tty) | |||
846 | 849 | ||
847 | pr_debug("stl_flushbuffer(tty=%p)\n", tty); | 850 | pr_debug("stl_flushbuffer(tty=%p)\n", tty); |
848 | 851 | ||
849 | if (tty == NULL) | ||
850 | return; | ||
851 | portp = tty->driver_data; | 852 | portp = tty->driver_data; |
852 | if (portp == NULL) | 853 | if (portp == NULL) |
853 | return; | 854 | return; |
@@ -865,8 +866,6 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
865 | 866 | ||
866 | pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); | 867 | pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); |
867 | 868 | ||
868 | if (tty == NULL) | ||
869 | return; | ||
870 | portp = tty->driver_data; | 869 | portp = tty->driver_data; |
871 | if (portp == NULL) | 870 | if (portp == NULL) |
872 | return; | 871 | return; |
@@ -949,7 +948,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
949 | tty_ldisc_flush(tty); | 948 | tty_ldisc_flush(tty); |
950 | 949 | ||
951 | tty->closing = 0; | 950 | tty->closing = 0; |
952 | portp->port.tty = NULL; | 951 | tty_port_tty_set(&portp->port, NULL); |
953 | 952 | ||
954 | if (portp->openwaitcnt) { | 953 | if (portp->openwaitcnt) { |
955 | if (portp->close_delay) | 954 | if (portp->close_delay) |
@@ -1033,8 +1032,6 @@ static int stl_putchar(struct tty_struct *tty, unsigned char ch) | |||
1033 | 1032 | ||
1034 | pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); | 1033 | pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); |
1035 | 1034 | ||
1036 | if (tty == NULL) | ||
1037 | return -EINVAL; | ||
1038 | portp = tty->driver_data; | 1035 | portp = tty->driver_data; |
1039 | if (portp == NULL) | 1036 | if (portp == NULL) |
1040 | return -EINVAL; | 1037 | return -EINVAL; |
@@ -1070,8 +1067,6 @@ static void stl_flushchars(struct tty_struct *tty) | |||
1070 | 1067 | ||
1071 | pr_debug("stl_flushchars(tty=%p)\n", tty); | 1068 | pr_debug("stl_flushchars(tty=%p)\n", tty); |
1072 | 1069 | ||
1073 | if (tty == NULL) | ||
1074 | return; | ||
1075 | portp = tty->driver_data; | 1070 | portp = tty->driver_data; |
1076 | if (portp == NULL) | 1071 | if (portp == NULL) |
1077 | return; | 1072 | return; |
@@ -1090,8 +1085,6 @@ static int stl_writeroom(struct tty_struct *tty) | |||
1090 | 1085 | ||
1091 | pr_debug("stl_writeroom(tty=%p)\n", tty); | 1086 | pr_debug("stl_writeroom(tty=%p)\n", tty); |
1092 | 1087 | ||
1093 | if (tty == NULL) | ||
1094 | return 0; | ||
1095 | portp = tty->driver_data; | 1088 | portp = tty->driver_data; |
1096 | if (portp == NULL) | 1089 | if (portp == NULL) |
1097 | return 0; | 1090 | return 0; |
@@ -1122,8 +1115,6 @@ static int stl_charsinbuffer(struct tty_struct *tty) | |||
1122 | 1115 | ||
1123 | pr_debug("stl_charsinbuffer(tty=%p)\n", tty); | 1116 | pr_debug("stl_charsinbuffer(tty=%p)\n", tty); |
1124 | 1117 | ||
1125 | if (tty == NULL) | ||
1126 | return 0; | ||
1127 | portp = tty->driver_data; | 1118 | portp = tty->driver_data; |
1128 | if (portp == NULL) | 1119 | if (portp == NULL) |
1129 | return 0; | 1120 | return 0; |
@@ -1183,8 +1174,9 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) | |||
1183 | * just quietly ignore any requests to change irq, etc. | 1174 | * just quietly ignore any requests to change irq, etc. |
1184 | */ | 1175 | */ |
1185 | 1176 | ||
1186 | static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) | 1177 | static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp) |
1187 | { | 1178 | { |
1179 | struct stlport * portp = tty->driver_data; | ||
1188 | struct serial_struct sio; | 1180 | struct serial_struct sio; |
1189 | 1181 | ||
1190 | pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); | 1182 | pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); |
@@ -1205,7 +1197,7 @@ static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) | |||
1205 | portp->close_delay = sio.close_delay; | 1197 | portp->close_delay = sio.close_delay; |
1206 | portp->closing_wait = sio.closing_wait; | 1198 | portp->closing_wait = sio.closing_wait; |
1207 | portp->custom_divisor = sio.custom_divisor; | 1199 | portp->custom_divisor = sio.custom_divisor; |
1208 | stl_setport(portp, portp->port.tty->termios); | 1200 | stl_setport(portp, tty->termios); |
1209 | return 0; | 1201 | return 0; |
1210 | } | 1202 | } |
1211 | 1203 | ||
@@ -1215,8 +1207,6 @@ static int stl_tiocmget(struct tty_struct *tty, struct file *file) | |||
1215 | { | 1207 | { |
1216 | struct stlport *portp; | 1208 | struct stlport *portp; |
1217 | 1209 | ||
1218 | if (tty == NULL) | ||
1219 | return -ENODEV; | ||
1220 | portp = tty->driver_data; | 1210 | portp = tty->driver_data; |
1221 | if (portp == NULL) | 1211 | if (portp == NULL) |
1222 | return -ENODEV; | 1212 | return -ENODEV; |
@@ -1232,8 +1222,6 @@ static int stl_tiocmset(struct tty_struct *tty, struct file *file, | |||
1232 | struct stlport *portp; | 1222 | struct stlport *portp; |
1233 | int rts = -1, dtr = -1; | 1223 | int rts = -1, dtr = -1; |
1234 | 1224 | ||
1235 | if (tty == NULL) | ||
1236 | return -ENODEV; | ||
1237 | portp = tty->driver_data; | 1225 | portp = tty->driver_data; |
1238 | if (portp == NULL) | 1226 | if (portp == NULL) |
1239 | return -ENODEV; | 1227 | return -ENODEV; |
@@ -1262,8 +1250,6 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd | |||
1262 | pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd, | 1250 | pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd, |
1263 | arg); | 1251 | arg); |
1264 | 1252 | ||
1265 | if (tty == NULL) | ||
1266 | return -ENODEV; | ||
1267 | portp = tty->driver_data; | 1253 | portp = tty->driver_data; |
1268 | if (portp == NULL) | 1254 | if (portp == NULL) |
1269 | return -ENODEV; | 1255 | return -ENODEV; |
@@ -1282,10 +1268,10 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd | |||
1282 | rc = stl_getserial(portp, argp); | 1268 | rc = stl_getserial(portp, argp); |
1283 | break; | 1269 | break; |
1284 | case TIOCSSERIAL: | 1270 | case TIOCSSERIAL: |
1285 | rc = stl_setserial(portp, argp); | 1271 | rc = stl_setserial(tty, argp); |
1286 | break; | 1272 | break; |
1287 | case COM_GETPORTSTATS: | 1273 | case COM_GETPORTSTATS: |
1288 | rc = stl_getportstats(portp, argp); | 1274 | rc = stl_getportstats(tty, portp, argp); |
1289 | break; | 1275 | break; |
1290 | case COM_CLRPORTSTATS: | 1276 | case COM_CLRPORTSTATS: |
1291 | rc = stl_clrportstats(portp, argp); | 1277 | rc = stl_clrportstats(portp, argp); |
@@ -1317,8 +1303,6 @@ static void stl_start(struct tty_struct *tty) | |||
1317 | 1303 | ||
1318 | pr_debug("stl_start(tty=%p)\n", tty); | 1304 | pr_debug("stl_start(tty=%p)\n", tty); |
1319 | 1305 | ||
1320 | if (tty == NULL) | ||
1321 | return; | ||
1322 | portp = tty->driver_data; | 1306 | portp = tty->driver_data; |
1323 | if (portp == NULL) | 1307 | if (portp == NULL) |
1324 | return; | 1308 | return; |
@@ -1334,8 +1318,6 @@ static void stl_settermios(struct tty_struct *tty, struct ktermios *old) | |||
1334 | 1318 | ||
1335 | pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); | 1319 | pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); |
1336 | 1320 | ||
1337 | if (tty == NULL) | ||
1338 | return; | ||
1339 | portp = tty->driver_data; | 1321 | portp = tty->driver_data; |
1340 | if (portp == NULL) | 1322 | if (portp == NULL) |
1341 | return; | 1323 | return; |
@@ -1369,8 +1351,6 @@ static void stl_throttle(struct tty_struct *tty) | |||
1369 | 1351 | ||
1370 | pr_debug("stl_throttle(tty=%p)\n", tty); | 1352 | pr_debug("stl_throttle(tty=%p)\n", tty); |
1371 | 1353 | ||
1372 | if (tty == NULL) | ||
1373 | return; | ||
1374 | portp = tty->driver_data; | 1354 | portp = tty->driver_data; |
1375 | if (portp == NULL) | 1355 | if (portp == NULL) |
1376 | return; | 1356 | return; |
@@ -1389,8 +1369,6 @@ static void stl_unthrottle(struct tty_struct *tty) | |||
1389 | 1369 | ||
1390 | pr_debug("stl_unthrottle(tty=%p)\n", tty); | 1370 | pr_debug("stl_unthrottle(tty=%p)\n", tty); |
1391 | 1371 | ||
1392 | if (tty == NULL) | ||
1393 | return; | ||
1394 | portp = tty->driver_data; | 1372 | portp = tty->driver_data; |
1395 | if (portp == NULL) | 1373 | if (portp == NULL) |
1396 | return; | 1374 | return; |
@@ -1410,8 +1388,6 @@ static void stl_stop(struct tty_struct *tty) | |||
1410 | 1388 | ||
1411 | pr_debug("stl_stop(tty=%p)\n", tty); | 1389 | pr_debug("stl_stop(tty=%p)\n", tty); |
1412 | 1390 | ||
1413 | if (tty == NULL) | ||
1414 | return; | ||
1415 | portp = tty->driver_data; | 1391 | portp = tty->driver_data; |
1416 | if (portp == NULL) | 1392 | if (portp == NULL) |
1417 | return; | 1393 | return; |
@@ -1432,8 +1408,6 @@ static void stl_hangup(struct tty_struct *tty) | |||
1432 | 1408 | ||
1433 | pr_debug("stl_hangup(tty=%p)\n", tty); | 1409 | pr_debug("stl_hangup(tty=%p)\n", tty); |
1434 | 1410 | ||
1435 | if (tty == NULL) | ||
1436 | return; | ||
1437 | portp = tty->driver_data; | 1411 | portp = tty->driver_data; |
1438 | if (portp == NULL) | 1412 | if (portp == NULL) |
1439 | return; | 1413 | return; |
@@ -1452,7 +1426,7 @@ static void stl_hangup(struct tty_struct *tty) | |||
1452 | portp->tx.head = NULL; | 1426 | portp->tx.head = NULL; |
1453 | portp->tx.tail = NULL; | 1427 | portp->tx.tail = NULL; |
1454 | } | 1428 | } |
1455 | portp->port.tty = NULL; | 1429 | tty_port_tty_set(&portp->port, NULL); |
1456 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1430 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1457 | portp->port.count = 0; | 1431 | portp->port.count = 0; |
1458 | wake_up_interruptible(&portp->port.open_wait); | 1432 | wake_up_interruptible(&portp->port.open_wait); |
@@ -1466,8 +1440,6 @@ static int stl_breakctl(struct tty_struct *tty, int state) | |||
1466 | 1440 | ||
1467 | pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); | 1441 | pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); |
1468 | 1442 | ||
1469 | if (tty == NULL) | ||
1470 | return -EINVAL; | ||
1471 | portp = tty->driver_data; | 1443 | portp = tty->driver_data; |
1472 | if (portp == NULL) | 1444 | if (portp == NULL) |
1473 | return -EINVAL; | 1445 | return -EINVAL; |
@@ -1484,8 +1456,6 @@ static void stl_sendxchar(struct tty_struct *tty, char ch) | |||
1484 | 1456 | ||
1485 | pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); | 1457 | pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); |
1486 | 1458 | ||
1487 | if (tty == NULL) | ||
1488 | return; | ||
1489 | portp = tty->driver_data; | 1459 | portp = tty->driver_data; |
1490 | if (portp == NULL) | 1460 | if (portp == NULL) |
1491 | return; | 1461 | return; |
@@ -1805,7 +1775,7 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) | |||
1805 | "(size=%Zd)\n", sizeof(struct stlport)); | 1775 | "(size=%Zd)\n", sizeof(struct stlport)); |
1806 | break; | 1776 | break; |
1807 | } | 1777 | } |
1808 | 1778 | tty_port_init(&portp->port); | |
1809 | portp->magic = STL_PORTMAGIC; | 1779 | portp->magic = STL_PORTMAGIC; |
1810 | portp->portnr = i; | 1780 | portp->portnr = i; |
1811 | portp->brdnr = panelp->brdnr; | 1781 | portp->brdnr = panelp->brdnr; |
@@ -1832,6 +1802,7 @@ static void stl_cleanup_panels(struct stlbrd *brdp) | |||
1832 | struct stlpanel *panelp; | 1802 | struct stlpanel *panelp; |
1833 | struct stlport *portp; | 1803 | struct stlport *portp; |
1834 | unsigned int j, k; | 1804 | unsigned int j, k; |
1805 | struct tty_struct *tty; | ||
1835 | 1806 | ||
1836 | for (j = 0; j < STL_MAXPANELS; j++) { | 1807 | for (j = 0; j < STL_MAXPANELS; j++) { |
1837 | panelp = brdp->panels[j]; | 1808 | panelp = brdp->panels[j]; |
@@ -1841,8 +1812,11 @@ static void stl_cleanup_panels(struct stlbrd *brdp) | |||
1841 | portp = panelp->ports[k]; | 1812 | portp = panelp->ports[k]; |
1842 | if (portp == NULL) | 1813 | if (portp == NULL) |
1843 | continue; | 1814 | continue; |
1844 | if (portp->port.tty != NULL) | 1815 | tty = tty_port_tty_get(&portp->port); |
1845 | stl_hangup(portp->port.tty); | 1816 | if (tty != NULL) { |
1817 | stl_hangup(tty); | ||
1818 | tty_kref_put(tty); | ||
1819 | } | ||
1846 | kfree(portp->tx.buf); | 1820 | kfree(portp->tx.buf); |
1847 | kfree(portp); | 1821 | kfree(portp); |
1848 | } | 1822 | } |
@@ -2498,7 +2472,7 @@ static struct stlport *stl_getport(int brdnr, int panelnr, int portnr) | |||
2498 | * what port to get stats for (used through board control device). | 2472 | * what port to get stats for (used through board control device). |
2499 | */ | 2473 | */ |
2500 | 2474 | ||
2501 | static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) | 2475 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp) |
2502 | { | 2476 | { |
2503 | comstats_t stl_comstats; | 2477 | comstats_t stl_comstats; |
2504 | unsigned char *head, *tail; | 2478 | unsigned char *head, *tail; |
@@ -2525,18 +2499,17 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) | |||
2525 | portp->stats.rxbuffered = 0; | 2499 | portp->stats.rxbuffered = 0; |
2526 | 2500 | ||
2527 | spin_lock_irqsave(&stallion_lock, flags); | 2501 | spin_lock_irqsave(&stallion_lock, flags); |
2528 | if (portp->port.tty != NULL) | 2502 | if (tty != NULL && portp->port.tty == tty) { |
2529 | if (portp->port.tty->driver_data == portp) { | 2503 | portp->stats.ttystate = tty->flags; |
2530 | portp->stats.ttystate = portp->port.tty->flags; | 2504 | /* No longer available as a statistic */ |
2531 | /* No longer available as a statistic */ | 2505 | portp->stats.rxbuffered = 1; /*tty->flip.count; */ |
2532 | portp->stats.rxbuffered = 1; /*portp->port.tty->flip.count; */ | 2506 | if (tty->termios != NULL) { |
2533 | if (portp->port.tty->termios != NULL) { | 2507 | portp->stats.cflags = tty->termios->c_cflag; |
2534 | portp->stats.cflags = portp->port.tty->termios->c_cflag; | 2508 | portp->stats.iflags = tty->termios->c_iflag; |
2535 | portp->stats.iflags = portp->port.tty->termios->c_iflag; | 2509 | portp->stats.oflags = tty->termios->c_oflag; |
2536 | portp->stats.oflags = portp->port.tty->termios->c_oflag; | 2510 | portp->stats.lflags = tty->termios->c_lflag; |
2537 | portp->stats.lflags = portp->port.tty->termios->c_lflag; | ||
2538 | } | ||
2539 | } | 2511 | } |
2512 | } | ||
2540 | spin_unlock_irqrestore(&stallion_lock, flags); | 2513 | spin_unlock_irqrestore(&stallion_lock, flags); |
2541 | 2514 | ||
2542 | head = portp->tx.head; | 2515 | head = portp->tx.head; |
@@ -2640,7 +2613,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns | |||
2640 | 2613 | ||
2641 | switch (cmd) { | 2614 | switch (cmd) { |
2642 | case COM_GETPORTSTATS: | 2615 | case COM_GETPORTSTATS: |
2643 | rc = stl_getportstats(NULL, argp); | 2616 | rc = stl_getportstats(NULL, NULL, argp); |
2644 | break; | 2617 | break; |
2645 | case COM_CLRPORTSTATS: | 2618 | case COM_CLRPORTSTATS: |
2646 | rc = stl_clrportstats(NULL, argp); | 2619 | rc = stl_clrportstats(NULL, argp); |
@@ -3243,7 +3216,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state) | |||
3243 | 3216 | ||
3244 | if (portp == NULL) | 3217 | if (portp == NULL) |
3245 | return; | 3218 | return; |
3246 | tty = portp->port.tty; | 3219 | tty = tty_port_tty_get(&portp->port); |
3247 | if (tty == NULL) | 3220 | if (tty == NULL) |
3248 | return; | 3221 | return; |
3249 | 3222 | ||
@@ -3288,6 +3261,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state) | |||
3288 | 3261 | ||
3289 | BRDDISABLE(portp->brdnr); | 3262 | BRDDISABLE(portp->brdnr); |
3290 | spin_unlock_irqrestore(&brd_lock, flags); | 3263 | spin_unlock_irqrestore(&brd_lock, flags); |
3264 | tty_kref_put(tty); | ||
3291 | } | 3265 | } |
3292 | 3266 | ||
3293 | /*****************************************************************************/ | 3267 | /*****************************************************************************/ |
@@ -3305,7 +3279,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state) | |||
3305 | 3279 | ||
3306 | if (portp == NULL) | 3280 | if (portp == NULL) |
3307 | return; | 3281 | return; |
3308 | tty = portp->port.tty; | 3282 | tty = tty_port_tty_get(&portp->port); |
3309 | if (tty == NULL) | 3283 | if (tty == NULL) |
3310 | return; | 3284 | return; |
3311 | 3285 | ||
@@ -3325,6 +3299,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state) | |||
3325 | } | 3299 | } |
3326 | BRDDISABLE(portp->brdnr); | 3300 | BRDDISABLE(portp->brdnr); |
3327 | spin_unlock_irqrestore(&brd_lock, flags); | 3301 | spin_unlock_irqrestore(&brd_lock, flags); |
3302 | tty_kref_put(tty); | ||
3328 | } | 3303 | } |
3329 | 3304 | ||
3330 | /*****************************************************************************/ | 3305 | /*****************************************************************************/ |
@@ -3478,6 +3453,7 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) | |||
3478 | int len, stlen; | 3453 | int len, stlen; |
3479 | char *head, *tail; | 3454 | char *head, *tail; |
3480 | unsigned char ioack, srer; | 3455 | unsigned char ioack, srer; |
3456 | struct tty_struct *tty; | ||
3481 | 3457 | ||
3482 | pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); | 3458 | pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); |
3483 | 3459 | ||
@@ -3504,8 +3480,11 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) | |||
3504 | if ((len == 0) || ((len < STL_TXBUFLOW) && | 3480 | if ((len == 0) || ((len < STL_TXBUFLOW) && |
3505 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { | 3481 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { |
3506 | set_bit(ASYI_TXLOW, &portp->istate); | 3482 | set_bit(ASYI_TXLOW, &portp->istate); |
3507 | if (portp->port.tty) | 3483 | tty = tty_port_tty_get(&portp->port); |
3508 | tty_wakeup(portp->port.tty); | 3484 | if (tty) { |
3485 | tty_wakeup(tty); | ||
3486 | tty_kref_put(tty); | ||
3487 | } | ||
3509 | } | 3488 | } |
3510 | 3489 | ||
3511 | if (len == 0) { | 3490 | if (len == 0) { |
@@ -3569,7 +3548,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) | |||
3569 | return; | 3548 | return; |
3570 | } | 3549 | } |
3571 | portp = panelp->ports[(ioack >> 3)]; | 3550 | portp = panelp->ports[(ioack >> 3)]; |
3572 | tty = portp->port.tty; | 3551 | tty = tty_port_tty_get(&portp->port); |
3573 | 3552 | ||
3574 | if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { | 3553 | if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { |
3575 | outb((RDCR + portp->uartaddr), ioaddr); | 3554 | outb((RDCR + portp->uartaddr), ioaddr); |
@@ -3633,10 +3612,12 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) | |||
3633 | } | 3612 | } |
3634 | } else { | 3613 | } else { |
3635 | printk("STALLION: bad RX interrupt ack value=%x\n", ioack); | 3614 | printk("STALLION: bad RX interrupt ack value=%x\n", ioack); |
3615 | tty_kref_put(tty); | ||
3636 | return; | 3616 | return; |
3637 | } | 3617 | } |
3638 | 3618 | ||
3639 | stl_rxalldone: | 3619 | stl_rxalldone: |
3620 | tty_kref_put(tty); | ||
3640 | outb((EOSRR + portp->uartaddr), ioaddr); | 3621 | outb((EOSRR + portp->uartaddr), ioaddr); |
3641 | outb(0, (ioaddr + EREG_DATA)); | 3622 | outb(0, (ioaddr + EREG_DATA)); |
3642 | } | 3623 | } |
@@ -4175,7 +4156,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state) | |||
4175 | 4156 | ||
4176 | if (portp == NULL) | 4157 | if (portp == NULL) |
4177 | return; | 4158 | return; |
4178 | tty = portp->port.tty; | 4159 | tty = tty_port_tty_get(&portp->port); |
4179 | if (tty == NULL) | 4160 | if (tty == NULL) |
4180 | return; | 4161 | return; |
4181 | 4162 | ||
@@ -4226,6 +4207,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state) | |||
4226 | 4207 | ||
4227 | BRDDISABLE(portp->brdnr); | 4208 | BRDDISABLE(portp->brdnr); |
4228 | spin_unlock_irqrestore(&brd_lock, flags); | 4209 | spin_unlock_irqrestore(&brd_lock, flags); |
4210 | tty_kref_put(tty); | ||
4229 | } | 4211 | } |
4230 | 4212 | ||
4231 | /*****************************************************************************/ | 4213 | /*****************************************************************************/ |
@@ -4244,7 +4226,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state) | |||
4244 | 4226 | ||
4245 | if (portp == NULL) | 4227 | if (portp == NULL) |
4246 | return; | 4228 | return; |
4247 | tty = portp->port.tty; | 4229 | tty = tty_port_tty_get(&portp->port); |
4248 | if (tty == NULL) | 4230 | if (tty == NULL) |
4249 | return; | 4231 | return; |
4250 | 4232 | ||
@@ -4269,6 +4251,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state) | |||
4269 | } | 4251 | } |
4270 | BRDDISABLE(portp->brdnr); | 4252 | BRDDISABLE(portp->brdnr); |
4271 | spin_unlock_irqrestore(&brd_lock, flags); | 4253 | spin_unlock_irqrestore(&brd_lock, flags); |
4254 | tty_kref_put(tty); | ||
4272 | } | 4255 | } |
4273 | 4256 | ||
4274 | /*****************************************************************************/ | 4257 | /*****************************************************************************/ |
@@ -4408,6 +4391,7 @@ static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase) | |||
4408 | 4391 | ||
4409 | static void stl_sc26198txisr(struct stlport *portp) | 4392 | static void stl_sc26198txisr(struct stlport *portp) |
4410 | { | 4393 | { |
4394 | struct tty_struct *tty; | ||
4411 | unsigned int ioaddr; | 4395 | unsigned int ioaddr; |
4412 | unsigned char mr0; | 4396 | unsigned char mr0; |
4413 | int len, stlen; | 4397 | int len, stlen; |
@@ -4422,8 +4406,11 @@ static void stl_sc26198txisr(struct stlport *portp) | |||
4422 | if ((len == 0) || ((len < STL_TXBUFLOW) && | 4406 | if ((len == 0) || ((len < STL_TXBUFLOW) && |
4423 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { | 4407 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { |
4424 | set_bit(ASYI_TXLOW, &portp->istate); | 4408 | set_bit(ASYI_TXLOW, &portp->istate); |
4425 | if (portp->port.tty) | 4409 | tty = tty_port_tty_get(&portp->port); |
4426 | tty_wakeup(portp->port.tty); | 4410 | if (tty) { |
4411 | tty_wakeup(tty); | ||
4412 | tty_kref_put(tty); | ||
4413 | } | ||
4427 | } | 4414 | } |
4428 | 4415 | ||
4429 | if (len == 0) { | 4416 | if (len == 0) { |
@@ -4476,7 +4463,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) | |||
4476 | 4463 | ||
4477 | pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); | 4464 | pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); |
4478 | 4465 | ||
4479 | tty = portp->port.tty; | 4466 | tty = tty_port_tty_get(&portp->port); |
4480 | ioaddr = portp->ioaddr; | 4467 | ioaddr = portp->ioaddr; |
4481 | outb(GIBCR, (ioaddr + XP_ADDR)); | 4468 | outb(GIBCR, (ioaddr + XP_ADDR)); |
4482 | len = inb(ioaddr + XP_DATA) + 1; | 4469 | len = inb(ioaddr + XP_DATA) + 1; |
@@ -4515,6 +4502,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) | |||
4515 | stl_sc26198txunflow(portp, tty); | 4502 | stl_sc26198txunflow(portp, tty); |
4516 | } | 4503 | } |
4517 | } | 4504 | } |
4505 | tty_kref_put(tty); | ||
4518 | } | 4506 | } |
4519 | 4507 | ||
4520 | /*****************************************************************************/ | 4508 | /*****************************************************************************/ |
@@ -4528,7 +4516,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char | |||
4528 | struct tty_struct *tty; | 4516 | struct tty_struct *tty; |
4529 | unsigned int ioaddr; | 4517 | unsigned int ioaddr; |
4530 | 4518 | ||
4531 | tty = portp->port.tty; | 4519 | tty = tty_port_tty_get(&portp->port); |
4532 | ioaddr = portp->ioaddr; | 4520 | ioaddr = portp->ioaddr; |
4533 | 4521 | ||
4534 | if (status & SR_RXPARITY) | 4522 | if (status & SR_RXPARITY) |
@@ -4566,6 +4554,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char | |||
4566 | if (status == 0) | 4554 | if (status == 0) |
4567 | portp->stats.rxtotal++; | 4555 | portp->stats.rxtotal++; |
4568 | } | 4556 | } |
4557 | tty_kref_put(tty); | ||
4569 | } | 4558 | } |
4570 | 4559 | ||
4571 | /*****************************************************************************/ | 4560 | /*****************************************************************************/ |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index c385206f9db5..5b8d7a1aa3e6 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -2504,7 +2504,7 @@ static void __devexit sx_remove_card(struct sx_board *board, | |||
2504 | del_timer(&board->timer); | 2504 | del_timer(&board->timer); |
2505 | if (pdev) { | 2505 | if (pdev) { |
2506 | #ifdef CONFIG_PCI | 2506 | #ifdef CONFIG_PCI |
2507 | pci_iounmap(pdev, board->base); | 2507 | pci_iounmap(pdev, board->base2); |
2508 | pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); | 2508 | pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); |
2509 | #endif | 2509 | #endif |
2510 | } else { | 2510 | } else { |
@@ -2703,7 +2703,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev, | |||
2703 | 2703 | ||
2704 | return 0; | 2704 | return 0; |
2705 | err_unmap: | 2705 | err_unmap: |
2706 | pci_iounmap(pdev, board->base); | 2706 | pci_iounmap(pdev, board->base2); |
2707 | err_reg: | 2707 | err_reg: |
2708 | pci_release_region(pdev, reg); | 2708 | pci_release_region(pdev, reg); |
2709 | err_flag: | 2709 | err_flag: |
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index 3582f43345a8..5787249934c8 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c | |||
@@ -93,7 +93,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, | |||
93 | get_task_comm(name, tsk); | 93 | get_task_comm(name, tsk); |
94 | audit_log_untrustedstring(ab, name); | 94 | audit_log_untrustedstring(ab, name); |
95 | audit_log_format(ab, " data="); | 95 | audit_log_format(ab, " data="); |
96 | audit_log_n_untrustedstring(ab, buf->data, buf->valid); | 96 | audit_log_n_hex(ab, buf->data, buf->valid); |
97 | audit_log_end(ab); | 97 | audit_log_end(ab); |
98 | } | 98 | } |
99 | buf->valid = 0; | 99 | buf->valid = 0; |
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c new file mode 100644 index 000000000000..810ee25d66a4 --- /dev/null +++ b/drivers/char/tty_buffer.c | |||
@@ -0,0 +1,511 @@ | |||
1 | /* | ||
2 | * Tty buffer allocation management | ||
3 | */ | ||
4 | |||
5 | #include <linux/types.h> | ||
6 | #include <linux/errno.h> | ||
7 | #include <linux/tty.h> | ||
8 | #include <linux/tty_driver.h> | ||
9 | #include <linux/tty_flip.h> | ||
10 | #include <linux/timer.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/wait.h> | ||
16 | #include <linux/bitops.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/module.h> | ||
19 | |||
20 | /** | ||
21 | * tty_buffer_free_all - free buffers used by a tty | ||
22 | * @tty: tty to free from | ||
23 | * | ||
24 | * Remove all the buffers pending on a tty whether queued with data | ||
25 | * or in the free ring. Must be called when the tty is no longer in use | ||
26 | * | ||
27 | * Locking: none | ||
28 | */ | ||
29 | |||
30 | void tty_buffer_free_all(struct tty_struct *tty) | ||
31 | { | ||
32 | struct tty_buffer *thead; | ||
33 | while ((thead = tty->buf.head) != NULL) { | ||
34 | tty->buf.head = thead->next; | ||
35 | kfree(thead); | ||
36 | } | ||
37 | while ((thead = tty->buf.free) != NULL) { | ||
38 | tty->buf.free = thead->next; | ||
39 | kfree(thead); | ||
40 | } | ||
41 | tty->buf.tail = NULL; | ||
42 | tty->buf.memory_used = 0; | ||
43 | } | ||
44 | |||
45 | /** | ||
46 | * tty_buffer_alloc - allocate a tty buffer | ||
47 | * @tty: tty device | ||
48 | * @size: desired size (characters) | ||
49 | * | ||
50 | * Allocate a new tty buffer to hold the desired number of characters. | ||
51 | * Return NULL if out of memory or the allocation would exceed the | ||
52 | * per device queue | ||
53 | * | ||
54 | * Locking: Caller must hold tty->buf.lock | ||
55 | */ | ||
56 | |||
57 | static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) | ||
58 | { | ||
59 | struct tty_buffer *p; | ||
60 | |||
61 | if (tty->buf.memory_used + size > 65536) | ||
62 | return NULL; | ||
63 | p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | ||
64 | if (p == NULL) | ||
65 | return NULL; | ||
66 | p->used = 0; | ||
67 | p->size = size; | ||
68 | p->next = NULL; | ||
69 | p->commit = 0; | ||
70 | p->read = 0; | ||
71 | p->char_buf_ptr = (char *)(p->data); | ||
72 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | ||
73 | tty->buf.memory_used += size; | ||
74 | return p; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * tty_buffer_free - free a tty buffer | ||
79 | * @tty: tty owning the buffer | ||
80 | * @b: the buffer to free | ||
81 | * | ||
82 | * Free a tty buffer, or add it to the free list according to our | ||
83 | * internal strategy | ||
84 | * | ||
85 | * Locking: Caller must hold tty->buf.lock | ||
86 | */ | ||
87 | |||
88 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | ||
89 | { | ||
90 | /* Dumb strategy for now - should keep some stats */ | ||
91 | tty->buf.memory_used -= b->size; | ||
92 | WARN_ON(tty->buf.memory_used < 0); | ||
93 | |||
94 | if (b->size >= 512) | ||
95 | kfree(b); | ||
96 | else { | ||
97 | b->next = tty->buf.free; | ||
98 | tty->buf.free = b; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * __tty_buffer_flush - flush full tty buffers | ||
104 | * @tty: tty to flush | ||
105 | * | ||
106 | * flush all the buffers containing receive data. Caller must | ||
107 | * hold the buffer lock and must have ensured no parallel flush to | ||
108 | * ldisc is running. | ||
109 | * | ||
110 | * Locking: Caller must hold tty->buf.lock | ||
111 | */ | ||
112 | |||
113 | static void __tty_buffer_flush(struct tty_struct *tty) | ||
114 | { | ||
115 | struct tty_buffer *thead; | ||
116 | |||
117 | while ((thead = tty->buf.head) != NULL) { | ||
118 | tty->buf.head = thead->next; | ||
119 | tty_buffer_free(tty, thead); | ||
120 | } | ||
121 | tty->buf.tail = NULL; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * tty_buffer_flush - flush full tty buffers | ||
126 | * @tty: tty to flush | ||
127 | * | ||
128 | * flush all the buffers containing receive data. If the buffer is | ||
129 | * being processed by flush_to_ldisc then we defer the processing | ||
130 | * to that function | ||
131 | * | ||
132 | * Locking: none | ||
133 | */ | ||
134 | |||
135 | void tty_buffer_flush(struct tty_struct *tty) | ||
136 | { | ||
137 | unsigned long flags; | ||
138 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
139 | |||
140 | /* If the data is being pushed to the tty layer then we can't | ||
141 | process it here. Instead set a flag and the flush_to_ldisc | ||
142 | path will process the flush request before it exits */ | ||
143 | if (test_bit(TTY_FLUSHING, &tty->flags)) { | ||
144 | set_bit(TTY_FLUSHPENDING, &tty->flags); | ||
145 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
146 | wait_event(tty->read_wait, | ||
147 | test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); | ||
148 | return; | ||
149 | } else | ||
150 | __tty_buffer_flush(tty); | ||
151 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * tty_buffer_find - find a free tty buffer | ||
156 | * @tty: tty owning the buffer | ||
157 | * @size: characters wanted | ||
158 | * | ||
159 | * Locate an existing suitable tty buffer or if we are lacking one then | ||
160 | * allocate a new one. We round our buffers off in 256 character chunks | ||
161 | * to get better allocation behaviour. | ||
162 | * | ||
163 | * Locking: Caller must hold tty->buf.lock | ||
164 | */ | ||
165 | |||
166 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | ||
167 | { | ||
168 | struct tty_buffer **tbh = &tty->buf.free; | ||
169 | while ((*tbh) != NULL) { | ||
170 | struct tty_buffer *t = *tbh; | ||
171 | if (t->size >= size) { | ||
172 | *tbh = t->next; | ||
173 | t->next = NULL; | ||
174 | t->used = 0; | ||
175 | t->commit = 0; | ||
176 | t->read = 0; | ||
177 | tty->buf.memory_used += t->size; | ||
178 | return t; | ||
179 | } | ||
180 | tbh = &((*tbh)->next); | ||
181 | } | ||
182 | /* Round the buffer size out */ | ||
183 | size = (size + 0xFF) & ~0xFF; | ||
184 | return tty_buffer_alloc(tty, size); | ||
185 | /* Should possibly check if this fails for the largest buffer we | ||
186 | have queued and recycle that ? */ | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * tty_buffer_request_room - grow tty buffer if needed | ||
191 | * @tty: tty structure | ||
192 | * @size: size desired | ||
193 | * | ||
194 | * Make at least size bytes of linear space available for the tty | ||
195 | * buffer. If we fail return the size we managed to find. | ||
196 | * | ||
197 | * Locking: Takes tty->buf.lock | ||
198 | */ | ||
199 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | ||
200 | { | ||
201 | struct tty_buffer *b, *n; | ||
202 | int left; | ||
203 | unsigned long flags; | ||
204 | |||
205 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
206 | |||
207 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | ||
208 | remove this conditional if its worth it. This would be invisible | ||
209 | to the callers */ | ||
210 | if ((b = tty->buf.tail) != NULL) | ||
211 | left = b->size - b->used; | ||
212 | else | ||
213 | left = 0; | ||
214 | |||
215 | if (left < size) { | ||
216 | /* This is the slow path - looking for new buffers to use */ | ||
217 | if ((n = tty_buffer_find(tty, size)) != NULL) { | ||
218 | if (b != NULL) { | ||
219 | b->next = n; | ||
220 | b->commit = b->used; | ||
221 | } else | ||
222 | tty->buf.head = n; | ||
223 | tty->buf.tail = n; | ||
224 | } else | ||
225 | size = left; | ||
226 | } | ||
227 | |||
228 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
229 | return size; | ||
230 | } | ||
231 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | ||
232 | |||
233 | /** | ||
234 | * tty_insert_flip_string - Add characters to the tty buffer | ||
235 | * @tty: tty structure | ||
236 | * @chars: characters | ||
237 | * @size: size | ||
238 | * | ||
239 | * Queue a series of bytes to the tty buffering. All the characters | ||
240 | * passed are marked as without error. Returns the number added. | ||
241 | * | ||
242 | * Locking: Called functions may take tty->buf.lock | ||
243 | */ | ||
244 | |||
245 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | ||
246 | size_t size) | ||
247 | { | ||
248 | int copied = 0; | ||
249 | do { | ||
250 | int space = tty_buffer_request_room(tty, size - copied); | ||
251 | struct tty_buffer *tb = tty->buf.tail; | ||
252 | /* If there is no space then tb may be NULL */ | ||
253 | if (unlikely(space == 0)) | ||
254 | break; | ||
255 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
256 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
257 | tb->used += space; | ||
258 | copied += space; | ||
259 | chars += space; | ||
260 | /* There is a small chance that we need to split the data over | ||
261 | several buffers. If this is the case we must loop */ | ||
262 | } while (unlikely(size > copied)); | ||
263 | return copied; | ||
264 | } | ||
265 | EXPORT_SYMBOL(tty_insert_flip_string); | ||
266 | |||
267 | /** | ||
268 | * tty_insert_flip_string_flags - Add characters to the tty buffer | ||
269 | * @tty: tty structure | ||
270 | * @chars: characters | ||
271 | * @flags: flag bytes | ||
272 | * @size: size | ||
273 | * | ||
274 | * Queue a series of bytes to the tty buffering. For each character | ||
275 | * the flags array indicates the status of the character. Returns the | ||
276 | * number added. | ||
277 | * | ||
278 | * Locking: Called functions may take tty->buf.lock | ||
279 | */ | ||
280 | |||
281 | int tty_insert_flip_string_flags(struct tty_struct *tty, | ||
282 | const unsigned char *chars, const char *flags, size_t size) | ||
283 | { | ||
284 | int copied = 0; | ||
285 | do { | ||
286 | int space = tty_buffer_request_room(tty, size - copied); | ||
287 | struct tty_buffer *tb = tty->buf.tail; | ||
288 | /* If there is no space then tb may be NULL */ | ||
289 | if (unlikely(space == 0)) | ||
290 | break; | ||
291 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
292 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | ||
293 | tb->used += space; | ||
294 | copied += space; | ||
295 | chars += space; | ||
296 | flags += space; | ||
297 | /* There is a small chance that we need to split the data over | ||
298 | several buffers. If this is the case we must loop */ | ||
299 | } while (unlikely(size > copied)); | ||
300 | return copied; | ||
301 | } | ||
302 | EXPORT_SYMBOL(tty_insert_flip_string_flags); | ||
303 | |||
304 | /** | ||
305 | * tty_schedule_flip - push characters to ldisc | ||
306 | * @tty: tty to push from | ||
307 | * | ||
308 | * Takes any pending buffers and transfers their ownership to the | ||
309 | * ldisc side of the queue. It then schedules those characters for | ||
310 | * processing by the line discipline. | ||
311 | * | ||
312 | * Locking: Takes tty->buf.lock | ||
313 | */ | ||
314 | |||
315 | void tty_schedule_flip(struct tty_struct *tty) | ||
316 | { | ||
317 | unsigned long flags; | ||
318 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
319 | if (tty->buf.tail != NULL) | ||
320 | tty->buf.tail->commit = tty->buf.tail->used; | ||
321 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
322 | schedule_delayed_work(&tty->buf.work, 1); | ||
323 | } | ||
324 | EXPORT_SYMBOL(tty_schedule_flip); | ||
325 | |||
326 | /** | ||
327 | * tty_prepare_flip_string - make room for characters | ||
328 | * @tty: tty | ||
329 | * @chars: return pointer for character write area | ||
330 | * @size: desired size | ||
331 | * | ||
332 | * Prepare a block of space in the buffer for data. Returns the length | ||
333 | * available and buffer pointer to the space which is now allocated and | ||
334 | * accounted for as ready for normal characters. This is used for drivers | ||
335 | * that need their own block copy routines into the buffer. There is no | ||
336 | * guarantee the buffer is a DMA target! | ||
337 | * | ||
338 | * Locking: May call functions taking tty->buf.lock | ||
339 | */ | ||
340 | |||
341 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, | ||
342 | size_t size) | ||
343 | { | ||
344 | int space = tty_buffer_request_room(tty, size); | ||
345 | if (likely(space)) { | ||
346 | struct tty_buffer *tb = tty->buf.tail; | ||
347 | *chars = tb->char_buf_ptr + tb->used; | ||
348 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
349 | tb->used += space; | ||
350 | } | ||
351 | return space; | ||
352 | } | ||
353 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | ||
354 | |||
355 | /** | ||
356 | * tty_prepare_flip_string_flags - make room for characters | ||
357 | * @tty: tty | ||
358 | * @chars: return pointer for character write area | ||
359 | * @flags: return pointer for status flag write area | ||
360 | * @size: desired size | ||
361 | * | ||
362 | * Prepare a block of space in the buffer for data. Returns the length | ||
363 | * available and buffer pointer to the space which is now allocated and | ||
364 | * accounted for as ready for characters. This is used for drivers | ||
365 | * that need their own block copy routines into the buffer. There is no | ||
366 | * guarantee the buffer is a DMA target! | ||
367 | * | ||
368 | * Locking: May call functions taking tty->buf.lock | ||
369 | */ | ||
370 | |||
371 | int tty_prepare_flip_string_flags(struct tty_struct *tty, | ||
372 | unsigned char **chars, char **flags, size_t size) | ||
373 | { | ||
374 | int space = tty_buffer_request_room(tty, size); | ||
375 | if (likely(space)) { | ||
376 | struct tty_buffer *tb = tty->buf.tail; | ||
377 | *chars = tb->char_buf_ptr + tb->used; | ||
378 | *flags = tb->flag_buf_ptr + tb->used; | ||
379 | tb->used += space; | ||
380 | } | ||
381 | return space; | ||
382 | } | ||
383 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | ||
384 | |||
385 | |||
386 | |||
387 | /** | ||
388 | * flush_to_ldisc | ||
389 | * @work: tty structure passed from work queue. | ||
390 | * | ||
391 | * This routine is called out of the software interrupt to flush data | ||
392 | * from the buffer chain to the line discipline. | ||
393 | * | ||
394 | * Locking: holds tty->buf.lock to guard buffer list. Drops the lock | ||
395 | * while invoking the line discipline receive_buf method. The | ||
396 | * receive_buf method is single threaded for each tty instance. | ||
397 | */ | ||
398 | |||
399 | static void flush_to_ldisc(struct work_struct *work) | ||
400 | { | ||
401 | struct tty_struct *tty = | ||
402 | container_of(work, struct tty_struct, buf.work.work); | ||
403 | unsigned long flags; | ||
404 | struct tty_ldisc *disc; | ||
405 | struct tty_buffer *tbuf, *head; | ||
406 | char *char_buf; | ||
407 | unsigned char *flag_buf; | ||
408 | |||
409 | disc = tty_ldisc_ref(tty); | ||
410 | if (disc == NULL) /* !TTY_LDISC */ | ||
411 | return; | ||
412 | |||
413 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
414 | /* So we know a flush is running */ | ||
415 | set_bit(TTY_FLUSHING, &tty->flags); | ||
416 | head = tty->buf.head; | ||
417 | if (head != NULL) { | ||
418 | tty->buf.head = NULL; | ||
419 | for (;;) { | ||
420 | int count = head->commit - head->read; | ||
421 | if (!count) { | ||
422 | if (head->next == NULL) | ||
423 | break; | ||
424 | tbuf = head; | ||
425 | head = head->next; | ||
426 | tty_buffer_free(tty, tbuf); | ||
427 | continue; | ||
428 | } | ||
429 | /* Ldisc or user is trying to flush the buffers | ||
430 | we are feeding to the ldisc, stop feeding the | ||
431 | line discipline as we want to empty the queue */ | ||
432 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) | ||
433 | break; | ||
434 | if (!tty->receive_room) { | ||
435 | schedule_delayed_work(&tty->buf.work, 1); | ||
436 | break; | ||
437 | } | ||
438 | if (count > tty->receive_room) | ||
439 | count = tty->receive_room; | ||
440 | char_buf = head->char_buf_ptr + head->read; | ||
441 | flag_buf = head->flag_buf_ptr + head->read; | ||
442 | head->read += count; | ||
443 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
444 | disc->ops->receive_buf(tty, char_buf, | ||
445 | flag_buf, count); | ||
446 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
447 | } | ||
448 | /* Restore the queue head */ | ||
449 | tty->buf.head = head; | ||
450 | } | ||
451 | /* We may have a deferred request to flush the input buffer, | ||
452 | if so pull the chain under the lock and empty the queue */ | ||
453 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { | ||
454 | __tty_buffer_flush(tty); | ||
455 | clear_bit(TTY_FLUSHPENDING, &tty->flags); | ||
456 | wake_up(&tty->read_wait); | ||
457 | } | ||
458 | clear_bit(TTY_FLUSHING, &tty->flags); | ||
459 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
460 | |||
461 | tty_ldisc_deref(disc); | ||
462 | } | ||
463 | |||
464 | /** | ||
465 | * tty_flip_buffer_push - terminal | ||
466 | * @tty: tty to push | ||
467 | * | ||
468 | * Queue a push of the terminal flip buffers to the line discipline. This | ||
469 | * function must not be called from IRQ context if tty->low_latency is set. | ||
470 | * | ||
471 | * In the event of the queue being busy for flipping the work will be | ||
472 | * held off and retried later. | ||
473 | * | ||
474 | * Locking: tty buffer lock. Driver locks in low latency mode. | ||
475 | */ | ||
476 | |||
477 | void tty_flip_buffer_push(struct tty_struct *tty) | ||
478 | { | ||
479 | unsigned long flags; | ||
480 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
481 | if (tty->buf.tail != NULL) | ||
482 | tty->buf.tail->commit = tty->buf.tail->used; | ||
483 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
484 | |||
485 | if (tty->low_latency) | ||
486 | flush_to_ldisc(&tty->buf.work.work); | ||
487 | else | ||
488 | schedule_delayed_work(&tty->buf.work, 1); | ||
489 | } | ||
490 | EXPORT_SYMBOL(tty_flip_buffer_push); | ||
491 | |||
492 | /** | ||
493 | * tty_buffer_init - prepare a tty buffer structure | ||
494 | * @tty: tty to initialise | ||
495 | * | ||
496 | * Set up the initial state of the buffer management for a tty device. | ||
497 | * Must be called before the other tty buffer functions are used. | ||
498 | * | ||
499 | * Locking: none | ||
500 | */ | ||
501 | |||
502 | void tty_buffer_init(struct tty_struct *tty) | ||
503 | { | ||
504 | spin_lock_init(&tty->buf.lock); | ||
505 | tty->buf.head = NULL; | ||
506 | tty->buf.tail = NULL; | ||
507 | tty->buf.free = NULL; | ||
508 | tty->buf.memory_used = 0; | ||
509 | INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); | ||
510 | } | ||
511 | |||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index e4dce8709541..7053d6333692 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -49,7 +49,7 @@ | |||
49 | * implement CONFIG_VT and generalize console device interface. | 49 | * implement CONFIG_VT and generalize console device interface. |
50 | * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97 | 50 | * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97 |
51 | * | 51 | * |
52 | * Rewrote init_dev and release_dev to eliminate races. | 52 | * Rewrote tty_init_dev and tty_release_dev to eliminate races. |
53 | * -- Bill Hawes <whawes@star.net>, June 97 | 53 | * -- Bill Hawes <whawes@star.net>, June 97 |
54 | * | 54 | * |
55 | * Added devfs support. | 55 | * Added devfs support. |
@@ -136,13 +136,6 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ | |||
136 | DEFINE_MUTEX(tty_mutex); | 136 | DEFINE_MUTEX(tty_mutex); |
137 | EXPORT_SYMBOL(tty_mutex); | 137 | EXPORT_SYMBOL(tty_mutex); |
138 | 138 | ||
139 | #ifdef CONFIG_UNIX98_PTYS | ||
140 | extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ | ||
141 | static int ptmx_open(struct inode *, struct file *); | ||
142 | #endif | ||
143 | |||
144 | static void initialize_tty_struct(struct tty_struct *tty); | ||
145 | |||
146 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 139 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
147 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); | 140 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
148 | ssize_t redirected_tty_write(struct file *, const char __user *, | 141 | ssize_t redirected_tty_write(struct file *, const char __user *, |
@@ -171,13 +164,11 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | |||
171 | * Locking: none | 164 | * Locking: none |
172 | */ | 165 | */ |
173 | 166 | ||
174 | static struct tty_struct *alloc_tty_struct(void) | 167 | struct tty_struct *alloc_tty_struct(void) |
175 | { | 168 | { |
176 | return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); | 169 | return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); |
177 | } | 170 | } |
178 | 171 | ||
179 | static void tty_buffer_free_all(struct tty_struct *); | ||
180 | |||
181 | /** | 172 | /** |
182 | * free_tty_struct - free a disused tty | 173 | * free_tty_struct - free a disused tty |
183 | * @tty: tty struct to free | 174 | * @tty: tty struct to free |
@@ -187,7 +178,7 @@ static void tty_buffer_free_all(struct tty_struct *); | |||
187 | * Locking: none. Must be called after tty is definitely unused | 178 | * Locking: none. Must be called after tty is definitely unused |
188 | */ | 179 | */ |
189 | 180 | ||
190 | static inline void free_tty_struct(struct tty_struct *tty) | 181 | void free_tty_struct(struct tty_struct *tty) |
191 | { | 182 | { |
192 | kfree(tty->write_buf); | 183 | kfree(tty->write_buf); |
193 | tty_buffer_free_all(tty); | 184 | tty_buffer_free_all(tty); |
@@ -263,398 +254,6 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
263 | return 0; | 254 | return 0; |
264 | } | 255 | } |
265 | 256 | ||
266 | /* | ||
267 | * Tty buffer allocation management | ||
268 | */ | ||
269 | |||
270 | /** | ||
271 | * tty_buffer_free_all - free buffers used by a tty | ||
272 | * @tty: tty to free from | ||
273 | * | ||
274 | * Remove all the buffers pending on a tty whether queued with data | ||
275 | * or in the free ring. Must be called when the tty is no longer in use | ||
276 | * | ||
277 | * Locking: none | ||
278 | */ | ||
279 | |||
280 | static void tty_buffer_free_all(struct tty_struct *tty) | ||
281 | { | ||
282 | struct tty_buffer *thead; | ||
283 | while ((thead = tty->buf.head) != NULL) { | ||
284 | tty->buf.head = thead->next; | ||
285 | kfree(thead); | ||
286 | } | ||
287 | while ((thead = tty->buf.free) != NULL) { | ||
288 | tty->buf.free = thead->next; | ||
289 | kfree(thead); | ||
290 | } | ||
291 | tty->buf.tail = NULL; | ||
292 | tty->buf.memory_used = 0; | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * tty_buffer_init - prepare a tty buffer structure | ||
297 | * @tty: tty to initialise | ||
298 | * | ||
299 | * Set up the initial state of the buffer management for a tty device. | ||
300 | * Must be called before the other tty buffer functions are used. | ||
301 | * | ||
302 | * Locking: none | ||
303 | */ | ||
304 | |||
305 | static void tty_buffer_init(struct tty_struct *tty) | ||
306 | { | ||
307 | spin_lock_init(&tty->buf.lock); | ||
308 | tty->buf.head = NULL; | ||
309 | tty->buf.tail = NULL; | ||
310 | tty->buf.free = NULL; | ||
311 | tty->buf.memory_used = 0; | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * tty_buffer_alloc - allocate a tty buffer | ||
316 | * @tty: tty device | ||
317 | * @size: desired size (characters) | ||
318 | * | ||
319 | * Allocate a new tty buffer to hold the desired number of characters. | ||
320 | * Return NULL if out of memory or the allocation would exceed the | ||
321 | * per device queue | ||
322 | * | ||
323 | * Locking: Caller must hold tty->buf.lock | ||
324 | */ | ||
325 | |||
326 | static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) | ||
327 | { | ||
328 | struct tty_buffer *p; | ||
329 | |||
330 | if (tty->buf.memory_used + size > 65536) | ||
331 | return NULL; | ||
332 | p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | ||
333 | if (p == NULL) | ||
334 | return NULL; | ||
335 | p->used = 0; | ||
336 | p->size = size; | ||
337 | p->next = NULL; | ||
338 | p->commit = 0; | ||
339 | p->read = 0; | ||
340 | p->char_buf_ptr = (char *)(p->data); | ||
341 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | ||
342 | tty->buf.memory_used += size; | ||
343 | return p; | ||
344 | } | ||
345 | |||
346 | /** | ||
347 | * tty_buffer_free - free a tty buffer | ||
348 | * @tty: tty owning the buffer | ||
349 | * @b: the buffer to free | ||
350 | * | ||
351 | * Free a tty buffer, or add it to the free list according to our | ||
352 | * internal strategy | ||
353 | * | ||
354 | * Locking: Caller must hold tty->buf.lock | ||
355 | */ | ||
356 | |||
357 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | ||
358 | { | ||
359 | /* Dumb strategy for now - should keep some stats */ | ||
360 | tty->buf.memory_used -= b->size; | ||
361 | WARN_ON(tty->buf.memory_used < 0); | ||
362 | |||
363 | if (b->size >= 512) | ||
364 | kfree(b); | ||
365 | else { | ||
366 | b->next = tty->buf.free; | ||
367 | tty->buf.free = b; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * __tty_buffer_flush - flush full tty buffers | ||
373 | * @tty: tty to flush | ||
374 | * | ||
375 | * flush all the buffers containing receive data. Caller must | ||
376 | * hold the buffer lock and must have ensured no parallel flush to | ||
377 | * ldisc is running. | ||
378 | * | ||
379 | * Locking: Caller must hold tty->buf.lock | ||
380 | */ | ||
381 | |||
382 | static void __tty_buffer_flush(struct tty_struct *tty) | ||
383 | { | ||
384 | struct tty_buffer *thead; | ||
385 | |||
386 | while ((thead = tty->buf.head) != NULL) { | ||
387 | tty->buf.head = thead->next; | ||
388 | tty_buffer_free(tty, thead); | ||
389 | } | ||
390 | tty->buf.tail = NULL; | ||
391 | } | ||
392 | |||
393 | /** | ||
394 | * tty_buffer_flush - flush full tty buffers | ||
395 | * @tty: tty to flush | ||
396 | * | ||
397 | * flush all the buffers containing receive data. If the buffer is | ||
398 | * being processed by flush_to_ldisc then we defer the processing | ||
399 | * to that function | ||
400 | * | ||
401 | * Locking: none | ||
402 | */ | ||
403 | |||
404 | static void tty_buffer_flush(struct tty_struct *tty) | ||
405 | { | ||
406 | unsigned long flags; | ||
407 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
408 | |||
409 | /* If the data is being pushed to the tty layer then we can't | ||
410 | process it here. Instead set a flag and the flush_to_ldisc | ||
411 | path will process the flush request before it exits */ | ||
412 | if (test_bit(TTY_FLUSHING, &tty->flags)) { | ||
413 | set_bit(TTY_FLUSHPENDING, &tty->flags); | ||
414 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
415 | wait_event(tty->read_wait, | ||
416 | test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); | ||
417 | return; | ||
418 | } else | ||
419 | __tty_buffer_flush(tty); | ||
420 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * tty_buffer_find - find a free tty buffer | ||
425 | * @tty: tty owning the buffer | ||
426 | * @size: characters wanted | ||
427 | * | ||
428 | * Locate an existing suitable tty buffer or if we are lacking one then | ||
429 | * allocate a new one. We round our buffers off in 256 character chunks | ||
430 | * to get better allocation behaviour. | ||
431 | * | ||
432 | * Locking: Caller must hold tty->buf.lock | ||
433 | */ | ||
434 | |||
435 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | ||
436 | { | ||
437 | struct tty_buffer **tbh = &tty->buf.free; | ||
438 | while ((*tbh) != NULL) { | ||
439 | struct tty_buffer *t = *tbh; | ||
440 | if (t->size >= size) { | ||
441 | *tbh = t->next; | ||
442 | t->next = NULL; | ||
443 | t->used = 0; | ||
444 | t->commit = 0; | ||
445 | t->read = 0; | ||
446 | tty->buf.memory_used += t->size; | ||
447 | return t; | ||
448 | } | ||
449 | tbh = &((*tbh)->next); | ||
450 | } | ||
451 | /* Round the buffer size out */ | ||
452 | size = (size + 0xFF) & ~0xFF; | ||
453 | return tty_buffer_alloc(tty, size); | ||
454 | /* Should possibly check if this fails for the largest buffer we | ||
455 | have queued and recycle that ? */ | ||
456 | } | ||
457 | |||
458 | /** | ||
459 | * tty_buffer_request_room - grow tty buffer if needed | ||
460 | * @tty: tty structure | ||
461 | * @size: size desired | ||
462 | * | ||
463 | * Make at least size bytes of linear space available for the tty | ||
464 | * buffer. If we fail return the size we managed to find. | ||
465 | * | ||
466 | * Locking: Takes tty->buf.lock | ||
467 | */ | ||
468 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | ||
469 | { | ||
470 | struct tty_buffer *b, *n; | ||
471 | int left; | ||
472 | unsigned long flags; | ||
473 | |||
474 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
475 | |||
476 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | ||
477 | remove this conditional if its worth it. This would be invisible | ||
478 | to the callers */ | ||
479 | if ((b = tty->buf.tail) != NULL) | ||
480 | left = b->size - b->used; | ||
481 | else | ||
482 | left = 0; | ||
483 | |||
484 | if (left < size) { | ||
485 | /* This is the slow path - looking for new buffers to use */ | ||
486 | if ((n = tty_buffer_find(tty, size)) != NULL) { | ||
487 | if (b != NULL) { | ||
488 | b->next = n; | ||
489 | b->commit = b->used; | ||
490 | } else | ||
491 | tty->buf.head = n; | ||
492 | tty->buf.tail = n; | ||
493 | } else | ||
494 | size = left; | ||
495 | } | ||
496 | |||
497 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
498 | return size; | ||
499 | } | ||
500 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | ||
501 | |||
502 | /** | ||
503 | * tty_insert_flip_string - Add characters to the tty buffer | ||
504 | * @tty: tty structure | ||
505 | * @chars: characters | ||
506 | * @size: size | ||
507 | * | ||
508 | * Queue a series of bytes to the tty buffering. All the characters | ||
509 | * passed are marked as without error. Returns the number added. | ||
510 | * | ||
511 | * Locking: Called functions may take tty->buf.lock | ||
512 | */ | ||
513 | |||
514 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | ||
515 | size_t size) | ||
516 | { | ||
517 | int copied = 0; | ||
518 | do { | ||
519 | int space = tty_buffer_request_room(tty, size - copied); | ||
520 | struct tty_buffer *tb = tty->buf.tail; | ||
521 | /* If there is no space then tb may be NULL */ | ||
522 | if (unlikely(space == 0)) | ||
523 | break; | ||
524 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
525 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
526 | tb->used += space; | ||
527 | copied += space; | ||
528 | chars += space; | ||
529 | /* There is a small chance that we need to split the data over | ||
530 | several buffers. If this is the case we must loop */ | ||
531 | } while (unlikely(size > copied)); | ||
532 | return copied; | ||
533 | } | ||
534 | EXPORT_SYMBOL(tty_insert_flip_string); | ||
535 | |||
536 | /** | ||
537 | * tty_insert_flip_string_flags - Add characters to the tty buffer | ||
538 | * @tty: tty structure | ||
539 | * @chars: characters | ||
540 | * @flags: flag bytes | ||
541 | * @size: size | ||
542 | * | ||
543 | * Queue a series of bytes to the tty buffering. For each character | ||
544 | * the flags array indicates the status of the character. Returns the | ||
545 | * number added. | ||
546 | * | ||
547 | * Locking: Called functions may take tty->buf.lock | ||
548 | */ | ||
549 | |||
550 | int tty_insert_flip_string_flags(struct tty_struct *tty, | ||
551 | const unsigned char *chars, const char *flags, size_t size) | ||
552 | { | ||
553 | int copied = 0; | ||
554 | do { | ||
555 | int space = tty_buffer_request_room(tty, size - copied); | ||
556 | struct tty_buffer *tb = tty->buf.tail; | ||
557 | /* If there is no space then tb may be NULL */ | ||
558 | if (unlikely(space == 0)) | ||
559 | break; | ||
560 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
561 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | ||
562 | tb->used += space; | ||
563 | copied += space; | ||
564 | chars += space; | ||
565 | flags += space; | ||
566 | /* There is a small chance that we need to split the data over | ||
567 | several buffers. If this is the case we must loop */ | ||
568 | } while (unlikely(size > copied)); | ||
569 | return copied; | ||
570 | } | ||
571 | EXPORT_SYMBOL(tty_insert_flip_string_flags); | ||
572 | |||
573 | /** | ||
574 | * tty_schedule_flip - push characters to ldisc | ||
575 | * @tty: tty to push from | ||
576 | * | ||
577 | * Takes any pending buffers and transfers their ownership to the | ||
578 | * ldisc side of the queue. It then schedules those characters for | ||
579 | * processing by the line discipline. | ||
580 | * | ||
581 | * Locking: Takes tty->buf.lock | ||
582 | */ | ||
583 | |||
584 | void tty_schedule_flip(struct tty_struct *tty) | ||
585 | { | ||
586 | unsigned long flags; | ||
587 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
588 | if (tty->buf.tail != NULL) | ||
589 | tty->buf.tail->commit = tty->buf.tail->used; | ||
590 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
591 | schedule_delayed_work(&tty->buf.work, 1); | ||
592 | } | ||
593 | EXPORT_SYMBOL(tty_schedule_flip); | ||
594 | |||
595 | /** | ||
596 | * tty_prepare_flip_string - make room for characters | ||
597 | * @tty: tty | ||
598 | * @chars: return pointer for character write area | ||
599 | * @size: desired size | ||
600 | * | ||
601 | * Prepare a block of space in the buffer for data. Returns the length | ||
602 | * available and buffer pointer to the space which is now allocated and | ||
603 | * accounted for as ready for normal characters. This is used for drivers | ||
604 | * that need their own block copy routines into the buffer. There is no | ||
605 | * guarantee the buffer is a DMA target! | ||
606 | * | ||
607 | * Locking: May call functions taking tty->buf.lock | ||
608 | */ | ||
609 | |||
610 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, | ||
611 | size_t size) | ||
612 | { | ||
613 | int space = tty_buffer_request_room(tty, size); | ||
614 | if (likely(space)) { | ||
615 | struct tty_buffer *tb = tty->buf.tail; | ||
616 | *chars = tb->char_buf_ptr + tb->used; | ||
617 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
618 | tb->used += space; | ||
619 | } | ||
620 | return space; | ||
621 | } | ||
622 | |||
623 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | ||
624 | |||
625 | /** | ||
626 | * tty_prepare_flip_string_flags - make room for characters | ||
627 | * @tty: tty | ||
628 | * @chars: return pointer for character write area | ||
629 | * @flags: return pointer for status flag write area | ||
630 | * @size: desired size | ||
631 | * | ||
632 | * Prepare a block of space in the buffer for data. Returns the length | ||
633 | * available and buffer pointer to the space which is now allocated and | ||
634 | * accounted for as ready for characters. This is used for drivers | ||
635 | * that need their own block copy routines into the buffer. There is no | ||
636 | * guarantee the buffer is a DMA target! | ||
637 | * | ||
638 | * Locking: May call functions taking tty->buf.lock | ||
639 | */ | ||
640 | |||
641 | int tty_prepare_flip_string_flags(struct tty_struct *tty, | ||
642 | unsigned char **chars, char **flags, size_t size) | ||
643 | { | ||
644 | int space = tty_buffer_request_room(tty, size); | ||
645 | if (likely(space)) { | ||
646 | struct tty_buffer *tb = tty->buf.tail; | ||
647 | *chars = tb->char_buf_ptr + tb->used; | ||
648 | *flags = tb->flag_buf_ptr + tb->used; | ||
649 | tb->used += space; | ||
650 | } | ||
651 | return space; | ||
652 | } | ||
653 | |||
654 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | ||
655 | |||
656 | |||
657 | |||
658 | /** | 257 | /** |
659 | * get_tty_driver - find device of a tty | 258 | * get_tty_driver - find device of a tty |
660 | * @dev_t: device identifier | 259 | * @dev_t: device identifier |
@@ -675,7 +274,7 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index) | |||
675 | if (device < base || device >= base + p->num) | 274 | if (device < base || device >= base + p->num) |
676 | continue; | 275 | continue; |
677 | *index = device - base; | 276 | *index = device - base; |
678 | return p; | 277 | return tty_driver_kref_get(p); |
679 | } | 278 | } |
680 | return NULL; | 279 | return NULL; |
681 | } | 280 | } |
@@ -719,7 +318,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
719 | 318 | ||
720 | if (tty_line >= 0 && tty_line <= p->num && p->ops && | 319 | if (tty_line >= 0 && tty_line <= p->num && p->ops && |
721 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { | 320 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { |
722 | res = p; | 321 | res = tty_driver_kref_get(p); |
723 | *line = tty_line; | 322 | *line = tty_line; |
724 | break; | 323 | break; |
725 | } | 324 | } |
@@ -819,20 +418,6 @@ static const struct file_operations tty_fops = { | |||
819 | .fasync = tty_fasync, | 418 | .fasync = tty_fasync, |
820 | }; | 419 | }; |
821 | 420 | ||
822 | #ifdef CONFIG_UNIX98_PTYS | ||
823 | static const struct file_operations ptmx_fops = { | ||
824 | .llseek = no_llseek, | ||
825 | .read = tty_read, | ||
826 | .write = tty_write, | ||
827 | .poll = tty_poll, | ||
828 | .unlocked_ioctl = tty_ioctl, | ||
829 | .compat_ioctl = tty_compat_ioctl, | ||
830 | .open = ptmx_open, | ||
831 | .release = tty_release, | ||
832 | .fasync = tty_fasync, | ||
833 | }; | ||
834 | #endif | ||
835 | |||
836 | static const struct file_operations console_fops = { | 421 | static const struct file_operations console_fops = { |
837 | .llseek = no_llseek, | 422 | .llseek = no_llseek, |
838 | .read = tty_read, | 423 | .read = tty_read, |
@@ -953,6 +538,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
953 | struct tty_ldisc *ld; | 538 | struct tty_ldisc *ld; |
954 | int closecount = 0, n; | 539 | int closecount = 0, n; |
955 | unsigned long flags; | 540 | unsigned long flags; |
541 | int refs = 0; | ||
956 | 542 | ||
957 | if (!tty) | 543 | if (!tty) |
958 | return; | 544 | return; |
@@ -1019,8 +605,12 @@ static void do_tty_hangup(struct work_struct *work) | |||
1019 | if (tty->session) { | 605 | if (tty->session) { |
1020 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { | 606 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { |
1021 | spin_lock_irq(&p->sighand->siglock); | 607 | spin_lock_irq(&p->sighand->siglock); |
1022 | if (p->signal->tty == tty) | 608 | if (p->signal->tty == tty) { |
1023 | p->signal->tty = NULL; | 609 | p->signal->tty = NULL; |
610 | /* We defer the dereferences outside fo | ||
611 | the tasklist lock */ | ||
612 | refs++; | ||
613 | } | ||
1024 | if (!p->signal->leader) { | 614 | if (!p->signal->leader) { |
1025 | spin_unlock_irq(&p->sighand->siglock); | 615 | spin_unlock_irq(&p->sighand->siglock); |
1026 | continue; | 616 | continue; |
@@ -1046,6 +636,10 @@ static void do_tty_hangup(struct work_struct *work) | |||
1046 | tty->ctrl_status = 0; | 636 | tty->ctrl_status = 0; |
1047 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 637 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
1048 | 638 | ||
639 | /* Account for the p->signal references we killed */ | ||
640 | while (refs--) | ||
641 | tty_kref_put(tty); | ||
642 | |||
1049 | /* | 643 | /* |
1050 | * If one of the devices matches a console pointer, we | 644 | * If one of the devices matches a console pointer, we |
1051 | * cannot just call hangup() because that will cause | 645 | * cannot just call hangup() because that will cause |
@@ -1115,6 +709,23 @@ void tty_vhangup(struct tty_struct *tty) | |||
1115 | EXPORT_SYMBOL(tty_vhangup); | 709 | EXPORT_SYMBOL(tty_vhangup); |
1116 | 710 | ||
1117 | /** | 711 | /** |
712 | * tty_vhangup_self - process vhangup for own ctty | ||
713 | * | ||
714 | * Perform a vhangup on the current controlling tty | ||
715 | */ | ||
716 | |||
717 | void tty_vhangup_self(void) | ||
718 | { | ||
719 | struct tty_struct *tty; | ||
720 | |||
721 | tty = get_current_tty(); | ||
722 | if (tty) { | ||
723 | tty_vhangup(tty); | ||
724 | tty_kref_put(tty); | ||
725 | } | ||
726 | } | ||
727 | |||
728 | /** | ||
1118 | * tty_hung_up_p - was tty hung up | 729 | * tty_hung_up_p - was tty hung up |
1119 | * @filp: file pointer of tty | 730 | * @filp: file pointer of tty |
1120 | * | 731 | * |
@@ -1167,16 +778,14 @@ void disassociate_ctty(int on_exit) | |||
1167 | struct pid *tty_pgrp = NULL; | 778 | struct pid *tty_pgrp = NULL; |
1168 | 779 | ||
1169 | 780 | ||
1170 | mutex_lock(&tty_mutex); | ||
1171 | tty = get_current_tty(); | 781 | tty = get_current_tty(); |
1172 | if (tty) { | 782 | if (tty) { |
1173 | tty_pgrp = get_pid(tty->pgrp); | 783 | tty_pgrp = get_pid(tty->pgrp); |
1174 | lock_kernel(); | 784 | lock_kernel(); |
1175 | mutex_unlock(&tty_mutex); | ||
1176 | /* XXX: here we race, there is nothing protecting tty */ | ||
1177 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 785 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) |
1178 | tty_vhangup(tty); | 786 | tty_vhangup(tty); |
1179 | unlock_kernel(); | 787 | unlock_kernel(); |
788 | tty_kref_put(tty); | ||
1180 | } else if (on_exit) { | 789 | } else if (on_exit) { |
1181 | struct pid *old_pgrp; | 790 | struct pid *old_pgrp; |
1182 | spin_lock_irq(¤t->sighand->siglock); | 791 | spin_lock_irq(¤t->sighand->siglock); |
@@ -1188,7 +797,6 @@ void disassociate_ctty(int on_exit) | |||
1188 | kill_pgrp(old_pgrp, SIGCONT, on_exit); | 797 | kill_pgrp(old_pgrp, SIGCONT, on_exit); |
1189 | put_pid(old_pgrp); | 798 | put_pid(old_pgrp); |
1190 | } | 799 | } |
1191 | mutex_unlock(&tty_mutex); | ||
1192 | return; | 800 | return; |
1193 | } | 801 | } |
1194 | if (tty_pgrp) { | 802 | if (tty_pgrp) { |
@@ -1203,8 +811,6 @@ void disassociate_ctty(int on_exit) | |||
1203 | current->signal->tty_old_pgrp = NULL; | 811 | current->signal->tty_old_pgrp = NULL; |
1204 | spin_unlock_irq(¤t->sighand->siglock); | 812 | spin_unlock_irq(¤t->sighand->siglock); |
1205 | 813 | ||
1206 | mutex_lock(&tty_mutex); | ||
1207 | /* It is possible that do_tty_hangup has free'd this tty */ | ||
1208 | tty = get_current_tty(); | 814 | tty = get_current_tty(); |
1209 | if (tty) { | 815 | if (tty) { |
1210 | unsigned long flags; | 816 | unsigned long flags; |
@@ -1214,13 +820,13 @@ void disassociate_ctty(int on_exit) | |||
1214 | tty->session = NULL; | 820 | tty->session = NULL; |
1215 | tty->pgrp = NULL; | 821 | tty->pgrp = NULL; |
1216 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 822 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
823 | tty_kref_put(tty); | ||
1217 | } else { | 824 | } else { |
1218 | #ifdef TTY_DEBUG_HANGUP | 825 | #ifdef TTY_DEBUG_HANGUP |
1219 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" | 826 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" |
1220 | " = NULL", tty); | 827 | " = NULL", tty); |
1221 | #endif | 828 | #endif |
1222 | } | 829 | } |
1223 | mutex_unlock(&tty_mutex); | ||
1224 | 830 | ||
1225 | /* Now clear signal->tty under the lock */ | 831 | /* Now clear signal->tty under the lock */ |
1226 | read_lock(&tasklist_lock); | 832 | read_lock(&tasklist_lock); |
@@ -1420,19 +1026,19 @@ static inline ssize_t do_tty_write( | |||
1420 | 1026 | ||
1421 | /* write_buf/write_cnt is protected by the atomic_write_lock mutex */ | 1027 | /* write_buf/write_cnt is protected by the atomic_write_lock mutex */ |
1422 | if (tty->write_cnt < chunk) { | 1028 | if (tty->write_cnt < chunk) { |
1423 | unsigned char *buf; | 1029 | unsigned char *buf_chunk; |
1424 | 1030 | ||
1425 | if (chunk < 1024) | 1031 | if (chunk < 1024) |
1426 | chunk = 1024; | 1032 | chunk = 1024; |
1427 | 1033 | ||
1428 | buf = kmalloc(chunk, GFP_KERNEL); | 1034 | buf_chunk = kmalloc(chunk, GFP_KERNEL); |
1429 | if (!buf) { | 1035 | if (!buf_chunk) { |
1430 | ret = -ENOMEM; | 1036 | ret = -ENOMEM; |
1431 | goto out; | 1037 | goto out; |
1432 | } | 1038 | } |
1433 | kfree(tty->write_buf); | 1039 | kfree(tty->write_buf); |
1434 | tty->write_cnt = chunk; | 1040 | tty->write_cnt = chunk; |
1435 | tty->write_buf = buf; | 1041 | tty->write_buf = buf_chunk; |
1436 | } | 1042 | } |
1437 | 1043 | ||
1438 | /* Do the write .. */ | 1044 | /* Do the write .. */ |
@@ -1466,6 +1072,31 @@ out: | |||
1466 | return ret; | 1072 | return ret; |
1467 | } | 1073 | } |
1468 | 1074 | ||
1075 | /** | ||
1076 | * tty_write_message - write a message to a certain tty, not just the console. | ||
1077 | * @tty: the destination tty_struct | ||
1078 | * @msg: the message to write | ||
1079 | * | ||
1080 | * This is used for messages that need to be redirected to a specific tty. | ||
1081 | * We don't put it into the syslog queue right now maybe in the future if | ||
1082 | * really needed. | ||
1083 | * | ||
1084 | * We must still hold the BKL and test the CLOSING flag for the moment. | ||
1085 | */ | ||
1086 | |||
1087 | void tty_write_message(struct tty_struct *tty, char *msg) | ||
1088 | { | ||
1089 | lock_kernel(); | ||
1090 | if (tty) { | ||
1091 | mutex_lock(&tty->atomic_write_lock); | ||
1092 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) | ||
1093 | tty->ops->write(tty, msg, strlen(msg)); | ||
1094 | tty_write_unlock(tty); | ||
1095 | } | ||
1096 | unlock_kernel(); | ||
1097 | return; | ||
1098 | } | ||
1099 | |||
1469 | 1100 | ||
1470 | /** | 1101 | /** |
1471 | * tty_write - write method for tty device file | 1102 | * tty_write - write method for tty device file |
@@ -1533,42 +1164,6 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf, | |||
1533 | return tty_write(file, buf, count, ppos); | 1164 | return tty_write(file, buf, count, ppos); |
1534 | } | 1165 | } |
1535 | 1166 | ||
1536 | void tty_port_init(struct tty_port *port) | ||
1537 | { | ||
1538 | memset(port, 0, sizeof(*port)); | ||
1539 | init_waitqueue_head(&port->open_wait); | ||
1540 | init_waitqueue_head(&port->close_wait); | ||
1541 | mutex_init(&port->mutex); | ||
1542 | port->close_delay = (50 * HZ) / 100; | ||
1543 | port->closing_wait = (3000 * HZ) / 100; | ||
1544 | } | ||
1545 | EXPORT_SYMBOL(tty_port_init); | ||
1546 | |||
1547 | int tty_port_alloc_xmit_buf(struct tty_port *port) | ||
1548 | { | ||
1549 | /* We may sleep in get_zeroed_page() */ | ||
1550 | mutex_lock(&port->mutex); | ||
1551 | if (port->xmit_buf == NULL) | ||
1552 | port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); | ||
1553 | mutex_unlock(&port->mutex); | ||
1554 | if (port->xmit_buf == NULL) | ||
1555 | return -ENOMEM; | ||
1556 | return 0; | ||
1557 | } | ||
1558 | EXPORT_SYMBOL(tty_port_alloc_xmit_buf); | ||
1559 | |||
1560 | void tty_port_free_xmit_buf(struct tty_port *port) | ||
1561 | { | ||
1562 | mutex_lock(&port->mutex); | ||
1563 | if (port->xmit_buf != NULL) { | ||
1564 | free_page((unsigned long)port->xmit_buf); | ||
1565 | port->xmit_buf = NULL; | ||
1566 | } | ||
1567 | mutex_unlock(&port->mutex); | ||
1568 | } | ||
1569 | EXPORT_SYMBOL(tty_port_free_xmit_buf); | ||
1570 | |||
1571 | |||
1572 | static char ptychar[] = "pqrstuvwxyzabcde"; | 1167 | static char ptychar[] = "pqrstuvwxyzabcde"; |
1573 | 1168 | ||
1574 | /** | 1169 | /** |
@@ -1592,7 +1187,7 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
1592 | } | 1187 | } |
1593 | 1188 | ||
1594 | /** | 1189 | /** |
1595 | * pty_line_name - generate name for a tty | 1190 | * tty_line_name - generate name for a tty |
1596 | * @driver: the tty driver in use | 1191 | * @driver: the tty driver in use |
1597 | * @index: the minor number | 1192 | * @index: the minor number |
1598 | * @p: output buffer of at least 7 bytes | 1193 | * @p: output buffer of at least 7 bytes |
@@ -1608,10 +1203,148 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) | |||
1608 | } | 1203 | } |
1609 | 1204 | ||
1610 | /** | 1205 | /** |
1611 | * init_dev - initialise a tty device | 1206 | * tty_driver_lookup_tty() - find an existing tty, if any |
1207 | * @driver: the driver for the tty | ||
1208 | * @idx: the minor number | ||
1209 | * | ||
1210 | * Return the tty, if found or ERR_PTR() otherwise. | ||
1211 | * | ||
1212 | * Locking: tty_mutex must be held. If tty is found, the mutex must | ||
1213 | * be held until the 'fast-open' is also done. Will change once we | ||
1214 | * have refcounting in the driver and per driver locking | ||
1215 | */ | ||
1216 | struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, | ||
1217 | struct inode *inode, int idx) | ||
1218 | { | ||
1219 | struct tty_struct *tty; | ||
1220 | |||
1221 | if (driver->ops->lookup) | ||
1222 | return driver->ops->lookup(driver, inode, idx); | ||
1223 | |||
1224 | tty = driver->ttys[idx]; | ||
1225 | return tty; | ||
1226 | } | ||
1227 | |||
1228 | /** | ||
1229 | * tty_init_termios - helper for termios setup | ||
1230 | * @tty: the tty to set up | ||
1231 | * | ||
1232 | * Initialise the termios structures for this tty. Thus runs under | ||
1233 | * the tty_mutex currently so we can be relaxed about ordering. | ||
1234 | */ | ||
1235 | |||
1236 | int tty_init_termios(struct tty_struct *tty) | ||
1237 | { | ||
1238 | struct ktermios *tp; | ||
1239 | int idx = tty->index; | ||
1240 | |||
1241 | tp = tty->driver->termios[idx]; | ||
1242 | if (tp == NULL) { | ||
1243 | tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
1244 | if (tp == NULL) | ||
1245 | return -ENOMEM; | ||
1246 | memcpy(tp, &tty->driver->init_termios, | ||
1247 | sizeof(struct ktermios)); | ||
1248 | tty->driver->termios[idx] = tp; | ||
1249 | } | ||
1250 | tty->termios = tp; | ||
1251 | tty->termios_locked = tp + 1; | ||
1252 | |||
1253 | /* Compatibility until drivers always set this */ | ||
1254 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1255 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1256 | return 0; | ||
1257 | } | ||
1258 | |||
1259 | /** | ||
1260 | * tty_driver_install_tty() - install a tty entry in the driver | ||
1261 | * @driver: the driver for the tty | ||
1262 | * @tty: the tty | ||
1263 | * | ||
1264 | * Install a tty object into the driver tables. The tty->index field | ||
1265 | * will be set by the time this is called. This method is responsible | ||
1266 | * for ensuring any need additional structures are allocated and | ||
1267 | * configured. | ||
1268 | * | ||
1269 | * Locking: tty_mutex for now | ||
1270 | */ | ||
1271 | static int tty_driver_install_tty(struct tty_driver *driver, | ||
1272 | struct tty_struct *tty) | ||
1273 | { | ||
1274 | int idx = tty->index; | ||
1275 | |||
1276 | if (driver->ops->install) | ||
1277 | return driver->ops->install(driver, tty); | ||
1278 | |||
1279 | if (tty_init_termios(tty) == 0) { | ||
1280 | tty_driver_kref_get(driver); | ||
1281 | tty->count++; | ||
1282 | driver->ttys[idx] = tty; | ||
1283 | return 0; | ||
1284 | } | ||
1285 | return -ENOMEM; | ||
1286 | } | ||
1287 | |||
1288 | /** | ||
1289 | * tty_driver_remove_tty() - remove a tty from the driver tables | ||
1290 | * @driver: the driver for the tty | ||
1291 | * @idx: the minor number | ||
1292 | * | ||
1293 | * Remvoe a tty object from the driver tables. The tty->index field | ||
1294 | * will be set by the time this is called. | ||
1295 | * | ||
1296 | * Locking: tty_mutex for now | ||
1297 | */ | ||
1298 | static void tty_driver_remove_tty(struct tty_driver *driver, | ||
1299 | struct tty_struct *tty) | ||
1300 | { | ||
1301 | if (driver->ops->remove) | ||
1302 | driver->ops->remove(driver, tty); | ||
1303 | else | ||
1304 | driver->ttys[tty->index] = NULL; | ||
1305 | } | ||
1306 | |||
1307 | /* | ||
1308 | * tty_reopen() - fast re-open of an open tty | ||
1309 | * @tty - the tty to open | ||
1310 | * | ||
1311 | * Return 0 on success, -errno on error. | ||
1312 | * | ||
1313 | * Locking: tty_mutex must be held from the time the tty was found | ||
1314 | * till this open completes. | ||
1315 | */ | ||
1316 | static int tty_reopen(struct tty_struct *tty) | ||
1317 | { | ||
1318 | struct tty_driver *driver = tty->driver; | ||
1319 | |||
1320 | if (test_bit(TTY_CLOSING, &tty->flags)) | ||
1321 | return -EIO; | ||
1322 | |||
1323 | if (driver->type == TTY_DRIVER_TYPE_PTY && | ||
1324 | driver->subtype == PTY_TYPE_MASTER) { | ||
1325 | /* | ||
1326 | * special case for PTY masters: only one open permitted, | ||
1327 | * and the slave side open count is incremented as well. | ||
1328 | */ | ||
1329 | if (tty->count) | ||
1330 | return -EIO; | ||
1331 | |||
1332 | tty->link->count++; | ||
1333 | } | ||
1334 | tty->count++; | ||
1335 | tty->driver = driver; /* N.B. why do this every time?? */ | ||
1336 | |||
1337 | WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | /** | ||
1343 | * tty_init_dev - initialise a tty device | ||
1612 | * @driver: tty driver we are opening a device on | 1344 | * @driver: tty driver we are opening a device on |
1613 | * @idx: device index | 1345 | * @idx: device index |
1614 | * @tty: returned tty structure | 1346 | * @ret_tty: returned tty structure |
1347 | * @first_ok: ok to open a new device (used by ptmx) | ||
1615 | * | 1348 | * |
1616 | * Prepare a tty device. This may not be a "new" clean device but | 1349 | * Prepare a tty device. This may not be a "new" clean device but |
1617 | * could also be an active device. The pty drivers require special | 1350 | * could also be an active device. The pty drivers require special |
@@ -1631,37 +1364,16 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) | |||
1631 | * relaxed for the (most common) case of reopening a tty. | 1364 | * relaxed for the (most common) case of reopening a tty. |
1632 | */ | 1365 | */ |
1633 | 1366 | ||
1634 | static int init_dev(struct tty_driver *driver, int idx, | 1367 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, |
1635 | struct tty_struct **ret_tty) | 1368 | int first_ok) |
1636 | { | 1369 | { |
1637 | struct tty_struct *tty, *o_tty; | 1370 | struct tty_struct *tty; |
1638 | struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; | 1371 | int retval; |
1639 | struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | ||
1640 | int retval = 0; | ||
1641 | 1372 | ||
1642 | /* check whether we're reopening an existing tty */ | 1373 | /* Check if pty master is being opened multiple times */ |
1643 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | 1374 | if (driver->subtype == PTY_TYPE_MASTER && |
1644 | tty = devpts_get_tty(idx); | 1375 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) |
1645 | /* | 1376 | return ERR_PTR(-EIO); |
1646 | * If we don't have a tty here on a slave open, it's because | ||
1647 | * the master already started the close process and there's | ||
1648 | * no relation between devpts file and tty anymore. | ||
1649 | */ | ||
1650 | if (!tty && driver->subtype == PTY_TYPE_SLAVE) { | ||
1651 | retval = -EIO; | ||
1652 | goto end_init; | ||
1653 | } | ||
1654 | /* | ||
1655 | * It's safe from now on because init_dev() is called with | ||
1656 | * tty_mutex held and release_dev() won't change tty->count | ||
1657 | * or tty->flags without having to grab tty_mutex | ||
1658 | */ | ||
1659 | if (tty && driver->subtype == PTY_TYPE_MASTER) | ||
1660 | tty = tty->link; | ||
1661 | } else { | ||
1662 | tty = driver->ttys[idx]; | ||
1663 | } | ||
1664 | if (tty) goto fast_track; | ||
1665 | 1377 | ||
1666 | /* | 1378 | /* |
1667 | * First time open is complex, especially for PTY devices. | 1379 | * First time open is complex, especially for PTY devices. |
@@ -1671,189 +1383,69 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1671 | * and locked termios may be retained.) | 1383 | * and locked termios may be retained.) |
1672 | */ | 1384 | */ |
1673 | 1385 | ||
1674 | if (!try_module_get(driver->owner)) { | 1386 | if (!try_module_get(driver->owner)) |
1675 | retval = -ENODEV; | 1387 | return ERR_PTR(-ENODEV); |
1676 | goto end_init; | ||
1677 | } | ||
1678 | |||
1679 | o_tty = NULL; | ||
1680 | tp = o_tp = NULL; | ||
1681 | ltp = o_ltp = NULL; | ||
1682 | 1388 | ||
1683 | tty = alloc_tty_struct(); | 1389 | tty = alloc_tty_struct(); |
1684 | if (!tty) | 1390 | if (!tty) |
1685 | goto fail_no_mem; | 1391 | goto fail_no_mem; |
1686 | initialize_tty_struct(tty); | 1392 | initialize_tty_struct(tty, driver, idx); |
1687 | tty->driver = driver; | ||
1688 | tty->ops = driver->ops; | ||
1689 | tty->index = idx; | ||
1690 | tty_line_name(driver, idx, tty->name); | ||
1691 | |||
1692 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | ||
1693 | tp_loc = &tty->termios; | ||
1694 | ltp_loc = &tty->termios_locked; | ||
1695 | } else { | ||
1696 | tp_loc = &driver->termios[idx]; | ||
1697 | ltp_loc = &driver->termios_locked[idx]; | ||
1698 | } | ||
1699 | |||
1700 | if (!*tp_loc) { | ||
1701 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1702 | if (!tp) | ||
1703 | goto free_mem_out; | ||
1704 | *tp = driver->init_termios; | ||
1705 | } | ||
1706 | |||
1707 | if (!*ltp_loc) { | ||
1708 | ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1709 | if (!ltp) | ||
1710 | goto free_mem_out; | ||
1711 | } | ||
1712 | |||
1713 | if (driver->type == TTY_DRIVER_TYPE_PTY) { | ||
1714 | o_tty = alloc_tty_struct(); | ||
1715 | if (!o_tty) | ||
1716 | goto free_mem_out; | ||
1717 | initialize_tty_struct(o_tty); | ||
1718 | o_tty->driver = driver->other; | ||
1719 | o_tty->ops = driver->ops; | ||
1720 | o_tty->index = idx; | ||
1721 | tty_line_name(driver->other, idx, o_tty->name); | ||
1722 | 1393 | ||
1723 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | 1394 | retval = tty_driver_install_tty(driver, tty); |
1724 | o_tp_loc = &o_tty->termios; | 1395 | if (retval < 0) { |
1725 | o_ltp_loc = &o_tty->termios_locked; | 1396 | free_tty_struct(tty); |
1726 | } else { | 1397 | module_put(driver->owner); |
1727 | o_tp_loc = &driver->other->termios[idx]; | 1398 | return ERR_PTR(retval); |
1728 | o_ltp_loc = &driver->other->termios_locked[idx]; | ||
1729 | } | ||
1730 | |||
1731 | if (!*o_tp_loc) { | ||
1732 | o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1733 | if (!o_tp) | ||
1734 | goto free_mem_out; | ||
1735 | *o_tp = driver->other->init_termios; | ||
1736 | } | ||
1737 | |||
1738 | if (!*o_ltp_loc) { | ||
1739 | o_ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1740 | if (!o_ltp) | ||
1741 | goto free_mem_out; | ||
1742 | } | ||
1743 | |||
1744 | /* | ||
1745 | * Everything allocated ... set up the o_tty structure. | ||
1746 | */ | ||
1747 | if (!(driver->other->flags & TTY_DRIVER_DEVPTS_MEM)) | ||
1748 | driver->other->ttys[idx] = o_tty; | ||
1749 | if (!*o_tp_loc) | ||
1750 | *o_tp_loc = o_tp; | ||
1751 | if (!*o_ltp_loc) | ||
1752 | *o_ltp_loc = o_ltp; | ||
1753 | o_tty->termios = *o_tp_loc; | ||
1754 | o_tty->termios_locked = *o_ltp_loc; | ||
1755 | driver->other->refcount++; | ||
1756 | if (driver->subtype == PTY_TYPE_MASTER) | ||
1757 | o_tty->count++; | ||
1758 | |||
1759 | /* Establish the links in both directions */ | ||
1760 | tty->link = o_tty; | ||
1761 | o_tty->link = tty; | ||
1762 | } | 1399 | } |
1763 | 1400 | ||
1764 | /* | 1401 | /* |
1765 | * All structures have been allocated, so now we install them. | ||
1766 | * Failures after this point use release_tty to clean up, so | ||
1767 | * there's no need to null out the local pointers. | ||
1768 | */ | ||
1769 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) | ||
1770 | driver->ttys[idx] = tty; | ||
1771 | |||
1772 | if (!*tp_loc) | ||
1773 | *tp_loc = tp; | ||
1774 | if (!*ltp_loc) | ||
1775 | *ltp_loc = ltp; | ||
1776 | tty->termios = *tp_loc; | ||
1777 | tty->termios_locked = *ltp_loc; | ||
1778 | /* Compatibility until drivers always set this */ | ||
1779 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1780 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1781 | driver->refcount++; | ||
1782 | tty->count++; | ||
1783 | |||
1784 | /* | ||
1785 | * Structures all installed ... call the ldisc open routines. | 1402 | * Structures all installed ... call the ldisc open routines. |
1786 | * If we fail here just call release_tty to clean up. No need | 1403 | * If we fail here just call release_tty to clean up. No need |
1787 | * to decrement the use counts, as release_tty doesn't care. | 1404 | * to decrement the use counts, as release_tty doesn't care. |
1788 | */ | 1405 | */ |
1789 | 1406 | ||
1790 | retval = tty_ldisc_setup(tty, o_tty); | 1407 | retval = tty_ldisc_setup(tty, tty->link); |
1791 | |||
1792 | if (retval) | 1408 | if (retval) |
1793 | goto release_mem_out; | 1409 | goto release_mem_out; |
1794 | goto success; | 1410 | return tty; |
1795 | |||
1796 | /* | ||
1797 | * This fast open can be used if the tty is already open. | ||
1798 | * No memory is allocated, and the only failures are from | ||
1799 | * attempting to open a closing tty or attempting multiple | ||
1800 | * opens on a pty master. | ||
1801 | */ | ||
1802 | fast_track: | ||
1803 | if (test_bit(TTY_CLOSING, &tty->flags)) { | ||
1804 | retval = -EIO; | ||
1805 | goto end_init; | ||
1806 | } | ||
1807 | if (driver->type == TTY_DRIVER_TYPE_PTY && | ||
1808 | driver->subtype == PTY_TYPE_MASTER) { | ||
1809 | /* | ||
1810 | * special case for PTY masters: only one open permitted, | ||
1811 | * and the slave side open count is incremented as well. | ||
1812 | */ | ||
1813 | if (tty->count) { | ||
1814 | retval = -EIO; | ||
1815 | goto end_init; | ||
1816 | } | ||
1817 | tty->link->count++; | ||
1818 | } | ||
1819 | tty->count++; | ||
1820 | tty->driver = driver; /* N.B. why do this every time?? */ | ||
1821 | |||
1822 | /* FIXME */ | ||
1823 | if (!test_bit(TTY_LDISC, &tty->flags)) | ||
1824 | printk(KERN_ERR "init_dev but no ldisc\n"); | ||
1825 | success: | ||
1826 | *ret_tty = tty; | ||
1827 | |||
1828 | /* All paths come through here to release the mutex */ | ||
1829 | end_init: | ||
1830 | return retval; | ||
1831 | |||
1832 | /* Release locally allocated memory ... nothing placed in slots */ | ||
1833 | free_mem_out: | ||
1834 | kfree(o_tp); | ||
1835 | if (o_tty) | ||
1836 | free_tty_struct(o_tty); | ||
1837 | kfree(ltp); | ||
1838 | kfree(tp); | ||
1839 | free_tty_struct(tty); | ||
1840 | 1411 | ||
1841 | fail_no_mem: | 1412 | fail_no_mem: |
1842 | module_put(driver->owner); | 1413 | module_put(driver->owner); |
1843 | retval = -ENOMEM; | 1414 | return ERR_PTR(-ENOMEM); |
1844 | goto end_init; | ||
1845 | 1415 | ||
1846 | /* call the tty release_tty routine to clean out this slot */ | 1416 | /* call the tty release_tty routine to clean out this slot */ |
1847 | release_mem_out: | 1417 | release_mem_out: |
1848 | if (printk_ratelimit()) | 1418 | if (printk_ratelimit()) |
1849 | printk(KERN_INFO "init_dev: ldisc open failed, " | 1419 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " |
1850 | "clearing slot %d\n", idx); | 1420 | "clearing slot %d\n", idx); |
1851 | release_tty(tty, idx); | 1421 | release_tty(tty, idx); |
1852 | goto end_init; | 1422 | return ERR_PTR(retval); |
1853 | } | 1423 | } |
1854 | 1424 | ||
1425 | void tty_free_termios(struct tty_struct *tty) | ||
1426 | { | ||
1427 | struct ktermios *tp; | ||
1428 | int idx = tty->index; | ||
1429 | /* Kill this flag and push into drivers for locking etc */ | ||
1430 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | ||
1431 | /* FIXME: Locking on ->termios array */ | ||
1432 | tp = tty->termios; | ||
1433 | tty->driver->termios[idx] = NULL; | ||
1434 | kfree(tp); | ||
1435 | } | ||
1436 | } | ||
1437 | EXPORT_SYMBOL(tty_free_termios); | ||
1438 | |||
1439 | void tty_shutdown(struct tty_struct *tty) | ||
1440 | { | ||
1441 | tty_driver_remove_tty(tty->driver, tty); | ||
1442 | tty_free_termios(tty); | ||
1443 | } | ||
1444 | EXPORT_SYMBOL(tty_shutdown); | ||
1445 | |||
1855 | /** | 1446 | /** |
1856 | * release_one_tty - release tty structure memory | 1447 | * release_one_tty - release tty structure memory |
1448 | * @kref: kref of tty we are obliterating | ||
1857 | * | 1449 | * |
1858 | * Releases memory associated with a tty structure, and clears out the | 1450 | * Releases memory associated with a tty structure, and clears out the |
1859 | * driver table slots. This function is called when a device is no longer | 1451 | * driver table slots. This function is called when a device is no longer |
@@ -1863,31 +1455,19 @@ release_mem_out: | |||
1863 | * tty_mutex - sometimes only | 1455 | * tty_mutex - sometimes only |
1864 | * takes the file list lock internally when working on the list | 1456 | * takes the file list lock internally when working on the list |
1865 | * of ttys that the driver keeps. | 1457 | * of ttys that the driver keeps. |
1866 | * FIXME: should we require tty_mutex is held here ?? | ||
1867 | */ | 1458 | */ |
1868 | static void release_one_tty(struct tty_struct *tty, int idx) | 1459 | static void release_one_tty(struct kref *kref) |
1869 | { | 1460 | { |
1870 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; | 1461 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1871 | struct ktermios *tp; | 1462 | struct tty_driver *driver = tty->driver; |
1872 | |||
1873 | if (!devpts) | ||
1874 | tty->driver->ttys[idx] = NULL; | ||
1875 | |||
1876 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | ||
1877 | tp = tty->termios; | ||
1878 | if (!devpts) | ||
1879 | tty->driver->termios[idx] = NULL; | ||
1880 | kfree(tp); | ||
1881 | |||
1882 | tp = tty->termios_locked; | ||
1883 | if (!devpts) | ||
1884 | tty->driver->termios_locked[idx] = NULL; | ||
1885 | kfree(tp); | ||
1886 | } | ||
1887 | |||
1888 | 1463 | ||
1464 | if (tty->ops->shutdown) | ||
1465 | tty->ops->shutdown(tty); | ||
1466 | else | ||
1467 | tty_shutdown(tty); | ||
1889 | tty->magic = 0; | 1468 | tty->magic = 0; |
1890 | tty->driver->refcount--; | 1469 | tty_driver_kref_put(driver); |
1470 | module_put(driver->owner); | ||
1891 | 1471 | ||
1892 | file_list_lock(); | 1472 | file_list_lock(); |
1893 | list_del_init(&tty->tty_files); | 1473 | list_del_init(&tty->tty_files); |
@@ -1897,6 +1477,21 @@ static void release_one_tty(struct tty_struct *tty, int idx) | |||
1897 | } | 1477 | } |
1898 | 1478 | ||
1899 | /** | 1479 | /** |
1480 | * tty_kref_put - release a tty kref | ||
1481 | * @tty: tty device | ||
1482 | * | ||
1483 | * Release a reference to a tty device and if need be let the kref | ||
1484 | * layer destruct the object for us | ||
1485 | */ | ||
1486 | |||
1487 | void tty_kref_put(struct tty_struct *tty) | ||
1488 | { | ||
1489 | if (tty) | ||
1490 | kref_put(&tty->kref, release_one_tty); | ||
1491 | } | ||
1492 | EXPORT_SYMBOL(tty_kref_put); | ||
1493 | |||
1494 | /** | ||
1900 | * release_tty - release tty structure memory | 1495 | * release_tty - release tty structure memory |
1901 | * | 1496 | * |
1902 | * Release both @tty and a possible linked partner (think pty pair), | 1497 | * Release both @tty and a possible linked partner (think pty pair), |
@@ -1907,15 +1502,16 @@ static void release_one_tty(struct tty_struct *tty, int idx) | |||
1907 | * takes the file list lock internally when working on the list | 1502 | * takes the file list lock internally when working on the list |
1908 | * of ttys that the driver keeps. | 1503 | * of ttys that the driver keeps. |
1909 | * FIXME: should we require tty_mutex is held here ?? | 1504 | * FIXME: should we require tty_mutex is held here ?? |
1505 | * | ||
1910 | */ | 1506 | */ |
1911 | static void release_tty(struct tty_struct *tty, int idx) | 1507 | static void release_tty(struct tty_struct *tty, int idx) |
1912 | { | 1508 | { |
1913 | struct tty_driver *driver = tty->driver; | 1509 | /* This should always be true but check for the moment */ |
1510 | WARN_ON(tty->index != idx); | ||
1914 | 1511 | ||
1915 | if (tty->link) | 1512 | if (tty->link) |
1916 | release_one_tty(tty->link, idx); | 1513 | tty_kref_put(tty->link); |
1917 | release_one_tty(tty, idx); | 1514 | tty_kref_put(tty); |
1918 | module_put(driver->owner); | ||
1919 | } | 1515 | } |
1920 | 1516 | ||
1921 | /* | 1517 | /* |
@@ -1926,20 +1522,21 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1926 | * WSH 09/09/97: rewritten to avoid some nasty race conditions that could | 1522 | * WSH 09/09/97: rewritten to avoid some nasty race conditions that could |
1927 | * lead to double frees or releasing memory still in use. | 1523 | * lead to double frees or releasing memory still in use. |
1928 | */ | 1524 | */ |
1929 | static void release_dev(struct file *filp) | 1525 | void tty_release_dev(struct file *filp) |
1930 | { | 1526 | { |
1931 | struct tty_struct *tty, *o_tty; | 1527 | struct tty_struct *tty, *o_tty; |
1932 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1528 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1933 | int devpts; | 1529 | int devpts; |
1934 | int idx; | 1530 | int idx; |
1935 | char buf[64]; | 1531 | char buf[64]; |
1532 | struct inode *inode; | ||
1936 | 1533 | ||
1534 | inode = filp->f_path.dentry->d_inode; | ||
1937 | tty = (struct tty_struct *)filp->private_data; | 1535 | tty = (struct tty_struct *)filp->private_data; |
1938 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, | 1536 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1939 | "release_dev")) | ||
1940 | return; | 1537 | return; |
1941 | 1538 | ||
1942 | check_tty_count(tty, "release_dev"); | 1539 | check_tty_count(tty, "tty_release_dev"); |
1943 | 1540 | ||
1944 | tty_fasync(-1, filp, 0); | 1541 | tty_fasync(-1, filp, 0); |
1945 | 1542 | ||
@@ -1951,33 +1548,27 @@ static void release_dev(struct file *filp) | |||
1951 | 1548 | ||
1952 | #ifdef TTY_PARANOIA_CHECK | 1549 | #ifdef TTY_PARANOIA_CHECK |
1953 | if (idx < 0 || idx >= tty->driver->num) { | 1550 | if (idx < 0 || idx >= tty->driver->num) { |
1954 | printk(KERN_DEBUG "release_dev: bad idx when trying to " | 1551 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " |
1955 | "free (%s)\n", tty->name); | 1552 | "free (%s)\n", tty->name); |
1956 | return; | 1553 | return; |
1957 | } | 1554 | } |
1958 | if (!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1555 | if (!devpts) { |
1959 | if (tty != tty->driver->ttys[idx]) { | 1556 | if (tty != tty->driver->ttys[idx]) { |
1960 | printk(KERN_DEBUG "release_dev: driver.table[%d] not tty " | 1557 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " |
1961 | "for (%s)\n", idx, tty->name); | 1558 | "for (%s)\n", idx, tty->name); |
1962 | return; | 1559 | return; |
1963 | } | 1560 | } |
1964 | if (tty->termios != tty->driver->termios[idx]) { | 1561 | if (tty->termios != tty->driver->termios[idx]) { |
1965 | printk(KERN_DEBUG "release_dev: driver.termios[%d] not termios " | 1562 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " |
1966 | "for (%s)\n", | 1563 | "for (%s)\n", |
1967 | idx, tty->name); | 1564 | idx, tty->name); |
1968 | return; | 1565 | return; |
1969 | } | 1566 | } |
1970 | if (tty->termios_locked != tty->driver->termios_locked[idx]) { | ||
1971 | printk(KERN_DEBUG "release_dev: driver.termios_locked[%d] not " | ||
1972 | "termios_locked for (%s)\n", | ||
1973 | idx, tty->name); | ||
1974 | return; | ||
1975 | } | ||
1976 | } | 1567 | } |
1977 | #endif | 1568 | #endif |
1978 | 1569 | ||
1979 | #ifdef TTY_DEBUG_HANGUP | 1570 | #ifdef TTY_DEBUG_HANGUP |
1980 | printk(KERN_DEBUG "release_dev of %s (tty count=%d)...", | 1571 | printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...", |
1981 | tty_name(tty, buf), tty->count); | 1572 | tty_name(tty, buf), tty->count); |
1982 | #endif | 1573 | #endif |
1983 | 1574 | ||
@@ -1985,26 +1576,19 @@ static void release_dev(struct file *filp) | |||
1985 | if (tty->driver->other && | 1576 | if (tty->driver->other && |
1986 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1577 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { |
1987 | if (o_tty != tty->driver->other->ttys[idx]) { | 1578 | if (o_tty != tty->driver->other->ttys[idx]) { |
1988 | printk(KERN_DEBUG "release_dev: other->table[%d] " | 1579 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " |
1989 | "not o_tty for (%s)\n", | 1580 | "not o_tty for (%s)\n", |
1990 | idx, tty->name); | 1581 | idx, tty->name); |
1991 | return; | 1582 | return; |
1992 | } | 1583 | } |
1993 | if (o_tty->termios != tty->driver->other->termios[idx]) { | 1584 | if (o_tty->termios != tty->driver->other->termios[idx]) { |
1994 | printk(KERN_DEBUG "release_dev: other->termios[%d] " | 1585 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " |
1995 | "not o_termios for (%s)\n", | 1586 | "not o_termios for (%s)\n", |
1996 | idx, tty->name); | 1587 | idx, tty->name); |
1997 | return; | 1588 | return; |
1998 | } | 1589 | } |
1999 | if (o_tty->termios_locked != | ||
2000 | tty->driver->other->termios_locked[idx]) { | ||
2001 | printk(KERN_DEBUG "release_dev: other->termios_locked[" | ||
2002 | "%d] not o_termios_locked for (%s)\n", | ||
2003 | idx, tty->name); | ||
2004 | return; | ||
2005 | } | ||
2006 | if (o_tty->link != tty) { | 1590 | if (o_tty->link != tty) { |
2007 | printk(KERN_DEBUG "release_dev: bad pty pointers\n"); | 1591 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); |
2008 | return; | 1592 | return; |
2009 | } | 1593 | } |
2010 | } | 1594 | } |
@@ -2062,7 +1646,7 @@ static void release_dev(struct file *filp) | |||
2062 | if (!do_sleep) | 1646 | if (!do_sleep) |
2063 | break; | 1647 | break; |
2064 | 1648 | ||
2065 | printk(KERN_WARNING "release_dev: %s: read/write wait queue " | 1649 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " |
2066 | "active!\n", tty_name(tty, buf)); | 1650 | "active!\n", tty_name(tty, buf)); |
2067 | mutex_unlock(&tty_mutex); | 1651 | mutex_unlock(&tty_mutex); |
2068 | schedule(); | 1652 | schedule(); |
@@ -2075,14 +1659,14 @@ static void release_dev(struct file *filp) | |||
2075 | */ | 1659 | */ |
2076 | if (pty_master) { | 1660 | if (pty_master) { |
2077 | if (--o_tty->count < 0) { | 1661 | if (--o_tty->count < 0) { |
2078 | printk(KERN_WARNING "release_dev: bad pty slave count " | 1662 | printk(KERN_WARNING "tty_release_dev: bad pty slave count " |
2079 | "(%d) for %s\n", | 1663 | "(%d) for %s\n", |
2080 | o_tty->count, tty_name(o_tty, buf)); | 1664 | o_tty->count, tty_name(o_tty, buf)); |
2081 | o_tty->count = 0; | 1665 | o_tty->count = 0; |
2082 | } | 1666 | } |
2083 | } | 1667 | } |
2084 | if (--tty->count < 0) { | 1668 | if (--tty->count < 0) { |
2085 | printk(KERN_WARNING "release_dev: bad tty->count (%d) for %s\n", | 1669 | printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n", |
2086 | tty->count, tty_name(tty, buf)); | 1670 | tty->count, tty_name(tty, buf)); |
2087 | tty->count = 0; | 1671 | tty->count = 0; |
2088 | } | 1672 | } |
@@ -2145,11 +1729,11 @@ static void release_dev(struct file *filp) | |||
2145 | 1729 | ||
2146 | /* Make this pty number available for reallocation */ | 1730 | /* Make this pty number available for reallocation */ |
2147 | if (devpts) | 1731 | if (devpts) |
2148 | devpts_kill_index(idx); | 1732 | devpts_kill_index(inode, idx); |
2149 | } | 1733 | } |
2150 | 1734 | ||
2151 | /** | 1735 | /** |
2152 | * tty_open - open a tty device | 1736 | * __tty_open - open a tty device |
2153 | * @inode: inode of device file | 1737 | * @inode: inode of device file |
2154 | * @filp: file pointer to tty | 1738 | * @filp: file pointer to tty |
2155 | * | 1739 | * |
@@ -2164,14 +1748,14 @@ static void release_dev(struct file *filp) | |||
2164 | * The termios state of a pty is reset on first open so that | 1748 | * The termios state of a pty is reset on first open so that |
2165 | * settings don't persist across reuse. | 1749 | * settings don't persist across reuse. |
2166 | * | 1750 | * |
2167 | * Locking: tty_mutex protects tty, get_tty_driver and init_dev work. | 1751 | * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work. |
2168 | * tty->count should protect the rest. | 1752 | * tty->count should protect the rest. |
2169 | * ->siglock protects ->signal/->sighand | 1753 | * ->siglock protects ->signal/->sighand |
2170 | */ | 1754 | */ |
2171 | 1755 | ||
2172 | static int __tty_open(struct inode *inode, struct file *filp) | 1756 | static int __tty_open(struct inode *inode, struct file *filp) |
2173 | { | 1757 | { |
2174 | struct tty_struct *tty; | 1758 | struct tty_struct *tty = NULL; |
2175 | int noctty, retval; | 1759 | int noctty, retval; |
2176 | struct tty_driver *driver; | 1760 | struct tty_driver *driver; |
2177 | int index; | 1761 | int index; |
@@ -2193,23 +1777,25 @@ retry_open: | |||
2193 | mutex_unlock(&tty_mutex); | 1777 | mutex_unlock(&tty_mutex); |
2194 | return -ENXIO; | 1778 | return -ENXIO; |
2195 | } | 1779 | } |
2196 | driver = tty->driver; | 1780 | driver = tty_driver_kref_get(tty->driver); |
2197 | index = tty->index; | 1781 | index = tty->index; |
2198 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | 1782 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ |
2199 | /* noctty = 1; */ | 1783 | /* noctty = 1; */ |
1784 | /* FIXME: Should we take a driver reference ? */ | ||
1785 | tty_kref_put(tty); | ||
2200 | goto got_driver; | 1786 | goto got_driver; |
2201 | } | 1787 | } |
2202 | #ifdef CONFIG_VT | 1788 | #ifdef CONFIG_VT |
2203 | if (device == MKDEV(TTY_MAJOR, 0)) { | 1789 | if (device == MKDEV(TTY_MAJOR, 0)) { |
2204 | extern struct tty_driver *console_driver; | 1790 | extern struct tty_driver *console_driver; |
2205 | driver = console_driver; | 1791 | driver = tty_driver_kref_get(console_driver); |
2206 | index = fg_console; | 1792 | index = fg_console; |
2207 | noctty = 1; | 1793 | noctty = 1; |
2208 | goto got_driver; | 1794 | goto got_driver; |
2209 | } | 1795 | } |
2210 | #endif | 1796 | #endif |
2211 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { | 1797 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { |
2212 | driver = console_device(&index); | 1798 | driver = tty_driver_kref_get(console_device(&index)); |
2213 | if (driver) { | 1799 | if (driver) { |
2214 | /* Don't let /dev/console block */ | 1800 | /* Don't let /dev/console block */ |
2215 | filp->f_flags |= O_NONBLOCK; | 1801 | filp->f_flags |= O_NONBLOCK; |
@@ -2226,10 +1812,25 @@ retry_open: | |||
2226 | return -ENODEV; | 1812 | return -ENODEV; |
2227 | } | 1813 | } |
2228 | got_driver: | 1814 | got_driver: |
2229 | retval = init_dev(driver, index, &tty); | 1815 | if (!tty) { |
1816 | /* check whether we're reopening an existing tty */ | ||
1817 | tty = tty_driver_lookup_tty(driver, inode, index); | ||
1818 | |||
1819 | if (IS_ERR(tty)) | ||
1820 | return PTR_ERR(tty); | ||
1821 | } | ||
1822 | |||
1823 | if (tty) { | ||
1824 | retval = tty_reopen(tty); | ||
1825 | if (retval) | ||
1826 | tty = ERR_PTR(retval); | ||
1827 | } else | ||
1828 | tty = tty_init_dev(driver, index, 0); | ||
1829 | |||
2230 | mutex_unlock(&tty_mutex); | 1830 | mutex_unlock(&tty_mutex); |
2231 | if (retval) | 1831 | tty_driver_kref_put(driver); |
2232 | return retval; | 1832 | if (IS_ERR(tty)) |
1833 | return PTR_ERR(tty); | ||
2233 | 1834 | ||
2234 | filp->private_data = tty; | 1835 | filp->private_data = tty; |
2235 | file_move(filp, &tty->tty_files); | 1836 | file_move(filp, &tty->tty_files); |
@@ -2257,7 +1858,7 @@ got_driver: | |||
2257 | printk(KERN_DEBUG "error %d in opening %s...", retval, | 1858 | printk(KERN_DEBUG "error %d in opening %s...", retval, |
2258 | tty->name); | 1859 | tty->name); |
2259 | #endif | 1860 | #endif |
2260 | release_dev(filp); | 1861 | tty_release_dev(filp); |
2261 | if (retval != -ERESTARTSYS) | 1862 | if (retval != -ERESTARTSYS) |
2262 | return retval; | 1863 | return retval; |
2263 | if (signal_pending(current)) | 1864 | if (signal_pending(current)) |
@@ -2296,69 +1897,6 @@ static int tty_open(struct inode *inode, struct file *filp) | |||
2296 | 1897 | ||
2297 | 1898 | ||
2298 | 1899 | ||
2299 | #ifdef CONFIG_UNIX98_PTYS | ||
2300 | /** | ||
2301 | * ptmx_open - open a unix 98 pty master | ||
2302 | * @inode: inode of device file | ||
2303 | * @filp: file pointer to tty | ||
2304 | * | ||
2305 | * Allocate a unix98 pty master device from the ptmx driver. | ||
2306 | * | ||
2307 | * Locking: tty_mutex protects theinit_dev work. tty->count should | ||
2308 | * protect the rest. | ||
2309 | * allocated_ptys_lock handles the list of free pty numbers | ||
2310 | */ | ||
2311 | |||
2312 | static int __ptmx_open(struct inode *inode, struct file *filp) | ||
2313 | { | ||
2314 | struct tty_struct *tty; | ||
2315 | int retval; | ||
2316 | int index; | ||
2317 | |||
2318 | nonseekable_open(inode, filp); | ||
2319 | |||
2320 | /* find a device that is not in use. */ | ||
2321 | index = devpts_new_index(); | ||
2322 | if (index < 0) | ||
2323 | return index; | ||
2324 | |||
2325 | mutex_lock(&tty_mutex); | ||
2326 | retval = init_dev(ptm_driver, index, &tty); | ||
2327 | mutex_unlock(&tty_mutex); | ||
2328 | |||
2329 | if (retval) | ||
2330 | goto out; | ||
2331 | |||
2332 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | ||
2333 | filp->private_data = tty; | ||
2334 | file_move(filp, &tty->tty_files); | ||
2335 | |||
2336 | retval = devpts_pty_new(tty->link); | ||
2337 | if (retval) | ||
2338 | goto out1; | ||
2339 | |||
2340 | check_tty_count(tty, "ptmx_open"); | ||
2341 | retval = ptm_driver->ops->open(tty, filp); | ||
2342 | if (!retval) | ||
2343 | return 0; | ||
2344 | out1: | ||
2345 | release_dev(filp); | ||
2346 | return retval; | ||
2347 | out: | ||
2348 | devpts_kill_index(index); | ||
2349 | return retval; | ||
2350 | } | ||
2351 | |||
2352 | static int ptmx_open(struct inode *inode, struct file *filp) | ||
2353 | { | ||
2354 | int ret; | ||
2355 | |||
2356 | lock_kernel(); | ||
2357 | ret = __ptmx_open(inode, filp); | ||
2358 | unlock_kernel(); | ||
2359 | return ret; | ||
2360 | } | ||
2361 | #endif | ||
2362 | 1900 | ||
2363 | /** | 1901 | /** |
2364 | * tty_release - vfs callback for close | 1902 | * tty_release - vfs callback for close |
@@ -2369,13 +1907,13 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
2369 | * this tty. There may however be several such references. | 1907 | * this tty. There may however be several such references. |
2370 | * | 1908 | * |
2371 | * Locking: | 1909 | * Locking: |
2372 | * Takes bkl. See release_dev | 1910 | * Takes bkl. See tty_release_dev |
2373 | */ | 1911 | */ |
2374 | 1912 | ||
2375 | static int tty_release(struct inode *inode, struct file *filp) | 1913 | static int tty_release(struct inode *inode, struct file *filp) |
2376 | { | 1914 | { |
2377 | lock_kernel(); | 1915 | lock_kernel(); |
2378 | release_dev(filp); | 1916 | tty_release_dev(filp); |
2379 | unlock_kernel(); | 1917 | unlock_kernel(); |
2380 | return 0; | 1918 | return 0; |
2381 | } | 1919 | } |
@@ -2524,7 +2062,7 @@ int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, | |||
2524 | 2062 | ||
2525 | /* For a PTY we need to lock the tty side */ | 2063 | /* For a PTY we need to lock the tty side */ |
2526 | mutex_lock(&real_tty->termios_mutex); | 2064 | mutex_lock(&real_tty->termios_mutex); |
2527 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) | 2065 | if (!memcmp(ws, &real_tty->winsize, sizeof(*ws))) |
2528 | goto done; | 2066 | goto done; |
2529 | /* Get the PID values and reference them so we can | 2067 | /* Get the PID values and reference them so we can |
2530 | avoid holding the tty ctrl lock while sending signals */ | 2068 | avoid holding the tty ctrl lock while sending signals */ |
@@ -2996,7 +2534,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2996 | case TIOCSTI: | 2534 | case TIOCSTI: |
2997 | return tiocsti(tty, p); | 2535 | return tiocsti(tty, p); |
2998 | case TIOCGWINSZ: | 2536 | case TIOCGWINSZ: |
2999 | return tiocgwinsz(tty, p); | 2537 | return tiocgwinsz(real_tty, p); |
3000 | case TIOCSWINSZ: | 2538 | case TIOCSWINSZ: |
3001 | return tiocswinsz(tty, real_tty, p); | 2539 | return tiocswinsz(tty, real_tty, p); |
3002 | case TIOCCONS: | 2540 | case TIOCCONS: |
@@ -3026,10 +2564,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3026 | return put_user(tty->ldisc.ops->num, (int __user *)p); | 2564 | return put_user(tty->ldisc.ops->num, (int __user *)p); |
3027 | case TIOCSETD: | 2565 | case TIOCSETD: |
3028 | return tiocsetd(tty, p); | 2566 | return tiocsetd(tty, p); |
3029 | #ifdef CONFIG_VT | ||
3030 | case TIOCLINUX: | ||
3031 | return tioclinux(tty, arg); | ||
3032 | #endif | ||
3033 | /* | 2567 | /* |
3034 | * Break handling | 2568 | * Break handling |
3035 | */ | 2569 | */ |
@@ -3220,113 +2754,6 @@ void do_SAK(struct tty_struct *tty) | |||
3220 | EXPORT_SYMBOL(do_SAK); | 2754 | EXPORT_SYMBOL(do_SAK); |
3221 | 2755 | ||
3222 | /** | 2756 | /** |
3223 | * flush_to_ldisc | ||
3224 | * @work: tty structure passed from work queue. | ||
3225 | * | ||
3226 | * This routine is called out of the software interrupt to flush data | ||
3227 | * from the buffer chain to the line discipline. | ||
3228 | * | ||
3229 | * Locking: holds tty->buf.lock to guard buffer list. Drops the lock | ||
3230 | * while invoking the line discipline receive_buf method. The | ||
3231 | * receive_buf method is single threaded for each tty instance. | ||
3232 | */ | ||
3233 | |||
3234 | static void flush_to_ldisc(struct work_struct *work) | ||
3235 | { | ||
3236 | struct tty_struct *tty = | ||
3237 | container_of(work, struct tty_struct, buf.work.work); | ||
3238 | unsigned long flags; | ||
3239 | struct tty_ldisc *disc; | ||
3240 | struct tty_buffer *tbuf, *head; | ||
3241 | char *char_buf; | ||
3242 | unsigned char *flag_buf; | ||
3243 | |||
3244 | disc = tty_ldisc_ref(tty); | ||
3245 | if (disc == NULL) /* !TTY_LDISC */ | ||
3246 | return; | ||
3247 | |||
3248 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
3249 | /* So we know a flush is running */ | ||
3250 | set_bit(TTY_FLUSHING, &tty->flags); | ||
3251 | head = tty->buf.head; | ||
3252 | if (head != NULL) { | ||
3253 | tty->buf.head = NULL; | ||
3254 | for (;;) { | ||
3255 | int count = head->commit - head->read; | ||
3256 | if (!count) { | ||
3257 | if (head->next == NULL) | ||
3258 | break; | ||
3259 | tbuf = head; | ||
3260 | head = head->next; | ||
3261 | tty_buffer_free(tty, tbuf); | ||
3262 | continue; | ||
3263 | } | ||
3264 | /* Ldisc or user is trying to flush the buffers | ||
3265 | we are feeding to the ldisc, stop feeding the | ||
3266 | line discipline as we want to empty the queue */ | ||
3267 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) | ||
3268 | break; | ||
3269 | if (!tty->receive_room) { | ||
3270 | schedule_delayed_work(&tty->buf.work, 1); | ||
3271 | break; | ||
3272 | } | ||
3273 | if (count > tty->receive_room) | ||
3274 | count = tty->receive_room; | ||
3275 | char_buf = head->char_buf_ptr + head->read; | ||
3276 | flag_buf = head->flag_buf_ptr + head->read; | ||
3277 | head->read += count; | ||
3278 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
3279 | disc->ops->receive_buf(tty, char_buf, | ||
3280 | flag_buf, count); | ||
3281 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
3282 | } | ||
3283 | /* Restore the queue head */ | ||
3284 | tty->buf.head = head; | ||
3285 | } | ||
3286 | /* We may have a deferred request to flush the input buffer, | ||
3287 | if so pull the chain under the lock and empty the queue */ | ||
3288 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { | ||
3289 | __tty_buffer_flush(tty); | ||
3290 | clear_bit(TTY_FLUSHPENDING, &tty->flags); | ||
3291 | wake_up(&tty->read_wait); | ||
3292 | } | ||
3293 | clear_bit(TTY_FLUSHING, &tty->flags); | ||
3294 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
3295 | |||
3296 | tty_ldisc_deref(disc); | ||
3297 | } | ||
3298 | |||
3299 | /** | ||
3300 | * tty_flip_buffer_push - terminal | ||
3301 | * @tty: tty to push | ||
3302 | * | ||
3303 | * Queue a push of the terminal flip buffers to the line discipline. This | ||
3304 | * function must not be called from IRQ context if tty->low_latency is set. | ||
3305 | * | ||
3306 | * In the event of the queue being busy for flipping the work will be | ||
3307 | * held off and retried later. | ||
3308 | * | ||
3309 | * Locking: tty buffer lock. Driver locks in low latency mode. | ||
3310 | */ | ||
3311 | |||
3312 | void tty_flip_buffer_push(struct tty_struct *tty) | ||
3313 | { | ||
3314 | unsigned long flags; | ||
3315 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
3316 | if (tty->buf.tail != NULL) | ||
3317 | tty->buf.tail->commit = tty->buf.tail->used; | ||
3318 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
3319 | |||
3320 | if (tty->low_latency) | ||
3321 | flush_to_ldisc(&tty->buf.work.work); | ||
3322 | else | ||
3323 | schedule_delayed_work(&tty->buf.work, 1); | ||
3324 | } | ||
3325 | |||
3326 | EXPORT_SYMBOL(tty_flip_buffer_push); | ||
3327 | |||
3328 | |||
3329 | /** | ||
3330 | * initialize_tty_struct | 2757 | * initialize_tty_struct |
3331 | * @tty: tty to initialize | 2758 | * @tty: tty to initialize |
3332 | * | 2759 | * |
@@ -3336,9 +2763,11 @@ EXPORT_SYMBOL(tty_flip_buffer_push); | |||
3336 | * Locking: none - tty in question must not be exposed at this point | 2763 | * Locking: none - tty in question must not be exposed at this point |
3337 | */ | 2764 | */ |
3338 | 2765 | ||
3339 | static void initialize_tty_struct(struct tty_struct *tty) | 2766 | void initialize_tty_struct(struct tty_struct *tty, |
2767 | struct tty_driver *driver, int idx) | ||
3340 | { | 2768 | { |
3341 | memset(tty, 0, sizeof(struct tty_struct)); | 2769 | memset(tty, 0, sizeof(struct tty_struct)); |
2770 | kref_init(&tty->kref); | ||
3342 | tty->magic = TTY_MAGIC; | 2771 | tty->magic = TTY_MAGIC; |
3343 | tty_ldisc_init(tty); | 2772 | tty_ldisc_init(tty); |
3344 | tty->session = NULL; | 2773 | tty->session = NULL; |
@@ -3346,7 +2775,6 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3346 | tty->overrun_time = jiffies; | 2775 | tty->overrun_time = jiffies; |
3347 | tty->buf.head = tty->buf.tail = NULL; | 2776 | tty->buf.head = tty->buf.tail = NULL; |
3348 | tty_buffer_init(tty); | 2777 | tty_buffer_init(tty); |
3349 | INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); | ||
3350 | mutex_init(&tty->termios_mutex); | 2778 | mutex_init(&tty->termios_mutex); |
3351 | init_waitqueue_head(&tty->write_wait); | 2779 | init_waitqueue_head(&tty->write_wait); |
3352 | init_waitqueue_head(&tty->read_wait); | 2780 | init_waitqueue_head(&tty->read_wait); |
@@ -3357,6 +2785,11 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3357 | spin_lock_init(&tty->ctrl_lock); | 2785 | spin_lock_init(&tty->ctrl_lock); |
3358 | INIT_LIST_HEAD(&tty->tty_files); | 2786 | INIT_LIST_HEAD(&tty->tty_files); |
3359 | INIT_WORK(&tty->SAK_work, do_SAK_work); | 2787 | INIT_WORK(&tty->SAK_work, do_SAK_work); |
2788 | |||
2789 | tty->driver = driver; | ||
2790 | tty->ops = driver->ops; | ||
2791 | tty->index = idx; | ||
2792 | tty_line_name(driver, idx, tty->name); | ||
3360 | } | 2793 | } |
3361 | 2794 | ||
3362 | /** | 2795 | /** |
@@ -3377,10 +2810,9 @@ int tty_put_char(struct tty_struct *tty, unsigned char ch) | |||
3377 | return tty->ops->put_char(tty, ch); | 2810 | return tty->ops->put_char(tty, ch); |
3378 | return tty->ops->write(tty, &ch, 1); | 2811 | return tty->ops->write(tty, &ch, 1); |
3379 | } | 2812 | } |
3380 | |||
3381 | EXPORT_SYMBOL_GPL(tty_put_char); | 2813 | EXPORT_SYMBOL_GPL(tty_put_char); |
3382 | 2814 | ||
3383 | static struct class *tty_class; | 2815 | struct class *tty_class; |
3384 | 2816 | ||
3385 | /** | 2817 | /** |
3386 | * tty_register_device - register a tty device | 2818 | * tty_register_device - register a tty device |
@@ -3420,6 +2852,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, | |||
3420 | 2852 | ||
3421 | return device_create_drvdata(tty_class, device, dev, NULL, name); | 2853 | return device_create_drvdata(tty_class, device, dev, NULL, name); |
3422 | } | 2854 | } |
2855 | EXPORT_SYMBOL(tty_register_device); | ||
3423 | 2856 | ||
3424 | /** | 2857 | /** |
3425 | * tty_unregister_device - unregister a tty device | 2858 | * tty_unregister_device - unregister a tty device |
@@ -3437,8 +2870,6 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) | |||
3437 | device_destroy(tty_class, | 2870 | device_destroy(tty_class, |
3438 | MKDEV(driver->major, driver->minor_start) + index); | 2871 | MKDEV(driver->major, driver->minor_start) + index); |
3439 | } | 2872 | } |
3440 | |||
3441 | EXPORT_SYMBOL(tty_register_device); | ||
3442 | EXPORT_SYMBOL(tty_unregister_device); | 2873 | EXPORT_SYMBOL(tty_unregister_device); |
3443 | 2874 | ||
3444 | struct tty_driver *alloc_tty_driver(int lines) | 2875 | struct tty_driver *alloc_tty_driver(int lines) |
@@ -3447,27 +2878,65 @@ struct tty_driver *alloc_tty_driver(int lines) | |||
3447 | 2878 | ||
3448 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); | 2879 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); |
3449 | if (driver) { | 2880 | if (driver) { |
2881 | kref_init(&driver->kref); | ||
3450 | driver->magic = TTY_DRIVER_MAGIC; | 2882 | driver->magic = TTY_DRIVER_MAGIC; |
3451 | driver->num = lines; | 2883 | driver->num = lines; |
3452 | /* later we'll move allocation of tables here */ | 2884 | /* later we'll move allocation of tables here */ |
3453 | } | 2885 | } |
3454 | return driver; | 2886 | return driver; |
3455 | } | 2887 | } |
2888 | EXPORT_SYMBOL(alloc_tty_driver); | ||
3456 | 2889 | ||
3457 | void put_tty_driver(struct tty_driver *driver) | 2890 | static void destruct_tty_driver(struct kref *kref) |
3458 | { | 2891 | { |
2892 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); | ||
2893 | int i; | ||
2894 | struct ktermios *tp; | ||
2895 | void *p; | ||
2896 | |||
2897 | if (driver->flags & TTY_DRIVER_INSTALLED) { | ||
2898 | /* | ||
2899 | * Free the termios and termios_locked structures because | ||
2900 | * we don't want to get memory leaks when modular tty | ||
2901 | * drivers are removed from the kernel. | ||
2902 | */ | ||
2903 | for (i = 0; i < driver->num; i++) { | ||
2904 | tp = driver->termios[i]; | ||
2905 | if (tp) { | ||
2906 | driver->termios[i] = NULL; | ||
2907 | kfree(tp); | ||
2908 | } | ||
2909 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) | ||
2910 | tty_unregister_device(driver, i); | ||
2911 | } | ||
2912 | p = driver->ttys; | ||
2913 | proc_tty_unregister_driver(driver); | ||
2914 | driver->ttys = NULL; | ||
2915 | driver->termios = NULL; | ||
2916 | kfree(p); | ||
2917 | cdev_del(&driver->cdev); | ||
2918 | } | ||
3459 | kfree(driver); | 2919 | kfree(driver); |
3460 | } | 2920 | } |
3461 | 2921 | ||
2922 | void tty_driver_kref_put(struct tty_driver *driver) | ||
2923 | { | ||
2924 | kref_put(&driver->kref, destruct_tty_driver); | ||
2925 | } | ||
2926 | EXPORT_SYMBOL(tty_driver_kref_put); | ||
2927 | |||
3462 | void tty_set_operations(struct tty_driver *driver, | 2928 | void tty_set_operations(struct tty_driver *driver, |
3463 | const struct tty_operations *op) | 2929 | const struct tty_operations *op) |
3464 | { | 2930 | { |
3465 | driver->ops = op; | 2931 | driver->ops = op; |
3466 | }; | 2932 | }; |
2933 | EXPORT_SYMBOL(tty_set_operations); | ||
3467 | 2934 | ||
3468 | EXPORT_SYMBOL(alloc_tty_driver); | 2935 | void put_tty_driver(struct tty_driver *d) |
2936 | { | ||
2937 | tty_driver_kref_put(d); | ||
2938 | } | ||
3469 | EXPORT_SYMBOL(put_tty_driver); | 2939 | EXPORT_SYMBOL(put_tty_driver); |
3470 | EXPORT_SYMBOL(tty_set_operations); | ||
3471 | 2940 | ||
3472 | /* | 2941 | /* |
3473 | * Called by a tty driver to register itself. | 2942 | * Called by a tty driver to register itself. |
@@ -3479,11 +2948,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3479 | dev_t dev; | 2948 | dev_t dev; |
3480 | void **p = NULL; | 2949 | void **p = NULL; |
3481 | 2950 | ||
3482 | if (driver->flags & TTY_DRIVER_INSTALLED) | ||
3483 | return 0; | ||
3484 | |||
3485 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { | 2951 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { |
3486 | p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); | 2952 | p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); |
3487 | if (!p) | 2953 | if (!p) |
3488 | return -ENOMEM; | 2954 | return -ENOMEM; |
3489 | } | 2955 | } |
@@ -3507,12 +2973,9 @@ int tty_register_driver(struct tty_driver *driver) | |||
3507 | if (p) { | 2973 | if (p) { |
3508 | driver->ttys = (struct tty_struct **)p; | 2974 | driver->ttys = (struct tty_struct **)p; |
3509 | driver->termios = (struct ktermios **)(p + driver->num); | 2975 | driver->termios = (struct ktermios **)(p + driver->num); |
3510 | driver->termios_locked = (struct ktermios **) | ||
3511 | (p + driver->num * 2); | ||
3512 | } else { | 2976 | } else { |
3513 | driver->ttys = NULL; | 2977 | driver->ttys = NULL; |
3514 | driver->termios = NULL; | 2978 | driver->termios = NULL; |
3515 | driver->termios_locked = NULL; | ||
3516 | } | 2979 | } |
3517 | 2980 | ||
3518 | cdev_init(&driver->cdev, &tty_fops); | 2981 | cdev_init(&driver->cdev, &tty_fops); |
@@ -3521,7 +2984,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3521 | if (error) { | 2984 | if (error) { |
3522 | unregister_chrdev_region(dev, driver->num); | 2985 | unregister_chrdev_region(dev, driver->num); |
3523 | driver->ttys = NULL; | 2986 | driver->ttys = NULL; |
3524 | driver->termios = driver->termios_locked = NULL; | 2987 | driver->termios = NULL; |
3525 | kfree(p); | 2988 | kfree(p); |
3526 | return error; | 2989 | return error; |
3527 | } | 2990 | } |
@@ -3535,6 +2998,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3535 | tty_register_device(driver, i, NULL); | 2998 | tty_register_device(driver, i, NULL); |
3536 | } | 2999 | } |
3537 | proc_tty_register_driver(driver); | 3000 | proc_tty_register_driver(driver); |
3001 | driver->flags |= TTY_DRIVER_INSTALLED; | ||
3538 | return 0; | 3002 | return 0; |
3539 | } | 3003 | } |
3540 | 3004 | ||
@@ -3545,46 +3009,19 @@ EXPORT_SYMBOL(tty_register_driver); | |||
3545 | */ | 3009 | */ |
3546 | int tty_unregister_driver(struct tty_driver *driver) | 3010 | int tty_unregister_driver(struct tty_driver *driver) |
3547 | { | 3011 | { |
3548 | int i; | 3012 | #if 0 |
3549 | struct ktermios *tp; | 3013 | /* FIXME */ |
3550 | void *p; | ||
3551 | |||
3552 | if (driver->refcount) | 3014 | if (driver->refcount) |
3553 | return -EBUSY; | 3015 | return -EBUSY; |
3554 | 3016 | #endif | |
3555 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), | 3017 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), |
3556 | driver->num); | 3018 | driver->num); |
3557 | mutex_lock(&tty_mutex); | 3019 | mutex_lock(&tty_mutex); |
3558 | list_del(&driver->tty_drivers); | 3020 | list_del(&driver->tty_drivers); |
3559 | mutex_unlock(&tty_mutex); | 3021 | mutex_unlock(&tty_mutex); |
3560 | |||
3561 | /* | ||
3562 | * Free the termios and termios_locked structures because | ||
3563 | * we don't want to get memory leaks when modular tty | ||
3564 | * drivers are removed from the kernel. | ||
3565 | */ | ||
3566 | for (i = 0; i < driver->num; i++) { | ||
3567 | tp = driver->termios[i]; | ||
3568 | if (tp) { | ||
3569 | driver->termios[i] = NULL; | ||
3570 | kfree(tp); | ||
3571 | } | ||
3572 | tp = driver->termios_locked[i]; | ||
3573 | if (tp) { | ||
3574 | driver->termios_locked[i] = NULL; | ||
3575 | kfree(tp); | ||
3576 | } | ||
3577 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) | ||
3578 | tty_unregister_device(driver, i); | ||
3579 | } | ||
3580 | p = driver->ttys; | ||
3581 | proc_tty_unregister_driver(driver); | ||
3582 | driver->ttys = NULL; | ||
3583 | driver->termios = driver->termios_locked = NULL; | ||
3584 | kfree(p); | ||
3585 | cdev_del(&driver->cdev); | ||
3586 | return 0; | 3022 | return 0; |
3587 | } | 3023 | } |
3024 | |||
3588 | EXPORT_SYMBOL(tty_unregister_driver); | 3025 | EXPORT_SYMBOL(tty_unregister_driver); |
3589 | 3026 | ||
3590 | dev_t tty_devnum(struct tty_struct *tty) | 3027 | dev_t tty_devnum(struct tty_struct *tty) |
@@ -3595,9 +3032,12 @@ EXPORT_SYMBOL(tty_devnum); | |||
3595 | 3032 | ||
3596 | void proc_clear_tty(struct task_struct *p) | 3033 | void proc_clear_tty(struct task_struct *p) |
3597 | { | 3034 | { |
3035 | struct tty_struct *tty; | ||
3598 | spin_lock_irq(&p->sighand->siglock); | 3036 | spin_lock_irq(&p->sighand->siglock); |
3037 | tty = p->signal->tty; | ||
3599 | p->signal->tty = NULL; | 3038 | p->signal->tty = NULL; |
3600 | spin_unlock_irq(&p->sighand->siglock); | 3039 | spin_unlock_irq(&p->sighand->siglock); |
3040 | tty_kref_put(tty); | ||
3601 | } | 3041 | } |
3602 | 3042 | ||
3603 | /* Called under the sighand lock */ | 3043 | /* Called under the sighand lock */ |
@@ -3613,9 +3053,13 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | |||
3613 | tty->pgrp = get_pid(task_pgrp(tsk)); | 3053 | tty->pgrp = get_pid(task_pgrp(tsk)); |
3614 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 3054 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
3615 | tty->session = get_pid(task_session(tsk)); | 3055 | tty->session = get_pid(task_session(tsk)); |
3056 | if (tsk->signal->tty) { | ||
3057 | printk(KERN_DEBUG "tty not NULL!!\n"); | ||
3058 | tty_kref_put(tsk->signal->tty); | ||
3059 | } | ||
3616 | } | 3060 | } |
3617 | put_pid(tsk->signal->tty_old_pgrp); | 3061 | put_pid(tsk->signal->tty_old_pgrp); |
3618 | tsk->signal->tty = tty; | 3062 | tsk->signal->tty = tty_kref_get(tty); |
3619 | tsk->signal->tty_old_pgrp = NULL; | 3063 | tsk->signal->tty_old_pgrp = NULL; |
3620 | } | 3064 | } |
3621 | 3065 | ||
@@ -3629,18 +3073,20 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | |||
3629 | struct tty_struct *get_current_tty(void) | 3073 | struct tty_struct *get_current_tty(void) |
3630 | { | 3074 | { |
3631 | struct tty_struct *tty; | 3075 | struct tty_struct *tty; |
3632 | WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); | 3076 | unsigned long flags; |
3633 | tty = current->signal->tty; | 3077 | |
3634 | /* | 3078 | spin_lock_irqsave(¤t->sighand->siglock, flags); |
3635 | * session->tty can be changed/cleared from under us, make sure we | 3079 | tty = tty_kref_get(current->signal->tty); |
3636 | * issue the load. The obtained pointer, when not NULL, is valid as | 3080 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); |
3637 | * long as we hold tty_mutex. | ||
3638 | */ | ||
3639 | barrier(); | ||
3640 | return tty; | 3081 | return tty; |
3641 | } | 3082 | } |
3642 | EXPORT_SYMBOL_GPL(get_current_tty); | 3083 | EXPORT_SYMBOL_GPL(get_current_tty); |
3643 | 3084 | ||
3085 | void tty_default_fops(struct file_operations *fops) | ||
3086 | { | ||
3087 | *fops = tty_fops; | ||
3088 | } | ||
3089 | |||
3644 | /* | 3090 | /* |
3645 | * Initialize the console device. This is called *early*, so | 3091 | * Initialize the console device. This is called *early*, so |
3646 | * we can't necessarily depend on lots of kernel help here. | 3092 | * we can't necessarily depend on lots of kernel help here. |
@@ -3678,12 +3124,6 @@ postcore_initcall(tty_class_init); | |||
3678 | /* 3/2004 jmc: why do these devices exist? */ | 3124 | /* 3/2004 jmc: why do these devices exist? */ |
3679 | 3125 | ||
3680 | static struct cdev tty_cdev, console_cdev; | 3126 | static struct cdev tty_cdev, console_cdev; |
3681 | #ifdef CONFIG_UNIX98_PTYS | ||
3682 | static struct cdev ptmx_cdev; | ||
3683 | #endif | ||
3684 | #ifdef CONFIG_VT | ||
3685 | static struct cdev vc0_cdev; | ||
3686 | #endif | ||
3687 | 3127 | ||
3688 | /* | 3128 | /* |
3689 | * Ok, now we can initialize the rest of the tty devices and can count | 3129 | * Ok, now we can initialize the rest of the tty devices and can count |
@@ -3695,32 +3135,18 @@ static int __init tty_init(void) | |||
3695 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || | 3135 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || |
3696 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) | 3136 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) |
3697 | panic("Couldn't register /dev/tty driver\n"); | 3137 | panic("Couldn't register /dev/tty driver\n"); |
3698 | device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, | 3138 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, |
3699 | "tty"); | 3139 | "tty"); |
3700 | 3140 | ||
3701 | cdev_init(&console_cdev, &console_fops); | 3141 | cdev_init(&console_cdev, &console_fops); |
3702 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || | 3142 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || |
3703 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) | 3143 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) |
3704 | panic("Couldn't register /dev/console driver\n"); | 3144 | panic("Couldn't register /dev/console driver\n"); |
3705 | device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, | 3145 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, |
3706 | "console"); | 3146 | "console"); |
3707 | 3147 | ||
3708 | #ifdef CONFIG_UNIX98_PTYS | ||
3709 | cdev_init(&ptmx_cdev, &ptmx_fops); | ||
3710 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || | ||
3711 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) | ||
3712 | panic("Couldn't register /dev/ptmx driver\n"); | ||
3713 | device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); | ||
3714 | #endif | ||
3715 | |||
3716 | #ifdef CONFIG_VT | 3148 | #ifdef CONFIG_VT |
3717 | cdev_init(&vc0_cdev, &console_fops); | 3149 | vty_init(&console_fops); |
3718 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || | ||
3719 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) | ||
3720 | panic("Couldn't register /dev/tty0 driver\n"); | ||
3721 | device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); | ||
3722 | |||
3723 | vty_init(); | ||
3724 | #endif | 3150 | #endif |
3725 | return 0; | 3151 | return 0; |
3726 | } | 3152 | } |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index bf34e4597421..a408c8e487ec 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -40,6 +40,15 @@ | |||
40 | #define TERMIOS_OLD 8 | 40 | #define TERMIOS_OLD 8 |
41 | 41 | ||
42 | 42 | ||
43 | /** | ||
44 | * tty_chars_in_buffer - characters pending | ||
45 | * @tty: terminal | ||
46 | * | ||
47 | * Return the number of bytes of data in the device private | ||
48 | * output queue. If no private method is supplied there is assumed | ||
49 | * to be no queue on the device. | ||
50 | */ | ||
51 | |||
43 | int tty_chars_in_buffer(struct tty_struct *tty) | 52 | int tty_chars_in_buffer(struct tty_struct *tty) |
44 | { | 53 | { |
45 | if (tty->ops->chars_in_buffer) | 54 | if (tty->ops->chars_in_buffer) |
@@ -47,26 +56,49 @@ int tty_chars_in_buffer(struct tty_struct *tty) | |||
47 | else | 56 | else |
48 | return 0; | 57 | return 0; |
49 | } | 58 | } |
50 | |||
51 | EXPORT_SYMBOL(tty_chars_in_buffer); | 59 | EXPORT_SYMBOL(tty_chars_in_buffer); |
52 | 60 | ||
61 | /** | ||
62 | * tty_write_room - write queue space | ||
63 | * @tty: terminal | ||
64 | * | ||
65 | * Return the number of bytes that can be queued to this device | ||
66 | * at the present time. The result should be treated as a guarantee | ||
67 | * and the driver cannot offer a value it later shrinks by more than | ||
68 | * the number of bytes written. If no method is provided 2K is always | ||
69 | * returned and data may be lost as there will be no flow control. | ||
70 | */ | ||
71 | |||
53 | int tty_write_room(struct tty_struct *tty) | 72 | int tty_write_room(struct tty_struct *tty) |
54 | { | 73 | { |
55 | if (tty->ops->write_room) | 74 | if (tty->ops->write_room) |
56 | return tty->ops->write_room(tty); | 75 | return tty->ops->write_room(tty); |
57 | return 2048; | 76 | return 2048; |
58 | } | 77 | } |
59 | |||
60 | EXPORT_SYMBOL(tty_write_room); | 78 | EXPORT_SYMBOL(tty_write_room); |
61 | 79 | ||
80 | /** | ||
81 | * tty_driver_flush_buffer - discard internal buffer | ||
82 | * @tty: terminal | ||
83 | * | ||
84 | * Discard the internal output buffer for this device. If no method | ||
85 | * is provided then either the buffer cannot be hardware flushed or | ||
86 | * there is no buffer driver side. | ||
87 | */ | ||
62 | void tty_driver_flush_buffer(struct tty_struct *tty) | 88 | void tty_driver_flush_buffer(struct tty_struct *tty) |
63 | { | 89 | { |
64 | if (tty->ops->flush_buffer) | 90 | if (tty->ops->flush_buffer) |
65 | tty->ops->flush_buffer(tty); | 91 | tty->ops->flush_buffer(tty); |
66 | } | 92 | } |
67 | |||
68 | EXPORT_SYMBOL(tty_driver_flush_buffer); | 93 | EXPORT_SYMBOL(tty_driver_flush_buffer); |
69 | 94 | ||
95 | /** | ||
96 | * tty_throttle - flow control | ||
97 | * @tty: terminal | ||
98 | * | ||
99 | * Indicate that a tty should stop transmitting data down the stack. | ||
100 | */ | ||
101 | |||
70 | void tty_throttle(struct tty_struct *tty) | 102 | void tty_throttle(struct tty_struct *tty) |
71 | { | 103 | { |
72 | /* check TTY_THROTTLED first so it indicates our state */ | 104 | /* check TTY_THROTTLED first so it indicates our state */ |
@@ -76,6 +108,13 @@ void tty_throttle(struct tty_struct *tty) | |||
76 | } | 108 | } |
77 | EXPORT_SYMBOL(tty_throttle); | 109 | EXPORT_SYMBOL(tty_throttle); |
78 | 110 | ||
111 | /** | ||
112 | * tty_unthrottle - flow control | ||
113 | * @tty: terminal | ||
114 | * | ||
115 | * Indicate that a tty may continue transmitting data down the stack. | ||
116 | */ | ||
117 | |||
79 | void tty_unthrottle(struct tty_struct *tty) | 118 | void tty_unthrottle(struct tty_struct *tty) |
80 | { | 119 | { |
81 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && | 120 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && |
@@ -112,6 +151,11 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout) | |||
112 | } | 151 | } |
113 | EXPORT_SYMBOL(tty_wait_until_sent); | 152 | EXPORT_SYMBOL(tty_wait_until_sent); |
114 | 153 | ||
154 | |||
155 | /* | ||
156 | * Termios Helper Methods | ||
157 | */ | ||
158 | |||
115 | static void unset_locked_termios(struct ktermios *termios, | 159 | static void unset_locked_termios(struct ktermios *termios, |
116 | struct ktermios *old, | 160 | struct ktermios *old, |
117 | struct ktermios *locked) | 161 | struct ktermios *locked) |
@@ -346,6 +390,16 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, | |||
346 | } | 390 | } |
347 | EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); | 391 | EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); |
348 | 392 | ||
393 | /** | ||
394 | * tty_encode_baud_rate - set baud rate of the tty | ||
395 | * @ibaud: input baud rate | ||
396 | * @obad: output baud rate | ||
397 | * | ||
398 | * Update the current termios data for the tty with the new speed | ||
399 | * settings. The caller must hold the termios_mutex for the tty in | ||
400 | * question. | ||
401 | */ | ||
402 | |||
349 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) | 403 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) |
350 | { | 404 | { |
351 | tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); | 405 | tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); |
@@ -430,12 +484,11 @@ EXPORT_SYMBOL(tty_termios_hw_change); | |||
430 | * is a bit of layering violation here with n_tty in terms of the | 484 | * is a bit of layering violation here with n_tty in terms of the |
431 | * internal knowledge of this function. | 485 | * internal knowledge of this function. |
432 | * | 486 | * |
433 | * Locking: termios_sem | 487 | * Locking: termios_mutex |
434 | */ | 488 | */ |
435 | 489 | ||
436 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | 490 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) |
437 | { | 491 | { |
438 | int canon_change; | ||
439 | struct ktermios old_termios; | 492 | struct ktermios old_termios; |
440 | struct tty_ldisc *ld; | 493 | struct tty_ldisc *ld; |
441 | unsigned long flags; | 494 | unsigned long flags; |
@@ -451,18 +504,6 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
451 | old_termios = *tty->termios; | 504 | old_termios = *tty->termios; |
452 | *tty->termios = *new_termios; | 505 | *tty->termios = *new_termios; |
453 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); | 506 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); |
454 | canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; | ||
455 | if (canon_change) { | ||
456 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | ||
457 | tty->canon_head = tty->read_tail; | ||
458 | tty->canon_data = 0; | ||
459 | tty->erasing = 0; | ||
460 | } | ||
461 | |||
462 | /* This bit should be in the ldisc code */ | ||
463 | if (canon_change && !L_ICANON(tty) && tty->read_cnt) | ||
464 | /* Get characters left over from canonical mode. */ | ||
465 | wake_up_interruptible(&tty->read_wait); | ||
466 | 507 | ||
467 | /* See if packet mode change of state. */ | 508 | /* See if packet mode change of state. */ |
468 | if (tty->link && tty->link->packet) { | 509 | if (tty->link && tty->link->packet) { |
@@ -508,7 +549,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
508 | * functions before using change_termios to do the actual changes. | 549 | * functions before using change_termios to do the actual changes. |
509 | * | 550 | * |
510 | * Locking: | 551 | * Locking: |
511 | * Called functions take ldisc and termios_sem locks | 552 | * Called functions take ldisc and termios_mutex locks |
512 | */ | 553 | */ |
513 | 554 | ||
514 | static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | 555 | static int set_termios(struct tty_struct *tty, void __user *arg, int opt) |
@@ -579,25 +620,51 @@ static int get_termio(struct tty_struct *tty, struct termio __user *termio) | |||
579 | return 0; | 620 | return 0; |
580 | } | 621 | } |
581 | 622 | ||
582 | static unsigned long inq_canon(struct tty_struct *tty) | 623 | |
624 | #ifdef TCGETX | ||
625 | |||
626 | /** | ||
627 | * set_termiox - set termiox fields if possible | ||
628 | * @tty: terminal | ||
629 | * @arg: termiox structure from user | ||
630 | * @opt: option flags for ioctl type | ||
631 | * | ||
632 | * Implement the device calling points for the SYS5 termiox ioctl | ||
633 | * interface in Linux | ||
634 | */ | ||
635 | |||
636 | static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) | ||
583 | { | 637 | { |
584 | int nr, head, tail; | 638 | struct termiox tnew; |
639 | struct tty_ldisc *ld; | ||
585 | 640 | ||
586 | if (!tty->canon_data || !tty->read_buf) | 641 | if (tty->termiox == NULL) |
587 | return 0; | 642 | return -EINVAL; |
588 | head = tty->canon_head; | 643 | if (copy_from_user(&tnew, arg, sizeof(struct termiox))) |
589 | tail = tty->read_tail; | 644 | return -EFAULT; |
590 | nr = (head - tail) & (N_TTY_BUF_SIZE-1); | 645 | |
591 | /* Skip EOF-chars.. */ | 646 | ld = tty_ldisc_ref(tty); |
592 | while (head != tail) { | 647 | if (ld != NULL) { |
593 | if (test_bit(tail, tty->read_flags) && | 648 | if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) |
594 | tty->read_buf[tail] == __DISABLED_CHAR) | 649 | ld->ops->flush_buffer(tty); |
595 | nr--; | 650 | tty_ldisc_deref(ld); |
596 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | ||
597 | } | 651 | } |
598 | return nr; | 652 | if (opt & TERMIOS_WAIT) { |
653 | tty_wait_until_sent(tty, 0); | ||
654 | if (signal_pending(current)) | ||
655 | return -EINTR; | ||
656 | } | ||
657 | |||
658 | mutex_lock(&tty->termios_mutex); | ||
659 | if (tty->ops->set_termiox) | ||
660 | tty->ops->set_termiox(tty, &tnew); | ||
661 | mutex_unlock(&tty->termios_mutex); | ||
662 | return 0; | ||
599 | } | 663 | } |
600 | 664 | ||
665 | #endif | ||
666 | |||
667 | |||
601 | #ifdef TIOCGETP | 668 | #ifdef TIOCGETP |
602 | /* | 669 | /* |
603 | * These are deprecated, but there is limited support.. | 670 | * These are deprecated, but there is limited support.. |
@@ -671,7 +738,7 @@ static void set_sgflags(struct ktermios *termios, int flags) | |||
671 | * Updates a terminal from the legacy BSD style terminal information | 738 | * Updates a terminal from the legacy BSD style terminal information |
672 | * structure. | 739 | * structure. |
673 | * | 740 | * |
674 | * Locking: termios_sem | 741 | * Locking: termios_mutex |
675 | */ | 742 | */ |
676 | 743 | ||
677 | static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) | 744 | static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) |
@@ -849,6 +916,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
849 | { | 916 | { |
850 | struct tty_struct *real_tty; | 917 | struct tty_struct *real_tty; |
851 | void __user *p = (void __user *)arg; | 918 | void __user *p = (void __user *)arg; |
919 | int ret = 0; | ||
852 | 920 | ||
853 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 921 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
854 | tty->driver->subtype == PTY_TYPE_MASTER) | 922 | tty->driver->subtype == PTY_TYPE_MASTER) |
@@ -884,18 +952,24 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
884 | return set_termios(real_tty, p, TERMIOS_OLD); | 952 | return set_termios(real_tty, p, TERMIOS_OLD); |
885 | #ifndef TCGETS2 | 953 | #ifndef TCGETS2 |
886 | case TCGETS: | 954 | case TCGETS: |
955 | mutex_lock(&real_tty->termios_mutex); | ||
887 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) | 956 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) |
888 | return -EFAULT; | 957 | ret = -EFAULT; |
889 | return 0; | 958 | mutex_unlock(&real_tty->termios_mutex); |
959 | return ret; | ||
890 | #else | 960 | #else |
891 | case TCGETS: | 961 | case TCGETS: |
962 | mutex_lock(&real_tty->termios_mutex); | ||
892 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) | 963 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) |
893 | return -EFAULT; | 964 | ret = -EFAULT; |
894 | return 0; | 965 | mutex_unlock(&real_tty->termios_mutex); |
966 | return ret; | ||
895 | case TCGETS2: | 967 | case TCGETS2: |
968 | mutex_lock(&real_tty->termios_mutex); | ||
896 | if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) | 969 | if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) |
897 | return -EFAULT; | 970 | ret = -EFAULT; |
898 | return 0; | 971 | mutex_unlock(&real_tty->termios_mutex); |
972 | return ret; | ||
899 | case TCSETSF2: | 973 | case TCSETSF2: |
900 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); | 974 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); |
901 | case TCSETSW2: | 975 | case TCSETSW2: |
@@ -913,34 +987,59 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
913 | return set_termios(real_tty, p, TERMIOS_TERMIO); | 987 | return set_termios(real_tty, p, TERMIOS_TERMIO); |
914 | #ifndef TCGETS2 | 988 | #ifndef TCGETS2 |
915 | case TIOCGLCKTRMIOS: | 989 | case TIOCGLCKTRMIOS: |
990 | mutex_lock(&real_tty->termios_mutex); | ||
916 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) | 991 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) |
917 | return -EFAULT; | 992 | ret = -EFAULT; |
918 | return 0; | 993 | mutex_unlock(&real_tty->termios_mutex); |
994 | return ret; | ||
919 | case TIOCSLCKTRMIOS: | 995 | case TIOCSLCKTRMIOS: |
920 | if (!capable(CAP_SYS_ADMIN)) | 996 | if (!capable(CAP_SYS_ADMIN)) |
921 | return -EPERM; | 997 | return -EPERM; |
998 | mutex_lock(&real_tty->termios_mutex); | ||
922 | if (user_termios_to_kernel_termios(real_tty->termios_locked, | 999 | if (user_termios_to_kernel_termios(real_tty->termios_locked, |
923 | (struct termios __user *) arg)) | 1000 | (struct termios __user *) arg)) |
924 | return -EFAULT; | 1001 | ret = -EFAULT; |
925 | return 0; | 1002 | mutex_unlock(&real_tty->termios_mutex); |
1003 | return ret; | ||
926 | #else | 1004 | #else |
927 | case TIOCGLCKTRMIOS: | 1005 | case TIOCGLCKTRMIOS: |
1006 | mutex_lock(&real_tty->termios_mutex); | ||
928 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) | 1007 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) |
929 | return -EFAULT; | 1008 | ret = -EFAULT; |
930 | return 0; | 1009 | mutex_unlock(&real_tty->termios_mutex); |
1010 | return ret; | ||
931 | case TIOCSLCKTRMIOS: | 1011 | case TIOCSLCKTRMIOS: |
932 | if (!capable(CAP_SYS_ADMIN)) | 1012 | if (!capable(CAP_SYS_ADMIN)) |
933 | return -EPERM; | 1013 | ret = -EPERM; |
1014 | mutex_lock(&real_tty->termios_mutex); | ||
934 | if (user_termios_to_kernel_termios_1(real_tty->termios_locked, | 1015 | if (user_termios_to_kernel_termios_1(real_tty->termios_locked, |
935 | (struct termios __user *) arg)) | 1016 | (struct termios __user *) arg)) |
936 | return -EFAULT; | 1017 | ret = -EFAULT; |
937 | return 0; | 1018 | mutex_unlock(&real_tty->termios_mutex); |
1019 | return ret; | ||
938 | #endif | 1020 | #endif |
1021 | #ifdef TCGETX | ||
1022 | case TCGETX: | ||
1023 | if (real_tty->termiox == NULL) | ||
1024 | return -EINVAL; | ||
1025 | mutex_lock(&real_tty->termios_mutex); | ||
1026 | if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox))) | ||
1027 | ret = -EFAULT; | ||
1028 | mutex_unlock(&real_tty->termios_mutex); | ||
1029 | return ret; | ||
1030 | case TCSETX: | ||
1031 | return set_termiox(real_tty, p, 0); | ||
1032 | case TCSETXW: | ||
1033 | return set_termiox(real_tty, p, TERMIOS_WAIT); | ||
1034 | case TCSETXF: | ||
1035 | return set_termiox(real_tty, p, TERMIOS_FLUSH); | ||
1036 | #endif | ||
939 | case TIOCGSOFTCAR: | 1037 | case TIOCGSOFTCAR: |
940 | /* FIXME: for correctness we may need to take the termios | 1038 | mutex_lock(&real_tty->termios_mutex); |
941 | lock here - review */ | 1039 | ret = put_user(C_CLOCAL(real_tty) ? 1 : 0, |
942 | return put_user(C_CLOCAL(real_tty) ? 1 : 0, | ||
943 | (int __user *)arg); | 1040 | (int __user *)arg); |
1041 | mutex_unlock(&real_tty->termios_mutex); | ||
1042 | return ret; | ||
944 | case TIOCSSOFTCAR: | 1043 | case TIOCSSOFTCAR: |
945 | if (get_user(arg, (unsigned int __user *) arg)) | 1044 | if (get_user(arg, (unsigned int __user *) arg)) |
946 | return -EFAULT; | 1045 | return -EFAULT; |
@@ -980,7 +1079,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | |||
980 | } | 1079 | } |
981 | EXPORT_SYMBOL_GPL(tty_perform_flush); | 1080 | EXPORT_SYMBOL_GPL(tty_perform_flush); |
982 | 1081 | ||
983 | int n_tty_ioctl(struct tty_struct *tty, struct file *file, | 1082 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
984 | unsigned int cmd, unsigned long arg) | 1083 | unsigned int cmd, unsigned long arg) |
985 | { | 1084 | { |
986 | unsigned long flags; | 1085 | unsigned long flags; |
@@ -1018,13 +1117,6 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
1018 | return 0; | 1117 | return 0; |
1019 | case TCFLSH: | 1118 | case TCFLSH: |
1020 | return tty_perform_flush(tty, arg); | 1119 | return tty_perform_flush(tty, arg); |
1021 | case TIOCOUTQ: | ||
1022 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); | ||
1023 | case TIOCINQ: | ||
1024 | retval = tty->read_cnt; | ||
1025 | if (L_ICANON(tty)) | ||
1026 | retval = inq_canon(tty); | ||
1027 | return put_user(retval, (unsigned int __user *) arg); | ||
1028 | case TIOCPKT: | 1120 | case TIOCPKT: |
1029 | { | 1121 | { |
1030 | int pktmode; | 1122 | int pktmode; |
@@ -1050,4 +1142,4 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
1050 | return tty_mode_ioctl(tty, file, cmd, arg); | 1142 | return tty_mode_ioctl(tty, file, cmd, arg); |
1051 | } | 1143 | } |
1052 | } | 1144 | } |
1053 | EXPORT_SYMBOL(n_tty_ioctl); | 1145 | EXPORT_SYMBOL(n_tty_ioctl_helper); |
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c new file mode 100644 index 000000000000..553b0e9d8d17 --- /dev/null +++ b/drivers/char/tty_port.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Tty port functions | ||
3 | */ | ||
4 | |||
5 | #include <linux/types.h> | ||
6 | #include <linux/errno.h> | ||
7 | #include <linux/tty.h> | ||
8 | #include <linux/tty_driver.h> | ||
9 | #include <linux/tty_flip.h> | ||
10 | #include <linux/timer.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/wait.h> | ||
16 | #include <linux/bitops.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/module.h> | ||
19 | |||
20 | void tty_port_init(struct tty_port *port) | ||
21 | { | ||
22 | memset(port, 0, sizeof(*port)); | ||
23 | init_waitqueue_head(&port->open_wait); | ||
24 | init_waitqueue_head(&port->close_wait); | ||
25 | mutex_init(&port->mutex); | ||
26 | spin_lock_init(&port->lock); | ||
27 | port->close_delay = (50 * HZ) / 100; | ||
28 | port->closing_wait = (3000 * HZ) / 100; | ||
29 | } | ||
30 | EXPORT_SYMBOL(tty_port_init); | ||
31 | |||
32 | int tty_port_alloc_xmit_buf(struct tty_port *port) | ||
33 | { | ||
34 | /* We may sleep in get_zeroed_page() */ | ||
35 | mutex_lock(&port->mutex); | ||
36 | if (port->xmit_buf == NULL) | ||
37 | port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); | ||
38 | mutex_unlock(&port->mutex); | ||
39 | if (port->xmit_buf == NULL) | ||
40 | return -ENOMEM; | ||
41 | return 0; | ||
42 | } | ||
43 | EXPORT_SYMBOL(tty_port_alloc_xmit_buf); | ||
44 | |||
45 | void tty_port_free_xmit_buf(struct tty_port *port) | ||
46 | { | ||
47 | mutex_lock(&port->mutex); | ||
48 | if (port->xmit_buf != NULL) { | ||
49 | free_page((unsigned long)port->xmit_buf); | ||
50 | port->xmit_buf = NULL; | ||
51 | } | ||
52 | mutex_unlock(&port->mutex); | ||
53 | } | ||
54 | EXPORT_SYMBOL(tty_port_free_xmit_buf); | ||
55 | |||
56 | |||
57 | /** | ||
58 | * tty_port_tty_get - get a tty reference | ||
59 | * @port: tty port | ||
60 | * | ||
61 | * Return a refcount protected tty instance or NULL if the port is not | ||
62 | * associated with a tty (eg due to close or hangup) | ||
63 | */ | ||
64 | |||
65 | struct tty_struct *tty_port_tty_get(struct tty_port *port) | ||
66 | { | ||
67 | unsigned long flags; | ||
68 | struct tty_struct *tty; | ||
69 | |||
70 | spin_lock_irqsave(&port->lock, flags); | ||
71 | tty = tty_kref_get(port->tty); | ||
72 | spin_unlock_irqrestore(&port->lock, flags); | ||
73 | return tty; | ||
74 | } | ||
75 | EXPORT_SYMBOL(tty_port_tty_get); | ||
76 | |||
77 | /** | ||
78 | * tty_port_tty_set - set the tty of a port | ||
79 | * @port: tty port | ||
80 | * @tty: the tty | ||
81 | * | ||
82 | * Associate the port and tty pair. Manages any internal refcounts. | ||
83 | * Pass NULL to deassociate a port | ||
84 | */ | ||
85 | |||
86 | void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty) | ||
87 | { | ||
88 | unsigned long flags; | ||
89 | |||
90 | spin_lock_irqsave(&port->lock, flags); | ||
91 | if (port->tty) | ||
92 | tty_kref_put(port->tty); | ||
93 | port->tty = tty; | ||
94 | spin_unlock_irqrestore(&port->lock, flags); | ||
95 | } | ||
96 | EXPORT_SYMBOL(tty_port_tty_set); | ||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 60359c360912..57029fefd64a 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -100,10 +100,10 @@ | |||
100 | #include <linux/font.h> | 100 | #include <linux/font.h> |
101 | #include <linux/bitops.h> | 101 | #include <linux/bitops.h> |
102 | #include <linux/notifier.h> | 102 | #include <linux/notifier.h> |
103 | 103 | #include <linux/device.h> | |
104 | #include <asm/io.h> | 104 | #include <linux/io.h> |
105 | #include <asm/system.h> | 105 | #include <asm/system.h> |
106 | #include <asm/uaccess.h> | 106 | #include <linux/uaccess.h> |
107 | 107 | ||
108 | #define MAX_NR_CON_DRIVER 16 | 108 | #define MAX_NR_CON_DRIVER 16 |
109 | 109 | ||
@@ -2136,27 +2136,9 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
2136 | release_console_sem(); | 2136 | release_console_sem(); |
2137 | return 0; | 2137 | return 0; |
2138 | } | 2138 | } |
2139 | release_console_sem(); | ||
2140 | |||
2141 | orig_buf = buf; | 2139 | orig_buf = buf; |
2142 | orig_count = count; | 2140 | orig_count = count; |
2143 | 2141 | ||
2144 | /* At this point 'buf' is guaranteed to be a kernel buffer | ||
2145 | * and therefore no access to userspace (and therefore sleeping) | ||
2146 | * will be needed. The con_buf_mtx serializes all tty based | ||
2147 | * console rendering and vcs write/read operations. We hold | ||
2148 | * the console spinlock during the entire write. | ||
2149 | */ | ||
2150 | |||
2151 | acquire_console_sem(); | ||
2152 | |||
2153 | vc = tty->driver_data; | ||
2154 | if (vc == NULL) { | ||
2155 | printk(KERN_ERR "vt: argh, driver_data _became_ NULL !\n"); | ||
2156 | release_console_sem(); | ||
2157 | goto out; | ||
2158 | } | ||
2159 | |||
2160 | himask = vc->vc_hi_font_mask; | 2142 | himask = vc->vc_hi_font_mask; |
2161 | charmask = himask ? 0x1ff : 0xff; | 2143 | charmask = himask ? 0x1ff : 0xff; |
2162 | 2144 | ||
@@ -2370,8 +2352,6 @@ rescan_last_byte: | |||
2370 | FLUSH | 2352 | FLUSH |
2371 | console_conditional_schedule(); | 2353 | console_conditional_schedule(); |
2372 | release_console_sem(); | 2354 | release_console_sem(); |
2373 | |||
2374 | out: | ||
2375 | notify_update(vc); | 2355 | notify_update(vc); |
2376 | return n; | 2356 | return n; |
2377 | #undef FLUSH | 2357 | #undef FLUSH |
@@ -2583,8 +2563,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2583 | int lines; | 2563 | int lines; |
2584 | int ret; | 2564 | int ret; |
2585 | 2565 | ||
2586 | if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE) | ||
2587 | return -EINVAL; | ||
2588 | if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN)) | 2566 | if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN)) |
2589 | return -EPERM; | 2567 | return -EPERM; |
2590 | if (get_user(type, p)) | 2568 | if (get_user(type, p)) |
@@ -2778,6 +2756,12 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2778 | ret = vc_allocate(currcons); | 2756 | ret = vc_allocate(currcons); |
2779 | if (ret == 0) { | 2757 | if (ret == 0) { |
2780 | struct vc_data *vc = vc_cons[currcons].d; | 2758 | struct vc_data *vc = vc_cons[currcons].d; |
2759 | |||
2760 | /* Still being freed */ | ||
2761 | if (vc->vc_tty) { | ||
2762 | release_console_sem(); | ||
2763 | return -ERESTARTSYS; | ||
2764 | } | ||
2781 | tty->driver_data = vc; | 2765 | tty->driver_data = vc; |
2782 | vc->vc_tty = tty; | 2766 | vc->vc_tty = tty; |
2783 | 2767 | ||
@@ -2798,34 +2782,20 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2798 | return ret; | 2782 | return ret; |
2799 | } | 2783 | } |
2800 | 2784 | ||
2801 | /* | ||
2802 | * We take tty_mutex in here to prevent another thread from coming in via init_dev | ||
2803 | * and taking a ref against the tty while we're in the process of forgetting | ||
2804 | * about it and cleaning things up. | ||
2805 | * | ||
2806 | * This is because vcs_remove_sysfs() can sleep and will drop the BKL. | ||
2807 | */ | ||
2808 | static void con_close(struct tty_struct *tty, struct file *filp) | 2785 | static void con_close(struct tty_struct *tty, struct file *filp) |
2809 | { | 2786 | { |
2810 | mutex_lock(&tty_mutex); | 2787 | /* Nothing to do - we defer to shutdown */ |
2811 | acquire_console_sem(); | 2788 | } |
2812 | if (tty && tty->count == 1) { | ||
2813 | struct vc_data *vc = tty->driver_data; | ||
2814 | 2789 | ||
2815 | if (vc) | 2790 | static void con_shutdown(struct tty_struct *tty) |
2816 | vc->vc_tty = NULL; | 2791 | { |
2817 | tty->driver_data = NULL; | 2792 | struct vc_data *vc = tty->driver_data; |
2818 | vcs_remove_sysfs(tty); | 2793 | BUG_ON(vc == NULL); |
2819 | release_console_sem(); | 2794 | acquire_console_sem(); |
2820 | mutex_unlock(&tty_mutex); | 2795 | vc->vc_tty = NULL; |
2821 | /* | 2796 | vcs_remove_sysfs(tty); |
2822 | * tty_mutex is released, but we still hold BKL, so there is | ||
2823 | * still exclusion against init_dev() | ||
2824 | */ | ||
2825 | return; | ||
2826 | } | ||
2827 | release_console_sem(); | 2797 | release_console_sem(); |
2828 | mutex_unlock(&tty_mutex); | 2798 | tty_shutdown(tty); |
2829 | } | 2799 | } |
2830 | 2800 | ||
2831 | static int default_italic_color = 2; // green (ASCII) | 2801 | static int default_italic_color = 2; // green (ASCII) |
@@ -2950,10 +2920,19 @@ static const struct tty_operations con_ops = { | |||
2950 | .throttle = con_throttle, | 2920 | .throttle = con_throttle, |
2951 | .unthrottle = con_unthrottle, | 2921 | .unthrottle = con_unthrottle, |
2952 | .resize = vt_resize, | 2922 | .resize = vt_resize, |
2923 | .shutdown = con_shutdown | ||
2953 | }; | 2924 | }; |
2954 | 2925 | ||
2955 | int __init vty_init(void) | 2926 | static struct cdev vc0_cdev; |
2927 | |||
2928 | int __init vty_init(const struct file_operations *console_fops) | ||
2956 | { | 2929 | { |
2930 | cdev_init(&vc0_cdev, console_fops); | ||
2931 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || | ||
2932 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) | ||
2933 | panic("Couldn't register /dev/tty0 driver\n"); | ||
2934 | device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); | ||
2935 | |||
2957 | vcs_init(); | 2936 | vcs_init(); |
2958 | 2937 | ||
2959 | console_driver = alloc_tty_driver(MAX_NR_CONSOLES); | 2938 | console_driver = alloc_tty_driver(MAX_NR_CONSOLES); |
@@ -2972,7 +2951,6 @@ int __init vty_init(void) | |||
2972 | tty_set_operations(console_driver, &con_ops); | 2951 | tty_set_operations(console_driver, &con_ops); |
2973 | if (tty_register_driver(console_driver)) | 2952 | if (tty_register_driver(console_driver)) |
2974 | panic("Couldn't register console driver\n"); | 2953 | panic("Couldn't register console driver\n"); |
2975 | |||
2976 | kbd_init(); | 2954 | kbd_init(); |
2977 | console_map_init(); | 2955 | console_map_init(); |
2978 | #ifdef CONFIG_PROM_CONSOLE | 2956 | #ifdef CONFIG_PROM_CONSOLE |
@@ -3466,7 +3444,7 @@ int register_con_driver(const struct consw *csw, int first, int last) | |||
3466 | if (retval) | 3444 | if (retval) |
3467 | goto err; | 3445 | goto err; |
3468 | 3446 | ||
3469 | con_driver->dev = device_create_drvdata(vtconsole_class, NULL, | 3447 | con_driver->dev = device_create(vtconsole_class, NULL, |
3470 | MKDEV(0, con_driver->node), | 3448 | MKDEV(0, con_driver->node), |
3471 | NULL, "vtcon%i", | 3449 | NULL, "vtcon%i", |
3472 | con_driver->node); | 3450 | con_driver->node); |
@@ -3577,7 +3555,7 @@ static int __init vtconsole_class_init(void) | |||
3577 | struct con_driver *con = ®istered_con_driver[i]; | 3555 | struct con_driver *con = ®istered_con_driver[i]; |
3578 | 3556 | ||
3579 | if (con->con && !con->dev) { | 3557 | if (con->con && !con->dev) { |
3580 | con->dev = device_create_drvdata(vtconsole_class, NULL, | 3558 | con->dev = device_create(vtconsole_class, NULL, |
3581 | MKDEV(0, con->node), | 3559 | MKDEV(0, con->node), |
3582 | NULL, "vtcon%i", | 3560 | NULL, "vtcon%i", |
3583 | con->node); | 3561 | con->node); |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index c904e9ad4a71..8944ce508e2f 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -395,6 +395,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
395 | 395 | ||
396 | kbd = kbd_table + console; | 396 | kbd = kbd_table + console; |
397 | switch (cmd) { | 397 | switch (cmd) { |
398 | case TIOCLINUX: | ||
399 | return tioclinux(tty, arg); | ||
398 | case KIOCSOUND: | 400 | case KIOCSOUND: |
399 | if (!perm) | 401 | if (!perm) |
400 | goto eperm; | 402 | goto eperm; |
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 871b0cbca5e4..798d7f3e42ef 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -1231,7 +1231,7 @@ static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file, | |||
1231 | int error = 0; | 1231 | int error = 0; |
1232 | switch (cmd) { | 1232 | switch (cmd) { |
1233 | default: | 1233 | default: |
1234 | error = n_tty_ioctl (tty, file, cmd, arg); | 1234 | error = n_tty_ioctl_helper(tty, file, cmd, arg); |
1235 | break; | 1235 | break; |
1236 | } | 1236 | } |
1237 | return error; | 1237 | return error; |
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index 5e89fa177816..07052ed2a0c5 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
@@ -571,6 +571,7 @@ gigaset_tty_close(struct tty_struct *tty) | |||
571 | } | 571 | } |
572 | 572 | ||
573 | /* prevent other callers from entering ldisc methods */ | 573 | /* prevent other callers from entering ldisc methods */ |
574 | /* FIXME: should use the tty state flags */ | ||
574 | tty->disc_data = NULL; | 575 | tty->disc_data = NULL; |
575 | 576 | ||
576 | if (!cs->hw.ser) | 577 | if (!cs->hw.ser) |
@@ -642,10 +643,11 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
642 | return -ENXIO; | 643 | return -ENXIO; |
643 | 644 | ||
644 | switch (cmd) { | 645 | switch (cmd) { |
645 | case TCGETS: | 646 | |
646 | case TCGETA: | 647 | case FIONREAD: |
647 | /* pass through to underlying serial device */ | 648 | /* unused, always return zero */ |
648 | rc = n_tty_ioctl(tty, file, cmd, arg); | 649 | val = 0; |
650 | rc = put_user(val, p); | ||
649 | break; | 651 | break; |
650 | 652 | ||
651 | case TCFLSH: | 653 | case TCFLSH: |
@@ -659,20 +661,13 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
659 | flush_send_queue(cs); | 661 | flush_send_queue(cs); |
660 | break; | 662 | break; |
661 | } | 663 | } |
662 | /* flush the serial port's buffer */ | 664 | /* Pass through */ |
663 | rc = n_tty_ioctl(tty, file, cmd, arg); | ||
664 | break; | ||
665 | |||
666 | case FIONREAD: | ||
667 | /* unused, always return zero */ | ||
668 | val = 0; | ||
669 | rc = put_user(val, p); | ||
670 | break; | ||
671 | 665 | ||
672 | default: | 666 | default: |
673 | rc = -ENOIOCTLCMD; | 667 | /* pass through to underlying serial device */ |
668 | rc = n_tty_ioctl_helper(tty, file, cmd, arg); | ||
669 | break; | ||
674 | } | 670 | } |
675 | |||
676 | cs_put(cs); | 671 | cs_put(cs); |
677 | return rc; | 672 | return rc; |
678 | } | 673 | } |
@@ -680,6 +675,8 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
680 | /* | 675 | /* |
681 | * Poll on the tty. | 676 | * Poll on the tty. |
682 | * Unused, always return zero. | 677 | * Unused, always return zero. |
678 | * | ||
679 | * FIXME: should probably return an exception - especially on hangup | ||
683 | */ | 680 | */ |
684 | static unsigned int | 681 | static unsigned int |
685 | gigaset_tty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) | 682 | gigaset_tty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) |
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 2ae2ec40015d..21efd99b9294 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig | |||
@@ -205,7 +205,7 @@ config WANXL_BUILD_FIRMWARE | |||
205 | 205 | ||
206 | config PC300 | 206 | config PC300 |
207 | tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)" | 207 | tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)" |
208 | depends on HDLC && PCI | 208 | depends on HDLC && PCI && BROKEN |
209 | ---help--- | 209 | ---help--- |
210 | Driver for the Cyclades-PC300 synchronous communication boards. | 210 | Driver for the Cyclades-PC300 synchronous communication boards. |
211 | 211 | ||
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index d18e6d2e0b49..40759c33477d 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c | |||
@@ -418,25 +418,22 @@ fs3270_open(struct inode *inode, struct file *filp) | |||
418 | { | 418 | { |
419 | struct fs3270 *fp; | 419 | struct fs3270 *fp; |
420 | struct idal_buffer *ib; | 420 | struct idal_buffer *ib; |
421 | int minor, rc; | 421 | int minor, rc = 0; |
422 | 422 | ||
423 | if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR) | 423 | if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR) |
424 | return -ENODEV; | 424 | return -ENODEV; |
425 | lock_kernel(); | ||
426 | minor = iminor(filp->f_path.dentry->d_inode); | 425 | minor = iminor(filp->f_path.dentry->d_inode); |
427 | /* Check for minor 0 multiplexer. */ | 426 | /* Check for minor 0 multiplexer. */ |
428 | if (minor == 0) { | 427 | if (minor == 0) { |
429 | struct tty_struct *tty; | 428 | struct tty_struct *tty = get_current_tty(); |
430 | mutex_lock(&tty_mutex); | ||
431 | tty = get_current_tty(); | ||
432 | if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) { | 429 | if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) { |
433 | mutex_unlock(&tty_mutex); | 430 | tty_kref_put(tty); |
434 | rc = -ENODEV; | 431 | return -ENODEV; |
435 | goto out; | ||
436 | } | 432 | } |
437 | minor = tty->index + RAW3270_FIRSTMINOR; | 433 | minor = tty->index + RAW3270_FIRSTMINOR; |
438 | mutex_unlock(&tty_mutex); | 434 | tty_kref_put(tty); |
439 | } | 435 | } |
436 | lock_kernel(); | ||
440 | /* Check if some other program is already using fullscreen mode. */ | 437 | /* Check if some other program is already using fullscreen mode. */ |
441 | fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); | 438 | fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); |
442 | if (!IS_ERR(fp)) { | 439 | if (!IS_ERR(fp)) { |
@@ -478,7 +475,7 @@ fs3270_open(struct inode *inode, struct file *filp) | |||
478 | filp->private_data = fp; | 475 | filp->private_data = fp; |
479 | out: | 476 | out: |
480 | unlock_kernel(); | 477 | unlock_kernel(); |
481 | return 0; | 478 | return rc; |
482 | } | 479 | } |
483 | 480 | ||
484 | /* | 481 | /* |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 9ccc563d8730..d4104a3bbe87 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -44,6 +44,10 @@ | |||
44 | 44 | ||
45 | #include "8250.h" | 45 | #include "8250.h" |
46 | 46 | ||
47 | #ifdef CONFIG_SPARC | ||
48 | #include "suncore.h" | ||
49 | #endif | ||
50 | |||
47 | /* | 51 | /* |
48 | * Configuration: | 52 | * Configuration: |
49 | * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option | 53 | * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option |
@@ -53,6 +57,13 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; | |||
53 | 57 | ||
54 | static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; | 58 | static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; |
55 | 59 | ||
60 | static struct uart_driver serial8250_reg; | ||
61 | |||
62 | static int serial_index(struct uart_port *port) | ||
63 | { | ||
64 | return (serial8250_reg.minor - 64) + port->line; | ||
65 | } | ||
66 | |||
56 | /* | 67 | /* |
57 | * Debugging. | 68 | * Debugging. |
58 | */ | 69 | */ |
@@ -536,7 +547,7 @@ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) | |||
536 | /* | 547 | /* |
537 | * FIFO support. | 548 | * FIFO support. |
538 | */ | 549 | */ |
539 | static inline void serial8250_clear_fifos(struct uart_8250_port *p) | 550 | static void serial8250_clear_fifos(struct uart_8250_port *p) |
540 | { | 551 | { |
541 | if (p->capabilities & UART_CAP_FIFO) { | 552 | if (p->capabilities & UART_CAP_FIFO) { |
542 | serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO); | 553 | serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO); |
@@ -551,7 +562,7 @@ static inline void serial8250_clear_fifos(struct uart_8250_port *p) | |||
551 | * capability" bit enabled. Note that on XR16C850s, we need to | 562 | * capability" bit enabled. Note that on XR16C850s, we need to |
552 | * reset LCR to write to IER. | 563 | * reset LCR to write to IER. |
553 | */ | 564 | */ |
554 | static inline void serial8250_set_sleep(struct uart_8250_port *p, int sleep) | 565 | static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) |
555 | { | 566 | { |
556 | if (p->capabilities & UART_CAP_SLEEP) { | 567 | if (p->capabilities & UART_CAP_SLEEP) { |
557 | if (p->capabilities & UART_CAP_EFR) { | 568 | if (p->capabilities & UART_CAP_EFR) { |
@@ -993,7 +1004,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
993 | return; | 1004 | return; |
994 | 1005 | ||
995 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ", | 1006 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ", |
996 | up->port.line, up->port.iobase, up->port.membase); | 1007 | serial_index(&up->port), up->port.iobase, up->port.membase); |
997 | 1008 | ||
998 | /* | 1009 | /* |
999 | * We really do need global IRQs disabled here - we're going to | 1010 | * We really do need global IRQs disabled here - we're going to |
@@ -1128,8 +1139,8 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
1128 | if (up->capabilities != uart_config[up->port.type].flags) { | 1139 | if (up->capabilities != uart_config[up->port.type].flags) { |
1129 | printk(KERN_WARNING | 1140 | printk(KERN_WARNING |
1130 | "ttyS%d: detected caps %08x should be %08x\n", | 1141 | "ttyS%d: detected caps %08x should be %08x\n", |
1131 | up->port.line, up->capabilities, | 1142 | serial_index(&up->port), up->capabilities, |
1132 | uart_config[up->port.type].flags); | 1143 | uart_config[up->port.type].flags); |
1133 | } | 1144 | } |
1134 | 1145 | ||
1135 | up->port.fifosize = uart_config[up->port.type].fifo_size; | 1146 | up->port.fifosize = uart_config[up->port.type].fifo_size; |
@@ -1424,8 +1435,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up) | |||
1424 | /* | 1435 | /* |
1425 | * This handles the interrupt from one port. | 1436 | * This handles the interrupt from one port. |
1426 | */ | 1437 | */ |
1427 | static inline void | 1438 | static void serial8250_handle_port(struct uart_8250_port *up) |
1428 | serial8250_handle_port(struct uart_8250_port *up) | ||
1429 | { | 1439 | { |
1430 | unsigned int status; | 1440 | unsigned int status; |
1431 | unsigned long flags; | 1441 | unsigned long flags; |
@@ -1719,7 +1729,7 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) | |||
1719 | /* | 1729 | /* |
1720 | * Wait for transmitter & holding register to empty | 1730 | * Wait for transmitter & holding register to empty |
1721 | */ | 1731 | */ |
1722 | static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) | 1732 | static void wait_for_xmitr(struct uart_8250_port *up, int bits) |
1723 | { | 1733 | { |
1724 | unsigned int status, tmout = 10000; | 1734 | unsigned int status, tmout = 10000; |
1725 | 1735 | ||
@@ -1854,7 +1864,8 @@ static int serial8250_startup(struct uart_port *port) | |||
1854 | */ | 1864 | */ |
1855 | if (!(up->port.flags & UPF_BUGGY_UART) && | 1865 | if (!(up->port.flags & UPF_BUGGY_UART) && |
1856 | (serial_inp(up, UART_LSR) == 0xff)) { | 1866 | (serial_inp(up, UART_LSR) == 0xff)) { |
1857 | printk("ttyS%d: LSR safety check engaged!\n", up->port.line); | 1867 | printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n", |
1868 | serial_index(&up->port)); | ||
1858 | return -ENODEV; | 1869 | return -ENODEV; |
1859 | } | 1870 | } |
1860 | 1871 | ||
@@ -1909,7 +1920,8 @@ static int serial8250_startup(struct uart_port *port) | |||
1909 | */ | 1920 | */ |
1910 | if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) { | 1921 | if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) { |
1911 | up->bugs |= UART_BUG_THRE; | 1922 | up->bugs |= UART_BUG_THRE; |
1912 | pr_debug("ttyS%d - using backup timer\n", port->line); | 1923 | pr_debug("ttyS%d - using backup timer\n", |
1924 | serial_index(port)); | ||
1913 | } | 1925 | } |
1914 | } | 1926 | } |
1915 | 1927 | ||
@@ -1969,7 +1981,7 @@ static int serial8250_startup(struct uart_port *port) | |||
1969 | if (!(up->bugs & UART_BUG_TXEN)) { | 1981 | if (!(up->bugs & UART_BUG_TXEN)) { |
1970 | up->bugs |= UART_BUG_TXEN; | 1982 | up->bugs |= UART_BUG_TXEN; |
1971 | pr_debug("ttyS%d - enabling bad tx status workarounds\n", | 1983 | pr_debug("ttyS%d - enabling bad tx status workarounds\n", |
1972 | port->line); | 1984 | serial_index(port)); |
1973 | } | 1985 | } |
1974 | } else { | 1986 | } else { |
1975 | up->bugs &= ~UART_BUG_TXEN; | 1987 | up->bugs &= ~UART_BUG_TXEN; |
@@ -2630,7 +2642,6 @@ static int serial8250_console_early_setup(void) | |||
2630 | return serial8250_find_port_for_earlycon(); | 2642 | return serial8250_find_port_for_earlycon(); |
2631 | } | 2643 | } |
2632 | 2644 | ||
2633 | static struct uart_driver serial8250_reg; | ||
2634 | static struct console serial8250_console = { | 2645 | static struct console serial8250_console = { |
2635 | .name = "ttyS", | 2646 | .name = "ttyS", |
2636 | .write = serial8250_console_write, | 2647 | .write = serial8250_console_write, |
@@ -2677,7 +2688,6 @@ static struct uart_driver serial8250_reg = { | |||
2677 | .dev_name = "ttyS", | 2688 | .dev_name = "ttyS", |
2678 | .major = TTY_MAJOR, | 2689 | .major = TTY_MAJOR, |
2679 | .minor = 64, | 2690 | .minor = 64, |
2680 | .nr = UART_NR, | ||
2681 | .cons = SERIAL8250_CONSOLE, | 2691 | .cons = SERIAL8250_CONSOLE, |
2682 | }; | 2692 | }; |
2683 | 2693 | ||
@@ -2959,10 +2969,12 @@ static int __init serial8250_init(void) | |||
2959 | "%d ports, IRQ sharing %sabled\n", nr_uarts, | 2969 | "%d ports, IRQ sharing %sabled\n", nr_uarts, |
2960 | share_irqs ? "en" : "dis"); | 2970 | share_irqs ? "en" : "dis"); |
2961 | 2971 | ||
2962 | for (i = 0; i < NR_IRQS; i++) | 2972 | #ifdef CONFIG_SPARC |
2963 | spin_lock_init(&irq_lists[i].lock); | 2973 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); |
2964 | 2974 | #else | |
2975 | serial8250_reg.nr = UART_NR; | ||
2965 | ret = uart_register_driver(&serial8250_reg); | 2976 | ret = uart_register_driver(&serial8250_reg); |
2977 | #endif | ||
2966 | if (ret) | 2978 | if (ret) |
2967 | goto out; | 2979 | goto out; |
2968 | 2980 | ||
@@ -2987,7 +2999,11 @@ static int __init serial8250_init(void) | |||
2987 | put_dev: | 2999 | put_dev: |
2988 | platform_device_put(serial8250_isa_devs); | 3000 | platform_device_put(serial8250_isa_devs); |
2989 | unreg_uart_drv: | 3001 | unreg_uart_drv: |
3002 | #ifdef CONFIG_SPARC | ||
3003 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | ||
3004 | #else | ||
2990 | uart_unregister_driver(&serial8250_reg); | 3005 | uart_unregister_driver(&serial8250_reg); |
3006 | #endif | ||
2991 | out: | 3007 | out: |
2992 | return ret; | 3008 | return ret; |
2993 | } | 3009 | } |
@@ -3006,7 +3022,11 @@ static void __exit serial8250_exit(void) | |||
3006 | platform_driver_unregister(&serial8250_isa_driver); | 3022 | platform_driver_unregister(&serial8250_isa_driver); |
3007 | platform_device_unregister(isa_dev); | 3023 | platform_device_unregister(isa_dev); |
3008 | 3024 | ||
3025 | #ifdef CONFIG_SPARC | ||
3026 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | ||
3027 | #else | ||
3009 | uart_unregister_driver(&serial8250_reg); | 3028 | uart_unregister_driver(&serial8250_reg); |
3029 | #endif | ||
3010 | } | 3030 | } |
3011 | 3031 | ||
3012 | module_init(serial8250_init); | 3032 | module_init(serial8250_init); |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index c2f23933155b..c014ffb110e9 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -2041,9 +2041,9 @@ static int pciserial_resume_one(struct pci_dev *dev) | |||
2041 | * The device may have been disabled. Re-enable it. | 2041 | * The device may have been disabled. Re-enable it. |
2042 | */ | 2042 | */ |
2043 | err = pci_enable_device(dev); | 2043 | err = pci_enable_device(dev); |
2044 | /* FIXME: We cannot simply error out here */ | ||
2044 | if (err) | 2045 | if (err) |
2045 | return err; | 2046 | printk(KERN_ERR "pciserial: Unable to re-enable ports, trying to continue.\n"); |
2046 | |||
2047 | pciserial_resume_ports(priv); | 2047 | pciserial_resume_ports(priv); |
2048 | } | 2048 | } |
2049 | return 0; | 2049 | return 0; |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 77cb34270fc1..31786b3b0a68 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -9,7 +9,6 @@ menu "Serial drivers" | |||
9 | # The new 8250/16550 serial drivers | 9 | # The new 8250/16550 serial drivers |
10 | config SERIAL_8250 | 10 | config SERIAL_8250 |
11 | tristate "8250/16550 and compatible serial support" | 11 | tristate "8250/16550 and compatible serial support" |
12 | depends on (BROKEN || !SPARC) | ||
13 | select SERIAL_CORE | 12 | select SERIAL_CORE |
14 | ---help--- | 13 | ---help--- |
15 | This selects whether you want to include the driver for the standard | 14 | This selects whether you want to include the driver for the standard |
@@ -994,24 +993,12 @@ config SERIAL_68328_RTS_CTS | |||
994 | bool "Support RTS/CTS on 68328 serial port" | 993 | bool "Support RTS/CTS on 68328 serial port" |
995 | depends on SERIAL_68328 | 994 | depends on SERIAL_68328 |
996 | 995 | ||
997 | config SERIAL_COLDFIRE | ||
998 | bool "ColdFire serial support (DEPRECATED)" | ||
999 | depends on COLDFIRE | ||
1000 | help | ||
1001 | This driver supports the built-in serial ports of the Motorola ColdFire | ||
1002 | family of CPUs. | ||
1003 | This driver is deprecated because it supports only the old interface | ||
1004 | for serial drivers and features like magic keys are not working. | ||
1005 | Please switch to the new style driver because this driver will be | ||
1006 | removed soon. | ||
1007 | |||
1008 | config SERIAL_MCF | 996 | config SERIAL_MCF |
1009 | bool "Coldfire serial support (new style driver)" | 997 | bool "Coldfire serial support" |
1010 | depends on COLDFIRE | 998 | depends on COLDFIRE |
1011 | select SERIAL_CORE | 999 | select SERIAL_CORE |
1012 | help | 1000 | help |
1013 | This new serial driver supports the Freescale Coldfire serial ports | 1001 | This serial driver supports the Freescale Coldfire serial ports. |
1014 | using the new serial driver subsystem. | ||
1015 | 1002 | ||
1016 | config SERIAL_MCF_BAUDRATE | 1003 | config SERIAL_MCF_BAUDRATE |
1017 | int "Default baudrate for Coldfire serial ports" | 1004 | int "Default baudrate for Coldfire serial ports" |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 7e7383e890d8..0c17c8ddb19d 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -4,6 +4,16 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_SERIAL_CORE) += serial_core.o | 5 | obj-$(CONFIG_SERIAL_CORE) += serial_core.o |
6 | obj-$(CONFIG_SERIAL_21285) += 21285.o | 6 | obj-$(CONFIG_SERIAL_21285) += 21285.o |
7 | |||
8 | # These Sparc drivers have to appear before others such as 8250 | ||
9 | # which share ttySx minor node space. Otherwise console device | ||
10 | # names change and other unplesantries. | ||
11 | obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o | ||
12 | obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o | ||
13 | obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o | ||
14 | obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o | ||
15 | obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o | ||
16 | |||
7 | obj-$(CONFIG_SERIAL_8250) += 8250.o | 17 | obj-$(CONFIG_SERIAL_8250) += 8250.o |
8 | obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o | 18 | obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o |
9 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o | 19 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o |
@@ -31,16 +41,10 @@ obj-$(CONFIG_SERIAL_S3C2400) += s3c2400.o | |||
31 | obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o | 41 | obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o |
32 | obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o | 42 | obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o |
33 | obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o | 43 | obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o |
34 | obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o | ||
35 | obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o | ||
36 | obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o | ||
37 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o | 44 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o |
38 | obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o | ||
39 | obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o | ||
40 | obj-$(CONFIG_SERIAL_MUX) += mux.o | 45 | obj-$(CONFIG_SERIAL_MUX) += mux.o |
41 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o | 46 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o |
42 | obj-$(CONFIG_SERIAL_68360) += 68360serial.o | 47 | obj-$(CONFIG_SERIAL_68360) += 68360serial.o |
43 | obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o | ||
44 | obj-$(CONFIG_SERIAL_MCF) += mcf.o | 48 | obj-$(CONFIG_SERIAL_MCF) += mcf.o |
45 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o | 49 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o |
46 | obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o | 50 | obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o |
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 4a0d30bed9f1..569f0e2476c6 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Blackfin On-Chip Serial Driver | 2 | * Blackfin On-Chip Serial Driver |
3 | * | 3 | * |
4 | * Copyright 2006-2007 Analog Devices Inc. | 4 | * Copyright 2006-2008 Analog Devices Inc. |
5 | * | 5 | * |
6 | * Enter bugs at http://blackfin.uclinux.org/ | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
7 | * | 7 | * |
@@ -42,6 +42,9 @@ | |||
42 | #define BFIN_SERIAL_MAJOR 204 | 42 | #define BFIN_SERIAL_MAJOR 204 |
43 | #define BFIN_SERIAL_MINOR 64 | 43 | #define BFIN_SERIAL_MINOR 64 |
44 | 44 | ||
45 | static struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; | ||
46 | static int nr_active_ports = ARRAY_SIZE(bfin_serial_resource); | ||
47 | |||
45 | /* | 48 | /* |
46 | * Setup for console. Argument comes from the menuconfig | 49 | * Setup for console. Argument comes from the menuconfig |
47 | */ | 50 | */ |
@@ -126,13 +129,13 @@ static int kgdb_entry_state; | |||
126 | void kgdb_put_debug_char(int chr) | 129 | void kgdb_put_debug_char(int chr) |
127 | { | 130 | { |
128 | struct bfin_serial_port *uart; | 131 | struct bfin_serial_port *uart; |
129 | 132 | ||
130 | if (CONFIG_KGDB_UART_PORT < 0 | 133 | if (CONFIG_KGDB_UART_PORT < 0 |
131 | || CONFIG_KGDB_UART_PORT >= BFIN_UART_NR_PORTS) | 134 | || CONFIG_KGDB_UART_PORT >= BFIN_UART_NR_PORTS) |
132 | uart = &bfin_serial_ports[0]; | 135 | uart = &bfin_serial_ports[0]; |
133 | else | 136 | else |
134 | uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; | 137 | uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; |
135 | 138 | ||
136 | while (!(UART_GET_LSR(uart) & THRE)) { | 139 | while (!(UART_GET_LSR(uart) & THRE)) { |
137 | SSYNC(); | 140 | SSYNC(); |
138 | } | 141 | } |
@@ -152,7 +155,7 @@ int kgdb_get_debug_char(void) | |||
152 | uart = &bfin_serial_ports[0]; | 155 | uart = &bfin_serial_ports[0]; |
153 | else | 156 | else |
154 | uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; | 157 | uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; |
155 | 158 | ||
156 | while(!(UART_GET_LSR(uart) & DR)) { | 159 | while(!(UART_GET_LSR(uart) & DR)) { |
157 | SSYNC(); | 160 | SSYNC(); |
158 | } | 161 | } |
@@ -298,7 +301,11 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) | |||
298 | bfin_serial_mctrl_check(uart); | 301 | bfin_serial_mctrl_check(uart); |
299 | 302 | ||
300 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { | 303 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { |
301 | bfin_serial_stop_tx(&uart->port); | 304 | #ifdef CONFIG_BF54x |
305 | /* Clear TFI bit */ | ||
306 | UART_PUT_LSR(uart, TFI); | ||
307 | #endif | ||
308 | UART_CLEAR_IER(uart, ETBEI); | ||
302 | return; | 309 | return; |
303 | } | 310 | } |
304 | 311 | ||
@@ -317,9 +324,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) | |||
317 | 324 | ||
318 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 325 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
319 | uart_write_wakeup(&uart->port); | 326 | uart_write_wakeup(&uart->port); |
320 | |||
321 | if (uart_circ_empty(xmit)) | ||
322 | bfin_serial_stop_tx(&uart->port); | ||
323 | } | 327 | } |
324 | 328 | ||
325 | static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) | 329 | static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) |
@@ -645,6 +649,42 @@ static int bfin_serial_startup(struct uart_port *port) | |||
645 | free_irq(uart->port.irq, uart); | 649 | free_irq(uart->port.irq, uart); |
646 | return -EBUSY; | 650 | return -EBUSY; |
647 | } | 651 | } |
652 | |||
653 | # ifdef CONFIG_BF54x | ||
654 | { | ||
655 | unsigned uart_dma_ch_rx, uart_dma_ch_tx; | ||
656 | |||
657 | switch (uart->port.irq) { | ||
658 | case IRQ_UART3_RX: | ||
659 | uart_dma_ch_rx = CH_UART3_RX; | ||
660 | uart_dma_ch_tx = CH_UART3_TX; | ||
661 | break; | ||
662 | case IRQ_UART2_RX: | ||
663 | uart_dma_ch_rx = CH_UART2_RX; | ||
664 | uart_dma_ch_tx = CH_UART2_TX; | ||
665 | break; | ||
666 | default: | ||
667 | uart_dma_ch_rx = uart_dma_ch_tx = 0; | ||
668 | break; | ||
669 | }; | ||
670 | |||
671 | if (uart_dma_ch_rx && | ||
672 | request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) { | ||
673 | printk(KERN_NOTICE"Fail to attach UART interrupt\n"); | ||
674 | free_irq(uart->port.irq, uart); | ||
675 | free_irq(uart->port.irq + 1, uart); | ||
676 | return -EBUSY; | ||
677 | } | ||
678 | if (uart_dma_ch_tx && | ||
679 | request_dma(uart_dma_ch_tx, "BFIN_UART_TX") < 0) { | ||
680 | printk(KERN_NOTICE "Fail to attach UART interrupt\n"); | ||
681 | free_dma(uart_dma_ch_rx); | ||
682 | free_irq(uart->port.irq, uart); | ||
683 | free_irq(uart->port.irq + 1, uart); | ||
684 | return -EBUSY; | ||
685 | } | ||
686 | } | ||
687 | # endif | ||
648 | #endif | 688 | #endif |
649 | UART_SET_IER(uart, ERBFI); | 689 | UART_SET_IER(uart, ERBFI); |
650 | return 0; | 690 | return 0; |
@@ -662,6 +702,20 @@ static void bfin_serial_shutdown(struct uart_port *port) | |||
662 | del_timer(&(uart->rx_dma_timer)); | 702 | del_timer(&(uart->rx_dma_timer)); |
663 | dma_free_coherent(NULL, PAGE_SIZE, uart->rx_dma_buf.buf, 0); | 703 | dma_free_coherent(NULL, PAGE_SIZE, uart->rx_dma_buf.buf, 0); |
664 | #else | 704 | #else |
705 | #ifdef CONFIG_BF54x | ||
706 | switch (uart->port.irq) { | ||
707 | case IRQ_UART3_RX: | ||
708 | free_dma(CH_UART3_RX); | ||
709 | free_dma(CH_UART3_TX); | ||
710 | break; | ||
711 | case IRQ_UART2_RX: | ||
712 | free_dma(CH_UART2_RX); | ||
713 | free_dma(CH_UART2_TX); | ||
714 | break; | ||
715 | default: | ||
716 | break; | ||
717 | }; | ||
718 | #endif | ||
665 | #ifdef CONFIG_KGDB_UART | 719 | #ifdef CONFIG_KGDB_UART |
666 | if (uart->port.line != CONFIG_KGDB_UART_PORT) | 720 | if (uart->port.line != CONFIG_KGDB_UART_PORT) |
667 | #endif | 721 | #endif |
@@ -757,6 +811,9 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
757 | val |= UCEN; | 811 | val |= UCEN; |
758 | UART_PUT_GCTL(uart, val); | 812 | UART_PUT_GCTL(uart, val); |
759 | 813 | ||
814 | /* Port speed changed, update the per-port timeout. */ | ||
815 | uart_update_timeout(port, termios->c_cflag, baud); | ||
816 | |||
760 | spin_unlock_irqrestore(&uart->port.lock, flags); | 817 | spin_unlock_irqrestore(&uart->port.lock, flags); |
761 | } | 818 | } |
762 | 819 | ||
@@ -859,8 +916,9 @@ static void __init bfin_serial_init_ports(void) | |||
859 | return; | 916 | return; |
860 | first = 0; | 917 | first = 0; |
861 | 918 | ||
862 | for (i = 0; i < nr_ports; i++) { | 919 | for (i = 0; i < nr_active_ports; i++) { |
863 | bfin_serial_ports[i].port.uartclk = get_sclk(); | 920 | bfin_serial_ports[i].port.uartclk = get_sclk(); |
921 | bfin_serial_ports[i].port.fifosize = BFIN_UART_TX_FIFO_SIZE; | ||
864 | bfin_serial_ports[i].port.ops = &bfin_serial_pops; | 922 | bfin_serial_ports[i].port.ops = &bfin_serial_pops; |
865 | bfin_serial_ports[i].port.line = i; | 923 | bfin_serial_ports[i].port.line = i; |
866 | bfin_serial_ports[i].port.iotype = UPIO_MEM; | 924 | bfin_serial_ports[i].port.iotype = UPIO_MEM; |
@@ -961,7 +1019,7 @@ bfin_serial_console_setup(struct console *co, char *options) | |||
961 | * if so, search for the first available port that does have | 1019 | * if so, search for the first available port that does have |
962 | * console support. | 1020 | * console support. |
963 | */ | 1021 | */ |
964 | if (co->index == -1 || co->index >= nr_ports) | 1022 | if (co->index == -1 || co->index >= nr_active_ports) |
965 | co->index = 0; | 1023 | co->index = 0; |
966 | uart = &bfin_serial_ports[co->index]; | 1024 | uart = &bfin_serial_ports[co->index]; |
967 | 1025 | ||
@@ -1056,7 +1114,7 @@ static __init void early_serial_write(struct console *con, const char *s, | |||
1056 | } | 1114 | } |
1057 | } | 1115 | } |
1058 | 1116 | ||
1059 | static struct __init console bfin_early_serial_console = { | 1117 | static struct __initdata console bfin_early_serial_console = { |
1060 | .name = "early_BFuart", | 1118 | .name = "early_BFuart", |
1061 | .write = early_serial_write, | 1119 | .write = early_serial_write, |
1062 | .device = uart_console_device, | 1120 | .device = uart_console_device, |
@@ -1072,7 +1130,7 @@ struct console __init *bfin_earlyserial_init(unsigned int port, | |||
1072 | struct bfin_serial_port *uart; | 1130 | struct bfin_serial_port *uart; |
1073 | struct ktermios t; | 1131 | struct ktermios t; |
1074 | 1132 | ||
1075 | if (port == -1 || port >= nr_ports) | 1133 | if (port == -1 || port >= nr_active_ports) |
1076 | port = 0; | 1134 | port = 0; |
1077 | bfin_serial_init_ports(); | 1135 | bfin_serial_init_ports(); |
1078 | bfin_early_serial_console.index = port; | 1136 | bfin_early_serial_console.index = port; |
@@ -1100,20 +1158,26 @@ static struct uart_driver bfin_serial_reg = { | |||
1100 | 1158 | ||
1101 | static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state) | 1159 | static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state) |
1102 | { | 1160 | { |
1103 | struct bfin_serial_port *uart = platform_get_drvdata(dev); | 1161 | int i; |
1104 | 1162 | ||
1105 | if (uart) | 1163 | for (i = 0; i < nr_active_ports; i++) { |
1106 | uart_suspend_port(&bfin_serial_reg, &uart->port); | 1164 | if (bfin_serial_ports[i].port.dev != &dev->dev) |
1165 | continue; | ||
1166 | uart_suspend_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | ||
1167 | } | ||
1107 | 1168 | ||
1108 | return 0; | 1169 | return 0; |
1109 | } | 1170 | } |
1110 | 1171 | ||
1111 | static int bfin_serial_resume(struct platform_device *dev) | 1172 | static int bfin_serial_resume(struct platform_device *dev) |
1112 | { | 1173 | { |
1113 | struct bfin_serial_port *uart = platform_get_drvdata(dev); | 1174 | int i; |
1114 | 1175 | ||
1115 | if (uart) | 1176 | for (i = 0; i < nr_active_ports; i++) { |
1116 | uart_resume_port(&bfin_serial_reg, &uart->port); | 1177 | if (bfin_serial_ports[i].port.dev != &dev->dev) |
1178 | continue; | ||
1179 | uart_resume_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | ||
1180 | } | ||
1117 | 1181 | ||
1118 | return 0; | 1182 | return 0; |
1119 | } | 1183 | } |
@@ -1128,32 +1192,31 @@ static int bfin_serial_probe(struct platform_device *dev) | |||
1128 | break; | 1192 | break; |
1129 | 1193 | ||
1130 | if (i < dev->num_resources) { | 1194 | if (i < dev->num_resources) { |
1131 | for (i = 0; i < nr_ports; i++, res++) { | 1195 | for (i = 0; i < nr_active_ports; i++, res++) { |
1132 | if (bfin_serial_ports[i].port.mapbase != res->start) | 1196 | if (bfin_serial_ports[i].port.mapbase != res->start) |
1133 | continue; | 1197 | continue; |
1134 | bfin_serial_ports[i].port.dev = &dev->dev; | 1198 | bfin_serial_ports[i].port.dev = &dev->dev; |
1135 | uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | 1199 | uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); |
1136 | platform_set_drvdata(dev, &bfin_serial_ports[i]); | ||
1137 | } | 1200 | } |
1138 | } | 1201 | } |
1139 | 1202 | ||
1140 | return 0; | 1203 | return 0; |
1141 | } | 1204 | } |
1142 | 1205 | ||
1143 | static int bfin_serial_remove(struct platform_device *pdev) | 1206 | static int bfin_serial_remove(struct platform_device *dev) |
1144 | { | 1207 | { |
1145 | struct bfin_serial_port *uart = platform_get_drvdata(pdev); | 1208 | int i; |
1146 | |||
1147 | 1209 | ||
1210 | for (i = 0; i < nr_active_ports; i++) { | ||
1211 | if (bfin_serial_ports[i].port.dev != &dev->dev) | ||
1212 | continue; | ||
1213 | uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | ||
1214 | bfin_serial_ports[i].port.dev = NULL; | ||
1148 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | 1215 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS |
1149 | gpio_free(uart->cts_pin); | 1216 | gpio_free(bfin_serial_ports[i].cts_pin); |
1150 | gpio_free(uart->rts_pin); | 1217 | gpio_free(bfin_serial_ports[i].rts_pin); |
1151 | #endif | 1218 | #endif |
1152 | 1219 | } | |
1153 | platform_set_drvdata(pdev, NULL); | ||
1154 | |||
1155 | if (uart) | ||
1156 | uart_remove_one_port(&bfin_serial_reg, &uart->port); | ||
1157 | 1220 | ||
1158 | return 0; | 1221 | return 0; |
1159 | } | 1222 | } |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index bf94a770bb44..211c21797ce0 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
@@ -457,7 +457,6 @@ static struct e100_serial rs_table[] = { | |||
457 | #define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial)) | 457 | #define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial)) |
458 | 458 | ||
459 | static struct ktermios *serial_termios[NR_PORTS]; | 459 | static struct ktermios *serial_termios[NR_PORTS]; |
460 | static struct ktermios *serial_termios_locked[NR_PORTS]; | ||
461 | #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER | 460 | #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER |
462 | static struct fast_timer fast_timers[NR_PORTS]; | 461 | static struct fast_timer fast_timers[NR_PORTS]; |
463 | #endif | 462 | #endif |
@@ -4419,6 +4418,7 @@ rs_init(void) | |||
4419 | rs485_pa_bit)) { | 4418 | rs485_pa_bit)) { |
4420 | printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " | 4419 | printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " |
4421 | "RS485 pin\n"); | 4420 | "RS485 pin\n"); |
4421 | put_tty_driver(driver); | ||
4422 | return -EBUSY; | 4422 | return -EBUSY; |
4423 | } | 4423 | } |
4424 | #endif | 4424 | #endif |
@@ -4427,6 +4427,7 @@ rs_init(void) | |||
4427 | rs485_port_g_bit)) { | 4427 | rs485_port_g_bit)) { |
4428 | printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " | 4428 | printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " |
4429 | "RS485 pin\n"); | 4429 | "RS485 pin\n"); |
4430 | put_tty_driver(driver); | ||
4430 | return -EBUSY; | 4431 | return -EBUSY; |
4431 | } | 4432 | } |
4432 | #endif | 4433 | #endif |
@@ -4446,8 +4447,6 @@ rs_init(void) | |||
4446 | driver->init_termios.c_ispeed = 115200; | 4447 | driver->init_termios.c_ispeed = 115200; |
4447 | driver->init_termios.c_ospeed = 115200; | 4448 | driver->init_termios.c_ospeed = 115200; |
4448 | driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 4449 | driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
4449 | driver->termios = serial_termios; | ||
4450 | driver->termios_locked = serial_termios_locked; | ||
4451 | 4450 | ||
4452 | tty_set_operations(driver, &rs_ops); | 4451 | tty_set_operations(driver, &rs_ops); |
4453 | serial_driver = driver; | 4452 | serial_driver = driver; |
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c deleted file mode 100644 index fbe3835f6b77..000000000000 --- a/drivers/serial/mcfserial.c +++ /dev/null | |||
@@ -1,1965 +0,0 @@ | |||
1 | #warning This driver is deprecated. Check Kconfig for details. | ||
2 | /* | ||
3 | * mcfserial.c -- serial driver for ColdFire internal UARTS. | ||
4 | * | ||
5 | * Copyright (C) 1999-2003 Greg Ungerer <gerg@snapgear.com> | ||
6 | * Copyright (c) 2000-2001 Lineo, Inc. <www.lineo.com> | ||
7 | * Copyright (C) 2001-2002 SnapGear Inc. <www.snapgear.com> | ||
8 | * | ||
9 | * Based on code from 68332serial.c which was: | ||
10 | * | ||
11 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | ||
12 | * Copyright (C) 1998 TSHG | ||
13 | * Copyright (c) 1999 Rt-Control Inc. <jeff@uclinux.org> | ||
14 | * | ||
15 | * Changes: | ||
16 | * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it> | ||
17 | * some cleanups in mcfrs_write. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/timer.h> | ||
26 | #include <linux/wait.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/tty.h> | ||
29 | #include <linux/tty_flip.h> | ||
30 | #include <linux/string.h> | ||
31 | #include <linux/fcntl.h> | ||
32 | #include <linux/mm.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/serial.h> | ||
35 | #include <linux/serialP.h> | ||
36 | #include <linux/console.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/bitops.h> | ||
39 | #include <linux/delay.h> | ||
40 | |||
41 | #include <asm/io.h> | ||
42 | #include <asm/irq.h> | ||
43 | #include <asm/system.h> | ||
44 | #include <asm/delay.h> | ||
45 | #include <asm/coldfire.h> | ||
46 | #include <asm/mcfsim.h> | ||
47 | #include <asm/mcfuart.h> | ||
48 | #include <asm/nettel.h> | ||
49 | #include <asm/uaccess.h> | ||
50 | #include "mcfserial.h" | ||
51 | |||
52 | struct timer_list mcfrs_timer_struct; | ||
53 | |||
54 | /* | ||
55 | * Default console baud rate, we use this as the default | ||
56 | * for all ports so init can just open /dev/console and | ||
57 | * keep going. Perhaps one day the cflag settings for the | ||
58 | * console can be used instead. | ||
59 | */ | ||
60 | #if defined(CONFIG_HW_FEITH) | ||
61 | #define CONSOLE_BAUD_RATE 38400 | ||
62 | #define DEFAULT_CBAUD B38400 | ||
63 | #elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || \ | ||
64 | defined(CONFIG_M5329EVB) || defined(CONFIG_GILBARCO) | ||
65 | #define CONSOLE_BAUD_RATE 115200 | ||
66 | #define DEFAULT_CBAUD B115200 | ||
67 | #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ | ||
68 | defined(CONFIG_senTec) || defined(CONFIG_SNEHA) || defined(CONFIG_AVNET) | ||
69 | #define CONSOLE_BAUD_RATE 19200 | ||
70 | #define DEFAULT_CBAUD B19200 | ||
71 | #endif | ||
72 | |||
73 | #ifndef CONSOLE_BAUD_RATE | ||
74 | #define CONSOLE_BAUD_RATE 9600 | ||
75 | #define DEFAULT_CBAUD B9600 | ||
76 | #endif | ||
77 | |||
78 | int mcfrs_console_inited = 0; | ||
79 | int mcfrs_console_port = -1; | ||
80 | int mcfrs_console_baud = CONSOLE_BAUD_RATE; | ||
81 | int mcfrs_console_cbaud = DEFAULT_CBAUD; | ||
82 | |||
83 | /* | ||
84 | * Driver data structures. | ||
85 | */ | ||
86 | static struct tty_driver *mcfrs_serial_driver; | ||
87 | |||
88 | /* number of characters left in xmit buffer before we ask for more */ | ||
89 | #define WAKEUP_CHARS 256 | ||
90 | |||
91 | /* Debugging... | ||
92 | */ | ||
93 | #undef SERIAL_DEBUG_OPEN | ||
94 | #undef SERIAL_DEBUG_FLOW | ||
95 | |||
96 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ | ||
97 | defined(CONFIG_M520x) || defined(CONFIG_M532x) | ||
98 | #define IRQBASE (MCFINT_VECBASE+MCFINT_UART0) | ||
99 | #else | ||
100 | #define IRQBASE 73 | ||
101 | #endif | ||
102 | |||
103 | /* | ||
104 | * Configuration table, UARTs to look for at startup. | ||
105 | */ | ||
106 | static struct mcf_serial mcfrs_table[] = { | ||
107 | { /* ttyS0 */ | ||
108 | .magic = 0, | ||
109 | .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE1), | ||
110 | .irq = IRQBASE, | ||
111 | .flags = ASYNC_BOOT_AUTOCONF, | ||
112 | }, | ||
113 | #ifdef MCFUART_BASE2 | ||
114 | { /* ttyS1 */ | ||
115 | .magic = 0, | ||
116 | .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE2), | ||
117 | .irq = IRQBASE+1, | ||
118 | .flags = ASYNC_BOOT_AUTOCONF, | ||
119 | }, | ||
120 | #endif | ||
121 | #ifdef MCFUART_BASE3 | ||
122 | { /* ttyS2 */ | ||
123 | .magic = 0, | ||
124 | .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE3), | ||
125 | .irq = IRQBASE+2, | ||
126 | .flags = ASYNC_BOOT_AUTOCONF, | ||
127 | }, | ||
128 | #endif | ||
129 | #ifdef MCFUART_BASE4 | ||
130 | { /* ttyS3 */ | ||
131 | .magic = 0, | ||
132 | .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE4), | ||
133 | .irq = IRQBASE+3, | ||
134 | .flags = ASYNC_BOOT_AUTOCONF, | ||
135 | }, | ||
136 | #endif | ||
137 | }; | ||
138 | |||
139 | |||
140 | #define NR_PORTS (sizeof(mcfrs_table) / sizeof(struct mcf_serial)) | ||
141 | |||
142 | /* | ||
143 | * This is used to figure out the divisor speeds and the timeouts. | ||
144 | */ | ||
145 | static int mcfrs_baud_table[] = { | ||
146 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | ||
147 | 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 | ||
148 | }; | ||
149 | #define MCFRS_BAUD_TABLE_SIZE \ | ||
150 | (sizeof(mcfrs_baud_table)/sizeof(mcfrs_baud_table[0])) | ||
151 | |||
152 | |||
153 | #ifdef CONFIG_MAGIC_SYSRQ | ||
154 | /* | ||
155 | * Magic system request keys. Used for debugging... | ||
156 | */ | ||
157 | extern int magic_sysrq_key(int ch); | ||
158 | #endif | ||
159 | |||
160 | |||
161 | /* | ||
162 | * Forware declarations... | ||
163 | */ | ||
164 | static void mcfrs_change_speed(struct mcf_serial *info); | ||
165 | static void mcfrs_wait_until_sent(struct tty_struct *tty, int timeout); | ||
166 | |||
167 | |||
168 | static inline int serial_paranoia_check(struct mcf_serial *info, | ||
169 | char *name, const char *routine) | ||
170 | { | ||
171 | #ifdef SERIAL_PARANOIA_CHECK | ||
172 | static const char badmagic[] = | ||
173 | "MCFRS(warning): bad magic number for serial struct %s in %s\n"; | ||
174 | static const char badinfo[] = | ||
175 | "MCFRS(warning): null mcf_serial for %s in %s\n"; | ||
176 | |||
177 | if (!info) { | ||
178 | printk(badinfo, name, routine); | ||
179 | return 1; | ||
180 | } | ||
181 | if (info->magic != SERIAL_MAGIC) { | ||
182 | printk(badmagic, name, routine); | ||
183 | return 1; | ||
184 | } | ||
185 | #endif | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * Sets or clears DTR and RTS on the requested line. | ||
191 | */ | ||
192 | static void mcfrs_setsignals(struct mcf_serial *info, int dtr, int rts) | ||
193 | { | ||
194 | volatile unsigned char *uartp; | ||
195 | unsigned long flags; | ||
196 | |||
197 | #if 0 | ||
198 | printk("%s(%d): mcfrs_setsignals(info=%x,dtr=%d,rts=%d)\n", | ||
199 | __FILE__, __LINE__, info, dtr, rts); | ||
200 | #endif | ||
201 | |||
202 | local_irq_save(flags); | ||
203 | if (dtr >= 0) { | ||
204 | #ifdef MCFPP_DTR0 | ||
205 | if (info->line) | ||
206 | mcf_setppdata(MCFPP_DTR1, (dtr ? 0 : MCFPP_DTR1)); | ||
207 | else | ||
208 | mcf_setppdata(MCFPP_DTR0, (dtr ? 0 : MCFPP_DTR0)); | ||
209 | #endif | ||
210 | } | ||
211 | if (rts >= 0) { | ||
212 | uartp = info->addr; | ||
213 | if (rts) { | ||
214 | info->sigs |= TIOCM_RTS; | ||
215 | uartp[MCFUART_UOP1] = MCFUART_UOP_RTS; | ||
216 | } else { | ||
217 | info->sigs &= ~TIOCM_RTS; | ||
218 | uartp[MCFUART_UOP0] = MCFUART_UOP_RTS; | ||
219 | } | ||
220 | } | ||
221 | local_irq_restore(flags); | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * Gets values of serial signals. | ||
227 | */ | ||
228 | static int mcfrs_getsignals(struct mcf_serial *info) | ||
229 | { | ||
230 | volatile unsigned char *uartp; | ||
231 | unsigned long flags; | ||
232 | int sigs; | ||
233 | #if defined(CONFIG_NETtel) && defined(CONFIG_M5307) | ||
234 | unsigned short ppdata; | ||
235 | #endif | ||
236 | |||
237 | #if 0 | ||
238 | printk("%s(%d): mcfrs_getsignals(info=%x)\n", __FILE__, __LINE__); | ||
239 | #endif | ||
240 | |||
241 | local_irq_save(flags); | ||
242 | uartp = info->addr; | ||
243 | sigs = (uartp[MCFUART_UIPR] & MCFUART_UIPR_CTS) ? 0 : TIOCM_CTS; | ||
244 | sigs |= (info->sigs & TIOCM_RTS); | ||
245 | |||
246 | #ifdef MCFPP_DCD0 | ||
247 | { | ||
248 | unsigned int ppdata; | ||
249 | ppdata = mcf_getppdata(); | ||
250 | if (info->line == 0) { | ||
251 | sigs |= (ppdata & MCFPP_DCD0) ? 0 : TIOCM_CD; | ||
252 | sigs |= (ppdata & MCFPP_DTR0) ? 0 : TIOCM_DTR; | ||
253 | } else if (info->line == 1) { | ||
254 | sigs |= (ppdata & MCFPP_DCD1) ? 0 : TIOCM_CD; | ||
255 | sigs |= (ppdata & MCFPP_DTR1) ? 0 : TIOCM_DTR; | ||
256 | } | ||
257 | } | ||
258 | #endif | ||
259 | |||
260 | local_irq_restore(flags); | ||
261 | return(sigs); | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * ------------------------------------------------------------ | ||
266 | * mcfrs_stop() and mcfrs_start() | ||
267 | * | ||
268 | * This routines are called before setting or resetting tty->stopped. | ||
269 | * They enable or disable transmitter interrupts, as necessary. | ||
270 | * ------------------------------------------------------------ | ||
271 | */ | ||
272 | static void mcfrs_stop(struct tty_struct *tty) | ||
273 | { | ||
274 | volatile unsigned char *uartp; | ||
275 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
276 | unsigned long flags; | ||
277 | |||
278 | if (serial_paranoia_check(info, tty->name, "mcfrs_stop")) | ||
279 | return; | ||
280 | |||
281 | local_irq_save(flags); | ||
282 | uartp = info->addr; | ||
283 | info->imr &= ~MCFUART_UIR_TXREADY; | ||
284 | uartp[MCFUART_UIMR] = info->imr; | ||
285 | local_irq_restore(flags); | ||
286 | } | ||
287 | |||
288 | static void mcfrs_start(struct tty_struct *tty) | ||
289 | { | ||
290 | volatile unsigned char *uartp; | ||
291 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
292 | unsigned long flags; | ||
293 | |||
294 | if (serial_paranoia_check(info, tty->name, "mcfrs_start")) | ||
295 | return; | ||
296 | |||
297 | local_irq_save(flags); | ||
298 | if (info->xmit_cnt && info->xmit_buf) { | ||
299 | uartp = info->addr; | ||
300 | info->imr |= MCFUART_UIR_TXREADY; | ||
301 | uartp[MCFUART_UIMR] = info->imr; | ||
302 | } | ||
303 | local_irq_restore(flags); | ||
304 | } | ||
305 | |||
306 | /* | ||
307 | * ---------------------------------------------------------------------- | ||
308 | * | ||
309 | * Here starts the interrupt handling routines. All of the following | ||
310 | * subroutines are declared as inline and are folded into | ||
311 | * mcfrs_interrupt(). They were separated out for readability's sake. | ||
312 | * | ||
313 | * Note: mcfrs_interrupt() is a "fast" interrupt, which means that it | ||
314 | * runs with interrupts turned off. People who may want to modify | ||
315 | * mcfrs_interrupt() should try to keep the interrupt handler as fast as | ||
316 | * possible. After you are done making modifications, it is not a bad | ||
317 | * idea to do: | ||
318 | * | ||
319 | * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c | ||
320 | * | ||
321 | * and look at the resulting assemble code in serial.s. | ||
322 | * | ||
323 | * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 | ||
324 | * ----------------------------------------------------------------------- | ||
325 | */ | ||
326 | |||
327 | static inline void receive_chars(struct mcf_serial *info) | ||
328 | { | ||
329 | volatile unsigned char *uartp; | ||
330 | struct tty_struct *tty = info->port.tty; | ||
331 | unsigned char status, ch, flag; | ||
332 | |||
333 | if (!tty) | ||
334 | return; | ||
335 | |||
336 | uartp = info->addr; | ||
337 | |||
338 | while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) { | ||
339 | ch = uartp[MCFUART_URB]; | ||
340 | info->stats.rx++; | ||
341 | |||
342 | #ifdef CONFIG_MAGIC_SYSRQ | ||
343 | if (mcfrs_console_inited && (info->line == mcfrs_console_port)) { | ||
344 | if (magic_sysrq_key(ch)) | ||
345 | continue; | ||
346 | } | ||
347 | #endif | ||
348 | |||
349 | flag = TTY_NORMAL; | ||
350 | if (status & MCFUART_USR_RXERR) { | ||
351 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; | ||
352 | if (status & MCFUART_USR_RXBREAK) { | ||
353 | info->stats.rxbreak++; | ||
354 | flag = TTY_BREAK; | ||
355 | } else if (status & MCFUART_USR_RXPARITY) { | ||
356 | info->stats.rxparity++; | ||
357 | flag = TTY_PARITY; | ||
358 | } else if (status & MCFUART_USR_RXOVERRUN) { | ||
359 | info->stats.rxoverrun++; | ||
360 | flag = TTY_OVERRUN; | ||
361 | } else if (status & MCFUART_USR_RXFRAMING) { | ||
362 | info->stats.rxframing++; | ||
363 | flag = TTY_FRAME; | ||
364 | } | ||
365 | } | ||
366 | tty_insert_flip_char(tty, ch, flag); | ||
367 | } | ||
368 | tty_schedule_flip(tty); | ||
369 | return; | ||
370 | } | ||
371 | |||
372 | static inline void transmit_chars(struct mcf_serial *info) | ||
373 | { | ||
374 | volatile unsigned char *uartp; | ||
375 | |||
376 | uartp = info->addr; | ||
377 | |||
378 | if (info->x_char) { | ||
379 | /* Send special char - probably flow control */ | ||
380 | uartp[MCFUART_UTB] = info->x_char; | ||
381 | info->x_char = 0; | ||
382 | info->stats.tx++; | ||
383 | } | ||
384 | |||
385 | if ((info->xmit_cnt <= 0) || info->port.tty->stopped) { | ||
386 | info->imr &= ~MCFUART_UIR_TXREADY; | ||
387 | uartp[MCFUART_UIMR] = info->imr; | ||
388 | return; | ||
389 | } | ||
390 | |||
391 | while (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) { | ||
392 | uartp[MCFUART_UTB] = info->xmit_buf[info->xmit_tail++]; | ||
393 | info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); | ||
394 | info->stats.tx++; | ||
395 | if (--info->xmit_cnt <= 0) | ||
396 | break; | ||
397 | } | ||
398 | |||
399 | if (info->xmit_cnt < WAKEUP_CHARS) | ||
400 | schedule_work(&info->tqueue); | ||
401 | return; | ||
402 | } | ||
403 | |||
404 | /* | ||
405 | * This is the serial driver's generic interrupt routine | ||
406 | */ | ||
407 | irqreturn_t mcfrs_interrupt(int irq, void *dev_id) | ||
408 | { | ||
409 | struct mcf_serial *info; | ||
410 | unsigned char isr; | ||
411 | |||
412 | info = &mcfrs_table[(irq - IRQBASE)]; | ||
413 | isr = info->addr[MCFUART_UISR] & info->imr; | ||
414 | |||
415 | if (isr & MCFUART_UIR_RXREADY) | ||
416 | receive_chars(info); | ||
417 | if (isr & MCFUART_UIR_TXREADY) | ||
418 | transmit_chars(info); | ||
419 | return IRQ_HANDLED; | ||
420 | } | ||
421 | |||
422 | /* | ||
423 | * ------------------------------------------------------------------- | ||
424 | * Here ends the serial interrupt routines. | ||
425 | * ------------------------------------------------------------------- | ||
426 | */ | ||
427 | |||
428 | static void mcfrs_offintr(struct work_struct *work) | ||
429 | { | ||
430 | struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue); | ||
431 | struct tty_struct *tty = info->port.tty; | ||
432 | |||
433 | if (tty) | ||
434 | tty_wakeup(tty); | ||
435 | } | ||
436 | |||
437 | |||
438 | /* | ||
439 | * Change of state on a DCD line. | ||
440 | */ | ||
441 | void mcfrs_modem_change(struct mcf_serial *info, int dcd) | ||
442 | { | ||
443 | if (info->count == 0) | ||
444 | return; | ||
445 | |||
446 | if (info->flags & ASYNC_CHECK_CD) { | ||
447 | if (dcd) | ||
448 | wake_up_interruptible(&info->open_wait); | ||
449 | else | ||
450 | schedule_work(&info->tqueue_hangup); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | |||
455 | #ifdef MCFPP_DCD0 | ||
456 | |||
457 | unsigned short mcfrs_ppstatus; | ||
458 | |||
459 | /* | ||
460 | * This subroutine is called when the RS_TIMER goes off. It is used | ||
461 | * to monitor the state of the DCD lines - since they have no edge | ||
462 | * sensors and interrupt generators. | ||
463 | */ | ||
464 | static void mcfrs_timer(void) | ||
465 | { | ||
466 | unsigned int ppstatus, dcdval, i; | ||
467 | |||
468 | ppstatus = mcf_getppdata() & (MCFPP_DCD0 | MCFPP_DCD1); | ||
469 | |||
470 | if (ppstatus != mcfrs_ppstatus) { | ||
471 | for (i = 0; (i < 2); i++) { | ||
472 | dcdval = (i ? MCFPP_DCD1 : MCFPP_DCD0); | ||
473 | if ((ppstatus & dcdval) != (mcfrs_ppstatus & dcdval)) { | ||
474 | mcfrs_modem_change(&mcfrs_table[i], | ||
475 | ((ppstatus & dcdval) ? 0 : 1)); | ||
476 | } | ||
477 | } | ||
478 | } | ||
479 | mcfrs_ppstatus = ppstatus; | ||
480 | |||
481 | /* Re-arm timer */ | ||
482 | mcfrs_timer_struct.expires = jiffies + HZ/25; | ||
483 | add_timer(&mcfrs_timer_struct); | ||
484 | } | ||
485 | |||
486 | #endif /* MCFPP_DCD0 */ | ||
487 | |||
488 | |||
489 | /* | ||
490 | * This routine is called from the scheduler tqueue when the interrupt | ||
491 | * routine has signalled that a hangup has occurred. The path of | ||
492 | * hangup processing is: | ||
493 | * | ||
494 | * serial interrupt routine -> (scheduler tqueue) -> | ||
495 | * do_serial_hangup() -> tty->hangup() -> mcfrs_hangup() | ||
496 | * | ||
497 | */ | ||
498 | static void do_serial_hangup(struct work_struct *work) | ||
499 | { | ||
500 | struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue_hangup); | ||
501 | struct tty_struct *tty = info->port.tty; | ||
502 | |||
503 | if (tty) | ||
504 | tty_hangup(tty); | ||
505 | } | ||
506 | |||
507 | static int startup(struct mcf_serial * info) | ||
508 | { | ||
509 | volatile unsigned char *uartp; | ||
510 | unsigned long flags; | ||
511 | |||
512 | if (info->flags & ASYNC_INITIALIZED) | ||
513 | return 0; | ||
514 | |||
515 | if (!info->xmit_buf) { | ||
516 | info->xmit_buf = (unsigned char *) __get_free_page(GFP_KERNEL); | ||
517 | if (!info->xmit_buf) | ||
518 | return -ENOMEM; | ||
519 | } | ||
520 | |||
521 | local_irq_save(flags); | ||
522 | |||
523 | #ifdef SERIAL_DEBUG_OPEN | ||
524 | printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq); | ||
525 | #endif | ||
526 | |||
527 | /* | ||
528 | * Reset UART, get it into known state... | ||
529 | */ | ||
530 | uartp = info->addr; | ||
531 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ | ||
532 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ | ||
533 | mcfrs_setsignals(info, 1, 1); | ||
534 | |||
535 | if (info->port.tty) | ||
536 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
537 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
538 | |||
539 | /* | ||
540 | * and set the speed of the serial port | ||
541 | */ | ||
542 | mcfrs_change_speed(info); | ||
543 | |||
544 | /* | ||
545 | * Lastly enable the UART transmitter and receiver, and | ||
546 | * interrupt enables. | ||
547 | */ | ||
548 | info->imr = MCFUART_UIR_RXREADY; | ||
549 | uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; | ||
550 | uartp[MCFUART_UIMR] = info->imr; | ||
551 | |||
552 | info->flags |= ASYNC_INITIALIZED; | ||
553 | local_irq_restore(flags); | ||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | /* | ||
558 | * This routine will shutdown a serial port; interrupts are disabled, and | ||
559 | * DTR is dropped if the hangup on close termio flag is on. | ||
560 | */ | ||
561 | static void shutdown(struct mcf_serial * info) | ||
562 | { | ||
563 | volatile unsigned char *uartp; | ||
564 | unsigned long flags; | ||
565 | |||
566 | if (!(info->flags & ASYNC_INITIALIZED)) | ||
567 | return; | ||
568 | |||
569 | #ifdef SERIAL_DEBUG_OPEN | ||
570 | printk("Shutting down serial port %d (irq %d)....\n", info->line, | ||
571 | info->irq); | ||
572 | #endif | ||
573 | |||
574 | local_irq_save(flags); | ||
575 | |||
576 | uartp = info->addr; | ||
577 | uartp[MCFUART_UIMR] = 0; /* mask all interrupts */ | ||
578 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ | ||
579 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ | ||
580 | |||
581 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) | ||
582 | mcfrs_setsignals(info, 0, 0); | ||
583 | |||
584 | if (info->xmit_buf) { | ||
585 | free_page((unsigned long) info->xmit_buf); | ||
586 | info->xmit_buf = 0; | ||
587 | } | ||
588 | |||
589 | if (info->port.tty) | ||
590 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
591 | |||
592 | info->flags &= ~ASYNC_INITIALIZED; | ||
593 | local_irq_restore(flags); | ||
594 | } | ||
595 | |||
596 | |||
597 | /* | ||
598 | * This routine is called to set the UART divisor registers to match | ||
599 | * the specified baud rate for a serial port. | ||
600 | */ | ||
601 | static void mcfrs_change_speed(struct mcf_serial *info) | ||
602 | { | ||
603 | volatile unsigned char *uartp; | ||
604 | unsigned int baudclk, cflag; | ||
605 | unsigned long flags; | ||
606 | unsigned char mr1, mr2; | ||
607 | int i; | ||
608 | #ifdef CONFIG_M5272 | ||
609 | unsigned int fraction; | ||
610 | #endif | ||
611 | |||
612 | if (!info->port.tty || !info->port.tty->termios) | ||
613 | return; | ||
614 | cflag = info->port.tty->termios->c_cflag; | ||
615 | if (info->addr == 0) | ||
616 | return; | ||
617 | |||
618 | #if 0 | ||
619 | printk("%s(%d): mcfrs_change_speed()\n", __FILE__, __LINE__); | ||
620 | #endif | ||
621 | |||
622 | i = cflag & CBAUD; | ||
623 | if (i & CBAUDEX) { | ||
624 | i &= ~CBAUDEX; | ||
625 | if (i < 1 || i > 4) | ||
626 | info->port.tty->termios->c_cflag &= ~CBAUDEX; | ||
627 | else | ||
628 | i += 15; | ||
629 | } | ||
630 | if (i == 0) { | ||
631 | mcfrs_setsignals(info, 0, -1); | ||
632 | return; | ||
633 | } | ||
634 | |||
635 | /* compute the baudrate clock */ | ||
636 | #ifdef CONFIG_M5272 | ||
637 | /* | ||
638 | * For the MCF5272, also compute the baudrate fraction. | ||
639 | */ | ||
640 | baudclk = (MCF_BUSCLK / mcfrs_baud_table[i]) / 32; | ||
641 | fraction = MCF_BUSCLK - (baudclk * 32 * mcfrs_baud_table[i]); | ||
642 | fraction *= 16; | ||
643 | fraction /= (32 * mcfrs_baud_table[i]); | ||
644 | #else | ||
645 | baudclk = ((MCF_BUSCLK / mcfrs_baud_table[i]) + 16) / 32; | ||
646 | #endif | ||
647 | |||
648 | info->baud = mcfrs_baud_table[i]; | ||
649 | |||
650 | mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR; | ||
651 | mr2 = 0; | ||
652 | |||
653 | switch (cflag & CSIZE) { | ||
654 | case CS5: mr1 |= MCFUART_MR1_CS5; break; | ||
655 | case CS6: mr1 |= MCFUART_MR1_CS6; break; | ||
656 | case CS7: mr1 |= MCFUART_MR1_CS7; break; | ||
657 | case CS8: | ||
658 | default: mr1 |= MCFUART_MR1_CS8; break; | ||
659 | } | ||
660 | |||
661 | if (cflag & PARENB) { | ||
662 | if (cflag & CMSPAR) { | ||
663 | if (cflag & PARODD) | ||
664 | mr1 |= MCFUART_MR1_PARITYMARK; | ||
665 | else | ||
666 | mr1 |= MCFUART_MR1_PARITYSPACE; | ||
667 | } else { | ||
668 | if (cflag & PARODD) | ||
669 | mr1 |= MCFUART_MR1_PARITYODD; | ||
670 | else | ||
671 | mr1 |= MCFUART_MR1_PARITYEVEN; | ||
672 | } | ||
673 | } else { | ||
674 | mr1 |= MCFUART_MR1_PARITYNONE; | ||
675 | } | ||
676 | |||
677 | if (cflag & CSTOPB) | ||
678 | mr2 |= MCFUART_MR2_STOP2; | ||
679 | else | ||
680 | mr2 |= MCFUART_MR2_STOP1; | ||
681 | |||
682 | if (cflag & CRTSCTS) { | ||
683 | mr1 |= MCFUART_MR1_RXRTS; | ||
684 | mr2 |= MCFUART_MR2_TXCTS; | ||
685 | } | ||
686 | |||
687 | if (cflag & CLOCAL) | ||
688 | info->flags &= ~ASYNC_CHECK_CD; | ||
689 | else | ||
690 | info->flags |= ASYNC_CHECK_CD; | ||
691 | |||
692 | uartp = info->addr; | ||
693 | |||
694 | local_irq_save(flags); | ||
695 | #if 0 | ||
696 | printk("%s(%d): mr1=%x mr2=%x baudclk=%x\n", __FILE__, __LINE__, | ||
697 | mr1, mr2, baudclk); | ||
698 | #endif | ||
699 | /* | ||
700 | Note: pg 12-16 of MCF5206e User's Manual states that a | ||
701 | software reset should be performed prior to changing | ||
702 | UMR1,2, UCSR, UACR, bit 7 | ||
703 | */ | ||
704 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ | ||
705 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ | ||
706 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */ | ||
707 | uartp[MCFUART_UMR] = mr1; | ||
708 | uartp[MCFUART_UMR] = mr2; | ||
709 | uartp[MCFUART_UBG1] = (baudclk & 0xff00) >> 8; /* set msb byte */ | ||
710 | uartp[MCFUART_UBG2] = (baudclk & 0xff); /* set lsb byte */ | ||
711 | #ifdef CONFIG_M5272 | ||
712 | uartp[MCFUART_UFPD] = (fraction & 0xf); /* set fraction */ | ||
713 | #endif | ||
714 | uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER; | ||
715 | uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; | ||
716 | mcfrs_setsignals(info, 1, -1); | ||
717 | local_irq_restore(flags); | ||
718 | return; | ||
719 | } | ||
720 | |||
721 | static void mcfrs_flush_chars(struct tty_struct *tty) | ||
722 | { | ||
723 | volatile unsigned char *uartp; | ||
724 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
725 | unsigned long flags; | ||
726 | |||
727 | if (serial_paranoia_check(info, tty->name, "mcfrs_flush_chars")) | ||
728 | return; | ||
729 | |||
730 | uartp = (volatile unsigned char *) info->addr; | ||
731 | |||
732 | /* | ||
733 | * re-enable receiver interrupt | ||
734 | */ | ||
735 | local_irq_save(flags); | ||
736 | if ((!(info->imr & MCFUART_UIR_RXREADY)) && | ||
737 | (info->flags & ASYNC_INITIALIZED) ) { | ||
738 | info->imr |= MCFUART_UIR_RXREADY; | ||
739 | uartp[MCFUART_UIMR] = info->imr; | ||
740 | } | ||
741 | local_irq_restore(flags); | ||
742 | |||
743 | if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || | ||
744 | !info->xmit_buf) | ||
745 | return; | ||
746 | |||
747 | /* Enable transmitter */ | ||
748 | local_irq_save(flags); | ||
749 | info->imr |= MCFUART_UIR_TXREADY; | ||
750 | uartp[MCFUART_UIMR] = info->imr; | ||
751 | local_irq_restore(flags); | ||
752 | } | ||
753 | |||
754 | static int mcfrs_write(struct tty_struct * tty, | ||
755 | const unsigned char *buf, int count) | ||
756 | { | ||
757 | volatile unsigned char *uartp; | ||
758 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
759 | unsigned long flags; | ||
760 | int c, total = 0; | ||
761 | |||
762 | #if 0 | ||
763 | printk("%s(%d): mcfrs_write(tty=%x,buf=%x,count=%d)\n", | ||
764 | __FILE__, __LINE__, (int)tty, (int)buf, count); | ||
765 | #endif | ||
766 | |||
767 | if (serial_paranoia_check(info, tty->name, "mcfrs_write")) | ||
768 | return 0; | ||
769 | |||
770 | if (!tty || !info->xmit_buf) | ||
771 | return 0; | ||
772 | |||
773 | local_save_flags(flags); | ||
774 | while (1) { | ||
775 | local_irq_disable(); | ||
776 | c = min(count, (int) min(((int)SERIAL_XMIT_SIZE) - info->xmit_cnt - 1, | ||
777 | ((int)SERIAL_XMIT_SIZE) - info->xmit_head)); | ||
778 | local_irq_restore(flags); | ||
779 | |||
780 | if (c <= 0) | ||
781 | break; | ||
782 | |||
783 | memcpy(info->xmit_buf + info->xmit_head, buf, c); | ||
784 | |||
785 | local_irq_disable(); | ||
786 | info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); | ||
787 | info->xmit_cnt += c; | ||
788 | local_irq_restore(flags); | ||
789 | |||
790 | buf += c; | ||
791 | count -= c; | ||
792 | total += c; | ||
793 | } | ||
794 | |||
795 | local_irq_disable(); | ||
796 | uartp = info->addr; | ||
797 | info->imr |= MCFUART_UIR_TXREADY; | ||
798 | uartp[MCFUART_UIMR] = info->imr; | ||
799 | local_irq_restore(flags); | ||
800 | |||
801 | return total; | ||
802 | } | ||
803 | |||
804 | static int mcfrs_write_room(struct tty_struct *tty) | ||
805 | { | ||
806 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
807 | int ret; | ||
808 | |||
809 | if (serial_paranoia_check(info, tty->name, "mcfrs_write_room")) | ||
810 | return 0; | ||
811 | ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; | ||
812 | if (ret < 0) | ||
813 | ret = 0; | ||
814 | return ret; | ||
815 | } | ||
816 | |||
817 | static int mcfrs_chars_in_buffer(struct tty_struct *tty) | ||
818 | { | ||
819 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
820 | |||
821 | if (serial_paranoia_check(info, tty->name, "mcfrs_chars_in_buffer")) | ||
822 | return 0; | ||
823 | return info->xmit_cnt; | ||
824 | } | ||
825 | |||
826 | static void mcfrs_flush_buffer(struct tty_struct *tty) | ||
827 | { | ||
828 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
829 | unsigned long flags; | ||
830 | |||
831 | if (serial_paranoia_check(info, tty->name, "mcfrs_flush_buffer")) | ||
832 | return; | ||
833 | |||
834 | local_irq_save(flags); | ||
835 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
836 | local_irq_restore(flags); | ||
837 | |||
838 | tty_wakeup(tty); | ||
839 | } | ||
840 | |||
841 | /* | ||
842 | * ------------------------------------------------------------ | ||
843 | * mcfrs_throttle() | ||
844 | * | ||
845 | * This routine is called by the upper-layer tty layer to signal that | ||
846 | * incoming characters should be throttled. | ||
847 | * ------------------------------------------------------------ | ||
848 | */ | ||
849 | static void mcfrs_throttle(struct tty_struct * tty) | ||
850 | { | ||
851 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
852 | #ifdef SERIAL_DEBUG_THROTTLE | ||
853 | char buf[64]; | ||
854 | |||
855 | printk("throttle %s: %d....\n", tty_name(tty, buf), | ||
856 | tty->ldisc.chars_in_buffer(tty)); | ||
857 | #endif | ||
858 | |||
859 | if (serial_paranoia_check(info, tty->name, "mcfrs_throttle")) | ||
860 | return; | ||
861 | |||
862 | if (I_IXOFF(tty)) | ||
863 | info->x_char = STOP_CHAR(tty); | ||
864 | |||
865 | /* Turn off RTS line (do this atomic) */ | ||
866 | } | ||
867 | |||
868 | static void mcfrs_unthrottle(struct tty_struct * tty) | ||
869 | { | ||
870 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
871 | #ifdef SERIAL_DEBUG_THROTTLE | ||
872 | char buf[64]; | ||
873 | |||
874 | printk("unthrottle %s: %d....\n", tty_name(tty, buf), | ||
875 | tty->ldisc.chars_in_buffer(tty)); | ||
876 | #endif | ||
877 | |||
878 | if (serial_paranoia_check(info, tty->name, "mcfrs_unthrottle")) | ||
879 | return; | ||
880 | |||
881 | if (I_IXOFF(tty)) { | ||
882 | if (info->x_char) | ||
883 | info->x_char = 0; | ||
884 | else | ||
885 | info->x_char = START_CHAR(tty); | ||
886 | } | ||
887 | |||
888 | /* Assert RTS line (do this atomic) */ | ||
889 | } | ||
890 | |||
891 | /* | ||
892 | * ------------------------------------------------------------ | ||
893 | * mcfrs_ioctl() and friends | ||
894 | * ------------------------------------------------------------ | ||
895 | */ | ||
896 | |||
897 | static int get_serial_info(struct mcf_serial * info, | ||
898 | struct serial_struct * retinfo) | ||
899 | { | ||
900 | struct serial_struct tmp; | ||
901 | |||
902 | if (!retinfo) | ||
903 | return -EFAULT; | ||
904 | memset(&tmp, 0, sizeof(tmp)); | ||
905 | tmp.type = info->type; | ||
906 | tmp.line = info->line; | ||
907 | tmp.port = (unsigned int) info->addr; | ||
908 | tmp.irq = info->irq; | ||
909 | tmp.flags = info->flags; | ||
910 | tmp.baud_base = info->baud_base; | ||
911 | tmp.close_delay = info->close_delay; | ||
912 | tmp.closing_wait = info->closing_wait; | ||
913 | tmp.custom_divisor = info->custom_divisor; | ||
914 | return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0; | ||
915 | } | ||
916 | |||
917 | static int set_serial_info(struct mcf_serial * info, | ||
918 | struct serial_struct * new_info) | ||
919 | { | ||
920 | struct serial_struct new_serial; | ||
921 | struct mcf_serial old_info; | ||
922 | int retval = 0; | ||
923 | |||
924 | if (!new_info) | ||
925 | return -EFAULT; | ||
926 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | ||
927 | return -EFAULT; | ||
928 | old_info = *info; | ||
929 | |||
930 | if (!capable(CAP_SYS_ADMIN)) { | ||
931 | if ((new_serial.baud_base != info->baud_base) || | ||
932 | (new_serial.type != info->type) || | ||
933 | (new_serial.close_delay != info->close_delay) || | ||
934 | ((new_serial.flags & ~ASYNC_USR_MASK) != | ||
935 | (info->flags & ~ASYNC_USR_MASK))) | ||
936 | return -EPERM; | ||
937 | info->flags = ((info->flags & ~ASYNC_USR_MASK) | | ||
938 | (new_serial.flags & ASYNC_USR_MASK)); | ||
939 | info->custom_divisor = new_serial.custom_divisor; | ||
940 | goto check_and_exit; | ||
941 | } | ||
942 | |||
943 | if (info->count > 1) | ||
944 | return -EBUSY; | ||
945 | |||
946 | /* | ||
947 | * OK, past this point, all the error checking has been done. | ||
948 | * At this point, we start making changes..... | ||
949 | */ | ||
950 | |||
951 | info->baud_base = new_serial.baud_base; | ||
952 | info->flags = ((info->flags & ~ASYNC_FLAGS) | | ||
953 | (new_serial.flags & ASYNC_FLAGS)); | ||
954 | info->type = new_serial.type; | ||
955 | info->close_delay = new_serial.close_delay; | ||
956 | info->closing_wait = new_serial.closing_wait; | ||
957 | |||
958 | check_and_exit: | ||
959 | retval = startup(info); | ||
960 | return retval; | ||
961 | } | ||
962 | |||
963 | /* | ||
964 | * get_lsr_info - get line status register info | ||
965 | * | ||
966 | * Purpose: Let user call ioctl() to get info when the UART physically | ||
967 | * is emptied. On bus types like RS485, the transmitter must | ||
968 | * release the bus after transmitting. This must be done when | ||
969 | * the transmit shift register is empty, not be done when the | ||
970 | * transmit holding register is empty. This functionality | ||
971 | * allows an RS485 driver to be written in user space. | ||
972 | */ | ||
973 | static int get_lsr_info(struct mcf_serial * info, unsigned int *value) | ||
974 | { | ||
975 | volatile unsigned char *uartp; | ||
976 | unsigned long flags; | ||
977 | unsigned char status; | ||
978 | |||
979 | local_irq_save(flags); | ||
980 | uartp = info->addr; | ||
981 | status = (uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY) ? TIOCSER_TEMT : 0; | ||
982 | local_irq_restore(flags); | ||
983 | |||
984 | return put_user(status,value); | ||
985 | } | ||
986 | |||
987 | /* | ||
988 | * This routine sends a break character out the serial port. | ||
989 | */ | ||
990 | static void send_break( struct mcf_serial * info, int duration) | ||
991 | { | ||
992 | volatile unsigned char *uartp; | ||
993 | unsigned long flags; | ||
994 | |||
995 | if (!info->addr) | ||
996 | return; | ||
997 | set_current_state(TASK_INTERRUPTIBLE); | ||
998 | uartp = info->addr; | ||
999 | |||
1000 | local_irq_save(flags); | ||
1001 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTART; | ||
1002 | schedule_timeout(duration); | ||
1003 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTOP; | ||
1004 | local_irq_restore(flags); | ||
1005 | } | ||
1006 | |||
1007 | static int mcfrs_tiocmget(struct tty_struct *tty, struct file *file) | ||
1008 | { | ||
1009 | struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; | ||
1010 | |||
1011 | if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl")) | ||
1012 | return -ENODEV; | ||
1013 | if (tty->flags & (1 << TTY_IO_ERROR)) | ||
1014 | return -EIO; | ||
1015 | |||
1016 | return mcfrs_getsignals(info); | ||
1017 | } | ||
1018 | |||
1019 | static int mcfrs_tiocmset(struct tty_struct *tty, struct file *file, | ||
1020 | unsigned int set, unsigned int clear) | ||
1021 | { | ||
1022 | struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; | ||
1023 | int rts = -1, dtr = -1; | ||
1024 | |||
1025 | if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl")) | ||
1026 | return -ENODEV; | ||
1027 | if (tty->flags & (1 << TTY_IO_ERROR)) | ||
1028 | return -EIO; | ||
1029 | |||
1030 | if (set & TIOCM_RTS) | ||
1031 | rts = 1; | ||
1032 | if (set & TIOCM_DTR) | ||
1033 | dtr = 1; | ||
1034 | if (clear & TIOCM_RTS) | ||
1035 | rts = 0; | ||
1036 | if (clear & TIOCM_DTR) | ||
1037 | dtr = 0; | ||
1038 | |||
1039 | mcfrs_setsignals(info, dtr, rts); | ||
1040 | |||
1041 | return 0; | ||
1042 | } | ||
1043 | |||
1044 | static int mcfrs_ioctl(struct tty_struct *tty, struct file * file, | ||
1045 | unsigned int cmd, unsigned long arg) | ||
1046 | { | ||
1047 | struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; | ||
1048 | int retval, error; | ||
1049 | |||
1050 | if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl")) | ||
1051 | return -ENODEV; | ||
1052 | |||
1053 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | ||
1054 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && | ||
1055 | (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { | ||
1056 | if (tty->flags & (1 << TTY_IO_ERROR)) | ||
1057 | return -EIO; | ||
1058 | } | ||
1059 | |||
1060 | switch (cmd) { | ||
1061 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | ||
1062 | retval = tty_check_change(tty); | ||
1063 | if (retval) | ||
1064 | return retval; | ||
1065 | tty_wait_until_sent(tty, 0); | ||
1066 | if (!arg) | ||
1067 | send_break(info, HZ/4); /* 1/4 second */ | ||
1068 | return 0; | ||
1069 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | ||
1070 | retval = tty_check_change(tty); | ||
1071 | if (retval) | ||
1072 | return retval; | ||
1073 | tty_wait_until_sent(tty, 0); | ||
1074 | send_break(info, arg ? arg*(HZ/10) : HZ/4); | ||
1075 | return 0; | ||
1076 | case TIOCGSERIAL: | ||
1077 | if (access_ok(VERIFY_WRITE, (void *) arg, | ||
1078 | sizeof(struct serial_struct))) | ||
1079 | return get_serial_info(info, | ||
1080 | (struct serial_struct *) arg); | ||
1081 | return -EFAULT; | ||
1082 | case TIOCSSERIAL: | ||
1083 | return set_serial_info(info, | ||
1084 | (struct serial_struct *) arg); | ||
1085 | case TIOCSERGETLSR: /* Get line status register */ | ||
1086 | if (access_ok(VERIFY_WRITE, (void *) arg, | ||
1087 | sizeof(unsigned int))) | ||
1088 | return get_lsr_info(info, (unsigned int *) arg); | ||
1089 | return -EFAULT; | ||
1090 | case TIOCSERGSTRUCT: | ||
1091 | error = copy_to_user((struct mcf_serial *) arg, | ||
1092 | info, sizeof(struct mcf_serial)); | ||
1093 | if (error) | ||
1094 | return -EFAULT; | ||
1095 | return 0; | ||
1096 | |||
1097 | #ifdef TIOCSET422 | ||
1098 | case TIOCSET422: { | ||
1099 | unsigned int val; | ||
1100 | get_user(val, (unsigned int *) arg); | ||
1101 | mcf_setpa(MCFPP_PA11, (val ? 0 : MCFPP_PA11)); | ||
1102 | break; | ||
1103 | } | ||
1104 | case TIOCGET422: { | ||
1105 | unsigned int val; | ||
1106 | val = (mcf_getpa() & MCFPP_PA11) ? 0 : 1; | ||
1107 | put_user(val, (unsigned int *) arg); | ||
1108 | break; | ||
1109 | } | ||
1110 | #endif | ||
1111 | |||
1112 | default: | ||
1113 | return -ENOIOCTLCMD; | ||
1114 | } | ||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | static void mcfrs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | ||
1119 | { | ||
1120 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
1121 | |||
1122 | if (tty->termios->c_cflag == old_termios->c_cflag) | ||
1123 | return; | ||
1124 | |||
1125 | mcfrs_change_speed(info); | ||
1126 | |||
1127 | if ((old_termios->c_cflag & CRTSCTS) && | ||
1128 | !(tty->termios->c_cflag & CRTSCTS)) { | ||
1129 | tty->hw_stopped = 0; | ||
1130 | mcfrs_setsignals(info, -1, 1); | ||
1131 | #if 0 | ||
1132 | mcfrs_start(tty); | ||
1133 | #endif | ||
1134 | } | ||
1135 | } | ||
1136 | |||
1137 | /* | ||
1138 | * ------------------------------------------------------------ | ||
1139 | * mcfrs_close() | ||
1140 | * | ||
1141 | * This routine is called when the serial port gets closed. First, we | ||
1142 | * wait for the last remaining data to be sent. Then, we unlink its | ||
1143 | * S structure from the interrupt chain if necessary, and we free | ||
1144 | * that IRQ if nothing is left in the chain. | ||
1145 | * ------------------------------------------------------------ | ||
1146 | */ | ||
1147 | static void mcfrs_close(struct tty_struct *tty, struct file * filp) | ||
1148 | { | ||
1149 | volatile unsigned char *uartp; | ||
1150 | struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; | ||
1151 | unsigned long flags; | ||
1152 | |||
1153 | if (!info || serial_paranoia_check(info, tty->name, "mcfrs_close")) | ||
1154 | return; | ||
1155 | |||
1156 | local_irq_save(flags); | ||
1157 | |||
1158 | if (tty_hung_up_p(filp)) { | ||
1159 | local_irq_restore(flags); | ||
1160 | return; | ||
1161 | } | ||
1162 | |||
1163 | #ifdef SERIAL_DEBUG_OPEN | ||
1164 | printk("mcfrs_close ttyS%d, count = %d\n", info->line, info->count); | ||
1165 | #endif | ||
1166 | if ((tty->count == 1) && (info->count != 1)) { | ||
1167 | /* | ||
1168 | * Uh, oh. tty->count is 1, which means that the tty | ||
1169 | * structure will be freed. Info->count should always | ||
1170 | * be one in these conditions. If it's greater than | ||
1171 | * one, we've got real problems, since it means the | ||
1172 | * serial port won't be shutdown. | ||
1173 | */ | ||
1174 | printk("MCFRS: bad serial port count; tty->count is 1, " | ||
1175 | "info->count is %d\n", info->count); | ||
1176 | info->count = 1; | ||
1177 | } | ||
1178 | if (--info->count < 0) { | ||
1179 | printk("MCFRS: bad serial port count for ttyS%d: %d\n", | ||
1180 | info->line, info->count); | ||
1181 | info->count = 0; | ||
1182 | } | ||
1183 | if (info->count) { | ||
1184 | local_irq_restore(flags); | ||
1185 | return; | ||
1186 | } | ||
1187 | info->flags |= ASYNC_CLOSING; | ||
1188 | |||
1189 | /* | ||
1190 | * Now we wait for the transmit buffer to clear; and we notify | ||
1191 | * the line discipline to only process XON/XOFF characters. | ||
1192 | */ | ||
1193 | tty->closing = 1; | ||
1194 | if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
1195 | tty_wait_until_sent(tty, info->closing_wait); | ||
1196 | |||
1197 | /* | ||
1198 | * At this point we stop accepting input. To do this, we | ||
1199 | * disable the receive line status interrupts, and tell the | ||
1200 | * interrupt driver to stop checking the data ready bit in the | ||
1201 | * line status register. | ||
1202 | */ | ||
1203 | info->imr &= ~MCFUART_UIR_RXREADY; | ||
1204 | uartp = info->addr; | ||
1205 | uartp[MCFUART_UIMR] = info->imr; | ||
1206 | |||
1207 | #if 0 | ||
1208 | /* FIXME: do we need to keep this enabled for console?? */ | ||
1209 | if (mcfrs_console_inited && (mcfrs_console_port == info->line)) { | ||
1210 | /* Do not disable the UART */ ; | ||
1211 | } else | ||
1212 | #endif | ||
1213 | shutdown(info); | ||
1214 | mcfrs_flush_buffer(tty); | ||
1215 | tty_ldisc_flush(tty); | ||
1216 | |||
1217 | tty->closing = 0; | ||
1218 | info->event = 0; | ||
1219 | info->port.tty = NULL; | ||
1220 | #if 0 | ||
1221 | if (tty->ldisc.num != ldiscs[N_TTY].num) { | ||
1222 | if (tty->ldisc.close) | ||
1223 | (tty->ldisc.close)(tty); | ||
1224 | tty->ldisc = ldiscs[N_TTY]; | ||
1225 | tty->termios->c_line = N_TTY; | ||
1226 | if (tty->ldisc.open) | ||
1227 | (tty->ldisc.open)(tty); | ||
1228 | } | ||
1229 | #endif | ||
1230 | if (info->blocked_open) { | ||
1231 | if (info->close_delay) { | ||
1232 | msleep_interruptible(jiffies_to_msecs(info->close_delay)); | ||
1233 | } | ||
1234 | wake_up_interruptible(&info->open_wait); | ||
1235 | } | ||
1236 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | ||
1237 | wake_up_interruptible(&info->close_wait); | ||
1238 | local_irq_restore(flags); | ||
1239 | } | ||
1240 | |||
1241 | /* | ||
1242 | * mcfrs_wait_until_sent() --- wait until the transmitter is empty | ||
1243 | */ | ||
1244 | static void | ||
1245 | mcfrs_wait_until_sent(struct tty_struct *tty, int timeout) | ||
1246 | { | ||
1247 | #ifdef CONFIG_M5272 | ||
1248 | #define MCF5272_FIFO_SIZE 25 /* fifo size + shift reg */ | ||
1249 | |||
1250 | struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; | ||
1251 | volatile unsigned char *uartp; | ||
1252 | unsigned long orig_jiffies, fifo_time, char_time, fifo_cnt; | ||
1253 | |||
1254 | if (serial_paranoia_check(info, tty->name, "mcfrs_wait_until_sent")) | ||
1255 | return; | ||
1256 | |||
1257 | orig_jiffies = jiffies; | ||
1258 | |||
1259 | /* | ||
1260 | * Set the check interval to be 1/5 of the approximate time | ||
1261 | * to send the entire fifo, and make it at least 1. The check | ||
1262 | * interval should also be less than the timeout. | ||
1263 | * | ||
1264 | * Note: we have to use pretty tight timings here to satisfy | ||
1265 | * the NIST-PCTS. | ||
1266 | */ | ||
1267 | lock_kernel(); | ||
1268 | |||
1269 | fifo_time = (MCF5272_FIFO_SIZE * HZ * 10) / info->baud; | ||
1270 | char_time = fifo_time / 5; | ||
1271 | if (char_time == 0) | ||
1272 | char_time = 1; | ||
1273 | if (timeout && timeout < char_time) | ||
1274 | char_time = timeout; | ||
1275 | |||
1276 | /* | ||
1277 | * Clamp the timeout period at 2 * the time to empty the | ||
1278 | * fifo. Just to be safe, set the minimum at .5 seconds. | ||
1279 | */ | ||
1280 | fifo_time *= 2; | ||
1281 | if (fifo_time < (HZ/2)) | ||
1282 | fifo_time = HZ/2; | ||
1283 | if (!timeout || timeout > fifo_time) | ||
1284 | timeout = fifo_time; | ||
1285 | |||
1286 | /* | ||
1287 | * Account for the number of bytes in the UART | ||
1288 | * transmitter FIFO plus any byte being shifted out. | ||
1289 | */ | ||
1290 | uartp = (volatile unsigned char *) info->addr; | ||
1291 | for (;;) { | ||
1292 | fifo_cnt = (uartp[MCFUART_UTF] & MCFUART_UTF_TXB); | ||
1293 | if ((uartp[MCFUART_USR] & (MCFUART_USR_TXREADY| | ||
1294 | MCFUART_USR_TXEMPTY)) == | ||
1295 | MCFUART_USR_TXREADY) | ||
1296 | fifo_cnt++; | ||
1297 | if (fifo_cnt == 0) | ||
1298 | break; | ||
1299 | msleep_interruptible(jiffies_to_msecs(char_time)); | ||
1300 | if (signal_pending(current)) | ||
1301 | break; | ||
1302 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | ||
1303 | break; | ||
1304 | } | ||
1305 | unlock_kernel(); | ||
1306 | #else | ||
1307 | /* | ||
1308 | * For the other coldfire models, assume all data has been sent | ||
1309 | */ | ||
1310 | #endif | ||
1311 | } | ||
1312 | |||
1313 | /* | ||
1314 | * mcfrs_hangup() --- called by tty_hangup() when a hangup is signaled. | ||
1315 | */ | ||
1316 | void mcfrs_hangup(struct tty_struct *tty) | ||
1317 | { | ||
1318 | struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; | ||
1319 | |||
1320 | if (serial_paranoia_check(info, tty->name, "mcfrs_hangup")) | ||
1321 | return; | ||
1322 | |||
1323 | mcfrs_flush_buffer(tty); | ||
1324 | shutdown(info); | ||
1325 | info->event = 0; | ||
1326 | info->count = 0; | ||
1327 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
1328 | info->port.tty = NULL; | ||
1329 | wake_up_interruptible(&info->open_wait); | ||
1330 | } | ||
1331 | |||
1332 | /* | ||
1333 | * ------------------------------------------------------------ | ||
1334 | * mcfrs_open() and friends | ||
1335 | * ------------------------------------------------------------ | ||
1336 | */ | ||
1337 | static int block_til_ready(struct tty_struct *tty, struct file * filp, | ||
1338 | struct mcf_serial *info) | ||
1339 | { | ||
1340 | DECLARE_WAITQUEUE(wait, current); | ||
1341 | int retval; | ||
1342 | int do_clocal = 0; | ||
1343 | |||
1344 | /* | ||
1345 | * If the device is in the middle of being closed, then block | ||
1346 | * until it's done, and then try again. | ||
1347 | */ | ||
1348 | if (info->flags & ASYNC_CLOSING) { | ||
1349 | interruptible_sleep_on(&info->close_wait); | ||
1350 | #ifdef SERIAL_DO_RESTART | ||
1351 | if (info->flags & ASYNC_HUP_NOTIFY) | ||
1352 | return -EAGAIN; | ||
1353 | else | ||
1354 | return -ERESTARTSYS; | ||
1355 | #else | ||
1356 | return -EAGAIN; | ||
1357 | #endif | ||
1358 | } | ||
1359 | |||
1360 | /* | ||
1361 | * If non-blocking mode is set, or the port is not enabled, | ||
1362 | * then make the check up front and then exit. | ||
1363 | */ | ||
1364 | if ((filp->f_flags & O_NONBLOCK) || | ||
1365 | (tty->flags & (1 << TTY_IO_ERROR))) { | ||
1366 | info->flags |= ASYNC_NORMAL_ACTIVE; | ||
1367 | return 0; | ||
1368 | } | ||
1369 | |||
1370 | if (tty->termios->c_cflag & CLOCAL) | ||
1371 | do_clocal = 1; | ||
1372 | |||
1373 | /* | ||
1374 | * Block waiting for the carrier detect and the line to become | ||
1375 | * free (i.e., not in use by the callout). While we are in | ||
1376 | * this loop, info->count is dropped by one, so that | ||
1377 | * mcfrs_close() knows when to free things. We restore it upon | ||
1378 | * exit, either normal or abnormal. | ||
1379 | */ | ||
1380 | retval = 0; | ||
1381 | add_wait_queue(&info->open_wait, &wait); | ||
1382 | #ifdef SERIAL_DEBUG_OPEN | ||
1383 | printk("block_til_ready before block: ttyS%d, count = %d\n", | ||
1384 | info->line, info->count); | ||
1385 | #endif | ||
1386 | info->count--; | ||
1387 | info->blocked_open++; | ||
1388 | while (1) { | ||
1389 | local_irq_disable(); | ||
1390 | mcfrs_setsignals(info, 1, 1); | ||
1391 | local_irq_enable(); | ||
1392 | current->state = TASK_INTERRUPTIBLE; | ||
1393 | if (tty_hung_up_p(filp) || | ||
1394 | !(info->flags & ASYNC_INITIALIZED)) { | ||
1395 | #ifdef SERIAL_DO_RESTART | ||
1396 | if (info->flags & ASYNC_HUP_NOTIFY) | ||
1397 | retval = -EAGAIN; | ||
1398 | else | ||
1399 | retval = -ERESTARTSYS; | ||
1400 | #else | ||
1401 | retval = -EAGAIN; | ||
1402 | #endif | ||
1403 | break; | ||
1404 | } | ||
1405 | if (!(info->flags & ASYNC_CLOSING) && | ||
1406 | (do_clocal || (mcfrs_getsignals(info) & TIOCM_CD))) | ||
1407 | break; | ||
1408 | if (signal_pending(current)) { | ||
1409 | retval = -ERESTARTSYS; | ||
1410 | break; | ||
1411 | } | ||
1412 | #ifdef SERIAL_DEBUG_OPEN | ||
1413 | printk("block_til_ready blocking: ttyS%d, count = %d\n", | ||
1414 | info->line, info->count); | ||
1415 | #endif | ||
1416 | schedule(); | ||
1417 | } | ||
1418 | current->state = TASK_RUNNING; | ||
1419 | remove_wait_queue(&info->open_wait, &wait); | ||
1420 | if (!tty_hung_up_p(filp)) | ||
1421 | info->count++; | ||
1422 | info->blocked_open--; | ||
1423 | #ifdef SERIAL_DEBUG_OPEN | ||
1424 | printk("block_til_ready after blocking: ttyS%d, count = %d\n", | ||
1425 | info->line, info->count); | ||
1426 | #endif | ||
1427 | if (retval) | ||
1428 | return retval; | ||
1429 | info->flags |= ASYNC_NORMAL_ACTIVE; | ||
1430 | return 0; | ||
1431 | } | ||
1432 | |||
1433 | /* | ||
1434 | * This routine is called whenever a serial port is opened. It | ||
1435 | * enables interrupts for a serial port, linking in its structure into | ||
1436 | * the IRQ chain. It also performs the serial-specific | ||
1437 | * initialization for the tty structure. | ||
1438 | */ | ||
1439 | int mcfrs_open(struct tty_struct *tty, struct file * filp) | ||
1440 | { | ||
1441 | struct mcf_serial *info; | ||
1442 | int retval, line; | ||
1443 | |||
1444 | line = tty->index; | ||
1445 | if ((line < 0) || (line >= NR_PORTS)) | ||
1446 | return -ENODEV; | ||
1447 | info = mcfrs_table + line; | ||
1448 | if (serial_paranoia_check(info, tty->name, "mcfrs_open")) | ||
1449 | return -ENODEV; | ||
1450 | #ifdef SERIAL_DEBUG_OPEN | ||
1451 | printk("mcfrs_open %s, count = %d\n", tty->name, info->count); | ||
1452 | #endif | ||
1453 | info->count++; | ||
1454 | tty->driver_data = info; | ||
1455 | info->port.tty = tty; | ||
1456 | |||
1457 | /* | ||
1458 | * Start up serial port | ||
1459 | */ | ||
1460 | retval = startup(info); | ||
1461 | if (retval) | ||
1462 | return retval; | ||
1463 | |||
1464 | retval = block_til_ready(tty, filp, info); | ||
1465 | if (retval) { | ||
1466 | #ifdef SERIAL_DEBUG_OPEN | ||
1467 | printk("mcfrs_open returning after block_til_ready with %d\n", | ||
1468 | retval); | ||
1469 | #endif | ||
1470 | return retval; | ||
1471 | } | ||
1472 | |||
1473 | #ifdef SERIAL_DEBUG_OPEN | ||
1474 | printk("mcfrs_open %s successful...\n", tty->name); | ||
1475 | #endif | ||
1476 | return 0; | ||
1477 | } | ||
1478 | |||
1479 | /* | ||
1480 | * Based on the line number set up the internal interrupt stuff. | ||
1481 | */ | ||
1482 | static void mcfrs_irqinit(struct mcf_serial *info) | ||
1483 | { | ||
1484 | #if defined(CONFIG_M5272) | ||
1485 | volatile unsigned long *icrp; | ||
1486 | volatile unsigned long *portp; | ||
1487 | volatile unsigned char *uartp; | ||
1488 | |||
1489 | uartp = info->addr; | ||
1490 | icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR2); | ||
1491 | |||
1492 | switch (info->line) { | ||
1493 | case 0: | ||
1494 | *icrp = 0xe0000000; | ||
1495 | break; | ||
1496 | case 1: | ||
1497 | *icrp = 0x0e000000; | ||
1498 | break; | ||
1499 | default: | ||
1500 | printk("MCFRS: don't know how to handle UART %d interrupt?\n", | ||
1501 | info->line); | ||
1502 | return; | ||
1503 | } | ||
1504 | |||
1505 | /* Enable the output lines for the serial ports */ | ||
1506 | portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PBCNT); | ||
1507 | *portp = (*portp & ~0x000000ff) | 0x00000055; | ||
1508 | portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PDCNT); | ||
1509 | *portp = (*portp & ~0x000003fc) | 0x000002a8; | ||
1510 | #elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) | ||
1511 | volatile unsigned char *icrp, *uartp; | ||
1512 | volatile unsigned long *imrp; | ||
1513 | |||
1514 | uartp = info->addr; | ||
1515 | |||
1516 | icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 + | ||
1517 | MCFINTC_ICR0 + MCFINT_UART0 + info->line); | ||
1518 | *icrp = 0x30 + info->line; /* level 6, line based priority */ | ||
1519 | |||
1520 | imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + | ||
1521 | MCFINTC_IMRL); | ||
1522 | *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); | ||
1523 | #if defined(CONFIG_M527x) | ||
1524 | { | ||
1525 | /* | ||
1526 | * External Pin Mask Setting & Enable External Pin for Interface | ||
1527 | * mrcbis@aliceposta.it | ||
1528 | */ | ||
1529 | u16 *serpin_enable_mask; | ||
1530 | serpin_enable_mask = (u16 *) (MCF_IPSBAR + MCF_GPIO_PAR_UART); | ||
1531 | if (info->line == 0) | ||
1532 | *serpin_enable_mask |= UART0_ENABLE_MASK; | ||
1533 | else if (info->line == 1) | ||
1534 | *serpin_enable_mask |= UART1_ENABLE_MASK; | ||
1535 | else if (info->line == 2) | ||
1536 | *serpin_enable_mask |= UART2_ENABLE_MASK; | ||
1537 | } | ||
1538 | #endif | ||
1539 | #if defined(CONFIG_M528x) | ||
1540 | /* make sure PUAPAR is set for UART0 and UART1 */ | ||
1541 | if (info->line < 2) { | ||
1542 | volatile unsigned char *portp = (volatile unsigned char *) (MCF_MBAR + MCF5282_GPIO_PUAPAR); | ||
1543 | *portp |= (0x03 << (info->line * 2)); | ||
1544 | } | ||
1545 | #endif | ||
1546 | #elif defined(CONFIG_M520x) | ||
1547 | volatile unsigned char *icrp, *uartp; | ||
1548 | volatile unsigned long *imrp; | ||
1549 | |||
1550 | uartp = info->addr; | ||
1551 | |||
1552 | icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 + | ||
1553 | MCFINTC_ICR0 + MCFINT_UART0 + info->line); | ||
1554 | *icrp = 0x03; | ||
1555 | |||
1556 | imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + | ||
1557 | MCFINTC_IMRL); | ||
1558 | *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); | ||
1559 | if (info->line < 2) { | ||
1560 | unsigned short *uart_par; | ||
1561 | uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART); | ||
1562 | if (info->line == 0) | ||
1563 | *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD0 | ||
1564 | | MCF_GPIO_PAR_UART_PAR_URXD0; | ||
1565 | else if (info->line == 1) | ||
1566 | *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD1 | ||
1567 | | MCF_GPIO_PAR_UART_PAR_URXD1; | ||
1568 | } else if (info->line == 2) { | ||
1569 | unsigned char *feci2c_par; | ||
1570 | feci2c_par = (unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C); | ||
1571 | *feci2c_par &= ~0x0F; | ||
1572 | *feci2c_par |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 | ||
1573 | | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2; | ||
1574 | } | ||
1575 | #elif defined(CONFIG_M532x) | ||
1576 | volatile unsigned char *uartp; | ||
1577 | uartp = info->addr; | ||
1578 | switch (info->line) { | ||
1579 | case 0: | ||
1580 | MCF_INTC0_ICR26 = 0x3; | ||
1581 | MCF_INTC0_CIMR = 26; | ||
1582 | /* GPIO initialization */ | ||
1583 | MCF_GPIO_PAR_UART |= 0x000F; | ||
1584 | break; | ||
1585 | case 1: | ||
1586 | MCF_INTC0_ICR27 = 0x3; | ||
1587 | MCF_INTC0_CIMR = 27; | ||
1588 | /* GPIO initialization */ | ||
1589 | MCF_GPIO_PAR_UART |= 0x0FF0; | ||
1590 | break; | ||
1591 | case 2: | ||
1592 | MCF_INTC0_ICR28 = 0x3; | ||
1593 | MCF_INTC0_CIMR = 28; | ||
1594 | /* GPIOs also must be initalized, depends on board */ | ||
1595 | break; | ||
1596 | } | ||
1597 | #else | ||
1598 | volatile unsigned char *icrp, *uartp; | ||
1599 | |||
1600 | switch (info->line) { | ||
1601 | case 0: | ||
1602 | icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART1ICR); | ||
1603 | *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 | | ||
1604 | MCFSIM_ICR_PRI1; | ||
1605 | mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); | ||
1606 | break; | ||
1607 | case 1: | ||
1608 | icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART2ICR); | ||
1609 | *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 | | ||
1610 | MCFSIM_ICR_PRI2; | ||
1611 | mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); | ||
1612 | break; | ||
1613 | default: | ||
1614 | printk("MCFRS: don't know how to handle UART %d interrupt?\n", | ||
1615 | info->line); | ||
1616 | return; | ||
1617 | } | ||
1618 | |||
1619 | uartp = info->addr; | ||
1620 | uartp[MCFUART_UIVR] = info->irq; | ||
1621 | #endif | ||
1622 | |||
1623 | /* Clear mask, so no surprise interrupts. */ | ||
1624 | uartp[MCFUART_UIMR] = 0; | ||
1625 | |||
1626 | if (request_irq(info->irq, mcfrs_interrupt, IRQF_DISABLED, | ||
1627 | "ColdFire UART", NULL)) { | ||
1628 | printk("MCFRS: Unable to attach ColdFire UART %d interrupt " | ||
1629 | "vector=%d\n", info->line, info->irq); | ||
1630 | } | ||
1631 | |||
1632 | return; | ||
1633 | } | ||
1634 | |||
1635 | |||
1636 | char *mcfrs_drivername = "ColdFire internal UART serial driver version 1.00\n"; | ||
1637 | |||
1638 | |||
1639 | /* | ||
1640 | * Serial stats reporting... | ||
1641 | */ | ||
1642 | int mcfrs_readproc(char *page, char **start, off_t off, int count, | ||
1643 | int *eof, void *data) | ||
1644 | { | ||
1645 | struct mcf_serial *info; | ||
1646 | char str[20]; | ||
1647 | int len, sigs, i; | ||
1648 | |||
1649 | len = sprintf(page, mcfrs_drivername); | ||
1650 | for (i = 0; (i < NR_PORTS); i++) { | ||
1651 | info = &mcfrs_table[i]; | ||
1652 | len += sprintf((page + len), "%d: port:%x irq=%d baud:%d ", | ||
1653 | i, (unsigned int) info->addr, info->irq, info->baud); | ||
1654 | if (info->stats.rx || info->stats.tx) | ||
1655 | len += sprintf((page + len), "tx:%d rx:%d ", | ||
1656 | info->stats.tx, info->stats.rx); | ||
1657 | if (info->stats.rxframing) | ||
1658 | len += sprintf((page + len), "fe:%d ", | ||
1659 | info->stats.rxframing); | ||
1660 | if (info->stats.rxparity) | ||
1661 | len += sprintf((page + len), "pe:%d ", | ||
1662 | info->stats.rxparity); | ||
1663 | if (info->stats.rxbreak) | ||
1664 | len += sprintf((page + len), "brk:%d ", | ||
1665 | info->stats.rxbreak); | ||
1666 | if (info->stats.rxoverrun) | ||
1667 | len += sprintf((page + len), "oe:%d ", | ||
1668 | info->stats.rxoverrun); | ||
1669 | |||
1670 | str[0] = str[1] = 0; | ||
1671 | if ((sigs = mcfrs_getsignals(info))) { | ||
1672 | if (sigs & TIOCM_RTS) | ||
1673 | strcat(str, "|RTS"); | ||
1674 | if (sigs & TIOCM_CTS) | ||
1675 | strcat(str, "|CTS"); | ||
1676 | if (sigs & TIOCM_DTR) | ||
1677 | strcat(str, "|DTR"); | ||
1678 | if (sigs & TIOCM_CD) | ||
1679 | strcat(str, "|CD"); | ||
1680 | } | ||
1681 | |||
1682 | len += sprintf((page + len), "%s\n", &str[1]); | ||
1683 | } | ||
1684 | |||
1685 | return(len); | ||
1686 | } | ||
1687 | |||
1688 | |||
1689 | /* Finally, routines used to initialize the serial driver. */ | ||
1690 | |||
1691 | static void show_serial_version(void) | ||
1692 | { | ||
1693 | printk(mcfrs_drivername); | ||
1694 | } | ||
1695 | |||
1696 | static const struct tty_operations mcfrs_ops = { | ||
1697 | .open = mcfrs_open, | ||
1698 | .close = mcfrs_close, | ||
1699 | .write = mcfrs_write, | ||
1700 | .flush_chars = mcfrs_flush_chars, | ||
1701 | .write_room = mcfrs_write_room, | ||
1702 | .chars_in_buffer = mcfrs_chars_in_buffer, | ||
1703 | .flush_buffer = mcfrs_flush_buffer, | ||
1704 | .ioctl = mcfrs_ioctl, | ||
1705 | .throttle = mcfrs_throttle, | ||
1706 | .unthrottle = mcfrs_unthrottle, | ||
1707 | .set_termios = mcfrs_set_termios, | ||
1708 | .stop = mcfrs_stop, | ||
1709 | .start = mcfrs_start, | ||
1710 | .hangup = mcfrs_hangup, | ||
1711 | .read_proc = mcfrs_readproc, | ||
1712 | .wait_until_sent = mcfrs_wait_until_sent, | ||
1713 | .tiocmget = mcfrs_tiocmget, | ||
1714 | .tiocmset = mcfrs_tiocmset, | ||
1715 | }; | ||
1716 | |||
1717 | /* mcfrs_init inits the driver */ | ||
1718 | static int __init | ||
1719 | mcfrs_init(void) | ||
1720 | { | ||
1721 | struct mcf_serial *info; | ||
1722 | unsigned long flags; | ||
1723 | int i; | ||
1724 | |||
1725 | /* Setup base handler, and timer table. */ | ||
1726 | #ifdef MCFPP_DCD0 | ||
1727 | init_timer(&mcfrs_timer_struct); | ||
1728 | mcfrs_timer_struct.function = mcfrs_timer; | ||
1729 | mcfrs_timer_struct.data = 0; | ||
1730 | mcfrs_timer_struct.expires = jiffies + HZ/25; | ||
1731 | add_timer(&mcfrs_timer_struct); | ||
1732 | mcfrs_ppstatus = mcf_getppdata() & (MCFPP_DCD0 | MCFPP_DCD1); | ||
1733 | #endif | ||
1734 | mcfrs_serial_driver = alloc_tty_driver(NR_PORTS); | ||
1735 | if (!mcfrs_serial_driver) | ||
1736 | return -ENOMEM; | ||
1737 | |||
1738 | show_serial_version(); | ||
1739 | |||
1740 | /* Initialize the tty_driver structure */ | ||
1741 | mcfrs_serial_driver->owner = THIS_MODULE; | ||
1742 | mcfrs_serial_driver->name = "ttyS"; | ||
1743 | mcfrs_serial_driver->driver_name = "mcfserial"; | ||
1744 | mcfrs_serial_driver->major = TTY_MAJOR; | ||
1745 | mcfrs_serial_driver->minor_start = 64; | ||
1746 | mcfrs_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
1747 | mcfrs_serial_driver->subtype = SERIAL_TYPE_NORMAL; | ||
1748 | mcfrs_serial_driver->init_termios = tty_std_termios; | ||
1749 | |||
1750 | mcfrs_serial_driver->init_termios.c_cflag = | ||
1751 | mcfrs_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL; | ||
1752 | mcfrs_serial_driver->flags = TTY_DRIVER_REAL_RAW; | ||
1753 | |||
1754 | tty_set_operations(mcfrs_serial_driver, &mcfrs_ops); | ||
1755 | |||
1756 | if (tty_register_driver(mcfrs_serial_driver)) { | ||
1757 | printk("MCFRS: Couldn't register serial driver\n"); | ||
1758 | put_tty_driver(mcfrs_serial_driver); | ||
1759 | return(-EBUSY); | ||
1760 | } | ||
1761 | |||
1762 | local_irq_save(flags); | ||
1763 | |||
1764 | /* | ||
1765 | * Configure all the attached serial ports. | ||
1766 | */ | ||
1767 | for (i = 0, info = mcfrs_table; (i < NR_PORTS); i++, info++) { | ||
1768 | info->magic = SERIAL_MAGIC; | ||
1769 | info->line = i; | ||
1770 | info->port.tty = NULL; | ||
1771 | info->custom_divisor = 16; | ||
1772 | info->close_delay = 50; | ||
1773 | info->closing_wait = 3000; | ||
1774 | info->x_char = 0; | ||
1775 | info->event = 0; | ||
1776 | info->count = 0; | ||
1777 | info->blocked_open = 0; | ||
1778 | INIT_WORK(&info->tqueue, mcfrs_offintr); | ||
1779 | INIT_WORK(&info->tqueue_hangup, do_serial_hangup); | ||
1780 | init_waitqueue_head(&info->open_wait); | ||
1781 | init_waitqueue_head(&info->close_wait); | ||
1782 | |||
1783 | info->imr = 0; | ||
1784 | mcfrs_setsignals(info, 0, 0); | ||
1785 | mcfrs_irqinit(info); | ||
1786 | |||
1787 | printk("ttyS%d at 0x%04x (irq = %d)", info->line, | ||
1788 | (unsigned int) info->addr, info->irq); | ||
1789 | printk(" is a builtin ColdFire UART\n"); | ||
1790 | } | ||
1791 | |||
1792 | local_irq_restore(flags); | ||
1793 | return 0; | ||
1794 | } | ||
1795 | |||
1796 | module_init(mcfrs_init); | ||
1797 | |||
1798 | /****************************************************************************/ | ||
1799 | /* Serial Console */ | ||
1800 | /****************************************************************************/ | ||
1801 | |||
1802 | /* | ||
1803 | * Quick and dirty UART initialization, for console output. | ||
1804 | */ | ||
1805 | |||
1806 | void mcfrs_init_console(void) | ||
1807 | { | ||
1808 | volatile unsigned char *uartp; | ||
1809 | unsigned int clk; | ||
1810 | |||
1811 | /* | ||
1812 | * Reset UART, get it into known state... | ||
1813 | */ | ||
1814 | uartp = (volatile unsigned char *) (MCF_MBAR + | ||
1815 | (mcfrs_console_port ? MCFUART_BASE2 : MCFUART_BASE1)); | ||
1816 | |||
1817 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ | ||
1818 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ | ||
1819 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */ | ||
1820 | |||
1821 | /* | ||
1822 | * Set port for defined baud , 8 data bits, 1 stop bit, no parity. | ||
1823 | */ | ||
1824 | uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8; | ||
1825 | uartp[MCFUART_UMR] = MCFUART_MR2_STOP1; | ||
1826 | |||
1827 | #ifdef CONFIG_M5272 | ||
1828 | { | ||
1829 | /* | ||
1830 | * For the MCF5272, also compute the baudrate fraction. | ||
1831 | */ | ||
1832 | int fraction = MCF_BUSCLK - (clk * 32 * mcfrs_console_baud); | ||
1833 | fraction *= 16; | ||
1834 | fraction /= (32 * mcfrs_console_baud); | ||
1835 | uartp[MCFUART_UFPD] = (fraction & 0xf); /* set fraction */ | ||
1836 | clk = (MCF_BUSCLK / mcfrs_console_baud) / 32; | ||
1837 | } | ||
1838 | #else | ||
1839 | clk = ((MCF_BUSCLK / mcfrs_console_baud) + 16) / 32; /* set baud */ | ||
1840 | #endif | ||
1841 | |||
1842 | uartp[MCFUART_UBG1] = (clk & 0xff00) >> 8; /* set msb baud */ | ||
1843 | uartp[MCFUART_UBG2] = (clk & 0xff); /* set lsb baud */ | ||
1844 | uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER; | ||
1845 | uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; | ||
1846 | |||
1847 | mcfrs_console_inited++; | ||
1848 | return; | ||
1849 | } | ||
1850 | |||
1851 | |||
1852 | /* | ||
1853 | * Setup for console. Argument comes from the boot command line. | ||
1854 | */ | ||
1855 | |||
1856 | int mcfrs_console_setup(struct console *cp, char *arg) | ||
1857 | { | ||
1858 | int i, n = CONSOLE_BAUD_RATE; | ||
1859 | |||
1860 | if (!cp) | ||
1861 | return(-1); | ||
1862 | |||
1863 | if (!strncmp(cp->name, "ttyS", 4)) | ||
1864 | mcfrs_console_port = cp->index; | ||
1865 | else if (!strncmp(cp->name, "cua", 3)) | ||
1866 | mcfrs_console_port = cp->index; | ||
1867 | else | ||
1868 | return(-1); | ||
1869 | |||
1870 | if (arg) | ||
1871 | n = simple_strtoul(arg,NULL,0); | ||
1872 | for (i = 0; i < MCFRS_BAUD_TABLE_SIZE; i++) | ||
1873 | if (mcfrs_baud_table[i] == n) | ||
1874 | break; | ||
1875 | if (i < MCFRS_BAUD_TABLE_SIZE) { | ||
1876 | mcfrs_console_baud = n; | ||
1877 | mcfrs_console_cbaud = 0; | ||
1878 | if (i > 15) { | ||
1879 | mcfrs_console_cbaud |= CBAUDEX; | ||
1880 | i -= 15; | ||
1881 | } | ||
1882 | mcfrs_console_cbaud |= i; | ||
1883 | } | ||
1884 | mcfrs_init_console(); /* make sure baud rate changes */ | ||
1885 | return(0); | ||
1886 | } | ||
1887 | |||
1888 | |||
1889 | static struct tty_driver *mcfrs_console_device(struct console *c, int *index) | ||
1890 | { | ||
1891 | *index = c->index; | ||
1892 | return mcfrs_serial_driver; | ||
1893 | } | ||
1894 | |||
1895 | |||
1896 | /* | ||
1897 | * Output a single character, using UART polled mode. | ||
1898 | * This is used for console output. | ||
1899 | */ | ||
1900 | |||
1901 | int mcfrs_put_char(char ch) | ||
1902 | { | ||
1903 | volatile unsigned char *uartp; | ||
1904 | unsigned long flags; | ||
1905 | int i; | ||
1906 | |||
1907 | uartp = (volatile unsigned char *) (MCF_MBAR + | ||
1908 | (mcfrs_console_port ? MCFUART_BASE2 : MCFUART_BASE1)); | ||
1909 | |||
1910 | local_irq_save(flags); | ||
1911 | for (i = 0; (i < 0x10000); i++) { | ||
1912 | if (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) | ||
1913 | break; | ||
1914 | } | ||
1915 | if (i < 0x10000) { | ||
1916 | uartp[MCFUART_UTB] = ch; | ||
1917 | for (i = 0; (i < 0x10000); i++) | ||
1918 | if (uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY) | ||
1919 | break; | ||
1920 | } | ||
1921 | if (i >= 0x10000) | ||
1922 | mcfrs_init_console(); /* try and get it back */ | ||
1923 | local_irq_restore(flags); | ||
1924 | |||
1925 | return 1; | ||
1926 | } | ||
1927 | |||
1928 | |||
1929 | /* | ||
1930 | * rs_console_write is registered for printk output. | ||
1931 | */ | ||
1932 | |||
1933 | void mcfrs_console_write(struct console *cp, const char *p, unsigned len) | ||
1934 | { | ||
1935 | if (!mcfrs_console_inited) | ||
1936 | mcfrs_init_console(); | ||
1937 | while (len-- > 0) { | ||
1938 | if (*p == '\n') | ||
1939 | mcfrs_put_char('\r'); | ||
1940 | mcfrs_put_char(*p++); | ||
1941 | } | ||
1942 | } | ||
1943 | |||
1944 | /* | ||
1945 | * declare our consoles | ||
1946 | */ | ||
1947 | |||
1948 | struct console mcfrs_console = { | ||
1949 | .name = "ttyS", | ||
1950 | .write = mcfrs_console_write, | ||
1951 | .device = mcfrs_console_device, | ||
1952 | .setup = mcfrs_console_setup, | ||
1953 | .flags = CON_PRINTBUFFER, | ||
1954 | .index = -1, | ||
1955 | }; | ||
1956 | |||
1957 | static int __init mcfrs_console_init(void) | ||
1958 | { | ||
1959 | register_console(&mcfrs_console); | ||
1960 | return 0; | ||
1961 | } | ||
1962 | |||
1963 | console_initcall(mcfrs_console_init); | ||
1964 | |||
1965 | /****************************************************************************/ | ||
diff --git a/drivers/serial/mcfserial.h b/drivers/serial/mcfserial.h deleted file mode 100644 index 56420e2cb110..000000000000 --- a/drivers/serial/mcfserial.h +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | /* | ||
2 | * mcfserial.c -- serial driver for ColdFire internal UARTS. | ||
3 | * | ||
4 | * Copyright (c) 1999 Greg Ungerer <gerg@snapgear.com> | ||
5 | * Copyright (c) 2000-2001 Lineo, Inc. <www.lineo.com> | ||
6 | * Copyright (c) 2002 SnapGear Inc., <www.snapgear.com> | ||
7 | * | ||
8 | * Based on code from 68332serial.c which was: | ||
9 | * | ||
10 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | ||
11 | * Copyright (C) 1998 TSHG | ||
12 | * Copyright (c) 1999 Rt-Control Inc. <jeff@uclinux.org> | ||
13 | */ | ||
14 | #ifndef _MCF_SERIAL_H | ||
15 | #define _MCF_SERIAL_H | ||
16 | |||
17 | #include <linux/serial.h> | ||
18 | |||
19 | #ifdef __KERNEL__ | ||
20 | |||
21 | /* | ||
22 | * Define a local serial stats structure. | ||
23 | */ | ||
24 | |||
25 | struct mcf_stats { | ||
26 | unsigned int rx; | ||
27 | unsigned int tx; | ||
28 | unsigned int rxbreak; | ||
29 | unsigned int rxframing; | ||
30 | unsigned int rxparity; | ||
31 | unsigned int rxoverrun; | ||
32 | }; | ||
33 | |||
34 | |||
35 | /* | ||
36 | * This is our internal structure for each serial port's state. | ||
37 | * Each serial port has one of these structures associated with it. | ||
38 | */ | ||
39 | |||
40 | struct mcf_serial { | ||
41 | int magic; | ||
42 | volatile unsigned char *addr; /* UART memory address */ | ||
43 | int irq; | ||
44 | int flags; /* defined in tty.h */ | ||
45 | int type; /* UART type */ | ||
46 | struct tty_struct *tty; | ||
47 | unsigned char imr; /* Software imr register */ | ||
48 | unsigned int baud; | ||
49 | int sigs; | ||
50 | int custom_divisor; | ||
51 | int x_char; /* xon/xoff character */ | ||
52 | int baud_base; | ||
53 | int close_delay; | ||
54 | unsigned short closing_wait; | ||
55 | unsigned short closing_wait2; | ||
56 | unsigned long event; | ||
57 | int line; | ||
58 | int count; /* # of fd on device */ | ||
59 | int blocked_open; /* # of blocked opens */ | ||
60 | unsigned char *xmit_buf; | ||
61 | int xmit_head; | ||
62 | int xmit_tail; | ||
63 | int xmit_cnt; | ||
64 | struct mcf_stats stats; | ||
65 | struct work_struct tqueue; | ||
66 | struct work_struct tqueue_hangup; | ||
67 | wait_queue_head_t open_wait; | ||
68 | wait_queue_head_t close_wait; | ||
69 | |||
70 | }; | ||
71 | |||
72 | #endif /* __KERNEL__ */ | ||
73 | |||
74 | #endif /* _MCF_SERIAL_H */ | ||
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index f977c98cfa95..6bdf3362e3b1 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -2051,7 +2051,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) | |||
2051 | "transmitter\n", | 2051 | "transmitter\n", |
2052 | port->dev ? port->dev->bus_id : "", | 2052 | port->dev ? port->dev->bus_id : "", |
2053 | port->dev ? ": " : "", | 2053 | port->dev ? ": " : "", |
2054 | drv->dev_name, port->line); | 2054 | drv->dev_name, |
2055 | drv->tty_driver->name_base + port->line); | ||
2055 | 2056 | ||
2056 | ops->shutdown(port); | 2057 | ops->shutdown(port); |
2057 | } | 2058 | } |
@@ -2154,12 +2155,11 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) | |||
2154 | 2155 | ||
2155 | switch (port->iotype) { | 2156 | switch (port->iotype) { |
2156 | case UPIO_PORT: | 2157 | case UPIO_PORT: |
2157 | snprintf(address, sizeof(address), | 2158 | snprintf(address, sizeof(address), "I/O 0x%lx", port->iobase); |
2158 | "I/O 0x%x", port->iobase); | ||
2159 | break; | 2159 | break; |
2160 | case UPIO_HUB6: | 2160 | case UPIO_HUB6: |
2161 | snprintf(address, sizeof(address), | 2161 | snprintf(address, sizeof(address), |
2162 | "I/O 0x%x offset 0x%x", port->iobase, port->hub6); | 2162 | "I/O 0x%lx offset 0x%x", port->iobase, port->hub6); |
2163 | break; | 2163 | break; |
2164 | case UPIO_MEM: | 2164 | case UPIO_MEM: |
2165 | case UPIO_MEM32: | 2165 | case UPIO_MEM32: |
@@ -2177,7 +2177,9 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) | |||
2177 | printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n", | 2177 | printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n", |
2178 | port->dev ? port->dev->bus_id : "", | 2178 | port->dev ? port->dev->bus_id : "", |
2179 | port->dev ? ": " : "", | 2179 | port->dev ? ": " : "", |
2180 | drv->dev_name, port->line, address, port->irq, uart_type(port)); | 2180 | drv->dev_name, |
2181 | drv->tty_driver->name_base + port->line, | ||
2182 | address, port->irq, uart_type(port)); | ||
2181 | } | 2183 | } |
2182 | 2184 | ||
2183 | static void | 2185 | static void |
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 79ea98c66fa8..99fb7dc59c45 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -272,7 +272,7 @@ static void aircable_read(struct work_struct *work) | |||
272 | * 64 bytes, to ensure I do not get throttled. | 272 | * 64 bytes, to ensure I do not get throttled. |
273 | * Ask USB mailing list for better aproach. | 273 | * Ask USB mailing list for better aproach. |
274 | */ | 274 | */ |
275 | tty = port->port.tty; | 275 | tty = tty_port_tty_get(&port->port); |
276 | 276 | ||
277 | if (!tty) { | 277 | if (!tty) { |
278 | schedule_work(&priv->rx_work); | 278 | schedule_work(&priv->rx_work); |
@@ -283,12 +283,13 @@ static void aircable_read(struct work_struct *work) | |||
283 | count = min(64, serial_buf_data_avail(priv->rx_buf)); | 283 | count = min(64, serial_buf_data_avail(priv->rx_buf)); |
284 | 284 | ||
285 | if (count <= 0) | 285 | if (count <= 0) |
286 | return; /* We have finished sending everything. */ | 286 | goto out; /* We have finished sending everything. */ |
287 | 287 | ||
288 | tty_prepare_flip_string(tty, &data, count); | 288 | tty_prepare_flip_string(tty, &data, count); |
289 | if (!data) { | 289 | if (!data) { |
290 | err("%s- kzalloc(%d) failed.", __func__, count); | 290 | dev_err(&port->dev, "%s- kzalloc(%d) failed.", |
291 | return; | 291 | __func__, count); |
292 | goto out; | ||
292 | } | 293 | } |
293 | 294 | ||
294 | serial_buf_get(priv->rx_buf, data, count); | 295 | serial_buf_get(priv->rx_buf, data, count); |
@@ -297,7 +298,8 @@ static void aircable_read(struct work_struct *work) | |||
297 | 298 | ||
298 | if (serial_buf_data_avail(priv->rx_buf)) | 299 | if (serial_buf_data_avail(priv->rx_buf)) |
299 | schedule_work(&priv->rx_work); | 300 | schedule_work(&priv->rx_work); |
300 | 301 | out: | |
302 | tty_kref_put(tty); | ||
301 | return; | 303 | return; |
302 | } | 304 | } |
303 | /* End of private methods */ | 305 | /* End of private methods */ |
@@ -495,7 +497,7 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
495 | usb_serial_debug_data(debug, &port->dev, __func__, | 497 | usb_serial_debug_data(debug, &port->dev, __func__, |
496 | urb->actual_length, urb->transfer_buffer); | 498 | urb->actual_length, urb->transfer_buffer); |
497 | 499 | ||
498 | tty = port->port.tty; | 500 | tty = tty_port_tty_get(&port->port); |
499 | if (tty && urb->actual_length) { | 501 | if (tty && urb->actual_length) { |
500 | if (urb->actual_length <= 2) { | 502 | if (urb->actual_length <= 2) { |
501 | /* This is an incomplete package */ | 503 | /* This is an incomplete package */ |
@@ -527,6 +529,7 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
527 | } | 529 | } |
528 | aircable_read(&priv->rx_work); | 530 | aircable_read(&priv->rx_work); |
529 | } | 531 | } |
532 | tty_kref_put(tty); | ||
530 | 533 | ||
531 | /* Schedule the next read _if_ we are still open */ | 534 | /* Schedule the next read _if_ we are still open */ |
532 | if (port->port.count) { | 535 | if (port->port.count) { |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 2ebe06c3405a..1913bc7c5f0b 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -322,7 +322,7 @@ static void belkin_sa_read_int_callback(struct urb *urb) | |||
322 | * to look in to this before committing any code. | 322 | * to look in to this before committing any code. |
323 | */ | 323 | */ |
324 | if (priv->last_lsr & BELKIN_SA_LSR_ERR) { | 324 | if (priv->last_lsr & BELKIN_SA_LSR_ERR) { |
325 | tty = port->port.tty; | 325 | tty = tty_port_tty_get(&port->port); |
326 | /* Overrun Error */ | 326 | /* Overrun Error */ |
327 | if (priv->last_lsr & BELKIN_SA_LSR_OE) { | 327 | if (priv->last_lsr & BELKIN_SA_LSR_OE) { |
328 | } | 328 | } |
@@ -335,6 +335,7 @@ static void belkin_sa_read_int_callback(struct urb *urb) | |||
335 | /* Break Indicator */ | 335 | /* Break Indicator */ |
336 | if (priv->last_lsr & BELKIN_SA_LSR_BI) { | 336 | if (priv->last_lsr & BELKIN_SA_LSR_BI) { |
337 | } | 337 | } |
338 | tty_kref_put(tty); | ||
338 | } | 339 | } |
339 | #endif | 340 | #endif |
340 | spin_unlock_irqrestore(&priv->lock, flags); | 341 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index e980766bb84b..5b20de130e08 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -117,7 +117,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | port = serial->port[0]; | 119 | port = serial->port[0]; |
120 | port->port.tty = NULL; | 120 | tty_port_tty_set(&port->port, NULL); |
121 | 121 | ||
122 | info->port = port; | 122 | info->port = port; |
123 | 123 | ||
@@ -143,7 +143,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
143 | } | 143 | } |
144 | memset(&dummy, 0, sizeof(struct ktermios)); | 144 | memset(&dummy, 0, sizeof(struct ktermios)); |
145 | tty->termios = termios; | 145 | tty->termios = termios; |
146 | port->port.tty = tty; | 146 | tty_port_tty_set(&port->port, tty); |
147 | } | 147 | } |
148 | 148 | ||
149 | /* only call the device specific open if this | 149 | /* only call the device specific open if this |
@@ -163,7 +163,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
163 | tty_termios_encode_baud_rate(termios, baud, baud); | 163 | tty_termios_encode_baud_rate(termios, baud, baud); |
164 | serial->type->set_termios(tty, port, &dummy); | 164 | serial->type->set_termios(tty, port, &dummy); |
165 | 165 | ||
166 | port->port.tty = NULL; | 166 | tty_port_tty_set(&port->port, NULL); |
167 | kfree(termios); | 167 | kfree(termios); |
168 | kfree(tty); | 168 | kfree(tty); |
169 | } | 169 | } |
@@ -176,7 +176,7 @@ out: | |||
176 | return retval; | 176 | return retval; |
177 | free_termios: | 177 | free_termios: |
178 | kfree(termios); | 178 | kfree(termios); |
179 | port->port.tty = NULL; | 179 | tty_port_tty_set(&port->port, NULL); |
180 | free_tty: | 180 | free_tty: |
181 | kfree(tty); | 181 | kfree(tty); |
182 | reset_open_count: | 182 | reset_open_count: |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index b4d72351cb96..94ef36c4764b 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -384,7 +384,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb) | |||
384 | return; | 384 | return; |
385 | } | 385 | } |
386 | 386 | ||
387 | tty = port->port.tty; | 387 | tty = tty_port_tty_get(&port->port); |
388 | if (!tty) { | 388 | if (!tty) { |
389 | dbg("%s - ignoring since device not open\n", __func__); | 389 | dbg("%s - ignoring since device not open\n", __func__); |
390 | return; | 390 | return; |
@@ -394,6 +394,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb) | |||
394 | tty_insert_flip_string(tty, data, urb->actual_length); | 394 | tty_insert_flip_string(tty, data, urb->actual_length); |
395 | tty_flip_buffer_push(tty); | 395 | tty_flip_buffer_push(tty); |
396 | } | 396 | } |
397 | tty_kref_put(tty); | ||
397 | 398 | ||
398 | spin_lock(&priv->lock); | 399 | spin_lock(&priv->lock); |
399 | 400 | ||
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 22837a3f2f89..f3514a91f915 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1286,7 +1286,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1286 | } | 1286 | } |
1287 | spin_unlock_irqrestore(&priv->lock, flags); | 1287 | spin_unlock_irqrestore(&priv->lock, flags); |
1288 | 1288 | ||
1289 | tty = port->port.tty; | 1289 | tty = tty_port_tty_get(&port->port); |
1290 | if (!tty) { | 1290 | if (!tty) { |
1291 | dbg("%s - bad tty pointer - exiting", __func__); | 1291 | dbg("%s - bad tty pointer - exiting", __func__); |
1292 | return; | 1292 | return; |
@@ -1362,7 +1362,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1362 | data[i]); | 1362 | data[i]); |
1363 | tty_insert_flip_char(tty, data[i], tty_flag); | 1363 | tty_insert_flip_char(tty, data[i], tty_flag); |
1364 | } | 1364 | } |
1365 | tty_flip_buffer_push(port->port.tty); | 1365 | tty_flip_buffer_push(tty); |
1366 | } | 1366 | } |
1367 | 1367 | ||
1368 | spin_lock_irqsave(&priv->lock, flags); | 1368 | spin_lock_irqsave(&priv->lock, flags); |
@@ -1371,6 +1371,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1371 | spin_unlock_irqrestore(&priv->lock, flags); | 1371 | spin_unlock_irqrestore(&priv->lock, flags); |
1372 | 1372 | ||
1373 | continue_read: | 1373 | continue_read: |
1374 | tty_kref_put(tty); | ||
1374 | 1375 | ||
1375 | /* Continue trying to always read... unless the port has closed. */ | 1376 | /* Continue trying to always read... unless the port has closed. */ |
1376 | 1377 | ||
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 240aad1acaab..5756ac6d6c92 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -604,7 +604,9 @@ static void digi_wakeup_write_lock(struct work_struct *work) | |||
604 | 604 | ||
605 | static void digi_wakeup_write(struct usb_serial_port *port) | 605 | static void digi_wakeup_write(struct usb_serial_port *port) |
606 | { | 606 | { |
607 | tty_wakeup(port->port.tty); | 607 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
608 | tty_wakeup(tty); | ||
609 | tty_kref_put(tty); | ||
608 | } | 610 | } |
609 | 611 | ||
610 | 612 | ||
@@ -1668,7 +1670,7 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1668 | { | 1670 | { |
1669 | 1671 | ||
1670 | struct usb_serial_port *port = urb->context; | 1672 | struct usb_serial_port *port = urb->context; |
1671 | struct tty_struct *tty = port->port.tty; | 1673 | struct tty_struct *tty; |
1672 | struct digi_port *priv = usb_get_serial_port_data(port); | 1674 | struct digi_port *priv = usb_get_serial_port_data(port); |
1673 | int opcode = ((unsigned char *)urb->transfer_buffer)[0]; | 1675 | int opcode = ((unsigned char *)urb->transfer_buffer)[0]; |
1674 | int len = ((unsigned char *)urb->transfer_buffer)[1]; | 1676 | int len = ((unsigned char *)urb->transfer_buffer)[1]; |
@@ -1692,6 +1694,7 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1692 | return -1; | 1694 | return -1; |
1693 | } | 1695 | } |
1694 | 1696 | ||
1697 | tty = tty_port_tty_get(&port->port); | ||
1695 | spin_lock(&priv->dp_port_lock); | 1698 | spin_lock(&priv->dp_port_lock); |
1696 | 1699 | ||
1697 | /* check for throttle; if set, do not resubmit read urb */ | 1700 | /* check for throttle; if set, do not resubmit read urb */ |
@@ -1735,6 +1738,7 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1735 | } | 1738 | } |
1736 | } | 1739 | } |
1737 | spin_unlock(&priv->dp_port_lock); | 1740 | spin_unlock(&priv->dp_port_lock); |
1741 | tty_kref_put(tty); | ||
1738 | 1742 | ||
1739 | if (opcode == DIGI_CMD_RECEIVE_DISABLE) | 1743 | if (opcode == DIGI_CMD_RECEIVE_DISABLE) |
1740 | dbg("%s: got RECEIVE_DISABLE", __func__); | 1744 | dbg("%s: got RECEIVE_DISABLE", __func__); |
@@ -1760,6 +1764,7 @@ static int digi_read_oob_callback(struct urb *urb) | |||
1760 | 1764 | ||
1761 | struct usb_serial_port *port = urb->context; | 1765 | struct usb_serial_port *port = urb->context; |
1762 | struct usb_serial *serial = port->serial; | 1766 | struct usb_serial *serial = port->serial; |
1767 | struct tty_struct *tty; | ||
1763 | struct digi_port *priv = usb_get_serial_port_data(port); | 1768 | struct digi_port *priv = usb_get_serial_port_data(port); |
1764 | int opcode, line, status, val; | 1769 | int opcode, line, status, val; |
1765 | int i; | 1770 | int i; |
@@ -1787,10 +1792,11 @@ static int digi_read_oob_callback(struct urb *urb) | |||
1787 | if (priv == NULL) | 1792 | if (priv == NULL) |
1788 | return -1; | 1793 | return -1; |
1789 | 1794 | ||
1795 | tty = tty_port_tty_get(&port->port); | ||
1790 | rts = 0; | 1796 | rts = 0; |
1791 | if (port->port.count) | 1797 | if (port->port.count) |
1792 | rts = port->port.tty->termios->c_cflag & CRTSCTS; | 1798 | rts = tty->termios->c_cflag & CRTSCTS; |
1793 | 1799 | ||
1794 | if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { | 1800 | if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { |
1795 | spin_lock(&priv->dp_port_lock); | 1801 | spin_lock(&priv->dp_port_lock); |
1796 | /* convert from digi flags to termiox flags */ | 1802 | /* convert from digi flags to termiox flags */ |
@@ -1798,14 +1804,14 @@ static int digi_read_oob_callback(struct urb *urb) | |||
1798 | priv->dp_modem_signals |= TIOCM_CTS; | 1804 | priv->dp_modem_signals |= TIOCM_CTS; |
1799 | /* port must be open to use tty struct */ | 1805 | /* port must be open to use tty struct */ |
1800 | if (rts) { | 1806 | if (rts) { |
1801 | port->port.tty->hw_stopped = 0; | 1807 | tty->hw_stopped = 0; |
1802 | digi_wakeup_write(port); | 1808 | digi_wakeup_write(port); |
1803 | } | 1809 | } |
1804 | } else { | 1810 | } else { |
1805 | priv->dp_modem_signals &= ~TIOCM_CTS; | 1811 | priv->dp_modem_signals &= ~TIOCM_CTS; |
1806 | /* port must be open to use tty struct */ | 1812 | /* port must be open to use tty struct */ |
1807 | if (rts) | 1813 | if (rts) |
1808 | port->port.tty->hw_stopped = 1; | 1814 | tty->hw_stopped = 1; |
1809 | } | 1815 | } |
1810 | if (val & DIGI_READ_INPUT_SIGNALS_DSR) | 1816 | if (val & DIGI_READ_INPUT_SIGNALS_DSR) |
1811 | priv->dp_modem_signals |= TIOCM_DSR; | 1817 | priv->dp_modem_signals |= TIOCM_DSR; |
@@ -1830,6 +1836,7 @@ static int digi_read_oob_callback(struct urb *urb) | |||
1830 | } else if (opcode == DIGI_CMD_IFLUSH_FIFO) { | 1836 | } else if (opcode == DIGI_CMD_IFLUSH_FIFO) { |
1831 | wake_up_interruptible(&priv->dp_flush_wait); | 1837 | wake_up_interruptible(&priv->dp_flush_wait); |
1832 | } | 1838 | } |
1839 | tty_kref_put(tty); | ||
1833 | } | 1840 | } |
1834 | return 0; | 1841 | return 0; |
1835 | 1842 | ||
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index a6ab5b58d9ca..1072e847280f 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -33,9 +33,8 @@ | |||
33 | * Moved MOD_DEC_USE_COUNT to end of empeg_close(). | 33 | * Moved MOD_DEC_USE_COUNT to end of empeg_close(). |
34 | * | 34 | * |
35 | * (12/03/2000) gb | 35 | * (12/03/2000) gb |
36 | * Added port->port.tty->ldisc.set_termios(port->port.tty, NULL) to | 36 | * Added tty->ldisc.set_termios(port, tty, NULL) to empeg_open(). |
37 | * empeg_open(). This notifies the tty driver that the termios have | 37 | * This notifies the tty driver that the termios have changed. |
38 | * changed. | ||
39 | * | 38 | * |
40 | * (11/13/2000) gb | 39 | * (11/13/2000) gb |
41 | * Moved tty->low_latency = 1 from empeg_read_bulk_callback() to | 40 | * Moved tty->low_latency = 1 from empeg_read_bulk_callback() to |
@@ -354,7 +353,7 @@ static void empeg_read_bulk_callback(struct urb *urb) | |||
354 | 353 | ||
355 | usb_serial_debug_data(debug, &port->dev, __func__, | 354 | usb_serial_debug_data(debug, &port->dev, __func__, |
356 | urb->actual_length, data); | 355 | urb->actual_length, data); |
357 | tty = port->port.tty; | 356 | tty = tty_port_tty_get(&port->port); |
358 | 357 | ||
359 | if (urb->actual_length) { | 358 | if (urb->actual_length) { |
360 | tty_buffer_request_room(tty, urb->actual_length); | 359 | tty_buffer_request_room(tty, urb->actual_length); |
@@ -362,6 +361,7 @@ static void empeg_read_bulk_callback(struct urb *urb) | |||
362 | tty_flip_buffer_push(tty); | 361 | tty_flip_buffer_push(tty); |
363 | bytes_in += urb->actual_length; | 362 | bytes_in += urb->actual_length; |
364 | } | 363 | } |
364 | tty_kref_put(tty); | ||
365 | 365 | ||
366 | /* Continue trying to always read */ | 366 | /* Continue trying to always read */ |
367 | usb_fill_bulk_urb( | 367 | usb_fill_bulk_urb( |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 3dc93b542b30..c2ac129557aa 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -860,7 +860,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
860 | 860 | ||
861 | kfree(buf); | 861 | kfree(buf); |
862 | if (rv < 0) { | 862 | if (rv < 0) { |
863 | err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", | 863 | dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", |
864 | __func__, | 864 | __func__, |
865 | (set & TIOCM_DTR) ? "HIGH" : | 865 | (set & TIOCM_DTR) ? "HIGH" : |
866 | (clear & TIOCM_DTR) ? "LOW" : "unchanged", | 866 | (clear & TIOCM_DTR) ? "LOW" : "unchanged", |
@@ -1808,7 +1808,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) | |||
1808 | if (port->port.count <= 0) | 1808 | if (port->port.count <= 0) |
1809 | return; | 1809 | return; |
1810 | 1810 | ||
1811 | tty = port->port.tty; | 1811 | tty = tty_port_tty_get(&port->port); |
1812 | if (!tty) { | 1812 | if (!tty) { |
1813 | dbg("%s - bad tty pointer - exiting", __func__); | 1813 | dbg("%s - bad tty pointer - exiting", __func__); |
1814 | return; | 1814 | return; |
@@ -1817,7 +1817,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) | |||
1817 | priv = usb_get_serial_port_data(port); | 1817 | priv = usb_get_serial_port_data(port); |
1818 | if (!priv) { | 1818 | if (!priv) { |
1819 | dbg("%s - bad port private data pointer - exiting", __func__); | 1819 | dbg("%s - bad port private data pointer - exiting", __func__); |
1820 | return; | 1820 | goto out; |
1821 | } | 1821 | } |
1822 | 1822 | ||
1823 | if (urb != port->read_urb) | 1823 | if (urb != port->read_urb) |
@@ -1827,7 +1827,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) | |||
1827 | /* This will happen at close every time so it is a dbg not an | 1827 | /* This will happen at close every time so it is a dbg not an |
1828 | err */ | 1828 | err */ |
1829 | dbg("(this is ok on close) nonzero read bulk status received: %d", status); | 1829 | dbg("(this is ok on close) nonzero read bulk status received: %d", status); |
1830 | return; | 1830 | goto out; |
1831 | } | 1831 | } |
1832 | 1832 | ||
1833 | /* count data bytes, but not status bytes */ | 1833 | /* count data bytes, but not status bytes */ |
@@ -1838,7 +1838,8 @@ static void ftdi_read_bulk_callback(struct urb *urb) | |||
1838 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 1838 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
1839 | 1839 | ||
1840 | ftdi_process_read(&priv->rx_work.work); | 1840 | ftdi_process_read(&priv->rx_work.work); |
1841 | 1841 | out: | |
1842 | tty_kref_put(tty); | ||
1842 | } /* ftdi_read_bulk_callback */ | 1843 | } /* ftdi_read_bulk_callback */ |
1843 | 1844 | ||
1844 | 1845 | ||
@@ -1863,7 +1864,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
1863 | if (port->port.count <= 0) | 1864 | if (port->port.count <= 0) |
1864 | return; | 1865 | return; |
1865 | 1866 | ||
1866 | tty = port->port.tty; | 1867 | tty = tty_port_tty_get(&port->port); |
1867 | if (!tty) { | 1868 | if (!tty) { |
1868 | dbg("%s - bad tty pointer - exiting", __func__); | 1869 | dbg("%s - bad tty pointer - exiting", __func__); |
1869 | return; | 1870 | return; |
@@ -1872,13 +1873,13 @@ static void ftdi_process_read(struct work_struct *work) | |||
1872 | priv = usb_get_serial_port_data(port); | 1873 | priv = usb_get_serial_port_data(port); |
1873 | if (!priv) { | 1874 | if (!priv) { |
1874 | dbg("%s - bad port private data pointer - exiting", __func__); | 1875 | dbg("%s - bad port private data pointer - exiting", __func__); |
1875 | return; | 1876 | goto out; |
1876 | } | 1877 | } |
1877 | 1878 | ||
1878 | urb = port->read_urb; | 1879 | urb = port->read_urb; |
1879 | if (!urb) { | 1880 | if (!urb) { |
1880 | dbg("%s - bad read_urb pointer - exiting", __func__); | 1881 | dbg("%s - bad read_urb pointer - exiting", __func__); |
1881 | return; | 1882 | goto out; |
1882 | } | 1883 | } |
1883 | 1884 | ||
1884 | data = urb->transfer_buffer; | 1885 | data = urb->transfer_buffer; |
@@ -2020,7 +2021,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
2020 | schedule_delayed_work(&priv->rx_work, 1); | 2021 | schedule_delayed_work(&priv->rx_work, 1); |
2021 | else | 2022 | else |
2022 | dbg("%s - port is closed", __func__); | 2023 | dbg("%s - port is closed", __func__); |
2023 | return; | 2024 | goto out; |
2024 | } | 2025 | } |
2025 | 2026 | ||
2026 | /* urb is completely processed */ | 2027 | /* urb is completely processed */ |
@@ -2041,6 +2042,8 @@ static void ftdi_process_read(struct work_struct *work) | |||
2041 | err("%s - failed resubmitting read urb, error %d", | 2042 | err("%s - failed resubmitting read urb, error %d", |
2042 | __func__, result); | 2043 | __func__, result); |
2043 | } | 2044 | } |
2045 | out: | ||
2046 | tty_kref_put(tty); | ||
2044 | } /* ftdi_process_read */ | 2047 | } /* ftdi_process_read */ |
2045 | 2048 | ||
2046 | 2049 | ||
@@ -2256,7 +2259,7 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2256 | 0, 0, | 2259 | 0, 0, |
2257 | buf, 1, WDR_TIMEOUT); | 2260 | buf, 1, WDR_TIMEOUT); |
2258 | if (ret < 0) { | 2261 | if (ret < 0) { |
2259 | err("%s Could not get modem status of device - err: %d", __func__, | 2262 | dbg("%s Could not get modem status of device - err: %d", __func__, |
2260 | ret); | 2263 | ret); |
2261 | return ret; | 2264 | return ret; |
2262 | } | 2265 | } |
@@ -2275,7 +2278,7 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2275 | 0, priv->interface, | 2278 | 0, priv->interface, |
2276 | buf, 2, WDR_TIMEOUT); | 2279 | buf, 2, WDR_TIMEOUT); |
2277 | if (ret < 0) { | 2280 | if (ret < 0) { |
2278 | err("%s Could not get modem status of device - err: %d", __func__, | 2281 | dbg("%s Could not get modem status of device - err: %d", __func__, |
2279 | ret); | 2282 | ret); |
2280 | return ret; | 2283 | return ret; |
2281 | } | 2284 | } |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index d95382088075..2ad0569bcf19 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -276,7 +276,7 @@ static inline int isAbortTrfCmnd(const unsigned char *buf) | |||
276 | static void send_to_tty(struct usb_serial_port *port, | 276 | static void send_to_tty(struct usb_serial_port *port, |
277 | char *data, unsigned int actual_length) | 277 | char *data, unsigned int actual_length) |
278 | { | 278 | { |
279 | struct tty_struct *tty = port->port.tty; | 279 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
280 | 280 | ||
281 | if (tty && actual_length) { | 281 | if (tty && actual_length) { |
282 | 282 | ||
@@ -287,6 +287,7 @@ static void send_to_tty(struct usb_serial_port *port, | |||
287 | tty_insert_flip_string(tty, data, actual_length); | 287 | tty_insert_flip_string(tty, data, actual_length); |
288 | tty_flip_buffer_push(tty); | 288 | tty_flip_buffer_push(tty); |
289 | } | 289 | } |
290 | tty_kref_put(tty); | ||
290 | } | 291 | } |
291 | 292 | ||
292 | 293 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index fe84c88ec20c..814909f1ee63 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -330,7 +330,7 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | |||
330 | static void flush_and_resubmit_read_urb(struct usb_serial_port *port) | 330 | static void flush_and_resubmit_read_urb(struct usb_serial_port *port) |
331 | { | 331 | { |
332 | struct urb *urb = port->read_urb; | 332 | struct urb *urb = port->read_urb; |
333 | struct tty_struct *tty = port->port.tty; | 333 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
334 | int room; | 334 | int room; |
335 | 335 | ||
336 | /* Push data to tty */ | 336 | /* Push data to tty */ |
@@ -341,6 +341,7 @@ static void flush_and_resubmit_read_urb(struct usb_serial_port *port) | |||
341 | tty_flip_buffer_push(tty); | 341 | tty_flip_buffer_push(tty); |
342 | } | 342 | } |
343 | } | 343 | } |
344 | tty_kref_put(tty); | ||
344 | 345 | ||
345 | resubmit_read_urb(port, GFP_ATOMIC); | 346 | resubmit_read_urb(port, GFP_ATOMIC); |
346 | } | 347 | } |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index bfa508ddb0fe..611f97fd62f1 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -600,6 +600,7 @@ static void edge_interrupt_callback(struct urb *urb) | |||
600 | struct edgeport_serial *edge_serial = urb->context; | 600 | struct edgeport_serial *edge_serial = urb->context; |
601 | struct edgeport_port *edge_port; | 601 | struct edgeport_port *edge_port; |
602 | struct usb_serial_port *port; | 602 | struct usb_serial_port *port; |
603 | struct tty_struct *tty; | ||
603 | unsigned char *data = urb->transfer_buffer; | 604 | unsigned char *data = urb->transfer_buffer; |
604 | int length = urb->actual_length; | 605 | int length = urb->actual_length; |
605 | int bytes_avail; | 606 | int bytes_avail; |
@@ -675,9 +676,12 @@ static void edge_interrupt_callback(struct urb *urb) | |||
675 | 676 | ||
676 | /* tell the tty driver that something | 677 | /* tell the tty driver that something |
677 | has changed */ | 678 | has changed */ |
678 | if (edge_port->port->port.tty) | 679 | tty = tty_port_tty_get( |
679 | tty_wakeup(edge_port->port->port.tty); | 680 | &edge_port->port->port); |
680 | 681 | if (tty) { | |
682 | tty_wakeup(tty); | ||
683 | tty_kref_put(tty); | ||
684 | } | ||
681 | /* Since we have more credit, check | 685 | /* Since we have more credit, check |
682 | if more data can be sent */ | 686 | if more data can be sent */ |
683 | send_more_port_data(edge_serial, | 687 | send_more_port_data(edge_serial, |
@@ -778,13 +782,14 @@ static void edge_bulk_out_data_callback(struct urb *urb) | |||
778 | __func__, status); | 782 | __func__, status); |
779 | } | 783 | } |
780 | 784 | ||
781 | tty = edge_port->port->port.tty; | 785 | tty = tty_port_tty_get(&edge_port->port->port); |
782 | 786 | ||
783 | if (tty && edge_port->open) { | 787 | if (tty && edge_port->open) { |
784 | /* let the tty driver wakeup if it has a special | 788 | /* let the tty driver wakeup if it has a special |
785 | write_wakeup function */ | 789 | write_wakeup function */ |
786 | tty_wakeup(tty); | 790 | tty_wakeup(tty); |
787 | } | 791 | } |
792 | tty_kref_put(tty); | ||
788 | 793 | ||
789 | /* Release the Write URB */ | 794 | /* Release the Write URB */ |
790 | edge_port->write_in_progress = false; | 795 | edge_port->write_in_progress = false; |
@@ -826,11 +831,12 @@ static void edge_bulk_out_cmd_callback(struct urb *urb) | |||
826 | } | 831 | } |
827 | 832 | ||
828 | /* Get pointer to tty */ | 833 | /* Get pointer to tty */ |
829 | tty = edge_port->port->port.tty; | 834 | tty = tty_port_tty_get(&edge_port->port->port); |
830 | 835 | ||
831 | /* tell the tty driver that something has changed */ | 836 | /* tell the tty driver that something has changed */ |
832 | if (tty && edge_port->open) | 837 | if (tty && edge_port->open) |
833 | tty_wakeup(tty); | 838 | tty_wakeup(tty); |
839 | tty_kref_put(tty); | ||
834 | 840 | ||
835 | /* we have completed the command */ | 841 | /* we have completed the command */ |
836 | edge_port->commandPending = false; | 842 | edge_port->commandPending = false; |
@@ -1932,11 +1938,13 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, | |||
1932 | edge_serial->rxPort]; | 1938 | edge_serial->rxPort]; |
1933 | edge_port = usb_get_serial_port_data(port); | 1939 | edge_port = usb_get_serial_port_data(port); |
1934 | if (edge_port->open) { | 1940 | if (edge_port->open) { |
1935 | tty = edge_port->port->port.tty; | 1941 | tty = tty_port_tty_get( |
1942 | &edge_port->port->port); | ||
1936 | if (tty) { | 1943 | if (tty) { |
1937 | dbg("%s - Sending %d bytes to TTY for port %d", | 1944 | dbg("%s - Sending %d bytes to TTY for port %d", |
1938 | __func__, rxLen, edge_serial->rxPort); | 1945 | __func__, rxLen, edge_serial->rxPort); |
1939 | edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen); | 1946 | edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen); |
1947 | tty_kref_put(tty); | ||
1940 | } | 1948 | } |
1941 | edge_port->icount.rx += rxLen; | 1949 | edge_port->icount.rx += rxLen; |
1942 | } | 1950 | } |
@@ -1971,6 +1979,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, | |||
1971 | { | 1979 | { |
1972 | struct usb_serial_port *port; | 1980 | struct usb_serial_port *port; |
1973 | struct edgeport_port *edge_port; | 1981 | struct edgeport_port *edge_port; |
1982 | struct tty_struct *tty; | ||
1974 | __u8 code = edge_serial->rxStatusCode; | 1983 | __u8 code = edge_serial->rxStatusCode; |
1975 | 1984 | ||
1976 | /* switch the port pointer to the one being currently talked about */ | 1985 | /* switch the port pointer to the one being currently talked about */ |
@@ -2020,10 +2029,12 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, | |||
2020 | 2029 | ||
2021 | /* send the current line settings to the port so we are | 2030 | /* send the current line settings to the port so we are |
2022 | in sync with any further termios calls */ | 2031 | in sync with any further termios calls */ |
2023 | /* FIXME: locking on tty */ | 2032 | tty = tty_port_tty_get(&edge_port->port->port); |
2024 | if (edge_port->port->port.tty) | 2033 | if (tty) { |
2025 | change_port_settings(edge_port->port->port.tty, | 2034 | change_port_settings(tty, |
2026 | edge_port, edge_port->port->port.tty->termios); | 2035 | edge_port, tty->termios); |
2036 | tty_kref_put(tty); | ||
2037 | } | ||
2027 | 2038 | ||
2028 | /* we have completed the open */ | 2039 | /* we have completed the open */ |
2029 | edge_port->openPending = false; | 2040 | edge_port->openPending = false; |
@@ -2163,10 +2174,14 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, | |||
2163 | } | 2174 | } |
2164 | 2175 | ||
2165 | /* Place LSR data byte into Rx buffer */ | 2176 | /* Place LSR data byte into Rx buffer */ |
2166 | if (lsrData && edge_port->port->port.tty) | 2177 | if (lsrData) { |
2167 | edge_tty_recv(&edge_port->port->dev, | 2178 | struct tty_struct *tty = |
2168 | edge_port->port->port.tty, &data, 1); | 2179 | tty_port_tty_get(&edge_port->port->port); |
2169 | 2180 | if (tty) { | |
2181 | edge_tty_recv(&edge_port->port->dev, tty, &data, 1); | ||
2182 | tty_kref_put(tty); | ||
2183 | } | ||
2184 | } | ||
2170 | /* update input line counters */ | 2185 | /* update input line counters */ |
2171 | icount = &edge_port->icount; | 2186 | icount = &edge_port->icount; |
2172 | if (newLsr & LSR_BREAK) | 2187 | if (newLsr & LSR_BREAK) |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index cb4c54316cf5..541dd8e6e7a2 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -572,7 +572,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, | |||
572 | int flush) | 572 | int flush) |
573 | { | 573 | { |
574 | int baud_rate; | 574 | int baud_rate; |
575 | struct tty_struct *tty = port->port->port.tty; | 575 | struct tty_struct *tty = tty_port_tty_get(&port->port->port); |
576 | wait_queue_t wait; | 576 | wait_queue_t wait; |
577 | unsigned long flags; | 577 | unsigned long flags; |
578 | 578 | ||
@@ -599,6 +599,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, | |||
599 | if (flush) | 599 | if (flush) |
600 | edge_buf_clear(port->ep_out_buf); | 600 | edge_buf_clear(port->ep_out_buf); |
601 | spin_unlock_irqrestore(&port->ep_lock, flags); | 601 | spin_unlock_irqrestore(&port->ep_lock, flags); |
602 | tty_kref_put(tty); | ||
602 | 603 | ||
603 | /* wait for data to drain from the device */ | 604 | /* wait for data to drain from the device */ |
604 | timeout += jiffies; | 605 | timeout += jiffies; |
@@ -1554,7 +1555,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) | |||
1554 | /* Save the new modem status */ | 1555 | /* Save the new modem status */ |
1555 | edge_port->shadow_msr = msr & 0xf0; | 1556 | edge_port->shadow_msr = msr & 0xf0; |
1556 | 1557 | ||
1557 | tty = edge_port->port->port.tty; | 1558 | tty = tty_port_tty_get(&edge_port->port->port); |
1558 | /* handle CTS flow control */ | 1559 | /* handle CTS flow control */ |
1559 | if (tty && C_CRTSCTS(tty)) { | 1560 | if (tty && C_CRTSCTS(tty)) { |
1560 | if (msr & EDGEPORT_MSR_CTS) { | 1561 | if (msr & EDGEPORT_MSR_CTS) { |
@@ -1564,6 +1565,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) | |||
1564 | tty->hw_stopped = 1; | 1565 | tty->hw_stopped = 1; |
1565 | } | 1566 | } |
1566 | } | 1567 | } |
1568 | tty_kref_put(tty); | ||
1567 | 1569 | ||
1568 | return; | 1570 | return; |
1569 | } | 1571 | } |
@@ -1574,6 +1576,7 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, | |||
1574 | struct async_icount *icount; | 1576 | struct async_icount *icount; |
1575 | __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | | 1577 | __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | |
1576 | LSR_FRM_ERR | LSR_BREAK)); | 1578 | LSR_FRM_ERR | LSR_BREAK)); |
1579 | struct tty_struct *tty; | ||
1577 | 1580 | ||
1578 | dbg("%s - %02x", __func__, new_lsr); | 1581 | dbg("%s - %02x", __func__, new_lsr); |
1579 | 1582 | ||
@@ -1587,8 +1590,13 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, | |||
1587 | new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); | 1590 | new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); |
1588 | 1591 | ||
1589 | /* Place LSR data byte into Rx buffer */ | 1592 | /* Place LSR data byte into Rx buffer */ |
1590 | if (lsr_data && edge_port->port->port.tty) | 1593 | if (lsr_data) { |
1591 | edge_tty_recv(&edge_port->port->dev, edge_port->port->port.tty, &data, 1); | 1594 | tty = tty_port_tty_get(&edge_port->port->port); |
1595 | if (tty) { | ||
1596 | edge_tty_recv(&edge_port->port->dev, tty, &data, 1); | ||
1597 | tty_kref_put(tty); | ||
1598 | } | ||
1599 | } | ||
1592 | 1600 | ||
1593 | /* update input line counters */ | 1601 | /* update input line counters */ |
1594 | icount = &edge_port->icount; | 1602 | icount = &edge_port->icount; |
@@ -1749,7 +1757,7 @@ static void edge_bulk_in_callback(struct urb *urb) | |||
1749 | ++data; | 1757 | ++data; |
1750 | } | 1758 | } |
1751 | 1759 | ||
1752 | tty = edge_port->port->port.tty; | 1760 | tty = tty_port_tty_get(&edge_port->port->port); |
1753 | if (tty && urb->actual_length) { | 1761 | if (tty && urb->actual_length) { |
1754 | usb_serial_debug_data(debug, &edge_port->port->dev, | 1762 | usb_serial_debug_data(debug, &edge_port->port->dev, |
1755 | __func__, urb->actual_length, data); | 1763 | __func__, urb->actual_length, data); |
@@ -1761,6 +1769,7 @@ static void edge_bulk_in_callback(struct urb *urb) | |||
1761 | urb->actual_length); | 1769 | urb->actual_length); |
1762 | edge_port->icount.rx += urb->actual_length; | 1770 | edge_port->icount.rx += urb->actual_length; |
1763 | } | 1771 | } |
1772 | tty_kref_put(tty); | ||
1764 | 1773 | ||
1765 | exit: | 1774 | exit: |
1766 | /* continue read unless stopped */ | 1775 | /* continue read unless stopped */ |
@@ -1796,6 +1805,7 @@ static void edge_bulk_out_callback(struct urb *urb) | |||
1796 | struct usb_serial_port *port = urb->context; | 1805 | struct usb_serial_port *port = urb->context; |
1797 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 1806 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
1798 | int status = urb->status; | 1807 | int status = urb->status; |
1808 | struct tty_struct *tty; | ||
1799 | 1809 | ||
1800 | dbg("%s - port %d", __func__, port->number); | 1810 | dbg("%s - port %d", __func__, port->number); |
1801 | 1811 | ||
@@ -1818,7 +1828,9 @@ static void edge_bulk_out_callback(struct urb *urb) | |||
1818 | } | 1828 | } |
1819 | 1829 | ||
1820 | /* send any buffered data */ | 1830 | /* send any buffered data */ |
1821 | edge_send(port->port.tty); | 1831 | tty = tty_port_tty_get(&port->port); |
1832 | edge_send(tty); | ||
1833 | tty_kref_put(tty); | ||
1822 | } | 1834 | } |
1823 | 1835 | ||
1824 | static int edge_open(struct tty_struct *tty, | 1836 | static int edge_open(struct tty_struct *tty, |
@@ -1876,7 +1888,7 @@ static int edge_open(struct tty_struct *tty, | |||
1876 | 1888 | ||
1877 | /* set up the port settings */ | 1889 | /* set up the port settings */ |
1878 | if (tty) | 1890 | if (tty) |
1879 | edge_set_termios(tty, port, port->port.tty->termios); | 1891 | edge_set_termios(tty, port, tty->termios); |
1880 | 1892 | ||
1881 | /* open up the port */ | 1893 | /* open up the port */ |
1882 | 1894 | ||
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index cd9a2e138c8b..2affa9c118b2 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -764,13 +764,14 @@ static void ipaq_read_bulk_callback(struct urb *urb) | |||
764 | usb_serial_debug_data(debug, &port->dev, __func__, | 764 | usb_serial_debug_data(debug, &port->dev, __func__, |
765 | urb->actual_length, data); | 765 | urb->actual_length, data); |
766 | 766 | ||
767 | tty = port->port.tty; | 767 | tty = tty_port_tty_get(&port->port); |
768 | if (tty && urb->actual_length) { | 768 | if (tty && urb->actual_length) { |
769 | tty_buffer_request_room(tty, urb->actual_length); | 769 | tty_buffer_request_room(tty, urb->actual_length); |
770 | tty_insert_flip_string(tty, data, urb->actual_length); | 770 | tty_insert_flip_string(tty, data, urb->actual_length); |
771 | tty_flip_buffer_push(tty); | 771 | tty_flip_buffer_push(tty); |
772 | bytes_in += urb->actual_length; | 772 | bytes_in += urb->actual_length; |
773 | } | 773 | } |
774 | tty_kref_put(tty); | ||
774 | 775 | ||
775 | /* Continue trying to always read */ | 776 | /* Continue trying to always read */ |
776 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 777 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index a842025b9b57..480cac27d646 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -170,12 +170,13 @@ static void ipw_read_bulk_callback(struct urb *urb) | |||
170 | usb_serial_debug_data(debug, &port->dev, __func__, | 170 | usb_serial_debug_data(debug, &port->dev, __func__, |
171 | urb->actual_length, data); | 171 | urb->actual_length, data); |
172 | 172 | ||
173 | tty = port->port.tty; | 173 | tty = tty_port_tty_get(&port->port); |
174 | if (tty && urb->actual_length) { | 174 | if (tty && urb->actual_length) { |
175 | tty_buffer_request_room(tty, urb->actual_length); | 175 | tty_buffer_request_room(tty, urb->actual_length); |
176 | tty_insert_flip_string(tty, data, urb->actual_length); | 176 | tty_insert_flip_string(tty, data, urb->actual_length); |
177 | tty_flip_buffer_push(tty); | 177 | tty_flip_buffer_push(tty); |
178 | } | 178 | } |
179 | tty_kref_put(tty); | ||
179 | 180 | ||
180 | /* Continue trying to always read */ | 181 | /* Continue trying to always read */ |
181 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 182 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index e59155c6607d..45d4043e04ab 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -465,11 +465,12 @@ static void ir_read_bulk_callback(struct urb *urb) | |||
465 | ir_baud = *data & 0x0f; | 465 | ir_baud = *data & 0x0f; |
466 | usb_serial_debug_data(debug, &port->dev, __func__, | 466 | usb_serial_debug_data(debug, &port->dev, __func__, |
467 | urb->actual_length, data); | 467 | urb->actual_length, data); |
468 | tty = port->port.tty; | 468 | tty = tty_port_tty_get(&port->port); |
469 | if (tty_buffer_request_room(tty, urb->actual_length - 1)) { | 469 | if (tty_buffer_request_room(tty, urb->actual_length - 1)) { |
470 | tty_insert_flip_string(tty, data+1, urb->actual_length - 1); | 470 | tty_insert_flip_string(tty, data+1, urb->actual_length - 1); |
471 | tty_flip_buffer_push(tty); | 471 | tty_flip_buffer_push(tty); |
472 | } | 472 | } |
473 | tty_kref_put(tty); | ||
473 | 474 | ||
474 | /* | 475 | /* |
475 | * No break here. | 476 | * No break here. |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index ddff37fa6339..53710aa7eadd 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -629,13 +629,14 @@ static void read_buf_callback(struct urb *urb) | |||
629 | } | 629 | } |
630 | 630 | ||
631 | dbg("%s - %i chars to write", __func__, urb->actual_length); | 631 | dbg("%s - %i chars to write", __func__, urb->actual_length); |
632 | tty = port->port.tty; | 632 | tty = tty_port_tty_get(&port->port); |
633 | if (data == NULL) | 633 | if (data == NULL) |
634 | dbg("%s - data is NULL !!!", __func__); | 634 | dbg("%s - data is NULL !!!", __func__); |
635 | if (tty && urb->actual_length && data) { | 635 | if (tty && urb->actual_length && data) { |
636 | tty_insert_flip_string(tty, data, urb->actual_length); | 636 | tty_insert_flip_string(tty, data, urb->actual_length); |
637 | tty_flip_buffer_push(tty); | 637 | tty_flip_buffer_push(tty); |
638 | } | 638 | } |
639 | tty_kref_put(tty); | ||
639 | iuu_led_activity_on(urb); | 640 | iuu_led_activity_on(urb); |
640 | } | 641 | } |
641 | 642 | ||
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 704716f6f6d3..15447af48691 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -430,7 +430,7 @@ static void usa26_indat_callback(struct urb *urb) | |||
430 | } | 430 | } |
431 | 431 | ||
432 | port = urb->context; | 432 | port = urb->context; |
433 | tty = port->port.tty; | 433 | tty = tty_port_tty_get(&port->port); |
434 | if (tty && urb->actual_length) { | 434 | if (tty && urb->actual_length) { |
435 | /* 0x80 bit is error flag */ | 435 | /* 0x80 bit is error flag */ |
436 | if ((data[0] & 0x80) == 0) { | 436 | if ((data[0] & 0x80) == 0) { |
@@ -459,6 +459,7 @@ static void usa26_indat_callback(struct urb *urb) | |||
459 | } | 459 | } |
460 | tty_flip_buffer_push(tty); | 460 | tty_flip_buffer_push(tty); |
461 | } | 461 | } |
462 | tty_kref_put(tty); | ||
462 | 463 | ||
463 | /* Resubmit urb so we continue receiving */ | 464 | /* Resubmit urb so we continue receiving */ |
464 | urb->dev = port->serial->dev; | 465 | urb->dev = port->serial->dev; |
@@ -513,6 +514,7 @@ static void usa26_instat_callback(struct urb *urb) | |||
513 | struct usb_serial *serial; | 514 | struct usb_serial *serial; |
514 | struct usb_serial_port *port; | 515 | struct usb_serial_port *port; |
515 | struct keyspan_port_private *p_priv; | 516 | struct keyspan_port_private *p_priv; |
517 | struct tty_struct *tty; | ||
516 | int old_dcd_state, err; | 518 | int old_dcd_state, err; |
517 | int status = urb->status; | 519 | int status = urb->status; |
518 | 520 | ||
@@ -553,12 +555,11 @@ static void usa26_instat_callback(struct urb *urb) | |||
553 | p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); | 555 | p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); |
554 | p_priv->ri_state = ((msg->ri) ? 1 : 0); | 556 | p_priv->ri_state = ((msg->ri) ? 1 : 0); |
555 | 557 | ||
556 | if (port->port.tty && !C_CLOCAL(port->port.tty) | 558 | if (old_dcd_state != p_priv->dcd_state) { |
557 | && old_dcd_state != p_priv->dcd_state) { | 559 | tty = tty_port_tty_get(&port->port); |
558 | if (old_dcd_state) | 560 | if (tty && !C_CLOCAL(tty)) |
559 | tty_hangup(port->port.tty); | 561 | tty_hangup(tty); |
560 | /* else */ | 562 | tty_kref_put(tty); |
561 | /* wake_up_interruptible(&p_priv->open_wait); */ | ||
562 | } | 563 | } |
563 | 564 | ||
564 | /* Resubmit urb so we continue receiving */ | 565 | /* Resubmit urb so we continue receiving */ |
@@ -604,11 +605,12 @@ static void usa28_indat_callback(struct urb *urb) | |||
604 | p_priv = usb_get_serial_port_data(port); | 605 | p_priv = usb_get_serial_port_data(port); |
605 | data = urb->transfer_buffer; | 606 | data = urb->transfer_buffer; |
606 | 607 | ||
607 | tty = port->port.tty; | 608 | tty =tty_port_tty_get(&port->port); |
608 | if (urb->actual_length) { | 609 | if (tty && urb->actual_length) { |
609 | tty_insert_flip_string(tty, data, urb->actual_length); | 610 | tty_insert_flip_string(tty, data, urb->actual_length); |
610 | tty_flip_buffer_push(tty); | 611 | tty_flip_buffer_push(tty); |
611 | } | 612 | } |
613 | tty_kref_put(tty); | ||
612 | 614 | ||
613 | /* Resubmit urb so we continue receiving */ | 615 | /* Resubmit urb so we continue receiving */ |
614 | urb->dev = port->serial->dev; | 616 | urb->dev = port->serial->dev; |
@@ -652,6 +654,7 @@ static void usa28_instat_callback(struct urb *urb) | |||
652 | struct usb_serial *serial; | 654 | struct usb_serial *serial; |
653 | struct usb_serial_port *port; | 655 | struct usb_serial_port *port; |
654 | struct keyspan_port_private *p_priv; | 656 | struct keyspan_port_private *p_priv; |
657 | struct tty_struct *tty; | ||
655 | int old_dcd_state; | 658 | int old_dcd_state; |
656 | int status = urb->status; | 659 | int status = urb->status; |
657 | 660 | ||
@@ -689,12 +692,11 @@ static void usa28_instat_callback(struct urb *urb) | |||
689 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); | 692 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); |
690 | p_priv->ri_state = ((msg->ri) ? 1 : 0); | 693 | p_priv->ri_state = ((msg->ri) ? 1 : 0); |
691 | 694 | ||
692 | if (port->port.tty && !C_CLOCAL(port->port.tty) | 695 | if( old_dcd_state != p_priv->dcd_state && old_dcd_state) { |
693 | && old_dcd_state != p_priv->dcd_state) { | 696 | tty = tty_port_tty_get(&port->port); |
694 | if (old_dcd_state) | 697 | if (tty && !C_CLOCAL(tty)) |
695 | tty_hangup(port->port.tty); | 698 | tty_hangup(tty); |
696 | /* else */ | 699 | tty_kref_put(tty); |
697 | /* wake_up_interruptible(&p_priv->open_wait); */ | ||
698 | } | 700 | } |
699 | 701 | ||
700 | /* Resubmit urb so we continue receiving */ | 702 | /* Resubmit urb so we continue receiving */ |
@@ -785,12 +787,11 @@ static void usa49_instat_callback(struct urb *urb) | |||
785 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); | 787 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); |
786 | p_priv->ri_state = ((msg->ri) ? 1 : 0); | 788 | p_priv->ri_state = ((msg->ri) ? 1 : 0); |
787 | 789 | ||
788 | if (port->port.tty && !C_CLOCAL(port->port.tty) | 790 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { |
789 | && old_dcd_state != p_priv->dcd_state) { | 791 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
790 | if (old_dcd_state) | 792 | if (tty && !C_CLOCAL(tty)) |
791 | tty_hangup(port->port.tty); | 793 | tty_hangup(tty); |
792 | /* else */ | 794 | tty_kref_put(tty); |
793 | /* wake_up_interruptible(&p_priv->open_wait); */ | ||
794 | } | 795 | } |
795 | 796 | ||
796 | /* Resubmit urb so we continue receiving */ | 797 | /* Resubmit urb so we continue receiving */ |
@@ -827,7 +828,7 @@ static void usa49_indat_callback(struct urb *urb) | |||
827 | } | 828 | } |
828 | 829 | ||
829 | port = urb->context; | 830 | port = urb->context; |
830 | tty = port->port.tty; | 831 | tty = tty_port_tty_get(&port->port); |
831 | if (tty && urb->actual_length) { | 832 | if (tty && urb->actual_length) { |
832 | /* 0x80 bit is error flag */ | 833 | /* 0x80 bit is error flag */ |
833 | if ((data[0] & 0x80) == 0) { | 834 | if ((data[0] & 0x80) == 0) { |
@@ -850,6 +851,7 @@ static void usa49_indat_callback(struct urb *urb) | |||
850 | } | 851 | } |
851 | tty_flip_buffer_push(tty); | 852 | tty_flip_buffer_push(tty); |
852 | } | 853 | } |
854 | tty_kref_put(tty); | ||
853 | 855 | ||
854 | /* Resubmit urb so we continue receiving */ | 856 | /* Resubmit urb so we continue receiving */ |
855 | urb->dev = port->serial->dev; | 857 | urb->dev = port->serial->dev; |
@@ -893,7 +895,7 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
893 | return; | 895 | return; |
894 | } | 896 | } |
895 | port = serial->port[data[i++]]; | 897 | port = serial->port[data[i++]]; |
896 | tty = port->port.tty; | 898 | tty = tty_port_tty_get(&port->port); |
897 | len = data[i++]; | 899 | len = data[i++]; |
898 | 900 | ||
899 | /* 0x80 bit is error flag */ | 901 | /* 0x80 bit is error flag */ |
@@ -927,6 +929,7 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
927 | } | 929 | } |
928 | if (port->port.count) | 930 | if (port->port.count) |
929 | tty_flip_buffer_push(tty); | 931 | tty_flip_buffer_push(tty); |
932 | tty_kref_put(tty); | ||
930 | } | 933 | } |
931 | } | 934 | } |
932 | 935 | ||
@@ -967,8 +970,8 @@ static void usa90_indat_callback(struct urb *urb) | |||
967 | port = urb->context; | 970 | port = urb->context; |
968 | p_priv = usb_get_serial_port_data(port); | 971 | p_priv = usb_get_serial_port_data(port); |
969 | 972 | ||
970 | tty = port->port.tty; | ||
971 | if (urb->actual_length) { | 973 | if (urb->actual_length) { |
974 | tty = tty_port_tty_get(&port->port); | ||
972 | /* if current mode is DMA, looks like usa28 format | 975 | /* if current mode is DMA, looks like usa28 format |
973 | otherwise looks like usa26 data format */ | 976 | otherwise looks like usa26 data format */ |
974 | 977 | ||
@@ -1004,6 +1007,7 @@ static void usa90_indat_callback(struct urb *urb) | |||
1004 | } | 1007 | } |
1005 | } | 1008 | } |
1006 | tty_flip_buffer_push(tty); | 1009 | tty_flip_buffer_push(tty); |
1010 | tty_kref_put(tty); | ||
1007 | } | 1011 | } |
1008 | 1012 | ||
1009 | /* Resubmit urb so we continue receiving */ | 1013 | /* Resubmit urb so we continue receiving */ |
@@ -1025,6 +1029,7 @@ static void usa90_instat_callback(struct urb *urb) | |||
1025 | struct usb_serial *serial; | 1029 | struct usb_serial *serial; |
1026 | struct usb_serial_port *port; | 1030 | struct usb_serial_port *port; |
1027 | struct keyspan_port_private *p_priv; | 1031 | struct keyspan_port_private *p_priv; |
1032 | struct tty_struct *tty; | ||
1028 | int old_dcd_state, err; | 1033 | int old_dcd_state, err; |
1029 | int status = urb->status; | 1034 | int status = urb->status; |
1030 | 1035 | ||
@@ -1053,12 +1058,11 @@ static void usa90_instat_callback(struct urb *urb) | |||
1053 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); | 1058 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); |
1054 | p_priv->ri_state = ((msg->ri) ? 1 : 0); | 1059 | p_priv->ri_state = ((msg->ri) ? 1 : 0); |
1055 | 1060 | ||
1056 | if (port->port.tty && !C_CLOCAL(port->port.tty) | 1061 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { |
1057 | && old_dcd_state != p_priv->dcd_state) { | 1062 | tty = tty_port_tty_get(&port->port); |
1058 | if (old_dcd_state) | 1063 | if (tty && !C_CLOCAL(tty)) |
1059 | tty_hangup(port->port.tty); | 1064 | tty_hangup(tty); |
1060 | /* else */ | 1065 | tty_kref_put(tty); |
1061 | /* wake_up_interruptible(&p_priv->open_wait); */ | ||
1062 | } | 1066 | } |
1063 | 1067 | ||
1064 | /* Resubmit urb so we continue receiving */ | 1068 | /* Resubmit urb so we continue receiving */ |
@@ -1130,12 +1134,11 @@ static void usa67_instat_callback(struct urb *urb) | |||
1130 | p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); | 1134 | p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); |
1131 | p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); | 1135 | p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); |
1132 | 1136 | ||
1133 | if (port->port.tty && !C_CLOCAL(port->port.tty) | 1137 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { |
1134 | && old_dcd_state != p_priv->dcd_state) { | 1138 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
1135 | if (old_dcd_state) | 1139 | if (tty && !C_CLOCAL(tty)) |
1136 | tty_hangup(port->port.tty); | 1140 | tty_hangup(tty); |
1137 | /* else */ | 1141 | tty_kref_put(tty); |
1138 | /* wake_up_interruptible(&p_priv->open_wait); */ | ||
1139 | } | 1142 | } |
1140 | 1143 | ||
1141 | /* Resubmit urb so we continue receiving */ | 1144 | /* Resubmit urb so we continue receiving */ |
@@ -1332,7 +1335,7 @@ static void keyspan_close(struct tty_struct *tty, | |||
1332 | stop_urb(p_priv->out_urbs[i]); | 1335 | stop_urb(p_priv->out_urbs[i]); |
1333 | } | 1336 | } |
1334 | } | 1337 | } |
1335 | port->port.tty = NULL; | 1338 | tty_port_tty_set(&port->port, NULL); |
1336 | } | 1339 | } |
1337 | 1340 | ||
1338 | /* download the firmware to a pre-renumeration device */ | 1341 | /* download the firmware to a pre-renumeration device */ |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 040040a267d9..99e9a14c5bf6 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -172,8 +172,9 @@ static void keyspan_pda_wakeup_write(struct work_struct *work) | |||
172 | struct keyspan_pda_private *priv = | 172 | struct keyspan_pda_private *priv = |
173 | container_of(work, struct keyspan_pda_private, wakeup_work); | 173 | container_of(work, struct keyspan_pda_private, wakeup_work); |
174 | struct usb_serial_port *port = priv->port; | 174 | struct usb_serial_port *port = priv->port; |
175 | 175 | struct tty_struct *tty = tty_port_tty_get(&port->port); | |
176 | tty_wakeup(port->port.tty); | 176 | tty_wakeup(tty); |
177 | tty_kref_put(tty); | ||
177 | } | 178 | } |
178 | 179 | ||
179 | static void keyspan_pda_request_unthrottle(struct work_struct *work) | 180 | static void keyspan_pda_request_unthrottle(struct work_struct *work) |
@@ -205,7 +206,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work) | |||
205 | static void keyspan_pda_rx_interrupt(struct urb *urb) | 206 | static void keyspan_pda_rx_interrupt(struct urb *urb) |
206 | { | 207 | { |
207 | struct usb_serial_port *port = urb->context; | 208 | struct usb_serial_port *port = urb->context; |
208 | struct tty_struct *tty = port->port.tty; | 209 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
209 | unsigned char *data = urb->transfer_buffer; | 210 | unsigned char *data = urb->transfer_buffer; |
210 | int retval; | 211 | int retval; |
211 | int status = urb->status; | 212 | int status = urb->status; |
@@ -222,7 +223,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) | |||
222 | /* this urb is terminated, clean up */ | 223 | /* this urb is terminated, clean up */ |
223 | dbg("%s - urb shutting down with status: %d", | 224 | dbg("%s - urb shutting down with status: %d", |
224 | __func__, status); | 225 | __func__, status); |
225 | return; | 226 | goto out; |
226 | default: | 227 | default: |
227 | dbg("%s - nonzero urb status received: %d", | 228 | dbg("%s - nonzero urb status received: %d", |
228 | __func__, status); | 229 | __func__, status); |
@@ -261,8 +262,11 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) | |||
261 | exit: | 262 | exit: |
262 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 263 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
263 | if (retval) | 264 | if (retval) |
264 | err("%s - usb_submit_urb failed with result %d", | 265 | dev_err(&port->dev, |
265 | __func__, retval); | 266 | "%s - usb_submit_urb failed with result %d", |
267 | __func__, retval); | ||
268 | out: | ||
269 | tty_kref_put(tty); | ||
266 | } | 270 | } |
267 | 271 | ||
268 | 272 | ||
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index b84dddc71124..ff3a07f5102f 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -658,7 +658,7 @@ static void klsi_105_read_bulk_callback(struct urb *urb) | |||
658 | } else { | 658 | } else { |
659 | int bytes_sent = ((__u8 *) data)[0] + | 659 | int bytes_sent = ((__u8 *) data)[0] + |
660 | ((unsigned int) ((__u8 *) data)[1] << 8); | 660 | ((unsigned int) ((__u8 *) data)[1] << 8); |
661 | tty = port->port.tty; | 661 | tty = tty_port_tty_get(&port->port); |
662 | /* we should immediately resubmit the URB, before attempting | 662 | /* we should immediately resubmit the URB, before attempting |
663 | * to pass the data on to the tty layer. But that needs locking | 663 | * to pass the data on to the tty layer. But that needs locking |
664 | * against re-entry an then mixed-up data because of | 664 | * against re-entry an then mixed-up data because of |
@@ -679,6 +679,7 @@ static void klsi_105_read_bulk_callback(struct urb *urb) | |||
679 | tty_buffer_request_room(tty, bytes_sent); | 679 | tty_buffer_request_room(tty, bytes_sent); |
680 | tty_insert_flip_string(tty, data + 2, bytes_sent); | 680 | tty_insert_flip_string(tty, data + 2, bytes_sent); |
681 | tty_flip_buffer_push(tty); | 681 | tty_flip_buffer_push(tty); |
682 | tty_kref_put(tty); | ||
682 | 683 | ||
683 | /* again lockless, but debug info only */ | 684 | /* again lockless, but debug info only */ |
684 | priv->bytes_in += bytes_sent; | 685 | priv->bytes_in += bytes_sent; |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index deba28ec77e8..cfcf37c2b957 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -383,7 +383,7 @@ static void kobil_read_int_callback(struct urb *urb) | |||
383 | return; | 383 | return; |
384 | } | 384 | } |
385 | 385 | ||
386 | tty = port->port.tty; | 386 | tty = tty_port_tty_get(&port->port); |
387 | if (urb->actual_length) { | 387 | if (urb->actual_length) { |
388 | 388 | ||
389 | /* BEGIN DEBUG */ | 389 | /* BEGIN DEBUG */ |
@@ -405,6 +405,7 @@ static void kobil_read_int_callback(struct urb *urb) | |||
405 | tty_insert_flip_string(tty, data, urb->actual_length); | 405 | tty_insert_flip_string(tty, data, urb->actual_length); |
406 | tty_flip_buffer_push(tty); | 406 | tty_flip_buffer_push(tty); |
407 | } | 407 | } |
408 | tty_kref_put(tty); | ||
408 | /* someone sets the dev to 0 if the close method has been called */ | 409 | /* someone sets the dev to 0 if the close method has been called */ |
409 | port->interrupt_in_urb->dev = port->serial->dev; | 410 | port->interrupt_in_urb->dev = port->serial->dev; |
410 | 411 | ||
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 0ded8bd6ec85..9b2cef81cde0 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -563,10 +563,11 @@ static void mct_u232_read_int_callback(struct urb *urb) | |||
563 | * Work-a-round: handle the 'usual' bulk-in pipe here | 563 | * Work-a-round: handle the 'usual' bulk-in pipe here |
564 | */ | 564 | */ |
565 | if (urb->transfer_buffer_length > 2) { | 565 | if (urb->transfer_buffer_length > 2) { |
566 | tty = port->port.tty; | 566 | tty = tty_port_tty_get(&port->port); |
567 | if (urb->actual_length) { | 567 | if (urb->actual_length) { |
568 | tty_insert_flip_string(tty, data, urb->actual_length); | 568 | tty_insert_flip_string(tty, data, urb->actual_length); |
569 | tty_flip_buffer_push(tty); | 569 | tty_flip_buffer_push(tty); |
570 | tty_kref_put(tty); | ||
570 | } | 571 | } |
571 | goto exit; | 572 | goto exit; |
572 | } | 573 | } |
@@ -591,7 +592,7 @@ static void mct_u232_read_int_callback(struct urb *urb) | |||
591 | * to look in to this before committing any code. | 592 | * to look in to this before committing any code. |
592 | */ | 593 | */ |
593 | if (priv->last_lsr & MCT_U232_LSR_ERR) { | 594 | if (priv->last_lsr & MCT_U232_LSR_ERR) { |
594 | tty = port->port.tty; | 595 | tty = tty_port_tty_get(&port->port); |
595 | /* Overrun Error */ | 596 | /* Overrun Error */ |
596 | if (priv->last_lsr & MCT_U232_LSR_OE) { | 597 | if (priv->last_lsr & MCT_U232_LSR_OE) { |
597 | } | 598 | } |
@@ -604,6 +605,7 @@ static void mct_u232_read_int_callback(struct urb *urb) | |||
604 | /* Break Indicator */ | 605 | /* Break Indicator */ |
605 | if (priv->last_lsr & MCT_U232_LSR_BI) { | 606 | if (priv->last_lsr & MCT_U232_LSR_BI) { |
606 | } | 607 | } |
608 | tty_kref_put(tty); | ||
607 | } | 609 | } |
608 | #endif | 610 | #endif |
609 | spin_unlock_irqrestore(&priv->lock, flags); | 611 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 7c4917d77c0a..7b538caec37f 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -216,12 +216,13 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
216 | 216 | ||
217 | data = urb->transfer_buffer; | 217 | data = urb->transfer_buffer; |
218 | 218 | ||
219 | tty = port->port.tty; | 219 | tty = tty_port_tty_get(&port->port); |
220 | if (tty && urb->actual_length) { | 220 | if (tty && urb->actual_length) { |
221 | tty_buffer_request_room(tty, urb->actual_length); | 221 | tty_buffer_request_room(tty, urb->actual_length); |
222 | tty_insert_flip_string(tty, data, urb->actual_length); | 222 | tty_insert_flip_string(tty, data, urb->actual_length); |
223 | tty_flip_buffer_push(tty); | 223 | tty_flip_buffer_push(tty); |
224 | } | 224 | } |
225 | tty_kref_put(tty); | ||
225 | 226 | ||
226 | if (!port->read_urb) { | 227 | if (!port->read_urb) { |
227 | dbg("URB KILLED !!!"); | 228 | dbg("URB KILLED !!!"); |
@@ -262,10 +263,11 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) | |||
262 | 263 | ||
263 | dbg("Entering ........."); | 264 | dbg("Entering ........."); |
264 | 265 | ||
265 | tty = mos7720_port->port->port.tty; | 266 | tty = tty_port_tty_get(&mos7720_port->port->port); |
266 | 267 | ||
267 | if (tty && mos7720_port->open) | 268 | if (tty && mos7720_port->open) |
268 | tty_wakeup(tty); | 269 | tty_wakeup(tty); |
270 | tty_kref_put(tty); | ||
269 | } | 271 | } |
270 | 272 | ||
271 | /* | 273 | /* |
@@ -1267,29 +1269,6 @@ static int get_lsr_info(struct tty_struct *tty, | |||
1267 | return 0; | 1269 | return 0; |
1268 | } | 1270 | } |
1269 | 1271 | ||
1270 | /* | ||
1271 | * get_number_bytes_avail - get number of bytes available | ||
1272 | * | ||
1273 | * Purpose: Let user call ioctl to get the count of number of bytes available. | ||
1274 | */ | ||
1275 | static int get_number_bytes_avail(struct moschip_port *mos7720_port, | ||
1276 | unsigned int __user *value) | ||
1277 | { | ||
1278 | unsigned int result = 0; | ||
1279 | struct tty_struct *tty = mos7720_port->port->port.tty; | ||
1280 | |||
1281 | if (!tty) | ||
1282 | return -ENOIOCTLCMD; | ||
1283 | |||
1284 | result = tty->read_cnt; | ||
1285 | |||
1286 | dbg("%s(%d) = %d", __func__, mos7720_port->port->number, result); | ||
1287 | if (copy_to_user(value, &result, sizeof(int))) | ||
1288 | return -EFAULT; | ||
1289 | |||
1290 | return -ENOIOCTLCMD; | ||
1291 | } | ||
1292 | |||
1293 | static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, | 1272 | static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, |
1294 | unsigned int __user *value) | 1273 | unsigned int __user *value) |
1295 | { | 1274 | { |
@@ -1409,13 +1388,6 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file, | |||
1409 | dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); | 1388 | dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); |
1410 | 1389 | ||
1411 | switch (cmd) { | 1390 | switch (cmd) { |
1412 | case TIOCINQ: | ||
1413 | /* return number of bytes available */ | ||
1414 | dbg("%s (%d) TIOCINQ", __func__, port->number); | ||
1415 | return get_number_bytes_avail(mos7720_port, | ||
1416 | (unsigned int __user *)arg); | ||
1417 | break; | ||
1418 | |||
1419 | case TIOCSERGETLSR: | 1391 | case TIOCSERGETLSR: |
1420 | dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); | 1392 | dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); |
1421 | return get_lsr_info(tty, mos7720_port, | 1393 | return get_lsr_info(tty, mos7720_port, |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 09d82062b973..60543d79ef56 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -709,12 +709,13 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
709 | dbg("%s", "Entering ........... \n"); | 709 | dbg("%s", "Entering ........... \n"); |
710 | 710 | ||
711 | if (urb->actual_length) { | 711 | if (urb->actual_length) { |
712 | tty = mos7840_port->port->port.tty; | 712 | tty = tty_port_tty_get(&mos7840_port->port->port); |
713 | if (tty) { | 713 | if (tty) { |
714 | tty_buffer_request_room(tty, urb->actual_length); | 714 | tty_buffer_request_room(tty, urb->actual_length); |
715 | tty_insert_flip_string(tty, data, urb->actual_length); | 715 | tty_insert_flip_string(tty, data, urb->actual_length); |
716 | dbg(" %s \n", data); | 716 | dbg(" %s \n", data); |
717 | tty_flip_buffer_push(tty); | 717 | tty_flip_buffer_push(tty); |
718 | tty_kref_put(tty); | ||
718 | } | 719 | } |
719 | mos7840_port->icount.rx += urb->actual_length; | 720 | mos7840_port->icount.rx += urb->actual_length; |
720 | smp_wmb(); | 721 | smp_wmb(); |
@@ -773,10 +774,10 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) | |||
773 | 774 | ||
774 | dbg("%s \n", "Entering ........."); | 775 | dbg("%s \n", "Entering ........."); |
775 | 776 | ||
776 | tty = mos7840_port->port->port.tty; | 777 | tty = tty_port_tty_get(&mos7840_port->port->port); |
777 | |||
778 | if (tty && mos7840_port->open) | 778 | if (tty && mos7840_port->open) |
779 | tty_wakeup(tty); | 779 | tty_wakeup(tty); |
780 | tty_kref_put(tty); | ||
780 | 781 | ||
781 | } | 782 | } |
782 | 783 | ||
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index d6736531a0fa..bcdcbb822705 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -64,12 +64,13 @@ static void navman_read_int_callback(struct urb *urb) | |||
64 | usb_serial_debug_data(debug, &port->dev, __func__, | 64 | usb_serial_debug_data(debug, &port->dev, __func__, |
65 | urb->actual_length, data); | 65 | urb->actual_length, data); |
66 | 66 | ||
67 | tty = port->port.tty; | 67 | tty = tty_port_tty_get(&port->port); |
68 | if (tty && urb->actual_length) { | 68 | if (tty && urb->actual_length) { |
69 | tty_buffer_request_room(tty, urb->actual_length); | 69 | tty_buffer_request_room(tty, urb->actual_length); |
70 | tty_insert_flip_string(tty, data, urb->actual_length); | 70 | tty_insert_flip_string(tty, data, urb->actual_length); |
71 | tty_flip_buffer_push(tty); | 71 | tty_flip_buffer_push(tty); |
72 | } | 72 | } |
73 | tty_kref_put(tty); | ||
73 | 74 | ||
74 | exit: | 75 | exit: |
75 | result = usb_submit_urb(urb, GFP_ATOMIC); | 76 | result = usb_submit_urb(urb, GFP_ATOMIC); |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index ae8e227f3db2..c4d70b0f1e48 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -172,7 +172,7 @@ static int omninet_open(struct tty_struct *tty, | |||
172 | dbg("%s - port %d", __func__, port->number); | 172 | dbg("%s - port %d", __func__, port->number); |
173 | 173 | ||
174 | wport = serial->port[1]; | 174 | wport = serial->port[1]; |
175 | wport->port.tty = tty; /* FIXME */ | 175 | tty_port_tty_set(&wport->port, tty); |
176 | 176 | ||
177 | /* Start reading from the device */ | 177 | /* Start reading from the device */ |
178 | usb_fill_bulk_urb(port->read_urb, serial->dev, | 178 | usb_fill_bulk_urb(port->read_urb, serial->dev, |
@@ -229,9 +229,11 @@ static void omninet_read_bulk_callback(struct urb *urb) | |||
229 | } | 229 | } |
230 | 230 | ||
231 | if (urb->actual_length && header->oh_len) { | 231 | if (urb->actual_length && header->oh_len) { |
232 | tty_insert_flip_string(port->port.tty, | 232 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
233 | data + OMNINET_DATAOFFSET, header->oh_len); | 233 | tty_insert_flip_string(tty, data + OMNINET_DATAOFFSET, |
234 | tty_flip_buffer_push(port->port.tty); | 234 | header->oh_len); |
235 | tty_flip_buffer_push(tty); | ||
236 | tty_kref_put(tty); | ||
235 | } | 237 | } |
236 | 238 | ||
237 | /* Continue trying to always read */ | 239 | /* Continue trying to always read */ |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 73f8277f88f2..6b1727e751e3 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -571,14 +571,14 @@ static void option_indat_callback(struct urb *urb) | |||
571 | dbg("%s: nonzero status: %d on endpoint %02x.", | 571 | dbg("%s: nonzero status: %d on endpoint %02x.", |
572 | __func__, status, endpoint); | 572 | __func__, status, endpoint); |
573 | } else { | 573 | } else { |
574 | tty = port->port.tty; | 574 | tty = tty_port_tty_get(&port->port); |
575 | if (urb->actual_length) { | 575 | if (urb->actual_length) { |
576 | tty_buffer_request_room(tty, urb->actual_length); | 576 | tty_buffer_request_room(tty, urb->actual_length); |
577 | tty_insert_flip_string(tty, data, urb->actual_length); | 577 | tty_insert_flip_string(tty, data, urb->actual_length); |
578 | tty_flip_buffer_push(tty); | 578 | tty_flip_buffer_push(tty); |
579 | } else { | 579 | } else |
580 | dbg("%s: empty read urb received", __func__); | 580 | dbg("%s: empty read urb received", __func__); |
581 | } | 581 | tty_kref_put(tty); |
582 | 582 | ||
583 | /* Resubmit urb so we continue receiving */ | 583 | /* Resubmit urb so we continue receiving */ |
584 | if (port->port.count && status != -ESHUTDOWN) { | 584 | if (port->port.count && status != -ESHUTDOWN) { |
@@ -647,9 +647,13 @@ static void option_instat_callback(struct urb *urb) | |||
647 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); | 647 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); |
648 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); | 648 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); |
649 | 649 | ||
650 | if (port->port.tty && !C_CLOCAL(port->port.tty) && | 650 | if (old_dcd_state && !portdata->dcd_state) { |
651 | old_dcd_state && !portdata->dcd_state) | 651 | struct tty_struct *tty = |
652 | tty_hangup(port->port.tty); | 652 | tty_port_tty_get(&port->port); |
653 | if (tty && !C_CLOCAL(tty)) | ||
654 | tty_hangup(tty); | ||
655 | tty_kref_put(tty); | ||
656 | } | ||
653 | } else { | 657 | } else { |
654 | dbg("%s: type %x req %x", __func__, | 658 | dbg("%s: type %x req %x", __func__, |
655 | req_pkt->bRequestType, req_pkt->bRequest); | 659 | req_pkt->bRequestType, req_pkt->bRequest); |
@@ -793,7 +797,7 @@ static void option_close(struct tty_struct *tty, | |||
793 | for (i = 0; i < N_OUT_URB; i++) | 797 | for (i = 0; i < N_OUT_URB; i++) |
794 | usb_kill_urb(portdata->out_urbs[i]); | 798 | usb_kill_urb(portdata->out_urbs[i]); |
795 | } | 799 | } |
796 | port->port.tty = NULL; /* FIXME */ | 800 | tty_port_tty_set(&port->port, NULL); |
797 | } | 801 | } |
798 | 802 | ||
799 | /* Helper functions used by option_setup_urbs */ | 803 | /* Helper functions used by option_setup_urbs */ |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 81db5715ee25..ba551f00f16f 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -224,10 +224,6 @@ struct oti6858_private { | |||
224 | struct usb_serial_port *port; /* USB port with which associated */ | 224 | struct usb_serial_port *port; /* USB port with which associated */ |
225 | }; | 225 | }; |
226 | 226 | ||
227 | #undef dbg | ||
228 | /* #define dbg(format, arg...) printk(KERN_INFO "%s: " format "\n", __FILE__, ## arg) */ | ||
229 | #define dbg(format, arg...) printk(KERN_INFO "" format "\n", ## arg) | ||
230 | |||
231 | static void setup_line(struct work_struct *work) | 227 | static void setup_line(struct work_struct *work) |
232 | { | 228 | { |
233 | struct oti6858_private *priv = container_of(work, | 229 | struct oti6858_private *priv = container_of(work, |
@@ -1002,11 +998,12 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
1002 | return; | 998 | return; |
1003 | } | 999 | } |
1004 | 1000 | ||
1005 | tty = port->port.tty; | 1001 | tty = tty_port_tty_get(&port->port); |
1006 | if (tty != NULL && urb->actual_length > 0) { | 1002 | if (tty != NULL && urb->actual_length > 0) { |
1007 | tty_insert_flip_string(tty, data, urb->actual_length); | 1003 | tty_insert_flip_string(tty, data, urb->actual_length); |
1008 | tty_flip_buffer_push(tty); | 1004 | tty_flip_buffer_push(tty); |
1009 | } | 1005 | } |
1006 | tty_kref_put(tty); | ||
1010 | 1007 | ||
1011 | /* schedule the interrupt urb if we are still open */ | 1008 | /* schedule the interrupt urb if we are still open */ |
1012 | if (port->port.count != 0) { | 1009 | if (port->port.count != 0) { |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 1ede1441cb1b..908437847165 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -154,7 +154,6 @@ struct pl2303_private { | |||
154 | wait_queue_head_t delta_msr_wait; | 154 | wait_queue_head_t delta_msr_wait; |
155 | u8 line_control; | 155 | u8 line_control; |
156 | u8 line_status; | 156 | u8 line_status; |
157 | u8 termios_initialized; | ||
158 | enum pl2303_type type; | 157 | enum pl2303_type type; |
159 | }; | 158 | }; |
160 | 159 | ||
@@ -526,16 +525,6 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
526 | 525 | ||
527 | dbg("%s - port %d", __func__, port->number); | 526 | dbg("%s - port %d", __func__, port->number); |
528 | 527 | ||
529 | spin_lock_irqsave(&priv->lock, flags); | ||
530 | if (!priv->termios_initialized) { | ||
531 | *(tty->termios) = tty_std_termios; | ||
532 | tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
533 | tty->termios->c_ispeed = 9600; | ||
534 | tty->termios->c_ospeed = 9600; | ||
535 | priv->termios_initialized = 1; | ||
536 | } | ||
537 | spin_unlock_irqrestore(&priv->lock, flags); | ||
538 | |||
539 | /* The PL2303 is reported to lose bytes if you change | 528 | /* The PL2303 is reported to lose bytes if you change |
540 | serial settings even to the same values as before. Thus | 529 | serial settings even to the same values as before. Thus |
541 | we actually need to filter in this specific case */ | 530 | we actually need to filter in this specific case */ |
@@ -1057,7 +1046,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1057 | tty_flag = TTY_FRAME; | 1046 | tty_flag = TTY_FRAME; |
1058 | dbg("%s - tty_flag = %d", __func__, tty_flag); | 1047 | dbg("%s - tty_flag = %d", __func__, tty_flag); |
1059 | 1048 | ||
1060 | tty = port->port.tty; | 1049 | tty = tty_port_tty_get(&port->port); |
1061 | if (tty && urb->actual_length) { | 1050 | if (tty && urb->actual_length) { |
1062 | tty_buffer_request_room(tty, urb->actual_length + 1); | 1051 | tty_buffer_request_room(tty, urb->actual_length + 1); |
1063 | /* overrun is special, not associated with a char */ | 1052 | /* overrun is special, not associated with a char */ |
@@ -1067,7 +1056,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1067 | tty_insert_flip_char(tty, data[i], tty_flag); | 1056 | tty_insert_flip_char(tty, data[i], tty_flag); |
1068 | tty_flip_buffer_push(tty); | 1057 | tty_flip_buffer_push(tty); |
1069 | } | 1058 | } |
1070 | 1059 | tty_kref_put(tty); | |
1071 | /* Schedule the next read _if_ we are still open */ | 1060 | /* Schedule the next read _if_ we are still open */ |
1072 | if (port->port.count) { | 1061 | if (port->port.count) { |
1073 | urb->dev = port->serial->dev; | 1062 | urb->dev = port->serial->dev; |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index def52d07a4ea..72903ac9f5c0 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -217,6 +217,7 @@ static void safe_read_bulk_callback(struct urb *urb) | |||
217 | struct usb_serial_port *port = urb->context; | 217 | struct usb_serial_port *port = urb->context; |
218 | unsigned char *data = urb->transfer_buffer; | 218 | unsigned char *data = urb->transfer_buffer; |
219 | unsigned char length = urb->actual_length; | 219 | unsigned char length = urb->actual_length; |
220 | struct tty_struct *tty; | ||
220 | int result; | 221 | int result; |
221 | int status = urb->status; | 222 | int status = urb->status; |
222 | 223 | ||
@@ -242,6 +243,7 @@ static void safe_read_bulk_callback(struct urb *urb) | |||
242 | printk("\n"); | 243 | printk("\n"); |
243 | } | 244 | } |
244 | #endif | 245 | #endif |
246 | tty = tty_port_tty_get(&port->port); | ||
245 | if (safe) { | 247 | if (safe) { |
246 | __u16 fcs; | 248 | __u16 fcs; |
247 | fcs = fcs_compute10(data, length, CRC10_INITFCS); | 249 | fcs = fcs_compute10(data, length, CRC10_INITFCS); |
@@ -250,9 +252,9 @@ static void safe_read_bulk_callback(struct urb *urb) | |||
250 | if (actual_length <= (length - 2)) { | 252 | if (actual_length <= (length - 2)) { |
251 | info("%s - actual: %d", __func__, | 253 | info("%s - actual: %d", __func__, |
252 | actual_length); | 254 | actual_length); |
253 | tty_insert_flip_string(port->port.tty, | 255 | tty_insert_flip_string(tty, |
254 | data, actual_length); | 256 | data, actual_length); |
255 | tty_flip_buffer_push(port->port.tty); | 257 | tty_flip_buffer_push(tty); |
256 | } else { | 258 | } else { |
257 | err("%s - inconsistent lengths %d:%d", | 259 | err("%s - inconsistent lengths %d:%d", |
258 | __func__, actual_length, length); | 260 | __func__, actual_length, length); |
@@ -261,9 +263,10 @@ static void safe_read_bulk_callback(struct urb *urb) | |||
261 | err("%s - bad CRC %x", __func__, fcs); | 263 | err("%s - bad CRC %x", __func__, fcs); |
262 | } | 264 | } |
263 | } else { | 265 | } else { |
264 | tty_insert_flip_string(port->port.tty, data, length); | 266 | tty_insert_flip_string(tty, data, length); |
265 | tty_flip_buffer_push(port->port.tty); | 267 | tty_flip_buffer_push(tty); |
266 | } | 268 | } |
269 | tty_kref_put(tty); | ||
267 | 270 | ||
268 | /* Continue trying to always read */ | 271 | /* Continue trying to always read */ |
269 | usb_fill_bulk_urb(urb, port->serial->dev, | 272 | usb_fill_bulk_urb(urb, port->serial->dev, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index ea1a103c99be..8b9eaf383679 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -440,14 +440,14 @@ static void sierra_indat_callback(struct urb *urb) | |||
440 | dbg("%s: nonzero status: %d on endpoint %02x.", | 440 | dbg("%s: nonzero status: %d on endpoint %02x.", |
441 | __func__, status, endpoint); | 441 | __func__, status, endpoint); |
442 | } else { | 442 | } else { |
443 | tty = port->port.tty; | ||
444 | if (urb->actual_length) { | 443 | if (urb->actual_length) { |
444 | tty = tty_port_tty_get(&port->port); | ||
445 | tty_buffer_request_room(tty, urb->actual_length); | 445 | tty_buffer_request_room(tty, urb->actual_length); |
446 | tty_insert_flip_string(tty, data, urb->actual_length); | 446 | tty_insert_flip_string(tty, data, urb->actual_length); |
447 | tty_flip_buffer_push(tty); | 447 | tty_flip_buffer_push(tty); |
448 | } else { | 448 | tty_kref_put(tty); |
449 | } else | ||
449 | dbg("%s: empty read urb received", __func__); | 450 | dbg("%s: empty read urb received", __func__); |
450 | } | ||
451 | 451 | ||
452 | /* Resubmit urb so we continue receiving */ | 452 | /* Resubmit urb so we continue receiving */ |
453 | if (port->port.count && status != -ESHUTDOWN) { | 453 | if (port->port.count && status != -ESHUTDOWN) { |
@@ -485,6 +485,7 @@ static void sierra_instat_callback(struct urb *urb) | |||
485 | unsigned char signals = *((unsigned char *) | 485 | unsigned char signals = *((unsigned char *) |
486 | urb->transfer_buffer + | 486 | urb->transfer_buffer + |
487 | sizeof(struct usb_ctrlrequest)); | 487 | sizeof(struct usb_ctrlrequest)); |
488 | struct tty_struct *tty; | ||
488 | 489 | ||
489 | dbg("%s: signal x%x", __func__, signals); | 490 | dbg("%s: signal x%x", __func__, signals); |
490 | 491 | ||
@@ -494,9 +495,11 @@ static void sierra_instat_callback(struct urb *urb) | |||
494 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); | 495 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); |
495 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); | 496 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); |
496 | 497 | ||
497 | if (port->port.tty && !C_CLOCAL(port->port.tty) && | 498 | tty = tty_port_tty_get(&port->port); |
499 | if (tty && !C_CLOCAL(tty) && | ||
498 | old_dcd_state && !portdata->dcd_state) | 500 | old_dcd_state && !portdata->dcd_state) |
499 | tty_hangup(port->port.tty); | 501 | tty_hangup(tty); |
502 | tty_kref_put(tty); | ||
500 | } else { | 503 | } else { |
501 | dbg("%s: type %x req %x", __func__, | 504 | dbg("%s: type %x req %x", __func__, |
502 | req_pkt->bRequestType, req_pkt->bRequest); | 505 | req_pkt->bRequestType, req_pkt->bRequest); |
@@ -616,8 +619,7 @@ static void sierra_close(struct tty_struct *tty, | |||
616 | } | 619 | } |
617 | 620 | ||
618 | usb_kill_urb(port->interrupt_in_urb); | 621 | usb_kill_urb(port->interrupt_in_urb); |
619 | 622 | tty_port_tty_set(&port->port, NULL); | |
620 | port->port.tty = NULL; /* FIXME */ | ||
621 | } | 623 | } |
622 | 624 | ||
623 | static int sierra_startup(struct usb_serial *serial) | 625 | static int sierra_startup(struct usb_serial *serial) |
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 283cf6b36b2c..1533d6e12238 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
@@ -755,7 +755,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb) | |||
755 | tty_flag = TTY_FRAME; | 755 | tty_flag = TTY_FRAME; |
756 | dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); | 756 | dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); |
757 | 757 | ||
758 | tty = port->port.tty; | 758 | tty = tty_port_tty_get(&port->port); |
759 | if (tty && urb->actual_length) { | 759 | if (tty && urb->actual_length) { |
760 | tty_buffer_request_room(tty, urb->actual_length + 1); | 760 | tty_buffer_request_room(tty, urb->actual_length + 1); |
761 | /* overrun is special, not associated with a char */ | 761 | /* overrun is special, not associated with a char */ |
@@ -765,6 +765,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb) | |||
765 | tty_insert_flip_char(tty, data[i], tty_flag); | 765 | tty_insert_flip_char(tty, data[i], tty_flag); |
766 | tty_flip_buffer_push(tty); | 766 | tty_flip_buffer_push(tty); |
767 | } | 767 | } |
768 | tty_kref_put(tty); | ||
768 | 769 | ||
769 | /* Schedule the next read _if_ we are still open */ | 770 | /* Schedule the next read _if_ we are still open */ |
770 | if (port->port.count) { | 771 | if (port->port.count) { |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 9a3e495c769c..c90237d48b0e 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -179,7 +179,7 @@ static int ti_set_mcr(struct ti_port *tport, unsigned int mcr); | |||
179 | static int ti_get_lsr(struct ti_port *tport); | 179 | static int ti_get_lsr(struct ti_port *tport); |
180 | static int ti_get_serial_info(struct ti_port *tport, | 180 | static int ti_get_serial_info(struct ti_port *tport, |
181 | struct serial_struct __user *ret_arg); | 181 | struct serial_struct __user *ret_arg); |
182 | static int ti_set_serial_info(struct ti_port *tport, | 182 | static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, |
183 | struct serial_struct __user *new_arg); | 183 | struct serial_struct __user *new_arg); |
184 | static void ti_handle_new_msr(struct ti_port *tport, __u8 msr); | 184 | static void ti_handle_new_msr(struct ti_port *tport, __u8 msr); |
185 | 185 | ||
@@ -857,8 +857,8 @@ static int ti_ioctl(struct tty_struct *tty, struct file *file, | |||
857 | (struct serial_struct __user *)arg); | 857 | (struct serial_struct __user *)arg); |
858 | case TIOCSSERIAL: | 858 | case TIOCSSERIAL: |
859 | dbg("%s - (%d) TIOCSSERIAL", __func__, port->number); | 859 | dbg("%s - (%d) TIOCSSERIAL", __func__, port->number); |
860 | return ti_set_serial_info(tport, | 860 | return ti_set_serial_info(tty, tport, |
861 | (struct serial_struct __user *)arg); | 861 | (struct serial_struct __user *)arg); |
862 | case TIOCMIWAIT: | 862 | case TIOCMIWAIT: |
863 | dbg("%s - (%d) TIOCMIWAIT", __func__, port->number); | 863 | dbg("%s - (%d) TIOCMIWAIT", __func__, port->number); |
864 | cprev = tport->tp_icount; | 864 | cprev = tport->tp_icount; |
@@ -1211,6 +1211,7 @@ static void ti_bulk_in_callback(struct urb *urb) | |||
1211 | struct device *dev = &urb->dev->dev; | 1211 | struct device *dev = &urb->dev->dev; |
1212 | int status = urb->status; | 1212 | int status = urb->status; |
1213 | int retval = 0; | 1213 | int retval = 0; |
1214 | struct tty_struct *tty; | ||
1214 | 1215 | ||
1215 | dbg("%s", __func__); | 1216 | dbg("%s", __func__); |
1216 | 1217 | ||
@@ -1239,20 +1240,22 @@ static void ti_bulk_in_callback(struct urb *urb) | |||
1239 | return; | 1240 | return; |
1240 | } | 1241 | } |
1241 | 1242 | ||
1242 | if (port->port.tty && urb->actual_length) { | 1243 | tty = tty_port_tty_get(&port->port); |
1244 | if (tty && urb->actual_length) { | ||
1243 | usb_serial_debug_data(debug, dev, __func__, | 1245 | usb_serial_debug_data(debug, dev, __func__, |
1244 | urb->actual_length, urb->transfer_buffer); | 1246 | urb->actual_length, urb->transfer_buffer); |
1245 | 1247 | ||
1246 | if (!tport->tp_is_open) | 1248 | if (!tport->tp_is_open) |
1247 | dbg("%s - port closed, dropping data", __func__); | 1249 | dbg("%s - port closed, dropping data", __func__); |
1248 | else | 1250 | else |
1249 | ti_recv(&urb->dev->dev, port->port.tty, | 1251 | ti_recv(&urb->dev->dev, tty, |
1250 | urb->transfer_buffer, | 1252 | urb->transfer_buffer, |
1251 | urb->actual_length); | 1253 | urb->actual_length); |
1252 | 1254 | ||
1253 | spin_lock(&tport->tp_lock); | 1255 | spin_lock(&tport->tp_lock); |
1254 | tport->tp_icount.rx += urb->actual_length; | 1256 | tport->tp_icount.rx += urb->actual_length; |
1255 | spin_unlock(&tport->tp_lock); | 1257 | spin_unlock(&tport->tp_lock); |
1258 | tty_kref_put(tty); | ||
1256 | } | 1259 | } |
1257 | 1260 | ||
1258 | exit: | 1261 | exit: |
@@ -1330,7 +1333,7 @@ static void ti_send(struct ti_port *tport) | |||
1330 | { | 1333 | { |
1331 | int count, result; | 1334 | int count, result; |
1332 | struct usb_serial_port *port = tport->tp_port; | 1335 | struct usb_serial_port *port = tport->tp_port; |
1333 | struct tty_struct *tty = port->port.tty; /* FIXME */ | 1336 | struct tty_struct *tty = tty_port_tty_get(&port->port); /* FIXME */ |
1334 | unsigned long flags; | 1337 | unsigned long flags; |
1335 | 1338 | ||
1336 | 1339 | ||
@@ -1338,19 +1341,15 @@ static void ti_send(struct ti_port *tport) | |||
1338 | 1341 | ||
1339 | spin_lock_irqsave(&tport->tp_lock, flags); | 1342 | spin_lock_irqsave(&tport->tp_lock, flags); |
1340 | 1343 | ||
1341 | if (tport->tp_write_urb_in_use) { | 1344 | if (tport->tp_write_urb_in_use) |
1342 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 1345 | goto unlock; |
1343 | return; | ||
1344 | } | ||
1345 | 1346 | ||
1346 | count = ti_buf_get(tport->tp_write_buf, | 1347 | count = ti_buf_get(tport->tp_write_buf, |
1347 | port->write_urb->transfer_buffer, | 1348 | port->write_urb->transfer_buffer, |
1348 | port->bulk_out_size); | 1349 | port->bulk_out_size); |
1349 | 1350 | ||
1350 | if (count == 0) { | 1351 | if (count == 0) |
1351 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 1352 | goto unlock; |
1352 | return; | ||
1353 | } | ||
1354 | 1353 | ||
1355 | tport->tp_write_urb_in_use = 1; | 1354 | tport->tp_write_urb_in_use = 1; |
1356 | 1355 | ||
@@ -1380,7 +1379,13 @@ static void ti_send(struct ti_port *tport) | |||
1380 | /* more room in the buffer for new writes, wakeup */ | 1379 | /* more room in the buffer for new writes, wakeup */ |
1381 | if (tty) | 1380 | if (tty) |
1382 | tty_wakeup(tty); | 1381 | tty_wakeup(tty); |
1382 | tty_kref_put(tty); | ||
1383 | wake_up_interruptible(&tport->tp_write_wait); | 1383 | wake_up_interruptible(&tport->tp_write_wait); |
1384 | return; | ||
1385 | unlock: | ||
1386 | spin_unlock_irqrestore(&tport->tp_lock, flags); | ||
1387 | tty_kref_put(tty); | ||
1388 | return; | ||
1384 | } | 1389 | } |
1385 | 1390 | ||
1386 | 1391 | ||
@@ -1464,20 +1469,16 @@ static int ti_get_serial_info(struct ti_port *tport, | |||
1464 | } | 1469 | } |
1465 | 1470 | ||
1466 | 1471 | ||
1467 | static int ti_set_serial_info(struct ti_port *tport, | 1472 | static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, |
1468 | struct serial_struct __user *new_arg) | 1473 | struct serial_struct __user *new_arg) |
1469 | { | 1474 | { |
1470 | struct usb_serial_port *port = tport->tp_port; | ||
1471 | struct serial_struct new_serial; | 1475 | struct serial_struct new_serial; |
1472 | 1476 | ||
1473 | if (copy_from_user(&new_serial, new_arg, sizeof(new_serial))) | 1477 | if (copy_from_user(&new_serial, new_arg, sizeof(new_serial))) |
1474 | return -EFAULT; | 1478 | return -EFAULT; |
1475 | 1479 | ||
1476 | tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS; | 1480 | tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS; |
1477 | /* FIXME */ | 1481 | tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1478 | if (port->port.tty) | ||
1479 | port->port.tty->low_latency = | ||
1480 | (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0; | ||
1481 | tport->tp_closing_wait = new_serial.closing_wait; | 1482 | tport->tp_closing_wait = new_serial.closing_wait; |
1482 | 1483 | ||
1483 | return 0; | 1484 | return 0; |
@@ -1510,7 +1511,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) | |||
1510 | tport->tp_msr = msr & TI_MSR_MASK; | 1511 | tport->tp_msr = msr & TI_MSR_MASK; |
1511 | 1512 | ||
1512 | /* handle CTS flow control */ | 1513 | /* handle CTS flow control */ |
1513 | tty = tport->tp_port->port.tty; | 1514 | tty = tty_port_tty_get(&tport->tp_port->port); |
1514 | if (tty && C_CRTSCTS(tty)) { | 1515 | if (tty && C_CRTSCTS(tty)) { |
1515 | if (msr & TI_MSR_CTS) { | 1516 | if (msr & TI_MSR_CTS) { |
1516 | tty->hw_stopped = 0; | 1517 | tty->hw_stopped = 0; |
@@ -1519,6 +1520,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) | |||
1519 | tty->hw_stopped = 1; | 1520 | tty->hw_stopped = 1; |
1520 | } | 1521 | } |
1521 | } | 1522 | } |
1523 | tty_kref_put(tty); | ||
1522 | } | 1524 | } |
1523 | 1525 | ||
1524 | 1526 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4f7f9e3ae0a4..e7d4246027b2 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -214,7 +214,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
214 | /* set up our port structure making the tty driver | 214 | /* set up our port structure making the tty driver |
215 | * remember our port object, and us it */ | 215 | * remember our port object, and us it */ |
216 | tty->driver_data = port; | 216 | tty->driver_data = port; |
217 | port->port.tty = tty; | 217 | tty_port_tty_set(&port->port, tty); |
218 | 218 | ||
219 | if (port->port.count == 1) { | 219 | if (port->port.count == 1) { |
220 | 220 | ||
@@ -246,7 +246,7 @@ bailout_module_put: | |||
246 | bailout_mutex_unlock: | 246 | bailout_mutex_unlock: |
247 | port->port.count = 0; | 247 | port->port.count = 0; |
248 | tty->driver_data = NULL; | 248 | tty->driver_data = NULL; |
249 | port->port.tty = NULL; | 249 | tty_port_tty_set(&port->port, NULL); |
250 | mutex_unlock(&port->mutex); | 250 | mutex_unlock(&port->mutex); |
251 | bailout_kref_put: | 251 | bailout_kref_put: |
252 | usb_serial_put(serial); | 252 | usb_serial_put(serial); |
@@ -276,10 +276,11 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
276 | port->serial->type->close(tty, port, filp); | 276 | port->serial->type->close(tty, port, filp); |
277 | 277 | ||
278 | if (port->port.count == (port->console? 1 : 0)) { | 278 | if (port->port.count == (port->console? 1 : 0)) { |
279 | if (port->port.tty) { | 279 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
280 | if (port->port.tty->driver_data) | 280 | if (tty) { |
281 | port->port.tty->driver_data = NULL; | 281 | if (tty->driver_data) |
282 | port->port.tty = NULL; | 282 | tty->driver_data = NULL; |
283 | tty_port_tty_set(&port->port, NULL); | ||
283 | } | 284 | } |
284 | } | 285 | } |
285 | 286 | ||
@@ -508,11 +509,12 @@ static void usb_serial_port_work(struct work_struct *work) | |||
508 | if (!port) | 509 | if (!port) |
509 | return; | 510 | return; |
510 | 511 | ||
511 | tty = port->port.tty; | 512 | tty = tty_port_tty_get(&port->port); |
512 | if (!tty) | 513 | if (!tty) |
513 | return; | 514 | return; |
514 | 515 | ||
515 | tty_wakeup(tty); | 516 | tty_wakeup(tty); |
517 | tty_kref_put(tty); | ||
516 | } | 518 | } |
517 | 519 | ||
518 | static void port_release(struct device *dev) | 520 | static void port_release(struct device *dev) |
@@ -819,6 +821,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
819 | port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); | 821 | port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); |
820 | if (!port) | 822 | if (!port) |
821 | goto probe_error; | 823 | goto probe_error; |
824 | tty_port_init(&port->port); | ||
822 | port->serial = serial; | 825 | port->serial = serial; |
823 | spin_lock_init(&port->lock); | 826 | spin_lock_init(&port->lock); |
824 | mutex_init(&port->mutex); | 827 | mutex_init(&port->mutex); |
@@ -1040,8 +1043,11 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1040 | for (i = 0; i < serial->num_ports; ++i) { | 1043 | for (i = 0; i < serial->num_ports; ++i) { |
1041 | port = serial->port[i]; | 1044 | port = serial->port[i]; |
1042 | if (port) { | 1045 | if (port) { |
1043 | if (port->port.tty) | 1046 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
1044 | tty_hangup(port->port.tty); | 1047 | if (tty) { |
1048 | tty_hangup(tty); | ||
1049 | tty_kref_put(tty); | ||
1050 | } | ||
1045 | kill_traffic(port); | 1051 | kill_traffic(port); |
1046 | } | 1052 | } |
1047 | } | 1053 | } |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index cf8924f9a2cc..a6d1c75a1c89 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -499,7 +499,7 @@ static void visor_read_bulk_callback(struct urb *urb) | |||
499 | int status = urb->status; | 499 | int status = urb->status; |
500 | struct tty_struct *tty; | 500 | struct tty_struct *tty; |
501 | int result; | 501 | int result; |
502 | int available_room; | 502 | int available_room = 0; |
503 | 503 | ||
504 | dbg("%s - port %d", __func__, port->number); | 504 | dbg("%s - port %d", __func__, port->number); |
505 | 505 | ||
@@ -512,13 +512,17 @@ static void visor_read_bulk_callback(struct urb *urb) | |||
512 | usb_serial_debug_data(debug, &port->dev, __func__, | 512 | usb_serial_debug_data(debug, &port->dev, __func__, |
513 | urb->actual_length, data); | 513 | urb->actual_length, data); |
514 | 514 | ||
515 | tty = port->port.tty; | 515 | if (urb->actual_length) { |
516 | if (tty && urb->actual_length) { | 516 | tty = tty_port_tty_get(&port->port); |
517 | available_room = tty_buffer_request_room(tty, | 517 | if (tty) { |
518 | available_room = tty_buffer_request_room(tty, | ||
518 | urb->actual_length); | 519 | urb->actual_length); |
519 | if (available_room) { | 520 | if (available_room) { |
520 | tty_insert_flip_string(tty, data, available_room); | 521 | tty_insert_flip_string(tty, data, |
521 | tty_flip_buffer_push(tty); | 522 | available_room); |
523 | tty_flip_buffer_push(tty); | ||
524 | } | ||
525 | tty_kref_put(tty); | ||
522 | } | 526 | } |
523 | spin_lock(&priv->lock); | 527 | spin_lock(&priv->lock); |
524 | priv->bytes_in += available_room; | 528 | priv->bytes_in += available_room; |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 3a9d14384a43..11c8b97a5177 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -1481,7 +1481,7 @@ static void rx_data_softint(struct work_struct *work) | |||
1481 | struct whiteheat_private *info = | 1481 | struct whiteheat_private *info = |
1482 | container_of(work, struct whiteheat_private, rx_work); | 1482 | container_of(work, struct whiteheat_private, rx_work); |
1483 | struct usb_serial_port *port = info->port; | 1483 | struct usb_serial_port *port = info->port; |
1484 | struct tty_struct *tty = port->port.tty; | 1484 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
1485 | struct whiteheat_urb_wrap *wrap; | 1485 | struct whiteheat_urb_wrap *wrap; |
1486 | struct urb *urb; | 1486 | struct urb *urb; |
1487 | unsigned long flags; | 1487 | unsigned long flags; |
@@ -1493,7 +1493,7 @@ static void rx_data_softint(struct work_struct *work) | |||
1493 | spin_lock_irqsave(&info->lock, flags); | 1493 | spin_lock_irqsave(&info->lock, flags); |
1494 | if (info->flags & THROTTLED) { | 1494 | if (info->flags & THROTTLED) { |
1495 | spin_unlock_irqrestore(&info->lock, flags); | 1495 | spin_unlock_irqrestore(&info->lock, flags); |
1496 | return; | 1496 | goto out; |
1497 | } | 1497 | } |
1498 | 1498 | ||
1499 | list_for_each_safe(tmp, tmp2, &info->rx_urb_q) { | 1499 | list_for_each_safe(tmp, tmp2, &info->rx_urb_q) { |
@@ -1513,7 +1513,7 @@ static void rx_data_softint(struct work_struct *work) | |||
1513 | spin_unlock_irqrestore(&info->lock, flags); | 1513 | spin_unlock_irqrestore(&info->lock, flags); |
1514 | tty_flip_buffer_push(tty); | 1514 | tty_flip_buffer_push(tty); |
1515 | schedule_work(&info->rx_work); | 1515 | schedule_work(&info->rx_work); |
1516 | return; | 1516 | goto out; |
1517 | } | 1517 | } |
1518 | tty_insert_flip_string(tty, urb->transfer_buffer, len); | 1518 | tty_insert_flip_string(tty, urb->transfer_buffer, len); |
1519 | sent += len; | 1519 | sent += len; |
@@ -1536,6 +1536,8 @@ static void rx_data_softint(struct work_struct *work) | |||
1536 | 1536 | ||
1537 | if (sent) | 1537 | if (sent) |
1538 | tty_flip_buffer_push(tty); | 1538 | tty_flip_buffer_push(tty); |
1539 | out: | ||
1540 | tty_kref_put(tty); | ||
1539 | } | 1541 | } |
1540 | 1542 | ||
1541 | 1543 | ||
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 488eb424f662..a70d5d0890c7 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #define DEVPTS_SUPER_MAGIC 0x1cd1 | 27 | #define DEVPTS_SUPER_MAGIC 0x1cd1 |
28 | 28 | ||
29 | #define DEVPTS_DEFAULT_MODE 0600 | 29 | #define DEVPTS_DEFAULT_MODE 0600 |
30 | #define PTMX_MINOR 2 | ||
30 | 31 | ||
31 | extern int pty_limit; /* Config limit on Unix98 ptys */ | 32 | extern int pty_limit; /* Config limit on Unix98 ptys */ |
32 | static DEFINE_IDA(allocated_ptys); | 33 | static DEFINE_IDA(allocated_ptys); |
@@ -169,15 +170,7 @@ static struct file_system_type devpts_fs_type = { | |||
169 | * to the System V naming convention | 170 | * to the System V naming convention |
170 | */ | 171 | */ |
171 | 172 | ||
172 | static struct dentry *get_node(int num) | 173 | int devpts_new_index(struct inode *ptmx_inode) |
173 | { | ||
174 | char s[12]; | ||
175 | struct dentry *root = devpts_root; | ||
176 | mutex_lock(&root->d_inode->i_mutex); | ||
177 | return lookup_one_len(s, root, sprintf(s, "%d", num)); | ||
178 | } | ||
179 | |||
180 | int devpts_new_index(void) | ||
181 | { | 174 | { |
182 | int index; | 175 | int index; |
183 | int ida_ret; | 176 | int ida_ret; |
@@ -205,20 +198,21 @@ retry: | |||
205 | return index; | 198 | return index; |
206 | } | 199 | } |
207 | 200 | ||
208 | void devpts_kill_index(int idx) | 201 | void devpts_kill_index(struct inode *ptmx_inode, int idx) |
209 | { | 202 | { |
210 | mutex_lock(&allocated_ptys_lock); | 203 | mutex_lock(&allocated_ptys_lock); |
211 | ida_remove(&allocated_ptys, idx); | 204 | ida_remove(&allocated_ptys, idx); |
212 | mutex_unlock(&allocated_ptys_lock); | 205 | mutex_unlock(&allocated_ptys_lock); |
213 | } | 206 | } |
214 | 207 | ||
215 | int devpts_pty_new(struct tty_struct *tty) | 208 | int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) |
216 | { | 209 | { |
217 | int number = tty->index; /* tty layer puts index from devpts_new_index() in here */ | 210 | int number = tty->index; /* tty layer puts index from devpts_new_index() in here */ |
218 | struct tty_driver *driver = tty->driver; | 211 | struct tty_driver *driver = tty->driver; |
219 | dev_t device = MKDEV(driver->major, driver->minor_start+number); | 212 | dev_t device = MKDEV(driver->major, driver->minor_start+number); |
220 | struct dentry *dentry; | 213 | struct dentry *dentry; |
221 | struct inode *inode = new_inode(devpts_mnt->mnt_sb); | 214 | struct inode *inode = new_inode(devpts_mnt->mnt_sb); |
215 | char s[12]; | ||
222 | 216 | ||
223 | /* We're supposed to be given the slave end of a pty */ | 217 | /* We're supposed to be given the slave end of a pty */ |
224 | BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY); | 218 | BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY); |
@@ -233,10 +227,15 @@ int devpts_pty_new(struct tty_struct *tty) | |||
233 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 227 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
234 | init_special_inode(inode, S_IFCHR|config.mode, device); | 228 | init_special_inode(inode, S_IFCHR|config.mode, device); |
235 | inode->i_private = tty; | 229 | inode->i_private = tty; |
230 | tty->driver_data = inode; | ||
236 | 231 | ||
237 | dentry = get_node(number); | 232 | sprintf(s, "%d", number); |
238 | if (!IS_ERR(dentry) && !dentry->d_inode) { | 233 | |
239 | d_instantiate(dentry, inode); | 234 | mutex_lock(&devpts_root->d_inode->i_mutex); |
235 | |||
236 | dentry = d_alloc_name(devpts_root, s); | ||
237 | if (!IS_ERR(dentry)) { | ||
238 | d_add(dentry, inode); | ||
240 | fsnotify_create(devpts_root->d_inode, dentry); | 239 | fsnotify_create(devpts_root->d_inode, dentry); |
241 | } | 240 | } |
242 | 241 | ||
@@ -245,36 +244,31 @@ int devpts_pty_new(struct tty_struct *tty) | |||
245 | return 0; | 244 | return 0; |
246 | } | 245 | } |
247 | 246 | ||
248 | struct tty_struct *devpts_get_tty(int number) | 247 | struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number) |
249 | { | 248 | { |
250 | struct dentry *dentry = get_node(number); | 249 | BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); |
251 | struct tty_struct *tty; | ||
252 | |||
253 | tty = NULL; | ||
254 | if (!IS_ERR(dentry)) { | ||
255 | if (dentry->d_inode) | ||
256 | tty = dentry->d_inode->i_private; | ||
257 | dput(dentry); | ||
258 | } | ||
259 | 250 | ||
260 | mutex_unlock(&devpts_root->d_inode->i_mutex); | 251 | if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) |
261 | 252 | return (struct tty_struct *)pts_inode->i_private; | |
262 | return tty; | 253 | return NULL; |
263 | } | 254 | } |
264 | 255 | ||
265 | void devpts_pty_kill(int number) | 256 | void devpts_pty_kill(struct tty_struct *tty) |
266 | { | 257 | { |
267 | struct dentry *dentry = get_node(number); | 258 | struct inode *inode = tty->driver_data; |
259 | struct dentry *dentry; | ||
268 | 260 | ||
269 | if (!IS_ERR(dentry)) { | 261 | BUG_ON(inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); |
270 | struct inode *inode = dentry->d_inode; | 262 | |
271 | if (inode) { | 263 | mutex_lock(&devpts_root->d_inode->i_mutex); |
272 | inode->i_nlink--; | 264 | |
273 | d_delete(dentry); | 265 | dentry = d_find_alias(inode); |
274 | dput(dentry); | 266 | if (dentry && !IS_ERR(dentry)) { |
275 | } | 267 | inode->i_nlink--; |
268 | d_delete(dentry); | ||
276 | dput(dentry); | 269 | dput(dentry); |
277 | } | 270 | } |
271 | |||
278 | mutex_unlock(&devpts_root->d_inode->i_mutex); | 272 | mutex_unlock(&devpts_root->d_inode->i_mutex); |
279 | } | 273 | } |
280 | 274 | ||
diff --git a/fs/dquot.c b/fs/dquot.c index 8ec4d6cc7633..ad7e59003e04 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -895,10 +895,9 @@ static void print_warning(struct dquot *dquot, const int warntype) | |||
895 | warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot)) | 895 | warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot)) |
896 | return; | 896 | return; |
897 | 897 | ||
898 | mutex_lock(&tty_mutex); | ||
899 | tty = get_current_tty(); | 898 | tty = get_current_tty(); |
900 | if (!tty) | 899 | if (!tty) |
901 | goto out_lock; | 900 | return; |
902 | tty_write_message(tty, dquot->dq_sb->s_id); | 901 | tty_write_message(tty, dquot->dq_sb->s_id); |
903 | if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN) | 902 | if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN) |
904 | tty_write_message(tty, ": warning, "); | 903 | tty_write_message(tty, ": warning, "); |
@@ -926,8 +925,7 @@ static void print_warning(struct dquot *dquot, const int warntype) | |||
926 | break; | 925 | break; |
927 | } | 926 | } |
928 | tty_write_message(tty, msg); | 927 | tty_write_message(tty, msg); |
929 | out_lock: | 928 | tty_kref_put(tty); |
930 | mutex_unlock(&tty_mutex); | ||
931 | } | 929 | } |
932 | #endif | 930 | #endif |
933 | 931 | ||
@@ -1141,8 +1141,7 @@ EXPORT_SYMBOL(sys_close); | |||
1141 | asmlinkage long sys_vhangup(void) | 1141 | asmlinkage long sys_vhangup(void) |
1142 | { | 1142 | { |
1143 | if (capable(CAP_SYS_TTY_CONFIG)) { | 1143 | if (capable(CAP_SYS_TTY_CONFIG)) { |
1144 | /* XXX: this needs locking */ | 1144 | tty_vhangup_self(); |
1145 | tty_vhangup(current->signal->tty); | ||
1146 | return 0; | 1145 | return 0; |
1147 | } | 1146 | } |
1148 | return -EPERM; | 1147 | return -EPERM; |
diff --git a/include/asm-x86/ioctls.h b/include/asm-x86/ioctls.h index 336603512399..06752a649044 100644 --- a/include/asm-x86/ioctls.h +++ b/include/asm-x86/ioctls.h | |||
@@ -51,9 +51,15 @@ | |||
51 | #define TCSETS2 _IOW('T', 0x2B, struct termios2) | 51 | #define TCSETS2 _IOW('T', 0x2B, struct termios2) |
52 | #define TCSETSW2 _IOW('T', 0x2C, struct termios2) | 52 | #define TCSETSW2 _IOW('T', 0x2C, struct termios2) |
53 | #define TCSETSF2 _IOW('T', 0x2D, struct termios2) | 53 | #define TCSETSF2 _IOW('T', 0x2D, struct termios2) |
54 | #define TIOCGRS485 0x542E | ||
55 | #define TIOCSRS485 0x542F | ||
54 | #define TIOCGPTN _IOR('T', 0x30, unsigned int) | 56 | #define TIOCGPTN _IOR('T', 0x30, unsigned int) |
55 | /* Get Pty Number (of pty-mux device) */ | 57 | /* Get Pty Number (of pty-mux device) */ |
56 | #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ | 58 | #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ |
59 | #define TCGETX 0x5432 /* SYS5 TCGETX compatibility */ | ||
60 | #define TCSETX 0x5433 | ||
61 | #define TCSETXF 0x5434 | ||
62 | #define TCSETXW 0x5435 | ||
57 | 63 | ||
58 | #define FIONCLEX 0x5450 | 64 | #define FIONCLEX 0x5450 |
59 | #define FIOCLEX 0x5451 | 65 | #define FIOCLEX 0x5451 |
diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h index 154769cad3f3..5ce0e5fd712e 100644 --- a/include/linux/devpts_fs.h +++ b/include/linux/devpts_fs.h | |||
@@ -17,20 +17,31 @@ | |||
17 | 17 | ||
18 | #ifdef CONFIG_UNIX98_PTYS | 18 | #ifdef CONFIG_UNIX98_PTYS |
19 | 19 | ||
20 | int devpts_new_index(void); | 20 | int devpts_new_index(struct inode *ptmx_inode); |
21 | void devpts_kill_index(int idx); | 21 | void devpts_kill_index(struct inode *ptmx_inode, int idx); |
22 | int devpts_pty_new(struct tty_struct *tty); /* mknod in devpts */ | 22 | /* mknod in devpts */ |
23 | struct tty_struct *devpts_get_tty(int number); /* get tty structure */ | 23 | int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty); |
24 | void devpts_pty_kill(int number); /* unlink */ | 24 | /* get tty structure */ |
25 | struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number); | ||
26 | /* unlink */ | ||
27 | void devpts_pty_kill(struct tty_struct *tty); | ||
25 | 28 | ||
26 | #else | 29 | #else |
27 | 30 | ||
28 | /* Dummy stubs in the no-pty case */ | 31 | /* Dummy stubs in the no-pty case */ |
29 | static inline int devpts_new_index(void) { return -EINVAL; } | 32 | static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; } |
30 | static inline void devpts_kill_index(int idx) { } | 33 | static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { } |
31 | static inline int devpts_pty_new(struct tty_struct *tty) { return -EINVAL; } | 34 | static inline int devpts_pty_new(struct inode *ptmx_inode, |
32 | static inline struct tty_struct *devpts_get_tty(int number) { return NULL; } | 35 | struct tty_struct *tty) |
33 | static inline void devpts_pty_kill(int number) { } | 36 | { |
37 | return -EINVAL; | ||
38 | } | ||
39 | static inline struct tty_struct *devpts_get_tty(struct inode *pts_inode, | ||
40 | int number) | ||
41 | { | ||
42 | return NULL; | ||
43 | } | ||
44 | static inline void devpts_pty_kill(struct tty_struct *tty) { } | ||
34 | 45 | ||
35 | #endif | 46 | #endif |
36 | 47 | ||
diff --git a/include/linux/serial.h b/include/linux/serial.h index deb714314fb1..1ea8d9265bf6 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h | |||
@@ -173,6 +173,22 @@ struct serial_icounter_struct { | |||
173 | int reserved[9]; | 173 | int reserved[9]; |
174 | }; | 174 | }; |
175 | 175 | ||
176 | /* | ||
177 | * Serial interface for controlling RS485 settings on chips with suitable | ||
178 | * support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your | ||
179 | * platform. The set function returns the new state, with any unsupported bits | ||
180 | * reverted appropriately. | ||
181 | */ | ||
182 | |||
183 | struct serial_rs485 { | ||
184 | __u32 flags; /* RS485 feature flags */ | ||
185 | #define SER_RS485_ENABLED (1 << 0) | ||
186 | #define SER_RS485_RTS_ON_SEND (1 << 1) | ||
187 | #define SER_RS485_RTS_AFTER_SEND (1 << 2) | ||
188 | __u32 delay_rts_before_send; /* Milliseconds */ | ||
189 | __u32 padding[6]; /* Memory is cheap, new structs | ||
190 | are a royal PITA .. */ | ||
191 | }; | ||
176 | 192 | ||
177 | #ifdef __KERNEL__ | 193 | #ifdef __KERNEL__ |
178 | #include <linux/compiler.h> | 194 | #include <linux/compiler.h> |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 3b2f6c04855e..e27f216361fc 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -241,7 +241,7 @@ typedef unsigned int __bitwise__ upf_t; | |||
241 | 241 | ||
242 | struct uart_port { | 242 | struct uart_port { |
243 | spinlock_t lock; /* port lock */ | 243 | spinlock_t lock; /* port lock */ |
244 | unsigned int iobase; /* in/out[bwl] */ | 244 | unsigned long iobase; /* in/out[bwl] */ |
245 | unsigned char __iomem *membase; /* read/write[bwl] */ | 245 | unsigned char __iomem *membase; /* read/write[bwl] */ |
246 | unsigned int irq; /* irq number */ | 246 | unsigned int irq; /* irq number */ |
247 | unsigned int uartclk; /* base uart clock */ | 247 | unsigned int uartclk; /* base uart clock */ |
diff --git a/include/linux/termios.h b/include/linux/termios.h index 478662889f48..2acd0c1f8a2a 100644 --- a/include/linux/termios.h +++ b/include/linux/termios.h | |||
@@ -4,4 +4,19 @@ | |||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <asm/termios.h> | 5 | #include <asm/termios.h> |
6 | 6 | ||
7 | #define NFF 5 | ||
8 | |||
9 | struct termiox | ||
10 | { | ||
11 | __u16 x_hflag; | ||
12 | __u16 x_cflag; | ||
13 | __u16 x_rflag[NFF]; | ||
14 | __u16 x_sflag; | ||
15 | }; | ||
16 | |||
17 | #define RTSXOFF 0x0001 /* RTS flow control on input */ | ||
18 | #define CTSXON 0x0002 /* CTS flow control on output */ | ||
19 | #define DTRXOFF 0x0004 /* DTR flow control on input */ | ||
20 | #define DSRXON 0x0008 /* DCD flow control on output */ | ||
21 | |||
7 | #endif | 22 | #endif |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 0cbec74ec086..3b8121d4e36f 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | #define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */ | 24 | #define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */ |
25 | #define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */ | 25 | #define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */ |
26 | #define NR_LDISCS 18 | 26 | #define NR_LDISCS 19 |
27 | 27 | ||
28 | /* line disciplines */ | 28 | /* line disciplines */ |
29 | #define N_TTY 0 | 29 | #define N_TTY 0 |
@@ -45,6 +45,7 @@ | |||
45 | #define N_HCI 15 /* Bluetooth HCI UART */ | 45 | #define N_HCI 15 /* Bluetooth HCI UART */ |
46 | #define N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */ | 46 | #define N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */ |
47 | #define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */ | 47 | #define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */ |
48 | #define N_PPS 18 /* Pulse per Second */ | ||
48 | 49 | ||
49 | /* | 50 | /* |
50 | * This character is the same as _POSIX_VDISABLE: it cannot be used as | 51 | * This character is the same as _POSIX_VDISABLE: it cannot be used as |
@@ -181,6 +182,7 @@ struct signal_struct; | |||
181 | 182 | ||
182 | struct tty_port { | 183 | struct tty_port { |
183 | struct tty_struct *tty; /* Back pointer */ | 184 | struct tty_struct *tty; /* Back pointer */ |
185 | spinlock_t lock; /* Lock protecting tty field */ | ||
184 | int blocked_open; /* Waiting to open */ | 186 | int blocked_open; /* Waiting to open */ |
185 | int count; /* Usage count */ | 187 | int count; /* Usage count */ |
186 | wait_queue_head_t open_wait; /* Open waiters */ | 188 | wait_queue_head_t open_wait; /* Open waiters */ |
@@ -208,6 +210,7 @@ struct tty_operations; | |||
208 | 210 | ||
209 | struct tty_struct { | 211 | struct tty_struct { |
210 | int magic; | 212 | int magic; |
213 | struct kref kref; | ||
211 | struct tty_driver *driver; | 214 | struct tty_driver *driver; |
212 | const struct tty_operations *ops; | 215 | const struct tty_operations *ops; |
213 | int index; | 216 | int index; |
@@ -217,6 +220,7 @@ struct tty_struct { | |||
217 | spinlock_t ctrl_lock; | 220 | spinlock_t ctrl_lock; |
218 | /* Termios values are protected by the termios mutex */ | 221 | /* Termios values are protected by the termios mutex */ |
219 | struct ktermios *termios, *termios_locked; | 222 | struct ktermios *termios, *termios_locked; |
223 | struct termiox *termiox; /* May be NULL for unsupported */ | ||
220 | char name[64]; | 224 | char name[64]; |
221 | struct pid *pgrp; /* Protected by ctrl lock */ | 225 | struct pid *pgrp; /* Protected by ctrl lock */ |
222 | struct pid *session; | 226 | struct pid *session; |
@@ -310,6 +314,25 @@ extern int kmsg_redirect; | |||
310 | extern void console_init(void); | 314 | extern void console_init(void); |
311 | extern int vcs_init(void); | 315 | extern int vcs_init(void); |
312 | 316 | ||
317 | extern struct class *tty_class; | ||
318 | |||
319 | /** | ||
320 | * tty_kref_get - get a tty reference | ||
321 | * @tty: tty device | ||
322 | * | ||
323 | * Return a new reference to a tty object. The caller must hold | ||
324 | * sufficient locks/counts to ensure that their existing reference cannot | ||
325 | * go away | ||
326 | */ | ||
327 | |||
328 | extern inline struct tty_struct *tty_kref_get(struct tty_struct *tty) | ||
329 | { | ||
330 | if (tty) | ||
331 | kref_get(&tty->kref); | ||
332 | return tty; | ||
333 | } | ||
334 | extern void tty_kref_put(struct tty_struct *tty); | ||
335 | |||
313 | extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, | 336 | extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, |
314 | const char *routine); | 337 | const char *routine); |
315 | extern char *tty_name(struct tty_struct *tty, char *buf); | 338 | extern char *tty_name(struct tty_struct *tty, char *buf); |
@@ -333,13 +356,15 @@ extern void tty_throttle(struct tty_struct *tty); | |||
333 | extern void tty_unthrottle(struct tty_struct *tty); | 356 | extern void tty_unthrottle(struct tty_struct *tty); |
334 | extern int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, | 357 | extern int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, |
335 | struct winsize *ws); | 358 | struct winsize *ws); |
336 | 359 | extern void tty_shutdown(struct tty_struct *tty); | |
360 | extern void tty_free_termios(struct tty_struct *tty); | ||
337 | extern int is_current_pgrp_orphaned(void); | 361 | extern int is_current_pgrp_orphaned(void); |
338 | extern struct pid *tty_get_pgrp(struct tty_struct *tty); | 362 | extern struct pid *tty_get_pgrp(struct tty_struct *tty); |
339 | extern int is_ignored(int sig); | 363 | extern int is_ignored(int sig); |
340 | extern int tty_signal(int sig, struct tty_struct *tty); | 364 | extern int tty_signal(int sig, struct tty_struct *tty); |
341 | extern void tty_hangup(struct tty_struct *tty); | 365 | extern void tty_hangup(struct tty_struct *tty); |
342 | extern void tty_vhangup(struct tty_struct *tty); | 366 | extern void tty_vhangup(struct tty_struct *tty); |
367 | extern void tty_vhangup_self(void); | ||
343 | extern void tty_unhangup(struct file *filp); | 368 | extern void tty_unhangup(struct file *filp); |
344 | extern int tty_hung_up_p(struct file *filp); | 369 | extern int tty_hung_up_p(struct file *filp); |
345 | extern void do_SAK(struct tty_struct *tty); | 370 | extern void do_SAK(struct tty_struct *tty); |
@@ -347,6 +372,9 @@ extern void __do_SAK(struct tty_struct *tty); | |||
347 | extern void disassociate_ctty(int priv); | 372 | extern void disassociate_ctty(int priv); |
348 | extern void no_tty(void); | 373 | extern void no_tty(void); |
349 | extern void tty_flip_buffer_push(struct tty_struct *tty); | 374 | extern void tty_flip_buffer_push(struct tty_struct *tty); |
375 | extern void tty_buffer_free_all(struct tty_struct *tty); | ||
376 | extern void tty_buffer_flush(struct tty_struct *tty); | ||
377 | extern void tty_buffer_init(struct tty_struct *tty); | ||
350 | extern speed_t tty_get_baud_rate(struct tty_struct *tty); | 378 | extern speed_t tty_get_baud_rate(struct tty_struct *tty); |
351 | extern speed_t tty_termios_baud_rate(struct ktermios *termios); | 379 | extern speed_t tty_termios_baud_rate(struct ktermios *termios); |
352 | extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); | 380 | extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); |
@@ -372,6 +400,15 @@ extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg); | |||
372 | extern dev_t tty_devnum(struct tty_struct *tty); | 400 | extern dev_t tty_devnum(struct tty_struct *tty); |
373 | extern void proc_clear_tty(struct task_struct *p); | 401 | extern void proc_clear_tty(struct task_struct *p); |
374 | extern struct tty_struct *get_current_tty(void); | 402 | extern struct tty_struct *get_current_tty(void); |
403 | extern void tty_default_fops(struct file_operations *fops); | ||
404 | extern struct tty_struct *alloc_tty_struct(void); | ||
405 | extern void free_tty_struct(struct tty_struct *tty); | ||
406 | extern void initialize_tty_struct(struct tty_struct *tty, | ||
407 | struct tty_driver *driver, int idx); | ||
408 | extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | ||
409 | int first_ok); | ||
410 | extern void tty_release_dev(struct file *filp); | ||
411 | extern int tty_init_termios(struct tty_struct *tty); | ||
375 | 412 | ||
376 | extern struct mutex tty_mutex; | 413 | extern struct mutex tty_mutex; |
377 | 414 | ||
@@ -382,6 +419,8 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay); | |||
382 | extern void tty_port_init(struct tty_port *port); | 419 | extern void tty_port_init(struct tty_port *port); |
383 | extern int tty_port_alloc_xmit_buf(struct tty_port *port); | 420 | extern int tty_port_alloc_xmit_buf(struct tty_port *port); |
384 | extern void tty_port_free_xmit_buf(struct tty_port *port); | 421 | extern void tty_port_free_xmit_buf(struct tty_port *port); |
422 | extern struct tty_struct *tty_port_tty_get(struct tty_port *port); | ||
423 | extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); | ||
385 | 424 | ||
386 | extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); | 425 | extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); |
387 | extern int tty_unregister_ldisc(int disc); | 426 | extern int tty_unregister_ldisc(int disc); |
@@ -427,7 +466,7 @@ static inline void tty_audit_push_task(struct task_struct *tsk, | |||
427 | #endif | 466 | #endif |
428 | 467 | ||
429 | /* tty_ioctl.c */ | 468 | /* tty_ioctl.c */ |
430 | extern int n_tty_ioctl(struct tty_struct *tty, struct file *file, | 469 | extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
431 | unsigned int cmd, unsigned long arg); | 470 | unsigned int cmd, unsigned long arg); |
432 | 471 | ||
433 | /* serial.c */ | 472 | /* serial.c */ |
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 16d27944c321..78416b901589 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h | |||
@@ -7,6 +7,28 @@ | |||
7 | * defined; unless noted otherwise, they are optional, and can be | 7 | * defined; unless noted otherwise, they are optional, and can be |
8 | * filled in with a null pointer. | 8 | * filled in with a null pointer. |
9 | * | 9 | * |
10 | * struct tty_struct * (*lookup)(struct tty_driver *self, int idx) | ||
11 | * | ||
12 | * Return the tty device corresponding to idx, NULL if there is not | ||
13 | * one currently in use and an ERR_PTR value on error. Called under | ||
14 | * tty_mutex (for now!) | ||
15 | * | ||
16 | * Optional method. Default behaviour is to use the ttys array | ||
17 | * | ||
18 | * int (*install)(struct tty_driver *self, struct tty_struct *tty) | ||
19 | * | ||
20 | * Install a new tty into the tty driver internal tables. Used in | ||
21 | * conjunction with lookup and remove methods. | ||
22 | * | ||
23 | * Optional method. Default behaviour is to use the ttys array | ||
24 | * | ||
25 | * void (*remove)(struct tty_driver *self, struct tty_struct *tty) | ||
26 | * | ||
27 | * Remove a closed tty from the tty driver internal tables. Used in | ||
28 | * conjunction with lookup and remove methods. | ||
29 | * | ||
30 | * Optional method. Default behaviour is to use the ttys array | ||
31 | * | ||
10 | * int (*open)(struct tty_struct * tty, struct file * filp); | 32 | * int (*open)(struct tty_struct * tty, struct file * filp); |
11 | * | 33 | * |
12 | * This routine is called when a particular tty device is opened. | 34 | * This routine is called when a particular tty device is opened. |
@@ -21,6 +43,11 @@ | |||
21 | * | 43 | * |
22 | * Required method. | 44 | * Required method. |
23 | * | 45 | * |
46 | * void (*shutdown)(struct tty_struct * tty); | ||
47 | * | ||
48 | * This routine is called when a particular tty device is closed for | ||
49 | * the last time freeing up the resources. | ||
50 | * | ||
24 | * int (*write)(struct tty_struct * tty, | 51 | * int (*write)(struct tty_struct * tty, |
25 | * const unsigned char *buf, int count); | 52 | * const unsigned char *buf, int count); |
26 | * | 53 | * |
@@ -180,6 +207,14 @@ | |||
180 | * not force errors here if they are not resizable objects (eg a serial | 207 | * not force errors here if they are not resizable objects (eg a serial |
181 | * line). See tty_do_resize() if you need to wrap the standard method | 208 | * line). See tty_do_resize() if you need to wrap the standard method |
182 | * in your own logic - the usual case. | 209 | * in your own logic - the usual case. |
210 | * | ||
211 | * void (*set_termiox)(struct tty_struct *tty, struct termiox *new); | ||
212 | * | ||
213 | * Called when the device receives a termiox based ioctl. Passes down | ||
214 | * the requested data from user space. This method will not be invoked | ||
215 | * unless the tty also has a valid tty->termiox pointer. | ||
216 | * | ||
217 | * Optional: Called under the termios lock | ||
183 | */ | 218 | */ |
184 | 219 | ||
185 | #include <linux/fs.h> | 220 | #include <linux/fs.h> |
@@ -190,8 +225,13 @@ struct tty_struct; | |||
190 | struct tty_driver; | 225 | struct tty_driver; |
191 | 226 | ||
192 | struct tty_operations { | 227 | struct tty_operations { |
228 | struct tty_struct * (*lookup)(struct tty_driver *driver, | ||
229 | struct inode *inode, int idx); | ||
230 | int (*install)(struct tty_driver *driver, struct tty_struct *tty); | ||
231 | void (*remove)(struct tty_driver *driver, struct tty_struct *tty); | ||
193 | int (*open)(struct tty_struct * tty, struct file * filp); | 232 | int (*open)(struct tty_struct * tty, struct file * filp); |
194 | void (*close)(struct tty_struct * tty, struct file * filp); | 233 | void (*close)(struct tty_struct * tty, struct file * filp); |
234 | void (*shutdown)(struct tty_struct *tty); | ||
195 | int (*write)(struct tty_struct * tty, | 235 | int (*write)(struct tty_struct * tty, |
196 | const unsigned char *buf, int count); | 236 | const unsigned char *buf, int count); |
197 | int (*put_char)(struct tty_struct *tty, unsigned char ch); | 237 | int (*put_char)(struct tty_struct *tty, unsigned char ch); |
@@ -220,6 +260,7 @@ struct tty_operations { | |||
220 | unsigned int set, unsigned int clear); | 260 | unsigned int set, unsigned int clear); |
221 | int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty, | 261 | int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty, |
222 | struct winsize *ws); | 262 | struct winsize *ws); |
263 | int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew); | ||
223 | #ifdef CONFIG_CONSOLE_POLL | 264 | #ifdef CONFIG_CONSOLE_POLL |
224 | int (*poll_init)(struct tty_driver *driver, int line, char *options); | 265 | int (*poll_init)(struct tty_driver *driver, int line, char *options); |
225 | int (*poll_get_char)(struct tty_driver *driver, int line); | 266 | int (*poll_get_char)(struct tty_driver *driver, int line); |
@@ -229,6 +270,7 @@ struct tty_operations { | |||
229 | 270 | ||
230 | struct tty_driver { | 271 | struct tty_driver { |
231 | int magic; /* magic number for this structure */ | 272 | int magic; /* magic number for this structure */ |
273 | struct kref kref; /* Reference management */ | ||
232 | struct cdev cdev; | 274 | struct cdev cdev; |
233 | struct module *owner; | 275 | struct module *owner; |
234 | const char *driver_name; | 276 | const char *driver_name; |
@@ -242,7 +284,6 @@ struct tty_driver { | |||
242 | short subtype; /* subtype of tty driver */ | 284 | short subtype; /* subtype of tty driver */ |
243 | struct ktermios init_termios; /* Initial termios */ | 285 | struct ktermios init_termios; /* Initial termios */ |
244 | int flags; /* tty driver flags */ | 286 | int flags; /* tty driver flags */ |
245 | int refcount; /* for loadable tty drivers */ | ||
246 | struct proc_dir_entry *proc_entry; /* /proc fs entry */ | 287 | struct proc_dir_entry *proc_entry; /* /proc fs entry */ |
247 | struct tty_driver *other; /* only used for the PTY driver */ | 288 | struct tty_driver *other; /* only used for the PTY driver */ |
248 | 289 | ||
@@ -264,12 +305,19 @@ struct tty_driver { | |||
264 | 305 | ||
265 | extern struct list_head tty_drivers; | 306 | extern struct list_head tty_drivers; |
266 | 307 | ||
267 | struct tty_driver *alloc_tty_driver(int lines); | 308 | extern struct tty_driver *alloc_tty_driver(int lines); |
268 | void put_tty_driver(struct tty_driver *driver); | 309 | extern void put_tty_driver(struct tty_driver *driver); |
269 | void tty_set_operations(struct tty_driver *driver, | 310 | extern void tty_set_operations(struct tty_driver *driver, |
270 | const struct tty_operations *op); | 311 | const struct tty_operations *op); |
271 | extern struct tty_driver *tty_find_polling_driver(char *name, int *line); | 312 | extern struct tty_driver *tty_find_polling_driver(char *name, int *line); |
272 | 313 | ||
314 | extern void tty_driver_kref_put(struct tty_driver *driver); | ||
315 | extern inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) | ||
316 | { | ||
317 | kref_get(&d->kref); | ||
318 | return d; | ||
319 | } | ||
320 | |||
273 | /* tty driver magic number */ | 321 | /* tty driver magic number */ |
274 | #define TTY_DRIVER_MAGIC 0x5402 | 322 | #define TTY_DRIVER_MAGIC 0x5402 |
275 | 323 | ||
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 1cbd0a7db4e6..2f1113467f70 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h | |||
@@ -96,7 +96,7 @@ void change_console(struct vc_data *new_vc); | |||
96 | void reset_vc(struct vc_data *vc); | 96 | void reset_vc(struct vc_data *vc); |
97 | extern int unbind_con_driver(const struct consw *csw, int first, int last, | 97 | extern int unbind_con_driver(const struct consw *csw, int first, int last, |
98 | int deflt); | 98 | int deflt); |
99 | int vty_init(void); | 99 | int vty_init(const struct file_operations *console_fops); |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * vc_screen.c shares this temporary buffer with the console write code so that | 102 | * vc_screen.c shares this temporary buffer with the console write code so that |
diff --git a/kernel/acct.c b/kernel/acct.c index dd68b9059418..f6006a60df5d 100644 --- a/kernel/acct.c +++ b/kernel/acct.c | |||
@@ -548,7 +548,7 @@ static void do_acct_process(struct bsd_acct_struct *acct, | |||
548 | #endif | 548 | #endif |
549 | 549 | ||
550 | spin_lock_irq(¤t->sighand->siglock); | 550 | spin_lock_irq(¤t->sighand->siglock); |
551 | tty = current->signal->tty; | 551 | tty = current->signal->tty; /* Safe as we hold the siglock */ |
552 | ac.ac_tty = tty ? old_encode_dev(tty_devnum(tty)) : 0; | 552 | ac.ac_tty = tty ? old_encode_dev(tty_devnum(tty)) : 0; |
553 | ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime))); | 553 | ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime))); |
554 | ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime))); | 554 | ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime))); |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 59cedfb040e7..cf5bc2f5f9c3 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -246,8 +246,8 @@ static int audit_match_perm(struct audit_context *ctx, int mask) | |||
246 | unsigned n; | 246 | unsigned n; |
247 | if (unlikely(!ctx)) | 247 | if (unlikely(!ctx)) |
248 | return 0; | 248 | return 0; |
249 | |||
250 | n = ctx->major; | 249 | n = ctx->major; |
250 | |||
251 | switch (audit_classify_syscall(ctx->arch, n)) { | 251 | switch (audit_classify_syscall(ctx->arch, n)) { |
252 | case 0: /* native */ | 252 | case 0: /* native */ |
253 | if ((mask & AUDIT_PERM_WRITE) && | 253 | if ((mask & AUDIT_PERM_WRITE) && |
@@ -1204,13 +1204,13 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1204 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", | 1204 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", |
1205 | context->return_code); | 1205 | context->return_code); |
1206 | 1206 | ||
1207 | mutex_lock(&tty_mutex); | 1207 | spin_lock_irq(&tsk->sighand->siglock); |
1208 | read_lock(&tasklist_lock); | ||
1209 | if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) | 1208 | if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) |
1210 | tty = tsk->signal->tty->name; | 1209 | tty = tsk->signal->tty->name; |
1211 | else | 1210 | else |
1212 | tty = "(none)"; | 1211 | tty = "(none)"; |
1213 | read_unlock(&tasklist_lock); | 1212 | spin_unlock_irq(&tsk->sighand->siglock); |
1213 | |||
1214 | audit_log_format(ab, | 1214 | audit_log_format(ab, |
1215 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" | 1215 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" |
1216 | " ppid=%d pid=%d auid=%u uid=%u gid=%u" | 1216 | " ppid=%d pid=%d auid=%u uid=%u gid=%u" |
@@ -1230,7 +1230,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1230 | context->egid, context->sgid, context->fsgid, tty, | 1230 | context->egid, context->sgid, context->fsgid, tty, |
1231 | tsk->sessionid); | 1231 | tsk->sessionid); |
1232 | 1232 | ||
1233 | mutex_unlock(&tty_mutex); | ||
1234 | 1233 | ||
1235 | audit_log_task_info(ab, tsk); | 1234 | audit_log_task_info(ab, tsk); |
1236 | if (context->filterkey) { | 1235 | if (context->filterkey) { |
diff --git a/kernel/fork.c b/kernel/fork.c index 7ce2ebe84796..30de644a40c4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -802,6 +802,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
802 | 802 | ||
803 | sig->leader = 0; /* session leadership doesn't inherit */ | 803 | sig->leader = 0; /* session leadership doesn't inherit */ |
804 | sig->tty_old_pgrp = NULL; | 804 | sig->tty_old_pgrp = NULL; |
805 | sig->tty = NULL; | ||
805 | 806 | ||
806 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; | 807 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; |
807 | sig->gtime = cputime_zero; | 808 | sig->gtime = cputime_zero; |
@@ -838,6 +839,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
838 | void __cleanup_signal(struct signal_struct *sig) | 839 | void __cleanup_signal(struct signal_struct *sig) |
839 | { | 840 | { |
840 | exit_thread_group_keys(sig); | 841 | exit_thread_group_keys(sig); |
842 | tty_kref_put(sig->tty); | ||
841 | kmem_cache_free(signal_cachep, sig); | 843 | kmem_cache_free(signal_cachep, sig); |
842 | } | 844 | } |
843 | 845 | ||
@@ -1227,7 +1229,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1227 | p->nsproxy->pid_ns->child_reaper = p; | 1229 | p->nsproxy->pid_ns->child_reaper = p; |
1228 | 1230 | ||
1229 | p->signal->leader_pid = pid; | 1231 | p->signal->leader_pid = pid; |
1230 | p->signal->tty = current->signal->tty; | 1232 | tty_kref_put(p->signal->tty); |
1233 | p->signal->tty = tty_kref_get(current->signal->tty); | ||
1231 | set_task_pgrp(p, task_pgrp_nr(current)); | 1234 | set_task_pgrp(p, task_pgrp_nr(current)); |
1232 | set_task_session(p, task_session_nr(current)); | 1235 | set_task_session(p, task_session_nr(current)); |
1233 | attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); | 1236 | attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); |
diff --git a/kernel/printk.c b/kernel/printk.c index b51b1567bb55..a430fd04008b 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -1291,22 +1291,6 @@ static int __init disable_boot_consoles(void) | |||
1291 | } | 1291 | } |
1292 | late_initcall(disable_boot_consoles); | 1292 | late_initcall(disable_boot_consoles); |
1293 | 1293 | ||
1294 | /** | ||
1295 | * tty_write_message - write a message to a certain tty, not just the console. | ||
1296 | * @tty: the destination tty_struct | ||
1297 | * @msg: the message to write | ||
1298 | * | ||
1299 | * This is used for messages that need to be redirected to a specific tty. | ||
1300 | * We don't put it into the syslog queue right now maybe in the future if | ||
1301 | * really needed. | ||
1302 | */ | ||
1303 | void tty_write_message(struct tty_struct *tty, char *msg) | ||
1304 | { | ||
1305 | if (tty && tty->ops->write) | ||
1306 | tty->ops->write(tty, msg, strlen(msg)); | ||
1307 | return; | ||
1308 | } | ||
1309 | |||
1310 | #if defined CONFIG_PRINTK | 1294 | #if defined CONFIG_PRINTK |
1311 | 1295 | ||
1312 | /* | 1296 | /* |
diff --git a/kernel/sys.c b/kernel/sys.c index 038a7bc0901d..234d9454294e 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1060,9 +1060,7 @@ asmlinkage long sys_setsid(void) | |||
1060 | group_leader->signal->leader = 1; | 1060 | group_leader->signal->leader = 1; |
1061 | __set_special_pids(sid); | 1061 | __set_special_pids(sid); |
1062 | 1062 | ||
1063 | spin_lock(&group_leader->sighand->siglock); | 1063 | proc_clear_tty(group_leader); |
1064 | group_leader->signal->tty = NULL; | ||
1065 | spin_unlock(&group_leader->sighand->siglock); | ||
1066 | 1064 | ||
1067 | err = session; | 1065 | err = session; |
1068 | out: | 1066 | out: |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4a7374c12d9c..48881394fbd4 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2121,7 +2121,6 @@ static inline void flush_unauthorized_files(struct files_struct *files) | |||
2121 | long j = -1; | 2121 | long j = -1; |
2122 | int drop_tty = 0; | 2122 | int drop_tty = 0; |
2123 | 2123 | ||
2124 | mutex_lock(&tty_mutex); | ||
2125 | tty = get_current_tty(); | 2124 | tty = get_current_tty(); |
2126 | if (tty) { | 2125 | if (tty) { |
2127 | file_list_lock(); | 2126 | file_list_lock(); |
@@ -2139,8 +2138,8 @@ static inline void flush_unauthorized_files(struct files_struct *files) | |||
2139 | } | 2138 | } |
2140 | } | 2139 | } |
2141 | file_list_unlock(); | 2140 | file_list_unlock(); |
2141 | tty_kref_put(tty); | ||
2142 | } | 2142 | } |
2143 | mutex_unlock(&tty_mutex); | ||
2144 | /* Reset controlling tty. */ | 2143 | /* Reset controlling tty. */ |
2145 | if (drop_tty) | 2144 | if (drop_tty) |
2146 | no_tty(); | 2145 | no_tty(); |