Commit bbbce516bb497404315c1d0a1b13a04038347d3d
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'tty-4.0-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial fixes from Greg KH: "Here are some tty and serial driver fixes for 4.0-rc3. Along with the atime fix that you know about, here are some other serial driver bugfixes as well. Most notable is a wait_until_sent bugfix that was traced back to being around since before 2.6.12 that Johan has fixed up. All have been in linux-next successfully" * tag 'tty-4.0-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: TTY: fix tty_wait_until_sent maximum timeout TTY: fix tty_wait_until_sent on 64-bit machines USB: serial: fix infinite wait_until_sent timeout TTY: bfin_jtag_comm: remove incorrect wait_until_sent operation net: irda: fix wait_until_sent poll timeout serial: uapi: Declare all userspace-visible io types serial: core: Fix iotype userspace breakage serial: sprd: Fix missing spin_unlock in sprd_handle_irq() console: Fix console name size mismatch tty: fix up atime/mtime mess, take four serial: 8250_dw: Fix get_mctrl behaviour serial:8250:8250_pci: delete unneeded quirk entries serial:8250:8250_pci: fix redundant entry report for WCH_CH352_2S Change email address for 8250_pci serial: 8250: Revert "tty: serial: 8250_core: read only RX if there is something in the FIFO" Revert "tty/serial: of_serial: add DT alias ID handling"
Showing 15 changed files Inline Diff
- Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt
- drivers/tty/bfin_jtag_comm.c
- drivers/tty/serial/8250/8250_core.c
- drivers/tty/serial/8250/8250_dw.c
- drivers/tty/serial/8250/8250_pci.c
- drivers/tty/serial/of_serial.c
- drivers/tty/serial/sprd_serial.c
- drivers/tty/tty_io.c
- drivers/tty/tty_ioctl.c
- drivers/usb/serial/generic.c
- include/linux/serial_core.h
- include/uapi/linux/serial.h
- kernel/printk/console_cmdline.h
- kernel/printk/printk.c
- net/irda/ircomm/ircomm_tty.c
Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt
1 | * Synopsys DesignWare ABP UART | 1 | * Synopsys DesignWare ABP UART |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible : "snps,dw-apb-uart" | 4 | - compatible : "snps,dw-apb-uart" |
5 | - reg : offset and length of the register set for the device. | 5 | - reg : offset and length of the register set for the device. |
6 | - interrupts : should contain uart interrupt. | 6 | - interrupts : should contain uart interrupt. |
7 | 7 | ||
8 | Clock handling: | 8 | Clock handling: |
9 | The clock rate of the input clock needs to be supplied by one of | 9 | The clock rate of the input clock needs to be supplied by one of |
10 | - clock-frequency : the input clock frequency for the UART. | 10 | - clock-frequency : the input clock frequency for the UART. |
11 | - clocks : phandle to the input clock | 11 | - clocks : phandle to the input clock |
12 | 12 | ||
13 | The supplying peripheral clock can also be handled, needing a second property | 13 | The supplying peripheral clock can also be handled, needing a second property |
14 | - clock-names: tuple listing input clock names. | 14 | - clock-names: tuple listing input clock names. |
15 | Required elements: "baudclk", "apb_pclk" | 15 | Required elements: "baudclk", "apb_pclk" |
16 | 16 | ||
17 | Optional properties: | 17 | Optional properties: |
18 | - resets : phandle to the parent reset controller. | 18 | - resets : phandle to the parent reset controller. |
19 | - reg-shift : quantity to shift the register offsets by. If this property is | 19 | - reg-shift : quantity to shift the register offsets by. If this property is |
20 | not present then the register offsets are not shifted. | 20 | not present then the register offsets are not shifted. |
21 | - reg-io-width : the size (in bytes) of the IO accesses that should be | 21 | - reg-io-width : the size (in bytes) of the IO accesses that should be |
22 | performed on the device. If this property is not present then single byte | 22 | performed on the device. If this property is not present then single byte |
23 | accesses are used. | 23 | accesses are used. |
24 | - dcd-override : Override the DCD modem status signal. This signal will always | ||
25 | be reported as active instead of being obtained from the modem status | ||
26 | register. Define this if your serial port does not use this pin. | ||
27 | - dsr-override : Override the DTS modem status signal. This signal will always | ||
28 | be reported as active instead of being obtained from the modem status | ||
29 | register. Define this if your serial port does not use this pin. | ||
30 | - cts-override : Override the CTS modem status signal. This signal will always | ||
31 | be reported as active instead of being obtained from the modem status | ||
32 | register. Define this if your serial port does not use this pin. | ||
33 | - ri-override : Override the RI modem status signal. This signal will always be | ||
34 | reported as inactive instead of being obtained from the modem status register. | ||
35 | Define this if your serial port does not use this pin. | ||
24 | 36 | ||
25 | Example: | 37 | Example: |
26 | 38 | ||
27 | uart@80230000 { | 39 | uart@80230000 { |
28 | compatible = "snps,dw-apb-uart"; | 40 | compatible = "snps,dw-apb-uart"; |
29 | reg = <0x80230000 0x100>; | 41 | reg = <0x80230000 0x100>; |
30 | clock-frequency = <3686400>; | 42 | clock-frequency = <3686400>; |
31 | interrupts = <10>; | 43 | interrupts = <10>; |
32 | reg-shift = <2>; | 44 | reg-shift = <2>; |
33 | reg-io-width = <4>; | 45 | reg-io-width = <4>; |
46 | dcd-override; | ||
47 | dsr-override; | ||
48 | cts-override; | ||
49 | ri-override; | ||
34 | }; | 50 | }; |
35 | 51 | ||
36 | Example with one clock: | 52 | Example with one clock: |
37 | 53 | ||
38 | uart@80230000 { | 54 | uart@80230000 { |
39 | compatible = "snps,dw-apb-uart"; | 55 | compatible = "snps,dw-apb-uart"; |
40 | reg = <0x80230000 0x100>; | 56 | reg = <0x80230000 0x100>; |
41 | clocks = <&baudclk>; | 57 | clocks = <&baudclk>; |
42 | interrupts = <10>; | 58 | interrupts = <10>; |
43 | reg-shift = <2>; | 59 | reg-shift = <2>; |
44 | reg-io-width = <4>; | 60 | reg-io-width = <4>; |
45 | }; | 61 | }; |
46 | 62 | ||
47 | Example with two clocks: | 63 | Example with two clocks: |
48 | 64 | ||
49 | uart@80230000 { | 65 | uart@80230000 { |
50 | compatible = "snps,dw-apb-uart"; | 66 | compatible = "snps,dw-apb-uart"; |
51 | reg = <0x80230000 0x100>; | 67 | reg = <0x80230000 0x100>; |
52 | clocks = <&baudclk>, <&apb_pclk>; | 68 | clocks = <&baudclk>, <&apb_pclk>; |
53 | clock-names = "baudclk", "apb_pclk"; | 69 | clock-names = "baudclk", "apb_pclk"; |
54 | interrupts = <10>; | 70 | interrupts = <10>; |
55 | reg-shift = <2>; | 71 | reg-shift = <2>; |
56 | reg-io-width = <4>; | 72 | reg-io-width = <4>; |
57 | }; | 73 | }; |
58 | 74 |
drivers/tty/bfin_jtag_comm.c
1 | /* | 1 | /* |
2 | * TTY over Blackfin JTAG Communication | 2 | * TTY over Blackfin JTAG Communication |
3 | * | 3 | * |
4 | * Copyright 2008-2009 Analog Devices Inc. | 4 | * Copyright 2008-2009 Analog Devices Inc. |
5 | * | 5 | * |
6 | * Enter bugs at http://blackfin.uclinux.org/ | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
7 | * | 7 | * |
8 | * Licensed under the GPL-2 or later. | 8 | * Licensed under the GPL-2 or later. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define DRV_NAME "bfin-jtag-comm" | 11 | #define DRV_NAME "bfin-jtag-comm" |
12 | #define DEV_NAME "ttyBFJC" | 12 | #define DEV_NAME "ttyBFJC" |
13 | #define pr_fmt(fmt) DRV_NAME ": " fmt | 13 | #define pr_fmt(fmt) DRV_NAME ": " fmt |
14 | 14 | ||
15 | #include <linux/circ_buf.h> | 15 | #include <linux/circ_buf.h> |
16 | #include <linux/console.h> | 16 | #include <linux/console.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/kthread.h> | 20 | #include <linux/kthread.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/tty.h> | 25 | #include <linux/tty.h> |
26 | #include <linux/tty_driver.h> | 26 | #include <linux/tty_driver.h> |
27 | #include <linux/tty_flip.h> | 27 | #include <linux/tty_flip.h> |
28 | #include <linux/atomic.h> | 28 | #include <linux/atomic.h> |
29 | 29 | ||
30 | #define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); }) | 30 | #define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); }) |
31 | 31 | ||
32 | /* See the Debug/Emulation chapter in the HRM */ | 32 | /* See the Debug/Emulation chapter in the HRM */ |
33 | #define EMUDOF 0x00000001 /* EMUDAT_OUT full & valid */ | 33 | #define EMUDOF 0x00000001 /* EMUDAT_OUT full & valid */ |
34 | #define EMUDIF 0x00000002 /* EMUDAT_IN full & valid */ | 34 | #define EMUDIF 0x00000002 /* EMUDAT_IN full & valid */ |
35 | #define EMUDOOVF 0x00000004 /* EMUDAT_OUT overflow */ | 35 | #define EMUDOOVF 0x00000004 /* EMUDAT_OUT overflow */ |
36 | #define EMUDIOVF 0x00000008 /* EMUDAT_IN overflow */ | 36 | #define EMUDIOVF 0x00000008 /* EMUDAT_IN overflow */ |
37 | 37 | ||
38 | static inline uint32_t bfin_write_emudat(uint32_t emudat) | 38 | static inline uint32_t bfin_write_emudat(uint32_t emudat) |
39 | { | 39 | { |
40 | __asm__ __volatile__("emudat = %0;" : : "d"(emudat)); | 40 | __asm__ __volatile__("emudat = %0;" : : "d"(emudat)); |
41 | return emudat; | 41 | return emudat; |
42 | } | 42 | } |
43 | 43 | ||
44 | static inline uint32_t bfin_read_emudat(void) | 44 | static inline uint32_t bfin_read_emudat(void) |
45 | { | 45 | { |
46 | uint32_t emudat; | 46 | uint32_t emudat; |
47 | __asm__ __volatile__("%0 = emudat;" : "=d"(emudat)); | 47 | __asm__ __volatile__("%0 = emudat;" : "=d"(emudat)); |
48 | return emudat; | 48 | return emudat; |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline uint32_t bfin_write_emudat_chars(char a, char b, char c, char d) | 51 | static inline uint32_t bfin_write_emudat_chars(char a, char b, char c, char d) |
52 | { | 52 | { |
53 | return bfin_write_emudat((a << 0) | (b << 8) | (c << 16) | (d << 24)); | 53 | return bfin_write_emudat((a << 0) | (b << 8) | (c << 16) | (d << 24)); |
54 | } | 54 | } |
55 | 55 | ||
56 | #define CIRC_SIZE 2048 /* see comment in tty_io.c:do_tty_write() */ | 56 | #define CIRC_SIZE 2048 /* see comment in tty_io.c:do_tty_write() */ |
57 | #define CIRC_MASK (CIRC_SIZE - 1) | 57 | #define CIRC_MASK (CIRC_SIZE - 1) |
58 | #define circ_empty(circ) ((circ)->head == (circ)->tail) | 58 | #define circ_empty(circ) ((circ)->head == (circ)->tail) |
59 | #define circ_free(circ) CIRC_SPACE((circ)->head, (circ)->tail, CIRC_SIZE) | 59 | #define circ_free(circ) CIRC_SPACE((circ)->head, (circ)->tail, CIRC_SIZE) |
60 | #define circ_cnt(circ) CIRC_CNT((circ)->head, (circ)->tail, CIRC_SIZE) | 60 | #define circ_cnt(circ) CIRC_CNT((circ)->head, (circ)->tail, CIRC_SIZE) |
61 | #define circ_byte(circ, idx) ((circ)->buf[(idx) & CIRC_MASK]) | 61 | #define circ_byte(circ, idx) ((circ)->buf[(idx) & CIRC_MASK]) |
62 | 62 | ||
63 | static struct tty_driver *bfin_jc_driver; | 63 | static struct tty_driver *bfin_jc_driver; |
64 | static struct task_struct *bfin_jc_kthread; | 64 | static struct task_struct *bfin_jc_kthread; |
65 | static struct tty_port port; | 65 | static struct tty_port port; |
66 | static volatile struct circ_buf bfin_jc_write_buf; | 66 | static volatile struct circ_buf bfin_jc_write_buf; |
67 | 67 | ||
68 | static int | 68 | static int |
69 | bfin_jc_emudat_manager(void *arg) | 69 | bfin_jc_emudat_manager(void *arg) |
70 | { | 70 | { |
71 | uint32_t inbound_len = 0, outbound_len = 0; | 71 | uint32_t inbound_len = 0, outbound_len = 0; |
72 | 72 | ||
73 | while (!kthread_should_stop()) { | 73 | while (!kthread_should_stop()) { |
74 | struct tty_struct *tty = tty_port_tty_get(&port); | 74 | struct tty_struct *tty = tty_port_tty_get(&port); |
75 | /* no one left to give data to, so sleep */ | 75 | /* no one left to give data to, so sleep */ |
76 | if (tty == NULL && circ_empty(&bfin_jc_write_buf)) { | 76 | if (tty == NULL && circ_empty(&bfin_jc_write_buf)) { |
77 | pr_debug("waiting for readers\n"); | 77 | pr_debug("waiting for readers\n"); |
78 | __set_current_state(TASK_UNINTERRUPTIBLE); | 78 | __set_current_state(TASK_UNINTERRUPTIBLE); |
79 | schedule(); | 79 | schedule(); |
80 | continue; | 80 | continue; |
81 | } | 81 | } |
82 | 82 | ||
83 | /* no data available, so just chill */ | 83 | /* no data available, so just chill */ |
84 | if (!(bfin_read_DBGSTAT() & EMUDIF) && circ_empty(&bfin_jc_write_buf)) { | 84 | if (!(bfin_read_DBGSTAT() & EMUDIF) && circ_empty(&bfin_jc_write_buf)) { |
85 | pr_debug("waiting for data (in_len = %i) (circ: %i %i)\n", | 85 | pr_debug("waiting for data (in_len = %i) (circ: %i %i)\n", |
86 | inbound_len, bfin_jc_write_buf.tail, bfin_jc_write_buf.head); | 86 | inbound_len, bfin_jc_write_buf.tail, bfin_jc_write_buf.head); |
87 | tty_kref_put(tty); | 87 | tty_kref_put(tty); |
88 | if (inbound_len) | 88 | if (inbound_len) |
89 | schedule(); | 89 | schedule(); |
90 | else | 90 | else |
91 | schedule_timeout_interruptible(HZ); | 91 | schedule_timeout_interruptible(HZ); |
92 | continue; | 92 | continue; |
93 | } | 93 | } |
94 | 94 | ||
95 | /* if incoming data is ready, eat it */ | 95 | /* if incoming data is ready, eat it */ |
96 | if (bfin_read_DBGSTAT() & EMUDIF) { | 96 | if (bfin_read_DBGSTAT() & EMUDIF) { |
97 | uint32_t emudat = bfin_read_emudat(); | 97 | uint32_t emudat = bfin_read_emudat(); |
98 | if (inbound_len == 0) { | 98 | if (inbound_len == 0) { |
99 | pr_debug("incoming length: 0x%08x\n", emudat); | 99 | pr_debug("incoming length: 0x%08x\n", emudat); |
100 | inbound_len = emudat; | 100 | inbound_len = emudat; |
101 | } else { | 101 | } else { |
102 | size_t num_chars = (4 <= inbound_len ? 4 : inbound_len); | 102 | size_t num_chars = (4 <= inbound_len ? 4 : inbound_len); |
103 | pr_debug(" incoming data: 0x%08x (pushing %zu)\n", emudat, num_chars); | 103 | pr_debug(" incoming data: 0x%08x (pushing %zu)\n", emudat, num_chars); |
104 | inbound_len -= num_chars; | 104 | inbound_len -= num_chars; |
105 | tty_insert_flip_string(&port, (unsigned char *)&emudat, num_chars); | 105 | tty_insert_flip_string(&port, (unsigned char *)&emudat, num_chars); |
106 | tty_flip_buffer_push(&port); | 106 | tty_flip_buffer_push(&port); |
107 | } | 107 | } |
108 | } | 108 | } |
109 | 109 | ||
110 | /* if outgoing data is ready, post it */ | 110 | /* if outgoing data is ready, post it */ |
111 | if (!(bfin_read_DBGSTAT() & EMUDOF) && !circ_empty(&bfin_jc_write_buf)) { | 111 | if (!(bfin_read_DBGSTAT() & EMUDOF) && !circ_empty(&bfin_jc_write_buf)) { |
112 | if (outbound_len == 0) { | 112 | if (outbound_len == 0) { |
113 | outbound_len = circ_cnt(&bfin_jc_write_buf); | 113 | outbound_len = circ_cnt(&bfin_jc_write_buf); |
114 | bfin_write_emudat(outbound_len); | 114 | bfin_write_emudat(outbound_len); |
115 | pr_debug("outgoing length: 0x%08x\n", outbound_len); | 115 | pr_debug("outgoing length: 0x%08x\n", outbound_len); |
116 | } else { | 116 | } else { |
117 | int tail = bfin_jc_write_buf.tail; | 117 | int tail = bfin_jc_write_buf.tail; |
118 | size_t ate = (4 <= outbound_len ? 4 : outbound_len); | 118 | size_t ate = (4 <= outbound_len ? 4 : outbound_len); |
119 | uint32_t emudat = | 119 | uint32_t emudat = |
120 | bfin_write_emudat_chars( | 120 | bfin_write_emudat_chars( |
121 | circ_byte(&bfin_jc_write_buf, tail + 0), | 121 | circ_byte(&bfin_jc_write_buf, tail + 0), |
122 | circ_byte(&bfin_jc_write_buf, tail + 1), | 122 | circ_byte(&bfin_jc_write_buf, tail + 1), |
123 | circ_byte(&bfin_jc_write_buf, tail + 2), | 123 | circ_byte(&bfin_jc_write_buf, tail + 2), |
124 | circ_byte(&bfin_jc_write_buf, tail + 3) | 124 | circ_byte(&bfin_jc_write_buf, tail + 3) |
125 | ); | 125 | ); |
126 | bfin_jc_write_buf.tail += ate; | 126 | bfin_jc_write_buf.tail += ate; |
127 | outbound_len -= ate; | 127 | outbound_len -= ate; |
128 | if (tty) | 128 | if (tty) |
129 | tty_wakeup(tty); | 129 | tty_wakeup(tty); |
130 | pr_debug(" outgoing data: 0x%08x (pushing %zu)\n", emudat, ate); | 130 | pr_debug(" outgoing data: 0x%08x (pushing %zu)\n", emudat, ate); |
131 | } | 131 | } |
132 | } | 132 | } |
133 | tty_kref_put(tty); | 133 | tty_kref_put(tty); |
134 | } | 134 | } |
135 | 135 | ||
136 | __set_current_state(TASK_RUNNING); | 136 | __set_current_state(TASK_RUNNING); |
137 | return 0; | 137 | return 0; |
138 | } | 138 | } |
139 | 139 | ||
140 | static int | 140 | static int |
141 | bfin_jc_open(struct tty_struct *tty, struct file *filp) | 141 | bfin_jc_open(struct tty_struct *tty, struct file *filp) |
142 | { | 142 | { |
143 | unsigned long flags; | 143 | unsigned long flags; |
144 | 144 | ||
145 | spin_lock_irqsave(&port.lock, flags); | 145 | spin_lock_irqsave(&port.lock, flags); |
146 | port.count++; | 146 | port.count++; |
147 | spin_unlock_irqrestore(&port.lock, flags); | 147 | spin_unlock_irqrestore(&port.lock, flags); |
148 | tty_port_tty_set(&port, tty); | 148 | tty_port_tty_set(&port, tty); |
149 | wake_up_process(bfin_jc_kthread); | 149 | wake_up_process(bfin_jc_kthread); |
150 | return 0; | 150 | return 0; |
151 | } | 151 | } |
152 | 152 | ||
153 | static void | 153 | static void |
154 | bfin_jc_close(struct tty_struct *tty, struct file *filp) | 154 | bfin_jc_close(struct tty_struct *tty, struct file *filp) |
155 | { | 155 | { |
156 | unsigned long flags; | 156 | unsigned long flags; |
157 | bool last; | 157 | bool last; |
158 | 158 | ||
159 | spin_lock_irqsave(&port.lock, flags); | 159 | spin_lock_irqsave(&port.lock, flags); |
160 | last = --port.count == 0; | 160 | last = --port.count == 0; |
161 | spin_unlock_irqrestore(&port.lock, flags); | 161 | spin_unlock_irqrestore(&port.lock, flags); |
162 | if (last) | 162 | if (last) |
163 | tty_port_tty_set(&port, NULL); | 163 | tty_port_tty_set(&port, NULL); |
164 | wake_up_process(bfin_jc_kthread); | 164 | wake_up_process(bfin_jc_kthread); |
165 | } | 165 | } |
166 | 166 | ||
167 | /* XXX: we dont handle the put_char() case where we must handle count = 1 */ | 167 | /* XXX: we dont handle the put_char() case where we must handle count = 1 */ |
168 | static int | 168 | static int |
169 | bfin_jc_circ_write(const unsigned char *buf, int count) | 169 | bfin_jc_circ_write(const unsigned char *buf, int count) |
170 | { | 170 | { |
171 | int i; | 171 | int i; |
172 | count = min(count, circ_free(&bfin_jc_write_buf)); | 172 | count = min(count, circ_free(&bfin_jc_write_buf)); |
173 | pr_debug("going to write chunk of %i bytes\n", count); | 173 | pr_debug("going to write chunk of %i bytes\n", count); |
174 | for (i = 0; i < count; ++i) | 174 | for (i = 0; i < count; ++i) |
175 | circ_byte(&bfin_jc_write_buf, bfin_jc_write_buf.head + i) = buf[i]; | 175 | circ_byte(&bfin_jc_write_buf, bfin_jc_write_buf.head + i) = buf[i]; |
176 | bfin_jc_write_buf.head += i; | 176 | bfin_jc_write_buf.head += i; |
177 | return i; | 177 | return i; |
178 | } | 178 | } |
179 | 179 | ||
180 | #ifndef CONFIG_BFIN_JTAG_COMM_CONSOLE | 180 | #ifndef CONFIG_BFIN_JTAG_COMM_CONSOLE |
181 | # define console_lock() | 181 | # define console_lock() |
182 | # define console_unlock() | 182 | # define console_unlock() |
183 | #endif | 183 | #endif |
184 | static int | 184 | static int |
185 | bfin_jc_write(struct tty_struct *tty, const unsigned char *buf, int count) | 185 | bfin_jc_write(struct tty_struct *tty, const unsigned char *buf, int count) |
186 | { | 186 | { |
187 | int i; | 187 | int i; |
188 | console_lock(); | 188 | console_lock(); |
189 | i = bfin_jc_circ_write(buf, count); | 189 | i = bfin_jc_circ_write(buf, count); |
190 | console_unlock(); | 190 | console_unlock(); |
191 | wake_up_process(bfin_jc_kthread); | 191 | wake_up_process(bfin_jc_kthread); |
192 | return i; | 192 | return i; |
193 | } | 193 | } |
194 | 194 | ||
195 | static void | 195 | static void |
196 | bfin_jc_flush_chars(struct tty_struct *tty) | 196 | bfin_jc_flush_chars(struct tty_struct *tty) |
197 | { | 197 | { |
198 | wake_up_process(bfin_jc_kthread); | 198 | wake_up_process(bfin_jc_kthread); |
199 | } | 199 | } |
200 | 200 | ||
201 | static int | 201 | static int |
202 | bfin_jc_write_room(struct tty_struct *tty) | 202 | bfin_jc_write_room(struct tty_struct *tty) |
203 | { | 203 | { |
204 | return circ_free(&bfin_jc_write_buf); | 204 | return circ_free(&bfin_jc_write_buf); |
205 | } | 205 | } |
206 | 206 | ||
207 | static int | 207 | static int |
208 | bfin_jc_chars_in_buffer(struct tty_struct *tty) | 208 | bfin_jc_chars_in_buffer(struct tty_struct *tty) |
209 | { | 209 | { |
210 | return circ_cnt(&bfin_jc_write_buf); | 210 | return circ_cnt(&bfin_jc_write_buf); |
211 | } | 211 | } |
212 | 212 | ||
213 | static void | ||
214 | bfin_jc_wait_until_sent(struct tty_struct *tty, int timeout) | ||
215 | { | ||
216 | unsigned long expire = jiffies + timeout; | ||
217 | while (!circ_empty(&bfin_jc_write_buf)) { | ||
218 | if (signal_pending(current)) | ||
219 | break; | ||
220 | if (time_after(jiffies, expire)) | ||
221 | break; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | static const struct tty_operations bfin_jc_ops = { | 213 | static const struct tty_operations bfin_jc_ops = { |
226 | .open = bfin_jc_open, | 214 | .open = bfin_jc_open, |
227 | .close = bfin_jc_close, | 215 | .close = bfin_jc_close, |
228 | .write = bfin_jc_write, | 216 | .write = bfin_jc_write, |
229 | /*.put_char = bfin_jc_put_char,*/ | 217 | /*.put_char = bfin_jc_put_char,*/ |
230 | .flush_chars = bfin_jc_flush_chars, | 218 | .flush_chars = bfin_jc_flush_chars, |
231 | .write_room = bfin_jc_write_room, | 219 | .write_room = bfin_jc_write_room, |
232 | .chars_in_buffer = bfin_jc_chars_in_buffer, | 220 | .chars_in_buffer = bfin_jc_chars_in_buffer, |
233 | .wait_until_sent = bfin_jc_wait_until_sent, | ||
234 | }; | 221 | }; |
235 | 222 | ||
236 | static int __init bfin_jc_init(void) | 223 | static int __init bfin_jc_init(void) |
237 | { | 224 | { |
238 | int ret; | 225 | int ret; |
239 | 226 | ||
240 | bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME); | 227 | bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME); |
241 | if (IS_ERR(bfin_jc_kthread)) | 228 | if (IS_ERR(bfin_jc_kthread)) |
242 | return PTR_ERR(bfin_jc_kthread); | 229 | return PTR_ERR(bfin_jc_kthread); |
243 | 230 | ||
244 | ret = -ENOMEM; | 231 | ret = -ENOMEM; |
245 | 232 | ||
246 | bfin_jc_write_buf.head = bfin_jc_write_buf.tail = 0; | 233 | bfin_jc_write_buf.head = bfin_jc_write_buf.tail = 0; |
247 | bfin_jc_write_buf.buf = kmalloc(CIRC_SIZE, GFP_KERNEL); | 234 | bfin_jc_write_buf.buf = kmalloc(CIRC_SIZE, GFP_KERNEL); |
248 | if (!bfin_jc_write_buf.buf) | 235 | if (!bfin_jc_write_buf.buf) |
249 | goto err_buf; | 236 | goto err_buf; |
250 | 237 | ||
251 | bfin_jc_driver = alloc_tty_driver(1); | 238 | bfin_jc_driver = alloc_tty_driver(1); |
252 | if (!bfin_jc_driver) | 239 | if (!bfin_jc_driver) |
253 | goto err_driver; | 240 | goto err_driver; |
254 | 241 | ||
255 | tty_port_init(&port); | 242 | tty_port_init(&port); |
256 | 243 | ||
257 | bfin_jc_driver->driver_name = DRV_NAME; | 244 | bfin_jc_driver->driver_name = DRV_NAME; |
258 | bfin_jc_driver->name = DEV_NAME; | 245 | bfin_jc_driver->name = DEV_NAME; |
259 | bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL; | 246 | bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL; |
260 | bfin_jc_driver->subtype = SERIAL_TYPE_NORMAL; | 247 | bfin_jc_driver->subtype = SERIAL_TYPE_NORMAL; |
261 | bfin_jc_driver->init_termios = tty_std_termios; | 248 | bfin_jc_driver->init_termios = tty_std_termios; |
262 | tty_set_operations(bfin_jc_driver, &bfin_jc_ops); | 249 | tty_set_operations(bfin_jc_driver, &bfin_jc_ops); |
263 | tty_port_link_device(&port, bfin_jc_driver, 0); | 250 | tty_port_link_device(&port, bfin_jc_driver, 0); |
264 | 251 | ||
265 | ret = tty_register_driver(bfin_jc_driver); | 252 | ret = tty_register_driver(bfin_jc_driver); |
266 | if (ret) | 253 | if (ret) |
267 | goto err; | 254 | goto err; |
268 | 255 | ||
269 | pr_init(KERN_INFO DRV_NAME ": initialized\n"); | 256 | pr_init(KERN_INFO DRV_NAME ": initialized\n"); |
270 | 257 | ||
271 | return 0; | 258 | return 0; |
272 | 259 | ||
273 | err: | 260 | err: |
274 | tty_port_destroy(&port); | 261 | tty_port_destroy(&port); |
275 | put_tty_driver(bfin_jc_driver); | 262 | put_tty_driver(bfin_jc_driver); |
276 | err_driver: | 263 | err_driver: |
277 | kfree(bfin_jc_write_buf.buf); | 264 | kfree(bfin_jc_write_buf.buf); |
278 | err_buf: | 265 | err_buf: |
279 | kthread_stop(bfin_jc_kthread); | 266 | kthread_stop(bfin_jc_kthread); |
280 | return ret; | 267 | return ret; |
281 | } | 268 | } |
282 | module_init(bfin_jc_init); | 269 | module_init(bfin_jc_init); |
283 | 270 | ||
284 | static void __exit bfin_jc_exit(void) | 271 | static void __exit bfin_jc_exit(void) |
285 | { | 272 | { |
286 | kthread_stop(bfin_jc_kthread); | 273 | kthread_stop(bfin_jc_kthread); |
287 | kfree(bfin_jc_write_buf.buf); | 274 | kfree(bfin_jc_write_buf.buf); |
288 | tty_unregister_driver(bfin_jc_driver); | 275 | tty_unregister_driver(bfin_jc_driver); |
289 | put_tty_driver(bfin_jc_driver); | 276 | put_tty_driver(bfin_jc_driver); |
290 | tty_port_destroy(&port); | 277 | tty_port_destroy(&port); |
291 | } | 278 | } |
292 | module_exit(bfin_jc_exit); | 279 | module_exit(bfin_jc_exit); |
293 | 280 | ||
294 | #if defined(CONFIG_BFIN_JTAG_COMM_CONSOLE) || defined(CONFIG_EARLY_PRINTK) | 281 | #if defined(CONFIG_BFIN_JTAG_COMM_CONSOLE) || defined(CONFIG_EARLY_PRINTK) |
295 | static void | 282 | static void |
296 | bfin_jc_straight_buffer_write(const char *buf, unsigned count) | 283 | bfin_jc_straight_buffer_write(const char *buf, unsigned count) |
297 | { | 284 | { |
298 | unsigned ate = 0; | 285 | unsigned ate = 0; |
299 | while (bfin_read_DBGSTAT() & EMUDOF) | 286 | while (bfin_read_DBGSTAT() & EMUDOF) |
300 | continue; | 287 | continue; |
301 | bfin_write_emudat(count); | 288 | bfin_write_emudat(count); |
302 | while (ate < count) { | 289 | while (ate < count) { |
303 | while (bfin_read_DBGSTAT() & EMUDOF) | 290 | while (bfin_read_DBGSTAT() & EMUDOF) |
304 | continue; | 291 | continue; |
305 | bfin_write_emudat_chars(buf[ate], buf[ate+1], buf[ate+2], buf[ate+3]); | 292 | bfin_write_emudat_chars(buf[ate], buf[ate+1], buf[ate+2], buf[ate+3]); |
306 | ate += 4; | 293 | ate += 4; |
307 | } | 294 | } |
308 | } | 295 | } |
309 | #endif | 296 | #endif |
310 | 297 | ||
311 | #ifdef CONFIG_BFIN_JTAG_COMM_CONSOLE | 298 | #ifdef CONFIG_BFIN_JTAG_COMM_CONSOLE |
312 | static void | 299 | static void |
313 | bfin_jc_console_write(struct console *co, const char *buf, unsigned count) | 300 | bfin_jc_console_write(struct console *co, const char *buf, unsigned count) |
314 | { | 301 | { |
315 | if (bfin_jc_kthread == NULL) | 302 | if (bfin_jc_kthread == NULL) |
316 | bfin_jc_straight_buffer_write(buf, count); | 303 | bfin_jc_straight_buffer_write(buf, count); |
317 | else | 304 | else |
318 | bfin_jc_circ_write(buf, count); | 305 | bfin_jc_circ_write(buf, count); |
319 | } | 306 | } |
320 | 307 | ||
321 | static struct tty_driver * | 308 | static struct tty_driver * |
322 | bfin_jc_console_device(struct console *co, int *index) | 309 | bfin_jc_console_device(struct console *co, int *index) |
323 | { | 310 | { |
324 | *index = co->index; | 311 | *index = co->index; |
325 | return bfin_jc_driver; | 312 | return bfin_jc_driver; |
326 | } | 313 | } |
327 | 314 | ||
328 | static struct console bfin_jc_console = { | 315 | static struct console bfin_jc_console = { |
329 | .name = DEV_NAME, | 316 | .name = DEV_NAME, |
330 | .write = bfin_jc_console_write, | 317 | .write = bfin_jc_console_write, |
331 | .device = bfin_jc_console_device, | 318 | .device = bfin_jc_console_device, |
332 | .flags = CON_ANYTIME | CON_PRINTBUFFER, | 319 | .flags = CON_ANYTIME | CON_PRINTBUFFER, |
333 | .index = -1, | 320 | .index = -1, |
334 | }; | 321 | }; |
335 | 322 | ||
336 | static int __init bfin_jc_console_init(void) | 323 | static int __init bfin_jc_console_init(void) |
337 | { | 324 | { |
338 | register_console(&bfin_jc_console); | 325 | register_console(&bfin_jc_console); |
339 | return 0; | 326 | return 0; |
340 | } | 327 | } |
341 | console_initcall(bfin_jc_console_init); | 328 | console_initcall(bfin_jc_console_init); |
342 | #endif | 329 | #endif |
343 | 330 | ||
344 | #ifdef CONFIG_EARLY_PRINTK | 331 | #ifdef CONFIG_EARLY_PRINTK |
345 | static void __init | 332 | static void __init |
346 | bfin_jc_early_write(struct console *co, const char *buf, unsigned int count) | 333 | bfin_jc_early_write(struct console *co, const char *buf, unsigned int count) |
347 | { | 334 | { |
348 | bfin_jc_straight_buffer_write(buf, count); | 335 | bfin_jc_straight_buffer_write(buf, count); |
349 | } | 336 | } |
350 | 337 | ||
351 | static struct console bfin_jc_early_console __initdata = { | 338 | static struct console bfin_jc_early_console __initdata = { |
352 | .name = "early_BFJC", | 339 | .name = "early_BFJC", |
353 | .write = bfin_jc_early_write, | 340 | .write = bfin_jc_early_write, |
354 | .flags = CON_ANYTIME | CON_PRINTBUFFER, | 341 | .flags = CON_ANYTIME | CON_PRINTBUFFER, |
355 | .index = -1, | 342 | .index = -1, |
356 | }; | 343 | }; |
357 | 344 | ||
358 | struct console * __init | 345 | struct console * __init |
359 | bfin_jc_early_init(unsigned int port, unsigned int cflag) | 346 | bfin_jc_early_init(unsigned int port, unsigned int cflag) |
360 | { | 347 | { |
361 | return &bfin_jc_early_console; | 348 | return &bfin_jc_early_console; |
362 | } | 349 | } |
363 | #endif | 350 | #endif |
364 | 351 | ||
365 | MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); | 352 | MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); |
366 | MODULE_DESCRIPTION("TTY over Blackfin JTAG Communication"); | 353 | MODULE_DESCRIPTION("TTY over Blackfin JTAG Communication"); |
367 | MODULE_LICENSE("GPL"); | 354 | MODULE_LICENSE("GPL"); |
368 | 355 |
drivers/tty/serial/8250/8250_core.c
1 | /* | 1 | /* |
2 | * Driver for 8250/16550-type serial ports | 2 | * Driver for 8250/16550-type serial ports |
3 | * | 3 | * |
4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
5 | * | 5 | * |
6 | * Copyright (C) 2001 Russell King. | 6 | * Copyright (C) 2001 Russell King. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | * | 12 | * |
13 | * A note about mapbase / membase | 13 | * A note about mapbase / membase |
14 | * | 14 | * |
15 | * mapbase is the physical address of the IO port. | 15 | * mapbase is the physical address of the IO port. |
16 | * membase is an 'ioremapped' cookie. | 16 | * membase is an 'ioremapped' cookie. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 19 | #if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
20 | #define SUPPORT_SYSRQ | 20 | #define SUPPORT_SYSRQ |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/console.h> | 27 | #include <linux/console.h> |
28 | #include <linux/sysrq.h> | 28 | #include <linux/sysrq.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
32 | #include <linux/ratelimit.h> | 32 | #include <linux/ratelimit.h> |
33 | #include <linux/tty_flip.h> | 33 | #include <linux/tty_flip.h> |
34 | #include <linux/serial_core.h> | 34 | #include <linux/serial_core.h> |
35 | #include <linux/serial.h> | 35 | #include <linux/serial.h> |
36 | #include <linux/serial_8250.h> | 36 | #include <linux/serial_8250.h> |
37 | #include <linux/nmi.h> | 37 | #include <linux/nmi.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/uaccess.h> | 40 | #include <linux/uaccess.h> |
41 | #include <linux/pm_runtime.h> | 41 | #include <linux/pm_runtime.h> |
42 | #ifdef CONFIG_SPARC | 42 | #ifdef CONFIG_SPARC |
43 | #include <linux/sunserialcore.h> | 43 | #include <linux/sunserialcore.h> |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #include <asm/io.h> | 46 | #include <asm/io.h> |
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | 48 | ||
49 | #include "8250.h" | 49 | #include "8250.h" |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * Configuration: | 52 | * Configuration: |
53 | * 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 |
54 | * is unsafe when used on edge-triggered interrupts. | 54 | * is unsafe when used on edge-triggered interrupts. |
55 | */ | 55 | */ |
56 | static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; | 56 | static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; |
57 | 57 | ||
58 | static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; | 58 | static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; |
59 | 59 | ||
60 | static struct uart_driver serial8250_reg; | 60 | static struct uart_driver serial8250_reg; |
61 | 61 | ||
62 | static int serial_index(struct uart_port *port) | 62 | static int serial_index(struct uart_port *port) |
63 | { | 63 | { |
64 | return (serial8250_reg.minor - 64) + port->line; | 64 | return (serial8250_reg.minor - 64) + port->line; |
65 | } | 65 | } |
66 | 66 | ||
67 | static unsigned int skip_txen_test; /* force skip of txen test at init time */ | 67 | static unsigned int skip_txen_test; /* force skip of txen test at init time */ |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * Debugging. | 70 | * Debugging. |
71 | */ | 71 | */ |
72 | #if 0 | 72 | #if 0 |
73 | #define DEBUG_AUTOCONF(fmt...) printk(fmt) | 73 | #define DEBUG_AUTOCONF(fmt...) printk(fmt) |
74 | #else | 74 | #else |
75 | #define DEBUG_AUTOCONF(fmt...) do { } while (0) | 75 | #define DEBUG_AUTOCONF(fmt...) do { } while (0) |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #if 0 | 78 | #if 0 |
79 | #define DEBUG_INTR(fmt...) printk(fmt) | 79 | #define DEBUG_INTR(fmt...) printk(fmt) |
80 | #else | 80 | #else |
81 | #define DEBUG_INTR(fmt...) do { } while (0) | 81 | #define DEBUG_INTR(fmt...) do { } while (0) |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | #define PASS_LIMIT 512 | 84 | #define PASS_LIMIT 512 |
85 | 85 | ||
86 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | 86 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) |
87 | 87 | ||
88 | 88 | ||
89 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ | 89 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
90 | #define CONFIG_SERIAL_DETECT_IRQ 1 | 90 | #define CONFIG_SERIAL_DETECT_IRQ 1 |
91 | #endif | 91 | #endif |
92 | #ifdef CONFIG_SERIAL_8250_MANY_PORTS | 92 | #ifdef CONFIG_SERIAL_8250_MANY_PORTS |
93 | #define CONFIG_SERIAL_MANY_PORTS 1 | 93 | #define CONFIG_SERIAL_MANY_PORTS 1 |
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * HUB6 is always on. This will be removed once the header | 97 | * HUB6 is always on. This will be removed once the header |
98 | * files have been cleaned. | 98 | * files have been cleaned. |
99 | */ | 99 | */ |
100 | #define CONFIG_HUB6 1 | 100 | #define CONFIG_HUB6 1 |
101 | 101 | ||
102 | #include <asm/serial.h> | 102 | #include <asm/serial.h> |
103 | /* | 103 | /* |
104 | * SERIAL_PORT_DFNS tells us about built-in ports that have no | 104 | * SERIAL_PORT_DFNS tells us about built-in ports that have no |
105 | * standard enumeration mechanism. Platforms that can find all | 105 | * standard enumeration mechanism. Platforms that can find all |
106 | * serial ports via mechanisms like ACPI or PCI need not supply it. | 106 | * serial ports via mechanisms like ACPI or PCI need not supply it. |
107 | */ | 107 | */ |
108 | #ifndef SERIAL_PORT_DFNS | 108 | #ifndef SERIAL_PORT_DFNS |
109 | #define SERIAL_PORT_DFNS | 109 | #define SERIAL_PORT_DFNS |
110 | #endif | 110 | #endif |
111 | 111 | ||
112 | static const struct old_serial_port old_serial_port[] = { | 112 | static const struct old_serial_port old_serial_port[] = { |
113 | SERIAL_PORT_DFNS /* defined in asm/serial.h */ | 113 | SERIAL_PORT_DFNS /* defined in asm/serial.h */ |
114 | }; | 114 | }; |
115 | 115 | ||
116 | #define UART_NR CONFIG_SERIAL_8250_NR_UARTS | 116 | #define UART_NR CONFIG_SERIAL_8250_NR_UARTS |
117 | 117 | ||
118 | #ifdef CONFIG_SERIAL_8250_RSA | 118 | #ifdef CONFIG_SERIAL_8250_RSA |
119 | 119 | ||
120 | #define PORT_RSA_MAX 4 | 120 | #define PORT_RSA_MAX 4 |
121 | static unsigned long probe_rsa[PORT_RSA_MAX]; | 121 | static unsigned long probe_rsa[PORT_RSA_MAX]; |
122 | static unsigned int probe_rsa_count; | 122 | static unsigned int probe_rsa_count; |
123 | #endif /* CONFIG_SERIAL_8250_RSA */ | 123 | #endif /* CONFIG_SERIAL_8250_RSA */ |
124 | 124 | ||
125 | struct irq_info { | 125 | struct irq_info { |
126 | struct hlist_node node; | 126 | struct hlist_node node; |
127 | int irq; | 127 | int irq; |
128 | spinlock_t lock; /* Protects list not the hash */ | 128 | spinlock_t lock; /* Protects list not the hash */ |
129 | struct list_head *head; | 129 | struct list_head *head; |
130 | }; | 130 | }; |
131 | 131 | ||
132 | #define NR_IRQ_HASH 32 /* Can be adjusted later */ | 132 | #define NR_IRQ_HASH 32 /* Can be adjusted later */ |
133 | static struct hlist_head irq_lists[NR_IRQ_HASH]; | 133 | static struct hlist_head irq_lists[NR_IRQ_HASH]; |
134 | static DEFINE_MUTEX(hash_mutex); /* Used to walk the hash */ | 134 | static DEFINE_MUTEX(hash_mutex); /* Used to walk the hash */ |
135 | 135 | ||
136 | /* | 136 | /* |
137 | * Here we define the default xmit fifo size used for each type of UART. | 137 | * Here we define the default xmit fifo size used for each type of UART. |
138 | */ | 138 | */ |
139 | static const struct serial8250_config uart_config[] = { | 139 | static const struct serial8250_config uart_config[] = { |
140 | [PORT_UNKNOWN] = { | 140 | [PORT_UNKNOWN] = { |
141 | .name = "unknown", | 141 | .name = "unknown", |
142 | .fifo_size = 1, | 142 | .fifo_size = 1, |
143 | .tx_loadsz = 1, | 143 | .tx_loadsz = 1, |
144 | }, | 144 | }, |
145 | [PORT_8250] = { | 145 | [PORT_8250] = { |
146 | .name = "8250", | 146 | .name = "8250", |
147 | .fifo_size = 1, | 147 | .fifo_size = 1, |
148 | .tx_loadsz = 1, | 148 | .tx_loadsz = 1, |
149 | }, | 149 | }, |
150 | [PORT_16450] = { | 150 | [PORT_16450] = { |
151 | .name = "16450", | 151 | .name = "16450", |
152 | .fifo_size = 1, | 152 | .fifo_size = 1, |
153 | .tx_loadsz = 1, | 153 | .tx_loadsz = 1, |
154 | }, | 154 | }, |
155 | [PORT_16550] = { | 155 | [PORT_16550] = { |
156 | .name = "16550", | 156 | .name = "16550", |
157 | .fifo_size = 1, | 157 | .fifo_size = 1, |
158 | .tx_loadsz = 1, | 158 | .tx_loadsz = 1, |
159 | }, | 159 | }, |
160 | [PORT_16550A] = { | 160 | [PORT_16550A] = { |
161 | .name = "16550A", | 161 | .name = "16550A", |
162 | .fifo_size = 16, | 162 | .fifo_size = 16, |
163 | .tx_loadsz = 16, | 163 | .tx_loadsz = 16, |
164 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 164 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
165 | .rxtrig_bytes = {1, 4, 8, 14}, | 165 | .rxtrig_bytes = {1, 4, 8, 14}, |
166 | .flags = UART_CAP_FIFO, | 166 | .flags = UART_CAP_FIFO, |
167 | }, | 167 | }, |
168 | [PORT_CIRRUS] = { | 168 | [PORT_CIRRUS] = { |
169 | .name = "Cirrus", | 169 | .name = "Cirrus", |
170 | .fifo_size = 1, | 170 | .fifo_size = 1, |
171 | .tx_loadsz = 1, | 171 | .tx_loadsz = 1, |
172 | }, | 172 | }, |
173 | [PORT_16650] = { | 173 | [PORT_16650] = { |
174 | .name = "ST16650", | 174 | .name = "ST16650", |
175 | .fifo_size = 1, | 175 | .fifo_size = 1, |
176 | .tx_loadsz = 1, | 176 | .tx_loadsz = 1, |
177 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, | 177 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, |
178 | }, | 178 | }, |
179 | [PORT_16650V2] = { | 179 | [PORT_16650V2] = { |
180 | .name = "ST16650V2", | 180 | .name = "ST16650V2", |
181 | .fifo_size = 32, | 181 | .fifo_size = 32, |
182 | .tx_loadsz = 16, | 182 | .tx_loadsz = 16, |
183 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | | 183 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | |
184 | UART_FCR_T_TRIG_00, | 184 | UART_FCR_T_TRIG_00, |
185 | .rxtrig_bytes = {8, 16, 24, 28}, | 185 | .rxtrig_bytes = {8, 16, 24, 28}, |
186 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, | 186 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, |
187 | }, | 187 | }, |
188 | [PORT_16750] = { | 188 | [PORT_16750] = { |
189 | .name = "TI16750", | 189 | .name = "TI16750", |
190 | .fifo_size = 64, | 190 | .fifo_size = 64, |
191 | .tx_loadsz = 64, | 191 | .tx_loadsz = 64, |
192 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | | 192 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | |
193 | UART_FCR7_64BYTE, | 193 | UART_FCR7_64BYTE, |
194 | .rxtrig_bytes = {1, 16, 32, 56}, | 194 | .rxtrig_bytes = {1, 16, 32, 56}, |
195 | .flags = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE, | 195 | .flags = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE, |
196 | }, | 196 | }, |
197 | [PORT_STARTECH] = { | 197 | [PORT_STARTECH] = { |
198 | .name = "Startech", | 198 | .name = "Startech", |
199 | .fifo_size = 1, | 199 | .fifo_size = 1, |
200 | .tx_loadsz = 1, | 200 | .tx_loadsz = 1, |
201 | }, | 201 | }, |
202 | [PORT_16C950] = { | 202 | [PORT_16C950] = { |
203 | .name = "16C950/954", | 203 | .name = "16C950/954", |
204 | .fifo_size = 128, | 204 | .fifo_size = 128, |
205 | .tx_loadsz = 128, | 205 | .tx_loadsz = 128, |
206 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 206 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
207 | /* UART_CAP_EFR breaks billionon CF bluetooth card. */ | 207 | /* UART_CAP_EFR breaks billionon CF bluetooth card. */ |
208 | .flags = UART_CAP_FIFO | UART_CAP_SLEEP, | 208 | .flags = UART_CAP_FIFO | UART_CAP_SLEEP, |
209 | }, | 209 | }, |
210 | [PORT_16654] = { | 210 | [PORT_16654] = { |
211 | .name = "ST16654", | 211 | .name = "ST16654", |
212 | .fifo_size = 64, | 212 | .fifo_size = 64, |
213 | .tx_loadsz = 32, | 213 | .tx_loadsz = 32, |
214 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | | 214 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | |
215 | UART_FCR_T_TRIG_10, | 215 | UART_FCR_T_TRIG_10, |
216 | .rxtrig_bytes = {8, 16, 56, 60}, | 216 | .rxtrig_bytes = {8, 16, 56, 60}, |
217 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, | 217 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, |
218 | }, | 218 | }, |
219 | [PORT_16850] = { | 219 | [PORT_16850] = { |
220 | .name = "XR16850", | 220 | .name = "XR16850", |
221 | .fifo_size = 128, | 221 | .fifo_size = 128, |
222 | .tx_loadsz = 128, | 222 | .tx_loadsz = 128, |
223 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 223 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
224 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, | 224 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, |
225 | }, | 225 | }, |
226 | [PORT_RSA] = { | 226 | [PORT_RSA] = { |
227 | .name = "RSA", | 227 | .name = "RSA", |
228 | .fifo_size = 2048, | 228 | .fifo_size = 2048, |
229 | .tx_loadsz = 2048, | 229 | .tx_loadsz = 2048, |
230 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11, | 230 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11, |
231 | .flags = UART_CAP_FIFO, | 231 | .flags = UART_CAP_FIFO, |
232 | }, | 232 | }, |
233 | [PORT_NS16550A] = { | 233 | [PORT_NS16550A] = { |
234 | .name = "NS16550A", | 234 | .name = "NS16550A", |
235 | .fifo_size = 16, | 235 | .fifo_size = 16, |
236 | .tx_loadsz = 16, | 236 | .tx_loadsz = 16, |
237 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 237 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
238 | .flags = UART_CAP_FIFO | UART_NATSEMI, | 238 | .flags = UART_CAP_FIFO | UART_NATSEMI, |
239 | }, | 239 | }, |
240 | [PORT_XSCALE] = { | 240 | [PORT_XSCALE] = { |
241 | .name = "XScale", | 241 | .name = "XScale", |
242 | .fifo_size = 32, | 242 | .fifo_size = 32, |
243 | .tx_loadsz = 32, | 243 | .tx_loadsz = 32, |
244 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 244 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
245 | .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, | 245 | .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, |
246 | }, | 246 | }, |
247 | [PORT_OCTEON] = { | 247 | [PORT_OCTEON] = { |
248 | .name = "OCTEON", | 248 | .name = "OCTEON", |
249 | .fifo_size = 64, | 249 | .fifo_size = 64, |
250 | .tx_loadsz = 64, | 250 | .tx_loadsz = 64, |
251 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 251 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
252 | .flags = UART_CAP_FIFO, | 252 | .flags = UART_CAP_FIFO, |
253 | }, | 253 | }, |
254 | [PORT_AR7] = { | 254 | [PORT_AR7] = { |
255 | .name = "AR7", | 255 | .name = "AR7", |
256 | .fifo_size = 16, | 256 | .fifo_size = 16, |
257 | .tx_loadsz = 16, | 257 | .tx_loadsz = 16, |
258 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, | 258 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, |
259 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | 259 | .flags = UART_CAP_FIFO | UART_CAP_AFE, |
260 | }, | 260 | }, |
261 | [PORT_U6_16550A] = { | 261 | [PORT_U6_16550A] = { |
262 | .name = "U6_16550A", | 262 | .name = "U6_16550A", |
263 | .fifo_size = 64, | 263 | .fifo_size = 64, |
264 | .tx_loadsz = 64, | 264 | .tx_loadsz = 64, |
265 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 265 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
266 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | 266 | .flags = UART_CAP_FIFO | UART_CAP_AFE, |
267 | }, | 267 | }, |
268 | [PORT_TEGRA] = { | 268 | [PORT_TEGRA] = { |
269 | .name = "Tegra", | 269 | .name = "Tegra", |
270 | .fifo_size = 32, | 270 | .fifo_size = 32, |
271 | .tx_loadsz = 8, | 271 | .tx_loadsz = 8, |
272 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | | 272 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | |
273 | UART_FCR_T_TRIG_01, | 273 | UART_FCR_T_TRIG_01, |
274 | .rxtrig_bytes = {1, 4, 8, 14}, | 274 | .rxtrig_bytes = {1, 4, 8, 14}, |
275 | .flags = UART_CAP_FIFO | UART_CAP_RTOIE, | 275 | .flags = UART_CAP_FIFO | UART_CAP_RTOIE, |
276 | }, | 276 | }, |
277 | [PORT_XR17D15X] = { | 277 | [PORT_XR17D15X] = { |
278 | .name = "XR17D15X", | 278 | .name = "XR17D15X", |
279 | .fifo_size = 64, | 279 | .fifo_size = 64, |
280 | .tx_loadsz = 64, | 280 | .tx_loadsz = 64, |
281 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 281 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
282 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | | 282 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | |
283 | UART_CAP_SLEEP, | 283 | UART_CAP_SLEEP, |
284 | }, | 284 | }, |
285 | [PORT_XR17V35X] = { | 285 | [PORT_XR17V35X] = { |
286 | .name = "XR17V35X", | 286 | .name = "XR17V35X", |
287 | .fifo_size = 256, | 287 | .fifo_size = 256, |
288 | .tx_loadsz = 256, | 288 | .tx_loadsz = 256, |
289 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 | | 289 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 | |
290 | UART_FCR_T_TRIG_11, | 290 | UART_FCR_T_TRIG_11, |
291 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | | 291 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | |
292 | UART_CAP_SLEEP, | 292 | UART_CAP_SLEEP, |
293 | }, | 293 | }, |
294 | [PORT_LPC3220] = { | 294 | [PORT_LPC3220] = { |
295 | .name = "LPC3220", | 295 | .name = "LPC3220", |
296 | .fifo_size = 64, | 296 | .fifo_size = 64, |
297 | .tx_loadsz = 32, | 297 | .tx_loadsz = 32, |
298 | .fcr = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | | 298 | .fcr = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | |
299 | UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, | 299 | UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, |
300 | .flags = UART_CAP_FIFO, | 300 | .flags = UART_CAP_FIFO, |
301 | }, | 301 | }, |
302 | [PORT_BRCM_TRUMANAGE] = { | 302 | [PORT_BRCM_TRUMANAGE] = { |
303 | .name = "TruManage", | 303 | .name = "TruManage", |
304 | .fifo_size = 1, | 304 | .fifo_size = 1, |
305 | .tx_loadsz = 1024, | 305 | .tx_loadsz = 1024, |
306 | .flags = UART_CAP_HFIFO, | 306 | .flags = UART_CAP_HFIFO, |
307 | }, | 307 | }, |
308 | [PORT_8250_CIR] = { | 308 | [PORT_8250_CIR] = { |
309 | .name = "CIR port" | 309 | .name = "CIR port" |
310 | }, | 310 | }, |
311 | [PORT_ALTR_16550_F32] = { | 311 | [PORT_ALTR_16550_F32] = { |
312 | .name = "Altera 16550 FIFO32", | 312 | .name = "Altera 16550 FIFO32", |
313 | .fifo_size = 32, | 313 | .fifo_size = 32, |
314 | .tx_loadsz = 32, | 314 | .tx_loadsz = 32, |
315 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 315 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
316 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | 316 | .flags = UART_CAP_FIFO | UART_CAP_AFE, |
317 | }, | 317 | }, |
318 | [PORT_ALTR_16550_F64] = { | 318 | [PORT_ALTR_16550_F64] = { |
319 | .name = "Altera 16550 FIFO64", | 319 | .name = "Altera 16550 FIFO64", |
320 | .fifo_size = 64, | 320 | .fifo_size = 64, |
321 | .tx_loadsz = 64, | 321 | .tx_loadsz = 64, |
322 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 322 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
323 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | 323 | .flags = UART_CAP_FIFO | UART_CAP_AFE, |
324 | }, | 324 | }, |
325 | [PORT_ALTR_16550_F128] = { | 325 | [PORT_ALTR_16550_F128] = { |
326 | .name = "Altera 16550 FIFO128", | 326 | .name = "Altera 16550 FIFO128", |
327 | .fifo_size = 128, | 327 | .fifo_size = 128, |
328 | .tx_loadsz = 128, | 328 | .tx_loadsz = 128, |
329 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 329 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
330 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | 330 | .flags = UART_CAP_FIFO | UART_CAP_AFE, |
331 | }, | 331 | }, |
332 | /* tx_loadsz is set to 63-bytes instead of 64-bytes to implement | 332 | /* tx_loadsz is set to 63-bytes instead of 64-bytes to implement |
333 | workaround of errata A-008006 which states that tx_loadsz should be | 333 | workaround of errata A-008006 which states that tx_loadsz should be |
334 | configured less than Maximum supported fifo bytes */ | 334 | configured less than Maximum supported fifo bytes */ |
335 | [PORT_16550A_FSL64] = { | 335 | [PORT_16550A_FSL64] = { |
336 | .name = "16550A_FSL64", | 336 | .name = "16550A_FSL64", |
337 | .fifo_size = 64, | 337 | .fifo_size = 64, |
338 | .tx_loadsz = 63, | 338 | .tx_loadsz = 63, |
339 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | | 339 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | |
340 | UART_FCR7_64BYTE, | 340 | UART_FCR7_64BYTE, |
341 | .flags = UART_CAP_FIFO, | 341 | .flags = UART_CAP_FIFO, |
342 | }, | 342 | }, |
343 | }; | 343 | }; |
344 | 344 | ||
345 | /* Uart divisor latch read */ | 345 | /* Uart divisor latch read */ |
346 | static int default_serial_dl_read(struct uart_8250_port *up) | 346 | static int default_serial_dl_read(struct uart_8250_port *up) |
347 | { | 347 | { |
348 | return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8; | 348 | return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8; |
349 | } | 349 | } |
350 | 350 | ||
351 | /* Uart divisor latch write */ | 351 | /* Uart divisor latch write */ |
352 | static void default_serial_dl_write(struct uart_8250_port *up, int value) | 352 | static void default_serial_dl_write(struct uart_8250_port *up, int value) |
353 | { | 353 | { |
354 | serial_out(up, UART_DLL, value & 0xff); | 354 | serial_out(up, UART_DLL, value & 0xff); |
355 | serial_out(up, UART_DLM, value >> 8 & 0xff); | 355 | serial_out(up, UART_DLM, value >> 8 & 0xff); |
356 | } | 356 | } |
357 | 357 | ||
358 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) | 358 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) |
359 | 359 | ||
360 | /* Au1x00/RT288x UART hardware has a weird register layout */ | 360 | /* Au1x00/RT288x UART hardware has a weird register layout */ |
361 | static const u8 au_io_in_map[] = { | 361 | static const u8 au_io_in_map[] = { |
362 | [UART_RX] = 0, | 362 | [UART_RX] = 0, |
363 | [UART_IER] = 2, | 363 | [UART_IER] = 2, |
364 | [UART_IIR] = 3, | 364 | [UART_IIR] = 3, |
365 | [UART_LCR] = 5, | 365 | [UART_LCR] = 5, |
366 | [UART_MCR] = 6, | 366 | [UART_MCR] = 6, |
367 | [UART_LSR] = 7, | 367 | [UART_LSR] = 7, |
368 | [UART_MSR] = 8, | 368 | [UART_MSR] = 8, |
369 | }; | 369 | }; |
370 | 370 | ||
371 | static const u8 au_io_out_map[] = { | 371 | static const u8 au_io_out_map[] = { |
372 | [UART_TX] = 1, | 372 | [UART_TX] = 1, |
373 | [UART_IER] = 2, | 373 | [UART_IER] = 2, |
374 | [UART_FCR] = 4, | 374 | [UART_FCR] = 4, |
375 | [UART_LCR] = 5, | 375 | [UART_LCR] = 5, |
376 | [UART_MCR] = 6, | 376 | [UART_MCR] = 6, |
377 | }; | 377 | }; |
378 | 378 | ||
379 | static unsigned int au_serial_in(struct uart_port *p, int offset) | 379 | static unsigned int au_serial_in(struct uart_port *p, int offset) |
380 | { | 380 | { |
381 | offset = au_io_in_map[offset] << p->regshift; | 381 | offset = au_io_in_map[offset] << p->regshift; |
382 | return __raw_readl(p->membase + offset); | 382 | return __raw_readl(p->membase + offset); |
383 | } | 383 | } |
384 | 384 | ||
385 | static void au_serial_out(struct uart_port *p, int offset, int value) | 385 | static void au_serial_out(struct uart_port *p, int offset, int value) |
386 | { | 386 | { |
387 | offset = au_io_out_map[offset] << p->regshift; | 387 | offset = au_io_out_map[offset] << p->regshift; |
388 | __raw_writel(value, p->membase + offset); | 388 | __raw_writel(value, p->membase + offset); |
389 | } | 389 | } |
390 | 390 | ||
391 | /* Au1x00 haven't got a standard divisor latch */ | 391 | /* Au1x00 haven't got a standard divisor latch */ |
392 | static int au_serial_dl_read(struct uart_8250_port *up) | 392 | static int au_serial_dl_read(struct uart_8250_port *up) |
393 | { | 393 | { |
394 | return __raw_readl(up->port.membase + 0x28); | 394 | return __raw_readl(up->port.membase + 0x28); |
395 | } | 395 | } |
396 | 396 | ||
397 | static void au_serial_dl_write(struct uart_8250_port *up, int value) | 397 | static void au_serial_dl_write(struct uart_8250_port *up, int value) |
398 | { | 398 | { |
399 | __raw_writel(value, up->port.membase + 0x28); | 399 | __raw_writel(value, up->port.membase + 0x28); |
400 | } | 400 | } |
401 | 401 | ||
402 | #endif | 402 | #endif |
403 | 403 | ||
404 | static unsigned int hub6_serial_in(struct uart_port *p, int offset) | 404 | static unsigned int hub6_serial_in(struct uart_port *p, int offset) |
405 | { | 405 | { |
406 | offset = offset << p->regshift; | 406 | offset = offset << p->regshift; |
407 | outb(p->hub6 - 1 + offset, p->iobase); | 407 | outb(p->hub6 - 1 + offset, p->iobase); |
408 | return inb(p->iobase + 1); | 408 | return inb(p->iobase + 1); |
409 | } | 409 | } |
410 | 410 | ||
411 | static void hub6_serial_out(struct uart_port *p, int offset, int value) | 411 | static void hub6_serial_out(struct uart_port *p, int offset, int value) |
412 | { | 412 | { |
413 | offset = offset << p->regshift; | 413 | offset = offset << p->regshift; |
414 | outb(p->hub6 - 1 + offset, p->iobase); | 414 | outb(p->hub6 - 1 + offset, p->iobase); |
415 | outb(value, p->iobase + 1); | 415 | outb(value, p->iobase + 1); |
416 | } | 416 | } |
417 | 417 | ||
418 | static unsigned int mem_serial_in(struct uart_port *p, int offset) | 418 | static unsigned int mem_serial_in(struct uart_port *p, int offset) |
419 | { | 419 | { |
420 | offset = offset << p->regshift; | 420 | offset = offset << p->regshift; |
421 | return readb(p->membase + offset); | 421 | return readb(p->membase + offset); |
422 | } | 422 | } |
423 | 423 | ||
424 | static void mem_serial_out(struct uart_port *p, int offset, int value) | 424 | static void mem_serial_out(struct uart_port *p, int offset, int value) |
425 | { | 425 | { |
426 | offset = offset << p->regshift; | 426 | offset = offset << p->regshift; |
427 | writeb(value, p->membase + offset); | 427 | writeb(value, p->membase + offset); |
428 | } | 428 | } |
429 | 429 | ||
430 | static void mem32_serial_out(struct uart_port *p, int offset, int value) | 430 | static void mem32_serial_out(struct uart_port *p, int offset, int value) |
431 | { | 431 | { |
432 | offset = offset << p->regshift; | 432 | offset = offset << p->regshift; |
433 | writel(value, p->membase + offset); | 433 | writel(value, p->membase + offset); |
434 | } | 434 | } |
435 | 435 | ||
436 | static unsigned int mem32_serial_in(struct uart_port *p, int offset) | 436 | static unsigned int mem32_serial_in(struct uart_port *p, int offset) |
437 | { | 437 | { |
438 | offset = offset << p->regshift; | 438 | offset = offset << p->regshift; |
439 | return readl(p->membase + offset); | 439 | return readl(p->membase + offset); |
440 | } | 440 | } |
441 | 441 | ||
442 | static unsigned int io_serial_in(struct uart_port *p, int offset) | 442 | static unsigned int io_serial_in(struct uart_port *p, int offset) |
443 | { | 443 | { |
444 | offset = offset << p->regshift; | 444 | offset = offset << p->regshift; |
445 | return inb(p->iobase + offset); | 445 | return inb(p->iobase + offset); |
446 | } | 446 | } |
447 | 447 | ||
448 | static void io_serial_out(struct uart_port *p, int offset, int value) | 448 | static void io_serial_out(struct uart_port *p, int offset, int value) |
449 | { | 449 | { |
450 | offset = offset << p->regshift; | 450 | offset = offset << p->regshift; |
451 | outb(value, p->iobase + offset); | 451 | outb(value, p->iobase + offset); |
452 | } | 452 | } |
453 | 453 | ||
454 | static int serial8250_default_handle_irq(struct uart_port *port); | 454 | static int serial8250_default_handle_irq(struct uart_port *port); |
455 | static int exar_handle_irq(struct uart_port *port); | 455 | static int exar_handle_irq(struct uart_port *port); |
456 | 456 | ||
457 | static void set_io_from_upio(struct uart_port *p) | 457 | static void set_io_from_upio(struct uart_port *p) |
458 | { | 458 | { |
459 | struct uart_8250_port *up = up_to_u8250p(p); | 459 | struct uart_8250_port *up = up_to_u8250p(p); |
460 | 460 | ||
461 | up->dl_read = default_serial_dl_read; | 461 | up->dl_read = default_serial_dl_read; |
462 | up->dl_write = default_serial_dl_write; | 462 | up->dl_write = default_serial_dl_write; |
463 | 463 | ||
464 | switch (p->iotype) { | 464 | switch (p->iotype) { |
465 | case UPIO_HUB6: | 465 | case UPIO_HUB6: |
466 | p->serial_in = hub6_serial_in; | 466 | p->serial_in = hub6_serial_in; |
467 | p->serial_out = hub6_serial_out; | 467 | p->serial_out = hub6_serial_out; |
468 | break; | 468 | break; |
469 | 469 | ||
470 | case UPIO_MEM: | 470 | case UPIO_MEM: |
471 | p->serial_in = mem_serial_in; | 471 | p->serial_in = mem_serial_in; |
472 | p->serial_out = mem_serial_out; | 472 | p->serial_out = mem_serial_out; |
473 | break; | 473 | break; |
474 | 474 | ||
475 | case UPIO_MEM32: | 475 | case UPIO_MEM32: |
476 | p->serial_in = mem32_serial_in; | 476 | p->serial_in = mem32_serial_in; |
477 | p->serial_out = mem32_serial_out; | 477 | p->serial_out = mem32_serial_out; |
478 | break; | 478 | break; |
479 | 479 | ||
480 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) | 480 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) |
481 | case UPIO_AU: | 481 | case UPIO_AU: |
482 | p->serial_in = au_serial_in; | 482 | p->serial_in = au_serial_in; |
483 | p->serial_out = au_serial_out; | 483 | p->serial_out = au_serial_out; |
484 | up->dl_read = au_serial_dl_read; | 484 | up->dl_read = au_serial_dl_read; |
485 | up->dl_write = au_serial_dl_write; | 485 | up->dl_write = au_serial_dl_write; |
486 | break; | 486 | break; |
487 | #endif | 487 | #endif |
488 | 488 | ||
489 | default: | 489 | default: |
490 | p->serial_in = io_serial_in; | 490 | p->serial_in = io_serial_in; |
491 | p->serial_out = io_serial_out; | 491 | p->serial_out = io_serial_out; |
492 | break; | 492 | break; |
493 | } | 493 | } |
494 | /* Remember loaded iotype */ | 494 | /* Remember loaded iotype */ |
495 | up->cur_iotype = p->iotype; | 495 | up->cur_iotype = p->iotype; |
496 | p->handle_irq = serial8250_default_handle_irq; | 496 | p->handle_irq = serial8250_default_handle_irq; |
497 | } | 497 | } |
498 | 498 | ||
499 | static void | 499 | static void |
500 | serial_port_out_sync(struct uart_port *p, int offset, int value) | 500 | serial_port_out_sync(struct uart_port *p, int offset, int value) |
501 | { | 501 | { |
502 | switch (p->iotype) { | 502 | switch (p->iotype) { |
503 | case UPIO_MEM: | 503 | case UPIO_MEM: |
504 | case UPIO_MEM32: | 504 | case UPIO_MEM32: |
505 | case UPIO_AU: | 505 | case UPIO_AU: |
506 | p->serial_out(p, offset, value); | 506 | p->serial_out(p, offset, value); |
507 | p->serial_in(p, UART_LCR); /* safe, no side-effects */ | 507 | p->serial_in(p, UART_LCR); /* safe, no side-effects */ |
508 | break; | 508 | break; |
509 | default: | 509 | default: |
510 | p->serial_out(p, offset, value); | 510 | p->serial_out(p, offset, value); |
511 | } | 511 | } |
512 | } | 512 | } |
513 | 513 | ||
514 | /* | 514 | /* |
515 | * For the 16C950 | 515 | * For the 16C950 |
516 | */ | 516 | */ |
517 | static void serial_icr_write(struct uart_8250_port *up, int offset, int value) | 517 | static void serial_icr_write(struct uart_8250_port *up, int offset, int value) |
518 | { | 518 | { |
519 | serial_out(up, UART_SCR, offset); | 519 | serial_out(up, UART_SCR, offset); |
520 | serial_out(up, UART_ICR, value); | 520 | serial_out(up, UART_ICR, value); |
521 | } | 521 | } |
522 | 522 | ||
523 | static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) | 523 | static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) |
524 | { | 524 | { |
525 | unsigned int value; | 525 | unsigned int value; |
526 | 526 | ||
527 | serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD); | 527 | serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD); |
528 | serial_out(up, UART_SCR, offset); | 528 | serial_out(up, UART_SCR, offset); |
529 | value = serial_in(up, UART_ICR); | 529 | value = serial_in(up, UART_ICR); |
530 | serial_icr_write(up, UART_ACR, up->acr); | 530 | serial_icr_write(up, UART_ACR, up->acr); |
531 | 531 | ||
532 | return value; | 532 | return value; |
533 | } | 533 | } |
534 | 534 | ||
535 | /* | 535 | /* |
536 | * FIFO support. | 536 | * FIFO support. |
537 | */ | 537 | */ |
538 | static void serial8250_clear_fifos(struct uart_8250_port *p) | 538 | static void serial8250_clear_fifos(struct uart_8250_port *p) |
539 | { | 539 | { |
540 | if (p->capabilities & UART_CAP_FIFO) { | 540 | if (p->capabilities & UART_CAP_FIFO) { |
541 | serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO); | 541 | serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO); |
542 | serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO | | 542 | serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO | |
543 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | 543 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); |
544 | serial_out(p, UART_FCR, 0); | 544 | serial_out(p, UART_FCR, 0); |
545 | } | 545 | } |
546 | } | 546 | } |
547 | 547 | ||
548 | void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) | 548 | void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) |
549 | { | 549 | { |
550 | serial8250_clear_fifos(p); | 550 | serial8250_clear_fifos(p); |
551 | serial_out(p, UART_FCR, p->fcr); | 551 | serial_out(p, UART_FCR, p->fcr); |
552 | } | 552 | } |
553 | EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); | 553 | EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); |
554 | 554 | ||
555 | void serial8250_rpm_get(struct uart_8250_port *p) | 555 | void serial8250_rpm_get(struct uart_8250_port *p) |
556 | { | 556 | { |
557 | if (!(p->capabilities & UART_CAP_RPM)) | 557 | if (!(p->capabilities & UART_CAP_RPM)) |
558 | return; | 558 | return; |
559 | pm_runtime_get_sync(p->port.dev); | 559 | pm_runtime_get_sync(p->port.dev); |
560 | } | 560 | } |
561 | EXPORT_SYMBOL_GPL(serial8250_rpm_get); | 561 | EXPORT_SYMBOL_GPL(serial8250_rpm_get); |
562 | 562 | ||
563 | void serial8250_rpm_put(struct uart_8250_port *p) | 563 | void serial8250_rpm_put(struct uart_8250_port *p) |
564 | { | 564 | { |
565 | if (!(p->capabilities & UART_CAP_RPM)) | 565 | if (!(p->capabilities & UART_CAP_RPM)) |
566 | return; | 566 | return; |
567 | pm_runtime_mark_last_busy(p->port.dev); | 567 | pm_runtime_mark_last_busy(p->port.dev); |
568 | pm_runtime_put_autosuspend(p->port.dev); | 568 | pm_runtime_put_autosuspend(p->port.dev); |
569 | } | 569 | } |
570 | EXPORT_SYMBOL_GPL(serial8250_rpm_put); | 570 | EXPORT_SYMBOL_GPL(serial8250_rpm_put); |
571 | 571 | ||
572 | /* | 572 | /* |
573 | * These two wrappers ensure that enable_runtime_pm_tx() can be called more than | 573 | * These two wrappers ensure that enable_runtime_pm_tx() can be called more than |
574 | * once and disable_runtime_pm_tx() will still disable RPM because the fifo is | 574 | * once and disable_runtime_pm_tx() will still disable RPM because the fifo is |
575 | * empty and the HW can idle again. | 575 | * empty and the HW can idle again. |
576 | */ | 576 | */ |
577 | static void serial8250_rpm_get_tx(struct uart_8250_port *p) | 577 | static void serial8250_rpm_get_tx(struct uart_8250_port *p) |
578 | { | 578 | { |
579 | unsigned char rpm_active; | 579 | unsigned char rpm_active; |
580 | 580 | ||
581 | if (!(p->capabilities & UART_CAP_RPM)) | 581 | if (!(p->capabilities & UART_CAP_RPM)) |
582 | return; | 582 | return; |
583 | 583 | ||
584 | rpm_active = xchg(&p->rpm_tx_active, 1); | 584 | rpm_active = xchg(&p->rpm_tx_active, 1); |
585 | if (rpm_active) | 585 | if (rpm_active) |
586 | return; | 586 | return; |
587 | pm_runtime_get_sync(p->port.dev); | 587 | pm_runtime_get_sync(p->port.dev); |
588 | } | 588 | } |
589 | 589 | ||
590 | static void serial8250_rpm_put_tx(struct uart_8250_port *p) | 590 | static void serial8250_rpm_put_tx(struct uart_8250_port *p) |
591 | { | 591 | { |
592 | unsigned char rpm_active; | 592 | unsigned char rpm_active; |
593 | 593 | ||
594 | if (!(p->capabilities & UART_CAP_RPM)) | 594 | if (!(p->capabilities & UART_CAP_RPM)) |
595 | return; | 595 | return; |
596 | 596 | ||
597 | rpm_active = xchg(&p->rpm_tx_active, 0); | 597 | rpm_active = xchg(&p->rpm_tx_active, 0); |
598 | if (!rpm_active) | 598 | if (!rpm_active) |
599 | return; | 599 | return; |
600 | pm_runtime_mark_last_busy(p->port.dev); | 600 | pm_runtime_mark_last_busy(p->port.dev); |
601 | pm_runtime_put_autosuspend(p->port.dev); | 601 | pm_runtime_put_autosuspend(p->port.dev); |
602 | } | 602 | } |
603 | 603 | ||
604 | /* | 604 | /* |
605 | * IER sleep support. UARTs which have EFRs need the "extended | 605 | * IER sleep support. UARTs which have EFRs need the "extended |
606 | * capability" bit enabled. Note that on XR16C850s, we need to | 606 | * capability" bit enabled. Note that on XR16C850s, we need to |
607 | * reset LCR to write to IER. | 607 | * reset LCR to write to IER. |
608 | */ | 608 | */ |
609 | static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) | 609 | static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) |
610 | { | 610 | { |
611 | unsigned char lcr = 0, efr = 0; | 611 | unsigned char lcr = 0, efr = 0; |
612 | /* | 612 | /* |
613 | * Exar UARTs have a SLEEP register that enables or disables | 613 | * Exar UARTs have a SLEEP register that enables or disables |
614 | * each UART to enter sleep mode separately. On the XR17V35x the | 614 | * each UART to enter sleep mode separately. On the XR17V35x the |
615 | * register is accessible to each UART at the UART_EXAR_SLEEP | 615 | * register is accessible to each UART at the UART_EXAR_SLEEP |
616 | * offset but the UART channel may only write to the corresponding | 616 | * offset but the UART channel may only write to the corresponding |
617 | * bit. | 617 | * bit. |
618 | */ | 618 | */ |
619 | serial8250_rpm_get(p); | 619 | serial8250_rpm_get(p); |
620 | if ((p->port.type == PORT_XR17V35X) || | 620 | if ((p->port.type == PORT_XR17V35X) || |
621 | (p->port.type == PORT_XR17D15X)) { | 621 | (p->port.type == PORT_XR17D15X)) { |
622 | serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0); | 622 | serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0); |
623 | goto out; | 623 | goto out; |
624 | } | 624 | } |
625 | 625 | ||
626 | if (p->capabilities & UART_CAP_SLEEP) { | 626 | if (p->capabilities & UART_CAP_SLEEP) { |
627 | if (p->capabilities & UART_CAP_EFR) { | 627 | if (p->capabilities & UART_CAP_EFR) { |
628 | lcr = serial_in(p, UART_LCR); | 628 | lcr = serial_in(p, UART_LCR); |
629 | efr = serial_in(p, UART_EFR); | 629 | efr = serial_in(p, UART_EFR); |
630 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); | 630 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); |
631 | serial_out(p, UART_EFR, UART_EFR_ECB); | 631 | serial_out(p, UART_EFR, UART_EFR_ECB); |
632 | serial_out(p, UART_LCR, 0); | 632 | serial_out(p, UART_LCR, 0); |
633 | } | 633 | } |
634 | serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); | 634 | serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); |
635 | if (p->capabilities & UART_CAP_EFR) { | 635 | if (p->capabilities & UART_CAP_EFR) { |
636 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); | 636 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); |
637 | serial_out(p, UART_EFR, efr); | 637 | serial_out(p, UART_EFR, efr); |
638 | serial_out(p, UART_LCR, lcr); | 638 | serial_out(p, UART_LCR, lcr); |
639 | } | 639 | } |
640 | } | 640 | } |
641 | out: | 641 | out: |
642 | serial8250_rpm_put(p); | 642 | serial8250_rpm_put(p); |
643 | } | 643 | } |
644 | 644 | ||
645 | #ifdef CONFIG_SERIAL_8250_RSA | 645 | #ifdef CONFIG_SERIAL_8250_RSA |
646 | /* | 646 | /* |
647 | * Attempts to turn on the RSA FIFO. Returns zero on failure. | 647 | * Attempts to turn on the RSA FIFO. Returns zero on failure. |
648 | * We set the port uart clock rate if we succeed. | 648 | * We set the port uart clock rate if we succeed. |
649 | */ | 649 | */ |
650 | static int __enable_rsa(struct uart_8250_port *up) | 650 | static int __enable_rsa(struct uart_8250_port *up) |
651 | { | 651 | { |
652 | unsigned char mode; | 652 | unsigned char mode; |
653 | int result; | 653 | int result; |
654 | 654 | ||
655 | mode = serial_in(up, UART_RSA_MSR); | 655 | mode = serial_in(up, UART_RSA_MSR); |
656 | result = mode & UART_RSA_MSR_FIFO; | 656 | result = mode & UART_RSA_MSR_FIFO; |
657 | 657 | ||
658 | if (!result) { | 658 | if (!result) { |
659 | serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); | 659 | serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); |
660 | mode = serial_in(up, UART_RSA_MSR); | 660 | mode = serial_in(up, UART_RSA_MSR); |
661 | result = mode & UART_RSA_MSR_FIFO; | 661 | result = mode & UART_RSA_MSR_FIFO; |
662 | } | 662 | } |
663 | 663 | ||
664 | if (result) | 664 | if (result) |
665 | up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16; | 665 | up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16; |
666 | 666 | ||
667 | return result; | 667 | return result; |
668 | } | 668 | } |
669 | 669 | ||
670 | static void enable_rsa(struct uart_8250_port *up) | 670 | static void enable_rsa(struct uart_8250_port *up) |
671 | { | 671 | { |
672 | if (up->port.type == PORT_RSA) { | 672 | if (up->port.type == PORT_RSA) { |
673 | if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { | 673 | if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { |
674 | spin_lock_irq(&up->port.lock); | 674 | spin_lock_irq(&up->port.lock); |
675 | __enable_rsa(up); | 675 | __enable_rsa(up); |
676 | spin_unlock_irq(&up->port.lock); | 676 | spin_unlock_irq(&up->port.lock); |
677 | } | 677 | } |
678 | if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) | 678 | if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) |
679 | serial_out(up, UART_RSA_FRR, 0); | 679 | serial_out(up, UART_RSA_FRR, 0); |
680 | } | 680 | } |
681 | } | 681 | } |
682 | 682 | ||
683 | /* | 683 | /* |
684 | * Attempts to turn off the RSA FIFO. Returns zero on failure. | 684 | * Attempts to turn off the RSA FIFO. Returns zero on failure. |
685 | * It is unknown why interrupts were disabled in here. However, | 685 | * It is unknown why interrupts were disabled in here. However, |
686 | * the caller is expected to preserve this behaviour by grabbing | 686 | * the caller is expected to preserve this behaviour by grabbing |
687 | * the spinlock before calling this function. | 687 | * the spinlock before calling this function. |
688 | */ | 688 | */ |
689 | static void disable_rsa(struct uart_8250_port *up) | 689 | static void disable_rsa(struct uart_8250_port *up) |
690 | { | 690 | { |
691 | unsigned char mode; | 691 | unsigned char mode; |
692 | int result; | 692 | int result; |
693 | 693 | ||
694 | if (up->port.type == PORT_RSA && | 694 | if (up->port.type == PORT_RSA && |
695 | up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { | 695 | up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { |
696 | spin_lock_irq(&up->port.lock); | 696 | spin_lock_irq(&up->port.lock); |
697 | 697 | ||
698 | mode = serial_in(up, UART_RSA_MSR); | 698 | mode = serial_in(up, UART_RSA_MSR); |
699 | result = !(mode & UART_RSA_MSR_FIFO); | 699 | result = !(mode & UART_RSA_MSR_FIFO); |
700 | 700 | ||
701 | if (!result) { | 701 | if (!result) { |
702 | serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); | 702 | serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); |
703 | mode = serial_in(up, UART_RSA_MSR); | 703 | mode = serial_in(up, UART_RSA_MSR); |
704 | result = !(mode & UART_RSA_MSR_FIFO); | 704 | result = !(mode & UART_RSA_MSR_FIFO); |
705 | } | 705 | } |
706 | 706 | ||
707 | if (result) | 707 | if (result) |
708 | up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; | 708 | up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; |
709 | spin_unlock_irq(&up->port.lock); | 709 | spin_unlock_irq(&up->port.lock); |
710 | } | 710 | } |
711 | } | 711 | } |
712 | #endif /* CONFIG_SERIAL_8250_RSA */ | 712 | #endif /* CONFIG_SERIAL_8250_RSA */ |
713 | 713 | ||
714 | /* | 714 | /* |
715 | * This is a quickie test to see how big the FIFO is. | 715 | * This is a quickie test to see how big the FIFO is. |
716 | * It doesn't work at all the time, more's the pity. | 716 | * It doesn't work at all the time, more's the pity. |
717 | */ | 717 | */ |
718 | static int size_fifo(struct uart_8250_port *up) | 718 | static int size_fifo(struct uart_8250_port *up) |
719 | { | 719 | { |
720 | unsigned char old_fcr, old_mcr, old_lcr; | 720 | unsigned char old_fcr, old_mcr, old_lcr; |
721 | unsigned short old_dl; | 721 | unsigned short old_dl; |
722 | int count; | 722 | int count; |
723 | 723 | ||
724 | old_lcr = serial_in(up, UART_LCR); | 724 | old_lcr = serial_in(up, UART_LCR); |
725 | serial_out(up, UART_LCR, 0); | 725 | serial_out(up, UART_LCR, 0); |
726 | old_fcr = serial_in(up, UART_FCR); | 726 | old_fcr = serial_in(up, UART_FCR); |
727 | old_mcr = serial_in(up, UART_MCR); | 727 | old_mcr = serial_in(up, UART_MCR); |
728 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | | 728 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | |
729 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | 729 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); |
730 | serial_out(up, UART_MCR, UART_MCR_LOOP); | 730 | serial_out(up, UART_MCR, UART_MCR_LOOP); |
731 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 731 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
732 | old_dl = serial_dl_read(up); | 732 | old_dl = serial_dl_read(up); |
733 | serial_dl_write(up, 0x0001); | 733 | serial_dl_write(up, 0x0001); |
734 | serial_out(up, UART_LCR, 0x03); | 734 | serial_out(up, UART_LCR, 0x03); |
735 | for (count = 0; count < 256; count++) | 735 | for (count = 0; count < 256; count++) |
736 | serial_out(up, UART_TX, count); | 736 | serial_out(up, UART_TX, count); |
737 | mdelay(20);/* FIXME - schedule_timeout */ | 737 | mdelay(20);/* FIXME - schedule_timeout */ |
738 | for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) && | 738 | for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) && |
739 | (count < 256); count++) | 739 | (count < 256); count++) |
740 | serial_in(up, UART_RX); | 740 | serial_in(up, UART_RX); |
741 | serial_out(up, UART_FCR, old_fcr); | 741 | serial_out(up, UART_FCR, old_fcr); |
742 | serial_out(up, UART_MCR, old_mcr); | 742 | serial_out(up, UART_MCR, old_mcr); |
743 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 743 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
744 | serial_dl_write(up, old_dl); | 744 | serial_dl_write(up, old_dl); |
745 | serial_out(up, UART_LCR, old_lcr); | 745 | serial_out(up, UART_LCR, old_lcr); |
746 | 746 | ||
747 | return count; | 747 | return count; |
748 | } | 748 | } |
749 | 749 | ||
750 | /* | 750 | /* |
751 | * Read UART ID using the divisor method - set DLL and DLM to zero | 751 | * Read UART ID using the divisor method - set DLL and DLM to zero |
752 | * and the revision will be in DLL and device type in DLM. We | 752 | * and the revision will be in DLL and device type in DLM. We |
753 | * preserve the device state across this. | 753 | * preserve the device state across this. |
754 | */ | 754 | */ |
755 | static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) | 755 | static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) |
756 | { | 756 | { |
757 | unsigned char old_dll, old_dlm, old_lcr; | 757 | unsigned char old_dll, old_dlm, old_lcr; |
758 | unsigned int id; | 758 | unsigned int id; |
759 | 759 | ||
760 | old_lcr = serial_in(p, UART_LCR); | 760 | old_lcr = serial_in(p, UART_LCR); |
761 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A); | 761 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A); |
762 | 762 | ||
763 | old_dll = serial_in(p, UART_DLL); | 763 | old_dll = serial_in(p, UART_DLL); |
764 | old_dlm = serial_in(p, UART_DLM); | 764 | old_dlm = serial_in(p, UART_DLM); |
765 | 765 | ||
766 | serial_out(p, UART_DLL, 0); | 766 | serial_out(p, UART_DLL, 0); |
767 | serial_out(p, UART_DLM, 0); | 767 | serial_out(p, UART_DLM, 0); |
768 | 768 | ||
769 | id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8; | 769 | id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8; |
770 | 770 | ||
771 | serial_out(p, UART_DLL, old_dll); | 771 | serial_out(p, UART_DLL, old_dll); |
772 | serial_out(p, UART_DLM, old_dlm); | 772 | serial_out(p, UART_DLM, old_dlm); |
773 | serial_out(p, UART_LCR, old_lcr); | 773 | serial_out(p, UART_LCR, old_lcr); |
774 | 774 | ||
775 | return id; | 775 | return id; |
776 | } | 776 | } |
777 | 777 | ||
778 | /* | 778 | /* |
779 | * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's. | 779 | * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's. |
780 | * When this function is called we know it is at least a StarTech | 780 | * When this function is called we know it is at least a StarTech |
781 | * 16650 V2, but it might be one of several StarTech UARTs, or one of | 781 | * 16650 V2, but it might be one of several StarTech UARTs, or one of |
782 | * its clones. (We treat the broken original StarTech 16650 V1 as a | 782 | * its clones. (We treat the broken original StarTech 16650 V1 as a |
783 | * 16550, and why not? Startech doesn't seem to even acknowledge its | 783 | * 16550, and why not? Startech doesn't seem to even acknowledge its |
784 | * existence.) | 784 | * existence.) |
785 | * | 785 | * |
786 | * What evil have men's minds wrought... | 786 | * What evil have men's minds wrought... |
787 | */ | 787 | */ |
788 | static void autoconfig_has_efr(struct uart_8250_port *up) | 788 | static void autoconfig_has_efr(struct uart_8250_port *up) |
789 | { | 789 | { |
790 | unsigned int id1, id2, id3, rev; | 790 | unsigned int id1, id2, id3, rev; |
791 | 791 | ||
792 | /* | 792 | /* |
793 | * Everything with an EFR has SLEEP | 793 | * Everything with an EFR has SLEEP |
794 | */ | 794 | */ |
795 | up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; | 795 | up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; |
796 | 796 | ||
797 | /* | 797 | /* |
798 | * First we check to see if it's an Oxford Semiconductor UART. | 798 | * First we check to see if it's an Oxford Semiconductor UART. |
799 | * | 799 | * |
800 | * If we have to do this here because some non-National | 800 | * If we have to do this here because some non-National |
801 | * Semiconductor clone chips lock up if you try writing to the | 801 | * Semiconductor clone chips lock up if you try writing to the |
802 | * LSR register (which serial_icr_read does) | 802 | * LSR register (which serial_icr_read does) |
803 | */ | 803 | */ |
804 | 804 | ||
805 | /* | 805 | /* |
806 | * Check for Oxford Semiconductor 16C950. | 806 | * Check for Oxford Semiconductor 16C950. |
807 | * | 807 | * |
808 | * EFR [4] must be set else this test fails. | 808 | * EFR [4] must be set else this test fails. |
809 | * | 809 | * |
810 | * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca) | 810 | * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca) |
811 | * claims that it's needed for 952 dual UART's (which are not | 811 | * claims that it's needed for 952 dual UART's (which are not |
812 | * recommended for new designs). | 812 | * recommended for new designs). |
813 | */ | 813 | */ |
814 | up->acr = 0; | 814 | up->acr = 0; |
815 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 815 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
816 | serial_out(up, UART_EFR, UART_EFR_ECB); | 816 | serial_out(up, UART_EFR, UART_EFR_ECB); |
817 | serial_out(up, UART_LCR, 0x00); | 817 | serial_out(up, UART_LCR, 0x00); |
818 | id1 = serial_icr_read(up, UART_ID1); | 818 | id1 = serial_icr_read(up, UART_ID1); |
819 | id2 = serial_icr_read(up, UART_ID2); | 819 | id2 = serial_icr_read(up, UART_ID2); |
820 | id3 = serial_icr_read(up, UART_ID3); | 820 | id3 = serial_icr_read(up, UART_ID3); |
821 | rev = serial_icr_read(up, UART_REV); | 821 | rev = serial_icr_read(up, UART_REV); |
822 | 822 | ||
823 | DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev); | 823 | DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev); |
824 | 824 | ||
825 | if (id1 == 0x16 && id2 == 0xC9 && | 825 | if (id1 == 0x16 && id2 == 0xC9 && |
826 | (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) { | 826 | (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) { |
827 | up->port.type = PORT_16C950; | 827 | up->port.type = PORT_16C950; |
828 | 828 | ||
829 | /* | 829 | /* |
830 | * Enable work around for the Oxford Semiconductor 952 rev B | 830 | * Enable work around for the Oxford Semiconductor 952 rev B |
831 | * chip which causes it to seriously miscalculate baud rates | 831 | * chip which causes it to seriously miscalculate baud rates |
832 | * when DLL is 0. | 832 | * when DLL is 0. |
833 | */ | 833 | */ |
834 | if (id3 == 0x52 && rev == 0x01) | 834 | if (id3 == 0x52 && rev == 0x01) |
835 | up->bugs |= UART_BUG_QUOT; | 835 | up->bugs |= UART_BUG_QUOT; |
836 | return; | 836 | return; |
837 | } | 837 | } |
838 | 838 | ||
839 | /* | 839 | /* |
840 | * We check for a XR16C850 by setting DLL and DLM to 0, and then | 840 | * We check for a XR16C850 by setting DLL and DLM to 0, and then |
841 | * reading back DLL and DLM. The chip type depends on the DLM | 841 | * reading back DLL and DLM. The chip type depends on the DLM |
842 | * value read back: | 842 | * value read back: |
843 | * 0x10 - XR16C850 and the DLL contains the chip revision. | 843 | * 0x10 - XR16C850 and the DLL contains the chip revision. |
844 | * 0x12 - XR16C2850. | 844 | * 0x12 - XR16C2850. |
845 | * 0x14 - XR16C854. | 845 | * 0x14 - XR16C854. |
846 | */ | 846 | */ |
847 | id1 = autoconfig_read_divisor_id(up); | 847 | id1 = autoconfig_read_divisor_id(up); |
848 | DEBUG_AUTOCONF("850id=%04x ", id1); | 848 | DEBUG_AUTOCONF("850id=%04x ", id1); |
849 | 849 | ||
850 | id2 = id1 >> 8; | 850 | id2 = id1 >> 8; |
851 | if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) { | 851 | if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) { |
852 | up->port.type = PORT_16850; | 852 | up->port.type = PORT_16850; |
853 | return; | 853 | return; |
854 | } | 854 | } |
855 | 855 | ||
856 | /* | 856 | /* |
857 | * It wasn't an XR16C850. | 857 | * It wasn't an XR16C850. |
858 | * | 858 | * |
859 | * We distinguish between the '654 and the '650 by counting | 859 | * We distinguish between the '654 and the '650 by counting |
860 | * how many bytes are in the FIFO. I'm using this for now, | 860 | * how many bytes are in the FIFO. I'm using this for now, |
861 | * since that's the technique that was sent to me in the | 861 | * since that's the technique that was sent to me in the |
862 | * serial driver update, but I'm not convinced this works. | 862 | * serial driver update, but I'm not convinced this works. |
863 | * I've had problems doing this in the past. -TYT | 863 | * I've had problems doing this in the past. -TYT |
864 | */ | 864 | */ |
865 | if (size_fifo(up) == 64) | 865 | if (size_fifo(up) == 64) |
866 | up->port.type = PORT_16654; | 866 | up->port.type = PORT_16654; |
867 | else | 867 | else |
868 | up->port.type = PORT_16650V2; | 868 | up->port.type = PORT_16650V2; |
869 | } | 869 | } |
870 | 870 | ||
871 | /* | 871 | /* |
872 | * We detected a chip without a FIFO. Only two fall into | 872 | * We detected a chip without a FIFO. Only two fall into |
873 | * this category - the original 8250 and the 16450. The | 873 | * this category - the original 8250 and the 16450. The |
874 | * 16450 has a scratch register (accessible with LCR=0) | 874 | * 16450 has a scratch register (accessible with LCR=0) |
875 | */ | 875 | */ |
876 | static void autoconfig_8250(struct uart_8250_port *up) | 876 | static void autoconfig_8250(struct uart_8250_port *up) |
877 | { | 877 | { |
878 | unsigned char scratch, status1, status2; | 878 | unsigned char scratch, status1, status2; |
879 | 879 | ||
880 | up->port.type = PORT_8250; | 880 | up->port.type = PORT_8250; |
881 | 881 | ||
882 | scratch = serial_in(up, UART_SCR); | 882 | scratch = serial_in(up, UART_SCR); |
883 | serial_out(up, UART_SCR, 0xa5); | 883 | serial_out(up, UART_SCR, 0xa5); |
884 | status1 = serial_in(up, UART_SCR); | 884 | status1 = serial_in(up, UART_SCR); |
885 | serial_out(up, UART_SCR, 0x5a); | 885 | serial_out(up, UART_SCR, 0x5a); |
886 | status2 = serial_in(up, UART_SCR); | 886 | status2 = serial_in(up, UART_SCR); |
887 | serial_out(up, UART_SCR, scratch); | 887 | serial_out(up, UART_SCR, scratch); |
888 | 888 | ||
889 | if (status1 == 0xa5 && status2 == 0x5a) | 889 | if (status1 == 0xa5 && status2 == 0x5a) |
890 | up->port.type = PORT_16450; | 890 | up->port.type = PORT_16450; |
891 | } | 891 | } |
892 | 892 | ||
893 | static int broken_efr(struct uart_8250_port *up) | 893 | static int broken_efr(struct uart_8250_port *up) |
894 | { | 894 | { |
895 | /* | 895 | /* |
896 | * Exar ST16C2550 "A2" devices incorrectly detect as | 896 | * Exar ST16C2550 "A2" devices incorrectly detect as |
897 | * having an EFR, and report an ID of 0x0201. See | 897 | * having an EFR, and report an ID of 0x0201. See |
898 | * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html | 898 | * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html |
899 | */ | 899 | */ |
900 | if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16) | 900 | if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16) |
901 | return 1; | 901 | return 1; |
902 | 902 | ||
903 | return 0; | 903 | return 0; |
904 | } | 904 | } |
905 | 905 | ||
906 | static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) | 906 | static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) |
907 | { | 907 | { |
908 | unsigned char status; | 908 | unsigned char status; |
909 | 909 | ||
910 | status = serial_in(up, 0x04); /* EXCR2 */ | 910 | status = serial_in(up, 0x04); /* EXCR2 */ |
911 | #define PRESL(x) ((x) & 0x30) | 911 | #define PRESL(x) ((x) & 0x30) |
912 | if (PRESL(status) == 0x10) { | 912 | if (PRESL(status) == 0x10) { |
913 | /* already in high speed mode */ | 913 | /* already in high speed mode */ |
914 | return 0; | 914 | return 0; |
915 | } else { | 915 | } else { |
916 | status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ | 916 | status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ |
917 | status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ | 917 | status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ |
918 | serial_out(up, 0x04, status); | 918 | serial_out(up, 0x04, status); |
919 | } | 919 | } |
920 | return 1; | 920 | return 1; |
921 | } | 921 | } |
922 | 922 | ||
923 | /* | 923 | /* |
924 | * We know that the chip has FIFOs. Does it have an EFR? The | 924 | * We know that the chip has FIFOs. Does it have an EFR? The |
925 | * EFR is located in the same register position as the IIR and | 925 | * EFR is located in the same register position as the IIR and |
926 | * we know the top two bits of the IIR are currently set. The | 926 | * we know the top two bits of the IIR are currently set. The |
927 | * EFR should contain zero. Try to read the EFR. | 927 | * EFR should contain zero. Try to read the EFR. |
928 | */ | 928 | */ |
929 | static void autoconfig_16550a(struct uart_8250_port *up) | 929 | static void autoconfig_16550a(struct uart_8250_port *up) |
930 | { | 930 | { |
931 | unsigned char status1, status2; | 931 | unsigned char status1, status2; |
932 | unsigned int iersave; | 932 | unsigned int iersave; |
933 | 933 | ||
934 | up->port.type = PORT_16550A; | 934 | up->port.type = PORT_16550A; |
935 | up->capabilities |= UART_CAP_FIFO; | 935 | up->capabilities |= UART_CAP_FIFO; |
936 | 936 | ||
937 | /* | 937 | /* |
938 | * XR17V35x UARTs have an extra divisor register, DLD | 938 | * XR17V35x UARTs have an extra divisor register, DLD |
939 | * that gets enabled with when DLAB is set which will | 939 | * that gets enabled with when DLAB is set which will |
940 | * cause the device to incorrectly match and assign | 940 | * cause the device to incorrectly match and assign |
941 | * port type to PORT_16650. The EFR for this UART is | 941 | * port type to PORT_16650. The EFR for this UART is |
942 | * found at offset 0x09. Instead check the Deice ID (DVID) | 942 | * found at offset 0x09. Instead check the Deice ID (DVID) |
943 | * register for a 2, 4 or 8 port UART. | 943 | * register for a 2, 4 or 8 port UART. |
944 | */ | 944 | */ |
945 | if (up->port.flags & UPF_EXAR_EFR) { | 945 | if (up->port.flags & UPF_EXAR_EFR) { |
946 | status1 = serial_in(up, UART_EXAR_DVID); | 946 | status1 = serial_in(up, UART_EXAR_DVID); |
947 | if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) { | 947 | if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) { |
948 | DEBUG_AUTOCONF("Exar XR17V35x "); | 948 | DEBUG_AUTOCONF("Exar XR17V35x "); |
949 | up->port.type = PORT_XR17V35X; | 949 | up->port.type = PORT_XR17V35X; |
950 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | | 950 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | |
951 | UART_CAP_SLEEP; | 951 | UART_CAP_SLEEP; |
952 | 952 | ||
953 | return; | 953 | return; |
954 | } | 954 | } |
955 | 955 | ||
956 | } | 956 | } |
957 | 957 | ||
958 | /* | 958 | /* |
959 | * Check for presence of the EFR when DLAB is set. | 959 | * Check for presence of the EFR when DLAB is set. |
960 | * Only ST16C650V1 UARTs pass this test. | 960 | * Only ST16C650V1 UARTs pass this test. |
961 | */ | 961 | */ |
962 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 962 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
963 | if (serial_in(up, UART_EFR) == 0) { | 963 | if (serial_in(up, UART_EFR) == 0) { |
964 | serial_out(up, UART_EFR, 0xA8); | 964 | serial_out(up, UART_EFR, 0xA8); |
965 | if (serial_in(up, UART_EFR) != 0) { | 965 | if (serial_in(up, UART_EFR) != 0) { |
966 | DEBUG_AUTOCONF("EFRv1 "); | 966 | DEBUG_AUTOCONF("EFRv1 "); |
967 | up->port.type = PORT_16650; | 967 | up->port.type = PORT_16650; |
968 | up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; | 968 | up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; |
969 | } else { | 969 | } else { |
970 | serial_out(up, UART_LCR, 0); | 970 | serial_out(up, UART_LCR, 0); |
971 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | | 971 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | |
972 | UART_FCR7_64BYTE); | 972 | UART_FCR7_64BYTE); |
973 | status1 = serial_in(up, UART_IIR) >> 5; | 973 | status1 = serial_in(up, UART_IIR) >> 5; |
974 | serial_out(up, UART_FCR, 0); | 974 | serial_out(up, UART_FCR, 0); |
975 | serial_out(up, UART_LCR, 0); | 975 | serial_out(up, UART_LCR, 0); |
976 | 976 | ||
977 | if (status1 == 7) | 977 | if (status1 == 7) |
978 | up->port.type = PORT_16550A_FSL64; | 978 | up->port.type = PORT_16550A_FSL64; |
979 | else | 979 | else |
980 | DEBUG_AUTOCONF("Motorola 8xxx DUART "); | 980 | DEBUG_AUTOCONF("Motorola 8xxx DUART "); |
981 | } | 981 | } |
982 | serial_out(up, UART_EFR, 0); | 982 | serial_out(up, UART_EFR, 0); |
983 | return; | 983 | return; |
984 | } | 984 | } |
985 | 985 | ||
986 | /* | 986 | /* |
987 | * Maybe it requires 0xbf to be written to the LCR. | 987 | * Maybe it requires 0xbf to be written to the LCR. |
988 | * (other ST16C650V2 UARTs, TI16C752A, etc) | 988 | * (other ST16C650V2 UARTs, TI16C752A, etc) |
989 | */ | 989 | */ |
990 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 990 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
991 | if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { | 991 | if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { |
992 | DEBUG_AUTOCONF("EFRv2 "); | 992 | DEBUG_AUTOCONF("EFRv2 "); |
993 | autoconfig_has_efr(up); | 993 | autoconfig_has_efr(up); |
994 | return; | 994 | return; |
995 | } | 995 | } |
996 | 996 | ||
997 | /* | 997 | /* |
998 | * Check for a National Semiconductor SuperIO chip. | 998 | * Check for a National Semiconductor SuperIO chip. |
999 | * Attempt to switch to bank 2, read the value of the LOOP bit | 999 | * Attempt to switch to bank 2, read the value of the LOOP bit |
1000 | * from EXCR1. Switch back to bank 0, change it in MCR. Then | 1000 | * from EXCR1. Switch back to bank 0, change it in MCR. Then |
1001 | * switch back to bank 2, read it from EXCR1 again and check | 1001 | * switch back to bank 2, read it from EXCR1 again and check |
1002 | * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 | 1002 | * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 |
1003 | */ | 1003 | */ |
1004 | serial_out(up, UART_LCR, 0); | 1004 | serial_out(up, UART_LCR, 0); |
1005 | status1 = serial_in(up, UART_MCR); | 1005 | status1 = serial_in(up, UART_MCR); |
1006 | serial_out(up, UART_LCR, 0xE0); | 1006 | serial_out(up, UART_LCR, 0xE0); |
1007 | status2 = serial_in(up, 0x02); /* EXCR1 */ | 1007 | status2 = serial_in(up, 0x02); /* EXCR1 */ |
1008 | 1008 | ||
1009 | if (!((status2 ^ status1) & UART_MCR_LOOP)) { | 1009 | if (!((status2 ^ status1) & UART_MCR_LOOP)) { |
1010 | serial_out(up, UART_LCR, 0); | 1010 | serial_out(up, UART_LCR, 0); |
1011 | serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP); | 1011 | serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP); |
1012 | serial_out(up, UART_LCR, 0xE0); | 1012 | serial_out(up, UART_LCR, 0xE0); |
1013 | status2 = serial_in(up, 0x02); /* EXCR1 */ | 1013 | status2 = serial_in(up, 0x02); /* EXCR1 */ |
1014 | serial_out(up, UART_LCR, 0); | 1014 | serial_out(up, UART_LCR, 0); |
1015 | serial_out(up, UART_MCR, status1); | 1015 | serial_out(up, UART_MCR, status1); |
1016 | 1016 | ||
1017 | if ((status2 ^ status1) & UART_MCR_LOOP) { | 1017 | if ((status2 ^ status1) & UART_MCR_LOOP) { |
1018 | unsigned short quot; | 1018 | unsigned short quot; |
1019 | 1019 | ||
1020 | serial_out(up, UART_LCR, 0xE0); | 1020 | serial_out(up, UART_LCR, 0xE0); |
1021 | 1021 | ||
1022 | quot = serial_dl_read(up); | 1022 | quot = serial_dl_read(up); |
1023 | quot <<= 3; | 1023 | quot <<= 3; |
1024 | 1024 | ||
1025 | if (ns16550a_goto_highspeed(up)) | 1025 | if (ns16550a_goto_highspeed(up)) |
1026 | serial_dl_write(up, quot); | 1026 | serial_dl_write(up, quot); |
1027 | 1027 | ||
1028 | serial_out(up, UART_LCR, 0); | 1028 | serial_out(up, UART_LCR, 0); |
1029 | 1029 | ||
1030 | up->port.uartclk = 921600*16; | 1030 | up->port.uartclk = 921600*16; |
1031 | up->port.type = PORT_NS16550A; | 1031 | up->port.type = PORT_NS16550A; |
1032 | up->capabilities |= UART_NATSEMI; | 1032 | up->capabilities |= UART_NATSEMI; |
1033 | return; | 1033 | return; |
1034 | } | 1034 | } |
1035 | } | 1035 | } |
1036 | 1036 | ||
1037 | /* | 1037 | /* |
1038 | * No EFR. Try to detect a TI16750, which only sets bit 5 of | 1038 | * No EFR. Try to detect a TI16750, which only sets bit 5 of |
1039 | * the IIR when 64 byte FIFO mode is enabled when DLAB is set. | 1039 | * the IIR when 64 byte FIFO mode is enabled when DLAB is set. |
1040 | * Try setting it with and without DLAB set. Cheap clones | 1040 | * Try setting it with and without DLAB set. Cheap clones |
1041 | * set bit 5 without DLAB set. | 1041 | * set bit 5 without DLAB set. |
1042 | */ | 1042 | */ |
1043 | serial_out(up, UART_LCR, 0); | 1043 | serial_out(up, UART_LCR, 0); |
1044 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); | 1044 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); |
1045 | status1 = serial_in(up, UART_IIR) >> 5; | 1045 | status1 = serial_in(up, UART_IIR) >> 5; |
1046 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 1046 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
1047 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 1047 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
1048 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); | 1048 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); |
1049 | status2 = serial_in(up, UART_IIR) >> 5; | 1049 | status2 = serial_in(up, UART_IIR) >> 5; |
1050 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 1050 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
1051 | serial_out(up, UART_LCR, 0); | 1051 | serial_out(up, UART_LCR, 0); |
1052 | 1052 | ||
1053 | DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); | 1053 | DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); |
1054 | 1054 | ||
1055 | if (status1 == 6 && status2 == 7) { | 1055 | if (status1 == 6 && status2 == 7) { |
1056 | up->port.type = PORT_16750; | 1056 | up->port.type = PORT_16750; |
1057 | up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; | 1057 | up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; |
1058 | return; | 1058 | return; |
1059 | } | 1059 | } |
1060 | 1060 | ||
1061 | /* | 1061 | /* |
1062 | * Try writing and reading the UART_IER_UUE bit (b6). | 1062 | * Try writing and reading the UART_IER_UUE bit (b6). |
1063 | * If it works, this is probably one of the Xscale platform's | 1063 | * If it works, this is probably one of the Xscale platform's |
1064 | * internal UARTs. | 1064 | * internal UARTs. |
1065 | * We're going to explicitly set the UUE bit to 0 before | 1065 | * We're going to explicitly set the UUE bit to 0 before |
1066 | * trying to write and read a 1 just to make sure it's not | 1066 | * trying to write and read a 1 just to make sure it's not |
1067 | * already a 1 and maybe locked there before we even start start. | 1067 | * already a 1 and maybe locked there before we even start start. |
1068 | */ | 1068 | */ |
1069 | iersave = serial_in(up, UART_IER); | 1069 | iersave = serial_in(up, UART_IER); |
1070 | serial_out(up, UART_IER, iersave & ~UART_IER_UUE); | 1070 | serial_out(up, UART_IER, iersave & ~UART_IER_UUE); |
1071 | if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { | 1071 | if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { |
1072 | /* | 1072 | /* |
1073 | * OK it's in a known zero state, try writing and reading | 1073 | * OK it's in a known zero state, try writing and reading |
1074 | * without disturbing the current state of the other bits. | 1074 | * without disturbing the current state of the other bits. |
1075 | */ | 1075 | */ |
1076 | serial_out(up, UART_IER, iersave | UART_IER_UUE); | 1076 | serial_out(up, UART_IER, iersave | UART_IER_UUE); |
1077 | if (serial_in(up, UART_IER) & UART_IER_UUE) { | 1077 | if (serial_in(up, UART_IER) & UART_IER_UUE) { |
1078 | /* | 1078 | /* |
1079 | * It's an Xscale. | 1079 | * It's an Xscale. |
1080 | * We'll leave the UART_IER_UUE bit set to 1 (enabled). | 1080 | * We'll leave the UART_IER_UUE bit set to 1 (enabled). |
1081 | */ | 1081 | */ |
1082 | DEBUG_AUTOCONF("Xscale "); | 1082 | DEBUG_AUTOCONF("Xscale "); |
1083 | up->port.type = PORT_XSCALE; | 1083 | up->port.type = PORT_XSCALE; |
1084 | up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE; | 1084 | up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE; |
1085 | return; | 1085 | return; |
1086 | } | 1086 | } |
1087 | } else { | 1087 | } else { |
1088 | /* | 1088 | /* |
1089 | * If we got here we couldn't force the IER_UUE bit to 0. | 1089 | * If we got here we couldn't force the IER_UUE bit to 0. |
1090 | * Log it and continue. | 1090 | * Log it and continue. |
1091 | */ | 1091 | */ |
1092 | DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); | 1092 | DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); |
1093 | } | 1093 | } |
1094 | serial_out(up, UART_IER, iersave); | 1094 | serial_out(up, UART_IER, iersave); |
1095 | 1095 | ||
1096 | /* | 1096 | /* |
1097 | * Exar uarts have EFR in a weird location | 1097 | * Exar uarts have EFR in a weird location |
1098 | */ | 1098 | */ |
1099 | if (up->port.flags & UPF_EXAR_EFR) { | 1099 | if (up->port.flags & UPF_EXAR_EFR) { |
1100 | DEBUG_AUTOCONF("Exar XR17D15x "); | 1100 | DEBUG_AUTOCONF("Exar XR17D15x "); |
1101 | up->port.type = PORT_XR17D15X; | 1101 | up->port.type = PORT_XR17D15X; |
1102 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | | 1102 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | |
1103 | UART_CAP_SLEEP; | 1103 | UART_CAP_SLEEP; |
1104 | 1104 | ||
1105 | return; | 1105 | return; |
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | /* | 1108 | /* |
1109 | * We distinguish between 16550A and U6 16550A by counting | 1109 | * We distinguish between 16550A and U6 16550A by counting |
1110 | * how many bytes are in the FIFO. | 1110 | * how many bytes are in the FIFO. |
1111 | */ | 1111 | */ |
1112 | if (up->port.type == PORT_16550A && size_fifo(up) == 64) { | 1112 | if (up->port.type == PORT_16550A && size_fifo(up) == 64) { |
1113 | up->port.type = PORT_U6_16550A; | 1113 | up->port.type = PORT_U6_16550A; |
1114 | up->capabilities |= UART_CAP_AFE; | 1114 | up->capabilities |= UART_CAP_AFE; |
1115 | } | 1115 | } |
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | /* | 1118 | /* |
1119 | * This routine is called by rs_init() to initialize a specific serial | 1119 | * This routine is called by rs_init() to initialize a specific serial |
1120 | * port. It determines what type of UART chip this serial port is | 1120 | * port. It determines what type of UART chip this serial port is |
1121 | * using: 8250, 16450, 16550, 16550A. The important question is | 1121 | * using: 8250, 16450, 16550, 16550A. The important question is |
1122 | * whether or not this UART is a 16550A or not, since this will | 1122 | * whether or not this UART is a 16550A or not, since this will |
1123 | * determine whether or not we can use its FIFO features or not. | 1123 | * determine whether or not we can use its FIFO features or not. |
1124 | */ | 1124 | */ |
1125 | static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | 1125 | static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) |
1126 | { | 1126 | { |
1127 | unsigned char status1, scratch, scratch2, scratch3; | 1127 | unsigned char status1, scratch, scratch2, scratch3; |
1128 | unsigned char save_lcr, save_mcr; | 1128 | unsigned char save_lcr, save_mcr; |
1129 | struct uart_port *port = &up->port; | 1129 | struct uart_port *port = &up->port; |
1130 | unsigned long flags; | 1130 | unsigned long flags; |
1131 | unsigned int old_capabilities; | 1131 | unsigned int old_capabilities; |
1132 | 1132 | ||
1133 | if (!port->iobase && !port->mapbase && !port->membase) | 1133 | if (!port->iobase && !port->mapbase && !port->membase) |
1134 | return; | 1134 | return; |
1135 | 1135 | ||
1136 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", | 1136 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", |
1137 | serial_index(port), port->iobase, port->membase); | 1137 | serial_index(port), port->iobase, port->membase); |
1138 | 1138 | ||
1139 | /* | 1139 | /* |
1140 | * We really do need global IRQs disabled here - we're going to | 1140 | * We really do need global IRQs disabled here - we're going to |
1141 | * be frobbing the chips IRQ enable register to see if it exists. | 1141 | * be frobbing the chips IRQ enable register to see if it exists. |
1142 | */ | 1142 | */ |
1143 | spin_lock_irqsave(&port->lock, flags); | 1143 | spin_lock_irqsave(&port->lock, flags); |
1144 | 1144 | ||
1145 | up->capabilities = 0; | 1145 | up->capabilities = 0; |
1146 | up->bugs = 0; | 1146 | up->bugs = 0; |
1147 | 1147 | ||
1148 | if (!(port->flags & UPF_BUGGY_UART)) { | 1148 | if (!(port->flags & UPF_BUGGY_UART)) { |
1149 | /* | 1149 | /* |
1150 | * Do a simple existence test first; if we fail this, | 1150 | * Do a simple existence test first; if we fail this, |
1151 | * there's no point trying anything else. | 1151 | * there's no point trying anything else. |
1152 | * | 1152 | * |
1153 | * 0x80 is used as a nonsense port to prevent against | 1153 | * 0x80 is used as a nonsense port to prevent against |
1154 | * false positives due to ISA bus float. The | 1154 | * false positives due to ISA bus float. The |
1155 | * assumption is that 0x80 is a non-existent port; | 1155 | * assumption is that 0x80 is a non-existent port; |
1156 | * which should be safe since include/asm/io.h also | 1156 | * which should be safe since include/asm/io.h also |
1157 | * makes this assumption. | 1157 | * makes this assumption. |
1158 | * | 1158 | * |
1159 | * Note: this is safe as long as MCR bit 4 is clear | 1159 | * Note: this is safe as long as MCR bit 4 is clear |
1160 | * and the device is in "PC" mode. | 1160 | * and the device is in "PC" mode. |
1161 | */ | 1161 | */ |
1162 | scratch = serial_in(up, UART_IER); | 1162 | scratch = serial_in(up, UART_IER); |
1163 | serial_out(up, UART_IER, 0); | 1163 | serial_out(up, UART_IER, 0); |
1164 | #ifdef __i386__ | 1164 | #ifdef __i386__ |
1165 | outb(0xff, 0x080); | 1165 | outb(0xff, 0x080); |
1166 | #endif | 1166 | #endif |
1167 | /* | 1167 | /* |
1168 | * Mask out IER[7:4] bits for test as some UARTs (e.g. TL | 1168 | * Mask out IER[7:4] bits for test as some UARTs (e.g. TL |
1169 | * 16C754B) allow only to modify them if an EFR bit is set. | 1169 | * 16C754B) allow only to modify them if an EFR bit is set. |
1170 | */ | 1170 | */ |
1171 | scratch2 = serial_in(up, UART_IER) & 0x0f; | 1171 | scratch2 = serial_in(up, UART_IER) & 0x0f; |
1172 | serial_out(up, UART_IER, 0x0F); | 1172 | serial_out(up, UART_IER, 0x0F); |
1173 | #ifdef __i386__ | 1173 | #ifdef __i386__ |
1174 | outb(0, 0x080); | 1174 | outb(0, 0x080); |
1175 | #endif | 1175 | #endif |
1176 | scratch3 = serial_in(up, UART_IER) & 0x0f; | 1176 | scratch3 = serial_in(up, UART_IER) & 0x0f; |
1177 | serial_out(up, UART_IER, scratch); | 1177 | serial_out(up, UART_IER, scratch); |
1178 | if (scratch2 != 0 || scratch3 != 0x0F) { | 1178 | if (scratch2 != 0 || scratch3 != 0x0F) { |
1179 | /* | 1179 | /* |
1180 | * We failed; there's nothing here | 1180 | * We failed; there's nothing here |
1181 | */ | 1181 | */ |
1182 | spin_unlock_irqrestore(&port->lock, flags); | 1182 | spin_unlock_irqrestore(&port->lock, flags); |
1183 | DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", | 1183 | DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", |
1184 | scratch2, scratch3); | 1184 | scratch2, scratch3); |
1185 | goto out; | 1185 | goto out; |
1186 | } | 1186 | } |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | save_mcr = serial_in(up, UART_MCR); | 1189 | save_mcr = serial_in(up, UART_MCR); |
1190 | save_lcr = serial_in(up, UART_LCR); | 1190 | save_lcr = serial_in(up, UART_LCR); |
1191 | 1191 | ||
1192 | /* | 1192 | /* |
1193 | * Check to see if a UART is really there. Certain broken | 1193 | * Check to see if a UART is really there. Certain broken |
1194 | * internal modems based on the Rockwell chipset fail this | 1194 | * internal modems based on the Rockwell chipset fail this |
1195 | * test, because they apparently don't implement the loopback | 1195 | * test, because they apparently don't implement the loopback |
1196 | * test mode. So this test is skipped on the COM 1 through | 1196 | * test mode. So this test is skipped on the COM 1 through |
1197 | * COM 4 ports. This *should* be safe, since no board | 1197 | * COM 4 ports. This *should* be safe, since no board |
1198 | * manufacturer would be stupid enough to design a board | 1198 | * manufacturer would be stupid enough to design a board |
1199 | * that conflicts with COM 1-4 --- we hope! | 1199 | * that conflicts with COM 1-4 --- we hope! |
1200 | */ | 1200 | */ |
1201 | if (!(port->flags & UPF_SKIP_TEST)) { | 1201 | if (!(port->flags & UPF_SKIP_TEST)) { |
1202 | serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A); | 1202 | serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A); |
1203 | status1 = serial_in(up, UART_MSR) & 0xF0; | 1203 | status1 = serial_in(up, UART_MSR) & 0xF0; |
1204 | serial_out(up, UART_MCR, save_mcr); | 1204 | serial_out(up, UART_MCR, save_mcr); |
1205 | if (status1 != 0x90) { | 1205 | if (status1 != 0x90) { |
1206 | spin_unlock_irqrestore(&port->lock, flags); | 1206 | spin_unlock_irqrestore(&port->lock, flags); |
1207 | DEBUG_AUTOCONF("LOOP test failed (%02x) ", | 1207 | DEBUG_AUTOCONF("LOOP test failed (%02x) ", |
1208 | status1); | 1208 | status1); |
1209 | goto out; | 1209 | goto out; |
1210 | } | 1210 | } |
1211 | } | 1211 | } |
1212 | 1212 | ||
1213 | /* | 1213 | /* |
1214 | * We're pretty sure there's a port here. Lets find out what | 1214 | * We're pretty sure there's a port here. Lets find out what |
1215 | * type of port it is. The IIR top two bits allows us to find | 1215 | * type of port it is. The IIR top two bits allows us to find |
1216 | * out if it's 8250 or 16450, 16550, 16550A or later. This | 1216 | * out if it's 8250 or 16450, 16550, 16550A or later. This |
1217 | * determines what we test for next. | 1217 | * determines what we test for next. |
1218 | * | 1218 | * |
1219 | * We also initialise the EFR (if any) to zero for later. The | 1219 | * We also initialise the EFR (if any) to zero for later. The |
1220 | * EFR occupies the same register location as the FCR and IIR. | 1220 | * EFR occupies the same register location as the FCR and IIR. |
1221 | */ | 1221 | */ |
1222 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 1222 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
1223 | serial_out(up, UART_EFR, 0); | 1223 | serial_out(up, UART_EFR, 0); |
1224 | serial_out(up, UART_LCR, 0); | 1224 | serial_out(up, UART_LCR, 0); |
1225 | 1225 | ||
1226 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 1226 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
1227 | scratch = serial_in(up, UART_IIR) >> 6; | 1227 | scratch = serial_in(up, UART_IIR) >> 6; |
1228 | 1228 | ||
1229 | switch (scratch) { | 1229 | switch (scratch) { |
1230 | case 0: | 1230 | case 0: |
1231 | autoconfig_8250(up); | 1231 | autoconfig_8250(up); |
1232 | break; | 1232 | break; |
1233 | case 1: | 1233 | case 1: |
1234 | port->type = PORT_UNKNOWN; | 1234 | port->type = PORT_UNKNOWN; |
1235 | break; | 1235 | break; |
1236 | case 2: | 1236 | case 2: |
1237 | port->type = PORT_16550; | 1237 | port->type = PORT_16550; |
1238 | break; | 1238 | break; |
1239 | case 3: | 1239 | case 3: |
1240 | autoconfig_16550a(up); | 1240 | autoconfig_16550a(up); |
1241 | break; | 1241 | break; |
1242 | } | 1242 | } |
1243 | 1243 | ||
1244 | #ifdef CONFIG_SERIAL_8250_RSA | 1244 | #ifdef CONFIG_SERIAL_8250_RSA |
1245 | /* | 1245 | /* |
1246 | * Only probe for RSA ports if we got the region. | 1246 | * Only probe for RSA ports if we got the region. |
1247 | */ | 1247 | */ |
1248 | if (port->type == PORT_16550A && probeflags & PROBE_RSA) { | 1248 | if (port->type == PORT_16550A && probeflags & PROBE_RSA) { |
1249 | int i; | 1249 | int i; |
1250 | 1250 | ||
1251 | for (i = 0 ; i < probe_rsa_count; ++i) { | 1251 | for (i = 0 ; i < probe_rsa_count; ++i) { |
1252 | if (probe_rsa[i] == port->iobase && __enable_rsa(up)) { | 1252 | if (probe_rsa[i] == port->iobase && __enable_rsa(up)) { |
1253 | port->type = PORT_RSA; | 1253 | port->type = PORT_RSA; |
1254 | break; | 1254 | break; |
1255 | } | 1255 | } |
1256 | } | 1256 | } |
1257 | } | 1257 | } |
1258 | #endif | 1258 | #endif |
1259 | 1259 | ||
1260 | serial_out(up, UART_LCR, save_lcr); | 1260 | serial_out(up, UART_LCR, save_lcr); |
1261 | 1261 | ||
1262 | port->fifosize = uart_config[up->port.type].fifo_size; | 1262 | port->fifosize = uart_config[up->port.type].fifo_size; |
1263 | old_capabilities = up->capabilities; | 1263 | old_capabilities = up->capabilities; |
1264 | up->capabilities = uart_config[port->type].flags; | 1264 | up->capabilities = uart_config[port->type].flags; |
1265 | up->tx_loadsz = uart_config[port->type].tx_loadsz; | 1265 | up->tx_loadsz = uart_config[port->type].tx_loadsz; |
1266 | 1266 | ||
1267 | if (port->type == PORT_UNKNOWN) | 1267 | if (port->type == PORT_UNKNOWN) |
1268 | goto out_lock; | 1268 | goto out_lock; |
1269 | 1269 | ||
1270 | /* | 1270 | /* |
1271 | * Reset the UART. | 1271 | * Reset the UART. |
1272 | */ | 1272 | */ |
1273 | #ifdef CONFIG_SERIAL_8250_RSA | 1273 | #ifdef CONFIG_SERIAL_8250_RSA |
1274 | if (port->type == PORT_RSA) | 1274 | if (port->type == PORT_RSA) |
1275 | serial_out(up, UART_RSA_FRR, 0); | 1275 | serial_out(up, UART_RSA_FRR, 0); |
1276 | #endif | 1276 | #endif |
1277 | serial_out(up, UART_MCR, save_mcr); | 1277 | serial_out(up, UART_MCR, save_mcr); |
1278 | serial8250_clear_fifos(up); | 1278 | serial8250_clear_fifos(up); |
1279 | serial_in(up, UART_RX); | 1279 | serial_in(up, UART_RX); |
1280 | if (up->capabilities & UART_CAP_UUE) | 1280 | if (up->capabilities & UART_CAP_UUE) |
1281 | serial_out(up, UART_IER, UART_IER_UUE); | 1281 | serial_out(up, UART_IER, UART_IER_UUE); |
1282 | else | 1282 | else |
1283 | serial_out(up, UART_IER, 0); | 1283 | serial_out(up, UART_IER, 0); |
1284 | 1284 | ||
1285 | out_lock: | 1285 | out_lock: |
1286 | spin_unlock_irqrestore(&port->lock, flags); | 1286 | spin_unlock_irqrestore(&port->lock, flags); |
1287 | if (up->capabilities != old_capabilities) { | 1287 | if (up->capabilities != old_capabilities) { |
1288 | printk(KERN_WARNING | 1288 | printk(KERN_WARNING |
1289 | "ttyS%d: detected caps %08x should be %08x\n", | 1289 | "ttyS%d: detected caps %08x should be %08x\n", |
1290 | serial_index(port), old_capabilities, | 1290 | serial_index(port), old_capabilities, |
1291 | up->capabilities); | 1291 | up->capabilities); |
1292 | } | 1292 | } |
1293 | out: | 1293 | out: |
1294 | DEBUG_AUTOCONF("iir=%d ", scratch); | 1294 | DEBUG_AUTOCONF("iir=%d ", scratch); |
1295 | DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name); | 1295 | DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name); |
1296 | } | 1296 | } |
1297 | 1297 | ||
1298 | static void autoconfig_irq(struct uart_8250_port *up) | 1298 | static void autoconfig_irq(struct uart_8250_port *up) |
1299 | { | 1299 | { |
1300 | struct uart_port *port = &up->port; | 1300 | struct uart_port *port = &up->port; |
1301 | unsigned char save_mcr, save_ier; | 1301 | unsigned char save_mcr, save_ier; |
1302 | unsigned char save_ICP = 0; | 1302 | unsigned char save_ICP = 0; |
1303 | unsigned int ICP = 0; | 1303 | unsigned int ICP = 0; |
1304 | unsigned long irqs; | 1304 | unsigned long irqs; |
1305 | int irq; | 1305 | int irq; |
1306 | 1306 | ||
1307 | if (port->flags & UPF_FOURPORT) { | 1307 | if (port->flags & UPF_FOURPORT) { |
1308 | ICP = (port->iobase & 0xfe0) | 0x1f; | 1308 | ICP = (port->iobase & 0xfe0) | 0x1f; |
1309 | save_ICP = inb_p(ICP); | 1309 | save_ICP = inb_p(ICP); |
1310 | outb_p(0x80, ICP); | 1310 | outb_p(0x80, ICP); |
1311 | inb_p(ICP); | 1311 | inb_p(ICP); |
1312 | } | 1312 | } |
1313 | 1313 | ||
1314 | /* forget possible initially masked and pending IRQ */ | 1314 | /* forget possible initially masked and pending IRQ */ |
1315 | probe_irq_off(probe_irq_on()); | 1315 | probe_irq_off(probe_irq_on()); |
1316 | save_mcr = serial_in(up, UART_MCR); | 1316 | save_mcr = serial_in(up, UART_MCR); |
1317 | save_ier = serial_in(up, UART_IER); | 1317 | save_ier = serial_in(up, UART_IER); |
1318 | serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); | 1318 | serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); |
1319 | 1319 | ||
1320 | irqs = probe_irq_on(); | 1320 | irqs = probe_irq_on(); |
1321 | serial_out(up, UART_MCR, 0); | 1321 | serial_out(up, UART_MCR, 0); |
1322 | udelay(10); | 1322 | udelay(10); |
1323 | if (port->flags & UPF_FOURPORT) { | 1323 | if (port->flags & UPF_FOURPORT) { |
1324 | serial_out(up, UART_MCR, | 1324 | serial_out(up, UART_MCR, |
1325 | UART_MCR_DTR | UART_MCR_RTS); | 1325 | UART_MCR_DTR | UART_MCR_RTS); |
1326 | } else { | 1326 | } else { |
1327 | serial_out(up, UART_MCR, | 1327 | serial_out(up, UART_MCR, |
1328 | UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); | 1328 | UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); |
1329 | } | 1329 | } |
1330 | serial_out(up, UART_IER, 0x0f); /* enable all intrs */ | 1330 | serial_out(up, UART_IER, 0x0f); /* enable all intrs */ |
1331 | serial_in(up, UART_LSR); | 1331 | serial_in(up, UART_LSR); |
1332 | serial_in(up, UART_RX); | 1332 | serial_in(up, UART_RX); |
1333 | serial_in(up, UART_IIR); | 1333 | serial_in(up, UART_IIR); |
1334 | serial_in(up, UART_MSR); | 1334 | serial_in(up, UART_MSR); |
1335 | serial_out(up, UART_TX, 0xFF); | 1335 | serial_out(up, UART_TX, 0xFF); |
1336 | udelay(20); | 1336 | udelay(20); |
1337 | irq = probe_irq_off(irqs); | 1337 | irq = probe_irq_off(irqs); |
1338 | 1338 | ||
1339 | serial_out(up, UART_MCR, save_mcr); | 1339 | serial_out(up, UART_MCR, save_mcr); |
1340 | serial_out(up, UART_IER, save_ier); | 1340 | serial_out(up, UART_IER, save_ier); |
1341 | 1341 | ||
1342 | if (port->flags & UPF_FOURPORT) | 1342 | if (port->flags & UPF_FOURPORT) |
1343 | outb_p(save_ICP, ICP); | 1343 | outb_p(save_ICP, ICP); |
1344 | 1344 | ||
1345 | port->irq = (irq > 0) ? irq : 0; | 1345 | port->irq = (irq > 0) ? irq : 0; |
1346 | } | 1346 | } |
1347 | 1347 | ||
1348 | static inline void __stop_tx(struct uart_8250_port *p) | 1348 | static inline void __stop_tx(struct uart_8250_port *p) |
1349 | { | 1349 | { |
1350 | if (p->ier & UART_IER_THRI) { | 1350 | if (p->ier & UART_IER_THRI) { |
1351 | p->ier &= ~UART_IER_THRI; | 1351 | p->ier &= ~UART_IER_THRI; |
1352 | serial_out(p, UART_IER, p->ier); | 1352 | serial_out(p, UART_IER, p->ier); |
1353 | serial8250_rpm_put_tx(p); | 1353 | serial8250_rpm_put_tx(p); |
1354 | } | 1354 | } |
1355 | } | 1355 | } |
1356 | 1356 | ||
1357 | static void serial8250_stop_tx(struct uart_port *port) | 1357 | static void serial8250_stop_tx(struct uart_port *port) |
1358 | { | 1358 | { |
1359 | struct uart_8250_port *up = up_to_u8250p(port); | 1359 | struct uart_8250_port *up = up_to_u8250p(port); |
1360 | 1360 | ||
1361 | serial8250_rpm_get(up); | 1361 | serial8250_rpm_get(up); |
1362 | __stop_tx(up); | 1362 | __stop_tx(up); |
1363 | 1363 | ||
1364 | /* | 1364 | /* |
1365 | * We really want to stop the transmitter from sending. | 1365 | * We really want to stop the transmitter from sending. |
1366 | */ | 1366 | */ |
1367 | if (port->type == PORT_16C950) { | 1367 | if (port->type == PORT_16C950) { |
1368 | up->acr |= UART_ACR_TXDIS; | 1368 | up->acr |= UART_ACR_TXDIS; |
1369 | serial_icr_write(up, UART_ACR, up->acr); | 1369 | serial_icr_write(up, UART_ACR, up->acr); |
1370 | } | 1370 | } |
1371 | serial8250_rpm_put(up); | 1371 | serial8250_rpm_put(up); |
1372 | } | 1372 | } |
1373 | 1373 | ||
1374 | static void serial8250_start_tx(struct uart_port *port) | 1374 | static void serial8250_start_tx(struct uart_port *port) |
1375 | { | 1375 | { |
1376 | struct uart_8250_port *up = up_to_u8250p(port); | 1376 | struct uart_8250_port *up = up_to_u8250p(port); |
1377 | 1377 | ||
1378 | serial8250_rpm_get_tx(up); | 1378 | serial8250_rpm_get_tx(up); |
1379 | 1379 | ||
1380 | if (up->dma && !up->dma->tx_dma(up)) | 1380 | if (up->dma && !up->dma->tx_dma(up)) |
1381 | return; | 1381 | return; |
1382 | 1382 | ||
1383 | if (!(up->ier & UART_IER_THRI)) { | 1383 | if (!(up->ier & UART_IER_THRI)) { |
1384 | up->ier |= UART_IER_THRI; | 1384 | up->ier |= UART_IER_THRI; |
1385 | serial_port_out(port, UART_IER, up->ier); | 1385 | serial_port_out(port, UART_IER, up->ier); |
1386 | 1386 | ||
1387 | if (up->bugs & UART_BUG_TXEN) { | 1387 | if (up->bugs & UART_BUG_TXEN) { |
1388 | unsigned char lsr; | 1388 | unsigned char lsr; |
1389 | lsr = serial_in(up, UART_LSR); | 1389 | lsr = serial_in(up, UART_LSR); |
1390 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1390 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1391 | if (lsr & UART_LSR_THRE) | 1391 | if (lsr & UART_LSR_THRE) |
1392 | serial8250_tx_chars(up); | 1392 | serial8250_tx_chars(up); |
1393 | } | 1393 | } |
1394 | } | 1394 | } |
1395 | 1395 | ||
1396 | /* | 1396 | /* |
1397 | * Re-enable the transmitter if we disabled it. | 1397 | * Re-enable the transmitter if we disabled it. |
1398 | */ | 1398 | */ |
1399 | if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { | 1399 | if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { |
1400 | up->acr &= ~UART_ACR_TXDIS; | 1400 | up->acr &= ~UART_ACR_TXDIS; |
1401 | serial_icr_write(up, UART_ACR, up->acr); | 1401 | serial_icr_write(up, UART_ACR, up->acr); |
1402 | } | 1402 | } |
1403 | } | 1403 | } |
1404 | 1404 | ||
1405 | static void serial8250_throttle(struct uart_port *port) | 1405 | static void serial8250_throttle(struct uart_port *port) |
1406 | { | 1406 | { |
1407 | port->throttle(port); | 1407 | port->throttle(port); |
1408 | } | 1408 | } |
1409 | 1409 | ||
1410 | static void serial8250_unthrottle(struct uart_port *port) | 1410 | static void serial8250_unthrottle(struct uart_port *port) |
1411 | { | 1411 | { |
1412 | port->unthrottle(port); | 1412 | port->unthrottle(port); |
1413 | } | 1413 | } |
1414 | 1414 | ||
1415 | static void serial8250_stop_rx(struct uart_port *port) | 1415 | static void serial8250_stop_rx(struct uart_port *port) |
1416 | { | 1416 | { |
1417 | struct uart_8250_port *up = up_to_u8250p(port); | 1417 | struct uart_8250_port *up = up_to_u8250p(port); |
1418 | 1418 | ||
1419 | serial8250_rpm_get(up); | 1419 | serial8250_rpm_get(up); |
1420 | 1420 | ||
1421 | up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); | 1421 | up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); |
1422 | up->port.read_status_mask &= ~UART_LSR_DR; | 1422 | up->port.read_status_mask &= ~UART_LSR_DR; |
1423 | serial_port_out(port, UART_IER, up->ier); | 1423 | serial_port_out(port, UART_IER, up->ier); |
1424 | 1424 | ||
1425 | serial8250_rpm_put(up); | 1425 | serial8250_rpm_put(up); |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | static void serial8250_disable_ms(struct uart_port *port) | 1428 | static void serial8250_disable_ms(struct uart_port *port) |
1429 | { | 1429 | { |
1430 | struct uart_8250_port *up = | 1430 | struct uart_8250_port *up = |
1431 | container_of(port, struct uart_8250_port, port); | 1431 | container_of(port, struct uart_8250_port, port); |
1432 | 1432 | ||
1433 | /* no MSR capabilities */ | 1433 | /* no MSR capabilities */ |
1434 | if (up->bugs & UART_BUG_NOMSR) | 1434 | if (up->bugs & UART_BUG_NOMSR) |
1435 | return; | 1435 | return; |
1436 | 1436 | ||
1437 | up->ier &= ~UART_IER_MSI; | 1437 | up->ier &= ~UART_IER_MSI; |
1438 | serial_port_out(port, UART_IER, up->ier); | 1438 | serial_port_out(port, UART_IER, up->ier); |
1439 | } | 1439 | } |
1440 | 1440 | ||
1441 | static void serial8250_enable_ms(struct uart_port *port) | 1441 | static void serial8250_enable_ms(struct uart_port *port) |
1442 | { | 1442 | { |
1443 | struct uart_8250_port *up = up_to_u8250p(port); | 1443 | struct uart_8250_port *up = up_to_u8250p(port); |
1444 | 1444 | ||
1445 | /* no MSR capabilities */ | 1445 | /* no MSR capabilities */ |
1446 | if (up->bugs & UART_BUG_NOMSR) | 1446 | if (up->bugs & UART_BUG_NOMSR) |
1447 | return; | 1447 | return; |
1448 | 1448 | ||
1449 | up->ier |= UART_IER_MSI; | 1449 | up->ier |= UART_IER_MSI; |
1450 | 1450 | ||
1451 | serial8250_rpm_get(up); | 1451 | serial8250_rpm_get(up); |
1452 | serial_port_out(port, UART_IER, up->ier); | 1452 | serial_port_out(port, UART_IER, up->ier); |
1453 | serial8250_rpm_put(up); | 1453 | serial8250_rpm_put(up); |
1454 | } | 1454 | } |
1455 | 1455 | ||
1456 | /* | 1456 | /* |
1457 | * serial8250_rx_chars: processes according to the passed in LSR | 1457 | * serial8250_rx_chars: processes according to the passed in LSR |
1458 | * value, and returns the remaining LSR bits not handled | 1458 | * value, and returns the remaining LSR bits not handled |
1459 | * by this Rx routine. | 1459 | * by this Rx routine. |
1460 | */ | 1460 | */ |
1461 | unsigned char | 1461 | unsigned char |
1462 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | 1462 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) |
1463 | { | 1463 | { |
1464 | struct uart_port *port = &up->port; | 1464 | struct uart_port *port = &up->port; |
1465 | unsigned char ch; | 1465 | unsigned char ch; |
1466 | int max_count = 256; | 1466 | int max_count = 256; |
1467 | char flag; | 1467 | char flag; |
1468 | 1468 | ||
1469 | do { | 1469 | do { |
1470 | if (likely(lsr & UART_LSR_DR)) | 1470 | if (likely(lsr & UART_LSR_DR)) |
1471 | ch = serial_in(up, UART_RX); | 1471 | ch = serial_in(up, UART_RX); |
1472 | else | 1472 | else |
1473 | /* | 1473 | /* |
1474 | * Intel 82571 has a Serial Over Lan device that will | 1474 | * Intel 82571 has a Serial Over Lan device that will |
1475 | * set UART_LSR_BI without setting UART_LSR_DR when | 1475 | * set UART_LSR_BI without setting UART_LSR_DR when |
1476 | * it receives a break. To avoid reading from the | 1476 | * it receives a break. To avoid reading from the |
1477 | * receive buffer without UART_LSR_DR bit set, we | 1477 | * receive buffer without UART_LSR_DR bit set, we |
1478 | * just force the read character to be 0 | 1478 | * just force the read character to be 0 |
1479 | */ | 1479 | */ |
1480 | ch = 0; | 1480 | ch = 0; |
1481 | 1481 | ||
1482 | flag = TTY_NORMAL; | 1482 | flag = TTY_NORMAL; |
1483 | port->icount.rx++; | 1483 | port->icount.rx++; |
1484 | 1484 | ||
1485 | lsr |= up->lsr_saved_flags; | 1485 | lsr |= up->lsr_saved_flags; |
1486 | up->lsr_saved_flags = 0; | 1486 | up->lsr_saved_flags = 0; |
1487 | 1487 | ||
1488 | if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { | 1488 | if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { |
1489 | if (lsr & UART_LSR_BI) { | 1489 | if (lsr & UART_LSR_BI) { |
1490 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | 1490 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); |
1491 | port->icount.brk++; | 1491 | port->icount.brk++; |
1492 | /* | 1492 | /* |
1493 | * We do the SysRQ and SAK checking | 1493 | * We do the SysRQ and SAK checking |
1494 | * here because otherwise the break | 1494 | * here because otherwise the break |
1495 | * may get masked by ignore_status_mask | 1495 | * may get masked by ignore_status_mask |
1496 | * or read_status_mask. | 1496 | * or read_status_mask. |
1497 | */ | 1497 | */ |
1498 | if (uart_handle_break(port)) | 1498 | if (uart_handle_break(port)) |
1499 | goto ignore_char; | 1499 | goto ignore_char; |
1500 | } else if (lsr & UART_LSR_PE) | 1500 | } else if (lsr & UART_LSR_PE) |
1501 | port->icount.parity++; | 1501 | port->icount.parity++; |
1502 | else if (lsr & UART_LSR_FE) | 1502 | else if (lsr & UART_LSR_FE) |
1503 | port->icount.frame++; | 1503 | port->icount.frame++; |
1504 | if (lsr & UART_LSR_OE) | 1504 | if (lsr & UART_LSR_OE) |
1505 | port->icount.overrun++; | 1505 | port->icount.overrun++; |
1506 | 1506 | ||
1507 | /* | 1507 | /* |
1508 | * Mask off conditions which should be ignored. | 1508 | * Mask off conditions which should be ignored. |
1509 | */ | 1509 | */ |
1510 | lsr &= port->read_status_mask; | 1510 | lsr &= port->read_status_mask; |
1511 | 1511 | ||
1512 | if (lsr & UART_LSR_BI) { | 1512 | if (lsr & UART_LSR_BI) { |
1513 | DEBUG_INTR("handling break...."); | 1513 | DEBUG_INTR("handling break...."); |
1514 | flag = TTY_BREAK; | 1514 | flag = TTY_BREAK; |
1515 | } else if (lsr & UART_LSR_PE) | 1515 | } else if (lsr & UART_LSR_PE) |
1516 | flag = TTY_PARITY; | 1516 | flag = TTY_PARITY; |
1517 | else if (lsr & UART_LSR_FE) | 1517 | else if (lsr & UART_LSR_FE) |
1518 | flag = TTY_FRAME; | 1518 | flag = TTY_FRAME; |
1519 | } | 1519 | } |
1520 | if (uart_handle_sysrq_char(port, ch)) | 1520 | if (uart_handle_sysrq_char(port, ch)) |
1521 | goto ignore_char; | 1521 | goto ignore_char; |
1522 | 1522 | ||
1523 | uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); | 1523 | uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); |
1524 | 1524 | ||
1525 | ignore_char: | 1525 | ignore_char: |
1526 | lsr = serial_in(up, UART_LSR); | 1526 | lsr = serial_in(up, UART_LSR); |
1527 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0)); | 1527 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0)); |
1528 | spin_unlock(&port->lock); | 1528 | spin_unlock(&port->lock); |
1529 | tty_flip_buffer_push(&port->state->port); | 1529 | tty_flip_buffer_push(&port->state->port); |
1530 | spin_lock(&port->lock); | 1530 | spin_lock(&port->lock); |
1531 | return lsr; | 1531 | return lsr; |
1532 | } | 1532 | } |
1533 | EXPORT_SYMBOL_GPL(serial8250_rx_chars); | 1533 | EXPORT_SYMBOL_GPL(serial8250_rx_chars); |
1534 | 1534 | ||
1535 | void serial8250_tx_chars(struct uart_8250_port *up) | 1535 | void serial8250_tx_chars(struct uart_8250_port *up) |
1536 | { | 1536 | { |
1537 | struct uart_port *port = &up->port; | 1537 | struct uart_port *port = &up->port; |
1538 | struct circ_buf *xmit = &port->state->xmit; | 1538 | struct circ_buf *xmit = &port->state->xmit; |
1539 | int count; | 1539 | int count; |
1540 | 1540 | ||
1541 | if (port->x_char) { | 1541 | if (port->x_char) { |
1542 | serial_out(up, UART_TX, port->x_char); | 1542 | serial_out(up, UART_TX, port->x_char); |
1543 | port->icount.tx++; | 1543 | port->icount.tx++; |
1544 | port->x_char = 0; | 1544 | port->x_char = 0; |
1545 | return; | 1545 | return; |
1546 | } | 1546 | } |
1547 | if (uart_tx_stopped(port)) { | 1547 | if (uart_tx_stopped(port)) { |
1548 | serial8250_stop_tx(port); | 1548 | serial8250_stop_tx(port); |
1549 | return; | 1549 | return; |
1550 | } | 1550 | } |
1551 | if (uart_circ_empty(xmit)) { | 1551 | if (uart_circ_empty(xmit)) { |
1552 | __stop_tx(up); | 1552 | __stop_tx(up); |
1553 | return; | 1553 | return; |
1554 | } | 1554 | } |
1555 | 1555 | ||
1556 | count = up->tx_loadsz; | 1556 | count = up->tx_loadsz; |
1557 | do { | 1557 | do { |
1558 | serial_out(up, UART_TX, xmit->buf[xmit->tail]); | 1558 | serial_out(up, UART_TX, xmit->buf[xmit->tail]); |
1559 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 1559 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
1560 | port->icount.tx++; | 1560 | port->icount.tx++; |
1561 | if (uart_circ_empty(xmit)) | 1561 | if (uart_circ_empty(xmit)) |
1562 | break; | 1562 | break; |
1563 | if (up->capabilities & UART_CAP_HFIFO) { | 1563 | if (up->capabilities & UART_CAP_HFIFO) { |
1564 | if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) != | 1564 | if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) != |
1565 | BOTH_EMPTY) | 1565 | BOTH_EMPTY) |
1566 | break; | 1566 | break; |
1567 | } | 1567 | } |
1568 | } while (--count > 0); | 1568 | } while (--count > 0); |
1569 | 1569 | ||
1570 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 1570 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
1571 | uart_write_wakeup(port); | 1571 | uart_write_wakeup(port); |
1572 | 1572 | ||
1573 | DEBUG_INTR("THRE..."); | 1573 | DEBUG_INTR("THRE..."); |
1574 | 1574 | ||
1575 | /* | 1575 | /* |
1576 | * With RPM enabled, we have to wait until the FIFO is empty before the | 1576 | * With RPM enabled, we have to wait until the FIFO is empty before the |
1577 | * HW can go idle. So we get here once again with empty FIFO and disable | 1577 | * HW can go idle. So we get here once again with empty FIFO and disable |
1578 | * the interrupt and RPM in __stop_tx() | 1578 | * the interrupt and RPM in __stop_tx() |
1579 | */ | 1579 | */ |
1580 | if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM)) | 1580 | if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM)) |
1581 | __stop_tx(up); | 1581 | __stop_tx(up); |
1582 | } | 1582 | } |
1583 | EXPORT_SYMBOL_GPL(serial8250_tx_chars); | 1583 | EXPORT_SYMBOL_GPL(serial8250_tx_chars); |
1584 | 1584 | ||
1585 | /* Caller holds uart port lock */ | 1585 | /* Caller holds uart port lock */ |
1586 | unsigned int serial8250_modem_status(struct uart_8250_port *up) | 1586 | unsigned int serial8250_modem_status(struct uart_8250_port *up) |
1587 | { | 1587 | { |
1588 | struct uart_port *port = &up->port; | 1588 | struct uart_port *port = &up->port; |
1589 | unsigned int status = serial_in(up, UART_MSR); | 1589 | unsigned int status = serial_in(up, UART_MSR); |
1590 | 1590 | ||
1591 | status |= up->msr_saved_flags; | 1591 | status |= up->msr_saved_flags; |
1592 | up->msr_saved_flags = 0; | 1592 | up->msr_saved_flags = 0; |
1593 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && | 1593 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && |
1594 | port->state != NULL) { | 1594 | port->state != NULL) { |
1595 | if (status & UART_MSR_TERI) | 1595 | if (status & UART_MSR_TERI) |
1596 | port->icount.rng++; | 1596 | port->icount.rng++; |
1597 | if (status & UART_MSR_DDSR) | 1597 | if (status & UART_MSR_DDSR) |
1598 | port->icount.dsr++; | 1598 | port->icount.dsr++; |
1599 | if (status & UART_MSR_DDCD) | 1599 | if (status & UART_MSR_DDCD) |
1600 | uart_handle_dcd_change(port, status & UART_MSR_DCD); | 1600 | uart_handle_dcd_change(port, status & UART_MSR_DCD); |
1601 | if (status & UART_MSR_DCTS) | 1601 | if (status & UART_MSR_DCTS) |
1602 | uart_handle_cts_change(port, status & UART_MSR_CTS); | 1602 | uart_handle_cts_change(port, status & UART_MSR_CTS); |
1603 | 1603 | ||
1604 | wake_up_interruptible(&port->state->port.delta_msr_wait); | 1604 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
1605 | } | 1605 | } |
1606 | 1606 | ||
1607 | return status; | 1607 | return status; |
1608 | } | 1608 | } |
1609 | EXPORT_SYMBOL_GPL(serial8250_modem_status); | 1609 | EXPORT_SYMBOL_GPL(serial8250_modem_status); |
1610 | 1610 | ||
1611 | /* | 1611 | /* |
1612 | * This handles the interrupt from one port. | 1612 | * This handles the interrupt from one port. |
1613 | */ | 1613 | */ |
1614 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | 1614 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir) |
1615 | { | 1615 | { |
1616 | unsigned char status; | 1616 | unsigned char status; |
1617 | unsigned long flags; | 1617 | unsigned long flags; |
1618 | struct uart_8250_port *up = up_to_u8250p(port); | 1618 | struct uart_8250_port *up = up_to_u8250p(port); |
1619 | int dma_err = 0; | 1619 | int dma_err = 0; |
1620 | 1620 | ||
1621 | if (iir & UART_IIR_NO_INT) | 1621 | if (iir & UART_IIR_NO_INT) |
1622 | return 0; | 1622 | return 0; |
1623 | 1623 | ||
1624 | spin_lock_irqsave(&port->lock, flags); | 1624 | spin_lock_irqsave(&port->lock, flags); |
1625 | 1625 | ||
1626 | status = serial_port_in(port, UART_LSR); | 1626 | status = serial_port_in(port, UART_LSR); |
1627 | 1627 | ||
1628 | DEBUG_INTR("status = %x...", status); | 1628 | DEBUG_INTR("status = %x...", status); |
1629 | 1629 | ||
1630 | if (status & (UART_LSR_DR | UART_LSR_BI)) { | 1630 | if (status & (UART_LSR_DR | UART_LSR_BI)) { |
1631 | if (up->dma) | 1631 | if (up->dma) |
1632 | dma_err = up->dma->rx_dma(up, iir); | 1632 | dma_err = up->dma->rx_dma(up, iir); |
1633 | 1633 | ||
1634 | if (!up->dma || dma_err) | 1634 | if (!up->dma || dma_err) |
1635 | status = serial8250_rx_chars(up, status); | 1635 | status = serial8250_rx_chars(up, status); |
1636 | } | 1636 | } |
1637 | serial8250_modem_status(up); | 1637 | serial8250_modem_status(up); |
1638 | if ((!up->dma || (up->dma && up->dma->tx_err)) && | 1638 | if ((!up->dma || (up->dma && up->dma->tx_err)) && |
1639 | (status & UART_LSR_THRE)) | 1639 | (status & UART_LSR_THRE)) |
1640 | serial8250_tx_chars(up); | 1640 | serial8250_tx_chars(up); |
1641 | 1641 | ||
1642 | spin_unlock_irqrestore(&port->lock, flags); | 1642 | spin_unlock_irqrestore(&port->lock, flags); |
1643 | return 1; | 1643 | return 1; |
1644 | } | 1644 | } |
1645 | EXPORT_SYMBOL_GPL(serial8250_handle_irq); | 1645 | EXPORT_SYMBOL_GPL(serial8250_handle_irq); |
1646 | 1646 | ||
1647 | static int serial8250_default_handle_irq(struct uart_port *port) | 1647 | static int serial8250_default_handle_irq(struct uart_port *port) |
1648 | { | 1648 | { |
1649 | struct uart_8250_port *up = up_to_u8250p(port); | 1649 | struct uart_8250_port *up = up_to_u8250p(port); |
1650 | unsigned int iir; | 1650 | unsigned int iir; |
1651 | int ret; | 1651 | int ret; |
1652 | 1652 | ||
1653 | serial8250_rpm_get(up); | 1653 | serial8250_rpm_get(up); |
1654 | 1654 | ||
1655 | iir = serial_port_in(port, UART_IIR); | 1655 | iir = serial_port_in(port, UART_IIR); |
1656 | ret = serial8250_handle_irq(port, iir); | 1656 | ret = serial8250_handle_irq(port, iir); |
1657 | 1657 | ||
1658 | serial8250_rpm_put(up); | 1658 | serial8250_rpm_put(up); |
1659 | return ret; | 1659 | return ret; |
1660 | } | 1660 | } |
1661 | 1661 | ||
1662 | /* | 1662 | /* |
1663 | * These Exar UARTs have an extra interrupt indicator that could | 1663 | * These Exar UARTs have an extra interrupt indicator that could |
1664 | * fire for a few unimplemented interrupts. One of which is a | 1664 | * fire for a few unimplemented interrupts. One of which is a |
1665 | * wakeup event when coming out of sleep. Put this here just | 1665 | * wakeup event when coming out of sleep. Put this here just |
1666 | * to be on the safe side that these interrupts don't go unhandled. | 1666 | * to be on the safe side that these interrupts don't go unhandled. |
1667 | */ | 1667 | */ |
1668 | static int exar_handle_irq(struct uart_port *port) | 1668 | static int exar_handle_irq(struct uart_port *port) |
1669 | { | 1669 | { |
1670 | unsigned char int0, int1, int2, int3; | 1670 | unsigned char int0, int1, int2, int3; |
1671 | unsigned int iir = serial_port_in(port, UART_IIR); | 1671 | unsigned int iir = serial_port_in(port, UART_IIR); |
1672 | int ret; | 1672 | int ret; |
1673 | 1673 | ||
1674 | ret = serial8250_handle_irq(port, iir); | 1674 | ret = serial8250_handle_irq(port, iir); |
1675 | 1675 | ||
1676 | if ((port->type == PORT_XR17V35X) || | 1676 | if ((port->type == PORT_XR17V35X) || |
1677 | (port->type == PORT_XR17D15X)) { | 1677 | (port->type == PORT_XR17D15X)) { |
1678 | int0 = serial_port_in(port, 0x80); | 1678 | int0 = serial_port_in(port, 0x80); |
1679 | int1 = serial_port_in(port, 0x81); | 1679 | int1 = serial_port_in(port, 0x81); |
1680 | int2 = serial_port_in(port, 0x82); | 1680 | int2 = serial_port_in(port, 0x82); |
1681 | int3 = serial_port_in(port, 0x83); | 1681 | int3 = serial_port_in(port, 0x83); |
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | return ret; | 1684 | return ret; |
1685 | } | 1685 | } |
1686 | 1686 | ||
1687 | /* | 1687 | /* |
1688 | * This is the serial driver's interrupt routine. | 1688 | * This is the serial driver's interrupt routine. |
1689 | * | 1689 | * |
1690 | * Arjan thinks the old way was overly complex, so it got simplified. | 1690 | * Arjan thinks the old way was overly complex, so it got simplified. |
1691 | * Alan disagrees, saying that need the complexity to handle the weird | 1691 | * Alan disagrees, saying that need the complexity to handle the weird |
1692 | * nature of ISA shared interrupts. (This is a special exception.) | 1692 | * nature of ISA shared interrupts. (This is a special exception.) |
1693 | * | 1693 | * |
1694 | * In order to handle ISA shared interrupts properly, we need to check | 1694 | * In order to handle ISA shared interrupts properly, we need to check |
1695 | * that all ports have been serviced, and therefore the ISA interrupt | 1695 | * that all ports have been serviced, and therefore the ISA interrupt |
1696 | * line has been de-asserted. | 1696 | * line has been de-asserted. |
1697 | * | 1697 | * |
1698 | * This means we need to loop through all ports. checking that they | 1698 | * This means we need to loop through all ports. checking that they |
1699 | * don't have an interrupt pending. | 1699 | * don't have an interrupt pending. |
1700 | */ | 1700 | */ |
1701 | static irqreturn_t serial8250_interrupt(int irq, void *dev_id) | 1701 | static irqreturn_t serial8250_interrupt(int irq, void *dev_id) |
1702 | { | 1702 | { |
1703 | struct irq_info *i = dev_id; | 1703 | struct irq_info *i = dev_id; |
1704 | struct list_head *l, *end = NULL; | 1704 | struct list_head *l, *end = NULL; |
1705 | int pass_counter = 0, handled = 0; | 1705 | int pass_counter = 0, handled = 0; |
1706 | 1706 | ||
1707 | DEBUG_INTR("serial8250_interrupt(%d)...", irq); | 1707 | DEBUG_INTR("serial8250_interrupt(%d)...", irq); |
1708 | 1708 | ||
1709 | spin_lock(&i->lock); | 1709 | spin_lock(&i->lock); |
1710 | 1710 | ||
1711 | l = i->head; | 1711 | l = i->head; |
1712 | do { | 1712 | do { |
1713 | struct uart_8250_port *up; | 1713 | struct uart_8250_port *up; |
1714 | struct uart_port *port; | 1714 | struct uart_port *port; |
1715 | 1715 | ||
1716 | up = list_entry(l, struct uart_8250_port, list); | 1716 | up = list_entry(l, struct uart_8250_port, list); |
1717 | port = &up->port; | 1717 | port = &up->port; |
1718 | 1718 | ||
1719 | if (port->handle_irq(port)) { | 1719 | if (port->handle_irq(port)) { |
1720 | handled = 1; | 1720 | handled = 1; |
1721 | end = NULL; | 1721 | end = NULL; |
1722 | } else if (end == NULL) | 1722 | } else if (end == NULL) |
1723 | end = l; | 1723 | end = l; |
1724 | 1724 | ||
1725 | l = l->next; | 1725 | l = l->next; |
1726 | 1726 | ||
1727 | if (l == i->head && pass_counter++ > PASS_LIMIT) { | 1727 | if (l == i->head && pass_counter++ > PASS_LIMIT) { |
1728 | /* If we hit this, we're dead. */ | 1728 | /* If we hit this, we're dead. */ |
1729 | printk_ratelimited(KERN_ERR | 1729 | printk_ratelimited(KERN_ERR |
1730 | "serial8250: too much work for irq%d\n", irq); | 1730 | "serial8250: too much work for irq%d\n", irq); |
1731 | break; | 1731 | break; |
1732 | } | 1732 | } |
1733 | } while (l != end); | 1733 | } while (l != end); |
1734 | 1734 | ||
1735 | spin_unlock(&i->lock); | 1735 | spin_unlock(&i->lock); |
1736 | 1736 | ||
1737 | DEBUG_INTR("end.\n"); | 1737 | DEBUG_INTR("end.\n"); |
1738 | 1738 | ||
1739 | return IRQ_RETVAL(handled); | 1739 | return IRQ_RETVAL(handled); |
1740 | } | 1740 | } |
1741 | 1741 | ||
1742 | /* | 1742 | /* |
1743 | * To support ISA shared interrupts, we need to have one interrupt | 1743 | * To support ISA shared interrupts, we need to have one interrupt |
1744 | * handler that ensures that the IRQ line has been deasserted | 1744 | * handler that ensures that the IRQ line has been deasserted |
1745 | * before returning. Failing to do this will result in the IRQ | 1745 | * before returning. Failing to do this will result in the IRQ |
1746 | * line being stuck active, and, since ISA irqs are edge triggered, | 1746 | * line being stuck active, and, since ISA irqs are edge triggered, |
1747 | * no more IRQs will be seen. | 1747 | * no more IRQs will be seen. |
1748 | */ | 1748 | */ |
1749 | static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up) | 1749 | static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up) |
1750 | { | 1750 | { |
1751 | spin_lock_irq(&i->lock); | 1751 | spin_lock_irq(&i->lock); |
1752 | 1752 | ||
1753 | if (!list_empty(i->head)) { | 1753 | if (!list_empty(i->head)) { |
1754 | if (i->head == &up->list) | 1754 | if (i->head == &up->list) |
1755 | i->head = i->head->next; | 1755 | i->head = i->head->next; |
1756 | list_del(&up->list); | 1756 | list_del(&up->list); |
1757 | } else { | 1757 | } else { |
1758 | BUG_ON(i->head != &up->list); | 1758 | BUG_ON(i->head != &up->list); |
1759 | i->head = NULL; | 1759 | i->head = NULL; |
1760 | } | 1760 | } |
1761 | spin_unlock_irq(&i->lock); | 1761 | spin_unlock_irq(&i->lock); |
1762 | /* List empty so throw away the hash node */ | 1762 | /* List empty so throw away the hash node */ |
1763 | if (i->head == NULL) { | 1763 | if (i->head == NULL) { |
1764 | hlist_del(&i->node); | 1764 | hlist_del(&i->node); |
1765 | kfree(i); | 1765 | kfree(i); |
1766 | } | 1766 | } |
1767 | } | 1767 | } |
1768 | 1768 | ||
1769 | static int serial_link_irq_chain(struct uart_8250_port *up) | 1769 | static int serial_link_irq_chain(struct uart_8250_port *up) |
1770 | { | 1770 | { |
1771 | struct hlist_head *h; | 1771 | struct hlist_head *h; |
1772 | struct hlist_node *n; | 1772 | struct hlist_node *n; |
1773 | struct irq_info *i; | 1773 | struct irq_info *i; |
1774 | int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; | 1774 | int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; |
1775 | 1775 | ||
1776 | mutex_lock(&hash_mutex); | 1776 | mutex_lock(&hash_mutex); |
1777 | 1777 | ||
1778 | h = &irq_lists[up->port.irq % NR_IRQ_HASH]; | 1778 | h = &irq_lists[up->port.irq % NR_IRQ_HASH]; |
1779 | 1779 | ||
1780 | hlist_for_each(n, h) { | 1780 | hlist_for_each(n, h) { |
1781 | i = hlist_entry(n, struct irq_info, node); | 1781 | i = hlist_entry(n, struct irq_info, node); |
1782 | if (i->irq == up->port.irq) | 1782 | if (i->irq == up->port.irq) |
1783 | break; | 1783 | break; |
1784 | } | 1784 | } |
1785 | 1785 | ||
1786 | if (n == NULL) { | 1786 | if (n == NULL) { |
1787 | i = kzalloc(sizeof(struct irq_info), GFP_KERNEL); | 1787 | i = kzalloc(sizeof(struct irq_info), GFP_KERNEL); |
1788 | if (i == NULL) { | 1788 | if (i == NULL) { |
1789 | mutex_unlock(&hash_mutex); | 1789 | mutex_unlock(&hash_mutex); |
1790 | return -ENOMEM; | 1790 | return -ENOMEM; |
1791 | } | 1791 | } |
1792 | spin_lock_init(&i->lock); | 1792 | spin_lock_init(&i->lock); |
1793 | i->irq = up->port.irq; | 1793 | i->irq = up->port.irq; |
1794 | hlist_add_head(&i->node, h); | 1794 | hlist_add_head(&i->node, h); |
1795 | } | 1795 | } |
1796 | mutex_unlock(&hash_mutex); | 1796 | mutex_unlock(&hash_mutex); |
1797 | 1797 | ||
1798 | spin_lock_irq(&i->lock); | 1798 | spin_lock_irq(&i->lock); |
1799 | 1799 | ||
1800 | if (i->head) { | 1800 | if (i->head) { |
1801 | list_add(&up->list, i->head); | 1801 | list_add(&up->list, i->head); |
1802 | spin_unlock_irq(&i->lock); | 1802 | spin_unlock_irq(&i->lock); |
1803 | 1803 | ||
1804 | ret = 0; | 1804 | ret = 0; |
1805 | } else { | 1805 | } else { |
1806 | INIT_LIST_HEAD(&up->list); | 1806 | INIT_LIST_HEAD(&up->list); |
1807 | i->head = &up->list; | 1807 | i->head = &up->list; |
1808 | spin_unlock_irq(&i->lock); | 1808 | spin_unlock_irq(&i->lock); |
1809 | irq_flags |= up->port.irqflags; | 1809 | irq_flags |= up->port.irqflags; |
1810 | ret = request_irq(up->port.irq, serial8250_interrupt, | 1810 | ret = request_irq(up->port.irq, serial8250_interrupt, |
1811 | irq_flags, "serial", i); | 1811 | irq_flags, "serial", i); |
1812 | if (ret < 0) | 1812 | if (ret < 0) |
1813 | serial_do_unlink(i, up); | 1813 | serial_do_unlink(i, up); |
1814 | } | 1814 | } |
1815 | 1815 | ||
1816 | return ret; | 1816 | return ret; |
1817 | } | 1817 | } |
1818 | 1818 | ||
1819 | static void serial_unlink_irq_chain(struct uart_8250_port *up) | 1819 | static void serial_unlink_irq_chain(struct uart_8250_port *up) |
1820 | { | 1820 | { |
1821 | /* | 1821 | /* |
1822 | * yes, some broken gcc emit "warning: 'i' may be used uninitialized" | 1822 | * yes, some broken gcc emit "warning: 'i' may be used uninitialized" |
1823 | * but no, we are not going to take a patch that assigns NULL below. | 1823 | * but no, we are not going to take a patch that assigns NULL below. |
1824 | */ | 1824 | */ |
1825 | struct irq_info *i; | 1825 | struct irq_info *i; |
1826 | struct hlist_node *n; | 1826 | struct hlist_node *n; |
1827 | struct hlist_head *h; | 1827 | struct hlist_head *h; |
1828 | 1828 | ||
1829 | mutex_lock(&hash_mutex); | 1829 | mutex_lock(&hash_mutex); |
1830 | 1830 | ||
1831 | h = &irq_lists[up->port.irq % NR_IRQ_HASH]; | 1831 | h = &irq_lists[up->port.irq % NR_IRQ_HASH]; |
1832 | 1832 | ||
1833 | hlist_for_each(n, h) { | 1833 | hlist_for_each(n, h) { |
1834 | i = hlist_entry(n, struct irq_info, node); | 1834 | i = hlist_entry(n, struct irq_info, node); |
1835 | if (i->irq == up->port.irq) | 1835 | if (i->irq == up->port.irq) |
1836 | break; | 1836 | break; |
1837 | } | 1837 | } |
1838 | 1838 | ||
1839 | BUG_ON(n == NULL); | 1839 | BUG_ON(n == NULL); |
1840 | BUG_ON(i->head == NULL); | 1840 | BUG_ON(i->head == NULL); |
1841 | 1841 | ||
1842 | if (list_empty(i->head)) | 1842 | if (list_empty(i->head)) |
1843 | free_irq(up->port.irq, i); | 1843 | free_irq(up->port.irq, i); |
1844 | 1844 | ||
1845 | serial_do_unlink(i, up); | 1845 | serial_do_unlink(i, up); |
1846 | mutex_unlock(&hash_mutex); | 1846 | mutex_unlock(&hash_mutex); |
1847 | } | 1847 | } |
1848 | 1848 | ||
1849 | /* | 1849 | /* |
1850 | * This function is used to handle ports that do not have an | 1850 | * This function is used to handle ports that do not have an |
1851 | * interrupt. This doesn't work very well for 16450's, but gives | 1851 | * interrupt. This doesn't work very well for 16450's, but gives |
1852 | * barely passable results for a 16550A. (Although at the expense | 1852 | * barely passable results for a 16550A. (Although at the expense |
1853 | * of much CPU overhead). | 1853 | * of much CPU overhead). |
1854 | */ | 1854 | */ |
1855 | static void serial8250_timeout(unsigned long data) | 1855 | static void serial8250_timeout(unsigned long data) |
1856 | { | 1856 | { |
1857 | struct uart_8250_port *up = (struct uart_8250_port *)data; | 1857 | struct uart_8250_port *up = (struct uart_8250_port *)data; |
1858 | 1858 | ||
1859 | up->port.handle_irq(&up->port); | 1859 | up->port.handle_irq(&up->port); |
1860 | mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port)); | 1860 | mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port)); |
1861 | } | 1861 | } |
1862 | 1862 | ||
1863 | static void serial8250_backup_timeout(unsigned long data) | 1863 | static void serial8250_backup_timeout(unsigned long data) |
1864 | { | 1864 | { |
1865 | struct uart_8250_port *up = (struct uart_8250_port *)data; | 1865 | struct uart_8250_port *up = (struct uart_8250_port *)data; |
1866 | unsigned int iir, ier = 0, lsr; | 1866 | unsigned int iir, ier = 0, lsr; |
1867 | unsigned long flags; | 1867 | unsigned long flags; |
1868 | 1868 | ||
1869 | spin_lock_irqsave(&up->port.lock, flags); | 1869 | spin_lock_irqsave(&up->port.lock, flags); |
1870 | 1870 | ||
1871 | /* | 1871 | /* |
1872 | * Must disable interrupts or else we risk racing with the interrupt | 1872 | * Must disable interrupts or else we risk racing with the interrupt |
1873 | * based handler. | 1873 | * based handler. |
1874 | */ | 1874 | */ |
1875 | if (up->port.irq) { | 1875 | if (up->port.irq) { |
1876 | ier = serial_in(up, UART_IER); | 1876 | ier = serial_in(up, UART_IER); |
1877 | serial_out(up, UART_IER, 0); | 1877 | serial_out(up, UART_IER, 0); |
1878 | } | 1878 | } |
1879 | 1879 | ||
1880 | iir = serial_in(up, UART_IIR); | 1880 | iir = serial_in(up, UART_IIR); |
1881 | 1881 | ||
1882 | /* | 1882 | /* |
1883 | * This should be a safe test for anyone who doesn't trust the | 1883 | * This should be a safe test for anyone who doesn't trust the |
1884 | * IIR bits on their UART, but it's specifically designed for | 1884 | * IIR bits on their UART, but it's specifically designed for |
1885 | * the "Diva" UART used on the management processor on many HP | 1885 | * the "Diva" UART used on the management processor on many HP |
1886 | * ia64 and parisc boxes. | 1886 | * ia64 and parisc boxes. |
1887 | */ | 1887 | */ |
1888 | lsr = serial_in(up, UART_LSR); | 1888 | lsr = serial_in(up, UART_LSR); |
1889 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1889 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1890 | if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && | 1890 | if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && |
1891 | (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) && | 1891 | (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) && |
1892 | (lsr & UART_LSR_THRE)) { | 1892 | (lsr & UART_LSR_THRE)) { |
1893 | iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); | 1893 | iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); |
1894 | iir |= UART_IIR_THRI; | 1894 | iir |= UART_IIR_THRI; |
1895 | } | 1895 | } |
1896 | 1896 | ||
1897 | if (!(iir & UART_IIR_NO_INT)) | 1897 | if (!(iir & UART_IIR_NO_INT)) |
1898 | serial8250_tx_chars(up); | 1898 | serial8250_tx_chars(up); |
1899 | 1899 | ||
1900 | if (up->port.irq) | 1900 | if (up->port.irq) |
1901 | serial_out(up, UART_IER, ier); | 1901 | serial_out(up, UART_IER, ier); |
1902 | 1902 | ||
1903 | spin_unlock_irqrestore(&up->port.lock, flags); | 1903 | spin_unlock_irqrestore(&up->port.lock, flags); |
1904 | 1904 | ||
1905 | /* Standard timer interval plus 0.2s to keep the port running */ | 1905 | /* Standard timer interval plus 0.2s to keep the port running */ |
1906 | mod_timer(&up->timer, | 1906 | mod_timer(&up->timer, |
1907 | jiffies + uart_poll_timeout(&up->port) + HZ / 5); | 1907 | jiffies + uart_poll_timeout(&up->port) + HZ / 5); |
1908 | } | 1908 | } |
1909 | 1909 | ||
1910 | static unsigned int serial8250_tx_empty(struct uart_port *port) | 1910 | static unsigned int serial8250_tx_empty(struct uart_port *port) |
1911 | { | 1911 | { |
1912 | struct uart_8250_port *up = up_to_u8250p(port); | 1912 | struct uart_8250_port *up = up_to_u8250p(port); |
1913 | unsigned long flags; | 1913 | unsigned long flags; |
1914 | unsigned int lsr; | 1914 | unsigned int lsr; |
1915 | 1915 | ||
1916 | serial8250_rpm_get(up); | 1916 | serial8250_rpm_get(up); |
1917 | 1917 | ||
1918 | spin_lock_irqsave(&port->lock, flags); | 1918 | spin_lock_irqsave(&port->lock, flags); |
1919 | lsr = serial_port_in(port, UART_LSR); | 1919 | lsr = serial_port_in(port, UART_LSR); |
1920 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1920 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1921 | spin_unlock_irqrestore(&port->lock, flags); | 1921 | spin_unlock_irqrestore(&port->lock, flags); |
1922 | 1922 | ||
1923 | serial8250_rpm_put(up); | 1923 | serial8250_rpm_put(up); |
1924 | 1924 | ||
1925 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; | 1925 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1928 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
1929 | { | 1929 | { |
1930 | struct uart_8250_port *up = up_to_u8250p(port); | 1930 | struct uart_8250_port *up = up_to_u8250p(port); |
1931 | unsigned int status; | 1931 | unsigned int status; |
1932 | unsigned int ret; | 1932 | unsigned int ret; |
1933 | 1933 | ||
1934 | serial8250_rpm_get(up); | 1934 | serial8250_rpm_get(up); |
1935 | status = serial8250_modem_status(up); | 1935 | status = serial8250_modem_status(up); |
1936 | serial8250_rpm_put(up); | 1936 | serial8250_rpm_put(up); |
1937 | 1937 | ||
1938 | ret = 0; | 1938 | ret = 0; |
1939 | if (status & UART_MSR_DCD) | 1939 | if (status & UART_MSR_DCD) |
1940 | ret |= TIOCM_CAR; | 1940 | ret |= TIOCM_CAR; |
1941 | if (status & UART_MSR_RI) | 1941 | if (status & UART_MSR_RI) |
1942 | ret |= TIOCM_RNG; | 1942 | ret |= TIOCM_RNG; |
1943 | if (status & UART_MSR_DSR) | 1943 | if (status & UART_MSR_DSR) |
1944 | ret |= TIOCM_DSR; | 1944 | ret |= TIOCM_DSR; |
1945 | if (status & UART_MSR_CTS) | 1945 | if (status & UART_MSR_CTS) |
1946 | ret |= TIOCM_CTS; | 1946 | ret |= TIOCM_CTS; |
1947 | return ret; | 1947 | return ret; |
1948 | } | 1948 | } |
1949 | 1949 | ||
1950 | void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) | 1950 | void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) |
1951 | { | 1951 | { |
1952 | struct uart_8250_port *up = up_to_u8250p(port); | 1952 | struct uart_8250_port *up = up_to_u8250p(port); |
1953 | unsigned char mcr = 0; | 1953 | unsigned char mcr = 0; |
1954 | 1954 | ||
1955 | if (mctrl & TIOCM_RTS) | 1955 | if (mctrl & TIOCM_RTS) |
1956 | mcr |= UART_MCR_RTS; | 1956 | mcr |= UART_MCR_RTS; |
1957 | if (mctrl & TIOCM_DTR) | 1957 | if (mctrl & TIOCM_DTR) |
1958 | mcr |= UART_MCR_DTR; | 1958 | mcr |= UART_MCR_DTR; |
1959 | if (mctrl & TIOCM_OUT1) | 1959 | if (mctrl & TIOCM_OUT1) |
1960 | mcr |= UART_MCR_OUT1; | 1960 | mcr |= UART_MCR_OUT1; |
1961 | if (mctrl & TIOCM_OUT2) | 1961 | if (mctrl & TIOCM_OUT2) |
1962 | mcr |= UART_MCR_OUT2; | 1962 | mcr |= UART_MCR_OUT2; |
1963 | if (mctrl & TIOCM_LOOP) | 1963 | if (mctrl & TIOCM_LOOP) |
1964 | mcr |= UART_MCR_LOOP; | 1964 | mcr |= UART_MCR_LOOP; |
1965 | 1965 | ||
1966 | mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; | 1966 | mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; |
1967 | 1967 | ||
1968 | serial_port_out(port, UART_MCR, mcr); | 1968 | serial_port_out(port, UART_MCR, mcr); |
1969 | } | 1969 | } |
1970 | EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); | 1970 | EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); |
1971 | 1971 | ||
1972 | static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | 1972 | static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) |
1973 | { | 1973 | { |
1974 | if (port->set_mctrl) | 1974 | if (port->set_mctrl) |
1975 | return port->set_mctrl(port, mctrl); | 1975 | return port->set_mctrl(port, mctrl); |
1976 | return serial8250_do_set_mctrl(port, mctrl); | 1976 | return serial8250_do_set_mctrl(port, mctrl); |
1977 | } | 1977 | } |
1978 | 1978 | ||
1979 | static void serial8250_break_ctl(struct uart_port *port, int break_state) | 1979 | static void serial8250_break_ctl(struct uart_port *port, int break_state) |
1980 | { | 1980 | { |
1981 | struct uart_8250_port *up = up_to_u8250p(port); | 1981 | struct uart_8250_port *up = up_to_u8250p(port); |
1982 | unsigned long flags; | 1982 | unsigned long flags; |
1983 | 1983 | ||
1984 | serial8250_rpm_get(up); | 1984 | serial8250_rpm_get(up); |
1985 | spin_lock_irqsave(&port->lock, flags); | 1985 | spin_lock_irqsave(&port->lock, flags); |
1986 | if (break_state == -1) | 1986 | if (break_state == -1) |
1987 | up->lcr |= UART_LCR_SBC; | 1987 | up->lcr |= UART_LCR_SBC; |
1988 | else | 1988 | else |
1989 | up->lcr &= ~UART_LCR_SBC; | 1989 | up->lcr &= ~UART_LCR_SBC; |
1990 | serial_port_out(port, UART_LCR, up->lcr); | 1990 | serial_port_out(port, UART_LCR, up->lcr); |
1991 | spin_unlock_irqrestore(&port->lock, flags); | 1991 | spin_unlock_irqrestore(&port->lock, flags); |
1992 | serial8250_rpm_put(up); | 1992 | serial8250_rpm_put(up); |
1993 | } | 1993 | } |
1994 | 1994 | ||
1995 | /* | 1995 | /* |
1996 | * Wait for transmitter & holding register to empty | 1996 | * Wait for transmitter & holding register to empty |
1997 | */ | 1997 | */ |
1998 | static void wait_for_xmitr(struct uart_8250_port *up, int bits) | 1998 | static void wait_for_xmitr(struct uart_8250_port *up, int bits) |
1999 | { | 1999 | { |
2000 | unsigned int status, tmout = 10000; | 2000 | unsigned int status, tmout = 10000; |
2001 | 2001 | ||
2002 | /* Wait up to 10ms for the character(s) to be sent. */ | 2002 | /* Wait up to 10ms for the character(s) to be sent. */ |
2003 | for (;;) { | 2003 | for (;;) { |
2004 | status = serial_in(up, UART_LSR); | 2004 | status = serial_in(up, UART_LSR); |
2005 | 2005 | ||
2006 | up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; | 2006 | up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; |
2007 | 2007 | ||
2008 | if ((status & bits) == bits) | 2008 | if ((status & bits) == bits) |
2009 | break; | 2009 | break; |
2010 | if (--tmout == 0) | 2010 | if (--tmout == 0) |
2011 | break; | 2011 | break; |
2012 | udelay(1); | 2012 | udelay(1); |
2013 | } | 2013 | } |
2014 | 2014 | ||
2015 | /* Wait up to 1s for flow control if necessary */ | 2015 | /* Wait up to 1s for flow control if necessary */ |
2016 | if (up->port.flags & UPF_CONS_FLOW) { | 2016 | if (up->port.flags & UPF_CONS_FLOW) { |
2017 | unsigned int tmout; | 2017 | unsigned int tmout; |
2018 | for (tmout = 1000000; tmout; tmout--) { | 2018 | for (tmout = 1000000; tmout; tmout--) { |
2019 | unsigned int msr = serial_in(up, UART_MSR); | 2019 | unsigned int msr = serial_in(up, UART_MSR); |
2020 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; | 2020 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; |
2021 | if (msr & UART_MSR_CTS) | 2021 | if (msr & UART_MSR_CTS) |
2022 | break; | 2022 | break; |
2023 | udelay(1); | 2023 | udelay(1); |
2024 | touch_nmi_watchdog(); | 2024 | touch_nmi_watchdog(); |
2025 | } | 2025 | } |
2026 | } | 2026 | } |
2027 | } | 2027 | } |
2028 | 2028 | ||
2029 | #ifdef CONFIG_CONSOLE_POLL | 2029 | #ifdef CONFIG_CONSOLE_POLL |
2030 | /* | 2030 | /* |
2031 | * Console polling routines for writing and reading from the uart while | 2031 | * Console polling routines for writing and reading from the uart while |
2032 | * in an interrupt or debug context. | 2032 | * in an interrupt or debug context. |
2033 | */ | 2033 | */ |
2034 | 2034 | ||
2035 | static int serial8250_get_poll_char(struct uart_port *port) | 2035 | static int serial8250_get_poll_char(struct uart_port *port) |
2036 | { | 2036 | { |
2037 | struct uart_8250_port *up = up_to_u8250p(port); | 2037 | struct uart_8250_port *up = up_to_u8250p(port); |
2038 | unsigned char lsr; | 2038 | unsigned char lsr; |
2039 | int status; | 2039 | int status; |
2040 | 2040 | ||
2041 | serial8250_rpm_get(up); | 2041 | serial8250_rpm_get(up); |
2042 | 2042 | ||
2043 | lsr = serial_port_in(port, UART_LSR); | 2043 | lsr = serial_port_in(port, UART_LSR); |
2044 | 2044 | ||
2045 | if (!(lsr & UART_LSR_DR)) { | 2045 | if (!(lsr & UART_LSR_DR)) { |
2046 | status = NO_POLL_CHAR; | 2046 | status = NO_POLL_CHAR; |
2047 | goto out; | 2047 | goto out; |
2048 | } | 2048 | } |
2049 | 2049 | ||
2050 | status = serial_port_in(port, UART_RX); | 2050 | status = serial_port_in(port, UART_RX); |
2051 | out: | 2051 | out: |
2052 | serial8250_rpm_put(up); | 2052 | serial8250_rpm_put(up); |
2053 | return status; | 2053 | return status; |
2054 | } | 2054 | } |
2055 | 2055 | ||
2056 | 2056 | ||
2057 | static void serial8250_put_poll_char(struct uart_port *port, | 2057 | static void serial8250_put_poll_char(struct uart_port *port, |
2058 | unsigned char c) | 2058 | unsigned char c) |
2059 | { | 2059 | { |
2060 | unsigned int ier; | 2060 | unsigned int ier; |
2061 | struct uart_8250_port *up = up_to_u8250p(port); | 2061 | struct uart_8250_port *up = up_to_u8250p(port); |
2062 | 2062 | ||
2063 | serial8250_rpm_get(up); | 2063 | serial8250_rpm_get(up); |
2064 | /* | 2064 | /* |
2065 | * First save the IER then disable the interrupts | 2065 | * First save the IER then disable the interrupts |
2066 | */ | 2066 | */ |
2067 | ier = serial_port_in(port, UART_IER); | 2067 | ier = serial_port_in(port, UART_IER); |
2068 | if (up->capabilities & UART_CAP_UUE) | 2068 | if (up->capabilities & UART_CAP_UUE) |
2069 | serial_port_out(port, UART_IER, UART_IER_UUE); | 2069 | serial_port_out(port, UART_IER, UART_IER_UUE); |
2070 | else | 2070 | else |
2071 | serial_port_out(port, UART_IER, 0); | 2071 | serial_port_out(port, UART_IER, 0); |
2072 | 2072 | ||
2073 | wait_for_xmitr(up, BOTH_EMPTY); | 2073 | wait_for_xmitr(up, BOTH_EMPTY); |
2074 | /* | 2074 | /* |
2075 | * Send the character out. | 2075 | * Send the character out. |
2076 | */ | 2076 | */ |
2077 | serial_port_out(port, UART_TX, c); | 2077 | serial_port_out(port, UART_TX, c); |
2078 | 2078 | ||
2079 | /* | 2079 | /* |
2080 | * Finally, wait for transmitter to become empty | 2080 | * Finally, wait for transmitter to become empty |
2081 | * and restore the IER | 2081 | * and restore the IER |
2082 | */ | 2082 | */ |
2083 | wait_for_xmitr(up, BOTH_EMPTY); | 2083 | wait_for_xmitr(up, BOTH_EMPTY); |
2084 | serial_port_out(port, UART_IER, ier); | 2084 | serial_port_out(port, UART_IER, ier); |
2085 | serial8250_rpm_put(up); | 2085 | serial8250_rpm_put(up); |
2086 | } | 2086 | } |
2087 | 2087 | ||
2088 | #endif /* CONFIG_CONSOLE_POLL */ | 2088 | #endif /* CONFIG_CONSOLE_POLL */ |
2089 | 2089 | ||
2090 | int serial8250_do_startup(struct uart_port *port) | 2090 | int serial8250_do_startup(struct uart_port *port) |
2091 | { | 2091 | { |
2092 | struct uart_8250_port *up = up_to_u8250p(port); | 2092 | struct uart_8250_port *up = up_to_u8250p(port); |
2093 | unsigned long flags; | 2093 | unsigned long flags; |
2094 | unsigned char lsr, iir; | 2094 | unsigned char lsr, iir; |
2095 | int retval; | 2095 | int retval; |
2096 | 2096 | ||
2097 | if (port->type == PORT_8250_CIR) | 2097 | if (port->type == PORT_8250_CIR) |
2098 | return -ENODEV; | 2098 | return -ENODEV; |
2099 | 2099 | ||
2100 | if (!port->fifosize) | 2100 | if (!port->fifosize) |
2101 | port->fifosize = uart_config[port->type].fifo_size; | 2101 | port->fifosize = uart_config[port->type].fifo_size; |
2102 | if (!up->tx_loadsz) | 2102 | if (!up->tx_loadsz) |
2103 | up->tx_loadsz = uart_config[port->type].tx_loadsz; | 2103 | up->tx_loadsz = uart_config[port->type].tx_loadsz; |
2104 | if (!up->capabilities) | 2104 | if (!up->capabilities) |
2105 | up->capabilities = uart_config[port->type].flags; | 2105 | up->capabilities = uart_config[port->type].flags; |
2106 | up->mcr = 0; | 2106 | up->mcr = 0; |
2107 | 2107 | ||
2108 | if (port->iotype != up->cur_iotype) | 2108 | if (port->iotype != up->cur_iotype) |
2109 | set_io_from_upio(port); | 2109 | set_io_from_upio(port); |
2110 | 2110 | ||
2111 | serial8250_rpm_get(up); | 2111 | serial8250_rpm_get(up); |
2112 | if (port->type == PORT_16C950) { | 2112 | if (port->type == PORT_16C950) { |
2113 | /* Wake up and initialize UART */ | 2113 | /* Wake up and initialize UART */ |
2114 | up->acr = 0; | 2114 | up->acr = 0; |
2115 | serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); | 2115 | serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); |
2116 | serial_port_out(port, UART_EFR, UART_EFR_ECB); | 2116 | serial_port_out(port, UART_EFR, UART_EFR_ECB); |
2117 | serial_port_out(port, UART_IER, 0); | 2117 | serial_port_out(port, UART_IER, 0); |
2118 | serial_port_out(port, UART_LCR, 0); | 2118 | serial_port_out(port, UART_LCR, 0); |
2119 | serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ | 2119 | serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ |
2120 | serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); | 2120 | serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); |
2121 | serial_port_out(port, UART_EFR, UART_EFR_ECB); | 2121 | serial_port_out(port, UART_EFR, UART_EFR_ECB); |
2122 | serial_port_out(port, UART_LCR, 0); | 2122 | serial_port_out(port, UART_LCR, 0); |
2123 | } | 2123 | } |
2124 | 2124 | ||
2125 | #ifdef CONFIG_SERIAL_8250_RSA | 2125 | #ifdef CONFIG_SERIAL_8250_RSA |
2126 | /* | 2126 | /* |
2127 | * If this is an RSA port, see if we can kick it up to the | 2127 | * If this is an RSA port, see if we can kick it up to the |
2128 | * higher speed clock. | 2128 | * higher speed clock. |
2129 | */ | 2129 | */ |
2130 | enable_rsa(up); | 2130 | enable_rsa(up); |
2131 | #endif | 2131 | #endif |
2132 | /* | 2132 | /* |
2133 | * Clear the FIFO buffers and disable them. | 2133 | * Clear the FIFO buffers and disable them. |
2134 | * (they will be reenabled in set_termios()) | 2134 | * (they will be reenabled in set_termios()) |
2135 | */ | 2135 | */ |
2136 | serial8250_clear_fifos(up); | 2136 | serial8250_clear_fifos(up); |
2137 | 2137 | ||
2138 | /* | 2138 | /* |
2139 | * Clear the interrupt registers. | 2139 | * Clear the interrupt registers. |
2140 | */ | 2140 | */ |
2141 | if (serial_port_in(port, UART_LSR) & UART_LSR_DR) | 2141 | serial_port_in(port, UART_LSR); |
2142 | serial_port_in(port, UART_RX); | 2142 | serial_port_in(port, UART_RX); |
2143 | serial_port_in(port, UART_IIR); | 2143 | serial_port_in(port, UART_IIR); |
2144 | serial_port_in(port, UART_MSR); | 2144 | serial_port_in(port, UART_MSR); |
2145 | 2145 | ||
2146 | /* | 2146 | /* |
2147 | * At this point, there's no way the LSR could still be 0xff; | 2147 | * At this point, there's no way the LSR could still be 0xff; |
2148 | * if it is, then bail out, because there's likely no UART | 2148 | * if it is, then bail out, because there's likely no UART |
2149 | * here. | 2149 | * here. |
2150 | */ | 2150 | */ |
2151 | if (!(port->flags & UPF_BUGGY_UART) && | 2151 | if (!(port->flags & UPF_BUGGY_UART) && |
2152 | (serial_port_in(port, UART_LSR) == 0xff)) { | 2152 | (serial_port_in(port, UART_LSR) == 0xff)) { |
2153 | printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", | 2153 | printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", |
2154 | serial_index(port)); | 2154 | serial_index(port)); |
2155 | retval = -ENODEV; | 2155 | retval = -ENODEV; |
2156 | goto out; | 2156 | goto out; |
2157 | } | 2157 | } |
2158 | 2158 | ||
2159 | /* | 2159 | /* |
2160 | * For a XR16C850, we need to set the trigger levels | 2160 | * For a XR16C850, we need to set the trigger levels |
2161 | */ | 2161 | */ |
2162 | if (port->type == PORT_16850) { | 2162 | if (port->type == PORT_16850) { |
2163 | unsigned char fctr; | 2163 | unsigned char fctr; |
2164 | 2164 | ||
2165 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 2165 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
2166 | 2166 | ||
2167 | fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); | 2167 | fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); |
2168 | serial_port_out(port, UART_FCTR, | 2168 | serial_port_out(port, UART_FCTR, |
2169 | fctr | UART_FCTR_TRGD | UART_FCTR_RX); | 2169 | fctr | UART_FCTR_TRGD | UART_FCTR_RX); |
2170 | serial_port_out(port, UART_TRG, UART_TRG_96); | 2170 | serial_port_out(port, UART_TRG, UART_TRG_96); |
2171 | serial_port_out(port, UART_FCTR, | 2171 | serial_port_out(port, UART_FCTR, |
2172 | fctr | UART_FCTR_TRGD | UART_FCTR_TX); | 2172 | fctr | UART_FCTR_TRGD | UART_FCTR_TX); |
2173 | serial_port_out(port, UART_TRG, UART_TRG_96); | 2173 | serial_port_out(port, UART_TRG, UART_TRG_96); |
2174 | 2174 | ||
2175 | serial_port_out(port, UART_LCR, 0); | 2175 | serial_port_out(port, UART_LCR, 0); |
2176 | } | 2176 | } |
2177 | 2177 | ||
2178 | if (port->irq) { | 2178 | if (port->irq) { |
2179 | unsigned char iir1; | 2179 | unsigned char iir1; |
2180 | /* | 2180 | /* |
2181 | * Test for UARTs that do not reassert THRE when the | 2181 | * Test for UARTs that do not reassert THRE when the |
2182 | * transmitter is idle and the interrupt has already | 2182 | * transmitter is idle and the interrupt has already |
2183 | * been cleared. Real 16550s should always reassert | 2183 | * been cleared. Real 16550s should always reassert |
2184 | * this interrupt whenever the transmitter is idle and | 2184 | * this interrupt whenever the transmitter is idle and |
2185 | * the interrupt is enabled. Delays are necessary to | 2185 | * the interrupt is enabled. Delays are necessary to |
2186 | * allow register changes to become visible. | 2186 | * allow register changes to become visible. |
2187 | */ | 2187 | */ |
2188 | spin_lock_irqsave(&port->lock, flags); | 2188 | spin_lock_irqsave(&port->lock, flags); |
2189 | if (up->port.irqflags & IRQF_SHARED) | 2189 | if (up->port.irqflags & IRQF_SHARED) |
2190 | disable_irq_nosync(port->irq); | 2190 | disable_irq_nosync(port->irq); |
2191 | 2191 | ||
2192 | wait_for_xmitr(up, UART_LSR_THRE); | 2192 | wait_for_xmitr(up, UART_LSR_THRE); |
2193 | serial_port_out_sync(port, UART_IER, UART_IER_THRI); | 2193 | serial_port_out_sync(port, UART_IER, UART_IER_THRI); |
2194 | udelay(1); /* allow THRE to set */ | 2194 | udelay(1); /* allow THRE to set */ |
2195 | iir1 = serial_port_in(port, UART_IIR); | 2195 | iir1 = serial_port_in(port, UART_IIR); |
2196 | serial_port_out(port, UART_IER, 0); | 2196 | serial_port_out(port, UART_IER, 0); |
2197 | serial_port_out_sync(port, UART_IER, UART_IER_THRI); | 2197 | serial_port_out_sync(port, UART_IER, UART_IER_THRI); |
2198 | udelay(1); /* allow a working UART time to re-assert THRE */ | 2198 | udelay(1); /* allow a working UART time to re-assert THRE */ |
2199 | iir = serial_port_in(port, UART_IIR); | 2199 | iir = serial_port_in(port, UART_IIR); |
2200 | serial_port_out(port, UART_IER, 0); | 2200 | serial_port_out(port, UART_IER, 0); |
2201 | 2201 | ||
2202 | if (port->irqflags & IRQF_SHARED) | 2202 | if (port->irqflags & IRQF_SHARED) |
2203 | enable_irq(port->irq); | 2203 | enable_irq(port->irq); |
2204 | spin_unlock_irqrestore(&port->lock, flags); | 2204 | spin_unlock_irqrestore(&port->lock, flags); |
2205 | 2205 | ||
2206 | /* | 2206 | /* |
2207 | * If the interrupt is not reasserted, or we otherwise | 2207 | * If the interrupt is not reasserted, or we otherwise |
2208 | * don't trust the iir, setup a timer to kick the UART | 2208 | * don't trust the iir, setup a timer to kick the UART |
2209 | * on a regular basis. | 2209 | * on a regular basis. |
2210 | */ | 2210 | */ |
2211 | if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) || | 2211 | if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) || |
2212 | up->port.flags & UPF_BUG_THRE) { | 2212 | up->port.flags & UPF_BUG_THRE) { |
2213 | up->bugs |= UART_BUG_THRE; | 2213 | up->bugs |= UART_BUG_THRE; |
2214 | pr_debug("ttyS%d - using backup timer\n", | 2214 | pr_debug("ttyS%d - using backup timer\n", |
2215 | serial_index(port)); | 2215 | serial_index(port)); |
2216 | } | 2216 | } |
2217 | } | 2217 | } |
2218 | 2218 | ||
2219 | /* | 2219 | /* |
2220 | * The above check will only give an accurate result the first time | 2220 | * The above check will only give an accurate result the first time |
2221 | * the port is opened so this value needs to be preserved. | 2221 | * the port is opened so this value needs to be preserved. |
2222 | */ | 2222 | */ |
2223 | if (up->bugs & UART_BUG_THRE) { | 2223 | if (up->bugs & UART_BUG_THRE) { |
2224 | up->timer.function = serial8250_backup_timeout; | 2224 | up->timer.function = serial8250_backup_timeout; |
2225 | up->timer.data = (unsigned long)up; | 2225 | up->timer.data = (unsigned long)up; |
2226 | mod_timer(&up->timer, jiffies + | 2226 | mod_timer(&up->timer, jiffies + |
2227 | uart_poll_timeout(port) + HZ / 5); | 2227 | uart_poll_timeout(port) + HZ / 5); |
2228 | } | 2228 | } |
2229 | 2229 | ||
2230 | /* | 2230 | /* |
2231 | * If the "interrupt" for this port doesn't correspond with any | 2231 | * If the "interrupt" for this port doesn't correspond with any |
2232 | * hardware interrupt, we use a timer-based system. The original | 2232 | * hardware interrupt, we use a timer-based system. The original |
2233 | * driver used to do this with IRQ0. | 2233 | * driver used to do this with IRQ0. |
2234 | */ | 2234 | */ |
2235 | if (!port->irq) { | 2235 | if (!port->irq) { |
2236 | up->timer.data = (unsigned long)up; | 2236 | up->timer.data = (unsigned long)up; |
2237 | mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); | 2237 | mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); |
2238 | } else { | 2238 | } else { |
2239 | retval = serial_link_irq_chain(up); | 2239 | retval = serial_link_irq_chain(up); |
2240 | if (retval) | 2240 | if (retval) |
2241 | goto out; | 2241 | goto out; |
2242 | } | 2242 | } |
2243 | 2243 | ||
2244 | /* | 2244 | /* |
2245 | * Now, initialize the UART | 2245 | * Now, initialize the UART |
2246 | */ | 2246 | */ |
2247 | serial_port_out(port, UART_LCR, UART_LCR_WLEN8); | 2247 | serial_port_out(port, UART_LCR, UART_LCR_WLEN8); |
2248 | 2248 | ||
2249 | spin_lock_irqsave(&port->lock, flags); | 2249 | spin_lock_irqsave(&port->lock, flags); |
2250 | if (up->port.flags & UPF_FOURPORT) { | 2250 | if (up->port.flags & UPF_FOURPORT) { |
2251 | if (!up->port.irq) | 2251 | if (!up->port.irq) |
2252 | up->port.mctrl |= TIOCM_OUT1; | 2252 | up->port.mctrl |= TIOCM_OUT1; |
2253 | } else | 2253 | } else |
2254 | /* | 2254 | /* |
2255 | * Most PC uarts need OUT2 raised to enable interrupts. | 2255 | * Most PC uarts need OUT2 raised to enable interrupts. |
2256 | */ | 2256 | */ |
2257 | if (port->irq) | 2257 | if (port->irq) |
2258 | up->port.mctrl |= TIOCM_OUT2; | 2258 | up->port.mctrl |= TIOCM_OUT2; |
2259 | 2259 | ||
2260 | serial8250_set_mctrl(port, port->mctrl); | 2260 | serial8250_set_mctrl(port, port->mctrl); |
2261 | 2261 | ||
2262 | /* Serial over Lan (SoL) hack: | 2262 | /* Serial over Lan (SoL) hack: |
2263 | Intel 8257x Gigabit ethernet chips have a | 2263 | Intel 8257x Gigabit ethernet chips have a |
2264 | 16550 emulation, to be used for Serial Over Lan. | 2264 | 16550 emulation, to be used for Serial Over Lan. |
2265 | Those chips take a longer time than a normal | 2265 | Those chips take a longer time than a normal |
2266 | serial device to signalize that a transmission | 2266 | serial device to signalize that a transmission |
2267 | data was queued. Due to that, the above test generally | 2267 | data was queued. Due to that, the above test generally |
2268 | fails. One solution would be to delay the reading of | 2268 | fails. One solution would be to delay the reading of |
2269 | iir. However, this is not reliable, since the timeout | 2269 | iir. However, this is not reliable, since the timeout |
2270 | is variable. So, let's just don't test if we receive | 2270 | is variable. So, let's just don't test if we receive |
2271 | TX irq. This way, we'll never enable UART_BUG_TXEN. | 2271 | TX irq. This way, we'll never enable UART_BUG_TXEN. |
2272 | */ | 2272 | */ |
2273 | if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST) | 2273 | if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST) |
2274 | goto dont_test_tx_en; | 2274 | goto dont_test_tx_en; |
2275 | 2275 | ||
2276 | /* | 2276 | /* |
2277 | * Do a quick test to see if we receive an | 2277 | * Do a quick test to see if we receive an |
2278 | * interrupt when we enable the TX irq. | 2278 | * interrupt when we enable the TX irq. |
2279 | */ | 2279 | */ |
2280 | serial_port_out(port, UART_IER, UART_IER_THRI); | 2280 | serial_port_out(port, UART_IER, UART_IER_THRI); |
2281 | lsr = serial_port_in(port, UART_LSR); | 2281 | lsr = serial_port_in(port, UART_LSR); |
2282 | iir = serial_port_in(port, UART_IIR); | 2282 | iir = serial_port_in(port, UART_IIR); |
2283 | serial_port_out(port, UART_IER, 0); | 2283 | serial_port_out(port, UART_IER, 0); |
2284 | 2284 | ||
2285 | if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { | 2285 | if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { |
2286 | if (!(up->bugs & UART_BUG_TXEN)) { | 2286 | if (!(up->bugs & UART_BUG_TXEN)) { |
2287 | up->bugs |= UART_BUG_TXEN; | 2287 | up->bugs |= UART_BUG_TXEN; |
2288 | pr_debug("ttyS%d - enabling bad tx status workarounds\n", | 2288 | pr_debug("ttyS%d - enabling bad tx status workarounds\n", |
2289 | serial_index(port)); | 2289 | serial_index(port)); |
2290 | } | 2290 | } |
2291 | } else { | 2291 | } else { |
2292 | up->bugs &= ~UART_BUG_TXEN; | 2292 | up->bugs &= ~UART_BUG_TXEN; |
2293 | } | 2293 | } |
2294 | 2294 | ||
2295 | dont_test_tx_en: | 2295 | dont_test_tx_en: |
2296 | spin_unlock_irqrestore(&port->lock, flags); | 2296 | spin_unlock_irqrestore(&port->lock, flags); |
2297 | 2297 | ||
2298 | /* | 2298 | /* |
2299 | * Clear the interrupt registers again for luck, and clear the | 2299 | * Clear the interrupt registers again for luck, and clear the |
2300 | * saved flags to avoid getting false values from polling | 2300 | * saved flags to avoid getting false values from polling |
2301 | * routines or the previous session. | 2301 | * routines or the previous session. |
2302 | */ | 2302 | */ |
2303 | if (serial_port_in(port, UART_LSR) & UART_LSR_DR) | 2303 | serial_port_in(port, UART_LSR); |
2304 | serial_port_in(port, UART_RX); | 2304 | serial_port_in(port, UART_RX); |
2305 | serial_port_in(port, UART_IIR); | 2305 | serial_port_in(port, UART_IIR); |
2306 | serial_port_in(port, UART_MSR); | 2306 | serial_port_in(port, UART_MSR); |
2307 | up->lsr_saved_flags = 0; | 2307 | up->lsr_saved_flags = 0; |
2308 | up->msr_saved_flags = 0; | 2308 | up->msr_saved_flags = 0; |
2309 | 2309 | ||
2310 | /* | 2310 | /* |
2311 | * Request DMA channels for both RX and TX. | 2311 | * Request DMA channels for both RX and TX. |
2312 | */ | 2312 | */ |
2313 | if (up->dma) { | 2313 | if (up->dma) { |
2314 | retval = serial8250_request_dma(up); | 2314 | retval = serial8250_request_dma(up); |
2315 | if (retval) { | 2315 | if (retval) { |
2316 | pr_warn_ratelimited("ttyS%d - failed to request DMA\n", | 2316 | pr_warn_ratelimited("ttyS%d - failed to request DMA\n", |
2317 | serial_index(port)); | 2317 | serial_index(port)); |
2318 | up->dma = NULL; | 2318 | up->dma = NULL; |
2319 | } | 2319 | } |
2320 | } | 2320 | } |
2321 | 2321 | ||
2322 | /* | 2322 | /* |
2323 | * Finally, enable interrupts. Note: Modem status interrupts | 2323 | * Finally, enable interrupts. Note: Modem status interrupts |
2324 | * are set via set_termios(), which will be occurring imminently | 2324 | * are set via set_termios(), which will be occurring imminently |
2325 | * anyway, so we don't enable them here. | 2325 | * anyway, so we don't enable them here. |
2326 | */ | 2326 | */ |
2327 | up->ier = UART_IER_RLSI | UART_IER_RDI; | 2327 | up->ier = UART_IER_RLSI | UART_IER_RDI; |
2328 | serial_port_out(port, UART_IER, up->ier); | 2328 | serial_port_out(port, UART_IER, up->ier); |
2329 | 2329 | ||
2330 | if (port->flags & UPF_FOURPORT) { | 2330 | if (port->flags & UPF_FOURPORT) { |
2331 | unsigned int icp; | 2331 | unsigned int icp; |
2332 | /* | 2332 | /* |
2333 | * Enable interrupts on the AST Fourport board | 2333 | * Enable interrupts on the AST Fourport board |
2334 | */ | 2334 | */ |
2335 | icp = (port->iobase & 0xfe0) | 0x01f; | 2335 | icp = (port->iobase & 0xfe0) | 0x01f; |
2336 | outb_p(0x80, icp); | 2336 | outb_p(0x80, icp); |
2337 | inb_p(icp); | 2337 | inb_p(icp); |
2338 | } | 2338 | } |
2339 | retval = 0; | 2339 | retval = 0; |
2340 | out: | 2340 | out: |
2341 | serial8250_rpm_put(up); | 2341 | serial8250_rpm_put(up); |
2342 | return retval; | 2342 | return retval; |
2343 | } | 2343 | } |
2344 | EXPORT_SYMBOL_GPL(serial8250_do_startup); | 2344 | EXPORT_SYMBOL_GPL(serial8250_do_startup); |
2345 | 2345 | ||
2346 | static int serial8250_startup(struct uart_port *port) | 2346 | static int serial8250_startup(struct uart_port *port) |
2347 | { | 2347 | { |
2348 | if (port->startup) | 2348 | if (port->startup) |
2349 | return port->startup(port); | 2349 | return port->startup(port); |
2350 | return serial8250_do_startup(port); | 2350 | return serial8250_do_startup(port); |
2351 | } | 2351 | } |
2352 | 2352 | ||
2353 | void serial8250_do_shutdown(struct uart_port *port) | 2353 | void serial8250_do_shutdown(struct uart_port *port) |
2354 | { | 2354 | { |
2355 | struct uart_8250_port *up = up_to_u8250p(port); | 2355 | struct uart_8250_port *up = up_to_u8250p(port); |
2356 | unsigned long flags; | 2356 | unsigned long flags; |
2357 | 2357 | ||
2358 | serial8250_rpm_get(up); | 2358 | serial8250_rpm_get(up); |
2359 | /* | 2359 | /* |
2360 | * Disable interrupts from this port | 2360 | * Disable interrupts from this port |
2361 | */ | 2361 | */ |
2362 | up->ier = 0; | 2362 | up->ier = 0; |
2363 | serial_port_out(port, UART_IER, 0); | 2363 | serial_port_out(port, UART_IER, 0); |
2364 | 2364 | ||
2365 | if (up->dma) | 2365 | if (up->dma) |
2366 | serial8250_release_dma(up); | 2366 | serial8250_release_dma(up); |
2367 | 2367 | ||
2368 | spin_lock_irqsave(&port->lock, flags); | 2368 | spin_lock_irqsave(&port->lock, flags); |
2369 | if (port->flags & UPF_FOURPORT) { | 2369 | if (port->flags & UPF_FOURPORT) { |
2370 | /* reset interrupts on the AST Fourport board */ | 2370 | /* reset interrupts on the AST Fourport board */ |
2371 | inb((port->iobase & 0xfe0) | 0x1f); | 2371 | inb((port->iobase & 0xfe0) | 0x1f); |
2372 | port->mctrl |= TIOCM_OUT1; | 2372 | port->mctrl |= TIOCM_OUT1; |
2373 | } else | 2373 | } else |
2374 | port->mctrl &= ~TIOCM_OUT2; | 2374 | port->mctrl &= ~TIOCM_OUT2; |
2375 | 2375 | ||
2376 | serial8250_set_mctrl(port, port->mctrl); | 2376 | serial8250_set_mctrl(port, port->mctrl); |
2377 | spin_unlock_irqrestore(&port->lock, flags); | 2377 | spin_unlock_irqrestore(&port->lock, flags); |
2378 | 2378 | ||
2379 | /* | 2379 | /* |
2380 | * Disable break condition and FIFOs | 2380 | * Disable break condition and FIFOs |
2381 | */ | 2381 | */ |
2382 | serial_port_out(port, UART_LCR, | 2382 | serial_port_out(port, UART_LCR, |
2383 | serial_port_in(port, UART_LCR) & ~UART_LCR_SBC); | 2383 | serial_port_in(port, UART_LCR) & ~UART_LCR_SBC); |
2384 | serial8250_clear_fifos(up); | 2384 | serial8250_clear_fifos(up); |
2385 | 2385 | ||
2386 | #ifdef CONFIG_SERIAL_8250_RSA | 2386 | #ifdef CONFIG_SERIAL_8250_RSA |
2387 | /* | 2387 | /* |
2388 | * Reset the RSA board back to 115kbps compat mode. | 2388 | * Reset the RSA board back to 115kbps compat mode. |
2389 | */ | 2389 | */ |
2390 | disable_rsa(up); | 2390 | disable_rsa(up); |
2391 | #endif | 2391 | #endif |
2392 | 2392 | ||
2393 | /* | 2393 | /* |
2394 | * Read data port to reset things, and then unlink from | 2394 | * Read data port to reset things, and then unlink from |
2395 | * the IRQ chain. | 2395 | * the IRQ chain. |
2396 | */ | 2396 | */ |
2397 | if (serial_port_in(port, UART_LSR) & UART_LSR_DR) | 2397 | serial_port_in(port, UART_RX); |
2398 | serial_port_in(port, UART_RX); | ||
2399 | serial8250_rpm_put(up); | 2398 | serial8250_rpm_put(up); |
2400 | 2399 | ||
2401 | del_timer_sync(&up->timer); | 2400 | del_timer_sync(&up->timer); |
2402 | up->timer.function = serial8250_timeout; | 2401 | up->timer.function = serial8250_timeout; |
2403 | if (port->irq) | 2402 | if (port->irq) |
2404 | serial_unlink_irq_chain(up); | 2403 | serial_unlink_irq_chain(up); |
2405 | } | 2404 | } |
2406 | EXPORT_SYMBOL_GPL(serial8250_do_shutdown); | 2405 | EXPORT_SYMBOL_GPL(serial8250_do_shutdown); |
2407 | 2406 | ||
2408 | static void serial8250_shutdown(struct uart_port *port) | 2407 | static void serial8250_shutdown(struct uart_port *port) |
2409 | { | 2408 | { |
2410 | if (port->shutdown) | 2409 | if (port->shutdown) |
2411 | port->shutdown(port); | 2410 | port->shutdown(port); |
2412 | else | 2411 | else |
2413 | serial8250_do_shutdown(port); | 2412 | serial8250_do_shutdown(port); |
2414 | } | 2413 | } |
2415 | 2414 | ||
2416 | /* | 2415 | /* |
2417 | * XR17V35x UARTs have an extra fractional divisor register (DLD) | 2416 | * XR17V35x UARTs have an extra fractional divisor register (DLD) |
2418 | * Calculate divisor with extra 4-bit fractional portion | 2417 | * Calculate divisor with extra 4-bit fractional portion |
2419 | */ | 2418 | */ |
2420 | static unsigned int xr17v35x_get_divisor(struct uart_8250_port *up, | 2419 | static unsigned int xr17v35x_get_divisor(struct uart_8250_port *up, |
2421 | unsigned int baud, | 2420 | unsigned int baud, |
2422 | unsigned int *frac) | 2421 | unsigned int *frac) |
2423 | { | 2422 | { |
2424 | struct uart_port *port = &up->port; | 2423 | struct uart_port *port = &up->port; |
2425 | unsigned int quot_16; | 2424 | unsigned int quot_16; |
2426 | 2425 | ||
2427 | quot_16 = DIV_ROUND_CLOSEST(port->uartclk, baud); | 2426 | quot_16 = DIV_ROUND_CLOSEST(port->uartclk, baud); |
2428 | *frac = quot_16 & 0x0f; | 2427 | *frac = quot_16 & 0x0f; |
2429 | 2428 | ||
2430 | return quot_16 >> 4; | 2429 | return quot_16 >> 4; |
2431 | } | 2430 | } |
2432 | 2431 | ||
2433 | static unsigned int serial8250_get_divisor(struct uart_8250_port *up, | 2432 | static unsigned int serial8250_get_divisor(struct uart_8250_port *up, |
2434 | unsigned int baud, | 2433 | unsigned int baud, |
2435 | unsigned int *frac) | 2434 | unsigned int *frac) |
2436 | { | 2435 | { |
2437 | struct uart_port *port = &up->port; | 2436 | struct uart_port *port = &up->port; |
2438 | unsigned int quot; | 2437 | unsigned int quot; |
2439 | 2438 | ||
2440 | /* | 2439 | /* |
2441 | * Handle magic divisors for baud rates above baud_base on | 2440 | * Handle magic divisors for baud rates above baud_base on |
2442 | * SMSC SuperIO chips. | 2441 | * SMSC SuperIO chips. |
2443 | * | 2442 | * |
2444 | */ | 2443 | */ |
2445 | if ((port->flags & UPF_MAGIC_MULTIPLIER) && | 2444 | if ((port->flags & UPF_MAGIC_MULTIPLIER) && |
2446 | baud == (port->uartclk/4)) | 2445 | baud == (port->uartclk/4)) |
2447 | quot = 0x8001; | 2446 | quot = 0x8001; |
2448 | else if ((port->flags & UPF_MAGIC_MULTIPLIER) && | 2447 | else if ((port->flags & UPF_MAGIC_MULTIPLIER) && |
2449 | baud == (port->uartclk/8)) | 2448 | baud == (port->uartclk/8)) |
2450 | quot = 0x8002; | 2449 | quot = 0x8002; |
2451 | else if (up->port.type == PORT_XR17V35X) | 2450 | else if (up->port.type == PORT_XR17V35X) |
2452 | quot = xr17v35x_get_divisor(up, baud, frac); | 2451 | quot = xr17v35x_get_divisor(up, baud, frac); |
2453 | else | 2452 | else |
2454 | quot = uart_get_divisor(port, baud); | 2453 | quot = uart_get_divisor(port, baud); |
2455 | 2454 | ||
2456 | /* | 2455 | /* |
2457 | * Oxford Semi 952 rev B workaround | 2456 | * Oxford Semi 952 rev B workaround |
2458 | */ | 2457 | */ |
2459 | if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) | 2458 | if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) |
2460 | quot++; | 2459 | quot++; |
2461 | 2460 | ||
2462 | return quot; | 2461 | return quot; |
2463 | } | 2462 | } |
2464 | 2463 | ||
2465 | static unsigned char serial8250_compute_lcr(struct uart_8250_port *up, | 2464 | static unsigned char serial8250_compute_lcr(struct uart_8250_port *up, |
2466 | tcflag_t c_cflag) | 2465 | tcflag_t c_cflag) |
2467 | { | 2466 | { |
2468 | unsigned char cval; | 2467 | unsigned char cval; |
2469 | 2468 | ||
2470 | switch (c_cflag & CSIZE) { | 2469 | switch (c_cflag & CSIZE) { |
2471 | case CS5: | 2470 | case CS5: |
2472 | cval = UART_LCR_WLEN5; | 2471 | cval = UART_LCR_WLEN5; |
2473 | break; | 2472 | break; |
2474 | case CS6: | 2473 | case CS6: |
2475 | cval = UART_LCR_WLEN6; | 2474 | cval = UART_LCR_WLEN6; |
2476 | break; | 2475 | break; |
2477 | case CS7: | 2476 | case CS7: |
2478 | cval = UART_LCR_WLEN7; | 2477 | cval = UART_LCR_WLEN7; |
2479 | break; | 2478 | break; |
2480 | default: | 2479 | default: |
2481 | case CS8: | 2480 | case CS8: |
2482 | cval = UART_LCR_WLEN8; | 2481 | cval = UART_LCR_WLEN8; |
2483 | break; | 2482 | break; |
2484 | } | 2483 | } |
2485 | 2484 | ||
2486 | if (c_cflag & CSTOPB) | 2485 | if (c_cflag & CSTOPB) |
2487 | cval |= UART_LCR_STOP; | 2486 | cval |= UART_LCR_STOP; |
2488 | if (c_cflag & PARENB) { | 2487 | if (c_cflag & PARENB) { |
2489 | cval |= UART_LCR_PARITY; | 2488 | cval |= UART_LCR_PARITY; |
2490 | if (up->bugs & UART_BUG_PARITY) | 2489 | if (up->bugs & UART_BUG_PARITY) |
2491 | up->fifo_bug = true; | 2490 | up->fifo_bug = true; |
2492 | } | 2491 | } |
2493 | if (!(c_cflag & PARODD)) | 2492 | if (!(c_cflag & PARODD)) |
2494 | cval |= UART_LCR_EPAR; | 2493 | cval |= UART_LCR_EPAR; |
2495 | #ifdef CMSPAR | 2494 | #ifdef CMSPAR |
2496 | if (c_cflag & CMSPAR) | 2495 | if (c_cflag & CMSPAR) |
2497 | cval |= UART_LCR_SPAR; | 2496 | cval |= UART_LCR_SPAR; |
2498 | #endif | 2497 | #endif |
2499 | 2498 | ||
2500 | return cval; | 2499 | return cval; |
2501 | } | 2500 | } |
2502 | 2501 | ||
2503 | static void serial8250_set_divisor(struct uart_port *port, unsigned int baud, | 2502 | static void serial8250_set_divisor(struct uart_port *port, unsigned int baud, |
2504 | unsigned int quot, unsigned int quot_frac) | 2503 | unsigned int quot, unsigned int quot_frac) |
2505 | { | 2504 | { |
2506 | struct uart_8250_port *up = up_to_u8250p(port); | 2505 | struct uart_8250_port *up = up_to_u8250p(port); |
2507 | 2506 | ||
2508 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ | 2507 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ |
2509 | if (is_omap1510_8250(up)) { | 2508 | if (is_omap1510_8250(up)) { |
2510 | if (baud == 115200) { | 2509 | if (baud == 115200) { |
2511 | quot = 1; | 2510 | quot = 1; |
2512 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); | 2511 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); |
2513 | } else | 2512 | } else |
2514 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); | 2513 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); |
2515 | } | 2514 | } |
2516 | 2515 | ||
2517 | /* | 2516 | /* |
2518 | * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, | 2517 | * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, |
2519 | * otherwise just set DLAB | 2518 | * otherwise just set DLAB |
2520 | */ | 2519 | */ |
2521 | if (up->capabilities & UART_NATSEMI) | 2520 | if (up->capabilities & UART_NATSEMI) |
2522 | serial_port_out(port, UART_LCR, 0xe0); | 2521 | serial_port_out(port, UART_LCR, 0xe0); |
2523 | else | 2522 | else |
2524 | serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); | 2523 | serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); |
2525 | 2524 | ||
2526 | serial_dl_write(up, quot); | 2525 | serial_dl_write(up, quot); |
2527 | 2526 | ||
2528 | /* XR17V35x UARTs have an extra fractional divisor register (DLD) */ | 2527 | /* XR17V35x UARTs have an extra fractional divisor register (DLD) */ |
2529 | if (up->port.type == PORT_XR17V35X) | 2528 | if (up->port.type == PORT_XR17V35X) |
2530 | serial_port_out(port, 0x2, quot_frac); | 2529 | serial_port_out(port, 0x2, quot_frac); |
2531 | } | 2530 | } |
2532 | 2531 | ||
2533 | void | 2532 | void |
2534 | serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | 2533 | serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, |
2535 | struct ktermios *old) | 2534 | struct ktermios *old) |
2536 | { | 2535 | { |
2537 | struct uart_8250_port *up = up_to_u8250p(port); | 2536 | struct uart_8250_port *up = up_to_u8250p(port); |
2538 | unsigned char cval; | 2537 | unsigned char cval; |
2539 | unsigned long flags; | 2538 | unsigned long flags; |
2540 | unsigned int baud, quot, frac = 0; | 2539 | unsigned int baud, quot, frac = 0; |
2541 | 2540 | ||
2542 | cval = serial8250_compute_lcr(up, termios->c_cflag); | 2541 | cval = serial8250_compute_lcr(up, termios->c_cflag); |
2543 | 2542 | ||
2544 | /* | 2543 | /* |
2545 | * Ask the core to calculate the divisor for us. | 2544 | * Ask the core to calculate the divisor for us. |
2546 | */ | 2545 | */ |
2547 | baud = uart_get_baud_rate(port, termios, old, | 2546 | baud = uart_get_baud_rate(port, termios, old, |
2548 | port->uartclk / 16 / 0xffff, | 2547 | port->uartclk / 16 / 0xffff, |
2549 | port->uartclk / 16); | 2548 | port->uartclk / 16); |
2550 | quot = serial8250_get_divisor(up, baud, &frac); | 2549 | quot = serial8250_get_divisor(up, baud, &frac); |
2551 | 2550 | ||
2552 | /* | 2551 | /* |
2553 | * Ok, we're now changing the port state. Do it with | 2552 | * Ok, we're now changing the port state. Do it with |
2554 | * interrupts disabled. | 2553 | * interrupts disabled. |
2555 | */ | 2554 | */ |
2556 | serial8250_rpm_get(up); | 2555 | serial8250_rpm_get(up); |
2557 | spin_lock_irqsave(&port->lock, flags); | 2556 | spin_lock_irqsave(&port->lock, flags); |
2558 | 2557 | ||
2559 | up->lcr = cval; /* Save computed LCR */ | 2558 | up->lcr = cval; /* Save computed LCR */ |
2560 | 2559 | ||
2561 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { | 2560 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { |
2562 | /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ | 2561 | /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ |
2563 | if ((baud < 2400 && !up->dma) || up->fifo_bug) { | 2562 | if ((baud < 2400 && !up->dma) || up->fifo_bug) { |
2564 | up->fcr &= ~UART_FCR_TRIGGER_MASK; | 2563 | up->fcr &= ~UART_FCR_TRIGGER_MASK; |
2565 | up->fcr |= UART_FCR_TRIGGER_1; | 2564 | up->fcr |= UART_FCR_TRIGGER_1; |
2566 | } | 2565 | } |
2567 | } | 2566 | } |
2568 | 2567 | ||
2569 | /* | 2568 | /* |
2570 | * MCR-based auto flow control. When AFE is enabled, RTS will be | 2569 | * MCR-based auto flow control. When AFE is enabled, RTS will be |
2571 | * deasserted when the receive FIFO contains more characters than | 2570 | * deasserted when the receive FIFO contains more characters than |
2572 | * the trigger, or the MCR RTS bit is cleared. In the case where | 2571 | * the trigger, or the MCR RTS bit is cleared. In the case where |
2573 | * the remote UART is not using CTS auto flow control, we must | 2572 | * the remote UART is not using CTS auto flow control, we must |
2574 | * have sufficient FIFO entries for the latency of the remote | 2573 | * have sufficient FIFO entries for the latency of the remote |
2575 | * UART to respond. IOW, at least 32 bytes of FIFO. | 2574 | * UART to respond. IOW, at least 32 bytes of FIFO. |
2576 | */ | 2575 | */ |
2577 | if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) { | 2576 | if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) { |
2578 | up->mcr &= ~UART_MCR_AFE; | 2577 | up->mcr &= ~UART_MCR_AFE; |
2579 | if (termios->c_cflag & CRTSCTS) | 2578 | if (termios->c_cflag & CRTSCTS) |
2580 | up->mcr |= UART_MCR_AFE; | 2579 | up->mcr |= UART_MCR_AFE; |
2581 | } | 2580 | } |
2582 | 2581 | ||
2583 | /* | 2582 | /* |
2584 | * Update the per-port timeout. | 2583 | * Update the per-port timeout. |
2585 | */ | 2584 | */ |
2586 | uart_update_timeout(port, termios->c_cflag, baud); | 2585 | uart_update_timeout(port, termios->c_cflag, baud); |
2587 | 2586 | ||
2588 | port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | 2587 | port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; |
2589 | if (termios->c_iflag & INPCK) | 2588 | if (termios->c_iflag & INPCK) |
2590 | port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | 2589 | port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; |
2591 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) | 2590 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) |
2592 | port->read_status_mask |= UART_LSR_BI; | 2591 | port->read_status_mask |= UART_LSR_BI; |
2593 | 2592 | ||
2594 | /* | 2593 | /* |
2595 | * Characteres to ignore | 2594 | * Characteres to ignore |
2596 | */ | 2595 | */ |
2597 | port->ignore_status_mask = 0; | 2596 | port->ignore_status_mask = 0; |
2598 | if (termios->c_iflag & IGNPAR) | 2597 | if (termios->c_iflag & IGNPAR) |
2599 | port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | 2598 | port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; |
2600 | if (termios->c_iflag & IGNBRK) { | 2599 | if (termios->c_iflag & IGNBRK) { |
2601 | port->ignore_status_mask |= UART_LSR_BI; | 2600 | port->ignore_status_mask |= UART_LSR_BI; |
2602 | /* | 2601 | /* |
2603 | * If we're ignoring parity and break indicators, | 2602 | * If we're ignoring parity and break indicators, |
2604 | * ignore overruns too (for real raw support). | 2603 | * ignore overruns too (for real raw support). |
2605 | */ | 2604 | */ |
2606 | if (termios->c_iflag & IGNPAR) | 2605 | if (termios->c_iflag & IGNPAR) |
2607 | port->ignore_status_mask |= UART_LSR_OE; | 2606 | port->ignore_status_mask |= UART_LSR_OE; |
2608 | } | 2607 | } |
2609 | 2608 | ||
2610 | /* | 2609 | /* |
2611 | * ignore all characters if CREAD is not set | 2610 | * ignore all characters if CREAD is not set |
2612 | */ | 2611 | */ |
2613 | if ((termios->c_cflag & CREAD) == 0) | 2612 | if ((termios->c_cflag & CREAD) == 0) |
2614 | port->ignore_status_mask |= UART_LSR_DR; | 2613 | port->ignore_status_mask |= UART_LSR_DR; |
2615 | 2614 | ||
2616 | /* | 2615 | /* |
2617 | * CTS flow control flag and modem status interrupts | 2616 | * CTS flow control flag and modem status interrupts |
2618 | */ | 2617 | */ |
2619 | up->ier &= ~UART_IER_MSI; | 2618 | up->ier &= ~UART_IER_MSI; |
2620 | if (!(up->bugs & UART_BUG_NOMSR) && | 2619 | if (!(up->bugs & UART_BUG_NOMSR) && |
2621 | UART_ENABLE_MS(&up->port, termios->c_cflag)) | 2620 | UART_ENABLE_MS(&up->port, termios->c_cflag)) |
2622 | up->ier |= UART_IER_MSI; | 2621 | up->ier |= UART_IER_MSI; |
2623 | if (up->capabilities & UART_CAP_UUE) | 2622 | if (up->capabilities & UART_CAP_UUE) |
2624 | up->ier |= UART_IER_UUE; | 2623 | up->ier |= UART_IER_UUE; |
2625 | if (up->capabilities & UART_CAP_RTOIE) | 2624 | if (up->capabilities & UART_CAP_RTOIE) |
2626 | up->ier |= UART_IER_RTOIE; | 2625 | up->ier |= UART_IER_RTOIE; |
2627 | 2626 | ||
2628 | serial_port_out(port, UART_IER, up->ier); | 2627 | serial_port_out(port, UART_IER, up->ier); |
2629 | 2628 | ||
2630 | if (up->capabilities & UART_CAP_EFR) { | 2629 | if (up->capabilities & UART_CAP_EFR) { |
2631 | unsigned char efr = 0; | 2630 | unsigned char efr = 0; |
2632 | /* | 2631 | /* |
2633 | * TI16C752/Startech hardware flow control. FIXME: | 2632 | * TI16C752/Startech hardware flow control. FIXME: |
2634 | * - TI16C752 requires control thresholds to be set. | 2633 | * - TI16C752 requires control thresholds to be set. |
2635 | * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled. | 2634 | * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled. |
2636 | */ | 2635 | */ |
2637 | if (termios->c_cflag & CRTSCTS) | 2636 | if (termios->c_cflag & CRTSCTS) |
2638 | efr |= UART_EFR_CTS; | 2637 | efr |= UART_EFR_CTS; |
2639 | 2638 | ||
2640 | serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); | 2639 | serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); |
2641 | if (port->flags & UPF_EXAR_EFR) | 2640 | if (port->flags & UPF_EXAR_EFR) |
2642 | serial_port_out(port, UART_XR_EFR, efr); | 2641 | serial_port_out(port, UART_XR_EFR, efr); |
2643 | else | 2642 | else |
2644 | serial_port_out(port, UART_EFR, efr); | 2643 | serial_port_out(port, UART_EFR, efr); |
2645 | } | 2644 | } |
2646 | 2645 | ||
2647 | serial8250_set_divisor(port, baud, quot, frac); | 2646 | serial8250_set_divisor(port, baud, quot, frac); |
2648 | 2647 | ||
2649 | /* | 2648 | /* |
2650 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR | 2649 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR |
2651 | * is written without DLAB set, this mode will be disabled. | 2650 | * is written without DLAB set, this mode will be disabled. |
2652 | */ | 2651 | */ |
2653 | if (port->type == PORT_16750) | 2652 | if (port->type == PORT_16750) |
2654 | serial_port_out(port, UART_FCR, up->fcr); | 2653 | serial_port_out(port, UART_FCR, up->fcr); |
2655 | 2654 | ||
2656 | serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */ | 2655 | serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */ |
2657 | if (port->type != PORT_16750) { | 2656 | if (port->type != PORT_16750) { |
2658 | /* emulated UARTs (Lucent Venus 167x) need two steps */ | 2657 | /* emulated UARTs (Lucent Venus 167x) need two steps */ |
2659 | if (up->fcr & UART_FCR_ENABLE_FIFO) | 2658 | if (up->fcr & UART_FCR_ENABLE_FIFO) |
2660 | serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); | 2659 | serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); |
2661 | serial_port_out(port, UART_FCR, up->fcr); /* set fcr */ | 2660 | serial_port_out(port, UART_FCR, up->fcr); /* set fcr */ |
2662 | } | 2661 | } |
2663 | serial8250_set_mctrl(port, port->mctrl); | 2662 | serial8250_set_mctrl(port, port->mctrl); |
2664 | spin_unlock_irqrestore(&port->lock, flags); | 2663 | spin_unlock_irqrestore(&port->lock, flags); |
2665 | serial8250_rpm_put(up); | 2664 | serial8250_rpm_put(up); |
2666 | 2665 | ||
2667 | /* Don't rewrite B0 */ | 2666 | /* Don't rewrite B0 */ |
2668 | if (tty_termios_baud_rate(termios)) | 2667 | if (tty_termios_baud_rate(termios)) |
2669 | tty_termios_encode_baud_rate(termios, baud, baud); | 2668 | tty_termios_encode_baud_rate(termios, baud, baud); |
2670 | } | 2669 | } |
2671 | EXPORT_SYMBOL(serial8250_do_set_termios); | 2670 | EXPORT_SYMBOL(serial8250_do_set_termios); |
2672 | 2671 | ||
2673 | static void | 2672 | static void |
2674 | serial8250_set_termios(struct uart_port *port, struct ktermios *termios, | 2673 | serial8250_set_termios(struct uart_port *port, struct ktermios *termios, |
2675 | struct ktermios *old) | 2674 | struct ktermios *old) |
2676 | { | 2675 | { |
2677 | if (port->set_termios) | 2676 | if (port->set_termios) |
2678 | port->set_termios(port, termios, old); | 2677 | port->set_termios(port, termios, old); |
2679 | else | 2678 | else |
2680 | serial8250_do_set_termios(port, termios, old); | 2679 | serial8250_do_set_termios(port, termios, old); |
2681 | } | 2680 | } |
2682 | 2681 | ||
2683 | static void | 2682 | static void |
2684 | serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios) | 2683 | serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios) |
2685 | { | 2684 | { |
2686 | if (termios->c_line == N_PPS) { | 2685 | if (termios->c_line == N_PPS) { |
2687 | port->flags |= UPF_HARDPPS_CD; | 2686 | port->flags |= UPF_HARDPPS_CD; |
2688 | spin_lock_irq(&port->lock); | 2687 | spin_lock_irq(&port->lock); |
2689 | serial8250_enable_ms(port); | 2688 | serial8250_enable_ms(port); |
2690 | spin_unlock_irq(&port->lock); | 2689 | spin_unlock_irq(&port->lock); |
2691 | } else { | 2690 | } else { |
2692 | port->flags &= ~UPF_HARDPPS_CD; | 2691 | port->flags &= ~UPF_HARDPPS_CD; |
2693 | if (!UART_ENABLE_MS(port, termios->c_cflag)) { | 2692 | if (!UART_ENABLE_MS(port, termios->c_cflag)) { |
2694 | spin_lock_irq(&port->lock); | 2693 | spin_lock_irq(&port->lock); |
2695 | serial8250_disable_ms(port); | 2694 | serial8250_disable_ms(port); |
2696 | spin_unlock_irq(&port->lock); | 2695 | spin_unlock_irq(&port->lock); |
2697 | } | 2696 | } |
2698 | } | 2697 | } |
2699 | } | 2698 | } |
2700 | 2699 | ||
2701 | 2700 | ||
2702 | void serial8250_do_pm(struct uart_port *port, unsigned int state, | 2701 | void serial8250_do_pm(struct uart_port *port, unsigned int state, |
2703 | unsigned int oldstate) | 2702 | unsigned int oldstate) |
2704 | { | 2703 | { |
2705 | struct uart_8250_port *p = up_to_u8250p(port); | 2704 | struct uart_8250_port *p = up_to_u8250p(port); |
2706 | 2705 | ||
2707 | serial8250_set_sleep(p, state != 0); | 2706 | serial8250_set_sleep(p, state != 0); |
2708 | } | 2707 | } |
2709 | EXPORT_SYMBOL(serial8250_do_pm); | 2708 | EXPORT_SYMBOL(serial8250_do_pm); |
2710 | 2709 | ||
2711 | static void | 2710 | static void |
2712 | serial8250_pm(struct uart_port *port, unsigned int state, | 2711 | serial8250_pm(struct uart_port *port, unsigned int state, |
2713 | unsigned int oldstate) | 2712 | unsigned int oldstate) |
2714 | { | 2713 | { |
2715 | if (port->pm) | 2714 | if (port->pm) |
2716 | port->pm(port, state, oldstate); | 2715 | port->pm(port, state, oldstate); |
2717 | else | 2716 | else |
2718 | serial8250_do_pm(port, state, oldstate); | 2717 | serial8250_do_pm(port, state, oldstate); |
2719 | } | 2718 | } |
2720 | 2719 | ||
2721 | static unsigned int serial8250_port_size(struct uart_8250_port *pt) | 2720 | static unsigned int serial8250_port_size(struct uart_8250_port *pt) |
2722 | { | 2721 | { |
2723 | if (pt->port.iotype == UPIO_AU) { | 2722 | if (pt->port.iotype == UPIO_AU) { |
2724 | if (pt->port.type == PORT_RT2880) | 2723 | if (pt->port.type == PORT_RT2880) |
2725 | return 0x100; | 2724 | return 0x100; |
2726 | return 0x1000; | 2725 | return 0x1000; |
2727 | } | 2726 | } |
2728 | if (is_omap1_8250(pt)) | 2727 | if (is_omap1_8250(pt)) |
2729 | return 0x16 << pt->port.regshift; | 2728 | return 0x16 << pt->port.regshift; |
2730 | 2729 | ||
2731 | return 8 << pt->port.regshift; | 2730 | return 8 << pt->port.regshift; |
2732 | } | 2731 | } |
2733 | 2732 | ||
2734 | /* | 2733 | /* |
2735 | * Resource handling. | 2734 | * Resource handling. |
2736 | */ | 2735 | */ |
2737 | static int serial8250_request_std_resource(struct uart_8250_port *up) | 2736 | static int serial8250_request_std_resource(struct uart_8250_port *up) |
2738 | { | 2737 | { |
2739 | unsigned int size = serial8250_port_size(up); | 2738 | unsigned int size = serial8250_port_size(up); |
2740 | struct uart_port *port = &up->port; | 2739 | struct uart_port *port = &up->port; |
2741 | int ret = 0; | 2740 | int ret = 0; |
2742 | 2741 | ||
2743 | switch (port->iotype) { | 2742 | switch (port->iotype) { |
2744 | case UPIO_AU: | 2743 | case UPIO_AU: |
2745 | case UPIO_TSI: | 2744 | case UPIO_TSI: |
2746 | case UPIO_MEM32: | 2745 | case UPIO_MEM32: |
2747 | case UPIO_MEM: | 2746 | case UPIO_MEM: |
2748 | if (!port->mapbase) | 2747 | if (!port->mapbase) |
2749 | break; | 2748 | break; |
2750 | 2749 | ||
2751 | if (!request_mem_region(port->mapbase, size, "serial")) { | 2750 | if (!request_mem_region(port->mapbase, size, "serial")) { |
2752 | ret = -EBUSY; | 2751 | ret = -EBUSY; |
2753 | break; | 2752 | break; |
2754 | } | 2753 | } |
2755 | 2754 | ||
2756 | if (port->flags & UPF_IOREMAP) { | 2755 | if (port->flags & UPF_IOREMAP) { |
2757 | port->membase = ioremap_nocache(port->mapbase, size); | 2756 | port->membase = ioremap_nocache(port->mapbase, size); |
2758 | if (!port->membase) { | 2757 | if (!port->membase) { |
2759 | release_mem_region(port->mapbase, size); | 2758 | release_mem_region(port->mapbase, size); |
2760 | ret = -ENOMEM; | 2759 | ret = -ENOMEM; |
2761 | } | 2760 | } |
2762 | } | 2761 | } |
2763 | break; | 2762 | break; |
2764 | 2763 | ||
2765 | case UPIO_HUB6: | 2764 | case UPIO_HUB6: |
2766 | case UPIO_PORT: | 2765 | case UPIO_PORT: |
2767 | if (!request_region(port->iobase, size, "serial")) | 2766 | if (!request_region(port->iobase, size, "serial")) |
2768 | ret = -EBUSY; | 2767 | ret = -EBUSY; |
2769 | break; | 2768 | break; |
2770 | } | 2769 | } |
2771 | return ret; | 2770 | return ret; |
2772 | } | 2771 | } |
2773 | 2772 | ||
2774 | static void serial8250_release_std_resource(struct uart_8250_port *up) | 2773 | static void serial8250_release_std_resource(struct uart_8250_port *up) |
2775 | { | 2774 | { |
2776 | unsigned int size = serial8250_port_size(up); | 2775 | unsigned int size = serial8250_port_size(up); |
2777 | struct uart_port *port = &up->port; | 2776 | struct uart_port *port = &up->port; |
2778 | 2777 | ||
2779 | switch (port->iotype) { | 2778 | switch (port->iotype) { |
2780 | case UPIO_AU: | 2779 | case UPIO_AU: |
2781 | case UPIO_TSI: | 2780 | case UPIO_TSI: |
2782 | case UPIO_MEM32: | 2781 | case UPIO_MEM32: |
2783 | case UPIO_MEM: | 2782 | case UPIO_MEM: |
2784 | if (!port->mapbase) | 2783 | if (!port->mapbase) |
2785 | break; | 2784 | break; |
2786 | 2785 | ||
2787 | if (port->flags & UPF_IOREMAP) { | 2786 | if (port->flags & UPF_IOREMAP) { |
2788 | iounmap(port->membase); | 2787 | iounmap(port->membase); |
2789 | port->membase = NULL; | 2788 | port->membase = NULL; |
2790 | } | 2789 | } |
2791 | 2790 | ||
2792 | release_mem_region(port->mapbase, size); | 2791 | release_mem_region(port->mapbase, size); |
2793 | break; | 2792 | break; |
2794 | 2793 | ||
2795 | case UPIO_HUB6: | 2794 | case UPIO_HUB6: |
2796 | case UPIO_PORT: | 2795 | case UPIO_PORT: |
2797 | release_region(port->iobase, size); | 2796 | release_region(port->iobase, size); |
2798 | break; | 2797 | break; |
2799 | } | 2798 | } |
2800 | } | 2799 | } |
2801 | 2800 | ||
2802 | static int serial8250_request_rsa_resource(struct uart_8250_port *up) | 2801 | static int serial8250_request_rsa_resource(struct uart_8250_port *up) |
2803 | { | 2802 | { |
2804 | unsigned long start = UART_RSA_BASE << up->port.regshift; | 2803 | unsigned long start = UART_RSA_BASE << up->port.regshift; |
2805 | unsigned int size = 8 << up->port.regshift; | 2804 | unsigned int size = 8 << up->port.regshift; |
2806 | struct uart_port *port = &up->port; | 2805 | struct uart_port *port = &up->port; |
2807 | int ret = -EINVAL; | 2806 | int ret = -EINVAL; |
2808 | 2807 | ||
2809 | switch (port->iotype) { | 2808 | switch (port->iotype) { |
2810 | case UPIO_HUB6: | 2809 | case UPIO_HUB6: |
2811 | case UPIO_PORT: | 2810 | case UPIO_PORT: |
2812 | start += port->iobase; | 2811 | start += port->iobase; |
2813 | if (request_region(start, size, "serial-rsa")) | 2812 | if (request_region(start, size, "serial-rsa")) |
2814 | ret = 0; | 2813 | ret = 0; |
2815 | else | 2814 | else |
2816 | ret = -EBUSY; | 2815 | ret = -EBUSY; |
2817 | break; | 2816 | break; |
2818 | } | 2817 | } |
2819 | 2818 | ||
2820 | return ret; | 2819 | return ret; |
2821 | } | 2820 | } |
2822 | 2821 | ||
2823 | static void serial8250_release_rsa_resource(struct uart_8250_port *up) | 2822 | static void serial8250_release_rsa_resource(struct uart_8250_port *up) |
2824 | { | 2823 | { |
2825 | unsigned long offset = UART_RSA_BASE << up->port.regshift; | 2824 | unsigned long offset = UART_RSA_BASE << up->port.regshift; |
2826 | unsigned int size = 8 << up->port.regshift; | 2825 | unsigned int size = 8 << up->port.regshift; |
2827 | struct uart_port *port = &up->port; | 2826 | struct uart_port *port = &up->port; |
2828 | 2827 | ||
2829 | switch (port->iotype) { | 2828 | switch (port->iotype) { |
2830 | case UPIO_HUB6: | 2829 | case UPIO_HUB6: |
2831 | case UPIO_PORT: | 2830 | case UPIO_PORT: |
2832 | release_region(port->iobase + offset, size); | 2831 | release_region(port->iobase + offset, size); |
2833 | break; | 2832 | break; |
2834 | } | 2833 | } |
2835 | } | 2834 | } |
2836 | 2835 | ||
2837 | static void serial8250_release_port(struct uart_port *port) | 2836 | static void serial8250_release_port(struct uart_port *port) |
2838 | { | 2837 | { |
2839 | struct uart_8250_port *up = up_to_u8250p(port); | 2838 | struct uart_8250_port *up = up_to_u8250p(port); |
2840 | 2839 | ||
2841 | serial8250_release_std_resource(up); | 2840 | serial8250_release_std_resource(up); |
2842 | if (port->type == PORT_RSA) | 2841 | if (port->type == PORT_RSA) |
2843 | serial8250_release_rsa_resource(up); | 2842 | serial8250_release_rsa_resource(up); |
2844 | } | 2843 | } |
2845 | 2844 | ||
2846 | static int serial8250_request_port(struct uart_port *port) | 2845 | static int serial8250_request_port(struct uart_port *port) |
2847 | { | 2846 | { |
2848 | struct uart_8250_port *up = up_to_u8250p(port); | 2847 | struct uart_8250_port *up = up_to_u8250p(port); |
2849 | int ret; | 2848 | int ret; |
2850 | 2849 | ||
2851 | if (port->type == PORT_8250_CIR) | 2850 | if (port->type == PORT_8250_CIR) |
2852 | return -ENODEV; | 2851 | return -ENODEV; |
2853 | 2852 | ||
2854 | ret = serial8250_request_std_resource(up); | 2853 | ret = serial8250_request_std_resource(up); |
2855 | if (ret == 0 && port->type == PORT_RSA) { | 2854 | if (ret == 0 && port->type == PORT_RSA) { |
2856 | ret = serial8250_request_rsa_resource(up); | 2855 | ret = serial8250_request_rsa_resource(up); |
2857 | if (ret < 0) | 2856 | if (ret < 0) |
2858 | serial8250_release_std_resource(up); | 2857 | serial8250_release_std_resource(up); |
2859 | } | 2858 | } |
2860 | 2859 | ||
2861 | return ret; | 2860 | return ret; |
2862 | } | 2861 | } |
2863 | 2862 | ||
2864 | static int fcr_get_rxtrig_bytes(struct uart_8250_port *up) | 2863 | static int fcr_get_rxtrig_bytes(struct uart_8250_port *up) |
2865 | { | 2864 | { |
2866 | const struct serial8250_config *conf_type = &uart_config[up->port.type]; | 2865 | const struct serial8250_config *conf_type = &uart_config[up->port.type]; |
2867 | unsigned char bytes; | 2866 | unsigned char bytes; |
2868 | 2867 | ||
2869 | bytes = conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)]; | 2868 | bytes = conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)]; |
2870 | 2869 | ||
2871 | return bytes ? bytes : -EOPNOTSUPP; | 2870 | return bytes ? bytes : -EOPNOTSUPP; |
2872 | } | 2871 | } |
2873 | 2872 | ||
2874 | static int bytes_to_fcr_rxtrig(struct uart_8250_port *up, unsigned char bytes) | 2873 | static int bytes_to_fcr_rxtrig(struct uart_8250_port *up, unsigned char bytes) |
2875 | { | 2874 | { |
2876 | const struct serial8250_config *conf_type = &uart_config[up->port.type]; | 2875 | const struct serial8250_config *conf_type = &uart_config[up->port.type]; |
2877 | int i; | 2876 | int i; |
2878 | 2877 | ||
2879 | if (!conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)]) | 2878 | if (!conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)]) |
2880 | return -EOPNOTSUPP; | 2879 | return -EOPNOTSUPP; |
2881 | 2880 | ||
2882 | for (i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) { | 2881 | for (i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) { |
2883 | if (bytes < conf_type->rxtrig_bytes[i]) | 2882 | if (bytes < conf_type->rxtrig_bytes[i]) |
2884 | /* Use the nearest lower value */ | 2883 | /* Use the nearest lower value */ |
2885 | return (--i) << UART_FCR_R_TRIG_SHIFT; | 2884 | return (--i) << UART_FCR_R_TRIG_SHIFT; |
2886 | } | 2885 | } |
2887 | 2886 | ||
2888 | return UART_FCR_R_TRIG_11; | 2887 | return UART_FCR_R_TRIG_11; |
2889 | } | 2888 | } |
2890 | 2889 | ||
2891 | static int do_get_rxtrig(struct tty_port *port) | 2890 | static int do_get_rxtrig(struct tty_port *port) |
2892 | { | 2891 | { |
2893 | struct uart_state *state = container_of(port, struct uart_state, port); | 2892 | struct uart_state *state = container_of(port, struct uart_state, port); |
2894 | struct uart_port *uport = state->uart_port; | 2893 | struct uart_port *uport = state->uart_port; |
2895 | struct uart_8250_port *up = | 2894 | struct uart_8250_port *up = |
2896 | container_of(uport, struct uart_8250_port, port); | 2895 | container_of(uport, struct uart_8250_port, port); |
2897 | 2896 | ||
2898 | if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) | 2897 | if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) |
2899 | return -EINVAL; | 2898 | return -EINVAL; |
2900 | 2899 | ||
2901 | return fcr_get_rxtrig_bytes(up); | 2900 | return fcr_get_rxtrig_bytes(up); |
2902 | } | 2901 | } |
2903 | 2902 | ||
2904 | static int do_serial8250_get_rxtrig(struct tty_port *port) | 2903 | static int do_serial8250_get_rxtrig(struct tty_port *port) |
2905 | { | 2904 | { |
2906 | int rxtrig_bytes; | 2905 | int rxtrig_bytes; |
2907 | 2906 | ||
2908 | mutex_lock(&port->mutex); | 2907 | mutex_lock(&port->mutex); |
2909 | rxtrig_bytes = do_get_rxtrig(port); | 2908 | rxtrig_bytes = do_get_rxtrig(port); |
2910 | mutex_unlock(&port->mutex); | 2909 | mutex_unlock(&port->mutex); |
2911 | 2910 | ||
2912 | return rxtrig_bytes; | 2911 | return rxtrig_bytes; |
2913 | } | 2912 | } |
2914 | 2913 | ||
2915 | static ssize_t serial8250_get_attr_rx_trig_bytes(struct device *dev, | 2914 | static ssize_t serial8250_get_attr_rx_trig_bytes(struct device *dev, |
2916 | struct device_attribute *attr, char *buf) | 2915 | struct device_attribute *attr, char *buf) |
2917 | { | 2916 | { |
2918 | struct tty_port *port = dev_get_drvdata(dev); | 2917 | struct tty_port *port = dev_get_drvdata(dev); |
2919 | int rxtrig_bytes; | 2918 | int rxtrig_bytes; |
2920 | 2919 | ||
2921 | rxtrig_bytes = do_serial8250_get_rxtrig(port); | 2920 | rxtrig_bytes = do_serial8250_get_rxtrig(port); |
2922 | if (rxtrig_bytes < 0) | 2921 | if (rxtrig_bytes < 0) |
2923 | return rxtrig_bytes; | 2922 | return rxtrig_bytes; |
2924 | 2923 | ||
2925 | return snprintf(buf, PAGE_SIZE, "%d\n", rxtrig_bytes); | 2924 | return snprintf(buf, PAGE_SIZE, "%d\n", rxtrig_bytes); |
2926 | } | 2925 | } |
2927 | 2926 | ||
2928 | static int do_set_rxtrig(struct tty_port *port, unsigned char bytes) | 2927 | static int do_set_rxtrig(struct tty_port *port, unsigned char bytes) |
2929 | { | 2928 | { |
2930 | struct uart_state *state = container_of(port, struct uart_state, port); | 2929 | struct uart_state *state = container_of(port, struct uart_state, port); |
2931 | struct uart_port *uport = state->uart_port; | 2930 | struct uart_port *uport = state->uart_port; |
2932 | struct uart_8250_port *up = | 2931 | struct uart_8250_port *up = |
2933 | container_of(uport, struct uart_8250_port, port); | 2932 | container_of(uport, struct uart_8250_port, port); |
2934 | int rxtrig; | 2933 | int rxtrig; |
2935 | 2934 | ||
2936 | if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 || | 2935 | if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 || |
2937 | up->fifo_bug) | 2936 | up->fifo_bug) |
2938 | return -EINVAL; | 2937 | return -EINVAL; |
2939 | 2938 | ||
2940 | rxtrig = bytes_to_fcr_rxtrig(up, bytes); | 2939 | rxtrig = bytes_to_fcr_rxtrig(up, bytes); |
2941 | if (rxtrig < 0) | 2940 | if (rxtrig < 0) |
2942 | return rxtrig; | 2941 | return rxtrig; |
2943 | 2942 | ||
2944 | serial8250_clear_fifos(up); | 2943 | serial8250_clear_fifos(up); |
2945 | up->fcr &= ~UART_FCR_TRIGGER_MASK; | 2944 | up->fcr &= ~UART_FCR_TRIGGER_MASK; |
2946 | up->fcr |= (unsigned char)rxtrig; | 2945 | up->fcr |= (unsigned char)rxtrig; |
2947 | serial_out(up, UART_FCR, up->fcr); | 2946 | serial_out(up, UART_FCR, up->fcr); |
2948 | return 0; | 2947 | return 0; |
2949 | } | 2948 | } |
2950 | 2949 | ||
2951 | static int do_serial8250_set_rxtrig(struct tty_port *port, unsigned char bytes) | 2950 | static int do_serial8250_set_rxtrig(struct tty_port *port, unsigned char bytes) |
2952 | { | 2951 | { |
2953 | int ret; | 2952 | int ret; |
2954 | 2953 | ||
2955 | mutex_lock(&port->mutex); | 2954 | mutex_lock(&port->mutex); |
2956 | ret = do_set_rxtrig(port, bytes); | 2955 | ret = do_set_rxtrig(port, bytes); |
2957 | mutex_unlock(&port->mutex); | 2956 | mutex_unlock(&port->mutex); |
2958 | 2957 | ||
2959 | return ret; | 2958 | return ret; |
2960 | } | 2959 | } |
2961 | 2960 | ||
2962 | static ssize_t serial8250_set_attr_rx_trig_bytes(struct device *dev, | 2961 | static ssize_t serial8250_set_attr_rx_trig_bytes(struct device *dev, |
2963 | struct device_attribute *attr, const char *buf, size_t count) | 2962 | struct device_attribute *attr, const char *buf, size_t count) |
2964 | { | 2963 | { |
2965 | struct tty_port *port = dev_get_drvdata(dev); | 2964 | struct tty_port *port = dev_get_drvdata(dev); |
2966 | unsigned char bytes; | 2965 | unsigned char bytes; |
2967 | int ret; | 2966 | int ret; |
2968 | 2967 | ||
2969 | if (!count) | 2968 | if (!count) |
2970 | return -EINVAL; | 2969 | return -EINVAL; |
2971 | 2970 | ||
2972 | ret = kstrtou8(buf, 10, &bytes); | 2971 | ret = kstrtou8(buf, 10, &bytes); |
2973 | if (ret < 0) | 2972 | if (ret < 0) |
2974 | return ret; | 2973 | return ret; |
2975 | 2974 | ||
2976 | ret = do_serial8250_set_rxtrig(port, bytes); | 2975 | ret = do_serial8250_set_rxtrig(port, bytes); |
2977 | if (ret < 0) | 2976 | if (ret < 0) |
2978 | return ret; | 2977 | return ret; |
2979 | 2978 | ||
2980 | return count; | 2979 | return count; |
2981 | } | 2980 | } |
2982 | 2981 | ||
2983 | static DEVICE_ATTR(rx_trig_bytes, S_IRUSR | S_IWUSR | S_IRGRP, | 2982 | static DEVICE_ATTR(rx_trig_bytes, S_IRUSR | S_IWUSR | S_IRGRP, |
2984 | serial8250_get_attr_rx_trig_bytes, | 2983 | serial8250_get_attr_rx_trig_bytes, |
2985 | serial8250_set_attr_rx_trig_bytes); | 2984 | serial8250_set_attr_rx_trig_bytes); |
2986 | 2985 | ||
2987 | static struct attribute *serial8250_dev_attrs[] = { | 2986 | static struct attribute *serial8250_dev_attrs[] = { |
2988 | &dev_attr_rx_trig_bytes.attr, | 2987 | &dev_attr_rx_trig_bytes.attr, |
2989 | NULL, | 2988 | NULL, |
2990 | }; | 2989 | }; |
2991 | 2990 | ||
2992 | static struct attribute_group serial8250_dev_attr_group = { | 2991 | static struct attribute_group serial8250_dev_attr_group = { |
2993 | .attrs = serial8250_dev_attrs, | 2992 | .attrs = serial8250_dev_attrs, |
2994 | }; | 2993 | }; |
2995 | 2994 | ||
2996 | static void register_dev_spec_attr_grp(struct uart_8250_port *up) | 2995 | static void register_dev_spec_attr_grp(struct uart_8250_port *up) |
2997 | { | 2996 | { |
2998 | const struct serial8250_config *conf_type = &uart_config[up->port.type]; | 2997 | const struct serial8250_config *conf_type = &uart_config[up->port.type]; |
2999 | 2998 | ||
3000 | if (conf_type->rxtrig_bytes[0]) | 2999 | if (conf_type->rxtrig_bytes[0]) |
3001 | up->port.attr_group = &serial8250_dev_attr_group; | 3000 | up->port.attr_group = &serial8250_dev_attr_group; |
3002 | } | 3001 | } |
3003 | 3002 | ||
3004 | static void serial8250_config_port(struct uart_port *port, int flags) | 3003 | static void serial8250_config_port(struct uart_port *port, int flags) |
3005 | { | 3004 | { |
3006 | struct uart_8250_port *up = up_to_u8250p(port); | 3005 | struct uart_8250_port *up = up_to_u8250p(port); |
3007 | int probeflags = PROBE_ANY; | 3006 | int probeflags = PROBE_ANY; |
3008 | int ret; | 3007 | int ret; |
3009 | 3008 | ||
3010 | if (port->type == PORT_8250_CIR) | 3009 | if (port->type == PORT_8250_CIR) |
3011 | return; | 3010 | return; |
3012 | 3011 | ||
3013 | /* | 3012 | /* |
3014 | * Find the region that we can probe for. This in turn | 3013 | * Find the region that we can probe for. This in turn |
3015 | * tells us whether we can probe for the type of port. | 3014 | * tells us whether we can probe for the type of port. |
3016 | */ | 3015 | */ |
3017 | ret = serial8250_request_std_resource(up); | 3016 | ret = serial8250_request_std_resource(up); |
3018 | if (ret < 0) | 3017 | if (ret < 0) |
3019 | return; | 3018 | return; |
3020 | 3019 | ||
3021 | ret = serial8250_request_rsa_resource(up); | 3020 | ret = serial8250_request_rsa_resource(up); |
3022 | if (ret < 0) | 3021 | if (ret < 0) |
3023 | probeflags &= ~PROBE_RSA; | 3022 | probeflags &= ~PROBE_RSA; |
3024 | 3023 | ||
3025 | if (port->iotype != up->cur_iotype) | 3024 | if (port->iotype != up->cur_iotype) |
3026 | set_io_from_upio(port); | 3025 | set_io_from_upio(port); |
3027 | 3026 | ||
3028 | if (flags & UART_CONFIG_TYPE) | 3027 | if (flags & UART_CONFIG_TYPE) |
3029 | autoconfig(up, probeflags); | 3028 | autoconfig(up, probeflags); |
3030 | 3029 | ||
3031 | /* if access method is AU, it is a 16550 with a quirk */ | 3030 | /* if access method is AU, it is a 16550 with a quirk */ |
3032 | if (port->type == PORT_16550A && port->iotype == UPIO_AU) | 3031 | if (port->type == PORT_16550A && port->iotype == UPIO_AU) |
3033 | up->bugs |= UART_BUG_NOMSR; | 3032 | up->bugs |= UART_BUG_NOMSR; |
3034 | 3033 | ||
3035 | /* HW bugs may trigger IRQ while IIR == NO_INT */ | 3034 | /* HW bugs may trigger IRQ while IIR == NO_INT */ |
3036 | if (port->type == PORT_TEGRA) | 3035 | if (port->type == PORT_TEGRA) |
3037 | up->bugs |= UART_BUG_NOMSR; | 3036 | up->bugs |= UART_BUG_NOMSR; |
3038 | 3037 | ||
3039 | if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) | 3038 | if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) |
3040 | autoconfig_irq(up); | 3039 | autoconfig_irq(up); |
3041 | 3040 | ||
3042 | if (port->type != PORT_RSA && probeflags & PROBE_RSA) | 3041 | if (port->type != PORT_RSA && probeflags & PROBE_RSA) |
3043 | serial8250_release_rsa_resource(up); | 3042 | serial8250_release_rsa_resource(up); |
3044 | if (port->type == PORT_UNKNOWN) | 3043 | if (port->type == PORT_UNKNOWN) |
3045 | serial8250_release_std_resource(up); | 3044 | serial8250_release_std_resource(up); |
3046 | 3045 | ||
3047 | /* Fixme: probably not the best place for this */ | 3046 | /* Fixme: probably not the best place for this */ |
3048 | if ((port->type == PORT_XR17V35X) || | 3047 | if ((port->type == PORT_XR17V35X) || |
3049 | (port->type == PORT_XR17D15X)) | 3048 | (port->type == PORT_XR17D15X)) |
3050 | port->handle_irq = exar_handle_irq; | 3049 | port->handle_irq = exar_handle_irq; |
3051 | 3050 | ||
3052 | register_dev_spec_attr_grp(up); | 3051 | register_dev_spec_attr_grp(up); |
3053 | up->fcr = uart_config[up->port.type].fcr; | 3052 | up->fcr = uart_config[up->port.type].fcr; |
3054 | } | 3053 | } |
3055 | 3054 | ||
3056 | static int | 3055 | static int |
3057 | serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) | 3056 | serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) |
3058 | { | 3057 | { |
3059 | if (ser->irq >= nr_irqs || ser->irq < 0 || | 3058 | if (ser->irq >= nr_irqs || ser->irq < 0 || |
3060 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || | 3059 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || |
3061 | ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || | 3060 | ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || |
3062 | ser->type == PORT_STARTECH) | 3061 | ser->type == PORT_STARTECH) |
3063 | return -EINVAL; | 3062 | return -EINVAL; |
3064 | return 0; | 3063 | return 0; |
3065 | } | 3064 | } |
3066 | 3065 | ||
3067 | static const char * | 3066 | static const char * |
3068 | serial8250_type(struct uart_port *port) | 3067 | serial8250_type(struct uart_port *port) |
3069 | { | 3068 | { |
3070 | int type = port->type; | 3069 | int type = port->type; |
3071 | 3070 | ||
3072 | if (type >= ARRAY_SIZE(uart_config)) | 3071 | if (type >= ARRAY_SIZE(uart_config)) |
3073 | type = 0; | 3072 | type = 0; |
3074 | return uart_config[type].name; | 3073 | return uart_config[type].name; |
3075 | } | 3074 | } |
3076 | 3075 | ||
3077 | static struct uart_ops serial8250_pops = { | 3076 | static struct uart_ops serial8250_pops = { |
3078 | .tx_empty = serial8250_tx_empty, | 3077 | .tx_empty = serial8250_tx_empty, |
3079 | .set_mctrl = serial8250_set_mctrl, | 3078 | .set_mctrl = serial8250_set_mctrl, |
3080 | .get_mctrl = serial8250_get_mctrl, | 3079 | .get_mctrl = serial8250_get_mctrl, |
3081 | .stop_tx = serial8250_stop_tx, | 3080 | .stop_tx = serial8250_stop_tx, |
3082 | .start_tx = serial8250_start_tx, | 3081 | .start_tx = serial8250_start_tx, |
3083 | .throttle = serial8250_throttle, | 3082 | .throttle = serial8250_throttle, |
3084 | .unthrottle = serial8250_unthrottle, | 3083 | .unthrottle = serial8250_unthrottle, |
3085 | .stop_rx = serial8250_stop_rx, | 3084 | .stop_rx = serial8250_stop_rx, |
3086 | .enable_ms = serial8250_enable_ms, | 3085 | .enable_ms = serial8250_enable_ms, |
3087 | .break_ctl = serial8250_break_ctl, | 3086 | .break_ctl = serial8250_break_ctl, |
3088 | .startup = serial8250_startup, | 3087 | .startup = serial8250_startup, |
3089 | .shutdown = serial8250_shutdown, | 3088 | .shutdown = serial8250_shutdown, |
3090 | .set_termios = serial8250_set_termios, | 3089 | .set_termios = serial8250_set_termios, |
3091 | .set_ldisc = serial8250_set_ldisc, | 3090 | .set_ldisc = serial8250_set_ldisc, |
3092 | .pm = serial8250_pm, | 3091 | .pm = serial8250_pm, |
3093 | .type = serial8250_type, | 3092 | .type = serial8250_type, |
3094 | .release_port = serial8250_release_port, | 3093 | .release_port = serial8250_release_port, |
3095 | .request_port = serial8250_request_port, | 3094 | .request_port = serial8250_request_port, |
3096 | .config_port = serial8250_config_port, | 3095 | .config_port = serial8250_config_port, |
3097 | .verify_port = serial8250_verify_port, | 3096 | .verify_port = serial8250_verify_port, |
3098 | #ifdef CONFIG_CONSOLE_POLL | 3097 | #ifdef CONFIG_CONSOLE_POLL |
3099 | .poll_get_char = serial8250_get_poll_char, | 3098 | .poll_get_char = serial8250_get_poll_char, |
3100 | .poll_put_char = serial8250_put_poll_char, | 3099 | .poll_put_char = serial8250_put_poll_char, |
3101 | #endif | 3100 | #endif |
3102 | }; | 3101 | }; |
3103 | 3102 | ||
3104 | static struct uart_8250_port serial8250_ports[UART_NR]; | 3103 | static struct uart_8250_port serial8250_ports[UART_NR]; |
3105 | 3104 | ||
3106 | /** | 3105 | /** |
3107 | * serial8250_get_port - retrieve struct uart_8250_port | 3106 | * serial8250_get_port - retrieve struct uart_8250_port |
3108 | * @line: serial line number | 3107 | * @line: serial line number |
3109 | * | 3108 | * |
3110 | * This function retrieves struct uart_8250_port for the specific line. | 3109 | * This function retrieves struct uart_8250_port for the specific line. |
3111 | * This struct *must* *not* be used to perform a 8250 or serial core operation | 3110 | * This struct *must* *not* be used to perform a 8250 or serial core operation |
3112 | * which is not accessible otherwise. Its only purpose is to make the struct | 3111 | * which is not accessible otherwise. Its only purpose is to make the struct |
3113 | * accessible to the runtime-pm callbacks for context suspend/restore. | 3112 | * accessible to the runtime-pm callbacks for context suspend/restore. |
3114 | * The lock assumption made here is none because runtime-pm suspend/resume | 3113 | * The lock assumption made here is none because runtime-pm suspend/resume |
3115 | * callbacks should not be invoked if there is any operation performed on the | 3114 | * callbacks should not be invoked if there is any operation performed on the |
3116 | * port. | 3115 | * port. |
3117 | */ | 3116 | */ |
3118 | struct uart_8250_port *serial8250_get_port(int line) | 3117 | struct uart_8250_port *serial8250_get_port(int line) |
3119 | { | 3118 | { |
3120 | return &serial8250_ports[line]; | 3119 | return &serial8250_ports[line]; |
3121 | } | 3120 | } |
3122 | EXPORT_SYMBOL_GPL(serial8250_get_port); | 3121 | EXPORT_SYMBOL_GPL(serial8250_get_port); |
3123 | 3122 | ||
3124 | static void (*serial8250_isa_config)(int port, struct uart_port *up, | 3123 | static void (*serial8250_isa_config)(int port, struct uart_port *up, |
3125 | unsigned short *capabilities); | 3124 | unsigned short *capabilities); |
3126 | 3125 | ||
3127 | void serial8250_set_isa_configurator( | 3126 | void serial8250_set_isa_configurator( |
3128 | void (*v)(int port, struct uart_port *up, unsigned short *capabilities)) | 3127 | void (*v)(int port, struct uart_port *up, unsigned short *capabilities)) |
3129 | { | 3128 | { |
3130 | serial8250_isa_config = v; | 3129 | serial8250_isa_config = v; |
3131 | } | 3130 | } |
3132 | EXPORT_SYMBOL(serial8250_set_isa_configurator); | 3131 | EXPORT_SYMBOL(serial8250_set_isa_configurator); |
3133 | 3132 | ||
3134 | static void __init serial8250_isa_init_ports(void) | 3133 | static void __init serial8250_isa_init_ports(void) |
3135 | { | 3134 | { |
3136 | struct uart_8250_port *up; | 3135 | struct uart_8250_port *up; |
3137 | static int first = 1; | 3136 | static int first = 1; |
3138 | int i, irqflag = 0; | 3137 | int i, irqflag = 0; |
3139 | 3138 | ||
3140 | if (!first) | 3139 | if (!first) |
3141 | return; | 3140 | return; |
3142 | first = 0; | 3141 | first = 0; |
3143 | 3142 | ||
3144 | if (nr_uarts > UART_NR) | 3143 | if (nr_uarts > UART_NR) |
3145 | nr_uarts = UART_NR; | 3144 | nr_uarts = UART_NR; |
3146 | 3145 | ||
3147 | for (i = 0; i < nr_uarts; i++) { | 3146 | for (i = 0; i < nr_uarts; i++) { |
3148 | struct uart_8250_port *up = &serial8250_ports[i]; | 3147 | struct uart_8250_port *up = &serial8250_ports[i]; |
3149 | struct uart_port *port = &up->port; | 3148 | struct uart_port *port = &up->port; |
3150 | 3149 | ||
3151 | port->line = i; | 3150 | port->line = i; |
3152 | spin_lock_init(&port->lock); | 3151 | spin_lock_init(&port->lock); |
3153 | 3152 | ||
3154 | init_timer(&up->timer); | 3153 | init_timer(&up->timer); |
3155 | up->timer.function = serial8250_timeout; | 3154 | up->timer.function = serial8250_timeout; |
3156 | up->cur_iotype = 0xFF; | 3155 | up->cur_iotype = 0xFF; |
3157 | 3156 | ||
3158 | /* | 3157 | /* |
3159 | * ALPHA_KLUDGE_MCR needs to be killed. | 3158 | * ALPHA_KLUDGE_MCR needs to be killed. |
3160 | */ | 3159 | */ |
3161 | up->mcr_mask = ~ALPHA_KLUDGE_MCR; | 3160 | up->mcr_mask = ~ALPHA_KLUDGE_MCR; |
3162 | up->mcr_force = ALPHA_KLUDGE_MCR; | 3161 | up->mcr_force = ALPHA_KLUDGE_MCR; |
3163 | 3162 | ||
3164 | port->ops = &serial8250_pops; | 3163 | port->ops = &serial8250_pops; |
3165 | } | 3164 | } |
3166 | 3165 | ||
3167 | if (share_irqs) | 3166 | if (share_irqs) |
3168 | irqflag = IRQF_SHARED; | 3167 | irqflag = IRQF_SHARED; |
3169 | 3168 | ||
3170 | for (i = 0, up = serial8250_ports; | 3169 | for (i = 0, up = serial8250_ports; |
3171 | i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; | 3170 | i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; |
3172 | i++, up++) { | 3171 | i++, up++) { |
3173 | struct uart_port *port = &up->port; | 3172 | struct uart_port *port = &up->port; |
3174 | 3173 | ||
3175 | port->iobase = old_serial_port[i].port; | 3174 | port->iobase = old_serial_port[i].port; |
3176 | port->irq = irq_canonicalize(old_serial_port[i].irq); | 3175 | port->irq = irq_canonicalize(old_serial_port[i].irq); |
3177 | port->irqflags = old_serial_port[i].irqflags; | 3176 | port->irqflags = old_serial_port[i].irqflags; |
3178 | port->uartclk = old_serial_port[i].baud_base * 16; | 3177 | port->uartclk = old_serial_port[i].baud_base * 16; |
3179 | port->flags = old_serial_port[i].flags; | 3178 | port->flags = old_serial_port[i].flags; |
3180 | port->hub6 = old_serial_port[i].hub6; | 3179 | port->hub6 = old_serial_port[i].hub6; |
3181 | port->membase = old_serial_port[i].iomem_base; | 3180 | port->membase = old_serial_port[i].iomem_base; |
3182 | port->iotype = old_serial_port[i].io_type; | 3181 | port->iotype = old_serial_port[i].io_type; |
3183 | port->regshift = old_serial_port[i].iomem_reg_shift; | 3182 | port->regshift = old_serial_port[i].iomem_reg_shift; |
3184 | set_io_from_upio(port); | 3183 | set_io_from_upio(port); |
3185 | port->irqflags |= irqflag; | 3184 | port->irqflags |= irqflag; |
3186 | if (serial8250_isa_config != NULL) | 3185 | if (serial8250_isa_config != NULL) |
3187 | serial8250_isa_config(i, &up->port, &up->capabilities); | 3186 | serial8250_isa_config(i, &up->port, &up->capabilities); |
3188 | 3187 | ||
3189 | } | 3188 | } |
3190 | } | 3189 | } |
3191 | 3190 | ||
3192 | static void | 3191 | static void |
3193 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) | 3192 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) |
3194 | { | 3193 | { |
3195 | up->port.type = type; | 3194 | up->port.type = type; |
3196 | if (!up->port.fifosize) | 3195 | if (!up->port.fifosize) |
3197 | up->port.fifosize = uart_config[type].fifo_size; | 3196 | up->port.fifosize = uart_config[type].fifo_size; |
3198 | if (!up->tx_loadsz) | 3197 | if (!up->tx_loadsz) |
3199 | up->tx_loadsz = uart_config[type].tx_loadsz; | 3198 | up->tx_loadsz = uart_config[type].tx_loadsz; |
3200 | if (!up->capabilities) | 3199 | if (!up->capabilities) |
3201 | up->capabilities = uart_config[type].flags; | 3200 | up->capabilities = uart_config[type].flags; |
3202 | } | 3201 | } |
3203 | 3202 | ||
3204 | static void __init | 3203 | static void __init |
3205 | serial8250_register_ports(struct uart_driver *drv, struct device *dev) | 3204 | serial8250_register_ports(struct uart_driver *drv, struct device *dev) |
3206 | { | 3205 | { |
3207 | int i; | 3206 | int i; |
3208 | 3207 | ||
3209 | for (i = 0; i < nr_uarts; i++) { | 3208 | for (i = 0; i < nr_uarts; i++) { |
3210 | struct uart_8250_port *up = &serial8250_ports[i]; | 3209 | struct uart_8250_port *up = &serial8250_ports[i]; |
3211 | 3210 | ||
3212 | if (up->port.dev) | 3211 | if (up->port.dev) |
3213 | continue; | 3212 | continue; |
3214 | 3213 | ||
3215 | up->port.dev = dev; | 3214 | up->port.dev = dev; |
3216 | 3215 | ||
3217 | if (up->port.flags & UPF_FIXED_TYPE) | 3216 | if (up->port.flags & UPF_FIXED_TYPE) |
3218 | serial8250_init_fixed_type_port(up, up->port.type); | 3217 | serial8250_init_fixed_type_port(up, up->port.type); |
3219 | 3218 | ||
3220 | uart_add_one_port(drv, &up->port); | 3219 | uart_add_one_port(drv, &up->port); |
3221 | } | 3220 | } |
3222 | } | 3221 | } |
3223 | 3222 | ||
3224 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 3223 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
3225 | 3224 | ||
3226 | static void serial8250_console_putchar(struct uart_port *port, int ch) | 3225 | static void serial8250_console_putchar(struct uart_port *port, int ch) |
3227 | { | 3226 | { |
3228 | struct uart_8250_port *up = up_to_u8250p(port); | 3227 | struct uart_8250_port *up = up_to_u8250p(port); |
3229 | 3228 | ||
3230 | wait_for_xmitr(up, UART_LSR_THRE); | 3229 | wait_for_xmitr(up, UART_LSR_THRE); |
3231 | serial_port_out(port, UART_TX, ch); | 3230 | serial_port_out(port, UART_TX, ch); |
3232 | } | 3231 | } |
3233 | 3232 | ||
3234 | /* | 3233 | /* |
3235 | * Print a string to the serial port trying not to disturb | 3234 | * Print a string to the serial port trying not to disturb |
3236 | * any possible real use of the port... | 3235 | * any possible real use of the port... |
3237 | * | 3236 | * |
3238 | * The console_lock must be held when we get here. | 3237 | * The console_lock must be held when we get here. |
3239 | */ | 3238 | */ |
3240 | static void | 3239 | static void |
3241 | serial8250_console_write(struct console *co, const char *s, unsigned int count) | 3240 | serial8250_console_write(struct console *co, const char *s, unsigned int count) |
3242 | { | 3241 | { |
3243 | struct uart_8250_port *up = &serial8250_ports[co->index]; | 3242 | struct uart_8250_port *up = &serial8250_ports[co->index]; |
3244 | struct uart_port *port = &up->port; | 3243 | struct uart_port *port = &up->port; |
3245 | unsigned long flags; | 3244 | unsigned long flags; |
3246 | unsigned int ier; | 3245 | unsigned int ier; |
3247 | int locked = 1; | 3246 | int locked = 1; |
3248 | 3247 | ||
3249 | touch_nmi_watchdog(); | 3248 | touch_nmi_watchdog(); |
3250 | 3249 | ||
3251 | serial8250_rpm_get(up); | 3250 | serial8250_rpm_get(up); |
3252 | 3251 | ||
3253 | if (port->sysrq) | 3252 | if (port->sysrq) |
3254 | locked = 0; | 3253 | locked = 0; |
3255 | else if (oops_in_progress) | 3254 | else if (oops_in_progress) |
3256 | locked = spin_trylock_irqsave(&port->lock, flags); | 3255 | locked = spin_trylock_irqsave(&port->lock, flags); |
3257 | else | 3256 | else |
3258 | spin_lock_irqsave(&port->lock, flags); | 3257 | spin_lock_irqsave(&port->lock, flags); |
3259 | 3258 | ||
3260 | /* | 3259 | /* |
3261 | * First save the IER then disable the interrupts | 3260 | * First save the IER then disable the interrupts |
3262 | */ | 3261 | */ |
3263 | ier = serial_port_in(port, UART_IER); | 3262 | ier = serial_port_in(port, UART_IER); |
3264 | 3263 | ||
3265 | if (up->capabilities & UART_CAP_UUE) | 3264 | if (up->capabilities & UART_CAP_UUE) |
3266 | serial_port_out(port, UART_IER, UART_IER_UUE); | 3265 | serial_port_out(port, UART_IER, UART_IER_UUE); |
3267 | else | 3266 | else |
3268 | serial_port_out(port, UART_IER, 0); | 3267 | serial_port_out(port, UART_IER, 0); |
3269 | 3268 | ||
3270 | /* check scratch reg to see if port powered off during system sleep */ | 3269 | /* check scratch reg to see if port powered off during system sleep */ |
3271 | if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { | 3270 | if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { |
3272 | struct ktermios termios; | 3271 | struct ktermios termios; |
3273 | unsigned int baud, quot, frac = 0; | 3272 | unsigned int baud, quot, frac = 0; |
3274 | 3273 | ||
3275 | termios.c_cflag = port->cons->cflag; | 3274 | termios.c_cflag = port->cons->cflag; |
3276 | if (port->state->port.tty && termios.c_cflag == 0) | 3275 | if (port->state->port.tty && termios.c_cflag == 0) |
3277 | termios.c_cflag = port->state->port.tty->termios.c_cflag; | 3276 | termios.c_cflag = port->state->port.tty->termios.c_cflag; |
3278 | 3277 | ||
3279 | baud = uart_get_baud_rate(port, &termios, NULL, | 3278 | baud = uart_get_baud_rate(port, &termios, NULL, |
3280 | port->uartclk / 16 / 0xffff, | 3279 | port->uartclk / 16 / 0xffff, |
3281 | port->uartclk / 16); | 3280 | port->uartclk / 16); |
3282 | quot = serial8250_get_divisor(up, baud, &frac); | 3281 | quot = serial8250_get_divisor(up, baud, &frac); |
3283 | 3282 | ||
3284 | serial8250_set_divisor(port, baud, quot, frac); | 3283 | serial8250_set_divisor(port, baud, quot, frac); |
3285 | serial_port_out(port, UART_LCR, up->lcr); | 3284 | serial_port_out(port, UART_LCR, up->lcr); |
3286 | serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); | 3285 | serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); |
3287 | 3286 | ||
3288 | up->canary = 0; | 3287 | up->canary = 0; |
3289 | } | 3288 | } |
3290 | 3289 | ||
3291 | uart_console_write(port, s, count, serial8250_console_putchar); | 3290 | uart_console_write(port, s, count, serial8250_console_putchar); |
3292 | 3291 | ||
3293 | /* | 3292 | /* |
3294 | * Finally, wait for transmitter to become empty | 3293 | * Finally, wait for transmitter to become empty |
3295 | * and restore the IER | 3294 | * and restore the IER |
3296 | */ | 3295 | */ |
3297 | wait_for_xmitr(up, BOTH_EMPTY); | 3296 | wait_for_xmitr(up, BOTH_EMPTY); |
3298 | serial_port_out(port, UART_IER, ier); | 3297 | serial_port_out(port, UART_IER, ier); |
3299 | 3298 | ||
3300 | /* | 3299 | /* |
3301 | * The receive handling will happen properly because the | 3300 | * The receive handling will happen properly because the |
3302 | * receive ready bit will still be set; it is not cleared | 3301 | * receive ready bit will still be set; it is not cleared |
3303 | * on read. However, modem control will not, we must | 3302 | * on read. However, modem control will not, we must |
3304 | * call it if we have saved something in the saved flags | 3303 | * call it if we have saved something in the saved flags |
3305 | * while processing with interrupts off. | 3304 | * while processing with interrupts off. |
3306 | */ | 3305 | */ |
3307 | if (up->msr_saved_flags) | 3306 | if (up->msr_saved_flags) |
3308 | serial8250_modem_status(up); | 3307 | serial8250_modem_status(up); |
3309 | 3308 | ||
3310 | if (locked) | 3309 | if (locked) |
3311 | spin_unlock_irqrestore(&port->lock, flags); | 3310 | spin_unlock_irqrestore(&port->lock, flags); |
3312 | serial8250_rpm_put(up); | 3311 | serial8250_rpm_put(up); |
3313 | } | 3312 | } |
3314 | 3313 | ||
3315 | static int serial8250_console_setup(struct console *co, char *options) | 3314 | static int serial8250_console_setup(struct console *co, char *options) |
3316 | { | 3315 | { |
3317 | struct uart_port *port; | 3316 | struct uart_port *port; |
3318 | int baud = 9600; | 3317 | int baud = 9600; |
3319 | int bits = 8; | 3318 | int bits = 8; |
3320 | int parity = 'n'; | 3319 | int parity = 'n'; |
3321 | int flow = 'n'; | 3320 | int flow = 'n'; |
3322 | 3321 | ||
3323 | /* | 3322 | /* |
3324 | * Check whether an invalid uart number has been specified, and | 3323 | * Check whether an invalid uart number has been specified, and |
3325 | * if so, search for the first available port that does have | 3324 | * if so, search for the first available port that does have |
3326 | * console support. | 3325 | * console support. |
3327 | */ | 3326 | */ |
3328 | if (co->index >= nr_uarts) | 3327 | if (co->index >= nr_uarts) |
3329 | co->index = 0; | 3328 | co->index = 0; |
3330 | port = &serial8250_ports[co->index].port; | 3329 | port = &serial8250_ports[co->index].port; |
3331 | if (!port->iobase && !port->membase) | 3330 | if (!port->iobase && !port->membase) |
3332 | return -ENODEV; | 3331 | return -ENODEV; |
3333 | 3332 | ||
3334 | if (options) | 3333 | if (options) |
3335 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 3334 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
3336 | 3335 | ||
3337 | return uart_set_options(port, co, baud, parity, bits, flow); | 3336 | return uart_set_options(port, co, baud, parity, bits, flow); |
3338 | } | 3337 | } |
3339 | 3338 | ||
3340 | static int serial8250_console_early_setup(void) | 3339 | static int serial8250_console_early_setup(void) |
3341 | { | 3340 | { |
3342 | return serial8250_find_port_for_earlycon(); | 3341 | return serial8250_find_port_for_earlycon(); |
3343 | } | 3342 | } |
3344 | 3343 | ||
3345 | static struct console serial8250_console = { | 3344 | static struct console serial8250_console = { |
3346 | .name = "ttyS", | 3345 | .name = "ttyS", |
3347 | .write = serial8250_console_write, | 3346 | .write = serial8250_console_write, |
3348 | .device = uart_console_device, | 3347 | .device = uart_console_device, |
3349 | .setup = serial8250_console_setup, | 3348 | .setup = serial8250_console_setup, |
3350 | .early_setup = serial8250_console_early_setup, | 3349 | .early_setup = serial8250_console_early_setup, |
3351 | .flags = CON_PRINTBUFFER | CON_ANYTIME, | 3350 | .flags = CON_PRINTBUFFER | CON_ANYTIME, |
3352 | .index = -1, | 3351 | .index = -1, |
3353 | .data = &serial8250_reg, | 3352 | .data = &serial8250_reg, |
3354 | }; | 3353 | }; |
3355 | 3354 | ||
3356 | static int __init serial8250_console_init(void) | 3355 | static int __init serial8250_console_init(void) |
3357 | { | 3356 | { |
3358 | serial8250_isa_init_ports(); | 3357 | serial8250_isa_init_ports(); |
3359 | register_console(&serial8250_console); | 3358 | register_console(&serial8250_console); |
3360 | return 0; | 3359 | return 0; |
3361 | } | 3360 | } |
3362 | console_initcall(serial8250_console_init); | 3361 | console_initcall(serial8250_console_init); |
3363 | 3362 | ||
3364 | int serial8250_find_port(struct uart_port *p) | 3363 | int serial8250_find_port(struct uart_port *p) |
3365 | { | 3364 | { |
3366 | int line; | 3365 | int line; |
3367 | struct uart_port *port; | 3366 | struct uart_port *port; |
3368 | 3367 | ||
3369 | for (line = 0; line < nr_uarts; line++) { | 3368 | for (line = 0; line < nr_uarts; line++) { |
3370 | port = &serial8250_ports[line].port; | 3369 | port = &serial8250_ports[line].port; |
3371 | if (uart_match_port(p, port)) | 3370 | if (uart_match_port(p, port)) |
3372 | return line; | 3371 | return line; |
3373 | } | 3372 | } |
3374 | return -ENODEV; | 3373 | return -ENODEV; |
3375 | } | 3374 | } |
3376 | 3375 | ||
3377 | #define SERIAL8250_CONSOLE &serial8250_console | 3376 | #define SERIAL8250_CONSOLE &serial8250_console |
3378 | #else | 3377 | #else |
3379 | #define SERIAL8250_CONSOLE NULL | 3378 | #define SERIAL8250_CONSOLE NULL |
3380 | #endif | 3379 | #endif |
3381 | 3380 | ||
3382 | static struct uart_driver serial8250_reg = { | 3381 | static struct uart_driver serial8250_reg = { |
3383 | .owner = THIS_MODULE, | 3382 | .owner = THIS_MODULE, |
3384 | .driver_name = "serial", | 3383 | .driver_name = "serial", |
3385 | .dev_name = "ttyS", | 3384 | .dev_name = "ttyS", |
3386 | .major = TTY_MAJOR, | 3385 | .major = TTY_MAJOR, |
3387 | .minor = 64, | 3386 | .minor = 64, |
3388 | .cons = SERIAL8250_CONSOLE, | 3387 | .cons = SERIAL8250_CONSOLE, |
3389 | }; | 3388 | }; |
3390 | 3389 | ||
3391 | /* | 3390 | /* |
3392 | * early_serial_setup - early registration for 8250 ports | 3391 | * early_serial_setup - early registration for 8250 ports |
3393 | * | 3392 | * |
3394 | * Setup an 8250 port structure prior to console initialisation. Use | 3393 | * Setup an 8250 port structure prior to console initialisation. Use |
3395 | * after console initialisation will cause undefined behaviour. | 3394 | * after console initialisation will cause undefined behaviour. |
3396 | */ | 3395 | */ |
3397 | int __init early_serial_setup(struct uart_port *port) | 3396 | int __init early_serial_setup(struct uart_port *port) |
3398 | { | 3397 | { |
3399 | struct uart_port *p; | 3398 | struct uart_port *p; |
3400 | 3399 | ||
3401 | if (port->line >= ARRAY_SIZE(serial8250_ports)) | 3400 | if (port->line >= ARRAY_SIZE(serial8250_ports)) |
3402 | return -ENODEV; | 3401 | return -ENODEV; |
3403 | 3402 | ||
3404 | serial8250_isa_init_ports(); | 3403 | serial8250_isa_init_ports(); |
3405 | p = &serial8250_ports[port->line].port; | 3404 | p = &serial8250_ports[port->line].port; |
3406 | p->iobase = port->iobase; | 3405 | p->iobase = port->iobase; |
3407 | p->membase = port->membase; | 3406 | p->membase = port->membase; |
3408 | p->irq = port->irq; | 3407 | p->irq = port->irq; |
3409 | p->irqflags = port->irqflags; | 3408 | p->irqflags = port->irqflags; |
3410 | p->uartclk = port->uartclk; | 3409 | p->uartclk = port->uartclk; |
3411 | p->fifosize = port->fifosize; | 3410 | p->fifosize = port->fifosize; |
3412 | p->regshift = port->regshift; | 3411 | p->regshift = port->regshift; |
3413 | p->iotype = port->iotype; | 3412 | p->iotype = port->iotype; |
3414 | p->flags = port->flags; | 3413 | p->flags = port->flags; |
3415 | p->mapbase = port->mapbase; | 3414 | p->mapbase = port->mapbase; |
3416 | p->private_data = port->private_data; | 3415 | p->private_data = port->private_data; |
3417 | p->type = port->type; | 3416 | p->type = port->type; |
3418 | p->line = port->line; | 3417 | p->line = port->line; |
3419 | 3418 | ||
3420 | set_io_from_upio(p); | 3419 | set_io_from_upio(p); |
3421 | if (port->serial_in) | 3420 | if (port->serial_in) |
3422 | p->serial_in = port->serial_in; | 3421 | p->serial_in = port->serial_in; |
3423 | if (port->serial_out) | 3422 | if (port->serial_out) |
3424 | p->serial_out = port->serial_out; | 3423 | p->serial_out = port->serial_out; |
3425 | if (port->handle_irq) | 3424 | if (port->handle_irq) |
3426 | p->handle_irq = port->handle_irq; | 3425 | p->handle_irq = port->handle_irq; |
3427 | else | 3426 | else |
3428 | p->handle_irq = serial8250_default_handle_irq; | 3427 | p->handle_irq = serial8250_default_handle_irq; |
3429 | 3428 | ||
3430 | return 0; | 3429 | return 0; |
3431 | } | 3430 | } |
3432 | 3431 | ||
3433 | /** | 3432 | /** |
3434 | * serial8250_suspend_port - suspend one serial port | 3433 | * serial8250_suspend_port - suspend one serial port |
3435 | * @line: serial line number | 3434 | * @line: serial line number |
3436 | * | 3435 | * |
3437 | * Suspend one serial port. | 3436 | * Suspend one serial port. |
3438 | */ | 3437 | */ |
3439 | void serial8250_suspend_port(int line) | 3438 | void serial8250_suspend_port(int line) |
3440 | { | 3439 | { |
3441 | struct uart_8250_port *up = &serial8250_ports[line]; | 3440 | struct uart_8250_port *up = &serial8250_ports[line]; |
3442 | struct uart_port *port = &up->port; | 3441 | struct uart_port *port = &up->port; |
3443 | 3442 | ||
3444 | if (!console_suspend_enabled && uart_console(port) && | 3443 | if (!console_suspend_enabled && uart_console(port) && |
3445 | port->type != PORT_8250) { | 3444 | port->type != PORT_8250) { |
3446 | unsigned char canary = 0xa5; | 3445 | unsigned char canary = 0xa5; |
3447 | serial_out(up, UART_SCR, canary); | 3446 | serial_out(up, UART_SCR, canary); |
3448 | up->canary = canary; | 3447 | up->canary = canary; |
3449 | } | 3448 | } |
3450 | 3449 | ||
3451 | uart_suspend_port(&serial8250_reg, port); | 3450 | uart_suspend_port(&serial8250_reg, port); |
3452 | } | 3451 | } |
3453 | 3452 | ||
3454 | /** | 3453 | /** |
3455 | * serial8250_resume_port - resume one serial port | 3454 | * serial8250_resume_port - resume one serial port |
3456 | * @line: serial line number | 3455 | * @line: serial line number |
3457 | * | 3456 | * |
3458 | * Resume one serial port. | 3457 | * Resume one serial port. |
3459 | */ | 3458 | */ |
3460 | void serial8250_resume_port(int line) | 3459 | void serial8250_resume_port(int line) |
3461 | { | 3460 | { |
3462 | struct uart_8250_port *up = &serial8250_ports[line]; | 3461 | struct uart_8250_port *up = &serial8250_ports[line]; |
3463 | struct uart_port *port = &up->port; | 3462 | struct uart_port *port = &up->port; |
3464 | 3463 | ||
3465 | up->canary = 0; | 3464 | up->canary = 0; |
3466 | 3465 | ||
3467 | if (up->capabilities & UART_NATSEMI) { | 3466 | if (up->capabilities & UART_NATSEMI) { |
3468 | /* Ensure it's still in high speed mode */ | 3467 | /* Ensure it's still in high speed mode */ |
3469 | serial_port_out(port, UART_LCR, 0xE0); | 3468 | serial_port_out(port, UART_LCR, 0xE0); |
3470 | 3469 | ||
3471 | ns16550a_goto_highspeed(up); | 3470 | ns16550a_goto_highspeed(up); |
3472 | 3471 | ||
3473 | serial_port_out(port, UART_LCR, 0); | 3472 | serial_port_out(port, UART_LCR, 0); |
3474 | port->uartclk = 921600*16; | 3473 | port->uartclk = 921600*16; |
3475 | } | 3474 | } |
3476 | uart_resume_port(&serial8250_reg, port); | 3475 | uart_resume_port(&serial8250_reg, port); |
3477 | } | 3476 | } |
3478 | 3477 | ||
3479 | /* | 3478 | /* |
3480 | * Register a set of serial devices attached to a platform device. The | 3479 | * Register a set of serial devices attached to a platform device. The |
3481 | * list is terminated with a zero flags entry, which means we expect | 3480 | * list is terminated with a zero flags entry, which means we expect |
3482 | * all entries to have at least UPF_BOOT_AUTOCONF set. | 3481 | * all entries to have at least UPF_BOOT_AUTOCONF set. |
3483 | */ | 3482 | */ |
3484 | static int serial8250_probe(struct platform_device *dev) | 3483 | static int serial8250_probe(struct platform_device *dev) |
3485 | { | 3484 | { |
3486 | struct plat_serial8250_port *p = dev_get_platdata(&dev->dev); | 3485 | struct plat_serial8250_port *p = dev_get_platdata(&dev->dev); |
3487 | struct uart_8250_port uart; | 3486 | struct uart_8250_port uart; |
3488 | int ret, i, irqflag = 0; | 3487 | int ret, i, irqflag = 0; |
3489 | 3488 | ||
3490 | memset(&uart, 0, sizeof(uart)); | 3489 | memset(&uart, 0, sizeof(uart)); |
3491 | 3490 | ||
3492 | if (share_irqs) | 3491 | if (share_irqs) |
3493 | irqflag = IRQF_SHARED; | 3492 | irqflag = IRQF_SHARED; |
3494 | 3493 | ||
3495 | for (i = 0; p && p->flags != 0; p++, i++) { | 3494 | for (i = 0; p && p->flags != 0; p++, i++) { |
3496 | uart.port.iobase = p->iobase; | 3495 | uart.port.iobase = p->iobase; |
3497 | uart.port.membase = p->membase; | 3496 | uart.port.membase = p->membase; |
3498 | uart.port.irq = p->irq; | 3497 | uart.port.irq = p->irq; |
3499 | uart.port.irqflags = p->irqflags; | 3498 | uart.port.irqflags = p->irqflags; |
3500 | uart.port.uartclk = p->uartclk; | 3499 | uart.port.uartclk = p->uartclk; |
3501 | uart.port.regshift = p->regshift; | 3500 | uart.port.regshift = p->regshift; |
3502 | uart.port.iotype = p->iotype; | 3501 | uart.port.iotype = p->iotype; |
3503 | uart.port.flags = p->flags; | 3502 | uart.port.flags = p->flags; |
3504 | uart.port.mapbase = p->mapbase; | 3503 | uart.port.mapbase = p->mapbase; |
3505 | uart.port.hub6 = p->hub6; | 3504 | uart.port.hub6 = p->hub6; |
3506 | uart.port.private_data = p->private_data; | 3505 | uart.port.private_data = p->private_data; |
3507 | uart.port.type = p->type; | 3506 | uart.port.type = p->type; |
3508 | uart.port.serial_in = p->serial_in; | 3507 | uart.port.serial_in = p->serial_in; |
3509 | uart.port.serial_out = p->serial_out; | 3508 | uart.port.serial_out = p->serial_out; |
3510 | uart.port.handle_irq = p->handle_irq; | 3509 | uart.port.handle_irq = p->handle_irq; |
3511 | uart.port.handle_break = p->handle_break; | 3510 | uart.port.handle_break = p->handle_break; |
3512 | uart.port.set_termios = p->set_termios; | 3511 | uart.port.set_termios = p->set_termios; |
3513 | uart.port.pm = p->pm; | 3512 | uart.port.pm = p->pm; |
3514 | uart.port.dev = &dev->dev; | 3513 | uart.port.dev = &dev->dev; |
3515 | uart.port.irqflags |= irqflag; | 3514 | uart.port.irqflags |= irqflag; |
3516 | ret = serial8250_register_8250_port(&uart); | 3515 | ret = serial8250_register_8250_port(&uart); |
3517 | if (ret < 0) { | 3516 | if (ret < 0) { |
3518 | dev_err(&dev->dev, "unable to register port at index %d " | 3517 | dev_err(&dev->dev, "unable to register port at index %d " |
3519 | "(IO%lx MEM%llx IRQ%d): %d\n", i, | 3518 | "(IO%lx MEM%llx IRQ%d): %d\n", i, |
3520 | p->iobase, (unsigned long long)p->mapbase, | 3519 | p->iobase, (unsigned long long)p->mapbase, |
3521 | p->irq, ret); | 3520 | p->irq, ret); |
3522 | } | 3521 | } |
3523 | } | 3522 | } |
3524 | return 0; | 3523 | return 0; |
3525 | } | 3524 | } |
3526 | 3525 | ||
3527 | /* | 3526 | /* |
3528 | * Remove serial ports registered against a platform device. | 3527 | * Remove serial ports registered against a platform device. |
3529 | */ | 3528 | */ |
3530 | static int serial8250_remove(struct platform_device *dev) | 3529 | static int serial8250_remove(struct platform_device *dev) |
3531 | { | 3530 | { |
3532 | int i; | 3531 | int i; |
3533 | 3532 | ||
3534 | for (i = 0; i < nr_uarts; i++) { | 3533 | for (i = 0; i < nr_uarts; i++) { |
3535 | struct uart_8250_port *up = &serial8250_ports[i]; | 3534 | struct uart_8250_port *up = &serial8250_ports[i]; |
3536 | 3535 | ||
3537 | if (up->port.dev == &dev->dev) | 3536 | if (up->port.dev == &dev->dev) |
3538 | serial8250_unregister_port(i); | 3537 | serial8250_unregister_port(i); |
3539 | } | 3538 | } |
3540 | return 0; | 3539 | return 0; |
3541 | } | 3540 | } |
3542 | 3541 | ||
3543 | static int serial8250_suspend(struct platform_device *dev, pm_message_t state) | 3542 | static int serial8250_suspend(struct platform_device *dev, pm_message_t state) |
3544 | { | 3543 | { |
3545 | int i; | 3544 | int i; |
3546 | 3545 | ||
3547 | for (i = 0; i < UART_NR; i++) { | 3546 | for (i = 0; i < UART_NR; i++) { |
3548 | struct uart_8250_port *up = &serial8250_ports[i]; | 3547 | struct uart_8250_port *up = &serial8250_ports[i]; |
3549 | 3548 | ||
3550 | if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) | 3549 | if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) |
3551 | uart_suspend_port(&serial8250_reg, &up->port); | 3550 | uart_suspend_port(&serial8250_reg, &up->port); |
3552 | } | 3551 | } |
3553 | 3552 | ||
3554 | return 0; | 3553 | return 0; |
3555 | } | 3554 | } |
3556 | 3555 | ||
3557 | static int serial8250_resume(struct platform_device *dev) | 3556 | static int serial8250_resume(struct platform_device *dev) |
3558 | { | 3557 | { |
3559 | int i; | 3558 | int i; |
3560 | 3559 | ||
3561 | for (i = 0; i < UART_NR; i++) { | 3560 | for (i = 0; i < UART_NR; i++) { |
3562 | struct uart_8250_port *up = &serial8250_ports[i]; | 3561 | struct uart_8250_port *up = &serial8250_ports[i]; |
3563 | 3562 | ||
3564 | if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) | 3563 | if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) |
3565 | serial8250_resume_port(i); | 3564 | serial8250_resume_port(i); |
3566 | } | 3565 | } |
3567 | 3566 | ||
3568 | return 0; | 3567 | return 0; |
3569 | } | 3568 | } |
3570 | 3569 | ||
3571 | static struct platform_driver serial8250_isa_driver = { | 3570 | static struct platform_driver serial8250_isa_driver = { |
3572 | .probe = serial8250_probe, | 3571 | .probe = serial8250_probe, |
3573 | .remove = serial8250_remove, | 3572 | .remove = serial8250_remove, |
3574 | .suspend = serial8250_suspend, | 3573 | .suspend = serial8250_suspend, |
3575 | .resume = serial8250_resume, | 3574 | .resume = serial8250_resume, |
3576 | .driver = { | 3575 | .driver = { |
3577 | .name = "serial8250", | 3576 | .name = "serial8250", |
3578 | }, | 3577 | }, |
3579 | }; | 3578 | }; |
3580 | 3579 | ||
3581 | /* | 3580 | /* |
3582 | * This "device" covers _all_ ISA 8250-compatible serial devices listed | 3581 | * This "device" covers _all_ ISA 8250-compatible serial devices listed |
3583 | * in the table in include/asm/serial.h | 3582 | * in the table in include/asm/serial.h |
3584 | */ | 3583 | */ |
3585 | static struct platform_device *serial8250_isa_devs; | 3584 | static struct platform_device *serial8250_isa_devs; |
3586 | 3585 | ||
3587 | /* | 3586 | /* |
3588 | * serial8250_register_8250_port and serial8250_unregister_port allows for | 3587 | * serial8250_register_8250_port and serial8250_unregister_port allows for |
3589 | * 16x50 serial ports to be configured at run-time, to support PCMCIA | 3588 | * 16x50 serial ports to be configured at run-time, to support PCMCIA |
3590 | * modems and PCI multiport cards. | 3589 | * modems and PCI multiport cards. |
3591 | */ | 3590 | */ |
3592 | static DEFINE_MUTEX(serial_mutex); | 3591 | static DEFINE_MUTEX(serial_mutex); |
3593 | 3592 | ||
3594 | static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port) | 3593 | static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port) |
3595 | { | 3594 | { |
3596 | int i; | 3595 | int i; |
3597 | 3596 | ||
3598 | /* | 3597 | /* |
3599 | * First, find a port entry which matches. | 3598 | * First, find a port entry which matches. |
3600 | */ | 3599 | */ |
3601 | for (i = 0; i < nr_uarts; i++) | 3600 | for (i = 0; i < nr_uarts; i++) |
3602 | if (uart_match_port(&serial8250_ports[i].port, port)) | 3601 | if (uart_match_port(&serial8250_ports[i].port, port)) |
3603 | return &serial8250_ports[i]; | 3602 | return &serial8250_ports[i]; |
3604 | 3603 | ||
3605 | /* try line number first if still available */ | 3604 | /* try line number first if still available */ |
3606 | i = port->line; | 3605 | i = port->line; |
3607 | if (i < nr_uarts && serial8250_ports[i].port.type == PORT_UNKNOWN && | 3606 | if (i < nr_uarts && serial8250_ports[i].port.type == PORT_UNKNOWN && |
3608 | serial8250_ports[i].port.iobase == 0) | 3607 | serial8250_ports[i].port.iobase == 0) |
3609 | return &serial8250_ports[i]; | 3608 | return &serial8250_ports[i]; |
3610 | /* | 3609 | /* |
3611 | * We didn't find a matching entry, so look for the first | 3610 | * We didn't find a matching entry, so look for the first |
3612 | * free entry. We look for one which hasn't been previously | 3611 | * free entry. We look for one which hasn't been previously |
3613 | * used (indicated by zero iobase). | 3612 | * used (indicated by zero iobase). |
3614 | */ | 3613 | */ |
3615 | for (i = 0; i < nr_uarts; i++) | 3614 | for (i = 0; i < nr_uarts; i++) |
3616 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && | 3615 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && |
3617 | serial8250_ports[i].port.iobase == 0) | 3616 | serial8250_ports[i].port.iobase == 0) |
3618 | return &serial8250_ports[i]; | 3617 | return &serial8250_ports[i]; |
3619 | 3618 | ||
3620 | /* | 3619 | /* |
3621 | * That also failed. Last resort is to find any entry which | 3620 | * That also failed. Last resort is to find any entry which |
3622 | * doesn't have a real port associated with it. | 3621 | * doesn't have a real port associated with it. |
3623 | */ | 3622 | */ |
3624 | for (i = 0; i < nr_uarts; i++) | 3623 | for (i = 0; i < nr_uarts; i++) |
3625 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) | 3624 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) |
3626 | return &serial8250_ports[i]; | 3625 | return &serial8250_ports[i]; |
3627 | 3626 | ||
3628 | return NULL; | 3627 | return NULL; |
3629 | } | 3628 | } |
3630 | 3629 | ||
3631 | /** | 3630 | /** |
3632 | * serial8250_register_8250_port - register a serial port | 3631 | * serial8250_register_8250_port - register a serial port |
3633 | * @up: serial port template | 3632 | * @up: serial port template |
3634 | * | 3633 | * |
3635 | * Configure the serial port specified by the request. If the | 3634 | * Configure the serial port specified by the request. If the |
3636 | * port exists and is in use, it is hung up and unregistered | 3635 | * port exists and is in use, it is hung up and unregistered |
3637 | * first. | 3636 | * first. |
3638 | * | 3637 | * |
3639 | * The port is then probed and if necessary the IRQ is autodetected | 3638 | * The port is then probed and if necessary the IRQ is autodetected |
3640 | * If this fails an error is returned. | 3639 | * If this fails an error is returned. |
3641 | * | 3640 | * |
3642 | * On success the port is ready to use and the line number is returned. | 3641 | * On success the port is ready to use and the line number is returned. |
3643 | */ | 3642 | */ |
3644 | int serial8250_register_8250_port(struct uart_8250_port *up) | 3643 | int serial8250_register_8250_port(struct uart_8250_port *up) |
3645 | { | 3644 | { |
3646 | struct uart_8250_port *uart; | 3645 | struct uart_8250_port *uart; |
3647 | int ret = -ENOSPC; | 3646 | int ret = -ENOSPC; |
3648 | 3647 | ||
3649 | if (up->port.uartclk == 0) | 3648 | if (up->port.uartclk == 0) |
3650 | return -EINVAL; | 3649 | return -EINVAL; |
3651 | 3650 | ||
3652 | mutex_lock(&serial_mutex); | 3651 | mutex_lock(&serial_mutex); |
3653 | 3652 | ||
3654 | uart = serial8250_find_match_or_unused(&up->port); | 3653 | uart = serial8250_find_match_or_unused(&up->port); |
3655 | if (uart && uart->port.type != PORT_8250_CIR) { | 3654 | if (uart && uart->port.type != PORT_8250_CIR) { |
3656 | if (uart->port.dev) | 3655 | if (uart->port.dev) |
3657 | uart_remove_one_port(&serial8250_reg, &uart->port); | 3656 | uart_remove_one_port(&serial8250_reg, &uart->port); |
3658 | 3657 | ||
3659 | uart->port.iobase = up->port.iobase; | 3658 | uart->port.iobase = up->port.iobase; |
3660 | uart->port.membase = up->port.membase; | 3659 | uart->port.membase = up->port.membase; |
3661 | uart->port.irq = up->port.irq; | 3660 | uart->port.irq = up->port.irq; |
3662 | uart->port.irqflags = up->port.irqflags; | 3661 | uart->port.irqflags = up->port.irqflags; |
3663 | uart->port.uartclk = up->port.uartclk; | 3662 | uart->port.uartclk = up->port.uartclk; |
3664 | uart->port.fifosize = up->port.fifosize; | 3663 | uart->port.fifosize = up->port.fifosize; |
3665 | uart->port.regshift = up->port.regshift; | 3664 | uart->port.regshift = up->port.regshift; |
3666 | uart->port.iotype = up->port.iotype; | 3665 | uart->port.iotype = up->port.iotype; |
3667 | uart->port.flags = up->port.flags | UPF_BOOT_AUTOCONF; | 3666 | uart->port.flags = up->port.flags | UPF_BOOT_AUTOCONF; |
3668 | uart->bugs = up->bugs; | 3667 | uart->bugs = up->bugs; |
3669 | uart->port.mapbase = up->port.mapbase; | 3668 | uart->port.mapbase = up->port.mapbase; |
3670 | uart->port.private_data = up->port.private_data; | 3669 | uart->port.private_data = up->port.private_data; |
3671 | uart->port.fifosize = up->port.fifosize; | 3670 | uart->port.fifosize = up->port.fifosize; |
3672 | uart->tx_loadsz = up->tx_loadsz; | 3671 | uart->tx_loadsz = up->tx_loadsz; |
3673 | uart->capabilities = up->capabilities; | 3672 | uart->capabilities = up->capabilities; |
3674 | uart->port.throttle = up->port.throttle; | 3673 | uart->port.throttle = up->port.throttle; |
3675 | uart->port.unthrottle = up->port.unthrottle; | 3674 | uart->port.unthrottle = up->port.unthrottle; |
3676 | uart->port.rs485_config = up->port.rs485_config; | 3675 | uart->port.rs485_config = up->port.rs485_config; |
3677 | uart->port.rs485 = up->port.rs485; | 3676 | uart->port.rs485 = up->port.rs485; |
3678 | 3677 | ||
3679 | /* Take tx_loadsz from fifosize if it wasn't set separately */ | 3678 | /* Take tx_loadsz from fifosize if it wasn't set separately */ |
3680 | if (uart->port.fifosize && !uart->tx_loadsz) | 3679 | if (uart->port.fifosize && !uart->tx_loadsz) |
3681 | uart->tx_loadsz = uart->port.fifosize; | 3680 | uart->tx_loadsz = uart->port.fifosize; |
3682 | 3681 | ||
3683 | if (up->port.dev) | 3682 | if (up->port.dev) |
3684 | uart->port.dev = up->port.dev; | 3683 | uart->port.dev = up->port.dev; |
3685 | 3684 | ||
3686 | if (up->port.flags & UPF_FIXED_TYPE) | 3685 | if (up->port.flags & UPF_FIXED_TYPE) |
3687 | serial8250_init_fixed_type_port(uart, up->port.type); | 3686 | serial8250_init_fixed_type_port(uart, up->port.type); |
3688 | 3687 | ||
3689 | set_io_from_upio(&uart->port); | 3688 | set_io_from_upio(&uart->port); |
3690 | /* Possibly override default I/O functions. */ | 3689 | /* Possibly override default I/O functions. */ |
3691 | if (up->port.serial_in) | 3690 | if (up->port.serial_in) |
3692 | uart->port.serial_in = up->port.serial_in; | 3691 | uart->port.serial_in = up->port.serial_in; |
3693 | if (up->port.serial_out) | 3692 | if (up->port.serial_out) |
3694 | uart->port.serial_out = up->port.serial_out; | 3693 | uart->port.serial_out = up->port.serial_out; |
3695 | if (up->port.handle_irq) | 3694 | if (up->port.handle_irq) |
3696 | uart->port.handle_irq = up->port.handle_irq; | 3695 | uart->port.handle_irq = up->port.handle_irq; |
3697 | /* Possibly override set_termios call */ | 3696 | /* Possibly override set_termios call */ |
3698 | if (up->port.set_termios) | 3697 | if (up->port.set_termios) |
3699 | uart->port.set_termios = up->port.set_termios; | 3698 | uart->port.set_termios = up->port.set_termios; |
3700 | if (up->port.set_mctrl) | 3699 | if (up->port.set_mctrl) |
3701 | uart->port.set_mctrl = up->port.set_mctrl; | 3700 | uart->port.set_mctrl = up->port.set_mctrl; |
3702 | if (up->port.startup) | 3701 | if (up->port.startup) |
3703 | uart->port.startup = up->port.startup; | 3702 | uart->port.startup = up->port.startup; |
3704 | if (up->port.shutdown) | 3703 | if (up->port.shutdown) |
3705 | uart->port.shutdown = up->port.shutdown; | 3704 | uart->port.shutdown = up->port.shutdown; |
3706 | if (up->port.pm) | 3705 | if (up->port.pm) |
3707 | uart->port.pm = up->port.pm; | 3706 | uart->port.pm = up->port.pm; |
3708 | if (up->port.handle_break) | 3707 | if (up->port.handle_break) |
3709 | uart->port.handle_break = up->port.handle_break; | 3708 | uart->port.handle_break = up->port.handle_break; |
3710 | if (up->dl_read) | 3709 | if (up->dl_read) |
3711 | uart->dl_read = up->dl_read; | 3710 | uart->dl_read = up->dl_read; |
3712 | if (up->dl_write) | 3711 | if (up->dl_write) |
3713 | uart->dl_write = up->dl_write; | 3712 | uart->dl_write = up->dl_write; |
3714 | if (up->dma) { | 3713 | if (up->dma) { |
3715 | uart->dma = up->dma; | 3714 | uart->dma = up->dma; |
3716 | if (!uart->dma->tx_dma) | 3715 | if (!uart->dma->tx_dma) |
3717 | uart->dma->tx_dma = serial8250_tx_dma; | 3716 | uart->dma->tx_dma = serial8250_tx_dma; |
3718 | if (!uart->dma->rx_dma) | 3717 | if (!uart->dma->rx_dma) |
3719 | uart->dma->rx_dma = serial8250_rx_dma; | 3718 | uart->dma->rx_dma = serial8250_rx_dma; |
3720 | } | 3719 | } |
3721 | 3720 | ||
3722 | if (serial8250_isa_config != NULL) | 3721 | if (serial8250_isa_config != NULL) |
3723 | serial8250_isa_config(0, &uart->port, | 3722 | serial8250_isa_config(0, &uart->port, |
3724 | &uart->capabilities); | 3723 | &uart->capabilities); |
3725 | 3724 | ||
3726 | ret = uart_add_one_port(&serial8250_reg, &uart->port); | 3725 | ret = uart_add_one_port(&serial8250_reg, &uart->port); |
3727 | if (ret == 0) | 3726 | if (ret == 0) |
3728 | ret = uart->port.line; | 3727 | ret = uart->port.line; |
3729 | } | 3728 | } |
3730 | mutex_unlock(&serial_mutex); | 3729 | mutex_unlock(&serial_mutex); |
3731 | 3730 | ||
3732 | return ret; | 3731 | return ret; |
3733 | } | 3732 | } |
3734 | EXPORT_SYMBOL(serial8250_register_8250_port); | 3733 | EXPORT_SYMBOL(serial8250_register_8250_port); |
3735 | 3734 | ||
3736 | /** | 3735 | /** |
3737 | * serial8250_unregister_port - remove a 16x50 serial port at runtime | 3736 | * serial8250_unregister_port - remove a 16x50 serial port at runtime |
3738 | * @line: serial line number | 3737 | * @line: serial line number |
3739 | * | 3738 | * |
3740 | * Remove one serial port. This may not be called from interrupt | 3739 | * Remove one serial port. This may not be called from interrupt |
3741 | * context. We hand the port back to the our control. | 3740 | * context. We hand the port back to the our control. |
3742 | */ | 3741 | */ |
3743 | void serial8250_unregister_port(int line) | 3742 | void serial8250_unregister_port(int line) |
3744 | { | 3743 | { |
3745 | struct uart_8250_port *uart = &serial8250_ports[line]; | 3744 | struct uart_8250_port *uart = &serial8250_ports[line]; |
3746 | 3745 | ||
3747 | mutex_lock(&serial_mutex); | 3746 | mutex_lock(&serial_mutex); |
3748 | uart_remove_one_port(&serial8250_reg, &uart->port); | 3747 | uart_remove_one_port(&serial8250_reg, &uart->port); |
3749 | if (serial8250_isa_devs) { | 3748 | if (serial8250_isa_devs) { |
3750 | uart->port.flags &= ~UPF_BOOT_AUTOCONF; | 3749 | uart->port.flags &= ~UPF_BOOT_AUTOCONF; |
3751 | uart->port.type = PORT_UNKNOWN; | 3750 | uart->port.type = PORT_UNKNOWN; |
3752 | uart->port.dev = &serial8250_isa_devs->dev; | 3751 | uart->port.dev = &serial8250_isa_devs->dev; |
3753 | uart->capabilities = uart_config[uart->port.type].flags; | 3752 | uart->capabilities = uart_config[uart->port.type].flags; |
3754 | uart_add_one_port(&serial8250_reg, &uart->port); | 3753 | uart_add_one_port(&serial8250_reg, &uart->port); |
3755 | } else { | 3754 | } else { |
3756 | uart->port.dev = NULL; | 3755 | uart->port.dev = NULL; |
3757 | } | 3756 | } |
3758 | mutex_unlock(&serial_mutex); | 3757 | mutex_unlock(&serial_mutex); |
3759 | } | 3758 | } |
3760 | EXPORT_SYMBOL(serial8250_unregister_port); | 3759 | EXPORT_SYMBOL(serial8250_unregister_port); |
3761 | 3760 | ||
3762 | static int __init serial8250_init(void) | 3761 | static int __init serial8250_init(void) |
3763 | { | 3762 | { |
3764 | int ret; | 3763 | int ret; |
3765 | 3764 | ||
3766 | serial8250_isa_init_ports(); | 3765 | serial8250_isa_init_ports(); |
3767 | 3766 | ||
3768 | printk(KERN_INFO "Serial: 8250/16550 driver, " | 3767 | printk(KERN_INFO "Serial: 8250/16550 driver, " |
3769 | "%d ports, IRQ sharing %sabled\n", nr_uarts, | 3768 | "%d ports, IRQ sharing %sabled\n", nr_uarts, |
3770 | share_irqs ? "en" : "dis"); | 3769 | share_irqs ? "en" : "dis"); |
3771 | 3770 | ||
3772 | #ifdef CONFIG_SPARC | 3771 | #ifdef CONFIG_SPARC |
3773 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); | 3772 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); |
3774 | #else | 3773 | #else |
3775 | serial8250_reg.nr = UART_NR; | 3774 | serial8250_reg.nr = UART_NR; |
3776 | ret = uart_register_driver(&serial8250_reg); | 3775 | ret = uart_register_driver(&serial8250_reg); |
3777 | #endif | 3776 | #endif |
3778 | if (ret) | 3777 | if (ret) |
3779 | goto out; | 3778 | goto out; |
3780 | 3779 | ||
3781 | ret = serial8250_pnp_init(); | 3780 | ret = serial8250_pnp_init(); |
3782 | if (ret) | 3781 | if (ret) |
3783 | goto unreg_uart_drv; | 3782 | goto unreg_uart_drv; |
3784 | 3783 | ||
3785 | serial8250_isa_devs = platform_device_alloc("serial8250", | 3784 | serial8250_isa_devs = platform_device_alloc("serial8250", |
3786 | PLAT8250_DEV_LEGACY); | 3785 | PLAT8250_DEV_LEGACY); |
3787 | if (!serial8250_isa_devs) { | 3786 | if (!serial8250_isa_devs) { |
3788 | ret = -ENOMEM; | 3787 | ret = -ENOMEM; |
3789 | goto unreg_pnp; | 3788 | goto unreg_pnp; |
3790 | } | 3789 | } |
3791 | 3790 | ||
3792 | ret = platform_device_add(serial8250_isa_devs); | 3791 | ret = platform_device_add(serial8250_isa_devs); |
3793 | if (ret) | 3792 | if (ret) |
3794 | goto put_dev; | 3793 | goto put_dev; |
3795 | 3794 | ||
3796 | serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev); | 3795 | serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev); |
3797 | 3796 | ||
3798 | ret = platform_driver_register(&serial8250_isa_driver); | 3797 | ret = platform_driver_register(&serial8250_isa_driver); |
3799 | if (ret == 0) | 3798 | if (ret == 0) |
3800 | goto out; | 3799 | goto out; |
3801 | 3800 | ||
3802 | platform_device_del(serial8250_isa_devs); | 3801 | platform_device_del(serial8250_isa_devs); |
3803 | put_dev: | 3802 | put_dev: |
3804 | platform_device_put(serial8250_isa_devs); | 3803 | platform_device_put(serial8250_isa_devs); |
3805 | unreg_pnp: | 3804 | unreg_pnp: |
3806 | serial8250_pnp_exit(); | 3805 | serial8250_pnp_exit(); |
3807 | unreg_uart_drv: | 3806 | unreg_uart_drv: |
3808 | #ifdef CONFIG_SPARC | 3807 | #ifdef CONFIG_SPARC |
3809 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | 3808 | sunserial_unregister_minors(&serial8250_reg, UART_NR); |
3810 | #else | 3809 | #else |
3811 | uart_unregister_driver(&serial8250_reg); | 3810 | uart_unregister_driver(&serial8250_reg); |
3812 | #endif | 3811 | #endif |
3813 | out: | 3812 | out: |
3814 | return ret; | 3813 | return ret; |
3815 | } | 3814 | } |
3816 | 3815 | ||
3817 | static void __exit serial8250_exit(void) | 3816 | static void __exit serial8250_exit(void) |
3818 | { | 3817 | { |
3819 | struct platform_device *isa_dev = serial8250_isa_devs; | 3818 | struct platform_device *isa_dev = serial8250_isa_devs; |
3820 | 3819 | ||
3821 | /* | 3820 | /* |
3822 | * This tells serial8250_unregister_port() not to re-register | 3821 | * This tells serial8250_unregister_port() not to re-register |
3823 | * the ports (thereby making serial8250_isa_driver permanently | 3822 | * the ports (thereby making serial8250_isa_driver permanently |
3824 | * in use.) | 3823 | * in use.) |
3825 | */ | 3824 | */ |
3826 | serial8250_isa_devs = NULL; | 3825 | serial8250_isa_devs = NULL; |
3827 | 3826 | ||
3828 | platform_driver_unregister(&serial8250_isa_driver); | 3827 | platform_driver_unregister(&serial8250_isa_driver); |
3829 | platform_device_unregister(isa_dev); | 3828 | platform_device_unregister(isa_dev); |
3830 | 3829 | ||
3831 | serial8250_pnp_exit(); | 3830 | serial8250_pnp_exit(); |
3832 | 3831 | ||
3833 | #ifdef CONFIG_SPARC | 3832 | #ifdef CONFIG_SPARC |
3834 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | 3833 | sunserial_unregister_minors(&serial8250_reg, UART_NR); |
3835 | #else | 3834 | #else |
3836 | uart_unregister_driver(&serial8250_reg); | 3835 | uart_unregister_driver(&serial8250_reg); |
3837 | #endif | 3836 | #endif |
3838 | } | 3837 | } |
3839 | 3838 | ||
3840 | module_init(serial8250_init); | 3839 | module_init(serial8250_init); |
3841 | module_exit(serial8250_exit); | 3840 | module_exit(serial8250_exit); |
3842 | 3841 | ||
3843 | EXPORT_SYMBOL(serial8250_suspend_port); | 3842 | EXPORT_SYMBOL(serial8250_suspend_port); |
3844 | EXPORT_SYMBOL(serial8250_resume_port); | 3843 | EXPORT_SYMBOL(serial8250_resume_port); |
3845 | 3844 | ||
3846 | MODULE_LICENSE("GPL"); | 3845 | MODULE_LICENSE("GPL"); |
3847 | MODULE_DESCRIPTION("Generic 8250/16x50 serial driver"); | 3846 | MODULE_DESCRIPTION("Generic 8250/16x50 serial driver"); |
3848 | 3847 | ||
3849 | module_param(share_irqs, uint, 0644); | 3848 | module_param(share_irqs, uint, 0644); |
3850 | MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" | 3849 | MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" |
3851 | " (unsafe)"); | 3850 | " (unsafe)"); |
3852 | 3851 | ||
3853 | module_param(nr_uarts, uint, 0644); | 3852 | module_param(nr_uarts, uint, 0644); |
3854 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); | 3853 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); |
3855 | 3854 | ||
3856 | module_param(skip_txen_test, uint, 0644); | 3855 | module_param(skip_txen_test, uint, 0644); |
3857 | MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time"); | 3856 | MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time"); |
3858 | 3857 | ||
3859 | #ifdef CONFIG_SERIAL_8250_RSA | 3858 | #ifdef CONFIG_SERIAL_8250_RSA |
3860 | module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); | 3859 | module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); |
3861 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); | 3860 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); |
3862 | #endif | 3861 | #endif |
3863 | MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); | 3862 | MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); |
3864 | 3863 | ||
3865 | #ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS | 3864 | #ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS |
3866 | #ifndef MODULE | 3865 | #ifndef MODULE |
3867 | /* This module was renamed to 8250_core in 3.7. Keep the old "8250" name | 3866 | /* This module was renamed to 8250_core in 3.7. Keep the old "8250" name |
3868 | * working as well for the module options so we don't break people. We | 3867 | * working as well for the module options so we don't break people. We |
3869 | * need to keep the names identical and the convenient macros will happily | 3868 | * need to keep the names identical and the convenient macros will happily |
3870 | * refuse to let us do that by failing the build with redefinition errors | 3869 | * refuse to let us do that by failing the build with redefinition errors |
3871 | * of global variables. So we stick them inside a dummy function to avoid | 3870 | * of global variables. So we stick them inside a dummy function to avoid |
3872 | * those conflicts. The options still get parsed, and the redefined | 3871 | * those conflicts. The options still get parsed, and the redefined |
3873 | * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive. | 3872 | * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive. |
3874 | * | 3873 | * |
3875 | * This is hacky. I'm sorry. | 3874 | * This is hacky. I'm sorry. |
3876 | */ | 3875 | */ |
3877 | static void __used s8250_options(void) | 3876 | static void __used s8250_options(void) |
3878 | { | 3877 | { |
3879 | #undef MODULE_PARAM_PREFIX | 3878 | #undef MODULE_PARAM_PREFIX |
3880 | #define MODULE_PARAM_PREFIX "8250_core." | 3879 | #define MODULE_PARAM_PREFIX "8250_core." |
3881 | 3880 | ||
3882 | module_param_cb(share_irqs, ¶m_ops_uint, &share_irqs, 0644); | 3881 | module_param_cb(share_irqs, ¶m_ops_uint, &share_irqs, 0644); |
3883 | module_param_cb(nr_uarts, ¶m_ops_uint, &nr_uarts, 0644); | 3882 | module_param_cb(nr_uarts, ¶m_ops_uint, &nr_uarts, 0644); |
3884 | module_param_cb(skip_txen_test, ¶m_ops_uint, &skip_txen_test, 0644); | 3883 | module_param_cb(skip_txen_test, ¶m_ops_uint, &skip_txen_test, 0644); |
3885 | #ifdef CONFIG_SERIAL_8250_RSA | 3884 | #ifdef CONFIG_SERIAL_8250_RSA |
3886 | __module_param_call(MODULE_PARAM_PREFIX, probe_rsa, | 3885 | __module_param_call(MODULE_PARAM_PREFIX, probe_rsa, |
3887 | ¶m_array_ops, .arr = &__param_arr_probe_rsa, | 3886 | ¶m_array_ops, .arr = &__param_arr_probe_rsa, |
3888 | 0444, -1, 0); | 3887 | 0444, -1, 0); |
3889 | #endif | 3888 | #endif |
3890 | } | 3889 | } |
3891 | #else | 3890 | #else |
3892 | MODULE_ALIAS("8250_core"); | 3891 | MODULE_ALIAS("8250_core"); |
3893 | #endif | 3892 | #endif |
3894 | #endif | 3893 | #endif |
3895 | 3894 |
drivers/tty/serial/8250/8250_dw.c
1 | /* | 1 | /* |
2 | * Synopsys DesignWare 8250 driver. | 2 | * Synopsys DesignWare 8250 driver. |
3 | * | 3 | * |
4 | * Copyright 2011 Picochip, Jamie Iles. | 4 | * Copyright 2011 Picochip, Jamie Iles. |
5 | * Copyright 2013 Intel Corporation | 5 | * Copyright 2013 Intel Corporation |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | * | 11 | * |
12 | * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the | 12 | * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the |
13 | * LCR is written whilst busy. If it is, then a busy detect interrupt is | 13 | * LCR is written whilst busy. If it is, then a busy detect interrupt is |
14 | * raised, the LCR needs to be rewritten and the uart status register read. | 14 | * raised, the LCR needs to be rewritten and the uart status register read. |
15 | */ | 15 | */ |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/serial_8250.h> | 19 | #include <linux/serial_8250.h> |
20 | #include <linux/serial_core.h> | 20 | #include <linux/serial_core.h> |
21 | #include <linux/serial_reg.h> | 21 | #include <linux/serial_reg.h> |
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_irq.h> | 23 | #include <linux/of_irq.h> |
24 | #include <linux/of_platform.h> | 24 | #include <linux/of_platform.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
28 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
29 | #include <linux/reset.h> | 29 | #include <linux/reset.h> |
30 | #include <linux/pm_runtime.h> | 30 | #include <linux/pm_runtime.h> |
31 | 31 | ||
32 | #include <asm/byteorder.h> | 32 | #include <asm/byteorder.h> |
33 | 33 | ||
34 | #include "8250.h" | 34 | #include "8250.h" |
35 | 35 | ||
36 | /* Offsets for the DesignWare specific registers */ | 36 | /* Offsets for the DesignWare specific registers */ |
37 | #define DW_UART_USR 0x1f /* UART Status Register */ | 37 | #define DW_UART_USR 0x1f /* UART Status Register */ |
38 | #define DW_UART_CPR 0xf4 /* Component Parameter Register */ | 38 | #define DW_UART_CPR 0xf4 /* Component Parameter Register */ |
39 | #define DW_UART_UCV 0xf8 /* UART Component Version */ | 39 | #define DW_UART_UCV 0xf8 /* UART Component Version */ |
40 | 40 | ||
41 | /* Component Parameter Register bits */ | 41 | /* Component Parameter Register bits */ |
42 | #define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0) | 42 | #define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0) |
43 | #define DW_UART_CPR_AFCE_MODE (1 << 4) | 43 | #define DW_UART_CPR_AFCE_MODE (1 << 4) |
44 | #define DW_UART_CPR_THRE_MODE (1 << 5) | 44 | #define DW_UART_CPR_THRE_MODE (1 << 5) |
45 | #define DW_UART_CPR_SIR_MODE (1 << 6) | 45 | #define DW_UART_CPR_SIR_MODE (1 << 6) |
46 | #define DW_UART_CPR_SIR_LP_MODE (1 << 7) | 46 | #define DW_UART_CPR_SIR_LP_MODE (1 << 7) |
47 | #define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8) | 47 | #define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8) |
48 | #define DW_UART_CPR_FIFO_ACCESS (1 << 9) | 48 | #define DW_UART_CPR_FIFO_ACCESS (1 << 9) |
49 | #define DW_UART_CPR_FIFO_STAT (1 << 10) | 49 | #define DW_UART_CPR_FIFO_STAT (1 << 10) |
50 | #define DW_UART_CPR_SHADOW (1 << 11) | 50 | #define DW_UART_CPR_SHADOW (1 << 11) |
51 | #define DW_UART_CPR_ENCODED_PARMS (1 << 12) | 51 | #define DW_UART_CPR_ENCODED_PARMS (1 << 12) |
52 | #define DW_UART_CPR_DMA_EXTRA (1 << 13) | 52 | #define DW_UART_CPR_DMA_EXTRA (1 << 13) |
53 | #define DW_UART_CPR_FIFO_MODE (0xff << 16) | 53 | #define DW_UART_CPR_FIFO_MODE (0xff << 16) |
54 | /* Helper for fifo size calculation */ | 54 | /* Helper for fifo size calculation */ |
55 | #define DW_UART_CPR_FIFO_SIZE(a) (((a >> 16) & 0xff) * 16) | 55 | #define DW_UART_CPR_FIFO_SIZE(a) (((a >> 16) & 0xff) * 16) |
56 | 56 | ||
57 | 57 | ||
58 | struct dw8250_data { | 58 | struct dw8250_data { |
59 | u8 usr_reg; | 59 | u8 usr_reg; |
60 | int last_mcr; | 60 | int last_mcr; |
61 | int line; | 61 | int line; |
62 | int msr_mask_on; | ||
63 | int msr_mask_off; | ||
62 | struct clk *clk; | 64 | struct clk *clk; |
63 | struct clk *pclk; | 65 | struct clk *pclk; |
64 | struct reset_control *rst; | 66 | struct reset_control *rst; |
65 | struct uart_8250_dma dma; | 67 | struct uart_8250_dma dma; |
66 | }; | 68 | }; |
67 | 69 | ||
68 | #define BYT_PRV_CLK 0x800 | 70 | #define BYT_PRV_CLK 0x800 |
69 | #define BYT_PRV_CLK_EN (1 << 0) | 71 | #define BYT_PRV_CLK_EN (1 << 0) |
70 | #define BYT_PRV_CLK_M_VAL_SHIFT 1 | 72 | #define BYT_PRV_CLK_M_VAL_SHIFT 1 |
71 | #define BYT_PRV_CLK_N_VAL_SHIFT 16 | 73 | #define BYT_PRV_CLK_N_VAL_SHIFT 16 |
72 | #define BYT_PRV_CLK_UPDATE (1 << 31) | 74 | #define BYT_PRV_CLK_UPDATE (1 << 31) |
73 | 75 | ||
74 | static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value) | 76 | static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value) |
75 | { | 77 | { |
76 | struct dw8250_data *d = p->private_data; | 78 | struct dw8250_data *d = p->private_data; |
77 | 79 | ||
78 | /* If reading MSR, report CTS asserted when auto-CTS/RTS enabled */ | 80 | /* If reading MSR, report CTS asserted when auto-CTS/RTS enabled */ |
79 | if (offset == UART_MSR && d->last_mcr & UART_MCR_AFE) { | 81 | if (offset == UART_MSR && d->last_mcr & UART_MCR_AFE) { |
80 | value |= UART_MSR_CTS; | 82 | value |= UART_MSR_CTS; |
81 | value &= ~UART_MSR_DCTS; | 83 | value &= ~UART_MSR_DCTS; |
82 | } | 84 | } |
83 | 85 | ||
86 | /* Override any modem control signals if needed */ | ||
87 | if (offset == UART_MSR) { | ||
88 | value |= d->msr_mask_on; | ||
89 | value &= ~d->msr_mask_off; | ||
90 | } | ||
91 | |||
84 | return value; | 92 | return value; |
85 | } | 93 | } |
86 | 94 | ||
87 | static void dw8250_force_idle(struct uart_port *p) | 95 | static void dw8250_force_idle(struct uart_port *p) |
88 | { | 96 | { |
89 | struct uart_8250_port *up = up_to_u8250p(p); | 97 | struct uart_8250_port *up = up_to_u8250p(p); |
90 | 98 | ||
91 | serial8250_clear_and_reinit_fifos(up); | 99 | serial8250_clear_and_reinit_fifos(up); |
92 | (void)p->serial_in(p, UART_RX); | 100 | (void)p->serial_in(p, UART_RX); |
93 | } | 101 | } |
94 | 102 | ||
95 | static void dw8250_serial_out(struct uart_port *p, int offset, int value) | 103 | static void dw8250_serial_out(struct uart_port *p, int offset, int value) |
96 | { | 104 | { |
97 | struct dw8250_data *d = p->private_data; | 105 | struct dw8250_data *d = p->private_data; |
98 | 106 | ||
99 | if (offset == UART_MCR) | 107 | if (offset == UART_MCR) |
100 | d->last_mcr = value; | 108 | d->last_mcr = value; |
101 | 109 | ||
102 | writeb(value, p->membase + (offset << p->regshift)); | 110 | writeb(value, p->membase + (offset << p->regshift)); |
103 | 111 | ||
104 | /* Make sure LCR write wasn't ignored */ | 112 | /* Make sure LCR write wasn't ignored */ |
105 | if (offset == UART_LCR) { | 113 | if (offset == UART_LCR) { |
106 | int tries = 1000; | 114 | int tries = 1000; |
107 | while (tries--) { | 115 | while (tries--) { |
108 | unsigned int lcr = p->serial_in(p, UART_LCR); | 116 | unsigned int lcr = p->serial_in(p, UART_LCR); |
109 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) | 117 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) |
110 | return; | 118 | return; |
111 | dw8250_force_idle(p); | 119 | dw8250_force_idle(p); |
112 | writeb(value, p->membase + (UART_LCR << p->regshift)); | 120 | writeb(value, p->membase + (UART_LCR << p->regshift)); |
113 | } | 121 | } |
114 | dev_err(p->dev, "Couldn't set LCR to %d\n", value); | 122 | dev_err(p->dev, "Couldn't set LCR to %d\n", value); |
115 | } | 123 | } |
116 | } | 124 | } |
117 | 125 | ||
118 | static unsigned int dw8250_serial_in(struct uart_port *p, int offset) | 126 | static unsigned int dw8250_serial_in(struct uart_port *p, int offset) |
119 | { | 127 | { |
120 | unsigned int value = readb(p->membase + (offset << p->regshift)); | 128 | unsigned int value = readb(p->membase + (offset << p->regshift)); |
121 | 129 | ||
122 | return dw8250_modify_msr(p, offset, value); | 130 | return dw8250_modify_msr(p, offset, value); |
123 | } | 131 | } |
124 | 132 | ||
125 | #ifdef CONFIG_64BIT | 133 | #ifdef CONFIG_64BIT |
126 | static unsigned int dw8250_serial_inq(struct uart_port *p, int offset) | 134 | static unsigned int dw8250_serial_inq(struct uart_port *p, int offset) |
127 | { | 135 | { |
128 | unsigned int value; | 136 | unsigned int value; |
129 | 137 | ||
130 | value = (u8)__raw_readq(p->membase + (offset << p->regshift)); | 138 | value = (u8)__raw_readq(p->membase + (offset << p->regshift)); |
131 | 139 | ||
132 | return dw8250_modify_msr(p, offset, value); | 140 | return dw8250_modify_msr(p, offset, value); |
133 | } | 141 | } |
134 | 142 | ||
135 | static void dw8250_serial_outq(struct uart_port *p, int offset, int value) | 143 | static void dw8250_serial_outq(struct uart_port *p, int offset, int value) |
136 | { | 144 | { |
137 | struct dw8250_data *d = p->private_data; | 145 | struct dw8250_data *d = p->private_data; |
138 | 146 | ||
139 | if (offset == UART_MCR) | 147 | if (offset == UART_MCR) |
140 | d->last_mcr = value; | 148 | d->last_mcr = value; |
141 | 149 | ||
142 | value &= 0xff; | 150 | value &= 0xff; |
143 | __raw_writeq(value, p->membase + (offset << p->regshift)); | 151 | __raw_writeq(value, p->membase + (offset << p->regshift)); |
144 | /* Read back to ensure register write ordering. */ | 152 | /* Read back to ensure register write ordering. */ |
145 | __raw_readq(p->membase + (UART_LCR << p->regshift)); | 153 | __raw_readq(p->membase + (UART_LCR << p->regshift)); |
146 | 154 | ||
147 | /* Make sure LCR write wasn't ignored */ | 155 | /* Make sure LCR write wasn't ignored */ |
148 | if (offset == UART_LCR) { | 156 | if (offset == UART_LCR) { |
149 | int tries = 1000; | 157 | int tries = 1000; |
150 | while (tries--) { | 158 | while (tries--) { |
151 | unsigned int lcr = p->serial_in(p, UART_LCR); | 159 | unsigned int lcr = p->serial_in(p, UART_LCR); |
152 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) | 160 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) |
153 | return; | 161 | return; |
154 | dw8250_force_idle(p); | 162 | dw8250_force_idle(p); |
155 | __raw_writeq(value & 0xff, | 163 | __raw_writeq(value & 0xff, |
156 | p->membase + (UART_LCR << p->regshift)); | 164 | p->membase + (UART_LCR << p->regshift)); |
157 | } | 165 | } |
158 | dev_err(p->dev, "Couldn't set LCR to %d\n", value); | 166 | dev_err(p->dev, "Couldn't set LCR to %d\n", value); |
159 | } | 167 | } |
160 | } | 168 | } |
161 | #endif /* CONFIG_64BIT */ | 169 | #endif /* CONFIG_64BIT */ |
162 | 170 | ||
163 | static void dw8250_serial_out32(struct uart_port *p, int offset, int value) | 171 | static void dw8250_serial_out32(struct uart_port *p, int offset, int value) |
164 | { | 172 | { |
165 | struct dw8250_data *d = p->private_data; | 173 | struct dw8250_data *d = p->private_data; |
166 | 174 | ||
167 | if (offset == UART_MCR) | 175 | if (offset == UART_MCR) |
168 | d->last_mcr = value; | 176 | d->last_mcr = value; |
169 | 177 | ||
170 | writel(value, p->membase + (offset << p->regshift)); | 178 | writel(value, p->membase + (offset << p->regshift)); |
171 | 179 | ||
172 | /* Make sure LCR write wasn't ignored */ | 180 | /* Make sure LCR write wasn't ignored */ |
173 | if (offset == UART_LCR) { | 181 | if (offset == UART_LCR) { |
174 | int tries = 1000; | 182 | int tries = 1000; |
175 | while (tries--) { | 183 | while (tries--) { |
176 | unsigned int lcr = p->serial_in(p, UART_LCR); | 184 | unsigned int lcr = p->serial_in(p, UART_LCR); |
177 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) | 185 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) |
178 | return; | 186 | return; |
179 | dw8250_force_idle(p); | 187 | dw8250_force_idle(p); |
180 | writel(value, p->membase + (UART_LCR << p->regshift)); | 188 | writel(value, p->membase + (UART_LCR << p->regshift)); |
181 | } | 189 | } |
182 | dev_err(p->dev, "Couldn't set LCR to %d\n", value); | 190 | dev_err(p->dev, "Couldn't set LCR to %d\n", value); |
183 | } | 191 | } |
184 | } | 192 | } |
185 | 193 | ||
186 | static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) | 194 | static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) |
187 | { | 195 | { |
188 | unsigned int value = readl(p->membase + (offset << p->regshift)); | 196 | unsigned int value = readl(p->membase + (offset << p->regshift)); |
189 | 197 | ||
190 | return dw8250_modify_msr(p, offset, value); | 198 | return dw8250_modify_msr(p, offset, value); |
191 | } | 199 | } |
192 | 200 | ||
193 | static int dw8250_handle_irq(struct uart_port *p) | 201 | static int dw8250_handle_irq(struct uart_port *p) |
194 | { | 202 | { |
195 | struct dw8250_data *d = p->private_data; | 203 | struct dw8250_data *d = p->private_data; |
196 | unsigned int iir = p->serial_in(p, UART_IIR); | 204 | unsigned int iir = p->serial_in(p, UART_IIR); |
197 | 205 | ||
198 | if (serial8250_handle_irq(p, iir)) { | 206 | if (serial8250_handle_irq(p, iir)) { |
199 | return 1; | 207 | return 1; |
200 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | 208 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { |
201 | /* Clear the USR */ | 209 | /* Clear the USR */ |
202 | (void)p->serial_in(p, d->usr_reg); | 210 | (void)p->serial_in(p, d->usr_reg); |
203 | 211 | ||
204 | return 1; | 212 | return 1; |
205 | } | 213 | } |
206 | 214 | ||
207 | return 0; | 215 | return 0; |
208 | } | 216 | } |
209 | 217 | ||
210 | static void | 218 | static void |
211 | dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) | 219 | dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) |
212 | { | 220 | { |
213 | if (!state) | 221 | if (!state) |
214 | pm_runtime_get_sync(port->dev); | 222 | pm_runtime_get_sync(port->dev); |
215 | 223 | ||
216 | serial8250_do_pm(port, state, old); | 224 | serial8250_do_pm(port, state, old); |
217 | 225 | ||
218 | if (state) | 226 | if (state) |
219 | pm_runtime_put_sync_suspend(port->dev); | 227 | pm_runtime_put_sync_suspend(port->dev); |
220 | } | 228 | } |
221 | 229 | ||
222 | static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios, | 230 | static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios, |
223 | struct ktermios *old) | 231 | struct ktermios *old) |
224 | { | 232 | { |
225 | unsigned int baud = tty_termios_baud_rate(termios); | 233 | unsigned int baud = tty_termios_baud_rate(termios); |
226 | struct dw8250_data *d = p->private_data; | 234 | struct dw8250_data *d = p->private_data; |
227 | unsigned int rate; | 235 | unsigned int rate; |
228 | int ret; | 236 | int ret; |
229 | 237 | ||
230 | if (IS_ERR(d->clk) || !old) | 238 | if (IS_ERR(d->clk) || !old) |
231 | goto out; | 239 | goto out; |
232 | 240 | ||
233 | /* Not requesting clock rates below 1.8432Mhz */ | 241 | /* Not requesting clock rates below 1.8432Mhz */ |
234 | if (baud < 115200) | 242 | if (baud < 115200) |
235 | baud = 115200; | 243 | baud = 115200; |
236 | 244 | ||
237 | clk_disable_unprepare(d->clk); | 245 | clk_disable_unprepare(d->clk); |
238 | rate = clk_round_rate(d->clk, baud * 16); | 246 | rate = clk_round_rate(d->clk, baud * 16); |
239 | ret = clk_set_rate(d->clk, rate); | 247 | ret = clk_set_rate(d->clk, rate); |
240 | clk_prepare_enable(d->clk); | 248 | clk_prepare_enable(d->clk); |
241 | 249 | ||
242 | if (!ret) | 250 | if (!ret) |
243 | p->uartclk = rate; | 251 | p->uartclk = rate; |
244 | out: | 252 | out: |
245 | serial8250_do_set_termios(p, termios, old); | 253 | serial8250_do_set_termios(p, termios, old); |
246 | } | 254 | } |
247 | 255 | ||
248 | static bool dw8250_dma_filter(struct dma_chan *chan, void *param) | 256 | static bool dw8250_dma_filter(struct dma_chan *chan, void *param) |
249 | { | 257 | { |
250 | return false; | 258 | return false; |
251 | } | 259 | } |
252 | 260 | ||
253 | static void dw8250_setup_port(struct uart_8250_port *up) | 261 | static void dw8250_setup_port(struct uart_8250_port *up) |
254 | { | 262 | { |
255 | struct uart_port *p = &up->port; | 263 | struct uart_port *p = &up->port; |
256 | u32 reg = readl(p->membase + DW_UART_UCV); | 264 | u32 reg = readl(p->membase + DW_UART_UCV); |
257 | 265 | ||
258 | /* | 266 | /* |
259 | * If the Component Version Register returns zero, we know that | 267 | * If the Component Version Register returns zero, we know that |
260 | * ADDITIONAL_FEATURES are not enabled. No need to go any further. | 268 | * ADDITIONAL_FEATURES are not enabled. No need to go any further. |
261 | */ | 269 | */ |
262 | if (!reg) | 270 | if (!reg) |
263 | return; | 271 | return; |
264 | 272 | ||
265 | dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n", | 273 | dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n", |
266 | (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); | 274 | (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); |
267 | 275 | ||
268 | reg = readl(p->membase + DW_UART_CPR); | 276 | reg = readl(p->membase + DW_UART_CPR); |
269 | if (!reg) | 277 | if (!reg) |
270 | return; | 278 | return; |
271 | 279 | ||
272 | /* Select the type based on fifo */ | 280 | /* Select the type based on fifo */ |
273 | if (reg & DW_UART_CPR_FIFO_MODE) { | 281 | if (reg & DW_UART_CPR_FIFO_MODE) { |
274 | p->type = PORT_16550A; | 282 | p->type = PORT_16550A; |
275 | p->flags |= UPF_FIXED_TYPE; | 283 | p->flags |= UPF_FIXED_TYPE; |
276 | p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); | 284 | p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); |
277 | up->tx_loadsz = p->fifosize; | 285 | up->tx_loadsz = p->fifosize; |
278 | up->capabilities = UART_CAP_FIFO; | 286 | up->capabilities = UART_CAP_FIFO; |
279 | } | 287 | } |
280 | 288 | ||
281 | if (reg & DW_UART_CPR_AFCE_MODE) | 289 | if (reg & DW_UART_CPR_AFCE_MODE) |
282 | up->capabilities |= UART_CAP_AFE; | 290 | up->capabilities |= UART_CAP_AFE; |
283 | } | 291 | } |
284 | 292 | ||
285 | static int dw8250_probe_of(struct uart_port *p, | 293 | static int dw8250_probe_of(struct uart_port *p, |
286 | struct dw8250_data *data) | 294 | struct dw8250_data *data) |
287 | { | 295 | { |
288 | struct device_node *np = p->dev->of_node; | 296 | struct device_node *np = p->dev->of_node; |
289 | struct uart_8250_port *up = up_to_u8250p(p); | 297 | struct uart_8250_port *up = up_to_u8250p(p); |
290 | u32 val; | 298 | u32 val; |
291 | bool has_ucv = true; | 299 | bool has_ucv = true; |
292 | int id; | 300 | int id; |
293 | 301 | ||
294 | #ifdef CONFIG_64BIT | 302 | #ifdef CONFIG_64BIT |
295 | if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) { | 303 | if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) { |
296 | p->serial_in = dw8250_serial_inq; | 304 | p->serial_in = dw8250_serial_inq; |
297 | p->serial_out = dw8250_serial_outq; | 305 | p->serial_out = dw8250_serial_outq; |
298 | p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; | 306 | p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; |
299 | p->type = PORT_OCTEON; | 307 | p->type = PORT_OCTEON; |
300 | data->usr_reg = 0x27; | 308 | data->usr_reg = 0x27; |
301 | has_ucv = false; | 309 | has_ucv = false; |
302 | } else | 310 | } else |
303 | #endif | 311 | #endif |
304 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | 312 | if (!of_property_read_u32(np, "reg-io-width", &val)) { |
305 | switch (val) { | 313 | switch (val) { |
306 | case 1: | 314 | case 1: |
307 | break; | 315 | break; |
308 | case 4: | 316 | case 4: |
309 | p->iotype = UPIO_MEM32; | 317 | p->iotype = UPIO_MEM32; |
310 | p->serial_in = dw8250_serial_in32; | 318 | p->serial_in = dw8250_serial_in32; |
311 | p->serial_out = dw8250_serial_out32; | 319 | p->serial_out = dw8250_serial_out32; |
312 | break; | 320 | break; |
313 | default: | 321 | default: |
314 | dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); | 322 | dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); |
315 | return -EINVAL; | 323 | return -EINVAL; |
316 | } | 324 | } |
317 | } | 325 | } |
318 | if (has_ucv) | 326 | if (has_ucv) |
319 | dw8250_setup_port(up); | 327 | dw8250_setup_port(up); |
320 | 328 | ||
321 | /* if we have a valid fifosize, try hooking up DMA here */ | 329 | /* if we have a valid fifosize, try hooking up DMA here */ |
322 | if (p->fifosize) { | 330 | if (p->fifosize) { |
323 | up->dma = &data->dma; | 331 | up->dma = &data->dma; |
324 | 332 | ||
325 | up->dma->rxconf.src_maxburst = p->fifosize / 4; | 333 | up->dma->rxconf.src_maxburst = p->fifosize / 4; |
326 | up->dma->txconf.dst_maxburst = p->fifosize / 4; | 334 | up->dma->txconf.dst_maxburst = p->fifosize / 4; |
327 | } | 335 | } |
328 | 336 | ||
329 | if (!of_property_read_u32(np, "reg-shift", &val)) | 337 | if (!of_property_read_u32(np, "reg-shift", &val)) |
330 | p->regshift = val; | 338 | p->regshift = val; |
331 | 339 | ||
332 | /* get index of serial line, if found in DT aliases */ | 340 | /* get index of serial line, if found in DT aliases */ |
333 | id = of_alias_get_id(np, "serial"); | 341 | id = of_alias_get_id(np, "serial"); |
334 | if (id >= 0) | 342 | if (id >= 0) |
335 | p->line = id; | 343 | p->line = id; |
344 | |||
345 | if (of_property_read_bool(np, "dcd-override")) { | ||
346 | /* Always report DCD as active */ | ||
347 | data->msr_mask_on |= UART_MSR_DCD; | ||
348 | data->msr_mask_off |= UART_MSR_DDCD; | ||
349 | } | ||
350 | |||
351 | if (of_property_read_bool(np, "dsr-override")) { | ||
352 | /* Always report DSR as active */ | ||
353 | data->msr_mask_on |= UART_MSR_DSR; | ||
354 | data->msr_mask_off |= UART_MSR_DDSR; | ||
355 | } | ||
356 | |||
357 | if (of_property_read_bool(np, "cts-override")) { | ||
358 | /* Always report DSR as active */ | ||
359 | data->msr_mask_on |= UART_MSR_DSR; | ||
360 | data->msr_mask_off |= UART_MSR_DDSR; | ||
361 | } | ||
362 | |||
363 | if (of_property_read_bool(np, "ri-override")) { | ||
364 | /* Always report Ring indicator as inactive */ | ||
365 | data->msr_mask_off |= UART_MSR_RI; | ||
366 | data->msr_mask_off |= UART_MSR_TERI; | ||
367 | } | ||
336 | 368 | ||
337 | /* clock got configured through clk api, all done */ | 369 | /* clock got configured through clk api, all done */ |
338 | if (p->uartclk) | 370 | if (p->uartclk) |
339 | return 0; | 371 | return 0; |
340 | 372 | ||
341 | /* try to find out clock frequency from DT as fallback */ | 373 | /* try to find out clock frequency from DT as fallback */ |
342 | if (of_property_read_u32(np, "clock-frequency", &val)) { | 374 | if (of_property_read_u32(np, "clock-frequency", &val)) { |
343 | dev_err(p->dev, "clk or clock-frequency not defined\n"); | 375 | dev_err(p->dev, "clk or clock-frequency not defined\n"); |
344 | return -EINVAL; | 376 | return -EINVAL; |
345 | } | 377 | } |
346 | p->uartclk = val; | 378 | p->uartclk = val; |
347 | 379 | ||
348 | return 0; | 380 | return 0; |
349 | } | 381 | } |
350 | 382 | ||
351 | static int dw8250_probe_acpi(struct uart_8250_port *up, | 383 | static int dw8250_probe_acpi(struct uart_8250_port *up, |
352 | struct dw8250_data *data) | 384 | struct dw8250_data *data) |
353 | { | 385 | { |
354 | const struct acpi_device_id *id; | 386 | const struct acpi_device_id *id; |
355 | struct uart_port *p = &up->port; | 387 | struct uart_port *p = &up->port; |
356 | 388 | ||
357 | dw8250_setup_port(up); | 389 | dw8250_setup_port(up); |
358 | 390 | ||
359 | id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); | 391 | id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); |
360 | if (!id) | 392 | if (!id) |
361 | return -ENODEV; | 393 | return -ENODEV; |
362 | 394 | ||
363 | if (!p->uartclk) | 395 | if (!p->uartclk) |
364 | if (device_property_read_u32(p->dev, "clock-frequency", | 396 | if (device_property_read_u32(p->dev, "clock-frequency", |
365 | &p->uartclk)) | 397 | &p->uartclk)) |
366 | return -EINVAL; | 398 | return -EINVAL; |
367 | 399 | ||
368 | p->iotype = UPIO_MEM32; | 400 | p->iotype = UPIO_MEM32; |
369 | p->serial_in = dw8250_serial_in32; | 401 | p->serial_in = dw8250_serial_in32; |
370 | p->serial_out = dw8250_serial_out32; | 402 | p->serial_out = dw8250_serial_out32; |
371 | p->regshift = 2; | 403 | p->regshift = 2; |
372 | 404 | ||
373 | up->dma = &data->dma; | 405 | up->dma = &data->dma; |
374 | 406 | ||
375 | up->dma->rxconf.src_maxburst = p->fifosize / 4; | 407 | up->dma->rxconf.src_maxburst = p->fifosize / 4; |
376 | up->dma->txconf.dst_maxburst = p->fifosize / 4; | 408 | up->dma->txconf.dst_maxburst = p->fifosize / 4; |
377 | 409 | ||
378 | up->port.set_termios = dw8250_set_termios; | 410 | up->port.set_termios = dw8250_set_termios; |
379 | 411 | ||
380 | return 0; | 412 | return 0; |
381 | } | 413 | } |
382 | 414 | ||
383 | static int dw8250_probe(struct platform_device *pdev) | 415 | static int dw8250_probe(struct platform_device *pdev) |
384 | { | 416 | { |
385 | struct uart_8250_port uart = {}; | 417 | struct uart_8250_port uart = {}; |
386 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 418 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
387 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 419 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
388 | struct dw8250_data *data; | 420 | struct dw8250_data *data; |
389 | int err; | 421 | int err; |
390 | 422 | ||
391 | if (!regs || !irq) { | 423 | if (!regs || !irq) { |
392 | dev_err(&pdev->dev, "no registers/irq defined\n"); | 424 | dev_err(&pdev->dev, "no registers/irq defined\n"); |
393 | return -EINVAL; | 425 | return -EINVAL; |
394 | } | 426 | } |
395 | 427 | ||
396 | spin_lock_init(&uart.port.lock); | 428 | spin_lock_init(&uart.port.lock); |
397 | uart.port.mapbase = regs->start; | 429 | uart.port.mapbase = regs->start; |
398 | uart.port.irq = irq->start; | 430 | uart.port.irq = irq->start; |
399 | uart.port.handle_irq = dw8250_handle_irq; | 431 | uart.port.handle_irq = dw8250_handle_irq; |
400 | uart.port.pm = dw8250_do_pm; | 432 | uart.port.pm = dw8250_do_pm; |
401 | uart.port.type = PORT_8250; | 433 | uart.port.type = PORT_8250; |
402 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; | 434 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; |
403 | uart.port.dev = &pdev->dev; | 435 | uart.port.dev = &pdev->dev; |
404 | 436 | ||
405 | uart.port.membase = devm_ioremap(&pdev->dev, regs->start, | 437 | uart.port.membase = devm_ioremap(&pdev->dev, regs->start, |
406 | resource_size(regs)); | 438 | resource_size(regs)); |
407 | if (!uart.port.membase) | 439 | if (!uart.port.membase) |
408 | return -ENOMEM; | 440 | return -ENOMEM; |
409 | 441 | ||
410 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | 442 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
411 | if (!data) | 443 | if (!data) |
412 | return -ENOMEM; | 444 | return -ENOMEM; |
413 | 445 | ||
414 | data->usr_reg = DW_UART_USR; | 446 | data->usr_reg = DW_UART_USR; |
415 | data->clk = devm_clk_get(&pdev->dev, "baudclk"); | 447 | data->clk = devm_clk_get(&pdev->dev, "baudclk"); |
416 | if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER) | 448 | if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER) |
417 | data->clk = devm_clk_get(&pdev->dev, NULL); | 449 | data->clk = devm_clk_get(&pdev->dev, NULL); |
418 | if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) | 450 | if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) |
419 | return -EPROBE_DEFER; | 451 | return -EPROBE_DEFER; |
420 | if (!IS_ERR(data->clk)) { | 452 | if (!IS_ERR(data->clk)) { |
421 | err = clk_prepare_enable(data->clk); | 453 | err = clk_prepare_enable(data->clk); |
422 | if (err) | 454 | if (err) |
423 | dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n", | 455 | dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n", |
424 | err); | 456 | err); |
425 | else | 457 | else |
426 | uart.port.uartclk = clk_get_rate(data->clk); | 458 | uart.port.uartclk = clk_get_rate(data->clk); |
427 | } | 459 | } |
428 | 460 | ||
429 | data->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); | 461 | data->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); |
430 | if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) { | 462 | if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) { |
431 | err = -EPROBE_DEFER; | 463 | err = -EPROBE_DEFER; |
432 | goto err_clk; | 464 | goto err_clk; |
433 | } | 465 | } |
434 | if (!IS_ERR(data->pclk)) { | 466 | if (!IS_ERR(data->pclk)) { |
435 | err = clk_prepare_enable(data->pclk); | 467 | err = clk_prepare_enable(data->pclk); |
436 | if (err) { | 468 | if (err) { |
437 | dev_err(&pdev->dev, "could not enable apb_pclk\n"); | 469 | dev_err(&pdev->dev, "could not enable apb_pclk\n"); |
438 | goto err_clk; | 470 | goto err_clk; |
439 | } | 471 | } |
440 | } | 472 | } |
441 | 473 | ||
442 | data->rst = devm_reset_control_get_optional(&pdev->dev, NULL); | 474 | data->rst = devm_reset_control_get_optional(&pdev->dev, NULL); |
443 | if (IS_ERR(data->rst) && PTR_ERR(data->rst) == -EPROBE_DEFER) { | 475 | if (IS_ERR(data->rst) && PTR_ERR(data->rst) == -EPROBE_DEFER) { |
444 | err = -EPROBE_DEFER; | 476 | err = -EPROBE_DEFER; |
445 | goto err_pclk; | 477 | goto err_pclk; |
446 | } | 478 | } |
447 | if (!IS_ERR(data->rst)) | 479 | if (!IS_ERR(data->rst)) |
448 | reset_control_deassert(data->rst); | 480 | reset_control_deassert(data->rst); |
449 | 481 | ||
450 | data->dma.rx_param = data; | 482 | data->dma.rx_param = data; |
451 | data->dma.tx_param = data; | 483 | data->dma.tx_param = data; |
452 | data->dma.fn = dw8250_dma_filter; | 484 | data->dma.fn = dw8250_dma_filter; |
453 | 485 | ||
454 | uart.port.iotype = UPIO_MEM; | 486 | uart.port.iotype = UPIO_MEM; |
455 | uart.port.serial_in = dw8250_serial_in; | 487 | uart.port.serial_in = dw8250_serial_in; |
456 | uart.port.serial_out = dw8250_serial_out; | 488 | uart.port.serial_out = dw8250_serial_out; |
457 | uart.port.private_data = data; | 489 | uart.port.private_data = data; |
458 | 490 | ||
459 | if (pdev->dev.of_node) { | 491 | if (pdev->dev.of_node) { |
460 | err = dw8250_probe_of(&uart.port, data); | 492 | err = dw8250_probe_of(&uart.port, data); |
461 | if (err) | 493 | if (err) |
462 | goto err_reset; | 494 | goto err_reset; |
463 | } else if (ACPI_HANDLE(&pdev->dev)) { | 495 | } else if (ACPI_HANDLE(&pdev->dev)) { |
464 | err = dw8250_probe_acpi(&uart, data); | 496 | err = dw8250_probe_acpi(&uart, data); |
465 | if (err) | 497 | if (err) |
466 | goto err_reset; | 498 | goto err_reset; |
467 | } else { | 499 | } else { |
468 | err = -ENODEV; | 500 | err = -ENODEV; |
469 | goto err_reset; | 501 | goto err_reset; |
470 | } | 502 | } |
471 | 503 | ||
472 | data->line = serial8250_register_8250_port(&uart); | 504 | data->line = serial8250_register_8250_port(&uart); |
473 | if (data->line < 0) { | 505 | if (data->line < 0) { |
474 | err = data->line; | 506 | err = data->line; |
475 | goto err_reset; | 507 | goto err_reset; |
476 | } | 508 | } |
477 | 509 | ||
478 | platform_set_drvdata(pdev, data); | 510 | platform_set_drvdata(pdev, data); |
479 | 511 | ||
480 | pm_runtime_set_active(&pdev->dev); | 512 | pm_runtime_set_active(&pdev->dev); |
481 | pm_runtime_enable(&pdev->dev); | 513 | pm_runtime_enable(&pdev->dev); |
482 | 514 | ||
483 | return 0; | 515 | return 0; |
484 | 516 | ||
485 | err_reset: | 517 | err_reset: |
486 | if (!IS_ERR(data->rst)) | 518 | if (!IS_ERR(data->rst)) |
487 | reset_control_assert(data->rst); | 519 | reset_control_assert(data->rst); |
488 | 520 | ||
489 | err_pclk: | 521 | err_pclk: |
490 | if (!IS_ERR(data->pclk)) | 522 | if (!IS_ERR(data->pclk)) |
491 | clk_disable_unprepare(data->pclk); | 523 | clk_disable_unprepare(data->pclk); |
492 | 524 | ||
493 | err_clk: | 525 | err_clk: |
494 | if (!IS_ERR(data->clk)) | 526 | if (!IS_ERR(data->clk)) |
495 | clk_disable_unprepare(data->clk); | 527 | clk_disable_unprepare(data->clk); |
496 | 528 | ||
497 | return err; | 529 | return err; |
498 | } | 530 | } |
499 | 531 | ||
500 | static int dw8250_remove(struct platform_device *pdev) | 532 | static int dw8250_remove(struct platform_device *pdev) |
501 | { | 533 | { |
502 | struct dw8250_data *data = platform_get_drvdata(pdev); | 534 | struct dw8250_data *data = platform_get_drvdata(pdev); |
503 | 535 | ||
504 | pm_runtime_get_sync(&pdev->dev); | 536 | pm_runtime_get_sync(&pdev->dev); |
505 | 537 | ||
506 | serial8250_unregister_port(data->line); | 538 | serial8250_unregister_port(data->line); |
507 | 539 | ||
508 | if (!IS_ERR(data->rst)) | 540 | if (!IS_ERR(data->rst)) |
509 | reset_control_assert(data->rst); | 541 | reset_control_assert(data->rst); |
510 | 542 | ||
511 | if (!IS_ERR(data->pclk)) | 543 | if (!IS_ERR(data->pclk)) |
512 | clk_disable_unprepare(data->pclk); | 544 | clk_disable_unprepare(data->pclk); |
513 | 545 | ||
514 | if (!IS_ERR(data->clk)) | 546 | if (!IS_ERR(data->clk)) |
515 | clk_disable_unprepare(data->clk); | 547 | clk_disable_unprepare(data->clk); |
516 | 548 | ||
517 | pm_runtime_disable(&pdev->dev); | 549 | pm_runtime_disable(&pdev->dev); |
518 | pm_runtime_put_noidle(&pdev->dev); | 550 | pm_runtime_put_noidle(&pdev->dev); |
519 | 551 | ||
520 | return 0; | 552 | return 0; |
521 | } | 553 | } |
522 | 554 | ||
523 | #ifdef CONFIG_PM_SLEEP | 555 | #ifdef CONFIG_PM_SLEEP |
524 | static int dw8250_suspend(struct device *dev) | 556 | static int dw8250_suspend(struct device *dev) |
525 | { | 557 | { |
526 | struct dw8250_data *data = dev_get_drvdata(dev); | 558 | struct dw8250_data *data = dev_get_drvdata(dev); |
527 | 559 | ||
528 | serial8250_suspend_port(data->line); | 560 | serial8250_suspend_port(data->line); |
529 | 561 | ||
530 | return 0; | 562 | return 0; |
531 | } | 563 | } |
532 | 564 | ||
533 | static int dw8250_resume(struct device *dev) | 565 | static int dw8250_resume(struct device *dev) |
534 | { | 566 | { |
535 | struct dw8250_data *data = dev_get_drvdata(dev); | 567 | struct dw8250_data *data = dev_get_drvdata(dev); |
536 | 568 | ||
537 | serial8250_resume_port(data->line); | 569 | serial8250_resume_port(data->line); |
538 | 570 | ||
539 | return 0; | 571 | return 0; |
540 | } | 572 | } |
541 | #endif /* CONFIG_PM_SLEEP */ | 573 | #endif /* CONFIG_PM_SLEEP */ |
542 | 574 | ||
543 | #ifdef CONFIG_PM | 575 | #ifdef CONFIG_PM |
544 | static int dw8250_runtime_suspend(struct device *dev) | 576 | static int dw8250_runtime_suspend(struct device *dev) |
545 | { | 577 | { |
546 | struct dw8250_data *data = dev_get_drvdata(dev); | 578 | struct dw8250_data *data = dev_get_drvdata(dev); |
547 | 579 | ||
548 | if (!IS_ERR(data->clk)) | 580 | if (!IS_ERR(data->clk)) |
549 | clk_disable_unprepare(data->clk); | 581 | clk_disable_unprepare(data->clk); |
550 | 582 | ||
551 | if (!IS_ERR(data->pclk)) | 583 | if (!IS_ERR(data->pclk)) |
552 | clk_disable_unprepare(data->pclk); | 584 | clk_disable_unprepare(data->pclk); |
553 | 585 | ||
554 | return 0; | 586 | return 0; |
555 | } | 587 | } |
556 | 588 | ||
557 | static int dw8250_runtime_resume(struct device *dev) | 589 | static int dw8250_runtime_resume(struct device *dev) |
558 | { | 590 | { |
559 | struct dw8250_data *data = dev_get_drvdata(dev); | 591 | struct dw8250_data *data = dev_get_drvdata(dev); |
560 | 592 | ||
561 | if (!IS_ERR(data->pclk)) | 593 | if (!IS_ERR(data->pclk)) |
562 | clk_prepare_enable(data->pclk); | 594 | clk_prepare_enable(data->pclk); |
563 | 595 | ||
564 | if (!IS_ERR(data->clk)) | 596 | if (!IS_ERR(data->clk)) |
565 | clk_prepare_enable(data->clk); | 597 | clk_prepare_enable(data->clk); |
566 | 598 | ||
567 | return 0; | 599 | return 0; |
568 | } | 600 | } |
569 | #endif | 601 | #endif |
570 | 602 | ||
571 | static const struct dev_pm_ops dw8250_pm_ops = { | 603 | static const struct dev_pm_ops dw8250_pm_ops = { |
572 | SET_SYSTEM_SLEEP_PM_OPS(dw8250_suspend, dw8250_resume) | 604 | SET_SYSTEM_SLEEP_PM_OPS(dw8250_suspend, dw8250_resume) |
573 | SET_RUNTIME_PM_OPS(dw8250_runtime_suspend, dw8250_runtime_resume, NULL) | 605 | SET_RUNTIME_PM_OPS(dw8250_runtime_suspend, dw8250_runtime_resume, NULL) |
574 | }; | 606 | }; |
575 | 607 | ||
576 | static const struct of_device_id dw8250_of_match[] = { | 608 | static const struct of_device_id dw8250_of_match[] = { |
577 | { .compatible = "snps,dw-apb-uart" }, | 609 | { .compatible = "snps,dw-apb-uart" }, |
578 | { .compatible = "cavium,octeon-3860-uart" }, | 610 | { .compatible = "cavium,octeon-3860-uart" }, |
579 | { /* Sentinel */ } | 611 | { /* Sentinel */ } |
580 | }; | 612 | }; |
581 | MODULE_DEVICE_TABLE(of, dw8250_of_match); | 613 | MODULE_DEVICE_TABLE(of, dw8250_of_match); |
582 | 614 | ||
583 | static const struct acpi_device_id dw8250_acpi_match[] = { | 615 | static const struct acpi_device_id dw8250_acpi_match[] = { |
584 | { "INT33C4", 0 }, | 616 | { "INT33C4", 0 }, |
585 | { "INT33C5", 0 }, | 617 | { "INT33C5", 0 }, |
586 | { "INT3434", 0 }, | 618 | { "INT3434", 0 }, |
587 | { "INT3435", 0 }, | 619 | { "INT3435", 0 }, |
588 | { "80860F0A", 0 }, | 620 | { "80860F0A", 0 }, |
589 | { "8086228A", 0 }, | 621 | { "8086228A", 0 }, |
590 | { "APMC0D08", 0}, | 622 | { "APMC0D08", 0}, |
591 | { }, | 623 | { }, |
592 | }; | 624 | }; |
593 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); | 625 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); |
594 | 626 | ||
595 | static struct platform_driver dw8250_platform_driver = { | 627 | static struct platform_driver dw8250_platform_driver = { |
596 | .driver = { | 628 | .driver = { |
597 | .name = "dw-apb-uart", | 629 | .name = "dw-apb-uart", |
598 | .pm = &dw8250_pm_ops, | 630 | .pm = &dw8250_pm_ops, |
599 | .of_match_table = dw8250_of_match, | 631 | .of_match_table = dw8250_of_match, |
600 | .acpi_match_table = ACPI_PTR(dw8250_acpi_match), | 632 | .acpi_match_table = ACPI_PTR(dw8250_acpi_match), |
601 | }, | 633 | }, |
602 | .probe = dw8250_probe, | 634 | .probe = dw8250_probe, |
603 | .remove = dw8250_remove, | 635 | .remove = dw8250_remove, |
604 | }; | 636 | }; |
605 | 637 | ||
606 | module_platform_driver(dw8250_platform_driver); | 638 | module_platform_driver(dw8250_platform_driver); |
607 | 639 | ||
608 | MODULE_AUTHOR("Jamie Iles"); | 640 | MODULE_AUTHOR("Jamie Iles"); |
609 | MODULE_LICENSE("GPL"); | 641 | MODULE_LICENSE("GPL"); |
610 | MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver"); | 642 | MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver"); |
611 | 643 |
drivers/tty/serial/8250/8250_pci.c
1 | /* | 1 | /* |
2 | * Probe module for 8250/16550-type PCI serial ports. | 2 | * Probe module for 8250/16550-type PCI serial ports. |
3 | * | 3 | * |
4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
5 | * | 5 | * |
6 | * Copyright (C) 2001 Russell King, All Rights Reserved. | 6 | * Copyright (C) 2001 Russell King, All Rights Reserved. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License. | 10 | * the Free Software Foundation; either version 2 of the License. |
11 | */ | 11 | */ |
12 | #undef DEBUG | 12 | #undef DEBUG |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/tty.h> | 19 | #include <linux/tty.h> |
20 | #include <linux/serial_reg.h> | 20 | #include <linux/serial_reg.h> |
21 | #include <linux/serial_core.h> | 21 | #include <linux/serial_core.h> |
22 | #include <linux/8250_pci.h> | 22 | #include <linux/8250_pci.h> |
23 | #include <linux/bitops.h> | 23 | #include <linux/bitops.h> |
24 | 24 | ||
25 | #include <asm/byteorder.h> | 25 | #include <asm/byteorder.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | 27 | ||
28 | #include <linux/dmaengine.h> | 28 | #include <linux/dmaengine.h> |
29 | #include <linux/platform_data/dma-dw.h> | 29 | #include <linux/platform_data/dma-dw.h> |
30 | 30 | ||
31 | #include "8250.h" | 31 | #include "8250.h" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * init function returns: | 34 | * init function returns: |
35 | * > 0 - number of ports | 35 | * > 0 - number of ports |
36 | * = 0 - use board->num_ports | 36 | * = 0 - use board->num_ports |
37 | * < 0 - error | 37 | * < 0 - error |
38 | */ | 38 | */ |
39 | struct pci_serial_quirk { | 39 | struct pci_serial_quirk { |
40 | u32 vendor; | 40 | u32 vendor; |
41 | u32 device; | 41 | u32 device; |
42 | u32 subvendor; | 42 | u32 subvendor; |
43 | u32 subdevice; | 43 | u32 subdevice; |
44 | int (*probe)(struct pci_dev *dev); | 44 | int (*probe)(struct pci_dev *dev); |
45 | int (*init)(struct pci_dev *dev); | 45 | int (*init)(struct pci_dev *dev); |
46 | int (*setup)(struct serial_private *, | 46 | int (*setup)(struct serial_private *, |
47 | const struct pciserial_board *, | 47 | const struct pciserial_board *, |
48 | struct uart_8250_port *, int); | 48 | struct uart_8250_port *, int); |
49 | void (*exit)(struct pci_dev *dev); | 49 | void (*exit)(struct pci_dev *dev); |
50 | }; | 50 | }; |
51 | 51 | ||
52 | #define PCI_NUM_BAR_RESOURCES 6 | 52 | #define PCI_NUM_BAR_RESOURCES 6 |
53 | 53 | ||
54 | struct serial_private { | 54 | struct serial_private { |
55 | struct pci_dev *dev; | 55 | struct pci_dev *dev; |
56 | unsigned int nr; | 56 | unsigned int nr; |
57 | void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES]; | 57 | void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES]; |
58 | struct pci_serial_quirk *quirk; | 58 | struct pci_serial_quirk *quirk; |
59 | int line[0]; | 59 | int line[0]; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static int pci_default_setup(struct serial_private*, | 62 | static int pci_default_setup(struct serial_private*, |
63 | const struct pciserial_board*, struct uart_8250_port *, int); | 63 | const struct pciserial_board*, struct uart_8250_port *, int); |
64 | 64 | ||
65 | static void moan_device(const char *str, struct pci_dev *dev) | 65 | static void moan_device(const char *str, struct pci_dev *dev) |
66 | { | 66 | { |
67 | dev_err(&dev->dev, | 67 | dev_err(&dev->dev, |
68 | "%s: %s\n" | 68 | "%s: %s\n" |
69 | "Please send the output of lspci -vv, this\n" | 69 | "Please send the output of lspci -vv, this\n" |
70 | "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" | 70 | "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" |
71 | "manufacturer and name of serial board or\n" | 71 | "manufacturer and name of serial board or\n" |
72 | "modem board to rmk+serial@arm.linux.org.uk.\n", | 72 | "modem board to <linux-serial@vger.kernel.org>.\n", |
73 | pci_name(dev), str, dev->vendor, dev->device, | 73 | pci_name(dev), str, dev->vendor, dev->device, |
74 | dev->subsystem_vendor, dev->subsystem_device); | 74 | dev->subsystem_vendor, dev->subsystem_device); |
75 | } | 75 | } |
76 | 76 | ||
77 | static int | 77 | static int |
78 | setup_port(struct serial_private *priv, struct uart_8250_port *port, | 78 | setup_port(struct serial_private *priv, struct uart_8250_port *port, |
79 | int bar, int offset, int regshift) | 79 | int bar, int offset, int regshift) |
80 | { | 80 | { |
81 | struct pci_dev *dev = priv->dev; | 81 | struct pci_dev *dev = priv->dev; |
82 | 82 | ||
83 | if (bar >= PCI_NUM_BAR_RESOURCES) | 83 | if (bar >= PCI_NUM_BAR_RESOURCES) |
84 | return -EINVAL; | 84 | return -EINVAL; |
85 | 85 | ||
86 | if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) { | 86 | if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) { |
87 | if (!priv->remapped_bar[bar]) | 87 | if (!priv->remapped_bar[bar]) |
88 | priv->remapped_bar[bar] = pci_ioremap_bar(dev, bar); | 88 | priv->remapped_bar[bar] = pci_ioremap_bar(dev, bar); |
89 | if (!priv->remapped_bar[bar]) | 89 | if (!priv->remapped_bar[bar]) |
90 | return -ENOMEM; | 90 | return -ENOMEM; |
91 | 91 | ||
92 | port->port.iotype = UPIO_MEM; | 92 | port->port.iotype = UPIO_MEM; |
93 | port->port.iobase = 0; | 93 | port->port.iobase = 0; |
94 | port->port.mapbase = pci_resource_start(dev, bar) + offset; | 94 | port->port.mapbase = pci_resource_start(dev, bar) + offset; |
95 | port->port.membase = priv->remapped_bar[bar] + offset; | 95 | port->port.membase = priv->remapped_bar[bar] + offset; |
96 | port->port.regshift = regshift; | 96 | port->port.regshift = regshift; |
97 | } else { | 97 | } else { |
98 | port->port.iotype = UPIO_PORT; | 98 | port->port.iotype = UPIO_PORT; |
99 | port->port.iobase = pci_resource_start(dev, bar) + offset; | 99 | port->port.iobase = pci_resource_start(dev, bar) + offset; |
100 | port->port.mapbase = 0; | 100 | port->port.mapbase = 0; |
101 | port->port.membase = NULL; | 101 | port->port.membase = NULL; |
102 | port->port.regshift = 0; | 102 | port->port.regshift = 0; |
103 | } | 103 | } |
104 | return 0; | 104 | return 0; |
105 | } | 105 | } |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * ADDI-DATA GmbH communication cards <info@addi-data.com> | 108 | * ADDI-DATA GmbH communication cards <info@addi-data.com> |
109 | */ | 109 | */ |
110 | static int addidata_apci7800_setup(struct serial_private *priv, | 110 | static int addidata_apci7800_setup(struct serial_private *priv, |
111 | const struct pciserial_board *board, | 111 | const struct pciserial_board *board, |
112 | struct uart_8250_port *port, int idx) | 112 | struct uart_8250_port *port, int idx) |
113 | { | 113 | { |
114 | unsigned int bar = 0, offset = board->first_offset; | 114 | unsigned int bar = 0, offset = board->first_offset; |
115 | bar = FL_GET_BASE(board->flags); | 115 | bar = FL_GET_BASE(board->flags); |
116 | 116 | ||
117 | if (idx < 2) { | 117 | if (idx < 2) { |
118 | offset += idx * board->uart_offset; | 118 | offset += idx * board->uart_offset; |
119 | } else if ((idx >= 2) && (idx < 4)) { | 119 | } else if ((idx >= 2) && (idx < 4)) { |
120 | bar += 1; | 120 | bar += 1; |
121 | offset += ((idx - 2) * board->uart_offset); | 121 | offset += ((idx - 2) * board->uart_offset); |
122 | } else if ((idx >= 4) && (idx < 6)) { | 122 | } else if ((idx >= 4) && (idx < 6)) { |
123 | bar += 2; | 123 | bar += 2; |
124 | offset += ((idx - 4) * board->uart_offset); | 124 | offset += ((idx - 4) * board->uart_offset); |
125 | } else if (idx >= 6) { | 125 | } else if (idx >= 6) { |
126 | bar += 3; | 126 | bar += 3; |
127 | offset += ((idx - 6) * board->uart_offset); | 127 | offset += ((idx - 6) * board->uart_offset); |
128 | } | 128 | } |
129 | 129 | ||
130 | return setup_port(priv, port, bar, offset, board->reg_shift); | 130 | return setup_port(priv, port, bar, offset, board->reg_shift); |
131 | } | 131 | } |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * AFAVLAB uses a different mixture of BARs and offsets | 134 | * AFAVLAB uses a different mixture of BARs and offsets |
135 | * Not that ugly ;) -- HW | 135 | * Not that ugly ;) -- HW |
136 | */ | 136 | */ |
137 | static int | 137 | static int |
138 | afavlab_setup(struct serial_private *priv, const struct pciserial_board *board, | 138 | afavlab_setup(struct serial_private *priv, const struct pciserial_board *board, |
139 | struct uart_8250_port *port, int idx) | 139 | struct uart_8250_port *port, int idx) |
140 | { | 140 | { |
141 | unsigned int bar, offset = board->first_offset; | 141 | unsigned int bar, offset = board->first_offset; |
142 | 142 | ||
143 | bar = FL_GET_BASE(board->flags); | 143 | bar = FL_GET_BASE(board->flags); |
144 | if (idx < 4) | 144 | if (idx < 4) |
145 | bar += idx; | 145 | bar += idx; |
146 | else { | 146 | else { |
147 | bar = 4; | 147 | bar = 4; |
148 | offset += (idx - 4) * board->uart_offset; | 148 | offset += (idx - 4) * board->uart_offset; |
149 | } | 149 | } |
150 | 150 | ||
151 | return setup_port(priv, port, bar, offset, board->reg_shift); | 151 | return setup_port(priv, port, bar, offset, board->reg_shift); |
152 | } | 152 | } |
153 | 153 | ||
154 | /* | 154 | /* |
155 | * HP's Remote Management Console. The Diva chip came in several | 155 | * HP's Remote Management Console. The Diva chip came in several |
156 | * different versions. N-class, L2000 and A500 have two Diva chips, each | 156 | * different versions. N-class, L2000 and A500 have two Diva chips, each |
157 | * with 3 UARTs (the third UART on the second chip is unused). Superdome | 157 | * with 3 UARTs (the third UART on the second chip is unused). Superdome |
158 | * and Keystone have one Diva chip with 3 UARTs. Some later machines have | 158 | * and Keystone have one Diva chip with 3 UARTs. Some later machines have |
159 | * one Diva chip, but it has been expanded to 5 UARTs. | 159 | * one Diva chip, but it has been expanded to 5 UARTs. |
160 | */ | 160 | */ |
161 | static int pci_hp_diva_init(struct pci_dev *dev) | 161 | static int pci_hp_diva_init(struct pci_dev *dev) |
162 | { | 162 | { |
163 | int rc = 0; | 163 | int rc = 0; |
164 | 164 | ||
165 | switch (dev->subsystem_device) { | 165 | switch (dev->subsystem_device) { |
166 | case PCI_DEVICE_ID_HP_DIVA_TOSCA1: | 166 | case PCI_DEVICE_ID_HP_DIVA_TOSCA1: |
167 | case PCI_DEVICE_ID_HP_DIVA_HALFDOME: | 167 | case PCI_DEVICE_ID_HP_DIVA_HALFDOME: |
168 | case PCI_DEVICE_ID_HP_DIVA_KEYSTONE: | 168 | case PCI_DEVICE_ID_HP_DIVA_KEYSTONE: |
169 | case PCI_DEVICE_ID_HP_DIVA_EVEREST: | 169 | case PCI_DEVICE_ID_HP_DIVA_EVEREST: |
170 | rc = 3; | 170 | rc = 3; |
171 | break; | 171 | break; |
172 | case PCI_DEVICE_ID_HP_DIVA_TOSCA2: | 172 | case PCI_DEVICE_ID_HP_DIVA_TOSCA2: |
173 | rc = 2; | 173 | rc = 2; |
174 | break; | 174 | break; |
175 | case PCI_DEVICE_ID_HP_DIVA_MAESTRO: | 175 | case PCI_DEVICE_ID_HP_DIVA_MAESTRO: |
176 | rc = 4; | 176 | rc = 4; |
177 | break; | 177 | break; |
178 | case PCI_DEVICE_ID_HP_DIVA_POWERBAR: | 178 | case PCI_DEVICE_ID_HP_DIVA_POWERBAR: |
179 | case PCI_DEVICE_ID_HP_DIVA_HURRICANE: | 179 | case PCI_DEVICE_ID_HP_DIVA_HURRICANE: |
180 | rc = 1; | 180 | rc = 1; |
181 | break; | 181 | break; |
182 | } | 182 | } |
183 | 183 | ||
184 | return rc; | 184 | return rc; |
185 | } | 185 | } |
186 | 186 | ||
187 | /* | 187 | /* |
188 | * HP's Diva chip puts the 4th/5th serial port further out, and | 188 | * HP's Diva chip puts the 4th/5th serial port further out, and |
189 | * some serial ports are supposed to be hidden on certain models. | 189 | * some serial ports are supposed to be hidden on certain models. |
190 | */ | 190 | */ |
191 | static int | 191 | static int |
192 | pci_hp_diva_setup(struct serial_private *priv, | 192 | pci_hp_diva_setup(struct serial_private *priv, |
193 | const struct pciserial_board *board, | 193 | const struct pciserial_board *board, |
194 | struct uart_8250_port *port, int idx) | 194 | struct uart_8250_port *port, int idx) |
195 | { | 195 | { |
196 | unsigned int offset = board->first_offset; | 196 | unsigned int offset = board->first_offset; |
197 | unsigned int bar = FL_GET_BASE(board->flags); | 197 | unsigned int bar = FL_GET_BASE(board->flags); |
198 | 198 | ||
199 | switch (priv->dev->subsystem_device) { | 199 | switch (priv->dev->subsystem_device) { |
200 | case PCI_DEVICE_ID_HP_DIVA_MAESTRO: | 200 | case PCI_DEVICE_ID_HP_DIVA_MAESTRO: |
201 | if (idx == 3) | 201 | if (idx == 3) |
202 | idx++; | 202 | idx++; |
203 | break; | 203 | break; |
204 | case PCI_DEVICE_ID_HP_DIVA_EVEREST: | 204 | case PCI_DEVICE_ID_HP_DIVA_EVEREST: |
205 | if (idx > 0) | 205 | if (idx > 0) |
206 | idx++; | 206 | idx++; |
207 | if (idx > 2) | 207 | if (idx > 2) |
208 | idx++; | 208 | idx++; |
209 | break; | 209 | break; |
210 | } | 210 | } |
211 | if (idx > 2) | 211 | if (idx > 2) |
212 | offset = 0x18; | 212 | offset = 0x18; |
213 | 213 | ||
214 | offset += idx * board->uart_offset; | 214 | offset += idx * board->uart_offset; |
215 | 215 | ||
216 | return setup_port(priv, port, bar, offset, board->reg_shift); | 216 | return setup_port(priv, port, bar, offset, board->reg_shift); |
217 | } | 217 | } |
218 | 218 | ||
219 | /* | 219 | /* |
220 | * Added for EKF Intel i960 serial boards | 220 | * Added for EKF Intel i960 serial boards |
221 | */ | 221 | */ |
222 | static int pci_inteli960ni_init(struct pci_dev *dev) | 222 | static int pci_inteli960ni_init(struct pci_dev *dev) |
223 | { | 223 | { |
224 | u32 oldval; | 224 | u32 oldval; |
225 | 225 | ||
226 | if (!(dev->subsystem_device & 0x1000)) | 226 | if (!(dev->subsystem_device & 0x1000)) |
227 | return -ENODEV; | 227 | return -ENODEV; |
228 | 228 | ||
229 | /* is firmware started? */ | 229 | /* is firmware started? */ |
230 | pci_read_config_dword(dev, 0x44, &oldval); | 230 | pci_read_config_dword(dev, 0x44, &oldval); |
231 | if (oldval == 0x00001000L) { /* RESET value */ | 231 | if (oldval == 0x00001000L) { /* RESET value */ |
232 | dev_dbg(&dev->dev, "Local i960 firmware missing\n"); | 232 | dev_dbg(&dev->dev, "Local i960 firmware missing\n"); |
233 | return -ENODEV; | 233 | return -ENODEV; |
234 | } | 234 | } |
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | 237 | ||
238 | /* | 238 | /* |
239 | * Some PCI serial cards using the PLX 9050 PCI interface chip require | 239 | * Some PCI serial cards using the PLX 9050 PCI interface chip require |
240 | * that the card interrupt be explicitly enabled or disabled. This | 240 | * that the card interrupt be explicitly enabled or disabled. This |
241 | * seems to be mainly needed on card using the PLX which also use I/O | 241 | * seems to be mainly needed on card using the PLX which also use I/O |
242 | * mapped memory. | 242 | * mapped memory. |
243 | */ | 243 | */ |
244 | static int pci_plx9050_init(struct pci_dev *dev) | 244 | static int pci_plx9050_init(struct pci_dev *dev) |
245 | { | 245 | { |
246 | u8 irq_config; | 246 | u8 irq_config; |
247 | void __iomem *p; | 247 | void __iomem *p; |
248 | 248 | ||
249 | if ((pci_resource_flags(dev, 0) & IORESOURCE_MEM) == 0) { | 249 | if ((pci_resource_flags(dev, 0) & IORESOURCE_MEM) == 0) { |
250 | moan_device("no memory in bar 0", dev); | 250 | moan_device("no memory in bar 0", dev); |
251 | return 0; | 251 | return 0; |
252 | } | 252 | } |
253 | 253 | ||
254 | irq_config = 0x41; | 254 | irq_config = 0x41; |
255 | if (dev->vendor == PCI_VENDOR_ID_PANACOM || | 255 | if (dev->vendor == PCI_VENDOR_ID_PANACOM || |
256 | dev->subsystem_vendor == PCI_SUBVENDOR_ID_EXSYS) | 256 | dev->subsystem_vendor == PCI_SUBVENDOR_ID_EXSYS) |
257 | irq_config = 0x43; | 257 | irq_config = 0x43; |
258 | 258 | ||
259 | if ((dev->vendor == PCI_VENDOR_ID_PLX) && | 259 | if ((dev->vendor == PCI_VENDOR_ID_PLX) && |
260 | (dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) | 260 | (dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) |
261 | /* | 261 | /* |
262 | * As the megawolf cards have the int pins active | 262 | * As the megawolf cards have the int pins active |
263 | * high, and have 2 UART chips, both ints must be | 263 | * high, and have 2 UART chips, both ints must be |
264 | * enabled on the 9050. Also, the UARTS are set in | 264 | * enabled on the 9050. Also, the UARTS are set in |
265 | * 16450 mode by default, so we have to enable the | 265 | * 16450 mode by default, so we have to enable the |
266 | * 16C950 'enhanced' mode so that we can use the | 266 | * 16C950 'enhanced' mode so that we can use the |
267 | * deep FIFOs | 267 | * deep FIFOs |
268 | */ | 268 | */ |
269 | irq_config = 0x5b; | 269 | irq_config = 0x5b; |
270 | /* | 270 | /* |
271 | * enable/disable interrupts | 271 | * enable/disable interrupts |
272 | */ | 272 | */ |
273 | p = ioremap_nocache(pci_resource_start(dev, 0), 0x80); | 273 | p = ioremap_nocache(pci_resource_start(dev, 0), 0x80); |
274 | if (p == NULL) | 274 | if (p == NULL) |
275 | return -ENOMEM; | 275 | return -ENOMEM; |
276 | writel(irq_config, p + 0x4c); | 276 | writel(irq_config, p + 0x4c); |
277 | 277 | ||
278 | /* | 278 | /* |
279 | * Read the register back to ensure that it took effect. | 279 | * Read the register back to ensure that it took effect. |
280 | */ | 280 | */ |
281 | readl(p + 0x4c); | 281 | readl(p + 0x4c); |
282 | iounmap(p); | 282 | iounmap(p); |
283 | 283 | ||
284 | return 0; | 284 | return 0; |
285 | } | 285 | } |
286 | 286 | ||
287 | static void pci_plx9050_exit(struct pci_dev *dev) | 287 | static void pci_plx9050_exit(struct pci_dev *dev) |
288 | { | 288 | { |
289 | u8 __iomem *p; | 289 | u8 __iomem *p; |
290 | 290 | ||
291 | if ((pci_resource_flags(dev, 0) & IORESOURCE_MEM) == 0) | 291 | if ((pci_resource_flags(dev, 0) & IORESOURCE_MEM) == 0) |
292 | return; | 292 | return; |
293 | 293 | ||
294 | /* | 294 | /* |
295 | * disable interrupts | 295 | * disable interrupts |
296 | */ | 296 | */ |
297 | p = ioremap_nocache(pci_resource_start(dev, 0), 0x80); | 297 | p = ioremap_nocache(pci_resource_start(dev, 0), 0x80); |
298 | if (p != NULL) { | 298 | if (p != NULL) { |
299 | writel(0, p + 0x4c); | 299 | writel(0, p + 0x4c); |
300 | 300 | ||
301 | /* | 301 | /* |
302 | * Read the register back to ensure that it took effect. | 302 | * Read the register back to ensure that it took effect. |
303 | */ | 303 | */ |
304 | readl(p + 0x4c); | 304 | readl(p + 0x4c); |
305 | iounmap(p); | 305 | iounmap(p); |
306 | } | 306 | } |
307 | } | 307 | } |
308 | 308 | ||
309 | #define NI8420_INT_ENABLE_REG 0x38 | 309 | #define NI8420_INT_ENABLE_REG 0x38 |
310 | #define NI8420_INT_ENABLE_BIT 0x2000 | 310 | #define NI8420_INT_ENABLE_BIT 0x2000 |
311 | 311 | ||
312 | static void pci_ni8420_exit(struct pci_dev *dev) | 312 | static void pci_ni8420_exit(struct pci_dev *dev) |
313 | { | 313 | { |
314 | void __iomem *p; | 314 | void __iomem *p; |
315 | unsigned int bar = 0; | 315 | unsigned int bar = 0; |
316 | 316 | ||
317 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { | 317 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { |
318 | moan_device("no memory in bar", dev); | 318 | moan_device("no memory in bar", dev); |
319 | return; | 319 | return; |
320 | } | 320 | } |
321 | 321 | ||
322 | p = pci_ioremap_bar(dev, bar); | 322 | p = pci_ioremap_bar(dev, bar); |
323 | if (p == NULL) | 323 | if (p == NULL) |
324 | return; | 324 | return; |
325 | 325 | ||
326 | /* Disable the CPU Interrupt */ | 326 | /* Disable the CPU Interrupt */ |
327 | writel(readl(p + NI8420_INT_ENABLE_REG) & ~(NI8420_INT_ENABLE_BIT), | 327 | writel(readl(p + NI8420_INT_ENABLE_REG) & ~(NI8420_INT_ENABLE_BIT), |
328 | p + NI8420_INT_ENABLE_REG); | 328 | p + NI8420_INT_ENABLE_REG); |
329 | iounmap(p); | 329 | iounmap(p); |
330 | } | 330 | } |
331 | 331 | ||
332 | 332 | ||
333 | /* MITE registers */ | 333 | /* MITE registers */ |
334 | #define MITE_IOWBSR1 0xc4 | 334 | #define MITE_IOWBSR1 0xc4 |
335 | #define MITE_IOWCR1 0xf4 | 335 | #define MITE_IOWCR1 0xf4 |
336 | #define MITE_LCIMR1 0x08 | 336 | #define MITE_LCIMR1 0x08 |
337 | #define MITE_LCIMR2 0x10 | 337 | #define MITE_LCIMR2 0x10 |
338 | 338 | ||
339 | #define MITE_LCIMR2_CLR_CPU_IE (1 << 30) | 339 | #define MITE_LCIMR2_CLR_CPU_IE (1 << 30) |
340 | 340 | ||
341 | static void pci_ni8430_exit(struct pci_dev *dev) | 341 | static void pci_ni8430_exit(struct pci_dev *dev) |
342 | { | 342 | { |
343 | void __iomem *p; | 343 | void __iomem *p; |
344 | unsigned int bar = 0; | 344 | unsigned int bar = 0; |
345 | 345 | ||
346 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { | 346 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { |
347 | moan_device("no memory in bar", dev); | 347 | moan_device("no memory in bar", dev); |
348 | return; | 348 | return; |
349 | } | 349 | } |
350 | 350 | ||
351 | p = pci_ioremap_bar(dev, bar); | 351 | p = pci_ioremap_bar(dev, bar); |
352 | if (p == NULL) | 352 | if (p == NULL) |
353 | return; | 353 | return; |
354 | 354 | ||
355 | /* Disable the CPU Interrupt */ | 355 | /* Disable the CPU Interrupt */ |
356 | writel(MITE_LCIMR2_CLR_CPU_IE, p + MITE_LCIMR2); | 356 | writel(MITE_LCIMR2_CLR_CPU_IE, p + MITE_LCIMR2); |
357 | iounmap(p); | 357 | iounmap(p); |
358 | } | 358 | } |
359 | 359 | ||
360 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ | 360 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ |
361 | static int | 361 | static int |
362 | sbs_setup(struct serial_private *priv, const struct pciserial_board *board, | 362 | sbs_setup(struct serial_private *priv, const struct pciserial_board *board, |
363 | struct uart_8250_port *port, int idx) | 363 | struct uart_8250_port *port, int idx) |
364 | { | 364 | { |
365 | unsigned int bar, offset = board->first_offset; | 365 | unsigned int bar, offset = board->first_offset; |
366 | 366 | ||
367 | bar = 0; | 367 | bar = 0; |
368 | 368 | ||
369 | if (idx < 4) { | 369 | if (idx < 4) { |
370 | /* first four channels map to 0, 0x100, 0x200, 0x300 */ | 370 | /* first four channels map to 0, 0x100, 0x200, 0x300 */ |
371 | offset += idx * board->uart_offset; | 371 | offset += idx * board->uart_offset; |
372 | } else if (idx < 8) { | 372 | } else if (idx < 8) { |
373 | /* last four channels map to 0x1000, 0x1100, 0x1200, 0x1300 */ | 373 | /* last four channels map to 0x1000, 0x1100, 0x1200, 0x1300 */ |
374 | offset += idx * board->uart_offset + 0xC00; | 374 | offset += idx * board->uart_offset + 0xC00; |
375 | } else /* we have only 8 ports on PMC-OCTALPRO */ | 375 | } else /* we have only 8 ports on PMC-OCTALPRO */ |
376 | return 1; | 376 | return 1; |
377 | 377 | ||
378 | return setup_port(priv, port, bar, offset, board->reg_shift); | 378 | return setup_port(priv, port, bar, offset, board->reg_shift); |
379 | } | 379 | } |
380 | 380 | ||
381 | /* | 381 | /* |
382 | * This does initialization for PMC OCTALPRO cards: | 382 | * This does initialization for PMC OCTALPRO cards: |
383 | * maps the device memory, resets the UARTs (needed, bc | 383 | * maps the device memory, resets the UARTs (needed, bc |
384 | * if the module is removed and inserted again, the card | 384 | * if the module is removed and inserted again, the card |
385 | * is in the sleep mode) and enables global interrupt. | 385 | * is in the sleep mode) and enables global interrupt. |
386 | */ | 386 | */ |
387 | 387 | ||
388 | /* global control register offset for SBS PMC-OctalPro */ | 388 | /* global control register offset for SBS PMC-OctalPro */ |
389 | #define OCT_REG_CR_OFF 0x500 | 389 | #define OCT_REG_CR_OFF 0x500 |
390 | 390 | ||
391 | static int sbs_init(struct pci_dev *dev) | 391 | static int sbs_init(struct pci_dev *dev) |
392 | { | 392 | { |
393 | u8 __iomem *p; | 393 | u8 __iomem *p; |
394 | 394 | ||
395 | p = pci_ioremap_bar(dev, 0); | 395 | p = pci_ioremap_bar(dev, 0); |
396 | 396 | ||
397 | if (p == NULL) | 397 | if (p == NULL) |
398 | return -ENOMEM; | 398 | return -ENOMEM; |
399 | /* Set bit-4 Control Register (UART RESET) in to reset the uarts */ | 399 | /* Set bit-4 Control Register (UART RESET) in to reset the uarts */ |
400 | writeb(0x10, p + OCT_REG_CR_OFF); | 400 | writeb(0x10, p + OCT_REG_CR_OFF); |
401 | udelay(50); | 401 | udelay(50); |
402 | writeb(0x0, p + OCT_REG_CR_OFF); | 402 | writeb(0x0, p + OCT_REG_CR_OFF); |
403 | 403 | ||
404 | /* Set bit-2 (INTENABLE) of Control Register */ | 404 | /* Set bit-2 (INTENABLE) of Control Register */ |
405 | writeb(0x4, p + OCT_REG_CR_OFF); | 405 | writeb(0x4, p + OCT_REG_CR_OFF); |
406 | iounmap(p); | 406 | iounmap(p); |
407 | 407 | ||
408 | return 0; | 408 | return 0; |
409 | } | 409 | } |
410 | 410 | ||
411 | /* | 411 | /* |
412 | * Disables the global interrupt of PMC-OctalPro | 412 | * Disables the global interrupt of PMC-OctalPro |
413 | */ | 413 | */ |
414 | 414 | ||
415 | static void sbs_exit(struct pci_dev *dev) | 415 | static void sbs_exit(struct pci_dev *dev) |
416 | { | 416 | { |
417 | u8 __iomem *p; | 417 | u8 __iomem *p; |
418 | 418 | ||
419 | p = pci_ioremap_bar(dev, 0); | 419 | p = pci_ioremap_bar(dev, 0); |
420 | /* FIXME: What if resource_len < OCT_REG_CR_OFF */ | 420 | /* FIXME: What if resource_len < OCT_REG_CR_OFF */ |
421 | if (p != NULL) | 421 | if (p != NULL) |
422 | writeb(0, p + OCT_REG_CR_OFF); | 422 | writeb(0, p + OCT_REG_CR_OFF); |
423 | iounmap(p); | 423 | iounmap(p); |
424 | } | 424 | } |
425 | 425 | ||
426 | /* | 426 | /* |
427 | * SIIG serial cards have an PCI interface chip which also controls | 427 | * SIIG serial cards have an PCI interface chip which also controls |
428 | * the UART clocking frequency. Each UART can be clocked independently | 428 | * the UART clocking frequency. Each UART can be clocked independently |
429 | * (except cards equipped with 4 UARTs) and initial clocking settings | 429 | * (except cards equipped with 4 UARTs) and initial clocking settings |
430 | * are stored in the EEPROM chip. It can cause problems because this | 430 | * are stored in the EEPROM chip. It can cause problems because this |
431 | * version of serial driver doesn't support differently clocked UART's | 431 | * version of serial driver doesn't support differently clocked UART's |
432 | * on single PCI card. To prevent this, initialization functions set | 432 | * on single PCI card. To prevent this, initialization functions set |
433 | * high frequency clocking for all UART's on given card. It is safe (I | 433 | * high frequency clocking for all UART's on given card. It is safe (I |
434 | * hope) because it doesn't touch EEPROM settings to prevent conflicts | 434 | * hope) because it doesn't touch EEPROM settings to prevent conflicts |
435 | * with other OSes (like M$ DOS). | 435 | * with other OSes (like M$ DOS). |
436 | * | 436 | * |
437 | * SIIG support added by Andrey Panin <pazke@donpac.ru>, 10/1999 | 437 | * SIIG support added by Andrey Panin <pazke@donpac.ru>, 10/1999 |
438 | * | 438 | * |
439 | * There is two family of SIIG serial cards with different PCI | 439 | * There is two family of SIIG serial cards with different PCI |
440 | * interface chip and different configuration methods: | 440 | * interface chip and different configuration methods: |
441 | * - 10x cards have control registers in IO and/or memory space; | 441 | * - 10x cards have control registers in IO and/or memory space; |
442 | * - 20x cards have control registers in standard PCI configuration space. | 442 | * - 20x cards have control registers in standard PCI configuration space. |
443 | * | 443 | * |
444 | * Note: all 10x cards have PCI device ids 0x10.. | 444 | * Note: all 10x cards have PCI device ids 0x10.. |
445 | * all 20x cards have PCI device ids 0x20.. | 445 | * all 20x cards have PCI device ids 0x20.. |
446 | * | 446 | * |
447 | * There are also Quartet Serial cards which use Oxford Semiconductor | 447 | * There are also Quartet Serial cards which use Oxford Semiconductor |
448 | * 16954 quad UART PCI chip clocked by 18.432 MHz quartz. | 448 | * 16954 quad UART PCI chip clocked by 18.432 MHz quartz. |
449 | * | 449 | * |
450 | * Note: some SIIG cards are probed by the parport_serial object. | 450 | * Note: some SIIG cards are probed by the parport_serial object. |
451 | */ | 451 | */ |
452 | 452 | ||
453 | #define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc) | 453 | #define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc) |
454 | #define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8) | 454 | #define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8) |
455 | 455 | ||
456 | static int pci_siig10x_init(struct pci_dev *dev) | 456 | static int pci_siig10x_init(struct pci_dev *dev) |
457 | { | 457 | { |
458 | u16 data; | 458 | u16 data; |
459 | void __iomem *p; | 459 | void __iomem *p; |
460 | 460 | ||
461 | switch (dev->device & 0xfff8) { | 461 | switch (dev->device & 0xfff8) { |
462 | case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */ | 462 | case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */ |
463 | data = 0xffdf; | 463 | data = 0xffdf; |
464 | break; | 464 | break; |
465 | case PCI_DEVICE_ID_SIIG_2S_10x: /* 2S, 2S1P */ | 465 | case PCI_DEVICE_ID_SIIG_2S_10x: /* 2S, 2S1P */ |
466 | data = 0xf7ff; | 466 | data = 0xf7ff; |
467 | break; | 467 | break; |
468 | default: /* 1S1P, 4S */ | 468 | default: /* 1S1P, 4S */ |
469 | data = 0xfffb; | 469 | data = 0xfffb; |
470 | break; | 470 | break; |
471 | } | 471 | } |
472 | 472 | ||
473 | p = ioremap_nocache(pci_resource_start(dev, 0), 0x80); | 473 | p = ioremap_nocache(pci_resource_start(dev, 0), 0x80); |
474 | if (p == NULL) | 474 | if (p == NULL) |
475 | return -ENOMEM; | 475 | return -ENOMEM; |
476 | 476 | ||
477 | writew(readw(p + 0x28) & data, p + 0x28); | 477 | writew(readw(p + 0x28) & data, p + 0x28); |
478 | readw(p + 0x28); | 478 | readw(p + 0x28); |
479 | iounmap(p); | 479 | iounmap(p); |
480 | return 0; | 480 | return 0; |
481 | } | 481 | } |
482 | 482 | ||
483 | #define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc) | 483 | #define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc) |
484 | #define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc) | 484 | #define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc) |
485 | 485 | ||
486 | static int pci_siig20x_init(struct pci_dev *dev) | 486 | static int pci_siig20x_init(struct pci_dev *dev) |
487 | { | 487 | { |
488 | u8 data; | 488 | u8 data; |
489 | 489 | ||
490 | /* Change clock frequency for the first UART. */ | 490 | /* Change clock frequency for the first UART. */ |
491 | pci_read_config_byte(dev, 0x6f, &data); | 491 | pci_read_config_byte(dev, 0x6f, &data); |
492 | pci_write_config_byte(dev, 0x6f, data & 0xef); | 492 | pci_write_config_byte(dev, 0x6f, data & 0xef); |
493 | 493 | ||
494 | /* If this card has 2 UART, we have to do the same with second UART. */ | 494 | /* If this card has 2 UART, we have to do the same with second UART. */ |
495 | if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) || | 495 | if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) || |
496 | ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) { | 496 | ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) { |
497 | pci_read_config_byte(dev, 0x73, &data); | 497 | pci_read_config_byte(dev, 0x73, &data); |
498 | pci_write_config_byte(dev, 0x73, data & 0xef); | 498 | pci_write_config_byte(dev, 0x73, data & 0xef); |
499 | } | 499 | } |
500 | return 0; | 500 | return 0; |
501 | } | 501 | } |
502 | 502 | ||
503 | static int pci_siig_init(struct pci_dev *dev) | 503 | static int pci_siig_init(struct pci_dev *dev) |
504 | { | 504 | { |
505 | unsigned int type = dev->device & 0xff00; | 505 | unsigned int type = dev->device & 0xff00; |
506 | 506 | ||
507 | if (type == 0x1000) | 507 | if (type == 0x1000) |
508 | return pci_siig10x_init(dev); | 508 | return pci_siig10x_init(dev); |
509 | else if (type == 0x2000) | 509 | else if (type == 0x2000) |
510 | return pci_siig20x_init(dev); | 510 | return pci_siig20x_init(dev); |
511 | 511 | ||
512 | moan_device("Unknown SIIG card", dev); | 512 | moan_device("Unknown SIIG card", dev); |
513 | return -ENODEV; | 513 | return -ENODEV; |
514 | } | 514 | } |
515 | 515 | ||
516 | static int pci_siig_setup(struct serial_private *priv, | 516 | static int pci_siig_setup(struct serial_private *priv, |
517 | const struct pciserial_board *board, | 517 | const struct pciserial_board *board, |
518 | struct uart_8250_port *port, int idx) | 518 | struct uart_8250_port *port, int idx) |
519 | { | 519 | { |
520 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; | 520 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; |
521 | 521 | ||
522 | if (idx > 3) { | 522 | if (idx > 3) { |
523 | bar = 4; | 523 | bar = 4; |
524 | offset = (idx - 4) * 8; | 524 | offset = (idx - 4) * 8; |
525 | } | 525 | } |
526 | 526 | ||
527 | return setup_port(priv, port, bar, offset, 0); | 527 | return setup_port(priv, port, bar, offset, 0); |
528 | } | 528 | } |
529 | 529 | ||
530 | /* | 530 | /* |
531 | * Timedia has an explosion of boards, and to avoid the PCI table from | 531 | * Timedia has an explosion of boards, and to avoid the PCI table from |
532 | * growing *huge*, we use this function to collapse some 70 entries | 532 | * growing *huge*, we use this function to collapse some 70 entries |
533 | * in the PCI table into one, for sanity's and compactness's sake. | 533 | * in the PCI table into one, for sanity's and compactness's sake. |
534 | */ | 534 | */ |
535 | static const unsigned short timedia_single_port[] = { | 535 | static const unsigned short timedia_single_port[] = { |
536 | 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 | 536 | 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 |
537 | }; | 537 | }; |
538 | 538 | ||
539 | static const unsigned short timedia_dual_port[] = { | 539 | static const unsigned short timedia_dual_port[] = { |
540 | 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085, | 540 | 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085, |
541 | 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, | 541 | 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, |
542 | 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, | 542 | 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, |
543 | 0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079, | 543 | 0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079, |
544 | 0xD079, 0 | 544 | 0xD079, 0 |
545 | }; | 545 | }; |
546 | 546 | ||
547 | static const unsigned short timedia_quad_port[] = { | 547 | static const unsigned short timedia_quad_port[] = { |
548 | 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, | 548 | 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, |
549 | 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, | 549 | 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, |
550 | 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056, | 550 | 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056, |
551 | 0xB157, 0 | 551 | 0xB157, 0 |
552 | }; | 552 | }; |
553 | 553 | ||
554 | static const unsigned short timedia_eight_port[] = { | 554 | static const unsigned short timedia_eight_port[] = { |
555 | 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, | 555 | 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, |
556 | 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 | 556 | 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 |
557 | }; | 557 | }; |
558 | 558 | ||
559 | static const struct timedia_struct { | 559 | static const struct timedia_struct { |
560 | int num; | 560 | int num; |
561 | const unsigned short *ids; | 561 | const unsigned short *ids; |
562 | } timedia_data[] = { | 562 | } timedia_data[] = { |
563 | { 1, timedia_single_port }, | 563 | { 1, timedia_single_port }, |
564 | { 2, timedia_dual_port }, | 564 | { 2, timedia_dual_port }, |
565 | { 4, timedia_quad_port }, | 565 | { 4, timedia_quad_port }, |
566 | { 8, timedia_eight_port } | 566 | { 8, timedia_eight_port } |
567 | }; | 567 | }; |
568 | 568 | ||
569 | /* | 569 | /* |
570 | * There are nearly 70 different Timedia/SUNIX PCI serial devices. Instead of | 570 | * There are nearly 70 different Timedia/SUNIX PCI serial devices. Instead of |
571 | * listing them individually, this driver merely grabs them all with | 571 | * listing them individually, this driver merely grabs them all with |
572 | * PCI_ANY_ID. Some of these devices, however, also feature a parallel port, | 572 | * PCI_ANY_ID. Some of these devices, however, also feature a parallel port, |
573 | * and should be left free to be claimed by parport_serial instead. | 573 | * and should be left free to be claimed by parport_serial instead. |
574 | */ | 574 | */ |
575 | static int pci_timedia_probe(struct pci_dev *dev) | 575 | static int pci_timedia_probe(struct pci_dev *dev) |
576 | { | 576 | { |
577 | /* | 577 | /* |
578 | * Check the third digit of the subdevice ID | 578 | * Check the third digit of the subdevice ID |
579 | * (0,2,3,5,6: serial only -- 7,8,9: serial + parallel) | 579 | * (0,2,3,5,6: serial only -- 7,8,9: serial + parallel) |
580 | */ | 580 | */ |
581 | if ((dev->subsystem_device & 0x00f0) >= 0x70) { | 581 | if ((dev->subsystem_device & 0x00f0) >= 0x70) { |
582 | dev_info(&dev->dev, | 582 | dev_info(&dev->dev, |
583 | "ignoring Timedia subdevice %04x for parport_serial\n", | 583 | "ignoring Timedia subdevice %04x for parport_serial\n", |
584 | dev->subsystem_device); | 584 | dev->subsystem_device); |
585 | return -ENODEV; | 585 | return -ENODEV; |
586 | } | 586 | } |
587 | 587 | ||
588 | return 0; | 588 | return 0; |
589 | } | 589 | } |
590 | 590 | ||
591 | static int pci_timedia_init(struct pci_dev *dev) | 591 | static int pci_timedia_init(struct pci_dev *dev) |
592 | { | 592 | { |
593 | const unsigned short *ids; | 593 | const unsigned short *ids; |
594 | int i, j; | 594 | int i, j; |
595 | 595 | ||
596 | for (i = 0; i < ARRAY_SIZE(timedia_data); i++) { | 596 | for (i = 0; i < ARRAY_SIZE(timedia_data); i++) { |
597 | ids = timedia_data[i].ids; | 597 | ids = timedia_data[i].ids; |
598 | for (j = 0; ids[j]; j++) | 598 | for (j = 0; ids[j]; j++) |
599 | if (dev->subsystem_device == ids[j]) | 599 | if (dev->subsystem_device == ids[j]) |
600 | return timedia_data[i].num; | 600 | return timedia_data[i].num; |
601 | } | 601 | } |
602 | return 0; | 602 | return 0; |
603 | } | 603 | } |
604 | 604 | ||
605 | /* | 605 | /* |
606 | * Timedia/SUNIX uses a mixture of BARs and offsets | 606 | * Timedia/SUNIX uses a mixture of BARs and offsets |
607 | * Ugh, this is ugly as all hell --- TYT | 607 | * Ugh, this is ugly as all hell --- TYT |
608 | */ | 608 | */ |
609 | static int | 609 | static int |
610 | pci_timedia_setup(struct serial_private *priv, | 610 | pci_timedia_setup(struct serial_private *priv, |
611 | const struct pciserial_board *board, | 611 | const struct pciserial_board *board, |
612 | struct uart_8250_port *port, int idx) | 612 | struct uart_8250_port *port, int idx) |
613 | { | 613 | { |
614 | unsigned int bar = 0, offset = board->first_offset; | 614 | unsigned int bar = 0, offset = board->first_offset; |
615 | 615 | ||
616 | switch (idx) { | 616 | switch (idx) { |
617 | case 0: | 617 | case 0: |
618 | bar = 0; | 618 | bar = 0; |
619 | break; | 619 | break; |
620 | case 1: | 620 | case 1: |
621 | offset = board->uart_offset; | 621 | offset = board->uart_offset; |
622 | bar = 0; | 622 | bar = 0; |
623 | break; | 623 | break; |
624 | case 2: | 624 | case 2: |
625 | bar = 1; | 625 | bar = 1; |
626 | break; | 626 | break; |
627 | case 3: | 627 | case 3: |
628 | offset = board->uart_offset; | 628 | offset = board->uart_offset; |
629 | /* FALLTHROUGH */ | 629 | /* FALLTHROUGH */ |
630 | case 4: /* BAR 2 */ | 630 | case 4: /* BAR 2 */ |
631 | case 5: /* BAR 3 */ | 631 | case 5: /* BAR 3 */ |
632 | case 6: /* BAR 4 */ | 632 | case 6: /* BAR 4 */ |
633 | case 7: /* BAR 5 */ | 633 | case 7: /* BAR 5 */ |
634 | bar = idx - 2; | 634 | bar = idx - 2; |
635 | } | 635 | } |
636 | 636 | ||
637 | return setup_port(priv, port, bar, offset, board->reg_shift); | 637 | return setup_port(priv, port, bar, offset, board->reg_shift); |
638 | } | 638 | } |
639 | 639 | ||
640 | /* | 640 | /* |
641 | * Some Titan cards are also a little weird | 641 | * Some Titan cards are also a little weird |
642 | */ | 642 | */ |
643 | static int | 643 | static int |
644 | titan_400l_800l_setup(struct serial_private *priv, | 644 | titan_400l_800l_setup(struct serial_private *priv, |
645 | const struct pciserial_board *board, | 645 | const struct pciserial_board *board, |
646 | struct uart_8250_port *port, int idx) | 646 | struct uart_8250_port *port, int idx) |
647 | { | 647 | { |
648 | unsigned int bar, offset = board->first_offset; | 648 | unsigned int bar, offset = board->first_offset; |
649 | 649 | ||
650 | switch (idx) { | 650 | switch (idx) { |
651 | case 0: | 651 | case 0: |
652 | bar = 1; | 652 | bar = 1; |
653 | break; | 653 | break; |
654 | case 1: | 654 | case 1: |
655 | bar = 2; | 655 | bar = 2; |
656 | break; | 656 | break; |
657 | default: | 657 | default: |
658 | bar = 4; | 658 | bar = 4; |
659 | offset = (idx - 2) * board->uart_offset; | 659 | offset = (idx - 2) * board->uart_offset; |
660 | } | 660 | } |
661 | 661 | ||
662 | return setup_port(priv, port, bar, offset, board->reg_shift); | 662 | return setup_port(priv, port, bar, offset, board->reg_shift); |
663 | } | 663 | } |
664 | 664 | ||
665 | static int pci_xircom_init(struct pci_dev *dev) | 665 | static int pci_xircom_init(struct pci_dev *dev) |
666 | { | 666 | { |
667 | msleep(100); | 667 | msleep(100); |
668 | return 0; | 668 | return 0; |
669 | } | 669 | } |
670 | 670 | ||
671 | static int pci_ni8420_init(struct pci_dev *dev) | 671 | static int pci_ni8420_init(struct pci_dev *dev) |
672 | { | 672 | { |
673 | void __iomem *p; | 673 | void __iomem *p; |
674 | unsigned int bar = 0; | 674 | unsigned int bar = 0; |
675 | 675 | ||
676 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { | 676 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { |
677 | moan_device("no memory in bar", dev); | 677 | moan_device("no memory in bar", dev); |
678 | return 0; | 678 | return 0; |
679 | } | 679 | } |
680 | 680 | ||
681 | p = pci_ioremap_bar(dev, bar); | 681 | p = pci_ioremap_bar(dev, bar); |
682 | if (p == NULL) | 682 | if (p == NULL) |
683 | return -ENOMEM; | 683 | return -ENOMEM; |
684 | 684 | ||
685 | /* Enable CPU Interrupt */ | 685 | /* Enable CPU Interrupt */ |
686 | writel(readl(p + NI8420_INT_ENABLE_REG) | NI8420_INT_ENABLE_BIT, | 686 | writel(readl(p + NI8420_INT_ENABLE_REG) | NI8420_INT_ENABLE_BIT, |
687 | p + NI8420_INT_ENABLE_REG); | 687 | p + NI8420_INT_ENABLE_REG); |
688 | 688 | ||
689 | iounmap(p); | 689 | iounmap(p); |
690 | return 0; | 690 | return 0; |
691 | } | 691 | } |
692 | 692 | ||
693 | #define MITE_IOWBSR1_WSIZE 0xa | 693 | #define MITE_IOWBSR1_WSIZE 0xa |
694 | #define MITE_IOWBSR1_WIN_OFFSET 0x800 | 694 | #define MITE_IOWBSR1_WIN_OFFSET 0x800 |
695 | #define MITE_IOWBSR1_WENAB (1 << 7) | 695 | #define MITE_IOWBSR1_WENAB (1 << 7) |
696 | #define MITE_LCIMR1_IO_IE_0 (1 << 24) | 696 | #define MITE_LCIMR1_IO_IE_0 (1 << 24) |
697 | #define MITE_LCIMR2_SET_CPU_IE (1 << 31) | 697 | #define MITE_LCIMR2_SET_CPU_IE (1 << 31) |
698 | #define MITE_IOWCR1_RAMSEL_MASK 0xfffffffe | 698 | #define MITE_IOWCR1_RAMSEL_MASK 0xfffffffe |
699 | 699 | ||
700 | static int pci_ni8430_init(struct pci_dev *dev) | 700 | static int pci_ni8430_init(struct pci_dev *dev) |
701 | { | 701 | { |
702 | void __iomem *p; | 702 | void __iomem *p; |
703 | struct pci_bus_region region; | 703 | struct pci_bus_region region; |
704 | u32 device_window; | 704 | u32 device_window; |
705 | unsigned int bar = 0; | 705 | unsigned int bar = 0; |
706 | 706 | ||
707 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { | 707 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { |
708 | moan_device("no memory in bar", dev); | 708 | moan_device("no memory in bar", dev); |
709 | return 0; | 709 | return 0; |
710 | } | 710 | } |
711 | 711 | ||
712 | p = pci_ioremap_bar(dev, bar); | 712 | p = pci_ioremap_bar(dev, bar); |
713 | if (p == NULL) | 713 | if (p == NULL) |
714 | return -ENOMEM; | 714 | return -ENOMEM; |
715 | 715 | ||
716 | /* | 716 | /* |
717 | * Set device window address and size in BAR0, while acknowledging that | 717 | * Set device window address and size in BAR0, while acknowledging that |
718 | * the resource structure may contain a translated address that differs | 718 | * the resource structure may contain a translated address that differs |
719 | * from the address the device responds to. | 719 | * from the address the device responds to. |
720 | */ | 720 | */ |
721 | pcibios_resource_to_bus(dev->bus, ®ion, &dev->resource[bar]); | 721 | pcibios_resource_to_bus(dev->bus, ®ion, &dev->resource[bar]); |
722 | device_window = ((region.start + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) | 722 | device_window = ((region.start + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) |
723 | | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE; | 723 | | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE; |
724 | writel(device_window, p + MITE_IOWBSR1); | 724 | writel(device_window, p + MITE_IOWBSR1); |
725 | 725 | ||
726 | /* Set window access to go to RAMSEL IO address space */ | 726 | /* Set window access to go to RAMSEL IO address space */ |
727 | writel((readl(p + MITE_IOWCR1) & MITE_IOWCR1_RAMSEL_MASK), | 727 | writel((readl(p + MITE_IOWCR1) & MITE_IOWCR1_RAMSEL_MASK), |
728 | p + MITE_IOWCR1); | 728 | p + MITE_IOWCR1); |
729 | 729 | ||
730 | /* Enable IO Bus Interrupt 0 */ | 730 | /* Enable IO Bus Interrupt 0 */ |
731 | writel(MITE_LCIMR1_IO_IE_0, p + MITE_LCIMR1); | 731 | writel(MITE_LCIMR1_IO_IE_0, p + MITE_LCIMR1); |
732 | 732 | ||
733 | /* Enable CPU Interrupt */ | 733 | /* Enable CPU Interrupt */ |
734 | writel(MITE_LCIMR2_SET_CPU_IE, p + MITE_LCIMR2); | 734 | writel(MITE_LCIMR2_SET_CPU_IE, p + MITE_LCIMR2); |
735 | 735 | ||
736 | iounmap(p); | 736 | iounmap(p); |
737 | return 0; | 737 | return 0; |
738 | } | 738 | } |
739 | 739 | ||
740 | /* UART Port Control Register */ | 740 | /* UART Port Control Register */ |
741 | #define NI8430_PORTCON 0x0f | 741 | #define NI8430_PORTCON 0x0f |
742 | #define NI8430_PORTCON_TXVR_ENABLE (1 << 3) | 742 | #define NI8430_PORTCON_TXVR_ENABLE (1 << 3) |
743 | 743 | ||
744 | static int | 744 | static int |
745 | pci_ni8430_setup(struct serial_private *priv, | 745 | pci_ni8430_setup(struct serial_private *priv, |
746 | const struct pciserial_board *board, | 746 | const struct pciserial_board *board, |
747 | struct uart_8250_port *port, int idx) | 747 | struct uart_8250_port *port, int idx) |
748 | { | 748 | { |
749 | struct pci_dev *dev = priv->dev; | 749 | struct pci_dev *dev = priv->dev; |
750 | void __iomem *p; | 750 | void __iomem *p; |
751 | unsigned int bar, offset = board->first_offset; | 751 | unsigned int bar, offset = board->first_offset; |
752 | 752 | ||
753 | if (idx >= board->num_ports) | 753 | if (idx >= board->num_ports) |
754 | return 1; | 754 | return 1; |
755 | 755 | ||
756 | bar = FL_GET_BASE(board->flags); | 756 | bar = FL_GET_BASE(board->flags); |
757 | offset += idx * board->uart_offset; | 757 | offset += idx * board->uart_offset; |
758 | 758 | ||
759 | p = pci_ioremap_bar(dev, bar); | 759 | p = pci_ioremap_bar(dev, bar); |
760 | if (!p) | 760 | if (!p) |
761 | return -ENOMEM; | 761 | return -ENOMEM; |
762 | 762 | ||
763 | /* enable the transceiver */ | 763 | /* enable the transceiver */ |
764 | writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE, | 764 | writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE, |
765 | p + offset + NI8430_PORTCON); | 765 | p + offset + NI8430_PORTCON); |
766 | 766 | ||
767 | iounmap(p); | 767 | iounmap(p); |
768 | 768 | ||
769 | return setup_port(priv, port, bar, offset, board->reg_shift); | 769 | return setup_port(priv, port, bar, offset, board->reg_shift); |
770 | } | 770 | } |
771 | 771 | ||
772 | static int pci_netmos_9900_setup(struct serial_private *priv, | 772 | static int pci_netmos_9900_setup(struct serial_private *priv, |
773 | const struct pciserial_board *board, | 773 | const struct pciserial_board *board, |
774 | struct uart_8250_port *port, int idx) | 774 | struct uart_8250_port *port, int idx) |
775 | { | 775 | { |
776 | unsigned int bar; | 776 | unsigned int bar; |
777 | 777 | ||
778 | if ((priv->dev->device != PCI_DEVICE_ID_NETMOS_9865) && | 778 | if ((priv->dev->device != PCI_DEVICE_ID_NETMOS_9865) && |
779 | (priv->dev->subsystem_device & 0xff00) == 0x3000) { | 779 | (priv->dev->subsystem_device & 0xff00) == 0x3000) { |
780 | /* netmos apparently orders BARs by datasheet layout, so serial | 780 | /* netmos apparently orders BARs by datasheet layout, so serial |
781 | * ports get BARs 0 and 3 (or 1 and 4 for memmapped) | 781 | * ports get BARs 0 and 3 (or 1 and 4 for memmapped) |
782 | */ | 782 | */ |
783 | bar = 3 * idx; | 783 | bar = 3 * idx; |
784 | 784 | ||
785 | return setup_port(priv, port, bar, 0, board->reg_shift); | 785 | return setup_port(priv, port, bar, 0, board->reg_shift); |
786 | } else { | 786 | } else { |
787 | return pci_default_setup(priv, board, port, idx); | 787 | return pci_default_setup(priv, board, port, idx); |
788 | } | 788 | } |
789 | } | 789 | } |
790 | 790 | ||
791 | /* the 99xx series comes with a range of device IDs and a variety | 791 | /* the 99xx series comes with a range of device IDs and a variety |
792 | * of capabilities: | 792 | * of capabilities: |
793 | * | 793 | * |
794 | * 9900 has varying capabilities and can cascade to sub-controllers | 794 | * 9900 has varying capabilities and can cascade to sub-controllers |
795 | * (cascading should be purely internal) | 795 | * (cascading should be purely internal) |
796 | * 9904 is hardwired with 4 serial ports | 796 | * 9904 is hardwired with 4 serial ports |
797 | * 9912 and 9922 are hardwired with 2 serial ports | 797 | * 9912 and 9922 are hardwired with 2 serial ports |
798 | */ | 798 | */ |
799 | static int pci_netmos_9900_numports(struct pci_dev *dev) | 799 | static int pci_netmos_9900_numports(struct pci_dev *dev) |
800 | { | 800 | { |
801 | unsigned int c = dev->class; | 801 | unsigned int c = dev->class; |
802 | unsigned int pi; | 802 | unsigned int pi; |
803 | unsigned short sub_serports; | 803 | unsigned short sub_serports; |
804 | 804 | ||
805 | pi = (c & 0xff); | 805 | pi = (c & 0xff); |
806 | 806 | ||
807 | if (pi == 2) { | 807 | if (pi == 2) { |
808 | return 1; | 808 | return 1; |
809 | } else if ((pi == 0) && | 809 | } else if ((pi == 0) && |
810 | (dev->device == PCI_DEVICE_ID_NETMOS_9900)) { | 810 | (dev->device == PCI_DEVICE_ID_NETMOS_9900)) { |
811 | /* two possibilities: 0x30ps encodes number of parallel and | 811 | /* two possibilities: 0x30ps encodes number of parallel and |
812 | * serial ports, or 0x1000 indicates *something*. This is not | 812 | * serial ports, or 0x1000 indicates *something*. This is not |
813 | * immediately obvious, since the 2s1p+4s configuration seems | 813 | * immediately obvious, since the 2s1p+4s configuration seems |
814 | * to offer all functionality on functions 0..2, while still | 814 | * to offer all functionality on functions 0..2, while still |
815 | * advertising the same function 3 as the 4s+2s1p config. | 815 | * advertising the same function 3 as the 4s+2s1p config. |
816 | */ | 816 | */ |
817 | sub_serports = dev->subsystem_device & 0xf; | 817 | sub_serports = dev->subsystem_device & 0xf; |
818 | if (sub_serports > 0) { | 818 | if (sub_serports > 0) { |
819 | return sub_serports; | 819 | return sub_serports; |
820 | } else { | 820 | } else { |
821 | dev_err(&dev->dev, "NetMos/Mostech serial driver ignoring port on ambiguous config.\n"); | 821 | dev_err(&dev->dev, "NetMos/Mostech serial driver ignoring port on ambiguous config.\n"); |
822 | return 0; | 822 | return 0; |
823 | } | 823 | } |
824 | } | 824 | } |
825 | 825 | ||
826 | moan_device("unknown NetMos/Mostech program interface", dev); | 826 | moan_device("unknown NetMos/Mostech program interface", dev); |
827 | return 0; | 827 | return 0; |
828 | } | 828 | } |
829 | 829 | ||
830 | static int pci_netmos_init(struct pci_dev *dev) | 830 | static int pci_netmos_init(struct pci_dev *dev) |
831 | { | 831 | { |
832 | /* subdevice 0x00PS means <P> parallel, <S> serial */ | 832 | /* subdevice 0x00PS means <P> parallel, <S> serial */ |
833 | unsigned int num_serial = dev->subsystem_device & 0xf; | 833 | unsigned int num_serial = dev->subsystem_device & 0xf; |
834 | 834 | ||
835 | if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) || | 835 | if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) || |
836 | (dev->device == PCI_DEVICE_ID_NETMOS_9865)) | 836 | (dev->device == PCI_DEVICE_ID_NETMOS_9865)) |
837 | return 0; | 837 | return 0; |
838 | 838 | ||
839 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && | 839 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && |
840 | dev->subsystem_device == 0x0299) | 840 | dev->subsystem_device == 0x0299) |
841 | return 0; | 841 | return 0; |
842 | 842 | ||
843 | switch (dev->device) { /* FALLTHROUGH on all */ | 843 | switch (dev->device) { /* FALLTHROUGH on all */ |
844 | case PCI_DEVICE_ID_NETMOS_9904: | 844 | case PCI_DEVICE_ID_NETMOS_9904: |
845 | case PCI_DEVICE_ID_NETMOS_9912: | 845 | case PCI_DEVICE_ID_NETMOS_9912: |
846 | case PCI_DEVICE_ID_NETMOS_9922: | 846 | case PCI_DEVICE_ID_NETMOS_9922: |
847 | case PCI_DEVICE_ID_NETMOS_9900: | 847 | case PCI_DEVICE_ID_NETMOS_9900: |
848 | num_serial = pci_netmos_9900_numports(dev); | 848 | num_serial = pci_netmos_9900_numports(dev); |
849 | break; | 849 | break; |
850 | 850 | ||
851 | default: | 851 | default: |
852 | if (num_serial == 0 ) { | 852 | if (num_serial == 0 ) { |
853 | moan_device("unknown NetMos/Mostech device", dev); | 853 | moan_device("unknown NetMos/Mostech device", dev); |
854 | } | 854 | } |
855 | } | 855 | } |
856 | 856 | ||
857 | if (num_serial == 0) | 857 | if (num_serial == 0) |
858 | return -ENODEV; | 858 | return -ENODEV; |
859 | 859 | ||
860 | return num_serial; | 860 | return num_serial; |
861 | } | 861 | } |
862 | 862 | ||
863 | /* | 863 | /* |
864 | * These chips are available with optionally one parallel port and up to | 864 | * These chips are available with optionally one parallel port and up to |
865 | * two serial ports. Unfortunately they all have the same product id. | 865 | * two serial ports. Unfortunately they all have the same product id. |
866 | * | 866 | * |
867 | * Basic configuration is done over a region of 32 I/O ports. The base | 867 | * Basic configuration is done over a region of 32 I/O ports. The base |
868 | * ioport is called INTA or INTC, depending on docs/other drivers. | 868 | * ioport is called INTA or INTC, depending on docs/other drivers. |
869 | * | 869 | * |
870 | * The region of the 32 I/O ports is configured in POSIO0R... | 870 | * The region of the 32 I/O ports is configured in POSIO0R... |
871 | */ | 871 | */ |
872 | 872 | ||
873 | /* registers */ | 873 | /* registers */ |
874 | #define ITE_887x_MISCR 0x9c | 874 | #define ITE_887x_MISCR 0x9c |
875 | #define ITE_887x_INTCBAR 0x78 | 875 | #define ITE_887x_INTCBAR 0x78 |
876 | #define ITE_887x_UARTBAR 0x7c | 876 | #define ITE_887x_UARTBAR 0x7c |
877 | #define ITE_887x_PS0BAR 0x10 | 877 | #define ITE_887x_PS0BAR 0x10 |
878 | #define ITE_887x_POSIO0 0x60 | 878 | #define ITE_887x_POSIO0 0x60 |
879 | 879 | ||
880 | /* I/O space size */ | 880 | /* I/O space size */ |
881 | #define ITE_887x_IOSIZE 32 | 881 | #define ITE_887x_IOSIZE 32 |
882 | /* I/O space size (bits 26-24; 8 bytes = 011b) */ | 882 | /* I/O space size (bits 26-24; 8 bytes = 011b) */ |
883 | #define ITE_887x_POSIO_IOSIZE_8 (3 << 24) | 883 | #define ITE_887x_POSIO_IOSIZE_8 (3 << 24) |
884 | /* I/O space size (bits 26-24; 32 bytes = 101b) */ | 884 | /* I/O space size (bits 26-24; 32 bytes = 101b) */ |
885 | #define ITE_887x_POSIO_IOSIZE_32 (5 << 24) | 885 | #define ITE_887x_POSIO_IOSIZE_32 (5 << 24) |
886 | /* Decoding speed (1 = slow, 2 = medium, 3 = fast) */ | 886 | /* Decoding speed (1 = slow, 2 = medium, 3 = fast) */ |
887 | #define ITE_887x_POSIO_SPEED (3 << 29) | 887 | #define ITE_887x_POSIO_SPEED (3 << 29) |
888 | /* enable IO_Space bit */ | 888 | /* enable IO_Space bit */ |
889 | #define ITE_887x_POSIO_ENABLE (1 << 31) | 889 | #define ITE_887x_POSIO_ENABLE (1 << 31) |
890 | 890 | ||
891 | static int pci_ite887x_init(struct pci_dev *dev) | 891 | static int pci_ite887x_init(struct pci_dev *dev) |
892 | { | 892 | { |
893 | /* inta_addr are the configuration addresses of the ITE */ | 893 | /* inta_addr are the configuration addresses of the ITE */ |
894 | static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0, | 894 | static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0, |
895 | 0x200, 0x280, 0 }; | 895 | 0x200, 0x280, 0 }; |
896 | int ret, i, type; | 896 | int ret, i, type; |
897 | struct resource *iobase = NULL; | 897 | struct resource *iobase = NULL; |
898 | u32 miscr, uartbar, ioport; | 898 | u32 miscr, uartbar, ioport; |
899 | 899 | ||
900 | /* search for the base-ioport */ | 900 | /* search for the base-ioport */ |
901 | i = 0; | 901 | i = 0; |
902 | while (inta_addr[i] && iobase == NULL) { | 902 | while (inta_addr[i] && iobase == NULL) { |
903 | iobase = request_region(inta_addr[i], ITE_887x_IOSIZE, | 903 | iobase = request_region(inta_addr[i], ITE_887x_IOSIZE, |
904 | "ite887x"); | 904 | "ite887x"); |
905 | if (iobase != NULL) { | 905 | if (iobase != NULL) { |
906 | /* write POSIO0R - speed | size | ioport */ | 906 | /* write POSIO0R - speed | size | ioport */ |
907 | pci_write_config_dword(dev, ITE_887x_POSIO0, | 907 | pci_write_config_dword(dev, ITE_887x_POSIO0, |
908 | ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | | 908 | ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | |
909 | ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]); | 909 | ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]); |
910 | /* write INTCBAR - ioport */ | 910 | /* write INTCBAR - ioport */ |
911 | pci_write_config_dword(dev, ITE_887x_INTCBAR, | 911 | pci_write_config_dword(dev, ITE_887x_INTCBAR, |
912 | inta_addr[i]); | 912 | inta_addr[i]); |
913 | ret = inb(inta_addr[i]); | 913 | ret = inb(inta_addr[i]); |
914 | if (ret != 0xff) { | 914 | if (ret != 0xff) { |
915 | /* ioport connected */ | 915 | /* ioport connected */ |
916 | break; | 916 | break; |
917 | } | 917 | } |
918 | release_region(iobase->start, ITE_887x_IOSIZE); | 918 | release_region(iobase->start, ITE_887x_IOSIZE); |
919 | iobase = NULL; | 919 | iobase = NULL; |
920 | } | 920 | } |
921 | i++; | 921 | i++; |
922 | } | 922 | } |
923 | 923 | ||
924 | if (!inta_addr[i]) { | 924 | if (!inta_addr[i]) { |
925 | dev_err(&dev->dev, "ite887x: could not find iobase\n"); | 925 | dev_err(&dev->dev, "ite887x: could not find iobase\n"); |
926 | return -ENODEV; | 926 | return -ENODEV; |
927 | } | 927 | } |
928 | 928 | ||
929 | /* start of undocumented type checking (see parport_pc.c) */ | 929 | /* start of undocumented type checking (see parport_pc.c) */ |
930 | type = inb(iobase->start + 0x18) & 0x0f; | 930 | type = inb(iobase->start + 0x18) & 0x0f; |
931 | 931 | ||
932 | switch (type) { | 932 | switch (type) { |
933 | case 0x2: /* ITE8871 (1P) */ | 933 | case 0x2: /* ITE8871 (1P) */ |
934 | case 0xa: /* ITE8875 (1P) */ | 934 | case 0xa: /* ITE8875 (1P) */ |
935 | ret = 0; | 935 | ret = 0; |
936 | break; | 936 | break; |
937 | case 0xe: /* ITE8872 (2S1P) */ | 937 | case 0xe: /* ITE8872 (2S1P) */ |
938 | ret = 2; | 938 | ret = 2; |
939 | break; | 939 | break; |
940 | case 0x6: /* ITE8873 (1S) */ | 940 | case 0x6: /* ITE8873 (1S) */ |
941 | ret = 1; | 941 | ret = 1; |
942 | break; | 942 | break; |
943 | case 0x8: /* ITE8874 (2S) */ | 943 | case 0x8: /* ITE8874 (2S) */ |
944 | ret = 2; | 944 | ret = 2; |
945 | break; | 945 | break; |
946 | default: | 946 | default: |
947 | moan_device("Unknown ITE887x", dev); | 947 | moan_device("Unknown ITE887x", dev); |
948 | ret = -ENODEV; | 948 | ret = -ENODEV; |
949 | } | 949 | } |
950 | 950 | ||
951 | /* configure all serial ports */ | 951 | /* configure all serial ports */ |
952 | for (i = 0; i < ret; i++) { | 952 | for (i = 0; i < ret; i++) { |
953 | /* read the I/O port from the device */ | 953 | /* read the I/O port from the device */ |
954 | pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)), | 954 | pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)), |
955 | &ioport); | 955 | &ioport); |
956 | ioport &= 0x0000FF00; /* the actual base address */ | 956 | ioport &= 0x0000FF00; /* the actual base address */ |
957 | pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)), | 957 | pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)), |
958 | ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | | 958 | ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | |
959 | ITE_887x_POSIO_IOSIZE_8 | ioport); | 959 | ITE_887x_POSIO_IOSIZE_8 | ioport); |
960 | 960 | ||
961 | /* write the ioport to the UARTBAR */ | 961 | /* write the ioport to the UARTBAR */ |
962 | pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar); | 962 | pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar); |
963 | uartbar &= ~(0xffff << (16 * i)); /* clear half the reg */ | 963 | uartbar &= ~(0xffff << (16 * i)); /* clear half the reg */ |
964 | uartbar |= (ioport << (16 * i)); /* set the ioport */ | 964 | uartbar |= (ioport << (16 * i)); /* set the ioport */ |
965 | pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar); | 965 | pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar); |
966 | 966 | ||
967 | /* get current config */ | 967 | /* get current config */ |
968 | pci_read_config_dword(dev, ITE_887x_MISCR, &miscr); | 968 | pci_read_config_dword(dev, ITE_887x_MISCR, &miscr); |
969 | /* disable interrupts (UARTx_Routing[3:0]) */ | 969 | /* disable interrupts (UARTx_Routing[3:0]) */ |
970 | miscr &= ~(0xf << (12 - 4 * i)); | 970 | miscr &= ~(0xf << (12 - 4 * i)); |
971 | /* activate the UART (UARTx_En) */ | 971 | /* activate the UART (UARTx_En) */ |
972 | miscr |= 1 << (23 - i); | 972 | miscr |= 1 << (23 - i); |
973 | /* write new config with activated UART */ | 973 | /* write new config with activated UART */ |
974 | pci_write_config_dword(dev, ITE_887x_MISCR, miscr); | 974 | pci_write_config_dword(dev, ITE_887x_MISCR, miscr); |
975 | } | 975 | } |
976 | 976 | ||
977 | if (ret <= 0) { | 977 | if (ret <= 0) { |
978 | /* the device has no UARTs if we get here */ | 978 | /* the device has no UARTs if we get here */ |
979 | release_region(iobase->start, ITE_887x_IOSIZE); | 979 | release_region(iobase->start, ITE_887x_IOSIZE); |
980 | } | 980 | } |
981 | 981 | ||
982 | return ret; | 982 | return ret; |
983 | } | 983 | } |
984 | 984 | ||
985 | static void pci_ite887x_exit(struct pci_dev *dev) | 985 | static void pci_ite887x_exit(struct pci_dev *dev) |
986 | { | 986 | { |
987 | u32 ioport; | 987 | u32 ioport; |
988 | /* the ioport is bit 0-15 in POSIO0R */ | 988 | /* the ioport is bit 0-15 in POSIO0R */ |
989 | pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport); | 989 | pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport); |
990 | ioport &= 0xffff; | 990 | ioport &= 0xffff; |
991 | release_region(ioport, ITE_887x_IOSIZE); | 991 | release_region(ioport, ITE_887x_IOSIZE); |
992 | } | 992 | } |
993 | 993 | ||
994 | /* | 994 | /* |
995 | * EndRun Technologies. | 995 | * EndRun Technologies. |
996 | * Determine the number of ports available on the device. | 996 | * Determine the number of ports available on the device. |
997 | */ | 997 | */ |
998 | #define PCI_VENDOR_ID_ENDRUN 0x7401 | 998 | #define PCI_VENDOR_ID_ENDRUN 0x7401 |
999 | #define PCI_DEVICE_ID_ENDRUN_1588 0xe100 | 999 | #define PCI_DEVICE_ID_ENDRUN_1588 0xe100 |
1000 | 1000 | ||
1001 | static int pci_endrun_init(struct pci_dev *dev) | 1001 | static int pci_endrun_init(struct pci_dev *dev) |
1002 | { | 1002 | { |
1003 | u8 __iomem *p; | 1003 | u8 __iomem *p; |
1004 | unsigned long deviceID; | 1004 | unsigned long deviceID; |
1005 | unsigned int number_uarts = 0; | 1005 | unsigned int number_uarts = 0; |
1006 | 1006 | ||
1007 | /* EndRun device is all 0xexxx */ | 1007 | /* EndRun device is all 0xexxx */ |
1008 | if (dev->vendor == PCI_VENDOR_ID_ENDRUN && | 1008 | if (dev->vendor == PCI_VENDOR_ID_ENDRUN && |
1009 | (dev->device & 0xf000) != 0xe000) | 1009 | (dev->device & 0xf000) != 0xe000) |
1010 | return 0; | 1010 | return 0; |
1011 | 1011 | ||
1012 | p = pci_iomap(dev, 0, 5); | 1012 | p = pci_iomap(dev, 0, 5); |
1013 | if (p == NULL) | 1013 | if (p == NULL) |
1014 | return -ENOMEM; | 1014 | return -ENOMEM; |
1015 | 1015 | ||
1016 | deviceID = ioread32(p); | 1016 | deviceID = ioread32(p); |
1017 | /* EndRun device */ | 1017 | /* EndRun device */ |
1018 | if (deviceID == 0x07000200) { | 1018 | if (deviceID == 0x07000200) { |
1019 | number_uarts = ioread8(p + 4); | 1019 | number_uarts = ioread8(p + 4); |
1020 | dev_dbg(&dev->dev, | 1020 | dev_dbg(&dev->dev, |
1021 | "%d ports detected on EndRun PCI Express device\n", | 1021 | "%d ports detected on EndRun PCI Express device\n", |
1022 | number_uarts); | 1022 | number_uarts); |
1023 | } | 1023 | } |
1024 | pci_iounmap(dev, p); | 1024 | pci_iounmap(dev, p); |
1025 | return number_uarts; | 1025 | return number_uarts; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | /* | 1028 | /* |
1029 | * Oxford Semiconductor Inc. | 1029 | * Oxford Semiconductor Inc. |
1030 | * Check that device is part of the Tornado range of devices, then determine | 1030 | * Check that device is part of the Tornado range of devices, then determine |
1031 | * the number of ports available on the device. | 1031 | * the number of ports available on the device. |
1032 | */ | 1032 | */ |
1033 | static int pci_oxsemi_tornado_init(struct pci_dev *dev) | 1033 | static int pci_oxsemi_tornado_init(struct pci_dev *dev) |
1034 | { | 1034 | { |
1035 | u8 __iomem *p; | 1035 | u8 __iomem *p; |
1036 | unsigned long deviceID; | 1036 | unsigned long deviceID; |
1037 | unsigned int number_uarts = 0; | 1037 | unsigned int number_uarts = 0; |
1038 | 1038 | ||
1039 | /* OxSemi Tornado devices are all 0xCxxx */ | 1039 | /* OxSemi Tornado devices are all 0xCxxx */ |
1040 | if (dev->vendor == PCI_VENDOR_ID_OXSEMI && | 1040 | if (dev->vendor == PCI_VENDOR_ID_OXSEMI && |
1041 | (dev->device & 0xF000) != 0xC000) | 1041 | (dev->device & 0xF000) != 0xC000) |
1042 | return 0; | 1042 | return 0; |
1043 | 1043 | ||
1044 | p = pci_iomap(dev, 0, 5); | 1044 | p = pci_iomap(dev, 0, 5); |
1045 | if (p == NULL) | 1045 | if (p == NULL) |
1046 | return -ENOMEM; | 1046 | return -ENOMEM; |
1047 | 1047 | ||
1048 | deviceID = ioread32(p); | 1048 | deviceID = ioread32(p); |
1049 | /* Tornado device */ | 1049 | /* Tornado device */ |
1050 | if (deviceID == 0x07000200) { | 1050 | if (deviceID == 0x07000200) { |
1051 | number_uarts = ioread8(p + 4); | 1051 | number_uarts = ioread8(p + 4); |
1052 | dev_dbg(&dev->dev, | 1052 | dev_dbg(&dev->dev, |
1053 | "%d ports detected on Oxford PCI Express device\n", | 1053 | "%d ports detected on Oxford PCI Express device\n", |
1054 | number_uarts); | 1054 | number_uarts); |
1055 | } | 1055 | } |
1056 | pci_iounmap(dev, p); | 1056 | pci_iounmap(dev, p); |
1057 | return number_uarts; | 1057 | return number_uarts; |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | static int pci_asix_setup(struct serial_private *priv, | 1060 | static int pci_asix_setup(struct serial_private *priv, |
1061 | const struct pciserial_board *board, | 1061 | const struct pciserial_board *board, |
1062 | struct uart_8250_port *port, int idx) | 1062 | struct uart_8250_port *port, int idx) |
1063 | { | 1063 | { |
1064 | port->bugs |= UART_BUG_PARITY; | 1064 | port->bugs |= UART_BUG_PARITY; |
1065 | return pci_default_setup(priv, board, port, idx); | 1065 | return pci_default_setup(priv, board, port, idx); |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | /* Quatech devices have their own extra interface features */ | 1068 | /* Quatech devices have their own extra interface features */ |
1069 | 1069 | ||
1070 | struct quatech_feature { | 1070 | struct quatech_feature { |
1071 | u16 devid; | 1071 | u16 devid; |
1072 | bool amcc; | 1072 | bool amcc; |
1073 | }; | 1073 | }; |
1074 | 1074 | ||
1075 | #define QPCR_TEST_FOR1 0x3F | 1075 | #define QPCR_TEST_FOR1 0x3F |
1076 | #define QPCR_TEST_GET1 0x00 | 1076 | #define QPCR_TEST_GET1 0x00 |
1077 | #define QPCR_TEST_FOR2 0x40 | 1077 | #define QPCR_TEST_FOR2 0x40 |
1078 | #define QPCR_TEST_GET2 0x40 | 1078 | #define QPCR_TEST_GET2 0x40 |
1079 | #define QPCR_TEST_FOR3 0x80 | 1079 | #define QPCR_TEST_FOR3 0x80 |
1080 | #define QPCR_TEST_GET3 0x40 | 1080 | #define QPCR_TEST_GET3 0x40 |
1081 | #define QPCR_TEST_FOR4 0xC0 | 1081 | #define QPCR_TEST_FOR4 0xC0 |
1082 | #define QPCR_TEST_GET4 0x80 | 1082 | #define QPCR_TEST_GET4 0x80 |
1083 | 1083 | ||
1084 | #define QOPR_CLOCK_X1 0x0000 | 1084 | #define QOPR_CLOCK_X1 0x0000 |
1085 | #define QOPR_CLOCK_X2 0x0001 | 1085 | #define QOPR_CLOCK_X2 0x0001 |
1086 | #define QOPR_CLOCK_X4 0x0002 | 1086 | #define QOPR_CLOCK_X4 0x0002 |
1087 | #define QOPR_CLOCK_X8 0x0003 | 1087 | #define QOPR_CLOCK_X8 0x0003 |
1088 | #define QOPR_CLOCK_RATE_MASK 0x0003 | 1088 | #define QOPR_CLOCK_RATE_MASK 0x0003 |
1089 | 1089 | ||
1090 | 1090 | ||
1091 | static struct quatech_feature quatech_cards[] = { | 1091 | static struct quatech_feature quatech_cards[] = { |
1092 | { PCI_DEVICE_ID_QUATECH_QSC100, 1 }, | 1092 | { PCI_DEVICE_ID_QUATECH_QSC100, 1 }, |
1093 | { PCI_DEVICE_ID_QUATECH_DSC100, 1 }, | 1093 | { PCI_DEVICE_ID_QUATECH_DSC100, 1 }, |
1094 | { PCI_DEVICE_ID_QUATECH_DSC100E, 0 }, | 1094 | { PCI_DEVICE_ID_QUATECH_DSC100E, 0 }, |
1095 | { PCI_DEVICE_ID_QUATECH_DSC200, 1 }, | 1095 | { PCI_DEVICE_ID_QUATECH_DSC200, 1 }, |
1096 | { PCI_DEVICE_ID_QUATECH_DSC200E, 0 }, | 1096 | { PCI_DEVICE_ID_QUATECH_DSC200E, 0 }, |
1097 | { PCI_DEVICE_ID_QUATECH_ESC100D, 1 }, | 1097 | { PCI_DEVICE_ID_QUATECH_ESC100D, 1 }, |
1098 | { PCI_DEVICE_ID_QUATECH_ESC100M, 1 }, | 1098 | { PCI_DEVICE_ID_QUATECH_ESC100M, 1 }, |
1099 | { PCI_DEVICE_ID_QUATECH_QSCP100, 1 }, | 1099 | { PCI_DEVICE_ID_QUATECH_QSCP100, 1 }, |
1100 | { PCI_DEVICE_ID_QUATECH_DSCP100, 1 }, | 1100 | { PCI_DEVICE_ID_QUATECH_DSCP100, 1 }, |
1101 | { PCI_DEVICE_ID_QUATECH_QSCP200, 1 }, | 1101 | { PCI_DEVICE_ID_QUATECH_QSCP200, 1 }, |
1102 | { PCI_DEVICE_ID_QUATECH_DSCP200, 1 }, | 1102 | { PCI_DEVICE_ID_QUATECH_DSCP200, 1 }, |
1103 | { PCI_DEVICE_ID_QUATECH_ESCLP100, 0 }, | 1103 | { PCI_DEVICE_ID_QUATECH_ESCLP100, 0 }, |
1104 | { PCI_DEVICE_ID_QUATECH_QSCLP100, 0 }, | 1104 | { PCI_DEVICE_ID_QUATECH_QSCLP100, 0 }, |
1105 | { PCI_DEVICE_ID_QUATECH_DSCLP100, 0 }, | 1105 | { PCI_DEVICE_ID_QUATECH_DSCLP100, 0 }, |
1106 | { PCI_DEVICE_ID_QUATECH_SSCLP100, 0 }, | 1106 | { PCI_DEVICE_ID_QUATECH_SSCLP100, 0 }, |
1107 | { PCI_DEVICE_ID_QUATECH_QSCLP200, 0 }, | 1107 | { PCI_DEVICE_ID_QUATECH_QSCLP200, 0 }, |
1108 | { PCI_DEVICE_ID_QUATECH_DSCLP200, 0 }, | 1108 | { PCI_DEVICE_ID_QUATECH_DSCLP200, 0 }, |
1109 | { PCI_DEVICE_ID_QUATECH_SSCLP200, 0 }, | 1109 | { PCI_DEVICE_ID_QUATECH_SSCLP200, 0 }, |
1110 | { PCI_DEVICE_ID_QUATECH_SPPXP_100, 0 }, | 1110 | { PCI_DEVICE_ID_QUATECH_SPPXP_100, 0 }, |
1111 | { 0, } | 1111 | { 0, } |
1112 | }; | 1112 | }; |
1113 | 1113 | ||
1114 | static int pci_quatech_amcc(u16 devid) | 1114 | static int pci_quatech_amcc(u16 devid) |
1115 | { | 1115 | { |
1116 | struct quatech_feature *qf = &quatech_cards[0]; | 1116 | struct quatech_feature *qf = &quatech_cards[0]; |
1117 | while (qf->devid) { | 1117 | while (qf->devid) { |
1118 | if (qf->devid == devid) | 1118 | if (qf->devid == devid) |
1119 | return qf->amcc; | 1119 | return qf->amcc; |
1120 | qf++; | 1120 | qf++; |
1121 | } | 1121 | } |
1122 | pr_err("quatech: unknown port type '0x%04X'.\n", devid); | 1122 | pr_err("quatech: unknown port type '0x%04X'.\n", devid); |
1123 | return 0; | 1123 | return 0; |
1124 | }; | 1124 | }; |
1125 | 1125 | ||
1126 | static int pci_quatech_rqopr(struct uart_8250_port *port) | 1126 | static int pci_quatech_rqopr(struct uart_8250_port *port) |
1127 | { | 1127 | { |
1128 | unsigned long base = port->port.iobase; | 1128 | unsigned long base = port->port.iobase; |
1129 | u8 LCR, val; | 1129 | u8 LCR, val; |
1130 | 1130 | ||
1131 | LCR = inb(base + UART_LCR); | 1131 | LCR = inb(base + UART_LCR); |
1132 | outb(0xBF, base + UART_LCR); | 1132 | outb(0xBF, base + UART_LCR); |
1133 | val = inb(base + UART_SCR); | 1133 | val = inb(base + UART_SCR); |
1134 | outb(LCR, base + UART_LCR); | 1134 | outb(LCR, base + UART_LCR); |
1135 | return val; | 1135 | return val; |
1136 | } | 1136 | } |
1137 | 1137 | ||
1138 | static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr) | 1138 | static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr) |
1139 | { | 1139 | { |
1140 | unsigned long base = port->port.iobase; | 1140 | unsigned long base = port->port.iobase; |
1141 | u8 LCR, val; | 1141 | u8 LCR, val; |
1142 | 1142 | ||
1143 | LCR = inb(base + UART_LCR); | 1143 | LCR = inb(base + UART_LCR); |
1144 | outb(0xBF, base + UART_LCR); | 1144 | outb(0xBF, base + UART_LCR); |
1145 | val = inb(base + UART_SCR); | 1145 | val = inb(base + UART_SCR); |
1146 | outb(qopr, base + UART_SCR); | 1146 | outb(qopr, base + UART_SCR); |
1147 | outb(LCR, base + UART_LCR); | 1147 | outb(LCR, base + UART_LCR); |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | static int pci_quatech_rqmcr(struct uart_8250_port *port) | 1150 | static int pci_quatech_rqmcr(struct uart_8250_port *port) |
1151 | { | 1151 | { |
1152 | unsigned long base = port->port.iobase; | 1152 | unsigned long base = port->port.iobase; |
1153 | u8 LCR, val, qmcr; | 1153 | u8 LCR, val, qmcr; |
1154 | 1154 | ||
1155 | LCR = inb(base + UART_LCR); | 1155 | LCR = inb(base + UART_LCR); |
1156 | outb(0xBF, base + UART_LCR); | 1156 | outb(0xBF, base + UART_LCR); |
1157 | val = inb(base + UART_SCR); | 1157 | val = inb(base + UART_SCR); |
1158 | outb(val | 0x10, base + UART_SCR); | 1158 | outb(val | 0x10, base + UART_SCR); |
1159 | qmcr = inb(base + UART_MCR); | 1159 | qmcr = inb(base + UART_MCR); |
1160 | outb(val, base + UART_SCR); | 1160 | outb(val, base + UART_SCR); |
1161 | outb(LCR, base + UART_LCR); | 1161 | outb(LCR, base + UART_LCR); |
1162 | 1162 | ||
1163 | return qmcr; | 1163 | return qmcr; |
1164 | } | 1164 | } |
1165 | 1165 | ||
1166 | static void pci_quatech_wqmcr(struct uart_8250_port *port, u8 qmcr) | 1166 | static void pci_quatech_wqmcr(struct uart_8250_port *port, u8 qmcr) |
1167 | { | 1167 | { |
1168 | unsigned long base = port->port.iobase; | 1168 | unsigned long base = port->port.iobase; |
1169 | u8 LCR, val; | 1169 | u8 LCR, val; |
1170 | 1170 | ||
1171 | LCR = inb(base + UART_LCR); | 1171 | LCR = inb(base + UART_LCR); |
1172 | outb(0xBF, base + UART_LCR); | 1172 | outb(0xBF, base + UART_LCR); |
1173 | val = inb(base + UART_SCR); | 1173 | val = inb(base + UART_SCR); |
1174 | outb(val | 0x10, base + UART_SCR); | 1174 | outb(val | 0x10, base + UART_SCR); |
1175 | outb(qmcr, base + UART_MCR); | 1175 | outb(qmcr, base + UART_MCR); |
1176 | outb(val, base + UART_SCR); | 1176 | outb(val, base + UART_SCR); |
1177 | outb(LCR, base + UART_LCR); | 1177 | outb(LCR, base + UART_LCR); |
1178 | } | 1178 | } |
1179 | 1179 | ||
1180 | static int pci_quatech_has_qmcr(struct uart_8250_port *port) | 1180 | static int pci_quatech_has_qmcr(struct uart_8250_port *port) |
1181 | { | 1181 | { |
1182 | unsigned long base = port->port.iobase; | 1182 | unsigned long base = port->port.iobase; |
1183 | u8 LCR, val; | 1183 | u8 LCR, val; |
1184 | 1184 | ||
1185 | LCR = inb(base + UART_LCR); | 1185 | LCR = inb(base + UART_LCR); |
1186 | outb(0xBF, base + UART_LCR); | 1186 | outb(0xBF, base + UART_LCR); |
1187 | val = inb(base + UART_SCR); | 1187 | val = inb(base + UART_SCR); |
1188 | if (val & 0x20) { | 1188 | if (val & 0x20) { |
1189 | outb(0x80, UART_LCR); | 1189 | outb(0x80, UART_LCR); |
1190 | if (!(inb(UART_SCR) & 0x20)) { | 1190 | if (!(inb(UART_SCR) & 0x20)) { |
1191 | outb(LCR, base + UART_LCR); | 1191 | outb(LCR, base + UART_LCR); |
1192 | return 1; | 1192 | return 1; |
1193 | } | 1193 | } |
1194 | } | 1194 | } |
1195 | return 0; | 1195 | return 0; |
1196 | } | 1196 | } |
1197 | 1197 | ||
1198 | static int pci_quatech_test(struct uart_8250_port *port) | 1198 | static int pci_quatech_test(struct uart_8250_port *port) |
1199 | { | 1199 | { |
1200 | u8 reg; | 1200 | u8 reg; |
1201 | u8 qopr = pci_quatech_rqopr(port); | 1201 | u8 qopr = pci_quatech_rqopr(port); |
1202 | pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1); | 1202 | pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1); |
1203 | reg = pci_quatech_rqopr(port) & 0xC0; | 1203 | reg = pci_quatech_rqopr(port) & 0xC0; |
1204 | if (reg != QPCR_TEST_GET1) | 1204 | if (reg != QPCR_TEST_GET1) |
1205 | return -EINVAL; | 1205 | return -EINVAL; |
1206 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR2); | 1206 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR2); |
1207 | reg = pci_quatech_rqopr(port) & 0xC0; | 1207 | reg = pci_quatech_rqopr(port) & 0xC0; |
1208 | if (reg != QPCR_TEST_GET2) | 1208 | if (reg != QPCR_TEST_GET2) |
1209 | return -EINVAL; | 1209 | return -EINVAL; |
1210 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR3); | 1210 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR3); |
1211 | reg = pci_quatech_rqopr(port) & 0xC0; | 1211 | reg = pci_quatech_rqopr(port) & 0xC0; |
1212 | if (reg != QPCR_TEST_GET3) | 1212 | if (reg != QPCR_TEST_GET3) |
1213 | return -EINVAL; | 1213 | return -EINVAL; |
1214 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR4); | 1214 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR4); |
1215 | reg = pci_quatech_rqopr(port) & 0xC0; | 1215 | reg = pci_quatech_rqopr(port) & 0xC0; |
1216 | if (reg != QPCR_TEST_GET4) | 1216 | if (reg != QPCR_TEST_GET4) |
1217 | return -EINVAL; | 1217 | return -EINVAL; |
1218 | 1218 | ||
1219 | pci_quatech_wqopr(port, qopr); | 1219 | pci_quatech_wqopr(port, qopr); |
1220 | return 0; | 1220 | return 0; |
1221 | } | 1221 | } |
1222 | 1222 | ||
1223 | static int pci_quatech_clock(struct uart_8250_port *port) | 1223 | static int pci_quatech_clock(struct uart_8250_port *port) |
1224 | { | 1224 | { |
1225 | u8 qopr, reg, set; | 1225 | u8 qopr, reg, set; |
1226 | unsigned long clock; | 1226 | unsigned long clock; |
1227 | 1227 | ||
1228 | if (pci_quatech_test(port) < 0) | 1228 | if (pci_quatech_test(port) < 0) |
1229 | return 1843200; | 1229 | return 1843200; |
1230 | 1230 | ||
1231 | qopr = pci_quatech_rqopr(port); | 1231 | qopr = pci_quatech_rqopr(port); |
1232 | 1232 | ||
1233 | pci_quatech_wqopr(port, qopr & ~QOPR_CLOCK_X8); | 1233 | pci_quatech_wqopr(port, qopr & ~QOPR_CLOCK_X8); |
1234 | reg = pci_quatech_rqopr(port); | 1234 | reg = pci_quatech_rqopr(port); |
1235 | if (reg & QOPR_CLOCK_X8) { | 1235 | if (reg & QOPR_CLOCK_X8) { |
1236 | clock = 1843200; | 1236 | clock = 1843200; |
1237 | goto out; | 1237 | goto out; |
1238 | } | 1238 | } |
1239 | pci_quatech_wqopr(port, qopr | QOPR_CLOCK_X8); | 1239 | pci_quatech_wqopr(port, qopr | QOPR_CLOCK_X8); |
1240 | reg = pci_quatech_rqopr(port); | 1240 | reg = pci_quatech_rqopr(port); |
1241 | if (!(reg & QOPR_CLOCK_X8)) { | 1241 | if (!(reg & QOPR_CLOCK_X8)) { |
1242 | clock = 1843200; | 1242 | clock = 1843200; |
1243 | goto out; | 1243 | goto out; |
1244 | } | 1244 | } |
1245 | reg &= QOPR_CLOCK_X8; | 1245 | reg &= QOPR_CLOCK_X8; |
1246 | if (reg == QOPR_CLOCK_X2) { | 1246 | if (reg == QOPR_CLOCK_X2) { |
1247 | clock = 3685400; | 1247 | clock = 3685400; |
1248 | set = QOPR_CLOCK_X2; | 1248 | set = QOPR_CLOCK_X2; |
1249 | } else if (reg == QOPR_CLOCK_X4) { | 1249 | } else if (reg == QOPR_CLOCK_X4) { |
1250 | clock = 7372800; | 1250 | clock = 7372800; |
1251 | set = QOPR_CLOCK_X4; | 1251 | set = QOPR_CLOCK_X4; |
1252 | } else if (reg == QOPR_CLOCK_X8) { | 1252 | } else if (reg == QOPR_CLOCK_X8) { |
1253 | clock = 14745600; | 1253 | clock = 14745600; |
1254 | set = QOPR_CLOCK_X8; | 1254 | set = QOPR_CLOCK_X8; |
1255 | } else { | 1255 | } else { |
1256 | clock = 1843200; | 1256 | clock = 1843200; |
1257 | set = QOPR_CLOCK_X1; | 1257 | set = QOPR_CLOCK_X1; |
1258 | } | 1258 | } |
1259 | qopr &= ~QOPR_CLOCK_RATE_MASK; | 1259 | qopr &= ~QOPR_CLOCK_RATE_MASK; |
1260 | qopr |= set; | 1260 | qopr |= set; |
1261 | 1261 | ||
1262 | out: | 1262 | out: |
1263 | pci_quatech_wqopr(port, qopr); | 1263 | pci_quatech_wqopr(port, qopr); |
1264 | return clock; | 1264 | return clock; |
1265 | } | 1265 | } |
1266 | 1266 | ||
1267 | static int pci_quatech_rs422(struct uart_8250_port *port) | 1267 | static int pci_quatech_rs422(struct uart_8250_port *port) |
1268 | { | 1268 | { |
1269 | u8 qmcr; | 1269 | u8 qmcr; |
1270 | int rs422 = 0; | 1270 | int rs422 = 0; |
1271 | 1271 | ||
1272 | if (!pci_quatech_has_qmcr(port)) | 1272 | if (!pci_quatech_has_qmcr(port)) |
1273 | return 0; | 1273 | return 0; |
1274 | qmcr = pci_quatech_rqmcr(port); | 1274 | qmcr = pci_quatech_rqmcr(port); |
1275 | pci_quatech_wqmcr(port, 0xFF); | 1275 | pci_quatech_wqmcr(port, 0xFF); |
1276 | if (pci_quatech_rqmcr(port)) | 1276 | if (pci_quatech_rqmcr(port)) |
1277 | rs422 = 1; | 1277 | rs422 = 1; |
1278 | pci_quatech_wqmcr(port, qmcr); | 1278 | pci_quatech_wqmcr(port, qmcr); |
1279 | return rs422; | 1279 | return rs422; |
1280 | } | 1280 | } |
1281 | 1281 | ||
1282 | static int pci_quatech_init(struct pci_dev *dev) | 1282 | static int pci_quatech_init(struct pci_dev *dev) |
1283 | { | 1283 | { |
1284 | if (pci_quatech_amcc(dev->device)) { | 1284 | if (pci_quatech_amcc(dev->device)) { |
1285 | unsigned long base = pci_resource_start(dev, 0); | 1285 | unsigned long base = pci_resource_start(dev, 0); |
1286 | if (base) { | 1286 | if (base) { |
1287 | u32 tmp; | 1287 | u32 tmp; |
1288 | outl(inl(base + 0x38) | 0x00002000, base + 0x38); | 1288 | outl(inl(base + 0x38) | 0x00002000, base + 0x38); |
1289 | tmp = inl(base + 0x3c); | 1289 | tmp = inl(base + 0x3c); |
1290 | outl(tmp | 0x01000000, base + 0x3c); | 1290 | outl(tmp | 0x01000000, base + 0x3c); |
1291 | outl(tmp &= ~0x01000000, base + 0x3c); | 1291 | outl(tmp &= ~0x01000000, base + 0x3c); |
1292 | } | 1292 | } |
1293 | } | 1293 | } |
1294 | return 0; | 1294 | return 0; |
1295 | } | 1295 | } |
1296 | 1296 | ||
1297 | static int pci_quatech_setup(struct serial_private *priv, | 1297 | static int pci_quatech_setup(struct serial_private *priv, |
1298 | const struct pciserial_board *board, | 1298 | const struct pciserial_board *board, |
1299 | struct uart_8250_port *port, int idx) | 1299 | struct uart_8250_port *port, int idx) |
1300 | { | 1300 | { |
1301 | /* Needed by pci_quatech calls below */ | 1301 | /* Needed by pci_quatech calls below */ |
1302 | port->port.iobase = pci_resource_start(priv->dev, FL_GET_BASE(board->flags)); | 1302 | port->port.iobase = pci_resource_start(priv->dev, FL_GET_BASE(board->flags)); |
1303 | /* Set up the clocking */ | 1303 | /* Set up the clocking */ |
1304 | port->port.uartclk = pci_quatech_clock(port); | 1304 | port->port.uartclk = pci_quatech_clock(port); |
1305 | /* For now just warn about RS422 */ | 1305 | /* For now just warn about RS422 */ |
1306 | if (pci_quatech_rs422(port)) | 1306 | if (pci_quatech_rs422(port)) |
1307 | pr_warn("quatech: software control of RS422 features not currently supported.\n"); | 1307 | pr_warn("quatech: software control of RS422 features not currently supported.\n"); |
1308 | return pci_default_setup(priv, board, port, idx); | 1308 | return pci_default_setup(priv, board, port, idx); |
1309 | } | 1309 | } |
1310 | 1310 | ||
1311 | static void pci_quatech_exit(struct pci_dev *dev) | 1311 | static void pci_quatech_exit(struct pci_dev *dev) |
1312 | { | 1312 | { |
1313 | } | 1313 | } |
1314 | 1314 | ||
1315 | static int pci_default_setup(struct serial_private *priv, | 1315 | static int pci_default_setup(struct serial_private *priv, |
1316 | const struct pciserial_board *board, | 1316 | const struct pciserial_board *board, |
1317 | struct uart_8250_port *port, int idx) | 1317 | struct uart_8250_port *port, int idx) |
1318 | { | 1318 | { |
1319 | unsigned int bar, offset = board->first_offset, maxnr; | 1319 | unsigned int bar, offset = board->first_offset, maxnr; |
1320 | 1320 | ||
1321 | bar = FL_GET_BASE(board->flags); | 1321 | bar = FL_GET_BASE(board->flags); |
1322 | if (board->flags & FL_BASE_BARS) | 1322 | if (board->flags & FL_BASE_BARS) |
1323 | bar += idx; | 1323 | bar += idx; |
1324 | else | 1324 | else |
1325 | offset += idx * board->uart_offset; | 1325 | offset += idx * board->uart_offset; |
1326 | 1326 | ||
1327 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >> | 1327 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >> |
1328 | (board->reg_shift + 3); | 1328 | (board->reg_shift + 3); |
1329 | 1329 | ||
1330 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) | 1330 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) |
1331 | return 1; | 1331 | return 1; |
1332 | 1332 | ||
1333 | return setup_port(priv, port, bar, offset, board->reg_shift); | 1333 | return setup_port(priv, port, bar, offset, board->reg_shift); |
1334 | } | 1334 | } |
1335 | 1335 | ||
1336 | static int pci_pericom_setup(struct serial_private *priv, | 1336 | static int pci_pericom_setup(struct serial_private *priv, |
1337 | const struct pciserial_board *board, | 1337 | const struct pciserial_board *board, |
1338 | struct uart_8250_port *port, int idx) | 1338 | struct uart_8250_port *port, int idx) |
1339 | { | 1339 | { |
1340 | unsigned int bar, offset = board->first_offset, maxnr; | 1340 | unsigned int bar, offset = board->first_offset, maxnr; |
1341 | 1341 | ||
1342 | bar = FL_GET_BASE(board->flags); | 1342 | bar = FL_GET_BASE(board->flags); |
1343 | if (board->flags & FL_BASE_BARS) | 1343 | if (board->flags & FL_BASE_BARS) |
1344 | bar += idx; | 1344 | bar += idx; |
1345 | else | 1345 | else |
1346 | offset += idx * board->uart_offset; | 1346 | offset += idx * board->uart_offset; |
1347 | 1347 | ||
1348 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >> | 1348 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >> |
1349 | (board->reg_shift + 3); | 1349 | (board->reg_shift + 3); |
1350 | 1350 | ||
1351 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) | 1351 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) |
1352 | return 1; | 1352 | return 1; |
1353 | 1353 | ||
1354 | port->port.uartclk = 14745600; | 1354 | port->port.uartclk = 14745600; |
1355 | 1355 | ||
1356 | return setup_port(priv, port, bar, offset, board->reg_shift); | 1356 | return setup_port(priv, port, bar, offset, board->reg_shift); |
1357 | } | 1357 | } |
1358 | 1358 | ||
1359 | static int | 1359 | static int |
1360 | ce4100_serial_setup(struct serial_private *priv, | 1360 | ce4100_serial_setup(struct serial_private *priv, |
1361 | const struct pciserial_board *board, | 1361 | const struct pciserial_board *board, |
1362 | struct uart_8250_port *port, int idx) | 1362 | struct uart_8250_port *port, int idx) |
1363 | { | 1363 | { |
1364 | int ret; | 1364 | int ret; |
1365 | 1365 | ||
1366 | ret = setup_port(priv, port, idx, 0, board->reg_shift); | 1366 | ret = setup_port(priv, port, idx, 0, board->reg_shift); |
1367 | port->port.iotype = UPIO_MEM32; | 1367 | port->port.iotype = UPIO_MEM32; |
1368 | port->port.type = PORT_XSCALE; | 1368 | port->port.type = PORT_XSCALE; |
1369 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); | 1369 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); |
1370 | port->port.regshift = 2; | 1370 | port->port.regshift = 2; |
1371 | 1371 | ||
1372 | return ret; | 1372 | return ret; |
1373 | } | 1373 | } |
1374 | 1374 | ||
1375 | #define PCI_DEVICE_ID_INTEL_BYT_UART1 0x0f0a | 1375 | #define PCI_DEVICE_ID_INTEL_BYT_UART1 0x0f0a |
1376 | #define PCI_DEVICE_ID_INTEL_BYT_UART2 0x0f0c | 1376 | #define PCI_DEVICE_ID_INTEL_BYT_UART2 0x0f0c |
1377 | 1377 | ||
1378 | #define PCI_DEVICE_ID_INTEL_BSW_UART1 0x228a | 1378 | #define PCI_DEVICE_ID_INTEL_BSW_UART1 0x228a |
1379 | #define PCI_DEVICE_ID_INTEL_BSW_UART2 0x228c | 1379 | #define PCI_DEVICE_ID_INTEL_BSW_UART2 0x228c |
1380 | 1380 | ||
1381 | #define BYT_PRV_CLK 0x800 | 1381 | #define BYT_PRV_CLK 0x800 |
1382 | #define BYT_PRV_CLK_EN (1 << 0) | 1382 | #define BYT_PRV_CLK_EN (1 << 0) |
1383 | #define BYT_PRV_CLK_M_VAL_SHIFT 1 | 1383 | #define BYT_PRV_CLK_M_VAL_SHIFT 1 |
1384 | #define BYT_PRV_CLK_N_VAL_SHIFT 16 | 1384 | #define BYT_PRV_CLK_N_VAL_SHIFT 16 |
1385 | #define BYT_PRV_CLK_UPDATE (1 << 31) | 1385 | #define BYT_PRV_CLK_UPDATE (1 << 31) |
1386 | 1386 | ||
1387 | #define BYT_TX_OVF_INT 0x820 | 1387 | #define BYT_TX_OVF_INT 0x820 |
1388 | #define BYT_TX_OVF_INT_MASK (1 << 1) | 1388 | #define BYT_TX_OVF_INT_MASK (1 << 1) |
1389 | 1389 | ||
1390 | static void | 1390 | static void |
1391 | byt_set_termios(struct uart_port *p, struct ktermios *termios, | 1391 | byt_set_termios(struct uart_port *p, struct ktermios *termios, |
1392 | struct ktermios *old) | 1392 | struct ktermios *old) |
1393 | { | 1393 | { |
1394 | unsigned int baud = tty_termios_baud_rate(termios); | 1394 | unsigned int baud = tty_termios_baud_rate(termios); |
1395 | unsigned int m, n; | 1395 | unsigned int m, n; |
1396 | u32 reg; | 1396 | u32 reg; |
1397 | 1397 | ||
1398 | /* | 1398 | /* |
1399 | * For baud rates 0.5M, 1M, 1.5M, 2M, 2.5M, 3M, 3.5M and 4M the | 1399 | * For baud rates 0.5M, 1M, 1.5M, 2M, 2.5M, 3M, 3.5M and 4M the |
1400 | * dividers must be adjusted. | 1400 | * dividers must be adjusted. |
1401 | * | 1401 | * |
1402 | * uartclk = (m / n) * 100 MHz, where m <= n | 1402 | * uartclk = (m / n) * 100 MHz, where m <= n |
1403 | */ | 1403 | */ |
1404 | switch (baud) { | 1404 | switch (baud) { |
1405 | case 500000: | 1405 | case 500000: |
1406 | case 1000000: | 1406 | case 1000000: |
1407 | case 2000000: | 1407 | case 2000000: |
1408 | case 4000000: | 1408 | case 4000000: |
1409 | m = 64; | 1409 | m = 64; |
1410 | n = 100; | 1410 | n = 100; |
1411 | p->uartclk = 64000000; | 1411 | p->uartclk = 64000000; |
1412 | break; | 1412 | break; |
1413 | case 3500000: | 1413 | case 3500000: |
1414 | m = 56; | 1414 | m = 56; |
1415 | n = 100; | 1415 | n = 100; |
1416 | p->uartclk = 56000000; | 1416 | p->uartclk = 56000000; |
1417 | break; | 1417 | break; |
1418 | case 1500000: | 1418 | case 1500000: |
1419 | case 3000000: | 1419 | case 3000000: |
1420 | m = 48; | 1420 | m = 48; |
1421 | n = 100; | 1421 | n = 100; |
1422 | p->uartclk = 48000000; | 1422 | p->uartclk = 48000000; |
1423 | break; | 1423 | break; |
1424 | case 2500000: | 1424 | case 2500000: |
1425 | m = 40; | 1425 | m = 40; |
1426 | n = 100; | 1426 | n = 100; |
1427 | p->uartclk = 40000000; | 1427 | p->uartclk = 40000000; |
1428 | break; | 1428 | break; |
1429 | default: | 1429 | default: |
1430 | m = 2304; | 1430 | m = 2304; |
1431 | n = 3125; | 1431 | n = 3125; |
1432 | p->uartclk = 73728000; | 1432 | p->uartclk = 73728000; |
1433 | } | 1433 | } |
1434 | 1434 | ||
1435 | /* Reset the clock */ | 1435 | /* Reset the clock */ |
1436 | reg = (m << BYT_PRV_CLK_M_VAL_SHIFT) | (n << BYT_PRV_CLK_N_VAL_SHIFT); | 1436 | reg = (m << BYT_PRV_CLK_M_VAL_SHIFT) | (n << BYT_PRV_CLK_N_VAL_SHIFT); |
1437 | writel(reg, p->membase + BYT_PRV_CLK); | 1437 | writel(reg, p->membase + BYT_PRV_CLK); |
1438 | reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE; | 1438 | reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE; |
1439 | writel(reg, p->membase + BYT_PRV_CLK); | 1439 | writel(reg, p->membase + BYT_PRV_CLK); |
1440 | 1440 | ||
1441 | serial8250_do_set_termios(p, termios, old); | 1441 | serial8250_do_set_termios(p, termios, old); |
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | static bool byt_dma_filter(struct dma_chan *chan, void *param) | 1444 | static bool byt_dma_filter(struct dma_chan *chan, void *param) |
1445 | { | 1445 | { |
1446 | struct dw_dma_slave *dws = param; | 1446 | struct dw_dma_slave *dws = param; |
1447 | 1447 | ||
1448 | if (dws->dma_dev != chan->device->dev) | 1448 | if (dws->dma_dev != chan->device->dev) |
1449 | return false; | 1449 | return false; |
1450 | 1450 | ||
1451 | chan->private = dws; | 1451 | chan->private = dws; |
1452 | return true; | 1452 | return true; |
1453 | } | 1453 | } |
1454 | 1454 | ||
1455 | static int | 1455 | static int |
1456 | byt_serial_setup(struct serial_private *priv, | 1456 | byt_serial_setup(struct serial_private *priv, |
1457 | const struct pciserial_board *board, | 1457 | const struct pciserial_board *board, |
1458 | struct uart_8250_port *port, int idx) | 1458 | struct uart_8250_port *port, int idx) |
1459 | { | 1459 | { |
1460 | struct pci_dev *pdev = priv->dev; | 1460 | struct pci_dev *pdev = priv->dev; |
1461 | struct device *dev = port->port.dev; | 1461 | struct device *dev = port->port.dev; |
1462 | struct uart_8250_dma *dma; | 1462 | struct uart_8250_dma *dma; |
1463 | struct dw_dma_slave *tx_param, *rx_param; | 1463 | struct dw_dma_slave *tx_param, *rx_param; |
1464 | struct pci_dev *dma_dev; | 1464 | struct pci_dev *dma_dev; |
1465 | int ret; | 1465 | int ret; |
1466 | 1466 | ||
1467 | dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); | 1467 | dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); |
1468 | if (!dma) | 1468 | if (!dma) |
1469 | return -ENOMEM; | 1469 | return -ENOMEM; |
1470 | 1470 | ||
1471 | tx_param = devm_kzalloc(dev, sizeof(*tx_param), GFP_KERNEL); | 1471 | tx_param = devm_kzalloc(dev, sizeof(*tx_param), GFP_KERNEL); |
1472 | if (!tx_param) | 1472 | if (!tx_param) |
1473 | return -ENOMEM; | 1473 | return -ENOMEM; |
1474 | 1474 | ||
1475 | rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL); | 1475 | rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL); |
1476 | if (!rx_param) | 1476 | if (!rx_param) |
1477 | return -ENOMEM; | 1477 | return -ENOMEM; |
1478 | 1478 | ||
1479 | switch (pdev->device) { | 1479 | switch (pdev->device) { |
1480 | case PCI_DEVICE_ID_INTEL_BYT_UART1: | 1480 | case PCI_DEVICE_ID_INTEL_BYT_UART1: |
1481 | case PCI_DEVICE_ID_INTEL_BSW_UART1: | 1481 | case PCI_DEVICE_ID_INTEL_BSW_UART1: |
1482 | rx_param->src_id = 3; | 1482 | rx_param->src_id = 3; |
1483 | tx_param->dst_id = 2; | 1483 | tx_param->dst_id = 2; |
1484 | break; | 1484 | break; |
1485 | case PCI_DEVICE_ID_INTEL_BYT_UART2: | 1485 | case PCI_DEVICE_ID_INTEL_BYT_UART2: |
1486 | case PCI_DEVICE_ID_INTEL_BSW_UART2: | 1486 | case PCI_DEVICE_ID_INTEL_BSW_UART2: |
1487 | rx_param->src_id = 5; | 1487 | rx_param->src_id = 5; |
1488 | tx_param->dst_id = 4; | 1488 | tx_param->dst_id = 4; |
1489 | break; | 1489 | break; |
1490 | default: | 1490 | default: |
1491 | return -EINVAL; | 1491 | return -EINVAL; |
1492 | } | 1492 | } |
1493 | 1493 | ||
1494 | rx_param->src_master = 1; | 1494 | rx_param->src_master = 1; |
1495 | rx_param->dst_master = 0; | 1495 | rx_param->dst_master = 0; |
1496 | 1496 | ||
1497 | dma->rxconf.src_maxburst = 16; | 1497 | dma->rxconf.src_maxburst = 16; |
1498 | 1498 | ||
1499 | tx_param->src_master = 1; | 1499 | tx_param->src_master = 1; |
1500 | tx_param->dst_master = 0; | 1500 | tx_param->dst_master = 0; |
1501 | 1501 | ||
1502 | dma->txconf.dst_maxburst = 16; | 1502 | dma->txconf.dst_maxburst = 16; |
1503 | 1503 | ||
1504 | dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 0)); | 1504 | dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 0)); |
1505 | rx_param->dma_dev = &dma_dev->dev; | 1505 | rx_param->dma_dev = &dma_dev->dev; |
1506 | tx_param->dma_dev = &dma_dev->dev; | 1506 | tx_param->dma_dev = &dma_dev->dev; |
1507 | 1507 | ||
1508 | dma->fn = byt_dma_filter; | 1508 | dma->fn = byt_dma_filter; |
1509 | dma->rx_param = rx_param; | 1509 | dma->rx_param = rx_param; |
1510 | dma->tx_param = tx_param; | 1510 | dma->tx_param = tx_param; |
1511 | 1511 | ||
1512 | ret = pci_default_setup(priv, board, port, idx); | 1512 | ret = pci_default_setup(priv, board, port, idx); |
1513 | port->port.iotype = UPIO_MEM; | 1513 | port->port.iotype = UPIO_MEM; |
1514 | port->port.type = PORT_16550A; | 1514 | port->port.type = PORT_16550A; |
1515 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); | 1515 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); |
1516 | port->port.set_termios = byt_set_termios; | 1516 | port->port.set_termios = byt_set_termios; |
1517 | port->port.fifosize = 64; | 1517 | port->port.fifosize = 64; |
1518 | port->tx_loadsz = 64; | 1518 | port->tx_loadsz = 64; |
1519 | port->dma = dma; | 1519 | port->dma = dma; |
1520 | port->capabilities = UART_CAP_FIFO | UART_CAP_AFE; | 1520 | port->capabilities = UART_CAP_FIFO | UART_CAP_AFE; |
1521 | 1521 | ||
1522 | /* Disable Tx counter interrupts */ | 1522 | /* Disable Tx counter interrupts */ |
1523 | writel(BYT_TX_OVF_INT_MASK, port->port.membase + BYT_TX_OVF_INT); | 1523 | writel(BYT_TX_OVF_INT_MASK, port->port.membase + BYT_TX_OVF_INT); |
1524 | 1524 | ||
1525 | return ret; | 1525 | return ret; |
1526 | } | 1526 | } |
1527 | 1527 | ||
1528 | static int | 1528 | static int |
1529 | pci_omegapci_setup(struct serial_private *priv, | 1529 | pci_omegapci_setup(struct serial_private *priv, |
1530 | const struct pciserial_board *board, | 1530 | const struct pciserial_board *board, |
1531 | struct uart_8250_port *port, int idx) | 1531 | struct uart_8250_port *port, int idx) |
1532 | { | 1532 | { |
1533 | return setup_port(priv, port, 2, idx * 8, 0); | 1533 | return setup_port(priv, port, 2, idx * 8, 0); |
1534 | } | 1534 | } |
1535 | 1535 | ||
1536 | static int | 1536 | static int |
1537 | pci_brcm_trumanage_setup(struct serial_private *priv, | 1537 | pci_brcm_trumanage_setup(struct serial_private *priv, |
1538 | const struct pciserial_board *board, | 1538 | const struct pciserial_board *board, |
1539 | struct uart_8250_port *port, int idx) | 1539 | struct uart_8250_port *port, int idx) |
1540 | { | 1540 | { |
1541 | int ret = pci_default_setup(priv, board, port, idx); | 1541 | int ret = pci_default_setup(priv, board, port, idx); |
1542 | 1542 | ||
1543 | port->port.type = PORT_BRCM_TRUMANAGE; | 1543 | port->port.type = PORT_BRCM_TRUMANAGE; |
1544 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); | 1544 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); |
1545 | return ret; | 1545 | return ret; |
1546 | } | 1546 | } |
1547 | 1547 | ||
1548 | static int pci_fintek_setup(struct serial_private *priv, | 1548 | static int pci_fintek_setup(struct serial_private *priv, |
1549 | const struct pciserial_board *board, | 1549 | const struct pciserial_board *board, |
1550 | struct uart_8250_port *port, int idx) | 1550 | struct uart_8250_port *port, int idx) |
1551 | { | 1551 | { |
1552 | struct pci_dev *pdev = priv->dev; | 1552 | struct pci_dev *pdev = priv->dev; |
1553 | unsigned long base; | 1553 | unsigned long base; |
1554 | unsigned long iobase; | 1554 | unsigned long iobase; |
1555 | unsigned long ciobase = 0; | 1555 | unsigned long ciobase = 0; |
1556 | u8 config_base; | 1556 | u8 config_base; |
1557 | u32 bar_data[3]; | 1557 | u32 bar_data[3]; |
1558 | 1558 | ||
1559 | /* | 1559 | /* |
1560 | * Find each UARTs offset in PCI configuraion space | 1560 | * Find each UARTs offset in PCI configuraion space |
1561 | */ | 1561 | */ |
1562 | switch (idx) { | 1562 | switch (idx) { |
1563 | case 0: | 1563 | case 0: |
1564 | config_base = 0x40; | 1564 | config_base = 0x40; |
1565 | break; | 1565 | break; |
1566 | case 1: | 1566 | case 1: |
1567 | config_base = 0x48; | 1567 | config_base = 0x48; |
1568 | break; | 1568 | break; |
1569 | case 2: | 1569 | case 2: |
1570 | config_base = 0x50; | 1570 | config_base = 0x50; |
1571 | break; | 1571 | break; |
1572 | case 3: | 1572 | case 3: |
1573 | config_base = 0x58; | 1573 | config_base = 0x58; |
1574 | break; | 1574 | break; |
1575 | case 4: | 1575 | case 4: |
1576 | config_base = 0x60; | 1576 | config_base = 0x60; |
1577 | break; | 1577 | break; |
1578 | case 5: | 1578 | case 5: |
1579 | config_base = 0x68; | 1579 | config_base = 0x68; |
1580 | break; | 1580 | break; |
1581 | case 6: | 1581 | case 6: |
1582 | config_base = 0x70; | 1582 | config_base = 0x70; |
1583 | break; | 1583 | break; |
1584 | case 7: | 1584 | case 7: |
1585 | config_base = 0x78; | 1585 | config_base = 0x78; |
1586 | break; | 1586 | break; |
1587 | case 8: | 1587 | case 8: |
1588 | config_base = 0x80; | 1588 | config_base = 0x80; |
1589 | break; | 1589 | break; |
1590 | case 9: | 1590 | case 9: |
1591 | config_base = 0x88; | 1591 | config_base = 0x88; |
1592 | break; | 1592 | break; |
1593 | case 10: | 1593 | case 10: |
1594 | config_base = 0x90; | 1594 | config_base = 0x90; |
1595 | break; | 1595 | break; |
1596 | case 11: | 1596 | case 11: |
1597 | config_base = 0x98; | 1597 | config_base = 0x98; |
1598 | break; | 1598 | break; |
1599 | default: | 1599 | default: |
1600 | /* Unknown number of ports, get out of here */ | 1600 | /* Unknown number of ports, get out of here */ |
1601 | return -EINVAL; | 1601 | return -EINVAL; |
1602 | } | 1602 | } |
1603 | 1603 | ||
1604 | if (idx < 4) { | 1604 | if (idx < 4) { |
1605 | base = pci_resource_start(priv->dev, 3); | 1605 | base = pci_resource_start(priv->dev, 3); |
1606 | ciobase = (int)(base + (0x8 * idx)); | 1606 | ciobase = (int)(base + (0x8 * idx)); |
1607 | } | 1607 | } |
1608 | 1608 | ||
1609 | /* Get the io address dispatch from the BIOS */ | 1609 | /* Get the io address dispatch from the BIOS */ |
1610 | pci_read_config_dword(pdev, 0x24, &bar_data[0]); | 1610 | pci_read_config_dword(pdev, 0x24, &bar_data[0]); |
1611 | pci_read_config_dword(pdev, 0x20, &bar_data[1]); | 1611 | pci_read_config_dword(pdev, 0x20, &bar_data[1]); |
1612 | pci_read_config_dword(pdev, 0x1c, &bar_data[2]); | 1612 | pci_read_config_dword(pdev, 0x1c, &bar_data[2]); |
1613 | 1613 | ||
1614 | /* Calculate Real IO Port */ | 1614 | /* Calculate Real IO Port */ |
1615 | iobase = (bar_data[idx/4] & 0xffffffe0) + (idx % 4) * 8; | 1615 | iobase = (bar_data[idx/4] & 0xffffffe0) + (idx % 4) * 8; |
1616 | 1616 | ||
1617 | dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n", | 1617 | dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n", |
1618 | __func__, idx, iobase, ciobase, config_base); | 1618 | __func__, idx, iobase, ciobase, config_base); |
1619 | 1619 | ||
1620 | /* Enable UART I/O port */ | 1620 | /* Enable UART I/O port */ |
1621 | pci_write_config_byte(pdev, config_base + 0x00, 0x01); | 1621 | pci_write_config_byte(pdev, config_base + 0x00, 0x01); |
1622 | 1622 | ||
1623 | /* Select 128-byte FIFO and 8x FIFO threshold */ | 1623 | /* Select 128-byte FIFO and 8x FIFO threshold */ |
1624 | pci_write_config_byte(pdev, config_base + 0x01, 0x33); | 1624 | pci_write_config_byte(pdev, config_base + 0x01, 0x33); |
1625 | 1625 | ||
1626 | /* LSB UART */ | 1626 | /* LSB UART */ |
1627 | pci_write_config_byte(pdev, config_base + 0x04, (u8)(iobase & 0xff)); | 1627 | pci_write_config_byte(pdev, config_base + 0x04, (u8)(iobase & 0xff)); |
1628 | 1628 | ||
1629 | /* MSB UART */ | 1629 | /* MSB UART */ |
1630 | pci_write_config_byte(pdev, config_base + 0x05, (u8)((iobase & 0xff00) >> 8)); | 1630 | pci_write_config_byte(pdev, config_base + 0x05, (u8)((iobase & 0xff00) >> 8)); |
1631 | 1631 | ||
1632 | /* irq number, this usually fails, but the spec says to do it anyway. */ | 1632 | /* irq number, this usually fails, but the spec says to do it anyway. */ |
1633 | pci_write_config_byte(pdev, config_base + 0x06, pdev->irq); | 1633 | pci_write_config_byte(pdev, config_base + 0x06, pdev->irq); |
1634 | 1634 | ||
1635 | port->port.iotype = UPIO_PORT; | 1635 | port->port.iotype = UPIO_PORT; |
1636 | port->port.iobase = iobase; | 1636 | port->port.iobase = iobase; |
1637 | port->port.mapbase = 0; | 1637 | port->port.mapbase = 0; |
1638 | port->port.membase = NULL; | 1638 | port->port.membase = NULL; |
1639 | port->port.regshift = 0; | 1639 | port->port.regshift = 0; |
1640 | 1640 | ||
1641 | return 0; | 1641 | return 0; |
1642 | } | 1642 | } |
1643 | 1643 | ||
1644 | static int skip_tx_en_setup(struct serial_private *priv, | 1644 | static int skip_tx_en_setup(struct serial_private *priv, |
1645 | const struct pciserial_board *board, | 1645 | const struct pciserial_board *board, |
1646 | struct uart_8250_port *port, int idx) | 1646 | struct uart_8250_port *port, int idx) |
1647 | { | 1647 | { |
1648 | port->port.flags |= UPF_NO_TXEN_TEST; | 1648 | port->port.flags |= UPF_NO_TXEN_TEST; |
1649 | dev_dbg(&priv->dev->dev, | 1649 | dev_dbg(&priv->dev->dev, |
1650 | "serial8250: skipping TxEn test for device [%04x:%04x] subsystem [%04x:%04x]\n", | 1650 | "serial8250: skipping TxEn test for device [%04x:%04x] subsystem [%04x:%04x]\n", |
1651 | priv->dev->vendor, priv->dev->device, | 1651 | priv->dev->vendor, priv->dev->device, |
1652 | priv->dev->subsystem_vendor, priv->dev->subsystem_device); | 1652 | priv->dev->subsystem_vendor, priv->dev->subsystem_device); |
1653 | 1653 | ||
1654 | return pci_default_setup(priv, board, port, idx); | 1654 | return pci_default_setup(priv, board, port, idx); |
1655 | } | 1655 | } |
1656 | 1656 | ||
1657 | static void kt_handle_break(struct uart_port *p) | 1657 | static void kt_handle_break(struct uart_port *p) |
1658 | { | 1658 | { |
1659 | struct uart_8250_port *up = up_to_u8250p(p); | 1659 | struct uart_8250_port *up = up_to_u8250p(p); |
1660 | /* | 1660 | /* |
1661 | * On receipt of a BI, serial device in Intel ME (Intel | 1661 | * On receipt of a BI, serial device in Intel ME (Intel |
1662 | * management engine) needs to have its fifos cleared for sane | 1662 | * management engine) needs to have its fifos cleared for sane |
1663 | * SOL (Serial Over Lan) output. | 1663 | * SOL (Serial Over Lan) output. |
1664 | */ | 1664 | */ |
1665 | serial8250_clear_and_reinit_fifos(up); | 1665 | serial8250_clear_and_reinit_fifos(up); |
1666 | } | 1666 | } |
1667 | 1667 | ||
1668 | static unsigned int kt_serial_in(struct uart_port *p, int offset) | 1668 | static unsigned int kt_serial_in(struct uart_port *p, int offset) |
1669 | { | 1669 | { |
1670 | struct uart_8250_port *up = up_to_u8250p(p); | 1670 | struct uart_8250_port *up = up_to_u8250p(p); |
1671 | unsigned int val; | 1671 | unsigned int val; |
1672 | 1672 | ||
1673 | /* | 1673 | /* |
1674 | * When the Intel ME (management engine) gets reset its serial | 1674 | * When the Intel ME (management engine) gets reset its serial |
1675 | * port registers could return 0 momentarily. Functions like | 1675 | * port registers could return 0 momentarily. Functions like |
1676 | * serial8250_console_write, read and save the IER, perform | 1676 | * serial8250_console_write, read and save the IER, perform |
1677 | * some operation and then restore it. In order to avoid | 1677 | * some operation and then restore it. In order to avoid |
1678 | * setting IER register inadvertently to 0, if the value read | 1678 | * setting IER register inadvertently to 0, if the value read |
1679 | * is 0, double check with ier value in uart_8250_port and use | 1679 | * is 0, double check with ier value in uart_8250_port and use |
1680 | * that instead. up->ier should be the same value as what is | 1680 | * that instead. up->ier should be the same value as what is |
1681 | * currently configured. | 1681 | * currently configured. |
1682 | */ | 1682 | */ |
1683 | val = inb(p->iobase + offset); | 1683 | val = inb(p->iobase + offset); |
1684 | if (offset == UART_IER) { | 1684 | if (offset == UART_IER) { |
1685 | if (val == 0) | 1685 | if (val == 0) |
1686 | val = up->ier; | 1686 | val = up->ier; |
1687 | } | 1687 | } |
1688 | return val; | 1688 | return val; |
1689 | } | 1689 | } |
1690 | 1690 | ||
1691 | static int kt_serial_setup(struct serial_private *priv, | 1691 | static int kt_serial_setup(struct serial_private *priv, |
1692 | const struct pciserial_board *board, | 1692 | const struct pciserial_board *board, |
1693 | struct uart_8250_port *port, int idx) | 1693 | struct uart_8250_port *port, int idx) |
1694 | { | 1694 | { |
1695 | port->port.flags |= UPF_BUG_THRE; | 1695 | port->port.flags |= UPF_BUG_THRE; |
1696 | port->port.serial_in = kt_serial_in; | 1696 | port->port.serial_in = kt_serial_in; |
1697 | port->port.handle_break = kt_handle_break; | 1697 | port->port.handle_break = kt_handle_break; |
1698 | return skip_tx_en_setup(priv, board, port, idx); | 1698 | return skip_tx_en_setup(priv, board, port, idx); |
1699 | } | 1699 | } |
1700 | 1700 | ||
1701 | static int pci_eg20t_init(struct pci_dev *dev) | 1701 | static int pci_eg20t_init(struct pci_dev *dev) |
1702 | { | 1702 | { |
1703 | #if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) | 1703 | #if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) |
1704 | return -ENODEV; | 1704 | return -ENODEV; |
1705 | #else | 1705 | #else |
1706 | return 0; | 1706 | return 0; |
1707 | #endif | 1707 | #endif |
1708 | } | 1708 | } |
1709 | 1709 | ||
1710 | static int | 1710 | static int |
1711 | pci_xr17c154_setup(struct serial_private *priv, | 1711 | pci_xr17c154_setup(struct serial_private *priv, |
1712 | const struct pciserial_board *board, | 1712 | const struct pciserial_board *board, |
1713 | struct uart_8250_port *port, int idx) | 1713 | struct uart_8250_port *port, int idx) |
1714 | { | 1714 | { |
1715 | port->port.flags |= UPF_EXAR_EFR; | 1715 | port->port.flags |= UPF_EXAR_EFR; |
1716 | return pci_default_setup(priv, board, port, idx); | 1716 | return pci_default_setup(priv, board, port, idx); |
1717 | } | 1717 | } |
1718 | 1718 | ||
1719 | static int | 1719 | static int |
1720 | pci_xr17v35x_setup(struct serial_private *priv, | 1720 | pci_xr17v35x_setup(struct serial_private *priv, |
1721 | const struct pciserial_board *board, | 1721 | const struct pciserial_board *board, |
1722 | struct uart_8250_port *port, int idx) | 1722 | struct uart_8250_port *port, int idx) |
1723 | { | 1723 | { |
1724 | u8 __iomem *p; | 1724 | u8 __iomem *p; |
1725 | 1725 | ||
1726 | p = pci_ioremap_bar(priv->dev, 0); | 1726 | p = pci_ioremap_bar(priv->dev, 0); |
1727 | if (p == NULL) | 1727 | if (p == NULL) |
1728 | return -ENOMEM; | 1728 | return -ENOMEM; |
1729 | 1729 | ||
1730 | port->port.flags |= UPF_EXAR_EFR; | 1730 | port->port.flags |= UPF_EXAR_EFR; |
1731 | 1731 | ||
1732 | /* | 1732 | /* |
1733 | * Setup Multipurpose Input/Output pins. | 1733 | * Setup Multipurpose Input/Output pins. |
1734 | */ | 1734 | */ |
1735 | if (idx == 0) { | 1735 | if (idx == 0) { |
1736 | writeb(0x00, p + 0x8f); /*MPIOINT[7:0]*/ | 1736 | writeb(0x00, p + 0x8f); /*MPIOINT[7:0]*/ |
1737 | writeb(0x00, p + 0x90); /*MPIOLVL[7:0]*/ | 1737 | writeb(0x00, p + 0x90); /*MPIOLVL[7:0]*/ |
1738 | writeb(0x00, p + 0x91); /*MPIO3T[7:0]*/ | 1738 | writeb(0x00, p + 0x91); /*MPIO3T[7:0]*/ |
1739 | writeb(0x00, p + 0x92); /*MPIOINV[7:0]*/ | 1739 | writeb(0x00, p + 0x92); /*MPIOINV[7:0]*/ |
1740 | writeb(0x00, p + 0x93); /*MPIOSEL[7:0]*/ | 1740 | writeb(0x00, p + 0x93); /*MPIOSEL[7:0]*/ |
1741 | writeb(0x00, p + 0x94); /*MPIOOD[7:0]*/ | 1741 | writeb(0x00, p + 0x94); /*MPIOOD[7:0]*/ |
1742 | writeb(0x00, p + 0x95); /*MPIOINT[15:8]*/ | 1742 | writeb(0x00, p + 0x95); /*MPIOINT[15:8]*/ |
1743 | writeb(0x00, p + 0x96); /*MPIOLVL[15:8]*/ | 1743 | writeb(0x00, p + 0x96); /*MPIOLVL[15:8]*/ |
1744 | writeb(0x00, p + 0x97); /*MPIO3T[15:8]*/ | 1744 | writeb(0x00, p + 0x97); /*MPIO3T[15:8]*/ |
1745 | writeb(0x00, p + 0x98); /*MPIOINV[15:8]*/ | 1745 | writeb(0x00, p + 0x98); /*MPIOINV[15:8]*/ |
1746 | writeb(0x00, p + 0x99); /*MPIOSEL[15:8]*/ | 1746 | writeb(0x00, p + 0x99); /*MPIOSEL[15:8]*/ |
1747 | writeb(0x00, p + 0x9a); /*MPIOOD[15:8]*/ | 1747 | writeb(0x00, p + 0x9a); /*MPIOOD[15:8]*/ |
1748 | } | 1748 | } |
1749 | writeb(0x00, p + UART_EXAR_8XMODE); | 1749 | writeb(0x00, p + UART_EXAR_8XMODE); |
1750 | writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); | 1750 | writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); |
1751 | writeb(128, p + UART_EXAR_TXTRG); | 1751 | writeb(128, p + UART_EXAR_TXTRG); |
1752 | writeb(128, p + UART_EXAR_RXTRG); | 1752 | writeb(128, p + UART_EXAR_RXTRG); |
1753 | iounmap(p); | 1753 | iounmap(p); |
1754 | 1754 | ||
1755 | return pci_default_setup(priv, board, port, idx); | 1755 | return pci_default_setup(priv, board, port, idx); |
1756 | } | 1756 | } |
1757 | 1757 | ||
1758 | #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 | 1758 | #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 |
1759 | #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 | 1759 | #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 |
1760 | #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a | 1760 | #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a |
1761 | #define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b | 1761 | #define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b |
1762 | 1762 | ||
1763 | static int | 1763 | static int |
1764 | pci_fastcom335_setup(struct serial_private *priv, | 1764 | pci_fastcom335_setup(struct serial_private *priv, |
1765 | const struct pciserial_board *board, | 1765 | const struct pciserial_board *board, |
1766 | struct uart_8250_port *port, int idx) | 1766 | struct uart_8250_port *port, int idx) |
1767 | { | 1767 | { |
1768 | u8 __iomem *p; | 1768 | u8 __iomem *p; |
1769 | 1769 | ||
1770 | p = pci_ioremap_bar(priv->dev, 0); | 1770 | p = pci_ioremap_bar(priv->dev, 0); |
1771 | if (p == NULL) | 1771 | if (p == NULL) |
1772 | return -ENOMEM; | 1772 | return -ENOMEM; |
1773 | 1773 | ||
1774 | port->port.flags |= UPF_EXAR_EFR; | 1774 | port->port.flags |= UPF_EXAR_EFR; |
1775 | 1775 | ||
1776 | /* | 1776 | /* |
1777 | * Setup Multipurpose Input/Output pins. | 1777 | * Setup Multipurpose Input/Output pins. |
1778 | */ | 1778 | */ |
1779 | if (idx == 0) { | 1779 | if (idx == 0) { |
1780 | switch (priv->dev->device) { | 1780 | switch (priv->dev->device) { |
1781 | case PCI_DEVICE_ID_COMMTECH_4222PCI335: | 1781 | case PCI_DEVICE_ID_COMMTECH_4222PCI335: |
1782 | case PCI_DEVICE_ID_COMMTECH_4224PCI335: | 1782 | case PCI_DEVICE_ID_COMMTECH_4224PCI335: |
1783 | writeb(0x78, p + 0x90); /* MPIOLVL[7:0] */ | 1783 | writeb(0x78, p + 0x90); /* MPIOLVL[7:0] */ |
1784 | writeb(0x00, p + 0x92); /* MPIOINV[7:0] */ | 1784 | writeb(0x00, p + 0x92); /* MPIOINV[7:0] */ |
1785 | writeb(0x00, p + 0x93); /* MPIOSEL[7:0] */ | 1785 | writeb(0x00, p + 0x93); /* MPIOSEL[7:0] */ |
1786 | break; | 1786 | break; |
1787 | case PCI_DEVICE_ID_COMMTECH_2324PCI335: | 1787 | case PCI_DEVICE_ID_COMMTECH_2324PCI335: |
1788 | case PCI_DEVICE_ID_COMMTECH_2328PCI335: | 1788 | case PCI_DEVICE_ID_COMMTECH_2328PCI335: |
1789 | writeb(0x00, p + 0x90); /* MPIOLVL[7:0] */ | 1789 | writeb(0x00, p + 0x90); /* MPIOLVL[7:0] */ |
1790 | writeb(0xc0, p + 0x92); /* MPIOINV[7:0] */ | 1790 | writeb(0xc0, p + 0x92); /* MPIOINV[7:0] */ |
1791 | writeb(0xc0, p + 0x93); /* MPIOSEL[7:0] */ | 1791 | writeb(0xc0, p + 0x93); /* MPIOSEL[7:0] */ |
1792 | break; | 1792 | break; |
1793 | } | 1793 | } |
1794 | writeb(0x00, p + 0x8f); /* MPIOINT[7:0] */ | 1794 | writeb(0x00, p + 0x8f); /* MPIOINT[7:0] */ |
1795 | writeb(0x00, p + 0x91); /* MPIO3T[7:0] */ | 1795 | writeb(0x00, p + 0x91); /* MPIO3T[7:0] */ |
1796 | writeb(0x00, p + 0x94); /* MPIOOD[7:0] */ | 1796 | writeb(0x00, p + 0x94); /* MPIOOD[7:0] */ |
1797 | } | 1797 | } |
1798 | writeb(0x00, p + UART_EXAR_8XMODE); | 1798 | writeb(0x00, p + UART_EXAR_8XMODE); |
1799 | writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); | 1799 | writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); |
1800 | writeb(32, p + UART_EXAR_TXTRG); | 1800 | writeb(32, p + UART_EXAR_TXTRG); |
1801 | writeb(32, p + UART_EXAR_RXTRG); | 1801 | writeb(32, p + UART_EXAR_RXTRG); |
1802 | iounmap(p); | 1802 | iounmap(p); |
1803 | 1803 | ||
1804 | return pci_default_setup(priv, board, port, idx); | 1804 | return pci_default_setup(priv, board, port, idx); |
1805 | } | 1805 | } |
1806 | 1806 | ||
1807 | static int | 1807 | static int |
1808 | pci_wch_ch353_setup(struct serial_private *priv, | 1808 | pci_wch_ch353_setup(struct serial_private *priv, |
1809 | const struct pciserial_board *board, | 1809 | const struct pciserial_board *board, |
1810 | struct uart_8250_port *port, int idx) | 1810 | struct uart_8250_port *port, int idx) |
1811 | { | 1811 | { |
1812 | port->port.flags |= UPF_FIXED_TYPE; | 1812 | port->port.flags |= UPF_FIXED_TYPE; |
1813 | port->port.type = PORT_16550A; | 1813 | port->port.type = PORT_16550A; |
1814 | return pci_default_setup(priv, board, port, idx); | 1814 | return pci_default_setup(priv, board, port, idx); |
1815 | } | 1815 | } |
1816 | 1816 | ||
1817 | static int | 1817 | static int |
1818 | pci_wch_ch38x_setup(struct serial_private *priv, | 1818 | pci_wch_ch38x_setup(struct serial_private *priv, |
1819 | const struct pciserial_board *board, | 1819 | const struct pciserial_board *board, |
1820 | struct uart_8250_port *port, int idx) | 1820 | struct uart_8250_port *port, int idx) |
1821 | { | 1821 | { |
1822 | port->port.flags |= UPF_FIXED_TYPE; | 1822 | port->port.flags |= UPF_FIXED_TYPE; |
1823 | port->port.type = PORT_16850; | 1823 | port->port.type = PORT_16850; |
1824 | return pci_default_setup(priv, board, port, idx); | 1824 | return pci_default_setup(priv, board, port, idx); |
1825 | } | 1825 | } |
1826 | 1826 | ||
1827 | #define PCI_VENDOR_ID_SBSMODULARIO 0x124B | 1827 | #define PCI_VENDOR_ID_SBSMODULARIO 0x124B |
1828 | #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B | 1828 | #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B |
1829 | #define PCI_DEVICE_ID_OCTPRO 0x0001 | 1829 | #define PCI_DEVICE_ID_OCTPRO 0x0001 |
1830 | #define PCI_SUBDEVICE_ID_OCTPRO232 0x0108 | 1830 | #define PCI_SUBDEVICE_ID_OCTPRO232 0x0108 |
1831 | #define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 | 1831 | #define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 |
1832 | #define PCI_SUBDEVICE_ID_POCTAL232 0x0308 | 1832 | #define PCI_SUBDEVICE_ID_POCTAL232 0x0308 |
1833 | #define PCI_SUBDEVICE_ID_POCTAL422 0x0408 | 1833 | #define PCI_SUBDEVICE_ID_POCTAL422 0x0408 |
1834 | #define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500 | 1834 | #define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500 |
1835 | #define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530 | 1835 | #define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530 |
1836 | #define PCI_VENDOR_ID_ADVANTECH 0x13fe | 1836 | #define PCI_VENDOR_ID_ADVANTECH 0x13fe |
1837 | #define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 | 1837 | #define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 |
1838 | #define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 | 1838 | #define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 |
1839 | #define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618 | 1839 | #define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618 |
1840 | #define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618 | 1840 | #define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618 |
1841 | #define PCI_DEVICE_ID_TITAN_200I 0x8028 | 1841 | #define PCI_DEVICE_ID_TITAN_200I 0x8028 |
1842 | #define PCI_DEVICE_ID_TITAN_400I 0x8048 | 1842 | #define PCI_DEVICE_ID_TITAN_400I 0x8048 |
1843 | #define PCI_DEVICE_ID_TITAN_800I 0x8088 | 1843 | #define PCI_DEVICE_ID_TITAN_800I 0x8088 |
1844 | #define PCI_DEVICE_ID_TITAN_800EH 0xA007 | 1844 | #define PCI_DEVICE_ID_TITAN_800EH 0xA007 |
1845 | #define PCI_DEVICE_ID_TITAN_800EHB 0xA008 | 1845 | #define PCI_DEVICE_ID_TITAN_800EHB 0xA008 |
1846 | #define PCI_DEVICE_ID_TITAN_400EH 0xA009 | 1846 | #define PCI_DEVICE_ID_TITAN_400EH 0xA009 |
1847 | #define PCI_DEVICE_ID_TITAN_100E 0xA010 | 1847 | #define PCI_DEVICE_ID_TITAN_100E 0xA010 |
1848 | #define PCI_DEVICE_ID_TITAN_200E 0xA012 | 1848 | #define PCI_DEVICE_ID_TITAN_200E 0xA012 |
1849 | #define PCI_DEVICE_ID_TITAN_400E 0xA013 | 1849 | #define PCI_DEVICE_ID_TITAN_400E 0xA013 |
1850 | #define PCI_DEVICE_ID_TITAN_800E 0xA014 | 1850 | #define PCI_DEVICE_ID_TITAN_800E 0xA014 |
1851 | #define PCI_DEVICE_ID_TITAN_200EI 0xA016 | 1851 | #define PCI_DEVICE_ID_TITAN_200EI 0xA016 |
1852 | #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 | 1852 | #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 |
1853 | #define PCI_DEVICE_ID_TITAN_200V3 0xA306 | 1853 | #define PCI_DEVICE_ID_TITAN_200V3 0xA306 |
1854 | #define PCI_DEVICE_ID_TITAN_400V3 0xA310 | 1854 | #define PCI_DEVICE_ID_TITAN_400V3 0xA310 |
1855 | #define PCI_DEVICE_ID_TITAN_410V3 0xA312 | 1855 | #define PCI_DEVICE_ID_TITAN_410V3 0xA312 |
1856 | #define PCI_DEVICE_ID_TITAN_800V3 0xA314 | 1856 | #define PCI_DEVICE_ID_TITAN_800V3 0xA314 |
1857 | #define PCI_DEVICE_ID_TITAN_800V3B 0xA315 | 1857 | #define PCI_DEVICE_ID_TITAN_800V3B 0xA315 |
1858 | #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 | 1858 | #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 |
1859 | #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 | 1859 | #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 |
1860 | #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 | 1860 | #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 |
1861 | #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d | 1861 | #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d |
1862 | #define PCI_VENDOR_ID_WCH 0x4348 | 1862 | #define PCI_VENDOR_ID_WCH 0x4348 |
1863 | #define PCI_DEVICE_ID_WCH_CH352_2S 0x3253 | 1863 | #define PCI_DEVICE_ID_WCH_CH352_2S 0x3253 |
1864 | #define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 | 1864 | #define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 |
1865 | #define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 | 1865 | #define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 |
1866 | #define PCI_DEVICE_ID_WCH_CH353_1S1P 0x5053 | 1866 | #define PCI_DEVICE_ID_WCH_CH353_1S1P 0x5053 |
1867 | #define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 | 1867 | #define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 |
1868 | #define PCI_VENDOR_ID_AGESTAR 0x5372 | 1868 | #define PCI_VENDOR_ID_AGESTAR 0x5372 |
1869 | #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 | 1869 | #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 |
1870 | #define PCI_VENDOR_ID_ASIX 0x9710 | 1870 | #define PCI_VENDOR_ID_ASIX 0x9710 |
1871 | #define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 | 1871 | #define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 |
1872 | #define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 | 1872 | #define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 |
1873 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 | 1873 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 |
1874 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a | 1874 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a |
1875 | #define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e | 1875 | #define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e |
1876 | #define PCI_DEVICE_ID_INTEL_QRK_UART 0x0936 | 1876 | #define PCI_DEVICE_ID_INTEL_QRK_UART 0x0936 |
1877 | 1877 | ||
1878 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 | 1878 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 |
1879 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 | 1879 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 |
1880 | 1880 | ||
1881 | #define PCIE_VENDOR_ID_WCH 0x1c00 | 1881 | #define PCIE_VENDOR_ID_WCH 0x1c00 |
1882 | #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 | 1882 | #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 |
1883 | #define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 | 1883 | #define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 |
1884 | 1884 | ||
1885 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1885 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1886 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1886 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
1887 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 | 1887 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 |
1888 | 1888 | ||
1889 | /* | 1889 | /* |
1890 | * Master list of serial port init/setup/exit quirks. | 1890 | * Master list of serial port init/setup/exit quirks. |
1891 | * This does not describe the general nature of the port. | 1891 | * This does not describe the general nature of the port. |
1892 | * (ie, baud base, number and location of ports, etc) | 1892 | * (ie, baud base, number and location of ports, etc) |
1893 | * | 1893 | * |
1894 | * This list is ordered alphabetically by vendor then device. | 1894 | * This list is ordered alphabetically by vendor then device. |
1895 | * Specific entries must come before more generic entries. | 1895 | * Specific entries must come before more generic entries. |
1896 | */ | 1896 | */ |
1897 | static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | 1897 | static struct pci_serial_quirk pci_serial_quirks[] __refdata = { |
1898 | /* | 1898 | /* |
1899 | * ADDI-DATA GmbH communication cards <info@addi-data.com> | 1899 | * ADDI-DATA GmbH communication cards <info@addi-data.com> |
1900 | */ | 1900 | */ |
1901 | { | 1901 | { |
1902 | .vendor = PCI_VENDOR_ID_AMCC, | 1902 | .vendor = PCI_VENDOR_ID_AMCC, |
1903 | .device = PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800, | 1903 | .device = PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800, |
1904 | .subvendor = PCI_ANY_ID, | 1904 | .subvendor = PCI_ANY_ID, |
1905 | .subdevice = PCI_ANY_ID, | 1905 | .subdevice = PCI_ANY_ID, |
1906 | .setup = addidata_apci7800_setup, | 1906 | .setup = addidata_apci7800_setup, |
1907 | }, | 1907 | }, |
1908 | /* | 1908 | /* |
1909 | * AFAVLAB cards - these may be called via parport_serial | 1909 | * AFAVLAB cards - these may be called via parport_serial |
1910 | * It is not clear whether this applies to all products. | 1910 | * It is not clear whether this applies to all products. |
1911 | */ | 1911 | */ |
1912 | { | 1912 | { |
1913 | .vendor = PCI_VENDOR_ID_AFAVLAB, | 1913 | .vendor = PCI_VENDOR_ID_AFAVLAB, |
1914 | .device = PCI_ANY_ID, | 1914 | .device = PCI_ANY_ID, |
1915 | .subvendor = PCI_ANY_ID, | 1915 | .subvendor = PCI_ANY_ID, |
1916 | .subdevice = PCI_ANY_ID, | 1916 | .subdevice = PCI_ANY_ID, |
1917 | .setup = afavlab_setup, | 1917 | .setup = afavlab_setup, |
1918 | }, | 1918 | }, |
1919 | /* | 1919 | /* |
1920 | * HP Diva | 1920 | * HP Diva |
1921 | */ | 1921 | */ |
1922 | { | 1922 | { |
1923 | .vendor = PCI_VENDOR_ID_HP, | 1923 | .vendor = PCI_VENDOR_ID_HP, |
1924 | .device = PCI_DEVICE_ID_HP_DIVA, | 1924 | .device = PCI_DEVICE_ID_HP_DIVA, |
1925 | .subvendor = PCI_ANY_ID, | 1925 | .subvendor = PCI_ANY_ID, |
1926 | .subdevice = PCI_ANY_ID, | 1926 | .subdevice = PCI_ANY_ID, |
1927 | .init = pci_hp_diva_init, | 1927 | .init = pci_hp_diva_init, |
1928 | .setup = pci_hp_diva_setup, | 1928 | .setup = pci_hp_diva_setup, |
1929 | }, | 1929 | }, |
1930 | /* | 1930 | /* |
1931 | * Intel | 1931 | * Intel |
1932 | */ | 1932 | */ |
1933 | { | 1933 | { |
1934 | .vendor = PCI_VENDOR_ID_INTEL, | 1934 | .vendor = PCI_VENDOR_ID_INTEL, |
1935 | .device = PCI_DEVICE_ID_INTEL_80960_RP, | 1935 | .device = PCI_DEVICE_ID_INTEL_80960_RP, |
1936 | .subvendor = 0xe4bf, | 1936 | .subvendor = 0xe4bf, |
1937 | .subdevice = PCI_ANY_ID, | 1937 | .subdevice = PCI_ANY_ID, |
1938 | .init = pci_inteli960ni_init, | 1938 | .init = pci_inteli960ni_init, |
1939 | .setup = pci_default_setup, | 1939 | .setup = pci_default_setup, |
1940 | }, | 1940 | }, |
1941 | { | 1941 | { |
1942 | .vendor = PCI_VENDOR_ID_INTEL, | 1942 | .vendor = PCI_VENDOR_ID_INTEL, |
1943 | .device = PCI_DEVICE_ID_INTEL_8257X_SOL, | 1943 | .device = PCI_DEVICE_ID_INTEL_8257X_SOL, |
1944 | .subvendor = PCI_ANY_ID, | 1944 | .subvendor = PCI_ANY_ID, |
1945 | .subdevice = PCI_ANY_ID, | 1945 | .subdevice = PCI_ANY_ID, |
1946 | .setup = skip_tx_en_setup, | 1946 | .setup = skip_tx_en_setup, |
1947 | }, | 1947 | }, |
1948 | { | 1948 | { |
1949 | .vendor = PCI_VENDOR_ID_INTEL, | 1949 | .vendor = PCI_VENDOR_ID_INTEL, |
1950 | .device = PCI_DEVICE_ID_INTEL_82573L_SOL, | 1950 | .device = PCI_DEVICE_ID_INTEL_82573L_SOL, |
1951 | .subvendor = PCI_ANY_ID, | 1951 | .subvendor = PCI_ANY_ID, |
1952 | .subdevice = PCI_ANY_ID, | 1952 | .subdevice = PCI_ANY_ID, |
1953 | .setup = skip_tx_en_setup, | 1953 | .setup = skip_tx_en_setup, |
1954 | }, | 1954 | }, |
1955 | { | 1955 | { |
1956 | .vendor = PCI_VENDOR_ID_INTEL, | 1956 | .vendor = PCI_VENDOR_ID_INTEL, |
1957 | .device = PCI_DEVICE_ID_INTEL_82573E_SOL, | 1957 | .device = PCI_DEVICE_ID_INTEL_82573E_SOL, |
1958 | .subvendor = PCI_ANY_ID, | 1958 | .subvendor = PCI_ANY_ID, |
1959 | .subdevice = PCI_ANY_ID, | 1959 | .subdevice = PCI_ANY_ID, |
1960 | .setup = skip_tx_en_setup, | 1960 | .setup = skip_tx_en_setup, |
1961 | }, | 1961 | }, |
1962 | { | 1962 | { |
1963 | .vendor = PCI_VENDOR_ID_INTEL, | 1963 | .vendor = PCI_VENDOR_ID_INTEL, |
1964 | .device = PCI_DEVICE_ID_INTEL_CE4100_UART, | 1964 | .device = PCI_DEVICE_ID_INTEL_CE4100_UART, |
1965 | .subvendor = PCI_ANY_ID, | 1965 | .subvendor = PCI_ANY_ID, |
1966 | .subdevice = PCI_ANY_ID, | 1966 | .subdevice = PCI_ANY_ID, |
1967 | .setup = ce4100_serial_setup, | 1967 | .setup = ce4100_serial_setup, |
1968 | }, | 1968 | }, |
1969 | { | 1969 | { |
1970 | .vendor = PCI_VENDOR_ID_INTEL, | 1970 | .vendor = PCI_VENDOR_ID_INTEL, |
1971 | .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, | 1971 | .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, |
1972 | .subvendor = PCI_ANY_ID, | 1972 | .subvendor = PCI_ANY_ID, |
1973 | .subdevice = PCI_ANY_ID, | 1973 | .subdevice = PCI_ANY_ID, |
1974 | .setup = kt_serial_setup, | 1974 | .setup = kt_serial_setup, |
1975 | }, | 1975 | }, |
1976 | { | 1976 | { |
1977 | .vendor = PCI_VENDOR_ID_INTEL, | 1977 | .vendor = PCI_VENDOR_ID_INTEL, |
1978 | .device = PCI_DEVICE_ID_INTEL_BYT_UART1, | 1978 | .device = PCI_DEVICE_ID_INTEL_BYT_UART1, |
1979 | .subvendor = PCI_ANY_ID, | 1979 | .subvendor = PCI_ANY_ID, |
1980 | .subdevice = PCI_ANY_ID, | 1980 | .subdevice = PCI_ANY_ID, |
1981 | .setup = byt_serial_setup, | 1981 | .setup = byt_serial_setup, |
1982 | }, | 1982 | }, |
1983 | { | 1983 | { |
1984 | .vendor = PCI_VENDOR_ID_INTEL, | 1984 | .vendor = PCI_VENDOR_ID_INTEL, |
1985 | .device = PCI_DEVICE_ID_INTEL_BYT_UART2, | 1985 | .device = PCI_DEVICE_ID_INTEL_BYT_UART2, |
1986 | .subvendor = PCI_ANY_ID, | 1986 | .subvendor = PCI_ANY_ID, |
1987 | .subdevice = PCI_ANY_ID, | 1987 | .subdevice = PCI_ANY_ID, |
1988 | .setup = byt_serial_setup, | 1988 | .setup = byt_serial_setup, |
1989 | }, | 1989 | }, |
1990 | { | 1990 | { |
1991 | .vendor = PCI_VENDOR_ID_INTEL, | 1991 | .vendor = PCI_VENDOR_ID_INTEL, |
1992 | .device = PCI_DEVICE_ID_INTEL_QRK_UART, | ||
1993 | .subvendor = PCI_ANY_ID, | ||
1994 | .subdevice = PCI_ANY_ID, | ||
1995 | .setup = pci_default_setup, | ||
1996 | }, | ||
1997 | { | ||
1998 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1999 | .device = PCI_DEVICE_ID_INTEL_BSW_UART1, | 1992 | .device = PCI_DEVICE_ID_INTEL_BSW_UART1, |
2000 | .subvendor = PCI_ANY_ID, | 1993 | .subvendor = PCI_ANY_ID, |
2001 | .subdevice = PCI_ANY_ID, | 1994 | .subdevice = PCI_ANY_ID, |
2002 | .setup = byt_serial_setup, | 1995 | .setup = byt_serial_setup, |
2003 | }, | 1996 | }, |
2004 | { | 1997 | { |
2005 | .vendor = PCI_VENDOR_ID_INTEL, | 1998 | .vendor = PCI_VENDOR_ID_INTEL, |
2006 | .device = PCI_DEVICE_ID_INTEL_BSW_UART2, | 1999 | .device = PCI_DEVICE_ID_INTEL_BSW_UART2, |
2007 | .subvendor = PCI_ANY_ID, | 2000 | .subvendor = PCI_ANY_ID, |
2008 | .subdevice = PCI_ANY_ID, | 2001 | .subdevice = PCI_ANY_ID, |
2009 | .setup = byt_serial_setup, | 2002 | .setup = byt_serial_setup, |
2010 | }, | 2003 | }, |
2011 | /* | 2004 | /* |
2012 | * ITE | 2005 | * ITE |
2013 | */ | 2006 | */ |
2014 | { | 2007 | { |
2015 | .vendor = PCI_VENDOR_ID_ITE, | 2008 | .vendor = PCI_VENDOR_ID_ITE, |
2016 | .device = PCI_DEVICE_ID_ITE_8872, | 2009 | .device = PCI_DEVICE_ID_ITE_8872, |
2017 | .subvendor = PCI_ANY_ID, | 2010 | .subvendor = PCI_ANY_ID, |
2018 | .subdevice = PCI_ANY_ID, | 2011 | .subdevice = PCI_ANY_ID, |
2019 | .init = pci_ite887x_init, | 2012 | .init = pci_ite887x_init, |
2020 | .setup = pci_default_setup, | 2013 | .setup = pci_default_setup, |
2021 | .exit = pci_ite887x_exit, | 2014 | .exit = pci_ite887x_exit, |
2022 | }, | 2015 | }, |
2023 | /* | 2016 | /* |
2024 | * National Instruments | 2017 | * National Instruments |
2025 | */ | 2018 | */ |
2026 | { | 2019 | { |
2027 | .vendor = PCI_VENDOR_ID_NI, | 2020 | .vendor = PCI_VENDOR_ID_NI, |
2028 | .device = PCI_DEVICE_ID_NI_PCI23216, | 2021 | .device = PCI_DEVICE_ID_NI_PCI23216, |
2029 | .subvendor = PCI_ANY_ID, | 2022 | .subvendor = PCI_ANY_ID, |
2030 | .subdevice = PCI_ANY_ID, | 2023 | .subdevice = PCI_ANY_ID, |
2031 | .init = pci_ni8420_init, | 2024 | .init = pci_ni8420_init, |
2032 | .setup = pci_default_setup, | 2025 | .setup = pci_default_setup, |
2033 | .exit = pci_ni8420_exit, | 2026 | .exit = pci_ni8420_exit, |
2034 | }, | 2027 | }, |
2035 | { | 2028 | { |
2036 | .vendor = PCI_VENDOR_ID_NI, | 2029 | .vendor = PCI_VENDOR_ID_NI, |
2037 | .device = PCI_DEVICE_ID_NI_PCI2328, | 2030 | .device = PCI_DEVICE_ID_NI_PCI2328, |
2038 | .subvendor = PCI_ANY_ID, | 2031 | .subvendor = PCI_ANY_ID, |
2039 | .subdevice = PCI_ANY_ID, | 2032 | .subdevice = PCI_ANY_ID, |
2040 | .init = pci_ni8420_init, | 2033 | .init = pci_ni8420_init, |
2041 | .setup = pci_default_setup, | 2034 | .setup = pci_default_setup, |
2042 | .exit = pci_ni8420_exit, | 2035 | .exit = pci_ni8420_exit, |
2043 | }, | 2036 | }, |
2044 | { | 2037 | { |
2045 | .vendor = PCI_VENDOR_ID_NI, | 2038 | .vendor = PCI_VENDOR_ID_NI, |
2046 | .device = PCI_DEVICE_ID_NI_PCI2324, | 2039 | .device = PCI_DEVICE_ID_NI_PCI2324, |
2047 | .subvendor = PCI_ANY_ID, | 2040 | .subvendor = PCI_ANY_ID, |
2048 | .subdevice = PCI_ANY_ID, | 2041 | .subdevice = PCI_ANY_ID, |
2049 | .init = pci_ni8420_init, | 2042 | .init = pci_ni8420_init, |
2050 | .setup = pci_default_setup, | 2043 | .setup = pci_default_setup, |
2051 | .exit = pci_ni8420_exit, | 2044 | .exit = pci_ni8420_exit, |
2052 | }, | 2045 | }, |
2053 | { | 2046 | { |
2054 | .vendor = PCI_VENDOR_ID_NI, | 2047 | .vendor = PCI_VENDOR_ID_NI, |
2055 | .device = PCI_DEVICE_ID_NI_PCI2322, | 2048 | .device = PCI_DEVICE_ID_NI_PCI2322, |
2056 | .subvendor = PCI_ANY_ID, | 2049 | .subvendor = PCI_ANY_ID, |
2057 | .subdevice = PCI_ANY_ID, | 2050 | .subdevice = PCI_ANY_ID, |
2058 | .init = pci_ni8420_init, | 2051 | .init = pci_ni8420_init, |
2059 | .setup = pci_default_setup, | 2052 | .setup = pci_default_setup, |
2060 | .exit = pci_ni8420_exit, | 2053 | .exit = pci_ni8420_exit, |
2061 | }, | 2054 | }, |
2062 | { | 2055 | { |
2063 | .vendor = PCI_VENDOR_ID_NI, | 2056 | .vendor = PCI_VENDOR_ID_NI, |
2064 | .device = PCI_DEVICE_ID_NI_PCI2324I, | 2057 | .device = PCI_DEVICE_ID_NI_PCI2324I, |
2065 | .subvendor = PCI_ANY_ID, | 2058 | .subvendor = PCI_ANY_ID, |
2066 | .subdevice = PCI_ANY_ID, | 2059 | .subdevice = PCI_ANY_ID, |
2067 | .init = pci_ni8420_init, | 2060 | .init = pci_ni8420_init, |
2068 | .setup = pci_default_setup, | 2061 | .setup = pci_default_setup, |
2069 | .exit = pci_ni8420_exit, | 2062 | .exit = pci_ni8420_exit, |
2070 | }, | 2063 | }, |
2071 | { | 2064 | { |
2072 | .vendor = PCI_VENDOR_ID_NI, | 2065 | .vendor = PCI_VENDOR_ID_NI, |
2073 | .device = PCI_DEVICE_ID_NI_PCI2322I, | 2066 | .device = PCI_DEVICE_ID_NI_PCI2322I, |
2074 | .subvendor = PCI_ANY_ID, | 2067 | .subvendor = PCI_ANY_ID, |
2075 | .subdevice = PCI_ANY_ID, | 2068 | .subdevice = PCI_ANY_ID, |
2076 | .init = pci_ni8420_init, | 2069 | .init = pci_ni8420_init, |
2077 | .setup = pci_default_setup, | 2070 | .setup = pci_default_setup, |
2078 | .exit = pci_ni8420_exit, | 2071 | .exit = pci_ni8420_exit, |
2079 | }, | 2072 | }, |
2080 | { | 2073 | { |
2081 | .vendor = PCI_VENDOR_ID_NI, | 2074 | .vendor = PCI_VENDOR_ID_NI, |
2082 | .device = PCI_DEVICE_ID_NI_PXI8420_23216, | 2075 | .device = PCI_DEVICE_ID_NI_PXI8420_23216, |
2083 | .subvendor = PCI_ANY_ID, | 2076 | .subvendor = PCI_ANY_ID, |
2084 | .subdevice = PCI_ANY_ID, | 2077 | .subdevice = PCI_ANY_ID, |
2085 | .init = pci_ni8420_init, | 2078 | .init = pci_ni8420_init, |
2086 | .setup = pci_default_setup, | 2079 | .setup = pci_default_setup, |
2087 | .exit = pci_ni8420_exit, | 2080 | .exit = pci_ni8420_exit, |
2088 | }, | 2081 | }, |
2089 | { | 2082 | { |
2090 | .vendor = PCI_VENDOR_ID_NI, | 2083 | .vendor = PCI_VENDOR_ID_NI, |
2091 | .device = PCI_DEVICE_ID_NI_PXI8420_2328, | 2084 | .device = PCI_DEVICE_ID_NI_PXI8420_2328, |
2092 | .subvendor = PCI_ANY_ID, | 2085 | .subvendor = PCI_ANY_ID, |
2093 | .subdevice = PCI_ANY_ID, | 2086 | .subdevice = PCI_ANY_ID, |
2094 | .init = pci_ni8420_init, | 2087 | .init = pci_ni8420_init, |
2095 | .setup = pci_default_setup, | 2088 | .setup = pci_default_setup, |
2096 | .exit = pci_ni8420_exit, | 2089 | .exit = pci_ni8420_exit, |
2097 | }, | 2090 | }, |
2098 | { | 2091 | { |
2099 | .vendor = PCI_VENDOR_ID_NI, | 2092 | .vendor = PCI_VENDOR_ID_NI, |
2100 | .device = PCI_DEVICE_ID_NI_PXI8420_2324, | 2093 | .device = PCI_DEVICE_ID_NI_PXI8420_2324, |
2101 | .subvendor = PCI_ANY_ID, | 2094 | .subvendor = PCI_ANY_ID, |
2102 | .subdevice = PCI_ANY_ID, | 2095 | .subdevice = PCI_ANY_ID, |
2103 | .init = pci_ni8420_init, | 2096 | .init = pci_ni8420_init, |
2104 | .setup = pci_default_setup, | 2097 | .setup = pci_default_setup, |
2105 | .exit = pci_ni8420_exit, | 2098 | .exit = pci_ni8420_exit, |
2106 | }, | 2099 | }, |
2107 | { | 2100 | { |
2108 | .vendor = PCI_VENDOR_ID_NI, | 2101 | .vendor = PCI_VENDOR_ID_NI, |
2109 | .device = PCI_DEVICE_ID_NI_PXI8420_2322, | 2102 | .device = PCI_DEVICE_ID_NI_PXI8420_2322, |
2110 | .subvendor = PCI_ANY_ID, | 2103 | .subvendor = PCI_ANY_ID, |
2111 | .subdevice = PCI_ANY_ID, | 2104 | .subdevice = PCI_ANY_ID, |
2112 | .init = pci_ni8420_init, | 2105 | .init = pci_ni8420_init, |
2113 | .setup = pci_default_setup, | 2106 | .setup = pci_default_setup, |
2114 | .exit = pci_ni8420_exit, | 2107 | .exit = pci_ni8420_exit, |
2115 | }, | 2108 | }, |
2116 | { | 2109 | { |
2117 | .vendor = PCI_VENDOR_ID_NI, | 2110 | .vendor = PCI_VENDOR_ID_NI, |
2118 | .device = PCI_DEVICE_ID_NI_PXI8422_2324, | 2111 | .device = PCI_DEVICE_ID_NI_PXI8422_2324, |
2119 | .subvendor = PCI_ANY_ID, | 2112 | .subvendor = PCI_ANY_ID, |
2120 | .subdevice = PCI_ANY_ID, | 2113 | .subdevice = PCI_ANY_ID, |
2121 | .init = pci_ni8420_init, | 2114 | .init = pci_ni8420_init, |
2122 | .setup = pci_default_setup, | 2115 | .setup = pci_default_setup, |
2123 | .exit = pci_ni8420_exit, | 2116 | .exit = pci_ni8420_exit, |
2124 | }, | 2117 | }, |
2125 | { | 2118 | { |
2126 | .vendor = PCI_VENDOR_ID_NI, | 2119 | .vendor = PCI_VENDOR_ID_NI, |
2127 | .device = PCI_DEVICE_ID_NI_PXI8422_2322, | 2120 | .device = PCI_DEVICE_ID_NI_PXI8422_2322, |
2128 | .subvendor = PCI_ANY_ID, | 2121 | .subvendor = PCI_ANY_ID, |
2129 | .subdevice = PCI_ANY_ID, | 2122 | .subdevice = PCI_ANY_ID, |
2130 | .init = pci_ni8420_init, | 2123 | .init = pci_ni8420_init, |
2131 | .setup = pci_default_setup, | 2124 | .setup = pci_default_setup, |
2132 | .exit = pci_ni8420_exit, | 2125 | .exit = pci_ni8420_exit, |
2133 | }, | 2126 | }, |
2134 | { | 2127 | { |
2135 | .vendor = PCI_VENDOR_ID_NI, | 2128 | .vendor = PCI_VENDOR_ID_NI, |
2136 | .device = PCI_ANY_ID, | 2129 | .device = PCI_ANY_ID, |
2137 | .subvendor = PCI_ANY_ID, | 2130 | .subvendor = PCI_ANY_ID, |
2138 | .subdevice = PCI_ANY_ID, | 2131 | .subdevice = PCI_ANY_ID, |
2139 | .init = pci_ni8430_init, | 2132 | .init = pci_ni8430_init, |
2140 | .setup = pci_ni8430_setup, | 2133 | .setup = pci_ni8430_setup, |
2141 | .exit = pci_ni8430_exit, | 2134 | .exit = pci_ni8430_exit, |
2142 | }, | 2135 | }, |
2143 | /* Quatech */ | 2136 | /* Quatech */ |
2144 | { | 2137 | { |
2145 | .vendor = PCI_VENDOR_ID_QUATECH, | 2138 | .vendor = PCI_VENDOR_ID_QUATECH, |
2146 | .device = PCI_ANY_ID, | 2139 | .device = PCI_ANY_ID, |
2147 | .subvendor = PCI_ANY_ID, | 2140 | .subvendor = PCI_ANY_ID, |
2148 | .subdevice = PCI_ANY_ID, | 2141 | .subdevice = PCI_ANY_ID, |
2149 | .init = pci_quatech_init, | 2142 | .init = pci_quatech_init, |
2150 | .setup = pci_quatech_setup, | 2143 | .setup = pci_quatech_setup, |
2151 | .exit = pci_quatech_exit, | 2144 | .exit = pci_quatech_exit, |
2152 | }, | 2145 | }, |
2153 | /* | 2146 | /* |
2154 | * Panacom | 2147 | * Panacom |
2155 | */ | 2148 | */ |
2156 | { | 2149 | { |
2157 | .vendor = PCI_VENDOR_ID_PANACOM, | 2150 | .vendor = PCI_VENDOR_ID_PANACOM, |
2158 | .device = PCI_DEVICE_ID_PANACOM_QUADMODEM, | 2151 | .device = PCI_DEVICE_ID_PANACOM_QUADMODEM, |
2159 | .subvendor = PCI_ANY_ID, | 2152 | .subvendor = PCI_ANY_ID, |
2160 | .subdevice = PCI_ANY_ID, | 2153 | .subdevice = PCI_ANY_ID, |
2161 | .init = pci_plx9050_init, | 2154 | .init = pci_plx9050_init, |
2162 | .setup = pci_default_setup, | 2155 | .setup = pci_default_setup, |
2163 | .exit = pci_plx9050_exit, | 2156 | .exit = pci_plx9050_exit, |
2164 | }, | 2157 | }, |
2165 | { | 2158 | { |
2166 | .vendor = PCI_VENDOR_ID_PANACOM, | 2159 | .vendor = PCI_VENDOR_ID_PANACOM, |
2167 | .device = PCI_DEVICE_ID_PANACOM_DUALMODEM, | 2160 | .device = PCI_DEVICE_ID_PANACOM_DUALMODEM, |
2168 | .subvendor = PCI_ANY_ID, | 2161 | .subvendor = PCI_ANY_ID, |
2169 | .subdevice = PCI_ANY_ID, | 2162 | .subdevice = PCI_ANY_ID, |
2170 | .init = pci_plx9050_init, | 2163 | .init = pci_plx9050_init, |
2171 | .setup = pci_default_setup, | 2164 | .setup = pci_default_setup, |
2172 | .exit = pci_plx9050_exit, | 2165 | .exit = pci_plx9050_exit, |
2173 | }, | 2166 | }, |
2174 | /* | 2167 | /* |
2175 | * Pericom | 2168 | * Pericom |
2176 | */ | 2169 | */ |
2177 | { | 2170 | { |
2178 | .vendor = 0x12d8, | 2171 | .vendor = 0x12d8, |
2179 | .device = 0x7952, | 2172 | .device = 0x7952, |
2180 | .subvendor = PCI_ANY_ID, | 2173 | .subvendor = PCI_ANY_ID, |
2181 | .subdevice = PCI_ANY_ID, | 2174 | .subdevice = PCI_ANY_ID, |
2182 | .setup = pci_pericom_setup, | 2175 | .setup = pci_pericom_setup, |
2183 | }, | 2176 | }, |
2184 | { | 2177 | { |
2185 | .vendor = 0x12d8, | 2178 | .vendor = 0x12d8, |
2186 | .device = 0x7954, | 2179 | .device = 0x7954, |
2187 | .subvendor = PCI_ANY_ID, | 2180 | .subvendor = PCI_ANY_ID, |
2188 | .subdevice = PCI_ANY_ID, | 2181 | .subdevice = PCI_ANY_ID, |
2189 | .setup = pci_pericom_setup, | 2182 | .setup = pci_pericom_setup, |
2190 | }, | 2183 | }, |
2191 | { | 2184 | { |
2192 | .vendor = 0x12d8, | 2185 | .vendor = 0x12d8, |
2193 | .device = 0x7958, | 2186 | .device = 0x7958, |
2194 | .subvendor = PCI_ANY_ID, | 2187 | .subvendor = PCI_ANY_ID, |
2195 | .subdevice = PCI_ANY_ID, | 2188 | .subdevice = PCI_ANY_ID, |
2196 | .setup = pci_pericom_setup, | 2189 | .setup = pci_pericom_setup, |
2197 | }, | 2190 | }, |
2198 | 2191 | ||
2199 | /* | 2192 | /* |
2200 | * PLX | 2193 | * PLX |
2201 | */ | 2194 | */ |
2202 | { | 2195 | { |
2203 | .vendor = PCI_VENDOR_ID_PLX, | 2196 | .vendor = PCI_VENDOR_ID_PLX, |
2204 | .device = PCI_DEVICE_ID_PLX_9030, | ||
2205 | .subvendor = PCI_SUBVENDOR_ID_PERLE, | ||
2206 | .subdevice = PCI_ANY_ID, | ||
2207 | .setup = pci_default_setup, | ||
2208 | }, | ||
2209 | { | ||
2210 | .vendor = PCI_VENDOR_ID_PLX, | ||
2211 | .device = PCI_DEVICE_ID_PLX_9050, | 2197 | .device = PCI_DEVICE_ID_PLX_9050, |
2212 | .subvendor = PCI_SUBVENDOR_ID_EXSYS, | 2198 | .subvendor = PCI_SUBVENDOR_ID_EXSYS, |
2213 | .subdevice = PCI_SUBDEVICE_ID_EXSYS_4055, | 2199 | .subdevice = PCI_SUBDEVICE_ID_EXSYS_4055, |
2214 | .init = pci_plx9050_init, | 2200 | .init = pci_plx9050_init, |
2215 | .setup = pci_default_setup, | 2201 | .setup = pci_default_setup, |
2216 | .exit = pci_plx9050_exit, | 2202 | .exit = pci_plx9050_exit, |
2217 | }, | 2203 | }, |
2218 | { | 2204 | { |
2219 | .vendor = PCI_VENDOR_ID_PLX, | 2205 | .vendor = PCI_VENDOR_ID_PLX, |
2220 | .device = PCI_DEVICE_ID_PLX_9050, | 2206 | .device = PCI_DEVICE_ID_PLX_9050, |
2221 | .subvendor = PCI_SUBVENDOR_ID_KEYSPAN, | 2207 | .subvendor = PCI_SUBVENDOR_ID_KEYSPAN, |
2222 | .subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2, | 2208 | .subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2, |
2223 | .init = pci_plx9050_init, | 2209 | .init = pci_plx9050_init, |
2224 | .setup = pci_default_setup, | 2210 | .setup = pci_default_setup, |
2225 | .exit = pci_plx9050_exit, | 2211 | .exit = pci_plx9050_exit, |
2226 | }, | 2212 | }, |
2227 | { | 2213 | { |
2228 | .vendor = PCI_VENDOR_ID_PLX, | 2214 | .vendor = PCI_VENDOR_ID_PLX, |
2229 | .device = PCI_DEVICE_ID_PLX_ROMULUS, | 2215 | .device = PCI_DEVICE_ID_PLX_ROMULUS, |
2230 | .subvendor = PCI_VENDOR_ID_PLX, | 2216 | .subvendor = PCI_VENDOR_ID_PLX, |
2231 | .subdevice = PCI_DEVICE_ID_PLX_ROMULUS, | 2217 | .subdevice = PCI_DEVICE_ID_PLX_ROMULUS, |
2232 | .init = pci_plx9050_init, | 2218 | .init = pci_plx9050_init, |
2233 | .setup = pci_default_setup, | 2219 | .setup = pci_default_setup, |
2234 | .exit = pci_plx9050_exit, | 2220 | .exit = pci_plx9050_exit, |
2235 | }, | 2221 | }, |
2236 | /* | 2222 | /* |
2237 | * SBS Technologies, Inc., PMC-OCTALPRO 232 | 2223 | * SBS Technologies, Inc., PMC-OCTALPRO 232 |
2238 | */ | 2224 | */ |
2239 | { | 2225 | { |
2240 | .vendor = PCI_VENDOR_ID_SBSMODULARIO, | 2226 | .vendor = PCI_VENDOR_ID_SBSMODULARIO, |
2241 | .device = PCI_DEVICE_ID_OCTPRO, | 2227 | .device = PCI_DEVICE_ID_OCTPRO, |
2242 | .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO, | 2228 | .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO, |
2243 | .subdevice = PCI_SUBDEVICE_ID_OCTPRO232, | 2229 | .subdevice = PCI_SUBDEVICE_ID_OCTPRO232, |
2244 | .init = sbs_init, | 2230 | .init = sbs_init, |
2245 | .setup = sbs_setup, | 2231 | .setup = sbs_setup, |
2246 | .exit = sbs_exit, | 2232 | .exit = sbs_exit, |
2247 | }, | 2233 | }, |
2248 | /* | 2234 | /* |
2249 | * SBS Technologies, Inc., PMC-OCTALPRO 422 | 2235 | * SBS Technologies, Inc., PMC-OCTALPRO 422 |
2250 | */ | 2236 | */ |
2251 | { | 2237 | { |
2252 | .vendor = PCI_VENDOR_ID_SBSMODULARIO, | 2238 | .vendor = PCI_VENDOR_ID_SBSMODULARIO, |
2253 | .device = PCI_DEVICE_ID_OCTPRO, | 2239 | .device = PCI_DEVICE_ID_OCTPRO, |
2254 | .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO, | 2240 | .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO, |
2255 | .subdevice = PCI_SUBDEVICE_ID_OCTPRO422, | 2241 | .subdevice = PCI_SUBDEVICE_ID_OCTPRO422, |
2256 | .init = sbs_init, | 2242 | .init = sbs_init, |
2257 | .setup = sbs_setup, | 2243 | .setup = sbs_setup, |
2258 | .exit = sbs_exit, | 2244 | .exit = sbs_exit, |
2259 | }, | 2245 | }, |
2260 | /* | 2246 | /* |
2261 | * SBS Technologies, Inc., P-Octal 232 | 2247 | * SBS Technologies, Inc., P-Octal 232 |
2262 | */ | 2248 | */ |
2263 | { | 2249 | { |
2264 | .vendor = PCI_VENDOR_ID_SBSMODULARIO, | 2250 | .vendor = PCI_VENDOR_ID_SBSMODULARIO, |
2265 | .device = PCI_DEVICE_ID_OCTPRO, | 2251 | .device = PCI_DEVICE_ID_OCTPRO, |
2266 | .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO, | 2252 | .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO, |
2267 | .subdevice = PCI_SUBDEVICE_ID_POCTAL232, | 2253 | .subdevice = PCI_SUBDEVICE_ID_POCTAL232, |
2268 | .init = sbs_init, | 2254 | .init = sbs_init, |
2269 | .setup = sbs_setup, | 2255 | .setup = sbs_setup, |
2270 | .exit = sbs_exit, | 2256 | .exit = sbs_exit, |
2271 | }, | 2257 | }, |
2272 | /* | 2258 | /* |
2273 | * SBS Technologies, Inc., P-Octal 422 | 2259 | * SBS Technologies, Inc., P-Octal 422 |
2274 | */ | 2260 | */ |
2275 | { | 2261 | { |
2276 | .vendor = PCI_VENDOR_ID_SBSMODULARIO, | 2262 | .vendor = PCI_VENDOR_ID_SBSMODULARIO, |
2277 | .device = PCI_DEVICE_ID_OCTPRO, | 2263 | .device = PCI_DEVICE_ID_OCTPRO, |
2278 | .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO, | 2264 | .subvendor = PCI_SUBVENDOR_ID_SBSMODULARIO, |
2279 | .subdevice = PCI_SUBDEVICE_ID_POCTAL422, | 2265 | .subdevice = PCI_SUBDEVICE_ID_POCTAL422, |
2280 | .init = sbs_init, | 2266 | .init = sbs_init, |
2281 | .setup = sbs_setup, | 2267 | .setup = sbs_setup, |
2282 | .exit = sbs_exit, | 2268 | .exit = sbs_exit, |
2283 | }, | 2269 | }, |
2284 | /* | 2270 | /* |
2285 | * SIIG cards - these may be called via parport_serial | 2271 | * SIIG cards - these may be called via parport_serial |
2286 | */ | 2272 | */ |
2287 | { | 2273 | { |
2288 | .vendor = PCI_VENDOR_ID_SIIG, | 2274 | .vendor = PCI_VENDOR_ID_SIIG, |
2289 | .device = PCI_ANY_ID, | 2275 | .device = PCI_ANY_ID, |
2290 | .subvendor = PCI_ANY_ID, | 2276 | .subvendor = PCI_ANY_ID, |
2291 | .subdevice = PCI_ANY_ID, | 2277 | .subdevice = PCI_ANY_ID, |
2292 | .init = pci_siig_init, | 2278 | .init = pci_siig_init, |
2293 | .setup = pci_siig_setup, | 2279 | .setup = pci_siig_setup, |
2294 | }, | 2280 | }, |
2295 | /* | 2281 | /* |
2296 | * Titan cards | 2282 | * Titan cards |
2297 | */ | 2283 | */ |
2298 | { | 2284 | { |
2299 | .vendor = PCI_VENDOR_ID_TITAN, | 2285 | .vendor = PCI_VENDOR_ID_TITAN, |
2300 | .device = PCI_DEVICE_ID_TITAN_400L, | 2286 | .device = PCI_DEVICE_ID_TITAN_400L, |
2301 | .subvendor = PCI_ANY_ID, | 2287 | .subvendor = PCI_ANY_ID, |
2302 | .subdevice = PCI_ANY_ID, | 2288 | .subdevice = PCI_ANY_ID, |
2303 | .setup = titan_400l_800l_setup, | 2289 | .setup = titan_400l_800l_setup, |
2304 | }, | 2290 | }, |
2305 | { | 2291 | { |
2306 | .vendor = PCI_VENDOR_ID_TITAN, | 2292 | .vendor = PCI_VENDOR_ID_TITAN, |
2307 | .device = PCI_DEVICE_ID_TITAN_800L, | 2293 | .device = PCI_DEVICE_ID_TITAN_800L, |
2308 | .subvendor = PCI_ANY_ID, | 2294 | .subvendor = PCI_ANY_ID, |
2309 | .subdevice = PCI_ANY_ID, | 2295 | .subdevice = PCI_ANY_ID, |
2310 | .setup = titan_400l_800l_setup, | 2296 | .setup = titan_400l_800l_setup, |
2311 | }, | 2297 | }, |
2312 | /* | 2298 | /* |
2313 | * Timedia cards | 2299 | * Timedia cards |
2314 | */ | 2300 | */ |
2315 | { | 2301 | { |
2316 | .vendor = PCI_VENDOR_ID_TIMEDIA, | 2302 | .vendor = PCI_VENDOR_ID_TIMEDIA, |
2317 | .device = PCI_DEVICE_ID_TIMEDIA_1889, | 2303 | .device = PCI_DEVICE_ID_TIMEDIA_1889, |
2318 | .subvendor = PCI_VENDOR_ID_TIMEDIA, | 2304 | .subvendor = PCI_VENDOR_ID_TIMEDIA, |
2319 | .subdevice = PCI_ANY_ID, | 2305 | .subdevice = PCI_ANY_ID, |
2320 | .probe = pci_timedia_probe, | 2306 | .probe = pci_timedia_probe, |
2321 | .init = pci_timedia_init, | 2307 | .init = pci_timedia_init, |
2322 | .setup = pci_timedia_setup, | 2308 | .setup = pci_timedia_setup, |
2323 | }, | 2309 | }, |
2324 | { | 2310 | { |
2325 | .vendor = PCI_VENDOR_ID_TIMEDIA, | 2311 | .vendor = PCI_VENDOR_ID_TIMEDIA, |
2326 | .device = PCI_ANY_ID, | 2312 | .device = PCI_ANY_ID, |
2327 | .subvendor = PCI_ANY_ID, | 2313 | .subvendor = PCI_ANY_ID, |
2328 | .subdevice = PCI_ANY_ID, | 2314 | .subdevice = PCI_ANY_ID, |
2329 | .setup = pci_timedia_setup, | 2315 | .setup = pci_timedia_setup, |
2330 | }, | 2316 | }, |
2331 | /* | 2317 | /* |
2332 | * SUNIX (Timedia) cards | 2318 | * SUNIX (Timedia) cards |
2333 | * Do not "probe" for these cards as there is at least one combination | 2319 | * Do not "probe" for these cards as there is at least one combination |
2334 | * card that should be handled by parport_pc that doesn't match the | 2320 | * card that should be handled by parport_pc that doesn't match the |
2335 | * rule in pci_timedia_probe. | 2321 | * rule in pci_timedia_probe. |
2336 | * It is part number is MIO5079A but its subdevice ID is 0x0102. | 2322 | * It is part number is MIO5079A but its subdevice ID is 0x0102. |
2337 | * There are some boards with part number SER5037AL that report | 2323 | * There are some boards with part number SER5037AL that report |
2338 | * subdevice ID 0x0002. | 2324 | * subdevice ID 0x0002. |
2339 | */ | 2325 | */ |
2340 | { | 2326 | { |
2341 | .vendor = PCI_VENDOR_ID_SUNIX, | 2327 | .vendor = PCI_VENDOR_ID_SUNIX, |
2342 | .device = PCI_DEVICE_ID_SUNIX_1999, | 2328 | .device = PCI_DEVICE_ID_SUNIX_1999, |
2343 | .subvendor = PCI_VENDOR_ID_SUNIX, | 2329 | .subvendor = PCI_VENDOR_ID_SUNIX, |
2344 | .subdevice = PCI_ANY_ID, | 2330 | .subdevice = PCI_ANY_ID, |
2345 | .init = pci_timedia_init, | 2331 | .init = pci_timedia_init, |
2346 | .setup = pci_timedia_setup, | 2332 | .setup = pci_timedia_setup, |
2347 | }, | 2333 | }, |
2348 | /* | 2334 | /* |
2349 | * Exar cards | 2335 | * Exar cards |
2350 | */ | 2336 | */ |
2351 | { | 2337 | { |
2352 | .vendor = PCI_VENDOR_ID_EXAR, | 2338 | .vendor = PCI_VENDOR_ID_EXAR, |
2353 | .device = PCI_DEVICE_ID_EXAR_XR17C152, | 2339 | .device = PCI_DEVICE_ID_EXAR_XR17C152, |
2354 | .subvendor = PCI_ANY_ID, | 2340 | .subvendor = PCI_ANY_ID, |
2355 | .subdevice = PCI_ANY_ID, | 2341 | .subdevice = PCI_ANY_ID, |
2356 | .setup = pci_xr17c154_setup, | 2342 | .setup = pci_xr17c154_setup, |
2357 | }, | 2343 | }, |
2358 | { | 2344 | { |
2359 | .vendor = PCI_VENDOR_ID_EXAR, | 2345 | .vendor = PCI_VENDOR_ID_EXAR, |
2360 | .device = PCI_DEVICE_ID_EXAR_XR17C154, | 2346 | .device = PCI_DEVICE_ID_EXAR_XR17C154, |
2361 | .subvendor = PCI_ANY_ID, | 2347 | .subvendor = PCI_ANY_ID, |
2362 | .subdevice = PCI_ANY_ID, | 2348 | .subdevice = PCI_ANY_ID, |
2363 | .setup = pci_xr17c154_setup, | 2349 | .setup = pci_xr17c154_setup, |
2364 | }, | 2350 | }, |
2365 | { | 2351 | { |
2366 | .vendor = PCI_VENDOR_ID_EXAR, | 2352 | .vendor = PCI_VENDOR_ID_EXAR, |
2367 | .device = PCI_DEVICE_ID_EXAR_XR17C158, | 2353 | .device = PCI_DEVICE_ID_EXAR_XR17C158, |
2368 | .subvendor = PCI_ANY_ID, | 2354 | .subvendor = PCI_ANY_ID, |
2369 | .subdevice = PCI_ANY_ID, | 2355 | .subdevice = PCI_ANY_ID, |
2370 | .setup = pci_xr17c154_setup, | 2356 | .setup = pci_xr17c154_setup, |
2371 | }, | 2357 | }, |
2372 | { | 2358 | { |
2373 | .vendor = PCI_VENDOR_ID_EXAR, | 2359 | .vendor = PCI_VENDOR_ID_EXAR, |
2374 | .device = PCI_DEVICE_ID_EXAR_XR17V352, | 2360 | .device = PCI_DEVICE_ID_EXAR_XR17V352, |
2375 | .subvendor = PCI_ANY_ID, | 2361 | .subvendor = PCI_ANY_ID, |
2376 | .subdevice = PCI_ANY_ID, | 2362 | .subdevice = PCI_ANY_ID, |
2377 | .setup = pci_xr17v35x_setup, | 2363 | .setup = pci_xr17v35x_setup, |
2378 | }, | 2364 | }, |
2379 | { | 2365 | { |
2380 | .vendor = PCI_VENDOR_ID_EXAR, | 2366 | .vendor = PCI_VENDOR_ID_EXAR, |
2381 | .device = PCI_DEVICE_ID_EXAR_XR17V354, | 2367 | .device = PCI_DEVICE_ID_EXAR_XR17V354, |
2382 | .subvendor = PCI_ANY_ID, | 2368 | .subvendor = PCI_ANY_ID, |
2383 | .subdevice = PCI_ANY_ID, | 2369 | .subdevice = PCI_ANY_ID, |
2384 | .setup = pci_xr17v35x_setup, | 2370 | .setup = pci_xr17v35x_setup, |
2385 | }, | 2371 | }, |
2386 | { | 2372 | { |
2387 | .vendor = PCI_VENDOR_ID_EXAR, | 2373 | .vendor = PCI_VENDOR_ID_EXAR, |
2388 | .device = PCI_DEVICE_ID_EXAR_XR17V358, | 2374 | .device = PCI_DEVICE_ID_EXAR_XR17V358, |
2389 | .subvendor = PCI_ANY_ID, | 2375 | .subvendor = PCI_ANY_ID, |
2390 | .subdevice = PCI_ANY_ID, | 2376 | .subdevice = PCI_ANY_ID, |
2391 | .setup = pci_xr17v35x_setup, | 2377 | .setup = pci_xr17v35x_setup, |
2392 | }, | 2378 | }, |
2393 | /* | 2379 | /* |
2394 | * Xircom cards | 2380 | * Xircom cards |
2395 | */ | 2381 | */ |
2396 | { | 2382 | { |
2397 | .vendor = PCI_VENDOR_ID_XIRCOM, | 2383 | .vendor = PCI_VENDOR_ID_XIRCOM, |
2398 | .device = PCI_DEVICE_ID_XIRCOM_X3201_MDM, | 2384 | .device = PCI_DEVICE_ID_XIRCOM_X3201_MDM, |
2399 | .subvendor = PCI_ANY_ID, | 2385 | .subvendor = PCI_ANY_ID, |
2400 | .subdevice = PCI_ANY_ID, | 2386 | .subdevice = PCI_ANY_ID, |
2401 | .init = pci_xircom_init, | 2387 | .init = pci_xircom_init, |
2402 | .setup = pci_default_setup, | 2388 | .setup = pci_default_setup, |
2403 | }, | 2389 | }, |
2404 | /* | 2390 | /* |
2405 | * Netmos cards - these may be called via parport_serial | 2391 | * Netmos cards - these may be called via parport_serial |
2406 | */ | 2392 | */ |
2407 | { | 2393 | { |
2408 | .vendor = PCI_VENDOR_ID_NETMOS, | 2394 | .vendor = PCI_VENDOR_ID_NETMOS, |
2409 | .device = PCI_ANY_ID, | 2395 | .device = PCI_ANY_ID, |
2410 | .subvendor = PCI_ANY_ID, | 2396 | .subvendor = PCI_ANY_ID, |
2411 | .subdevice = PCI_ANY_ID, | 2397 | .subdevice = PCI_ANY_ID, |
2412 | .init = pci_netmos_init, | 2398 | .init = pci_netmos_init, |
2413 | .setup = pci_netmos_9900_setup, | 2399 | .setup = pci_netmos_9900_setup, |
2414 | }, | 2400 | }, |
2415 | /* | 2401 | /* |
2416 | * EndRun Technologies | 2402 | * EndRun Technologies |
2417 | */ | 2403 | */ |
2418 | { | 2404 | { |
2419 | .vendor = PCI_VENDOR_ID_ENDRUN, | 2405 | .vendor = PCI_VENDOR_ID_ENDRUN, |
2420 | .device = PCI_ANY_ID, | 2406 | .device = PCI_ANY_ID, |
2421 | .subvendor = PCI_ANY_ID, | 2407 | .subvendor = PCI_ANY_ID, |
2422 | .subdevice = PCI_ANY_ID, | 2408 | .subdevice = PCI_ANY_ID, |
2423 | .init = pci_endrun_init, | 2409 | .init = pci_endrun_init, |
2424 | .setup = pci_default_setup, | 2410 | .setup = pci_default_setup, |
2425 | }, | 2411 | }, |
2426 | /* | 2412 | /* |
2427 | * For Oxford Semiconductor Tornado based devices | 2413 | * For Oxford Semiconductor Tornado based devices |
2428 | */ | 2414 | */ |
2429 | { | 2415 | { |
2430 | .vendor = PCI_VENDOR_ID_OXSEMI, | 2416 | .vendor = PCI_VENDOR_ID_OXSEMI, |
2431 | .device = PCI_ANY_ID, | 2417 | .device = PCI_ANY_ID, |
2432 | .subvendor = PCI_ANY_ID, | 2418 | .subvendor = PCI_ANY_ID, |
2433 | .subdevice = PCI_ANY_ID, | 2419 | .subdevice = PCI_ANY_ID, |
2434 | .init = pci_oxsemi_tornado_init, | 2420 | .init = pci_oxsemi_tornado_init, |
2435 | .setup = pci_default_setup, | 2421 | .setup = pci_default_setup, |
2436 | }, | 2422 | }, |
2437 | { | 2423 | { |
2438 | .vendor = PCI_VENDOR_ID_MAINPINE, | 2424 | .vendor = PCI_VENDOR_ID_MAINPINE, |
2439 | .device = PCI_ANY_ID, | 2425 | .device = PCI_ANY_ID, |
2440 | .subvendor = PCI_ANY_ID, | 2426 | .subvendor = PCI_ANY_ID, |
2441 | .subdevice = PCI_ANY_ID, | 2427 | .subdevice = PCI_ANY_ID, |
2442 | .init = pci_oxsemi_tornado_init, | 2428 | .init = pci_oxsemi_tornado_init, |
2443 | .setup = pci_default_setup, | 2429 | .setup = pci_default_setup, |
2444 | }, | 2430 | }, |
2445 | { | 2431 | { |
2446 | .vendor = PCI_VENDOR_ID_DIGI, | 2432 | .vendor = PCI_VENDOR_ID_DIGI, |
2447 | .device = PCIE_DEVICE_ID_NEO_2_OX_IBM, | 2433 | .device = PCIE_DEVICE_ID_NEO_2_OX_IBM, |
2448 | .subvendor = PCI_SUBVENDOR_ID_IBM, | 2434 | .subvendor = PCI_SUBVENDOR_ID_IBM, |
2449 | .subdevice = PCI_ANY_ID, | 2435 | .subdevice = PCI_ANY_ID, |
2450 | .init = pci_oxsemi_tornado_init, | 2436 | .init = pci_oxsemi_tornado_init, |
2451 | .setup = pci_default_setup, | 2437 | .setup = pci_default_setup, |
2452 | }, | 2438 | }, |
2453 | { | 2439 | { |
2454 | .vendor = PCI_VENDOR_ID_INTEL, | 2440 | .vendor = PCI_VENDOR_ID_INTEL, |
2455 | .device = 0x8811, | 2441 | .device = 0x8811, |
2456 | .subvendor = PCI_ANY_ID, | 2442 | .subvendor = PCI_ANY_ID, |
2457 | .subdevice = PCI_ANY_ID, | 2443 | .subdevice = PCI_ANY_ID, |
2458 | .init = pci_eg20t_init, | 2444 | .init = pci_eg20t_init, |
2459 | .setup = pci_default_setup, | 2445 | .setup = pci_default_setup, |
2460 | }, | 2446 | }, |
2461 | { | 2447 | { |
2462 | .vendor = PCI_VENDOR_ID_INTEL, | 2448 | .vendor = PCI_VENDOR_ID_INTEL, |
2463 | .device = 0x8812, | 2449 | .device = 0x8812, |
2464 | .subvendor = PCI_ANY_ID, | 2450 | .subvendor = PCI_ANY_ID, |
2465 | .subdevice = PCI_ANY_ID, | 2451 | .subdevice = PCI_ANY_ID, |
2466 | .init = pci_eg20t_init, | 2452 | .init = pci_eg20t_init, |
2467 | .setup = pci_default_setup, | 2453 | .setup = pci_default_setup, |
2468 | }, | 2454 | }, |
2469 | { | 2455 | { |
2470 | .vendor = PCI_VENDOR_ID_INTEL, | 2456 | .vendor = PCI_VENDOR_ID_INTEL, |
2471 | .device = 0x8813, | 2457 | .device = 0x8813, |
2472 | .subvendor = PCI_ANY_ID, | 2458 | .subvendor = PCI_ANY_ID, |
2473 | .subdevice = PCI_ANY_ID, | 2459 | .subdevice = PCI_ANY_ID, |
2474 | .init = pci_eg20t_init, | 2460 | .init = pci_eg20t_init, |
2475 | .setup = pci_default_setup, | 2461 | .setup = pci_default_setup, |
2476 | }, | 2462 | }, |
2477 | { | 2463 | { |
2478 | .vendor = PCI_VENDOR_ID_INTEL, | 2464 | .vendor = PCI_VENDOR_ID_INTEL, |
2479 | .device = 0x8814, | 2465 | .device = 0x8814, |
2480 | .subvendor = PCI_ANY_ID, | 2466 | .subvendor = PCI_ANY_ID, |
2481 | .subdevice = PCI_ANY_ID, | 2467 | .subdevice = PCI_ANY_ID, |
2482 | .init = pci_eg20t_init, | 2468 | .init = pci_eg20t_init, |
2483 | .setup = pci_default_setup, | 2469 | .setup = pci_default_setup, |
2484 | }, | 2470 | }, |
2485 | { | 2471 | { |
2486 | .vendor = 0x10DB, | 2472 | .vendor = 0x10DB, |
2487 | .device = 0x8027, | 2473 | .device = 0x8027, |
2488 | .subvendor = PCI_ANY_ID, | 2474 | .subvendor = PCI_ANY_ID, |
2489 | .subdevice = PCI_ANY_ID, | 2475 | .subdevice = PCI_ANY_ID, |
2490 | .init = pci_eg20t_init, | 2476 | .init = pci_eg20t_init, |
2491 | .setup = pci_default_setup, | 2477 | .setup = pci_default_setup, |
2492 | }, | 2478 | }, |
2493 | { | 2479 | { |
2494 | .vendor = 0x10DB, | 2480 | .vendor = 0x10DB, |
2495 | .device = 0x8028, | 2481 | .device = 0x8028, |
2496 | .subvendor = PCI_ANY_ID, | 2482 | .subvendor = PCI_ANY_ID, |
2497 | .subdevice = PCI_ANY_ID, | 2483 | .subdevice = PCI_ANY_ID, |
2498 | .init = pci_eg20t_init, | 2484 | .init = pci_eg20t_init, |
2499 | .setup = pci_default_setup, | 2485 | .setup = pci_default_setup, |
2500 | }, | 2486 | }, |
2501 | { | 2487 | { |
2502 | .vendor = 0x10DB, | 2488 | .vendor = 0x10DB, |
2503 | .device = 0x8029, | 2489 | .device = 0x8029, |
2504 | .subvendor = PCI_ANY_ID, | 2490 | .subvendor = PCI_ANY_ID, |
2505 | .subdevice = PCI_ANY_ID, | 2491 | .subdevice = PCI_ANY_ID, |
2506 | .init = pci_eg20t_init, | 2492 | .init = pci_eg20t_init, |
2507 | .setup = pci_default_setup, | 2493 | .setup = pci_default_setup, |
2508 | }, | 2494 | }, |
2509 | { | 2495 | { |
2510 | .vendor = 0x10DB, | 2496 | .vendor = 0x10DB, |
2511 | .device = 0x800C, | 2497 | .device = 0x800C, |
2512 | .subvendor = PCI_ANY_ID, | 2498 | .subvendor = PCI_ANY_ID, |
2513 | .subdevice = PCI_ANY_ID, | 2499 | .subdevice = PCI_ANY_ID, |
2514 | .init = pci_eg20t_init, | 2500 | .init = pci_eg20t_init, |
2515 | .setup = pci_default_setup, | 2501 | .setup = pci_default_setup, |
2516 | }, | 2502 | }, |
2517 | { | 2503 | { |
2518 | .vendor = 0x10DB, | 2504 | .vendor = 0x10DB, |
2519 | .device = 0x800D, | 2505 | .device = 0x800D, |
2520 | .subvendor = PCI_ANY_ID, | 2506 | .subvendor = PCI_ANY_ID, |
2521 | .subdevice = PCI_ANY_ID, | 2507 | .subdevice = PCI_ANY_ID, |
2522 | .init = pci_eg20t_init, | 2508 | .init = pci_eg20t_init, |
2523 | .setup = pci_default_setup, | 2509 | .setup = pci_default_setup, |
2524 | }, | 2510 | }, |
2525 | /* | 2511 | /* |
2526 | * Cronyx Omega PCI (PLX-chip based) | 2512 | * Cronyx Omega PCI (PLX-chip based) |
2527 | */ | 2513 | */ |
2528 | { | 2514 | { |
2529 | .vendor = PCI_VENDOR_ID_PLX, | 2515 | .vendor = PCI_VENDOR_ID_PLX, |
2530 | .device = PCI_DEVICE_ID_PLX_CRONYX_OMEGA, | 2516 | .device = PCI_DEVICE_ID_PLX_CRONYX_OMEGA, |
2531 | .subvendor = PCI_ANY_ID, | 2517 | .subvendor = PCI_ANY_ID, |
2532 | .subdevice = PCI_ANY_ID, | 2518 | .subdevice = PCI_ANY_ID, |
2533 | .setup = pci_omegapci_setup, | 2519 | .setup = pci_omegapci_setup, |
2534 | }, | 2520 | }, |
2535 | /* WCH CH353 1S1P card (16550 clone) */ | 2521 | /* WCH CH353 1S1P card (16550 clone) */ |
2536 | { | 2522 | { |
2537 | .vendor = PCI_VENDOR_ID_WCH, | 2523 | .vendor = PCI_VENDOR_ID_WCH, |
2538 | .device = PCI_DEVICE_ID_WCH_CH353_1S1P, | 2524 | .device = PCI_DEVICE_ID_WCH_CH353_1S1P, |
2539 | .subvendor = PCI_ANY_ID, | 2525 | .subvendor = PCI_ANY_ID, |
2540 | .subdevice = PCI_ANY_ID, | 2526 | .subdevice = PCI_ANY_ID, |
2541 | .setup = pci_wch_ch353_setup, | 2527 | .setup = pci_wch_ch353_setup, |
2542 | }, | 2528 | }, |
2543 | /* WCH CH353 2S1P card (16550 clone) */ | 2529 | /* WCH CH353 2S1P card (16550 clone) */ |
2544 | { | 2530 | { |
2545 | .vendor = PCI_VENDOR_ID_WCH, | 2531 | .vendor = PCI_VENDOR_ID_WCH, |
2546 | .device = PCI_DEVICE_ID_WCH_CH353_2S1P, | 2532 | .device = PCI_DEVICE_ID_WCH_CH353_2S1P, |
2547 | .subvendor = PCI_ANY_ID, | 2533 | .subvendor = PCI_ANY_ID, |
2548 | .subdevice = PCI_ANY_ID, | 2534 | .subdevice = PCI_ANY_ID, |
2549 | .setup = pci_wch_ch353_setup, | 2535 | .setup = pci_wch_ch353_setup, |
2550 | }, | 2536 | }, |
2551 | /* WCH CH353 4S card (16550 clone) */ | 2537 | /* WCH CH353 4S card (16550 clone) */ |
2552 | { | 2538 | { |
2553 | .vendor = PCI_VENDOR_ID_WCH, | 2539 | .vendor = PCI_VENDOR_ID_WCH, |
2554 | .device = PCI_DEVICE_ID_WCH_CH353_4S, | 2540 | .device = PCI_DEVICE_ID_WCH_CH353_4S, |
2555 | .subvendor = PCI_ANY_ID, | 2541 | .subvendor = PCI_ANY_ID, |
2556 | .subdevice = PCI_ANY_ID, | 2542 | .subdevice = PCI_ANY_ID, |
2557 | .setup = pci_wch_ch353_setup, | 2543 | .setup = pci_wch_ch353_setup, |
2558 | }, | 2544 | }, |
2559 | /* WCH CH353 2S1PF card (16550 clone) */ | 2545 | /* WCH CH353 2S1PF card (16550 clone) */ |
2560 | { | 2546 | { |
2561 | .vendor = PCI_VENDOR_ID_WCH, | 2547 | .vendor = PCI_VENDOR_ID_WCH, |
2562 | .device = PCI_DEVICE_ID_WCH_CH353_2S1PF, | 2548 | .device = PCI_DEVICE_ID_WCH_CH353_2S1PF, |
2563 | .subvendor = PCI_ANY_ID, | 2549 | .subvendor = PCI_ANY_ID, |
2564 | .subdevice = PCI_ANY_ID, | 2550 | .subdevice = PCI_ANY_ID, |
2565 | .setup = pci_wch_ch353_setup, | 2551 | .setup = pci_wch_ch353_setup, |
2566 | }, | 2552 | }, |
2567 | /* WCH CH352 2S card (16550 clone) */ | 2553 | /* WCH CH352 2S card (16550 clone) */ |
2568 | { | 2554 | { |
2569 | .vendor = PCI_VENDOR_ID_WCH, | 2555 | .vendor = PCI_VENDOR_ID_WCH, |
2570 | .device = PCI_DEVICE_ID_WCH_CH352_2S, | 2556 | .device = PCI_DEVICE_ID_WCH_CH352_2S, |
2571 | .subvendor = PCI_ANY_ID, | 2557 | .subvendor = PCI_ANY_ID, |
2572 | .subdevice = PCI_ANY_ID, | 2558 | .subdevice = PCI_ANY_ID, |
2573 | .setup = pci_wch_ch353_setup, | 2559 | .setup = pci_wch_ch353_setup, |
2574 | }, | 2560 | }, |
2575 | /* WCH CH382 2S1P card (16850 clone) */ | 2561 | /* WCH CH382 2S1P card (16850 clone) */ |
2576 | { | 2562 | { |
2577 | .vendor = PCIE_VENDOR_ID_WCH, | 2563 | .vendor = PCIE_VENDOR_ID_WCH, |
2578 | .device = PCIE_DEVICE_ID_WCH_CH382_2S1P, | 2564 | .device = PCIE_DEVICE_ID_WCH_CH382_2S1P, |
2579 | .subvendor = PCI_ANY_ID, | 2565 | .subvendor = PCI_ANY_ID, |
2580 | .subdevice = PCI_ANY_ID, | 2566 | .subdevice = PCI_ANY_ID, |
2581 | .setup = pci_wch_ch38x_setup, | 2567 | .setup = pci_wch_ch38x_setup, |
2582 | }, | 2568 | }, |
2583 | /* WCH CH384 4S card (16850 clone) */ | 2569 | /* WCH CH384 4S card (16850 clone) */ |
2584 | { | 2570 | { |
2585 | .vendor = PCIE_VENDOR_ID_WCH, | 2571 | .vendor = PCIE_VENDOR_ID_WCH, |
2586 | .device = PCIE_DEVICE_ID_WCH_CH384_4S, | 2572 | .device = PCIE_DEVICE_ID_WCH_CH384_4S, |
2587 | .subvendor = PCI_ANY_ID, | 2573 | .subvendor = PCI_ANY_ID, |
2588 | .subdevice = PCI_ANY_ID, | 2574 | .subdevice = PCI_ANY_ID, |
2589 | .setup = pci_wch_ch38x_setup, | 2575 | .setup = pci_wch_ch38x_setup, |
2590 | }, | 2576 | }, |
2591 | /* | 2577 | /* |
2592 | * ASIX devices with FIFO bug | 2578 | * ASIX devices with FIFO bug |
2593 | */ | 2579 | */ |
2594 | { | 2580 | { |
2595 | .vendor = PCI_VENDOR_ID_ASIX, | 2581 | .vendor = PCI_VENDOR_ID_ASIX, |
2596 | .device = PCI_ANY_ID, | 2582 | .device = PCI_ANY_ID, |
2597 | .subvendor = PCI_ANY_ID, | 2583 | .subvendor = PCI_ANY_ID, |
2598 | .subdevice = PCI_ANY_ID, | 2584 | .subdevice = PCI_ANY_ID, |
2599 | .setup = pci_asix_setup, | 2585 | .setup = pci_asix_setup, |
2600 | }, | 2586 | }, |
2601 | /* | 2587 | /* |
2602 | * Commtech, Inc. Fastcom adapters | 2588 | * Commtech, Inc. Fastcom adapters |
2603 | * | 2589 | * |
2604 | */ | 2590 | */ |
2605 | { | 2591 | { |
2606 | .vendor = PCI_VENDOR_ID_COMMTECH, | 2592 | .vendor = PCI_VENDOR_ID_COMMTECH, |
2607 | .device = PCI_DEVICE_ID_COMMTECH_4222PCI335, | 2593 | .device = PCI_DEVICE_ID_COMMTECH_4222PCI335, |
2608 | .subvendor = PCI_ANY_ID, | 2594 | .subvendor = PCI_ANY_ID, |
2609 | .subdevice = PCI_ANY_ID, | 2595 | .subdevice = PCI_ANY_ID, |
2610 | .setup = pci_fastcom335_setup, | 2596 | .setup = pci_fastcom335_setup, |
2611 | }, | 2597 | }, |
2612 | { | 2598 | { |
2613 | .vendor = PCI_VENDOR_ID_COMMTECH, | 2599 | .vendor = PCI_VENDOR_ID_COMMTECH, |
2614 | .device = PCI_DEVICE_ID_COMMTECH_4224PCI335, | 2600 | .device = PCI_DEVICE_ID_COMMTECH_4224PCI335, |
2615 | .subvendor = PCI_ANY_ID, | 2601 | .subvendor = PCI_ANY_ID, |
2616 | .subdevice = PCI_ANY_ID, | 2602 | .subdevice = PCI_ANY_ID, |
2617 | .setup = pci_fastcom335_setup, | 2603 | .setup = pci_fastcom335_setup, |
2618 | }, | 2604 | }, |
2619 | { | 2605 | { |
2620 | .vendor = PCI_VENDOR_ID_COMMTECH, | 2606 | .vendor = PCI_VENDOR_ID_COMMTECH, |
2621 | .device = PCI_DEVICE_ID_COMMTECH_2324PCI335, | 2607 | .device = PCI_DEVICE_ID_COMMTECH_2324PCI335, |
2622 | .subvendor = PCI_ANY_ID, | 2608 | .subvendor = PCI_ANY_ID, |
2623 | .subdevice = PCI_ANY_ID, | 2609 | .subdevice = PCI_ANY_ID, |
2624 | .setup = pci_fastcom335_setup, | 2610 | .setup = pci_fastcom335_setup, |
2625 | }, | 2611 | }, |
2626 | { | 2612 | { |
2627 | .vendor = PCI_VENDOR_ID_COMMTECH, | 2613 | .vendor = PCI_VENDOR_ID_COMMTECH, |
2628 | .device = PCI_DEVICE_ID_COMMTECH_2328PCI335, | 2614 | .device = PCI_DEVICE_ID_COMMTECH_2328PCI335, |
2629 | .subvendor = PCI_ANY_ID, | 2615 | .subvendor = PCI_ANY_ID, |
2630 | .subdevice = PCI_ANY_ID, | 2616 | .subdevice = PCI_ANY_ID, |
2631 | .setup = pci_fastcom335_setup, | 2617 | .setup = pci_fastcom335_setup, |
2632 | }, | 2618 | }, |
2633 | { | 2619 | { |
2634 | .vendor = PCI_VENDOR_ID_COMMTECH, | 2620 | .vendor = PCI_VENDOR_ID_COMMTECH, |
2635 | .device = PCI_DEVICE_ID_COMMTECH_4222PCIE, | 2621 | .device = PCI_DEVICE_ID_COMMTECH_4222PCIE, |
2636 | .subvendor = PCI_ANY_ID, | 2622 | .subvendor = PCI_ANY_ID, |
2637 | .subdevice = PCI_ANY_ID, | 2623 | .subdevice = PCI_ANY_ID, |
2638 | .setup = pci_xr17v35x_setup, | 2624 | .setup = pci_xr17v35x_setup, |
2639 | }, | 2625 | }, |
2640 | { | 2626 | { |
2641 | .vendor = PCI_VENDOR_ID_COMMTECH, | 2627 | .vendor = PCI_VENDOR_ID_COMMTECH, |
2642 | .device = PCI_DEVICE_ID_COMMTECH_4224PCIE, | 2628 | .device = PCI_DEVICE_ID_COMMTECH_4224PCIE, |
2643 | .subvendor = PCI_ANY_ID, | 2629 | .subvendor = PCI_ANY_ID, |
2644 | .subdevice = PCI_ANY_ID, | 2630 | .subdevice = PCI_ANY_ID, |
2645 | .setup = pci_xr17v35x_setup, | 2631 | .setup = pci_xr17v35x_setup, |
2646 | }, | 2632 | }, |
2647 | { | 2633 | { |
2648 | .vendor = PCI_VENDOR_ID_COMMTECH, | 2634 | .vendor = PCI_VENDOR_ID_COMMTECH, |
2649 | .device = PCI_DEVICE_ID_COMMTECH_4228PCIE, | 2635 | .device = PCI_DEVICE_ID_COMMTECH_4228PCIE, |
2650 | .subvendor = PCI_ANY_ID, | 2636 | .subvendor = PCI_ANY_ID, |
2651 | .subdevice = PCI_ANY_ID, | 2637 | .subdevice = PCI_ANY_ID, |
2652 | .setup = pci_xr17v35x_setup, | 2638 | .setup = pci_xr17v35x_setup, |
2653 | }, | 2639 | }, |
2654 | /* | 2640 | /* |
2655 | * Broadcom TruManage (NetXtreme) | 2641 | * Broadcom TruManage (NetXtreme) |
2656 | */ | 2642 | */ |
2657 | { | 2643 | { |
2658 | .vendor = PCI_VENDOR_ID_BROADCOM, | 2644 | .vendor = PCI_VENDOR_ID_BROADCOM, |
2659 | .device = PCI_DEVICE_ID_BROADCOM_TRUMANAGE, | 2645 | .device = PCI_DEVICE_ID_BROADCOM_TRUMANAGE, |
2660 | .subvendor = PCI_ANY_ID, | 2646 | .subvendor = PCI_ANY_ID, |
2661 | .subdevice = PCI_ANY_ID, | 2647 | .subdevice = PCI_ANY_ID, |
2662 | .setup = pci_brcm_trumanage_setup, | 2648 | .setup = pci_brcm_trumanage_setup, |
2663 | }, | 2649 | }, |
2664 | { | 2650 | { |
2665 | .vendor = 0x1c29, | 2651 | .vendor = 0x1c29, |
2666 | .device = 0x1104, | 2652 | .device = 0x1104, |
2667 | .subvendor = PCI_ANY_ID, | 2653 | .subvendor = PCI_ANY_ID, |
2668 | .subdevice = PCI_ANY_ID, | 2654 | .subdevice = PCI_ANY_ID, |
2669 | .setup = pci_fintek_setup, | 2655 | .setup = pci_fintek_setup, |
2670 | }, | 2656 | }, |
2671 | { | 2657 | { |
2672 | .vendor = 0x1c29, | 2658 | .vendor = 0x1c29, |
2673 | .device = 0x1108, | 2659 | .device = 0x1108, |
2674 | .subvendor = PCI_ANY_ID, | 2660 | .subvendor = PCI_ANY_ID, |
2675 | .subdevice = PCI_ANY_ID, | 2661 | .subdevice = PCI_ANY_ID, |
2676 | .setup = pci_fintek_setup, | 2662 | .setup = pci_fintek_setup, |
2677 | }, | 2663 | }, |
2678 | { | 2664 | { |
2679 | .vendor = 0x1c29, | 2665 | .vendor = 0x1c29, |
2680 | .device = 0x1112, | 2666 | .device = 0x1112, |
2681 | .subvendor = PCI_ANY_ID, | 2667 | .subvendor = PCI_ANY_ID, |
2682 | .subdevice = PCI_ANY_ID, | 2668 | .subdevice = PCI_ANY_ID, |
2683 | .setup = pci_fintek_setup, | 2669 | .setup = pci_fintek_setup, |
2684 | }, | 2670 | }, |
2685 | 2671 | ||
2686 | /* | 2672 | /* |
2687 | * Default "match everything" terminator entry | 2673 | * Default "match everything" terminator entry |
2688 | */ | 2674 | */ |
2689 | { | 2675 | { |
2690 | .vendor = PCI_ANY_ID, | 2676 | .vendor = PCI_ANY_ID, |
2691 | .device = PCI_ANY_ID, | 2677 | .device = PCI_ANY_ID, |
2692 | .subvendor = PCI_ANY_ID, | 2678 | .subvendor = PCI_ANY_ID, |
2693 | .subdevice = PCI_ANY_ID, | 2679 | .subdevice = PCI_ANY_ID, |
2694 | .setup = pci_default_setup, | 2680 | .setup = pci_default_setup, |
2695 | } | 2681 | } |
2696 | }; | 2682 | }; |
2697 | 2683 | ||
2698 | static inline int quirk_id_matches(u32 quirk_id, u32 dev_id) | 2684 | static inline int quirk_id_matches(u32 quirk_id, u32 dev_id) |
2699 | { | 2685 | { |
2700 | return quirk_id == PCI_ANY_ID || quirk_id == dev_id; | 2686 | return quirk_id == PCI_ANY_ID || quirk_id == dev_id; |
2701 | } | 2687 | } |
2702 | 2688 | ||
2703 | static struct pci_serial_quirk *find_quirk(struct pci_dev *dev) | 2689 | static struct pci_serial_quirk *find_quirk(struct pci_dev *dev) |
2704 | { | 2690 | { |
2705 | struct pci_serial_quirk *quirk; | 2691 | struct pci_serial_quirk *quirk; |
2706 | 2692 | ||
2707 | for (quirk = pci_serial_quirks; ; quirk++) | 2693 | for (quirk = pci_serial_quirks; ; quirk++) |
2708 | if (quirk_id_matches(quirk->vendor, dev->vendor) && | 2694 | if (quirk_id_matches(quirk->vendor, dev->vendor) && |
2709 | quirk_id_matches(quirk->device, dev->device) && | 2695 | quirk_id_matches(quirk->device, dev->device) && |
2710 | quirk_id_matches(quirk->subvendor, dev->subsystem_vendor) && | 2696 | quirk_id_matches(quirk->subvendor, dev->subsystem_vendor) && |
2711 | quirk_id_matches(quirk->subdevice, dev->subsystem_device)) | 2697 | quirk_id_matches(quirk->subdevice, dev->subsystem_device)) |
2712 | break; | 2698 | break; |
2713 | return quirk; | 2699 | return quirk; |
2714 | } | 2700 | } |
2715 | 2701 | ||
2716 | static inline int get_pci_irq(struct pci_dev *dev, | 2702 | static inline int get_pci_irq(struct pci_dev *dev, |
2717 | const struct pciserial_board *board) | 2703 | const struct pciserial_board *board) |
2718 | { | 2704 | { |
2719 | if (board->flags & FL_NOIRQ) | 2705 | if (board->flags & FL_NOIRQ) |
2720 | return 0; | 2706 | return 0; |
2721 | else | 2707 | else |
2722 | return dev->irq; | 2708 | return dev->irq; |
2723 | } | 2709 | } |
2724 | 2710 | ||
2725 | /* | 2711 | /* |
2726 | * This is the configuration table for all of the PCI serial boards | 2712 | * This is the configuration table for all of the PCI serial boards |
2727 | * which we support. It is directly indexed by the pci_board_num_t enum | 2713 | * which we support. It is directly indexed by the pci_board_num_t enum |
2728 | * value, which is encoded in the pci_device_id PCI probe table's | 2714 | * value, which is encoded in the pci_device_id PCI probe table's |
2729 | * driver_data member. | 2715 | * driver_data member. |
2730 | * | 2716 | * |
2731 | * The makeup of these names are: | 2717 | * The makeup of these names are: |
2732 | * pbn_bn{_bt}_n_baud{_offsetinhex} | 2718 | * pbn_bn{_bt}_n_baud{_offsetinhex} |
2733 | * | 2719 | * |
2734 | * bn = PCI BAR number | 2720 | * bn = PCI BAR number |
2735 | * bt = Index using PCI BARs | 2721 | * bt = Index using PCI BARs |
2736 | * n = number of serial ports | 2722 | * n = number of serial ports |
2737 | * baud = baud rate | 2723 | * baud = baud rate |
2738 | * offsetinhex = offset for each sequential port (in hex) | 2724 | * offsetinhex = offset for each sequential port (in hex) |
2739 | * | 2725 | * |
2740 | * This table is sorted by (in order): bn, bt, baud, offsetindex, n. | 2726 | * This table is sorted by (in order): bn, bt, baud, offsetindex, n. |
2741 | * | 2727 | * |
2742 | * Please note: in theory if n = 1, _bt infix should make no difference. | 2728 | * Please note: in theory if n = 1, _bt infix should make no difference. |
2743 | * ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200 | 2729 | * ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200 |
2744 | */ | 2730 | */ |
2745 | enum pci_board_num_t { | 2731 | enum pci_board_num_t { |
2746 | pbn_default = 0, | 2732 | pbn_default = 0, |
2747 | 2733 | ||
2748 | pbn_b0_1_115200, | 2734 | pbn_b0_1_115200, |
2749 | pbn_b0_2_115200, | 2735 | pbn_b0_2_115200, |
2750 | pbn_b0_4_115200, | 2736 | pbn_b0_4_115200, |
2751 | pbn_b0_5_115200, | 2737 | pbn_b0_5_115200, |
2752 | pbn_b0_8_115200, | 2738 | pbn_b0_8_115200, |
2753 | 2739 | ||
2754 | pbn_b0_1_921600, | 2740 | pbn_b0_1_921600, |
2755 | pbn_b0_2_921600, | 2741 | pbn_b0_2_921600, |
2756 | pbn_b0_4_921600, | 2742 | pbn_b0_4_921600, |
2757 | 2743 | ||
2758 | pbn_b0_2_1130000, | 2744 | pbn_b0_2_1130000, |
2759 | 2745 | ||
2760 | pbn_b0_4_1152000, | 2746 | pbn_b0_4_1152000, |
2761 | 2747 | ||
2762 | pbn_b0_2_1152000_200, | 2748 | pbn_b0_2_1152000_200, |
2763 | pbn_b0_4_1152000_200, | 2749 | pbn_b0_4_1152000_200, |
2764 | pbn_b0_8_1152000_200, | 2750 | pbn_b0_8_1152000_200, |
2765 | 2751 | ||
2766 | pbn_b0_2_1843200, | 2752 | pbn_b0_2_1843200, |
2767 | pbn_b0_4_1843200, | 2753 | pbn_b0_4_1843200, |
2768 | 2754 | ||
2769 | pbn_b0_2_1843200_200, | 2755 | pbn_b0_2_1843200_200, |
2770 | pbn_b0_4_1843200_200, | 2756 | pbn_b0_4_1843200_200, |
2771 | pbn_b0_8_1843200_200, | 2757 | pbn_b0_8_1843200_200, |
2772 | 2758 | ||
2773 | pbn_b0_1_4000000, | 2759 | pbn_b0_1_4000000, |
2774 | 2760 | ||
2775 | pbn_b0_bt_1_115200, | 2761 | pbn_b0_bt_1_115200, |
2776 | pbn_b0_bt_2_115200, | 2762 | pbn_b0_bt_2_115200, |
2777 | pbn_b0_bt_4_115200, | 2763 | pbn_b0_bt_4_115200, |
2778 | pbn_b0_bt_8_115200, | 2764 | pbn_b0_bt_8_115200, |
2779 | 2765 | ||
2780 | pbn_b0_bt_1_460800, | 2766 | pbn_b0_bt_1_460800, |
2781 | pbn_b0_bt_2_460800, | 2767 | pbn_b0_bt_2_460800, |
2782 | pbn_b0_bt_4_460800, | 2768 | pbn_b0_bt_4_460800, |
2783 | 2769 | ||
2784 | pbn_b0_bt_1_921600, | 2770 | pbn_b0_bt_1_921600, |
2785 | pbn_b0_bt_2_921600, | 2771 | pbn_b0_bt_2_921600, |
2786 | pbn_b0_bt_4_921600, | 2772 | pbn_b0_bt_4_921600, |
2787 | pbn_b0_bt_8_921600, | 2773 | pbn_b0_bt_8_921600, |
2788 | 2774 | ||
2789 | pbn_b1_1_115200, | 2775 | pbn_b1_1_115200, |
2790 | pbn_b1_2_115200, | 2776 | pbn_b1_2_115200, |
2791 | pbn_b1_4_115200, | 2777 | pbn_b1_4_115200, |
2792 | pbn_b1_8_115200, | 2778 | pbn_b1_8_115200, |
2793 | pbn_b1_16_115200, | 2779 | pbn_b1_16_115200, |
2794 | 2780 | ||
2795 | pbn_b1_1_921600, | 2781 | pbn_b1_1_921600, |
2796 | pbn_b1_2_921600, | 2782 | pbn_b1_2_921600, |
2797 | pbn_b1_4_921600, | 2783 | pbn_b1_4_921600, |
2798 | pbn_b1_8_921600, | 2784 | pbn_b1_8_921600, |
2799 | 2785 | ||
2800 | pbn_b1_2_1250000, | 2786 | pbn_b1_2_1250000, |
2801 | 2787 | ||
2802 | pbn_b1_bt_1_115200, | 2788 | pbn_b1_bt_1_115200, |
2803 | pbn_b1_bt_2_115200, | 2789 | pbn_b1_bt_2_115200, |
2804 | pbn_b1_bt_4_115200, | 2790 | pbn_b1_bt_4_115200, |
2805 | 2791 | ||
2806 | pbn_b1_bt_2_921600, | 2792 | pbn_b1_bt_2_921600, |
2807 | 2793 | ||
2808 | pbn_b1_1_1382400, | 2794 | pbn_b1_1_1382400, |
2809 | pbn_b1_2_1382400, | 2795 | pbn_b1_2_1382400, |
2810 | pbn_b1_4_1382400, | 2796 | pbn_b1_4_1382400, |
2811 | pbn_b1_8_1382400, | 2797 | pbn_b1_8_1382400, |
2812 | 2798 | ||
2813 | pbn_b2_1_115200, | 2799 | pbn_b2_1_115200, |
2814 | pbn_b2_2_115200, | 2800 | pbn_b2_2_115200, |
2815 | pbn_b2_4_115200, | 2801 | pbn_b2_4_115200, |
2816 | pbn_b2_8_115200, | 2802 | pbn_b2_8_115200, |
2817 | 2803 | ||
2818 | pbn_b2_1_460800, | 2804 | pbn_b2_1_460800, |
2819 | pbn_b2_4_460800, | 2805 | pbn_b2_4_460800, |
2820 | pbn_b2_8_460800, | 2806 | pbn_b2_8_460800, |
2821 | pbn_b2_16_460800, | 2807 | pbn_b2_16_460800, |
2822 | 2808 | ||
2823 | pbn_b2_1_921600, | 2809 | pbn_b2_1_921600, |
2824 | pbn_b2_4_921600, | 2810 | pbn_b2_4_921600, |
2825 | pbn_b2_8_921600, | 2811 | pbn_b2_8_921600, |
2826 | 2812 | ||
2827 | pbn_b2_8_1152000, | 2813 | pbn_b2_8_1152000, |
2828 | 2814 | ||
2829 | pbn_b2_bt_1_115200, | 2815 | pbn_b2_bt_1_115200, |
2830 | pbn_b2_bt_2_115200, | 2816 | pbn_b2_bt_2_115200, |
2831 | pbn_b2_bt_4_115200, | 2817 | pbn_b2_bt_4_115200, |
2832 | 2818 | ||
2833 | pbn_b2_bt_2_921600, | 2819 | pbn_b2_bt_2_921600, |
2834 | pbn_b2_bt_4_921600, | 2820 | pbn_b2_bt_4_921600, |
2835 | 2821 | ||
2836 | pbn_b3_2_115200, | 2822 | pbn_b3_2_115200, |
2837 | pbn_b3_4_115200, | 2823 | pbn_b3_4_115200, |
2838 | pbn_b3_8_115200, | 2824 | pbn_b3_8_115200, |
2839 | 2825 | ||
2840 | pbn_b4_bt_2_921600, | 2826 | pbn_b4_bt_2_921600, |
2841 | pbn_b4_bt_4_921600, | 2827 | pbn_b4_bt_4_921600, |
2842 | pbn_b4_bt_8_921600, | 2828 | pbn_b4_bt_8_921600, |
2843 | 2829 | ||
2844 | /* | 2830 | /* |
2845 | * Board-specific versions. | 2831 | * Board-specific versions. |
2846 | */ | 2832 | */ |
2847 | pbn_panacom, | 2833 | pbn_panacom, |
2848 | pbn_panacom2, | 2834 | pbn_panacom2, |
2849 | pbn_panacom4, | 2835 | pbn_panacom4, |
2850 | pbn_plx_romulus, | 2836 | pbn_plx_romulus, |
2851 | pbn_endrun_2_4000000, | 2837 | pbn_endrun_2_4000000, |
2852 | pbn_oxsemi, | 2838 | pbn_oxsemi, |
2853 | pbn_oxsemi_1_4000000, | 2839 | pbn_oxsemi_1_4000000, |
2854 | pbn_oxsemi_2_4000000, | 2840 | pbn_oxsemi_2_4000000, |
2855 | pbn_oxsemi_4_4000000, | 2841 | pbn_oxsemi_4_4000000, |
2856 | pbn_oxsemi_8_4000000, | 2842 | pbn_oxsemi_8_4000000, |
2857 | pbn_intel_i960, | 2843 | pbn_intel_i960, |
2858 | pbn_sgi_ioc3, | 2844 | pbn_sgi_ioc3, |
2859 | pbn_computone_4, | 2845 | pbn_computone_4, |
2860 | pbn_computone_6, | 2846 | pbn_computone_6, |
2861 | pbn_computone_8, | 2847 | pbn_computone_8, |
2862 | pbn_sbsxrsio, | 2848 | pbn_sbsxrsio, |
2863 | pbn_exar_XR17C152, | 2849 | pbn_exar_XR17C152, |
2864 | pbn_exar_XR17C154, | 2850 | pbn_exar_XR17C154, |
2865 | pbn_exar_XR17C158, | 2851 | pbn_exar_XR17C158, |
2866 | pbn_exar_XR17V352, | 2852 | pbn_exar_XR17V352, |
2867 | pbn_exar_XR17V354, | 2853 | pbn_exar_XR17V354, |
2868 | pbn_exar_XR17V358, | 2854 | pbn_exar_XR17V358, |
2869 | pbn_exar_ibm_saturn, | 2855 | pbn_exar_ibm_saturn, |
2870 | pbn_pasemi_1682M, | 2856 | pbn_pasemi_1682M, |
2871 | pbn_ni8430_2, | 2857 | pbn_ni8430_2, |
2872 | pbn_ni8430_4, | 2858 | pbn_ni8430_4, |
2873 | pbn_ni8430_8, | 2859 | pbn_ni8430_8, |
2874 | pbn_ni8430_16, | 2860 | pbn_ni8430_16, |
2875 | pbn_ADDIDATA_PCIe_1_3906250, | 2861 | pbn_ADDIDATA_PCIe_1_3906250, |
2876 | pbn_ADDIDATA_PCIe_2_3906250, | 2862 | pbn_ADDIDATA_PCIe_2_3906250, |
2877 | pbn_ADDIDATA_PCIe_4_3906250, | 2863 | pbn_ADDIDATA_PCIe_4_3906250, |
2878 | pbn_ADDIDATA_PCIe_8_3906250, | 2864 | pbn_ADDIDATA_PCIe_8_3906250, |
2879 | pbn_ce4100_1_115200, | 2865 | pbn_ce4100_1_115200, |
2880 | pbn_byt, | 2866 | pbn_byt, |
2881 | pbn_qrk, | 2867 | pbn_qrk, |
2882 | pbn_omegapci, | 2868 | pbn_omegapci, |
2883 | pbn_NETMOS9900_2s_115200, | 2869 | pbn_NETMOS9900_2s_115200, |
2884 | pbn_brcm_trumanage, | 2870 | pbn_brcm_trumanage, |
2885 | pbn_fintek_4, | 2871 | pbn_fintek_4, |
2886 | pbn_fintek_8, | 2872 | pbn_fintek_8, |
2887 | pbn_fintek_12, | 2873 | pbn_fintek_12, |
2888 | pbn_wch384_4, | 2874 | pbn_wch384_4, |
2889 | }; | 2875 | }; |
2890 | 2876 | ||
2891 | /* | 2877 | /* |
2892 | * uart_offset - the space between channels | 2878 | * uart_offset - the space between channels |
2893 | * reg_shift - describes how the UART registers are mapped | 2879 | * reg_shift - describes how the UART registers are mapped |
2894 | * to PCI memory by the card. | 2880 | * to PCI memory by the card. |
2895 | * For example IER register on SBS, Inc. PMC-OctPro is located at | 2881 | * For example IER register on SBS, Inc. PMC-OctPro is located at |
2896 | * offset 0x10 from the UART base, while UART_IER is defined as 1 | 2882 | * offset 0x10 from the UART base, while UART_IER is defined as 1 |
2897 | * in include/linux/serial_reg.h, | 2883 | * in include/linux/serial_reg.h, |
2898 | * see first lines of serial_in() and serial_out() in 8250.c | 2884 | * see first lines of serial_in() and serial_out() in 8250.c |
2899 | */ | 2885 | */ |
2900 | 2886 | ||
2901 | static struct pciserial_board pci_boards[] = { | 2887 | static struct pciserial_board pci_boards[] = { |
2902 | [pbn_default] = { | 2888 | [pbn_default] = { |
2903 | .flags = FL_BASE0, | 2889 | .flags = FL_BASE0, |
2904 | .num_ports = 1, | 2890 | .num_ports = 1, |
2905 | .base_baud = 115200, | 2891 | .base_baud = 115200, |
2906 | .uart_offset = 8, | 2892 | .uart_offset = 8, |
2907 | }, | 2893 | }, |
2908 | [pbn_b0_1_115200] = { | 2894 | [pbn_b0_1_115200] = { |
2909 | .flags = FL_BASE0, | 2895 | .flags = FL_BASE0, |
2910 | .num_ports = 1, | 2896 | .num_ports = 1, |
2911 | .base_baud = 115200, | 2897 | .base_baud = 115200, |
2912 | .uart_offset = 8, | 2898 | .uart_offset = 8, |
2913 | }, | 2899 | }, |
2914 | [pbn_b0_2_115200] = { | 2900 | [pbn_b0_2_115200] = { |
2915 | .flags = FL_BASE0, | 2901 | .flags = FL_BASE0, |
2916 | .num_ports = 2, | 2902 | .num_ports = 2, |
2917 | .base_baud = 115200, | 2903 | .base_baud = 115200, |
2918 | .uart_offset = 8, | 2904 | .uart_offset = 8, |
2919 | }, | 2905 | }, |
2920 | [pbn_b0_4_115200] = { | 2906 | [pbn_b0_4_115200] = { |
2921 | .flags = FL_BASE0, | 2907 | .flags = FL_BASE0, |
2922 | .num_ports = 4, | 2908 | .num_ports = 4, |
2923 | .base_baud = 115200, | 2909 | .base_baud = 115200, |
2924 | .uart_offset = 8, | 2910 | .uart_offset = 8, |
2925 | }, | 2911 | }, |
2926 | [pbn_b0_5_115200] = { | 2912 | [pbn_b0_5_115200] = { |
2927 | .flags = FL_BASE0, | 2913 | .flags = FL_BASE0, |
2928 | .num_ports = 5, | 2914 | .num_ports = 5, |
2929 | .base_baud = 115200, | 2915 | .base_baud = 115200, |
2930 | .uart_offset = 8, | 2916 | .uart_offset = 8, |
2931 | }, | 2917 | }, |
2932 | [pbn_b0_8_115200] = { | 2918 | [pbn_b0_8_115200] = { |
2933 | .flags = FL_BASE0, | 2919 | .flags = FL_BASE0, |
2934 | .num_ports = 8, | 2920 | .num_ports = 8, |
2935 | .base_baud = 115200, | 2921 | .base_baud = 115200, |
2936 | .uart_offset = 8, | 2922 | .uart_offset = 8, |
2937 | }, | 2923 | }, |
2938 | [pbn_b0_1_921600] = { | 2924 | [pbn_b0_1_921600] = { |
2939 | .flags = FL_BASE0, | 2925 | .flags = FL_BASE0, |
2940 | .num_ports = 1, | 2926 | .num_ports = 1, |
2941 | .base_baud = 921600, | 2927 | .base_baud = 921600, |
2942 | .uart_offset = 8, | 2928 | .uart_offset = 8, |
2943 | }, | 2929 | }, |
2944 | [pbn_b0_2_921600] = { | 2930 | [pbn_b0_2_921600] = { |
2945 | .flags = FL_BASE0, | 2931 | .flags = FL_BASE0, |
2946 | .num_ports = 2, | 2932 | .num_ports = 2, |
2947 | .base_baud = 921600, | 2933 | .base_baud = 921600, |
2948 | .uart_offset = 8, | 2934 | .uart_offset = 8, |
2949 | }, | 2935 | }, |
2950 | [pbn_b0_4_921600] = { | 2936 | [pbn_b0_4_921600] = { |
2951 | .flags = FL_BASE0, | 2937 | .flags = FL_BASE0, |
2952 | .num_ports = 4, | 2938 | .num_ports = 4, |
2953 | .base_baud = 921600, | 2939 | .base_baud = 921600, |
2954 | .uart_offset = 8, | 2940 | .uart_offset = 8, |
2955 | }, | 2941 | }, |
2956 | 2942 | ||
2957 | [pbn_b0_2_1130000] = { | 2943 | [pbn_b0_2_1130000] = { |
2958 | .flags = FL_BASE0, | 2944 | .flags = FL_BASE0, |
2959 | .num_ports = 2, | 2945 | .num_ports = 2, |
2960 | .base_baud = 1130000, | 2946 | .base_baud = 1130000, |
2961 | .uart_offset = 8, | 2947 | .uart_offset = 8, |
2962 | }, | 2948 | }, |
2963 | 2949 | ||
2964 | [pbn_b0_4_1152000] = { | 2950 | [pbn_b0_4_1152000] = { |
2965 | .flags = FL_BASE0, | 2951 | .flags = FL_BASE0, |
2966 | .num_ports = 4, | 2952 | .num_ports = 4, |
2967 | .base_baud = 1152000, | 2953 | .base_baud = 1152000, |
2968 | .uart_offset = 8, | 2954 | .uart_offset = 8, |
2969 | }, | 2955 | }, |
2970 | 2956 | ||
2971 | [pbn_b0_2_1152000_200] = { | 2957 | [pbn_b0_2_1152000_200] = { |
2972 | .flags = FL_BASE0, | 2958 | .flags = FL_BASE0, |
2973 | .num_ports = 2, | 2959 | .num_ports = 2, |
2974 | .base_baud = 1152000, | 2960 | .base_baud = 1152000, |
2975 | .uart_offset = 0x200, | 2961 | .uart_offset = 0x200, |
2976 | }, | 2962 | }, |
2977 | 2963 | ||
2978 | [pbn_b0_4_1152000_200] = { | 2964 | [pbn_b0_4_1152000_200] = { |
2979 | .flags = FL_BASE0, | 2965 | .flags = FL_BASE0, |
2980 | .num_ports = 4, | 2966 | .num_ports = 4, |
2981 | .base_baud = 1152000, | 2967 | .base_baud = 1152000, |
2982 | .uart_offset = 0x200, | 2968 | .uart_offset = 0x200, |
2983 | }, | 2969 | }, |
2984 | 2970 | ||
2985 | [pbn_b0_8_1152000_200] = { | 2971 | [pbn_b0_8_1152000_200] = { |
2986 | .flags = FL_BASE0, | 2972 | .flags = FL_BASE0, |
2987 | .num_ports = 8, | 2973 | .num_ports = 8, |
2988 | .base_baud = 1152000, | 2974 | .base_baud = 1152000, |
2989 | .uart_offset = 0x200, | 2975 | .uart_offset = 0x200, |
2990 | }, | 2976 | }, |
2991 | 2977 | ||
2992 | [pbn_b0_2_1843200] = { | 2978 | [pbn_b0_2_1843200] = { |
2993 | .flags = FL_BASE0, | 2979 | .flags = FL_BASE0, |
2994 | .num_ports = 2, | 2980 | .num_ports = 2, |
2995 | .base_baud = 1843200, | 2981 | .base_baud = 1843200, |
2996 | .uart_offset = 8, | 2982 | .uart_offset = 8, |
2997 | }, | 2983 | }, |
2998 | [pbn_b0_4_1843200] = { | 2984 | [pbn_b0_4_1843200] = { |
2999 | .flags = FL_BASE0, | 2985 | .flags = FL_BASE0, |
3000 | .num_ports = 4, | 2986 | .num_ports = 4, |
3001 | .base_baud = 1843200, | 2987 | .base_baud = 1843200, |
3002 | .uart_offset = 8, | 2988 | .uart_offset = 8, |
3003 | }, | 2989 | }, |
3004 | 2990 | ||
3005 | [pbn_b0_2_1843200_200] = { | 2991 | [pbn_b0_2_1843200_200] = { |
3006 | .flags = FL_BASE0, | 2992 | .flags = FL_BASE0, |
3007 | .num_ports = 2, | 2993 | .num_ports = 2, |
3008 | .base_baud = 1843200, | 2994 | .base_baud = 1843200, |
3009 | .uart_offset = 0x200, | 2995 | .uart_offset = 0x200, |
3010 | }, | 2996 | }, |
3011 | [pbn_b0_4_1843200_200] = { | 2997 | [pbn_b0_4_1843200_200] = { |
3012 | .flags = FL_BASE0, | 2998 | .flags = FL_BASE0, |
3013 | .num_ports = 4, | 2999 | .num_ports = 4, |
3014 | .base_baud = 1843200, | 3000 | .base_baud = 1843200, |
3015 | .uart_offset = 0x200, | 3001 | .uart_offset = 0x200, |
3016 | }, | 3002 | }, |
3017 | [pbn_b0_8_1843200_200] = { | 3003 | [pbn_b0_8_1843200_200] = { |
3018 | .flags = FL_BASE0, | 3004 | .flags = FL_BASE0, |
3019 | .num_ports = 8, | 3005 | .num_ports = 8, |
3020 | .base_baud = 1843200, | 3006 | .base_baud = 1843200, |
3021 | .uart_offset = 0x200, | 3007 | .uart_offset = 0x200, |
3022 | }, | 3008 | }, |
3023 | [pbn_b0_1_4000000] = { | 3009 | [pbn_b0_1_4000000] = { |
3024 | .flags = FL_BASE0, | 3010 | .flags = FL_BASE0, |
3025 | .num_ports = 1, | 3011 | .num_ports = 1, |
3026 | .base_baud = 4000000, | 3012 | .base_baud = 4000000, |
3027 | .uart_offset = 8, | 3013 | .uart_offset = 8, |
3028 | }, | 3014 | }, |
3029 | 3015 | ||
3030 | [pbn_b0_bt_1_115200] = { | 3016 | [pbn_b0_bt_1_115200] = { |
3031 | .flags = FL_BASE0|FL_BASE_BARS, | 3017 | .flags = FL_BASE0|FL_BASE_BARS, |
3032 | .num_ports = 1, | 3018 | .num_ports = 1, |
3033 | .base_baud = 115200, | 3019 | .base_baud = 115200, |
3034 | .uart_offset = 8, | 3020 | .uart_offset = 8, |
3035 | }, | 3021 | }, |
3036 | [pbn_b0_bt_2_115200] = { | 3022 | [pbn_b0_bt_2_115200] = { |
3037 | .flags = FL_BASE0|FL_BASE_BARS, | 3023 | .flags = FL_BASE0|FL_BASE_BARS, |
3038 | .num_ports = 2, | 3024 | .num_ports = 2, |
3039 | .base_baud = 115200, | 3025 | .base_baud = 115200, |
3040 | .uart_offset = 8, | 3026 | .uart_offset = 8, |
3041 | }, | 3027 | }, |
3042 | [pbn_b0_bt_4_115200] = { | 3028 | [pbn_b0_bt_4_115200] = { |
3043 | .flags = FL_BASE0|FL_BASE_BARS, | 3029 | .flags = FL_BASE0|FL_BASE_BARS, |
3044 | .num_ports = 4, | 3030 | .num_ports = 4, |
3045 | .base_baud = 115200, | 3031 | .base_baud = 115200, |
3046 | .uart_offset = 8, | 3032 | .uart_offset = 8, |
3047 | }, | 3033 | }, |
3048 | [pbn_b0_bt_8_115200] = { | 3034 | [pbn_b0_bt_8_115200] = { |
3049 | .flags = FL_BASE0|FL_BASE_BARS, | 3035 | .flags = FL_BASE0|FL_BASE_BARS, |
3050 | .num_ports = 8, | 3036 | .num_ports = 8, |
3051 | .base_baud = 115200, | 3037 | .base_baud = 115200, |
3052 | .uart_offset = 8, | 3038 | .uart_offset = 8, |
3053 | }, | 3039 | }, |
3054 | 3040 | ||
3055 | [pbn_b0_bt_1_460800] = { | 3041 | [pbn_b0_bt_1_460800] = { |
3056 | .flags = FL_BASE0|FL_BASE_BARS, | 3042 | .flags = FL_BASE0|FL_BASE_BARS, |
3057 | .num_ports = 1, | 3043 | .num_ports = 1, |
3058 | .base_baud = 460800, | 3044 | .base_baud = 460800, |
3059 | .uart_offset = 8, | 3045 | .uart_offset = 8, |
3060 | }, | 3046 | }, |
3061 | [pbn_b0_bt_2_460800] = { | 3047 | [pbn_b0_bt_2_460800] = { |
3062 | .flags = FL_BASE0|FL_BASE_BARS, | 3048 | .flags = FL_BASE0|FL_BASE_BARS, |
3063 | .num_ports = 2, | 3049 | .num_ports = 2, |
3064 | .base_baud = 460800, | 3050 | .base_baud = 460800, |
3065 | .uart_offset = 8, | 3051 | .uart_offset = 8, |
3066 | }, | 3052 | }, |
3067 | [pbn_b0_bt_4_460800] = { | 3053 | [pbn_b0_bt_4_460800] = { |
3068 | .flags = FL_BASE0|FL_BASE_BARS, | 3054 | .flags = FL_BASE0|FL_BASE_BARS, |
3069 | .num_ports = 4, | 3055 | .num_ports = 4, |
3070 | .base_baud = 460800, | 3056 | .base_baud = 460800, |
3071 | .uart_offset = 8, | 3057 | .uart_offset = 8, |
3072 | }, | 3058 | }, |
3073 | 3059 | ||
3074 | [pbn_b0_bt_1_921600] = { | 3060 | [pbn_b0_bt_1_921600] = { |
3075 | .flags = FL_BASE0|FL_BASE_BARS, | 3061 | .flags = FL_BASE0|FL_BASE_BARS, |
3076 | .num_ports = 1, | 3062 | .num_ports = 1, |
3077 | .base_baud = 921600, | 3063 | .base_baud = 921600, |
3078 | .uart_offset = 8, | 3064 | .uart_offset = 8, |
3079 | }, | 3065 | }, |
3080 | [pbn_b0_bt_2_921600] = { | 3066 | [pbn_b0_bt_2_921600] = { |
3081 | .flags = FL_BASE0|FL_BASE_BARS, | 3067 | .flags = FL_BASE0|FL_BASE_BARS, |
3082 | .num_ports = 2, | 3068 | .num_ports = 2, |
3083 | .base_baud = 921600, | 3069 | .base_baud = 921600, |
3084 | .uart_offset = 8, | 3070 | .uart_offset = 8, |
3085 | }, | 3071 | }, |
3086 | [pbn_b0_bt_4_921600] = { | 3072 | [pbn_b0_bt_4_921600] = { |
3087 | .flags = FL_BASE0|FL_BASE_BARS, | 3073 | .flags = FL_BASE0|FL_BASE_BARS, |
3088 | .num_ports = 4, | 3074 | .num_ports = 4, |
3089 | .base_baud = 921600, | 3075 | .base_baud = 921600, |
3090 | .uart_offset = 8, | 3076 | .uart_offset = 8, |
3091 | }, | 3077 | }, |
3092 | [pbn_b0_bt_8_921600] = { | 3078 | [pbn_b0_bt_8_921600] = { |
3093 | .flags = FL_BASE0|FL_BASE_BARS, | 3079 | .flags = FL_BASE0|FL_BASE_BARS, |
3094 | .num_ports = 8, | 3080 | .num_ports = 8, |
3095 | .base_baud = 921600, | 3081 | .base_baud = 921600, |
3096 | .uart_offset = 8, | 3082 | .uart_offset = 8, |
3097 | }, | 3083 | }, |
3098 | 3084 | ||
3099 | [pbn_b1_1_115200] = { | 3085 | [pbn_b1_1_115200] = { |
3100 | .flags = FL_BASE1, | 3086 | .flags = FL_BASE1, |
3101 | .num_ports = 1, | 3087 | .num_ports = 1, |
3102 | .base_baud = 115200, | 3088 | .base_baud = 115200, |
3103 | .uart_offset = 8, | 3089 | .uart_offset = 8, |
3104 | }, | 3090 | }, |
3105 | [pbn_b1_2_115200] = { | 3091 | [pbn_b1_2_115200] = { |
3106 | .flags = FL_BASE1, | 3092 | .flags = FL_BASE1, |
3107 | .num_ports = 2, | 3093 | .num_ports = 2, |
3108 | .base_baud = 115200, | 3094 | .base_baud = 115200, |
3109 | .uart_offset = 8, | 3095 | .uart_offset = 8, |
3110 | }, | 3096 | }, |
3111 | [pbn_b1_4_115200] = { | 3097 | [pbn_b1_4_115200] = { |
3112 | .flags = FL_BASE1, | 3098 | .flags = FL_BASE1, |
3113 | .num_ports = 4, | 3099 | .num_ports = 4, |
3114 | .base_baud = 115200, | 3100 | .base_baud = 115200, |
3115 | .uart_offset = 8, | 3101 | .uart_offset = 8, |
3116 | }, | 3102 | }, |
3117 | [pbn_b1_8_115200] = { | 3103 | [pbn_b1_8_115200] = { |
3118 | .flags = FL_BASE1, | 3104 | .flags = FL_BASE1, |
3119 | .num_ports = 8, | 3105 | .num_ports = 8, |
3120 | .base_baud = 115200, | 3106 | .base_baud = 115200, |
3121 | .uart_offset = 8, | 3107 | .uart_offset = 8, |
3122 | }, | 3108 | }, |
3123 | [pbn_b1_16_115200] = { | 3109 | [pbn_b1_16_115200] = { |
3124 | .flags = FL_BASE1, | 3110 | .flags = FL_BASE1, |
3125 | .num_ports = 16, | 3111 | .num_ports = 16, |
3126 | .base_baud = 115200, | 3112 | .base_baud = 115200, |
3127 | .uart_offset = 8, | 3113 | .uart_offset = 8, |
3128 | }, | 3114 | }, |
3129 | 3115 | ||
3130 | [pbn_b1_1_921600] = { | 3116 | [pbn_b1_1_921600] = { |
3131 | .flags = FL_BASE1, | 3117 | .flags = FL_BASE1, |
3132 | .num_ports = 1, | 3118 | .num_ports = 1, |
3133 | .base_baud = 921600, | 3119 | .base_baud = 921600, |
3134 | .uart_offset = 8, | 3120 | .uart_offset = 8, |
3135 | }, | 3121 | }, |
3136 | [pbn_b1_2_921600] = { | 3122 | [pbn_b1_2_921600] = { |
3137 | .flags = FL_BASE1, | 3123 | .flags = FL_BASE1, |
3138 | .num_ports = 2, | 3124 | .num_ports = 2, |
3139 | .base_baud = 921600, | 3125 | .base_baud = 921600, |
3140 | .uart_offset = 8, | 3126 | .uart_offset = 8, |
3141 | }, | 3127 | }, |
3142 | [pbn_b1_4_921600] = { | 3128 | [pbn_b1_4_921600] = { |
3143 | .flags = FL_BASE1, | 3129 | .flags = FL_BASE1, |
3144 | .num_ports = 4, | 3130 | .num_ports = 4, |
3145 | .base_baud = 921600, | 3131 | .base_baud = 921600, |
3146 | .uart_offset = 8, | 3132 | .uart_offset = 8, |
3147 | }, | 3133 | }, |
3148 | [pbn_b1_8_921600] = { | 3134 | [pbn_b1_8_921600] = { |
3149 | .flags = FL_BASE1, | 3135 | .flags = FL_BASE1, |
3150 | .num_ports = 8, | 3136 | .num_ports = 8, |
3151 | .base_baud = 921600, | 3137 | .base_baud = 921600, |
3152 | .uart_offset = 8, | 3138 | .uart_offset = 8, |
3153 | }, | 3139 | }, |
3154 | [pbn_b1_2_1250000] = { | 3140 | [pbn_b1_2_1250000] = { |
3155 | .flags = FL_BASE1, | 3141 | .flags = FL_BASE1, |
3156 | .num_ports = 2, | 3142 | .num_ports = 2, |
3157 | .base_baud = 1250000, | 3143 | .base_baud = 1250000, |
3158 | .uart_offset = 8, | 3144 | .uart_offset = 8, |
3159 | }, | 3145 | }, |
3160 | 3146 | ||
3161 | [pbn_b1_bt_1_115200] = { | 3147 | [pbn_b1_bt_1_115200] = { |
3162 | .flags = FL_BASE1|FL_BASE_BARS, | 3148 | .flags = FL_BASE1|FL_BASE_BARS, |
3163 | .num_ports = 1, | 3149 | .num_ports = 1, |
3164 | .base_baud = 115200, | 3150 | .base_baud = 115200, |
3165 | .uart_offset = 8, | 3151 | .uart_offset = 8, |
3166 | }, | 3152 | }, |
3167 | [pbn_b1_bt_2_115200] = { | 3153 | [pbn_b1_bt_2_115200] = { |
3168 | .flags = FL_BASE1|FL_BASE_BARS, | 3154 | .flags = FL_BASE1|FL_BASE_BARS, |
3169 | .num_ports = 2, | 3155 | .num_ports = 2, |
3170 | .base_baud = 115200, | 3156 | .base_baud = 115200, |
3171 | .uart_offset = 8, | 3157 | .uart_offset = 8, |
3172 | }, | 3158 | }, |
3173 | [pbn_b1_bt_4_115200] = { | 3159 | [pbn_b1_bt_4_115200] = { |
3174 | .flags = FL_BASE1|FL_BASE_BARS, | 3160 | .flags = FL_BASE1|FL_BASE_BARS, |
3175 | .num_ports = 4, | 3161 | .num_ports = 4, |
3176 | .base_baud = 115200, | 3162 | .base_baud = 115200, |
3177 | .uart_offset = 8, | 3163 | .uart_offset = 8, |
3178 | }, | 3164 | }, |
3179 | 3165 | ||
3180 | [pbn_b1_bt_2_921600] = { | 3166 | [pbn_b1_bt_2_921600] = { |
3181 | .flags = FL_BASE1|FL_BASE_BARS, | 3167 | .flags = FL_BASE1|FL_BASE_BARS, |
3182 | .num_ports = 2, | 3168 | .num_ports = 2, |
3183 | .base_baud = 921600, | 3169 | .base_baud = 921600, |
3184 | .uart_offset = 8, | 3170 | .uart_offset = 8, |
3185 | }, | 3171 | }, |
3186 | 3172 | ||
3187 | [pbn_b1_1_1382400] = { | 3173 | [pbn_b1_1_1382400] = { |
3188 | .flags = FL_BASE1, | 3174 | .flags = FL_BASE1, |
3189 | .num_ports = 1, | 3175 | .num_ports = 1, |
3190 | .base_baud = 1382400, | 3176 | .base_baud = 1382400, |
3191 | .uart_offset = 8, | 3177 | .uart_offset = 8, |
3192 | }, | 3178 | }, |
3193 | [pbn_b1_2_1382400] = { | 3179 | [pbn_b1_2_1382400] = { |
3194 | .flags = FL_BASE1, | 3180 | .flags = FL_BASE1, |
3195 | .num_ports = 2, | 3181 | .num_ports = 2, |
3196 | .base_baud = 1382400, | 3182 | .base_baud = 1382400, |
3197 | .uart_offset = 8, | 3183 | .uart_offset = 8, |
3198 | }, | 3184 | }, |
3199 | [pbn_b1_4_1382400] = { | 3185 | [pbn_b1_4_1382400] = { |
3200 | .flags = FL_BASE1, | 3186 | .flags = FL_BASE1, |
3201 | .num_ports = 4, | 3187 | .num_ports = 4, |
3202 | .base_baud = 1382400, | 3188 | .base_baud = 1382400, |
3203 | .uart_offset = 8, | 3189 | .uart_offset = 8, |
3204 | }, | 3190 | }, |
3205 | [pbn_b1_8_1382400] = { | 3191 | [pbn_b1_8_1382400] = { |
3206 | .flags = FL_BASE1, | 3192 | .flags = FL_BASE1, |
3207 | .num_ports = 8, | 3193 | .num_ports = 8, |
3208 | .base_baud = 1382400, | 3194 | .base_baud = 1382400, |
3209 | .uart_offset = 8, | 3195 | .uart_offset = 8, |
3210 | }, | 3196 | }, |
3211 | 3197 | ||
3212 | [pbn_b2_1_115200] = { | 3198 | [pbn_b2_1_115200] = { |
3213 | .flags = FL_BASE2, | 3199 | .flags = FL_BASE2, |
3214 | .num_ports = 1, | 3200 | .num_ports = 1, |
3215 | .base_baud = 115200, | 3201 | .base_baud = 115200, |
3216 | .uart_offset = 8, | 3202 | .uart_offset = 8, |
3217 | }, | 3203 | }, |
3218 | [pbn_b2_2_115200] = { | 3204 | [pbn_b2_2_115200] = { |
3219 | .flags = FL_BASE2, | 3205 | .flags = FL_BASE2, |
3220 | .num_ports = 2, | 3206 | .num_ports = 2, |
3221 | .base_baud = 115200, | 3207 | .base_baud = 115200, |
3222 | .uart_offset = 8, | 3208 | .uart_offset = 8, |
3223 | }, | 3209 | }, |
3224 | [pbn_b2_4_115200] = { | 3210 | [pbn_b2_4_115200] = { |
3225 | .flags = FL_BASE2, | 3211 | .flags = FL_BASE2, |
3226 | .num_ports = 4, | 3212 | .num_ports = 4, |
3227 | .base_baud = 115200, | 3213 | .base_baud = 115200, |
3228 | .uart_offset = 8, | 3214 | .uart_offset = 8, |
3229 | }, | 3215 | }, |
3230 | [pbn_b2_8_115200] = { | 3216 | [pbn_b2_8_115200] = { |
3231 | .flags = FL_BASE2, | 3217 | .flags = FL_BASE2, |
3232 | .num_ports = 8, | 3218 | .num_ports = 8, |
3233 | .base_baud = 115200, | 3219 | .base_baud = 115200, |
3234 | .uart_offset = 8, | 3220 | .uart_offset = 8, |
3235 | }, | 3221 | }, |
3236 | 3222 | ||
3237 | [pbn_b2_1_460800] = { | 3223 | [pbn_b2_1_460800] = { |
3238 | .flags = FL_BASE2, | 3224 | .flags = FL_BASE2, |
3239 | .num_ports = 1, | 3225 | .num_ports = 1, |
3240 | .base_baud = 460800, | 3226 | .base_baud = 460800, |
3241 | .uart_offset = 8, | 3227 | .uart_offset = 8, |
3242 | }, | 3228 | }, |
3243 | [pbn_b2_4_460800] = { | 3229 | [pbn_b2_4_460800] = { |
3244 | .flags = FL_BASE2, | 3230 | .flags = FL_BASE2, |
3245 | .num_ports = 4, | 3231 | .num_ports = 4, |
3246 | .base_baud = 460800, | 3232 | .base_baud = 460800, |
3247 | .uart_offset = 8, | 3233 | .uart_offset = 8, |
3248 | }, | 3234 | }, |
3249 | [pbn_b2_8_460800] = { | 3235 | [pbn_b2_8_460800] = { |
3250 | .flags = FL_BASE2, | 3236 | .flags = FL_BASE2, |
3251 | .num_ports = 8, | 3237 | .num_ports = 8, |
3252 | .base_baud = 460800, | 3238 | .base_baud = 460800, |
3253 | .uart_offset = 8, | 3239 | .uart_offset = 8, |
3254 | }, | 3240 | }, |
3255 | [pbn_b2_16_460800] = { | 3241 | [pbn_b2_16_460800] = { |
3256 | .flags = FL_BASE2, | 3242 | .flags = FL_BASE2, |
3257 | .num_ports = 16, | 3243 | .num_ports = 16, |
3258 | .base_baud = 460800, | 3244 | .base_baud = 460800, |
3259 | .uart_offset = 8, | 3245 | .uart_offset = 8, |
3260 | }, | 3246 | }, |
3261 | 3247 | ||
3262 | [pbn_b2_1_921600] = { | 3248 | [pbn_b2_1_921600] = { |
3263 | .flags = FL_BASE2, | 3249 | .flags = FL_BASE2, |
3264 | .num_ports = 1, | 3250 | .num_ports = 1, |
3265 | .base_baud = 921600, | 3251 | .base_baud = 921600, |
3266 | .uart_offset = 8, | 3252 | .uart_offset = 8, |
3267 | }, | 3253 | }, |
3268 | [pbn_b2_4_921600] = { | 3254 | [pbn_b2_4_921600] = { |
3269 | .flags = FL_BASE2, | 3255 | .flags = FL_BASE2, |
3270 | .num_ports = 4, | 3256 | .num_ports = 4, |
3271 | .base_baud = 921600, | 3257 | .base_baud = 921600, |
3272 | .uart_offset = 8, | 3258 | .uart_offset = 8, |
3273 | }, | 3259 | }, |
3274 | [pbn_b2_8_921600] = { | 3260 | [pbn_b2_8_921600] = { |
3275 | .flags = FL_BASE2, | 3261 | .flags = FL_BASE2, |
3276 | .num_ports = 8, | 3262 | .num_ports = 8, |
3277 | .base_baud = 921600, | 3263 | .base_baud = 921600, |
3278 | .uart_offset = 8, | 3264 | .uart_offset = 8, |
3279 | }, | 3265 | }, |
3280 | 3266 | ||
3281 | [pbn_b2_8_1152000] = { | 3267 | [pbn_b2_8_1152000] = { |
3282 | .flags = FL_BASE2, | 3268 | .flags = FL_BASE2, |
3283 | .num_ports = 8, | 3269 | .num_ports = 8, |
3284 | .base_baud = 1152000, | 3270 | .base_baud = 1152000, |
3285 | .uart_offset = 8, | 3271 | .uart_offset = 8, |
3286 | }, | 3272 | }, |
3287 | 3273 | ||
3288 | [pbn_b2_bt_1_115200] = { | 3274 | [pbn_b2_bt_1_115200] = { |
3289 | .flags = FL_BASE2|FL_BASE_BARS, | 3275 | .flags = FL_BASE2|FL_BASE_BARS, |
3290 | .num_ports = 1, | 3276 | .num_ports = 1, |
3291 | .base_baud = 115200, | 3277 | .base_baud = 115200, |
3292 | .uart_offset = 8, | 3278 | .uart_offset = 8, |
3293 | }, | 3279 | }, |
3294 | [pbn_b2_bt_2_115200] = { | 3280 | [pbn_b2_bt_2_115200] = { |
3295 | .flags = FL_BASE2|FL_BASE_BARS, | 3281 | .flags = FL_BASE2|FL_BASE_BARS, |
3296 | .num_ports = 2, | 3282 | .num_ports = 2, |
3297 | .base_baud = 115200, | 3283 | .base_baud = 115200, |
3298 | .uart_offset = 8, | 3284 | .uart_offset = 8, |
3299 | }, | 3285 | }, |
3300 | [pbn_b2_bt_4_115200] = { | 3286 | [pbn_b2_bt_4_115200] = { |
3301 | .flags = FL_BASE2|FL_BASE_BARS, | 3287 | .flags = FL_BASE2|FL_BASE_BARS, |
3302 | .num_ports = 4, | 3288 | .num_ports = 4, |
3303 | .base_baud = 115200, | 3289 | .base_baud = 115200, |
3304 | .uart_offset = 8, | 3290 | .uart_offset = 8, |
3305 | }, | 3291 | }, |
3306 | 3292 | ||
3307 | [pbn_b2_bt_2_921600] = { | 3293 | [pbn_b2_bt_2_921600] = { |
3308 | .flags = FL_BASE2|FL_BASE_BARS, | 3294 | .flags = FL_BASE2|FL_BASE_BARS, |
3309 | .num_ports = 2, | 3295 | .num_ports = 2, |
3310 | .base_baud = 921600, | 3296 | .base_baud = 921600, |
3311 | .uart_offset = 8, | 3297 | .uart_offset = 8, |
3312 | }, | 3298 | }, |
3313 | [pbn_b2_bt_4_921600] = { | 3299 | [pbn_b2_bt_4_921600] = { |
3314 | .flags = FL_BASE2|FL_BASE_BARS, | 3300 | .flags = FL_BASE2|FL_BASE_BARS, |
3315 | .num_ports = 4, | 3301 | .num_ports = 4, |
3316 | .base_baud = 921600, | 3302 | .base_baud = 921600, |
3317 | .uart_offset = 8, | 3303 | .uart_offset = 8, |
3318 | }, | 3304 | }, |
3319 | 3305 | ||
3320 | [pbn_b3_2_115200] = { | 3306 | [pbn_b3_2_115200] = { |
3321 | .flags = FL_BASE3, | 3307 | .flags = FL_BASE3, |
3322 | .num_ports = 2, | 3308 | .num_ports = 2, |
3323 | .base_baud = 115200, | 3309 | .base_baud = 115200, |
3324 | .uart_offset = 8, | 3310 | .uart_offset = 8, |
3325 | }, | 3311 | }, |
3326 | [pbn_b3_4_115200] = { | 3312 | [pbn_b3_4_115200] = { |
3327 | .flags = FL_BASE3, | 3313 | .flags = FL_BASE3, |
3328 | .num_ports = 4, | 3314 | .num_ports = 4, |
3329 | .base_baud = 115200, | 3315 | .base_baud = 115200, |
3330 | .uart_offset = 8, | 3316 | .uart_offset = 8, |
3331 | }, | 3317 | }, |
3332 | [pbn_b3_8_115200] = { | 3318 | [pbn_b3_8_115200] = { |
3333 | .flags = FL_BASE3, | 3319 | .flags = FL_BASE3, |
3334 | .num_ports = 8, | 3320 | .num_ports = 8, |
3335 | .base_baud = 115200, | 3321 | .base_baud = 115200, |
3336 | .uart_offset = 8, | 3322 | .uart_offset = 8, |
3337 | }, | 3323 | }, |
3338 | 3324 | ||
3339 | [pbn_b4_bt_2_921600] = { | 3325 | [pbn_b4_bt_2_921600] = { |
3340 | .flags = FL_BASE4, | 3326 | .flags = FL_BASE4, |
3341 | .num_ports = 2, | 3327 | .num_ports = 2, |
3342 | .base_baud = 921600, | 3328 | .base_baud = 921600, |
3343 | .uart_offset = 8, | 3329 | .uart_offset = 8, |
3344 | }, | 3330 | }, |
3345 | [pbn_b4_bt_4_921600] = { | 3331 | [pbn_b4_bt_4_921600] = { |
3346 | .flags = FL_BASE4, | 3332 | .flags = FL_BASE4, |
3347 | .num_ports = 4, | 3333 | .num_ports = 4, |
3348 | .base_baud = 921600, | 3334 | .base_baud = 921600, |
3349 | .uart_offset = 8, | 3335 | .uart_offset = 8, |
3350 | }, | 3336 | }, |
3351 | [pbn_b4_bt_8_921600] = { | 3337 | [pbn_b4_bt_8_921600] = { |
3352 | .flags = FL_BASE4, | 3338 | .flags = FL_BASE4, |
3353 | .num_ports = 8, | 3339 | .num_ports = 8, |
3354 | .base_baud = 921600, | 3340 | .base_baud = 921600, |
3355 | .uart_offset = 8, | 3341 | .uart_offset = 8, |
3356 | }, | 3342 | }, |
3357 | 3343 | ||
3358 | /* | 3344 | /* |
3359 | * Entries following this are board-specific. | 3345 | * Entries following this are board-specific. |
3360 | */ | 3346 | */ |
3361 | 3347 | ||
3362 | /* | 3348 | /* |
3363 | * Panacom - IOMEM | 3349 | * Panacom - IOMEM |
3364 | */ | 3350 | */ |
3365 | [pbn_panacom] = { | 3351 | [pbn_panacom] = { |
3366 | .flags = FL_BASE2, | 3352 | .flags = FL_BASE2, |
3367 | .num_ports = 2, | 3353 | .num_ports = 2, |
3368 | .base_baud = 921600, | 3354 | .base_baud = 921600, |
3369 | .uart_offset = 0x400, | 3355 | .uart_offset = 0x400, |
3370 | .reg_shift = 7, | 3356 | .reg_shift = 7, |
3371 | }, | 3357 | }, |
3372 | [pbn_panacom2] = { | 3358 | [pbn_panacom2] = { |
3373 | .flags = FL_BASE2|FL_BASE_BARS, | 3359 | .flags = FL_BASE2|FL_BASE_BARS, |
3374 | .num_ports = 2, | 3360 | .num_ports = 2, |
3375 | .base_baud = 921600, | 3361 | .base_baud = 921600, |
3376 | .uart_offset = 0x400, | 3362 | .uart_offset = 0x400, |
3377 | .reg_shift = 7, | 3363 | .reg_shift = 7, |
3378 | }, | 3364 | }, |
3379 | [pbn_panacom4] = { | 3365 | [pbn_panacom4] = { |
3380 | .flags = FL_BASE2|FL_BASE_BARS, | 3366 | .flags = FL_BASE2|FL_BASE_BARS, |
3381 | .num_ports = 4, | 3367 | .num_ports = 4, |
3382 | .base_baud = 921600, | 3368 | .base_baud = 921600, |
3383 | .uart_offset = 0x400, | 3369 | .uart_offset = 0x400, |
3384 | .reg_shift = 7, | 3370 | .reg_shift = 7, |
3385 | }, | 3371 | }, |
3386 | 3372 | ||
3387 | /* I think this entry is broken - the first_offset looks wrong --rmk */ | 3373 | /* I think this entry is broken - the first_offset looks wrong --rmk */ |
3388 | [pbn_plx_romulus] = { | 3374 | [pbn_plx_romulus] = { |
3389 | .flags = FL_BASE2, | 3375 | .flags = FL_BASE2, |
3390 | .num_ports = 4, | 3376 | .num_ports = 4, |
3391 | .base_baud = 921600, | 3377 | .base_baud = 921600, |
3392 | .uart_offset = 8 << 2, | 3378 | .uart_offset = 8 << 2, |
3393 | .reg_shift = 2, | 3379 | .reg_shift = 2, |
3394 | .first_offset = 0x03, | 3380 | .first_offset = 0x03, |
3395 | }, | 3381 | }, |
3396 | 3382 | ||
3397 | /* | 3383 | /* |
3398 | * EndRun Technologies | 3384 | * EndRun Technologies |
3399 | * Uses the size of PCI Base region 0 to | 3385 | * Uses the size of PCI Base region 0 to |
3400 | * signal now many ports are available | 3386 | * signal now many ports are available |
3401 | * 2 port 952 Uart support | 3387 | * 2 port 952 Uart support |
3402 | */ | 3388 | */ |
3403 | [pbn_endrun_2_4000000] = { | 3389 | [pbn_endrun_2_4000000] = { |
3404 | .flags = FL_BASE0, | 3390 | .flags = FL_BASE0, |
3405 | .num_ports = 2, | 3391 | .num_ports = 2, |
3406 | .base_baud = 4000000, | 3392 | .base_baud = 4000000, |
3407 | .uart_offset = 0x200, | 3393 | .uart_offset = 0x200, |
3408 | .first_offset = 0x1000, | 3394 | .first_offset = 0x1000, |
3409 | }, | 3395 | }, |
3410 | 3396 | ||
3411 | /* | 3397 | /* |
3412 | * This board uses the size of PCI Base region 0 to | 3398 | * This board uses the size of PCI Base region 0 to |
3413 | * signal now many ports are available | 3399 | * signal now many ports are available |
3414 | */ | 3400 | */ |
3415 | [pbn_oxsemi] = { | 3401 | [pbn_oxsemi] = { |
3416 | .flags = FL_BASE0|FL_REGION_SZ_CAP, | 3402 | .flags = FL_BASE0|FL_REGION_SZ_CAP, |
3417 | .num_ports = 32, | 3403 | .num_ports = 32, |
3418 | .base_baud = 115200, | 3404 | .base_baud = 115200, |
3419 | .uart_offset = 8, | 3405 | .uart_offset = 8, |
3420 | }, | 3406 | }, |
3421 | [pbn_oxsemi_1_4000000] = { | 3407 | [pbn_oxsemi_1_4000000] = { |
3422 | .flags = FL_BASE0, | 3408 | .flags = FL_BASE0, |
3423 | .num_ports = 1, | 3409 | .num_ports = 1, |
3424 | .base_baud = 4000000, | 3410 | .base_baud = 4000000, |
3425 | .uart_offset = 0x200, | 3411 | .uart_offset = 0x200, |
3426 | .first_offset = 0x1000, | 3412 | .first_offset = 0x1000, |
3427 | }, | 3413 | }, |
3428 | [pbn_oxsemi_2_4000000] = { | 3414 | [pbn_oxsemi_2_4000000] = { |
3429 | .flags = FL_BASE0, | 3415 | .flags = FL_BASE0, |
3430 | .num_ports = 2, | 3416 | .num_ports = 2, |
3431 | .base_baud = 4000000, | 3417 | .base_baud = 4000000, |
3432 | .uart_offset = 0x200, | 3418 | .uart_offset = 0x200, |
3433 | .first_offset = 0x1000, | 3419 | .first_offset = 0x1000, |
3434 | }, | 3420 | }, |
3435 | [pbn_oxsemi_4_4000000] = { | 3421 | [pbn_oxsemi_4_4000000] = { |
3436 | .flags = FL_BASE0, | 3422 | .flags = FL_BASE0, |
3437 | .num_ports = 4, | 3423 | .num_ports = 4, |
3438 | .base_baud = 4000000, | 3424 | .base_baud = 4000000, |
3439 | .uart_offset = 0x200, | 3425 | .uart_offset = 0x200, |
3440 | .first_offset = 0x1000, | 3426 | .first_offset = 0x1000, |
3441 | }, | 3427 | }, |
3442 | [pbn_oxsemi_8_4000000] = { | 3428 | [pbn_oxsemi_8_4000000] = { |
3443 | .flags = FL_BASE0, | 3429 | .flags = FL_BASE0, |
3444 | .num_ports = 8, | 3430 | .num_ports = 8, |
3445 | .base_baud = 4000000, | 3431 | .base_baud = 4000000, |
3446 | .uart_offset = 0x200, | 3432 | .uart_offset = 0x200, |
3447 | .first_offset = 0x1000, | 3433 | .first_offset = 0x1000, |
3448 | }, | 3434 | }, |
3449 | 3435 | ||
3450 | 3436 | ||
3451 | /* | 3437 | /* |
3452 | * EKF addition for i960 Boards form EKF with serial port. | 3438 | * EKF addition for i960 Boards form EKF with serial port. |
3453 | * Max 256 ports. | 3439 | * Max 256 ports. |
3454 | */ | 3440 | */ |
3455 | [pbn_intel_i960] = { | 3441 | [pbn_intel_i960] = { |
3456 | .flags = FL_BASE0, | 3442 | .flags = FL_BASE0, |
3457 | .num_ports = 32, | 3443 | .num_ports = 32, |
3458 | .base_baud = 921600, | 3444 | .base_baud = 921600, |
3459 | .uart_offset = 8 << 2, | 3445 | .uart_offset = 8 << 2, |
3460 | .reg_shift = 2, | 3446 | .reg_shift = 2, |
3461 | .first_offset = 0x10000, | 3447 | .first_offset = 0x10000, |
3462 | }, | 3448 | }, |
3463 | [pbn_sgi_ioc3] = { | 3449 | [pbn_sgi_ioc3] = { |
3464 | .flags = FL_BASE0|FL_NOIRQ, | 3450 | .flags = FL_BASE0|FL_NOIRQ, |
3465 | .num_ports = 1, | 3451 | .num_ports = 1, |
3466 | .base_baud = 458333, | 3452 | .base_baud = 458333, |
3467 | .uart_offset = 8, | 3453 | .uart_offset = 8, |
3468 | .reg_shift = 0, | 3454 | .reg_shift = 0, |
3469 | .first_offset = 0x20178, | 3455 | .first_offset = 0x20178, |
3470 | }, | 3456 | }, |
3471 | 3457 | ||
3472 | /* | 3458 | /* |
3473 | * Computone - uses IOMEM. | 3459 | * Computone - uses IOMEM. |
3474 | */ | 3460 | */ |
3475 | [pbn_computone_4] = { | 3461 | [pbn_computone_4] = { |
3476 | .flags = FL_BASE0, | 3462 | .flags = FL_BASE0, |
3477 | .num_ports = 4, | 3463 | .num_ports = 4, |
3478 | .base_baud = 921600, | 3464 | .base_baud = 921600, |
3479 | .uart_offset = 0x40, | 3465 | .uart_offset = 0x40, |
3480 | .reg_shift = 2, | 3466 | .reg_shift = 2, |
3481 | .first_offset = 0x200, | 3467 | .first_offset = 0x200, |
3482 | }, | 3468 | }, |
3483 | [pbn_computone_6] = { | 3469 | [pbn_computone_6] = { |
3484 | .flags = FL_BASE0, | 3470 | .flags = FL_BASE0, |
3485 | .num_ports = 6, | 3471 | .num_ports = 6, |
3486 | .base_baud = 921600, | 3472 | .base_baud = 921600, |
3487 | .uart_offset = 0x40, | 3473 | .uart_offset = 0x40, |
3488 | .reg_shift = 2, | 3474 | .reg_shift = 2, |
3489 | .first_offset = 0x200, | 3475 | .first_offset = 0x200, |
3490 | }, | 3476 | }, |
3491 | [pbn_computone_8] = { | 3477 | [pbn_computone_8] = { |
3492 | .flags = FL_BASE0, | 3478 | .flags = FL_BASE0, |
3493 | .num_ports = 8, | 3479 | .num_ports = 8, |
3494 | .base_baud = 921600, | 3480 | .base_baud = 921600, |
3495 | .uart_offset = 0x40, | 3481 | .uart_offset = 0x40, |
3496 | .reg_shift = 2, | 3482 | .reg_shift = 2, |
3497 | .first_offset = 0x200, | 3483 | .first_offset = 0x200, |
3498 | }, | 3484 | }, |
3499 | [pbn_sbsxrsio] = { | 3485 | [pbn_sbsxrsio] = { |
3500 | .flags = FL_BASE0, | 3486 | .flags = FL_BASE0, |
3501 | .num_ports = 8, | 3487 | .num_ports = 8, |
3502 | .base_baud = 460800, | 3488 | .base_baud = 460800, |
3503 | .uart_offset = 256, | 3489 | .uart_offset = 256, |
3504 | .reg_shift = 4, | 3490 | .reg_shift = 4, |
3505 | }, | 3491 | }, |
3506 | /* | 3492 | /* |
3507 | * Exar Corp. XR17C15[248] Dual/Quad/Octal UART | 3493 | * Exar Corp. XR17C15[248] Dual/Quad/Octal UART |
3508 | * Only basic 16550A support. | 3494 | * Only basic 16550A support. |
3509 | * XR17C15[24] are not tested, but they should work. | 3495 | * XR17C15[24] are not tested, but they should work. |
3510 | */ | 3496 | */ |
3511 | [pbn_exar_XR17C152] = { | 3497 | [pbn_exar_XR17C152] = { |
3512 | .flags = FL_BASE0, | 3498 | .flags = FL_BASE0, |
3513 | .num_ports = 2, | 3499 | .num_ports = 2, |
3514 | .base_baud = 921600, | 3500 | .base_baud = 921600, |
3515 | .uart_offset = 0x200, | 3501 | .uart_offset = 0x200, |
3516 | }, | 3502 | }, |
3517 | [pbn_exar_XR17C154] = { | 3503 | [pbn_exar_XR17C154] = { |
3518 | .flags = FL_BASE0, | 3504 | .flags = FL_BASE0, |
3519 | .num_ports = 4, | 3505 | .num_ports = 4, |
3520 | .base_baud = 921600, | 3506 | .base_baud = 921600, |
3521 | .uart_offset = 0x200, | 3507 | .uart_offset = 0x200, |
3522 | }, | 3508 | }, |
3523 | [pbn_exar_XR17C158] = { | 3509 | [pbn_exar_XR17C158] = { |
3524 | .flags = FL_BASE0, | 3510 | .flags = FL_BASE0, |
3525 | .num_ports = 8, | 3511 | .num_ports = 8, |
3526 | .base_baud = 921600, | 3512 | .base_baud = 921600, |
3527 | .uart_offset = 0x200, | 3513 | .uart_offset = 0x200, |
3528 | }, | 3514 | }, |
3529 | [pbn_exar_XR17V352] = { | 3515 | [pbn_exar_XR17V352] = { |
3530 | .flags = FL_BASE0, | 3516 | .flags = FL_BASE0, |
3531 | .num_ports = 2, | 3517 | .num_ports = 2, |
3532 | .base_baud = 7812500, | 3518 | .base_baud = 7812500, |
3533 | .uart_offset = 0x400, | 3519 | .uart_offset = 0x400, |
3534 | .reg_shift = 0, | 3520 | .reg_shift = 0, |
3535 | .first_offset = 0, | 3521 | .first_offset = 0, |
3536 | }, | 3522 | }, |
3537 | [pbn_exar_XR17V354] = { | 3523 | [pbn_exar_XR17V354] = { |
3538 | .flags = FL_BASE0, | 3524 | .flags = FL_BASE0, |
3539 | .num_ports = 4, | 3525 | .num_ports = 4, |
3540 | .base_baud = 7812500, | 3526 | .base_baud = 7812500, |
3541 | .uart_offset = 0x400, | 3527 | .uart_offset = 0x400, |
3542 | .reg_shift = 0, | 3528 | .reg_shift = 0, |
3543 | .first_offset = 0, | 3529 | .first_offset = 0, |
3544 | }, | 3530 | }, |
3545 | [pbn_exar_XR17V358] = { | 3531 | [pbn_exar_XR17V358] = { |
3546 | .flags = FL_BASE0, | 3532 | .flags = FL_BASE0, |
3547 | .num_ports = 8, | 3533 | .num_ports = 8, |
3548 | .base_baud = 7812500, | 3534 | .base_baud = 7812500, |
3549 | .uart_offset = 0x400, | 3535 | .uart_offset = 0x400, |
3550 | .reg_shift = 0, | 3536 | .reg_shift = 0, |
3551 | .first_offset = 0, | 3537 | .first_offset = 0, |
3552 | }, | 3538 | }, |
3553 | [pbn_exar_ibm_saturn] = { | 3539 | [pbn_exar_ibm_saturn] = { |
3554 | .flags = FL_BASE0, | 3540 | .flags = FL_BASE0, |
3555 | .num_ports = 1, | 3541 | .num_ports = 1, |
3556 | .base_baud = 921600, | 3542 | .base_baud = 921600, |
3557 | .uart_offset = 0x200, | 3543 | .uart_offset = 0x200, |
3558 | }, | 3544 | }, |
3559 | 3545 | ||
3560 | /* | 3546 | /* |
3561 | * PA Semi PWRficient PA6T-1682M on-chip UART | 3547 | * PA Semi PWRficient PA6T-1682M on-chip UART |
3562 | */ | 3548 | */ |
3563 | [pbn_pasemi_1682M] = { | 3549 | [pbn_pasemi_1682M] = { |
3564 | .flags = FL_BASE0, | 3550 | .flags = FL_BASE0, |
3565 | .num_ports = 1, | 3551 | .num_ports = 1, |
3566 | .base_baud = 8333333, | 3552 | .base_baud = 8333333, |
3567 | }, | 3553 | }, |
3568 | /* | 3554 | /* |
3569 | * National Instruments 843x | 3555 | * National Instruments 843x |
3570 | */ | 3556 | */ |
3571 | [pbn_ni8430_16] = { | 3557 | [pbn_ni8430_16] = { |
3572 | .flags = FL_BASE0, | 3558 | .flags = FL_BASE0, |
3573 | .num_ports = 16, | 3559 | .num_ports = 16, |
3574 | .base_baud = 3686400, | 3560 | .base_baud = 3686400, |
3575 | .uart_offset = 0x10, | 3561 | .uart_offset = 0x10, |
3576 | .first_offset = 0x800, | 3562 | .first_offset = 0x800, |
3577 | }, | 3563 | }, |
3578 | [pbn_ni8430_8] = { | 3564 | [pbn_ni8430_8] = { |
3579 | .flags = FL_BASE0, | 3565 | .flags = FL_BASE0, |
3580 | .num_ports = 8, | 3566 | .num_ports = 8, |
3581 | .base_baud = 3686400, | 3567 | .base_baud = 3686400, |
3582 | .uart_offset = 0x10, | 3568 | .uart_offset = 0x10, |
3583 | .first_offset = 0x800, | 3569 | .first_offset = 0x800, |
3584 | }, | 3570 | }, |
3585 | [pbn_ni8430_4] = { | 3571 | [pbn_ni8430_4] = { |
3586 | .flags = FL_BASE0, | 3572 | .flags = FL_BASE0, |
3587 | .num_ports = 4, | 3573 | .num_ports = 4, |
3588 | .base_baud = 3686400, | 3574 | .base_baud = 3686400, |
3589 | .uart_offset = 0x10, | 3575 | .uart_offset = 0x10, |
3590 | .first_offset = 0x800, | 3576 | .first_offset = 0x800, |
3591 | }, | 3577 | }, |
3592 | [pbn_ni8430_2] = { | 3578 | [pbn_ni8430_2] = { |
3593 | .flags = FL_BASE0, | 3579 | .flags = FL_BASE0, |
3594 | .num_ports = 2, | 3580 | .num_ports = 2, |
3595 | .base_baud = 3686400, | 3581 | .base_baud = 3686400, |
3596 | .uart_offset = 0x10, | 3582 | .uart_offset = 0x10, |
3597 | .first_offset = 0x800, | 3583 | .first_offset = 0x800, |
3598 | }, | 3584 | }, |
3599 | /* | 3585 | /* |
3600 | * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com> | 3586 | * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com> |
3601 | */ | 3587 | */ |
3602 | [pbn_ADDIDATA_PCIe_1_3906250] = { | 3588 | [pbn_ADDIDATA_PCIe_1_3906250] = { |
3603 | .flags = FL_BASE0, | 3589 | .flags = FL_BASE0, |
3604 | .num_ports = 1, | 3590 | .num_ports = 1, |
3605 | .base_baud = 3906250, | 3591 | .base_baud = 3906250, |
3606 | .uart_offset = 0x200, | 3592 | .uart_offset = 0x200, |
3607 | .first_offset = 0x1000, | 3593 | .first_offset = 0x1000, |
3608 | }, | 3594 | }, |
3609 | [pbn_ADDIDATA_PCIe_2_3906250] = { | 3595 | [pbn_ADDIDATA_PCIe_2_3906250] = { |
3610 | .flags = FL_BASE0, | 3596 | .flags = FL_BASE0, |
3611 | .num_ports = 2, | 3597 | .num_ports = 2, |
3612 | .base_baud = 3906250, | 3598 | .base_baud = 3906250, |
3613 | .uart_offset = 0x200, | 3599 | .uart_offset = 0x200, |
3614 | .first_offset = 0x1000, | 3600 | .first_offset = 0x1000, |
3615 | }, | 3601 | }, |
3616 | [pbn_ADDIDATA_PCIe_4_3906250] = { | 3602 | [pbn_ADDIDATA_PCIe_4_3906250] = { |
3617 | .flags = FL_BASE0, | 3603 | .flags = FL_BASE0, |
3618 | .num_ports = 4, | 3604 | .num_ports = 4, |
3619 | .base_baud = 3906250, | 3605 | .base_baud = 3906250, |
3620 | .uart_offset = 0x200, | 3606 | .uart_offset = 0x200, |
3621 | .first_offset = 0x1000, | 3607 | .first_offset = 0x1000, |
3622 | }, | 3608 | }, |
3623 | [pbn_ADDIDATA_PCIe_8_3906250] = { | 3609 | [pbn_ADDIDATA_PCIe_8_3906250] = { |
3624 | .flags = FL_BASE0, | 3610 | .flags = FL_BASE0, |
3625 | .num_ports = 8, | 3611 | .num_ports = 8, |
3626 | .base_baud = 3906250, | 3612 | .base_baud = 3906250, |
3627 | .uart_offset = 0x200, | 3613 | .uart_offset = 0x200, |
3628 | .first_offset = 0x1000, | 3614 | .first_offset = 0x1000, |
3629 | }, | 3615 | }, |
3630 | [pbn_ce4100_1_115200] = { | 3616 | [pbn_ce4100_1_115200] = { |
3631 | .flags = FL_BASE_BARS, | 3617 | .flags = FL_BASE_BARS, |
3632 | .num_ports = 2, | 3618 | .num_ports = 2, |
3633 | .base_baud = 921600, | 3619 | .base_baud = 921600, |
3634 | .reg_shift = 2, | 3620 | .reg_shift = 2, |
3635 | }, | 3621 | }, |
3636 | /* | 3622 | /* |
3637 | * Intel BayTrail HSUART reference clock is 44.2368 MHz at power-on, | 3623 | * Intel BayTrail HSUART reference clock is 44.2368 MHz at power-on, |
3638 | * but is overridden by byt_set_termios. | 3624 | * but is overridden by byt_set_termios. |
3639 | */ | 3625 | */ |
3640 | [pbn_byt] = { | 3626 | [pbn_byt] = { |
3641 | .flags = FL_BASE0, | 3627 | .flags = FL_BASE0, |
3642 | .num_ports = 1, | 3628 | .num_ports = 1, |
3643 | .base_baud = 2764800, | 3629 | .base_baud = 2764800, |
3644 | .uart_offset = 0x80, | 3630 | .uart_offset = 0x80, |
3645 | .reg_shift = 2, | 3631 | .reg_shift = 2, |
3646 | }, | 3632 | }, |
3647 | [pbn_qrk] = { | 3633 | [pbn_qrk] = { |
3648 | .flags = FL_BASE0, | 3634 | .flags = FL_BASE0, |
3649 | .num_ports = 1, | 3635 | .num_ports = 1, |
3650 | .base_baud = 2764800, | 3636 | .base_baud = 2764800, |
3651 | .reg_shift = 2, | 3637 | .reg_shift = 2, |
3652 | }, | 3638 | }, |
3653 | [pbn_omegapci] = { | 3639 | [pbn_omegapci] = { |
3654 | .flags = FL_BASE0, | 3640 | .flags = FL_BASE0, |
3655 | .num_ports = 8, | 3641 | .num_ports = 8, |
3656 | .base_baud = 115200, | 3642 | .base_baud = 115200, |
3657 | .uart_offset = 0x200, | 3643 | .uart_offset = 0x200, |
3658 | }, | 3644 | }, |
3659 | [pbn_NETMOS9900_2s_115200] = { | 3645 | [pbn_NETMOS9900_2s_115200] = { |
3660 | .flags = FL_BASE0, | 3646 | .flags = FL_BASE0, |
3661 | .num_ports = 2, | 3647 | .num_ports = 2, |
3662 | .base_baud = 115200, | 3648 | .base_baud = 115200, |
3663 | }, | 3649 | }, |
3664 | [pbn_brcm_trumanage] = { | 3650 | [pbn_brcm_trumanage] = { |
3665 | .flags = FL_BASE0, | 3651 | .flags = FL_BASE0, |
3666 | .num_ports = 1, | 3652 | .num_ports = 1, |
3667 | .reg_shift = 2, | 3653 | .reg_shift = 2, |
3668 | .base_baud = 115200, | 3654 | .base_baud = 115200, |
3669 | }, | 3655 | }, |
3670 | [pbn_fintek_4] = { | 3656 | [pbn_fintek_4] = { |
3671 | .num_ports = 4, | 3657 | .num_ports = 4, |
3672 | .uart_offset = 8, | 3658 | .uart_offset = 8, |
3673 | .base_baud = 115200, | 3659 | .base_baud = 115200, |
3674 | .first_offset = 0x40, | 3660 | .first_offset = 0x40, |
3675 | }, | 3661 | }, |
3676 | [pbn_fintek_8] = { | 3662 | [pbn_fintek_8] = { |
3677 | .num_ports = 8, | 3663 | .num_ports = 8, |
3678 | .uart_offset = 8, | 3664 | .uart_offset = 8, |
3679 | .base_baud = 115200, | 3665 | .base_baud = 115200, |
3680 | .first_offset = 0x40, | 3666 | .first_offset = 0x40, |
3681 | }, | 3667 | }, |
3682 | [pbn_fintek_12] = { | 3668 | [pbn_fintek_12] = { |
3683 | .num_ports = 12, | 3669 | .num_ports = 12, |
3684 | .uart_offset = 8, | 3670 | .uart_offset = 8, |
3685 | .base_baud = 115200, | 3671 | .base_baud = 115200, |
3686 | .first_offset = 0x40, | 3672 | .first_offset = 0x40, |
3687 | }, | 3673 | }, |
3688 | 3674 | ||
3689 | [pbn_wch384_4] = { | 3675 | [pbn_wch384_4] = { |
3690 | .flags = FL_BASE0, | 3676 | .flags = FL_BASE0, |
3691 | .num_ports = 4, | 3677 | .num_ports = 4, |
3692 | .base_baud = 115200, | 3678 | .base_baud = 115200, |
3693 | .uart_offset = 8, | 3679 | .uart_offset = 8, |
3694 | .first_offset = 0xC0, | 3680 | .first_offset = 0xC0, |
3695 | }, | 3681 | }, |
3696 | }; | 3682 | }; |
3697 | 3683 | ||
3698 | static const struct pci_device_id blacklist[] = { | 3684 | static const struct pci_device_id blacklist[] = { |
3699 | /* softmodems */ | 3685 | /* softmodems */ |
3700 | { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ | 3686 | { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ |
3701 | { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */ | 3687 | { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */ |
3702 | { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */ | 3688 | { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */ |
3703 | 3689 | ||
3704 | /* multi-io cards handled by parport_serial */ | 3690 | /* multi-io cards handled by parport_serial */ |
3705 | { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ | 3691 | { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ |
3706 | { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ | 3692 | { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ |
3707 | { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ | 3693 | { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ |
3708 | { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ | 3694 | { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ |
3709 | }; | 3695 | }; |
3710 | 3696 | ||
3711 | /* | 3697 | /* |
3712 | * Given a complete unknown PCI device, try to use some heuristics to | 3698 | * Given a complete unknown PCI device, try to use some heuristics to |
3713 | * guess what the configuration might be, based on the pitiful PCI | 3699 | * guess what the configuration might be, based on the pitiful PCI |
3714 | * serial specs. Returns 0 on success, 1 on failure. | 3700 | * serial specs. Returns 0 on success, 1 on failure. |
3715 | */ | 3701 | */ |
3716 | static int | 3702 | static int |
3717 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) | 3703 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) |
3718 | { | 3704 | { |
3719 | const struct pci_device_id *bldev; | 3705 | const struct pci_device_id *bldev; |
3720 | int num_iomem, num_port, first_port = -1, i; | 3706 | int num_iomem, num_port, first_port = -1, i; |
3721 | 3707 | ||
3722 | /* | 3708 | /* |
3723 | * If it is not a communications device or the programming | 3709 | * If it is not a communications device or the programming |
3724 | * interface is greater than 6, give up. | 3710 | * interface is greater than 6, give up. |
3725 | * | 3711 | * |
3726 | * (Should we try to make guesses for multiport serial devices | 3712 | * (Should we try to make guesses for multiport serial devices |
3727 | * later?) | 3713 | * later?) |
3728 | */ | 3714 | */ |
3729 | if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) && | 3715 | if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) && |
3730 | ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) || | 3716 | ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) || |
3731 | (dev->class & 0xff) > 6) | 3717 | (dev->class & 0xff) > 6) |
3732 | return -ENODEV; | 3718 | return -ENODEV; |
3733 | 3719 | ||
3734 | /* | 3720 | /* |
3735 | * Do not access blacklisted devices that are known not to | 3721 | * Do not access blacklisted devices that are known not to |
3736 | * feature serial ports or are handled by other modules. | 3722 | * feature serial ports or are handled by other modules. |
3737 | */ | 3723 | */ |
3738 | for (bldev = blacklist; | 3724 | for (bldev = blacklist; |
3739 | bldev < blacklist + ARRAY_SIZE(blacklist); | 3725 | bldev < blacklist + ARRAY_SIZE(blacklist); |
3740 | bldev++) { | 3726 | bldev++) { |
3741 | if (dev->vendor == bldev->vendor && | 3727 | if (dev->vendor == bldev->vendor && |
3742 | dev->device == bldev->device) | 3728 | dev->device == bldev->device) |
3743 | return -ENODEV; | 3729 | return -ENODEV; |
3744 | } | 3730 | } |
3745 | 3731 | ||
3746 | num_iomem = num_port = 0; | 3732 | num_iomem = num_port = 0; |
3747 | for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { | 3733 | for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { |
3748 | if (pci_resource_flags(dev, i) & IORESOURCE_IO) { | 3734 | if (pci_resource_flags(dev, i) & IORESOURCE_IO) { |
3749 | num_port++; | 3735 | num_port++; |
3750 | if (first_port == -1) | 3736 | if (first_port == -1) |
3751 | first_port = i; | 3737 | first_port = i; |
3752 | } | 3738 | } |
3753 | if (pci_resource_flags(dev, i) & IORESOURCE_MEM) | 3739 | if (pci_resource_flags(dev, i) & IORESOURCE_MEM) |
3754 | num_iomem++; | 3740 | num_iomem++; |
3755 | } | 3741 | } |
3756 | 3742 | ||
3757 | /* | 3743 | /* |
3758 | * If there is 1 or 0 iomem regions, and exactly one port, | 3744 | * If there is 1 or 0 iomem regions, and exactly one port, |
3759 | * use it. We guess the number of ports based on the IO | 3745 | * use it. We guess the number of ports based on the IO |
3760 | * region size. | 3746 | * region size. |
3761 | */ | 3747 | */ |
3762 | if (num_iomem <= 1 && num_port == 1) { | 3748 | if (num_iomem <= 1 && num_port == 1) { |
3763 | board->flags = first_port; | 3749 | board->flags = first_port; |
3764 | board->num_ports = pci_resource_len(dev, first_port) / 8; | 3750 | board->num_ports = pci_resource_len(dev, first_port) / 8; |
3765 | return 0; | 3751 | return 0; |
3766 | } | 3752 | } |
3767 | 3753 | ||
3768 | /* | 3754 | /* |
3769 | * Now guess if we've got a board which indexes by BARs. | 3755 | * Now guess if we've got a board which indexes by BARs. |
3770 | * Each IO BAR should be 8 bytes, and they should follow | 3756 | * Each IO BAR should be 8 bytes, and they should follow |
3771 | * consecutively. | 3757 | * consecutively. |
3772 | */ | 3758 | */ |
3773 | first_port = -1; | 3759 | first_port = -1; |
3774 | num_port = 0; | 3760 | num_port = 0; |
3775 | for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { | 3761 | for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { |
3776 | if (pci_resource_flags(dev, i) & IORESOURCE_IO && | 3762 | if (pci_resource_flags(dev, i) & IORESOURCE_IO && |
3777 | pci_resource_len(dev, i) == 8 && | 3763 | pci_resource_len(dev, i) == 8 && |
3778 | (first_port == -1 || (first_port + num_port) == i)) { | 3764 | (first_port == -1 || (first_port + num_port) == i)) { |
3779 | num_port++; | 3765 | num_port++; |
3780 | if (first_port == -1) | 3766 | if (first_port == -1) |
3781 | first_port = i; | 3767 | first_port = i; |
3782 | } | 3768 | } |
3783 | } | 3769 | } |
3784 | 3770 | ||
3785 | if (num_port > 1) { | 3771 | if (num_port > 1) { |
3786 | board->flags = first_port | FL_BASE_BARS; | 3772 | board->flags = first_port | FL_BASE_BARS; |
3787 | board->num_ports = num_port; | 3773 | board->num_ports = num_port; |
3788 | return 0; | 3774 | return 0; |
3789 | } | 3775 | } |
3790 | 3776 | ||
3791 | return -ENODEV; | 3777 | return -ENODEV; |
3792 | } | 3778 | } |
3793 | 3779 | ||
3794 | static inline int | 3780 | static inline int |
3795 | serial_pci_matches(const struct pciserial_board *board, | 3781 | serial_pci_matches(const struct pciserial_board *board, |
3796 | const struct pciserial_board *guessed) | 3782 | const struct pciserial_board *guessed) |
3797 | { | 3783 | { |
3798 | return | 3784 | return |
3799 | board->num_ports == guessed->num_ports && | 3785 | board->num_ports == guessed->num_ports && |
3800 | board->base_baud == guessed->base_baud && | 3786 | board->base_baud == guessed->base_baud && |
3801 | board->uart_offset == guessed->uart_offset && | 3787 | board->uart_offset == guessed->uart_offset && |
3802 | board->reg_shift == guessed->reg_shift && | 3788 | board->reg_shift == guessed->reg_shift && |
3803 | board->first_offset == guessed->first_offset; | 3789 | board->first_offset == guessed->first_offset; |
3804 | } | 3790 | } |
3805 | 3791 | ||
3806 | struct serial_private * | 3792 | struct serial_private * |
3807 | pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) | 3793 | pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) |
3808 | { | 3794 | { |
3809 | struct uart_8250_port uart; | 3795 | struct uart_8250_port uart; |
3810 | struct serial_private *priv; | 3796 | struct serial_private *priv; |
3811 | struct pci_serial_quirk *quirk; | 3797 | struct pci_serial_quirk *quirk; |
3812 | int rc, nr_ports, i; | 3798 | int rc, nr_ports, i; |
3813 | 3799 | ||
3814 | nr_ports = board->num_ports; | 3800 | nr_ports = board->num_ports; |
3815 | 3801 | ||
3816 | /* | 3802 | /* |
3817 | * Find an init and setup quirks. | 3803 | * Find an init and setup quirks. |
3818 | */ | 3804 | */ |
3819 | quirk = find_quirk(dev); | 3805 | quirk = find_quirk(dev); |
3820 | 3806 | ||
3821 | /* | 3807 | /* |
3822 | * Run the new-style initialization function. | 3808 | * Run the new-style initialization function. |
3823 | * The initialization function returns: | 3809 | * The initialization function returns: |
3824 | * <0 - error | 3810 | * <0 - error |
3825 | * 0 - use board->num_ports | 3811 | * 0 - use board->num_ports |
3826 | * >0 - number of ports | 3812 | * >0 - number of ports |
3827 | */ | 3813 | */ |
3828 | if (quirk->init) { | 3814 | if (quirk->init) { |
3829 | rc = quirk->init(dev); | 3815 | rc = quirk->init(dev); |
3830 | if (rc < 0) { | 3816 | if (rc < 0) { |
3831 | priv = ERR_PTR(rc); | 3817 | priv = ERR_PTR(rc); |
3832 | goto err_out; | 3818 | goto err_out; |
3833 | } | 3819 | } |
3834 | if (rc) | 3820 | if (rc) |
3835 | nr_ports = rc; | 3821 | nr_ports = rc; |
3836 | } | 3822 | } |
3837 | 3823 | ||
3838 | priv = kzalloc(sizeof(struct serial_private) + | 3824 | priv = kzalloc(sizeof(struct serial_private) + |
3839 | sizeof(unsigned int) * nr_ports, | 3825 | sizeof(unsigned int) * nr_ports, |
3840 | GFP_KERNEL); | 3826 | GFP_KERNEL); |
3841 | if (!priv) { | 3827 | if (!priv) { |
3842 | priv = ERR_PTR(-ENOMEM); | 3828 | priv = ERR_PTR(-ENOMEM); |
3843 | goto err_deinit; | 3829 | goto err_deinit; |
3844 | } | 3830 | } |
3845 | 3831 | ||
3846 | priv->dev = dev; | 3832 | priv->dev = dev; |
3847 | priv->quirk = quirk; | 3833 | priv->quirk = quirk; |
3848 | 3834 | ||
3849 | memset(&uart, 0, sizeof(uart)); | 3835 | memset(&uart, 0, sizeof(uart)); |
3850 | uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | 3836 | uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; |
3851 | uart.port.uartclk = board->base_baud * 16; | 3837 | uart.port.uartclk = board->base_baud * 16; |
3852 | uart.port.irq = get_pci_irq(dev, board); | 3838 | uart.port.irq = get_pci_irq(dev, board); |
3853 | uart.port.dev = &dev->dev; | 3839 | uart.port.dev = &dev->dev; |
3854 | 3840 | ||
3855 | for (i = 0; i < nr_ports; i++) { | 3841 | for (i = 0; i < nr_ports; i++) { |
3856 | if (quirk->setup(priv, board, &uart, i)) | 3842 | if (quirk->setup(priv, board, &uart, i)) |
3857 | break; | 3843 | break; |
3858 | 3844 | ||
3859 | dev_dbg(&dev->dev, "Setup PCI port: port %lx, irq %d, type %d\n", | 3845 | dev_dbg(&dev->dev, "Setup PCI port: port %lx, irq %d, type %d\n", |
3860 | uart.port.iobase, uart.port.irq, uart.port.iotype); | 3846 | uart.port.iobase, uart.port.irq, uart.port.iotype); |
3861 | 3847 | ||
3862 | priv->line[i] = serial8250_register_8250_port(&uart); | 3848 | priv->line[i] = serial8250_register_8250_port(&uart); |
3863 | if (priv->line[i] < 0) { | 3849 | if (priv->line[i] < 0) { |
3864 | dev_err(&dev->dev, | 3850 | dev_err(&dev->dev, |
3865 | "Couldn't register serial port %lx, irq %d, type %d, error %d\n", | 3851 | "Couldn't register serial port %lx, irq %d, type %d, error %d\n", |
3866 | uart.port.iobase, uart.port.irq, | 3852 | uart.port.iobase, uart.port.irq, |
3867 | uart.port.iotype, priv->line[i]); | 3853 | uart.port.iotype, priv->line[i]); |
3868 | break; | 3854 | break; |
3869 | } | 3855 | } |
3870 | } | 3856 | } |
3871 | priv->nr = i; | 3857 | priv->nr = i; |
3872 | return priv; | 3858 | return priv; |
3873 | 3859 | ||
3874 | err_deinit: | 3860 | err_deinit: |
3875 | if (quirk->exit) | 3861 | if (quirk->exit) |
3876 | quirk->exit(dev); | 3862 | quirk->exit(dev); |
3877 | err_out: | 3863 | err_out: |
3878 | return priv; | 3864 | return priv; |
3879 | } | 3865 | } |
3880 | EXPORT_SYMBOL_GPL(pciserial_init_ports); | 3866 | EXPORT_SYMBOL_GPL(pciserial_init_ports); |
3881 | 3867 | ||
3882 | void pciserial_remove_ports(struct serial_private *priv) | 3868 | void pciserial_remove_ports(struct serial_private *priv) |
3883 | { | 3869 | { |
3884 | struct pci_serial_quirk *quirk; | 3870 | struct pci_serial_quirk *quirk; |
3885 | int i; | 3871 | int i; |
3886 | 3872 | ||
3887 | for (i = 0; i < priv->nr; i++) | 3873 | for (i = 0; i < priv->nr; i++) |
3888 | serial8250_unregister_port(priv->line[i]); | 3874 | serial8250_unregister_port(priv->line[i]); |
3889 | 3875 | ||
3890 | for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { | 3876 | for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { |
3891 | if (priv->remapped_bar[i]) | 3877 | if (priv->remapped_bar[i]) |
3892 | iounmap(priv->remapped_bar[i]); | 3878 | iounmap(priv->remapped_bar[i]); |
3893 | priv->remapped_bar[i] = NULL; | 3879 | priv->remapped_bar[i] = NULL; |
3894 | } | 3880 | } |
3895 | 3881 | ||
3896 | /* | 3882 | /* |
3897 | * Find the exit quirks. | 3883 | * Find the exit quirks. |
3898 | */ | 3884 | */ |
3899 | quirk = find_quirk(priv->dev); | 3885 | quirk = find_quirk(priv->dev); |
3900 | if (quirk->exit) | 3886 | if (quirk->exit) |
3901 | quirk->exit(priv->dev); | 3887 | quirk->exit(priv->dev); |
3902 | 3888 | ||
3903 | kfree(priv); | 3889 | kfree(priv); |
3904 | } | 3890 | } |
3905 | EXPORT_SYMBOL_GPL(pciserial_remove_ports); | 3891 | EXPORT_SYMBOL_GPL(pciserial_remove_ports); |
3906 | 3892 | ||
3907 | void pciserial_suspend_ports(struct serial_private *priv) | 3893 | void pciserial_suspend_ports(struct serial_private *priv) |
3908 | { | 3894 | { |
3909 | int i; | 3895 | int i; |
3910 | 3896 | ||
3911 | for (i = 0; i < priv->nr; i++) | 3897 | for (i = 0; i < priv->nr; i++) |
3912 | if (priv->line[i] >= 0) | 3898 | if (priv->line[i] >= 0) |
3913 | serial8250_suspend_port(priv->line[i]); | 3899 | serial8250_suspend_port(priv->line[i]); |
3914 | 3900 | ||
3915 | /* | 3901 | /* |
3916 | * Ensure that every init quirk is properly torn down | 3902 | * Ensure that every init quirk is properly torn down |
3917 | */ | 3903 | */ |
3918 | if (priv->quirk->exit) | 3904 | if (priv->quirk->exit) |
3919 | priv->quirk->exit(priv->dev); | 3905 | priv->quirk->exit(priv->dev); |
3920 | } | 3906 | } |
3921 | EXPORT_SYMBOL_GPL(pciserial_suspend_ports); | 3907 | EXPORT_SYMBOL_GPL(pciserial_suspend_ports); |
3922 | 3908 | ||
3923 | void pciserial_resume_ports(struct serial_private *priv) | 3909 | void pciserial_resume_ports(struct serial_private *priv) |
3924 | { | 3910 | { |
3925 | int i; | 3911 | int i; |
3926 | 3912 | ||
3927 | /* | 3913 | /* |
3928 | * Ensure that the board is correctly configured. | 3914 | * Ensure that the board is correctly configured. |
3929 | */ | 3915 | */ |
3930 | if (priv->quirk->init) | 3916 | if (priv->quirk->init) |
3931 | priv->quirk->init(priv->dev); | 3917 | priv->quirk->init(priv->dev); |
3932 | 3918 | ||
3933 | for (i = 0; i < priv->nr; i++) | 3919 | for (i = 0; i < priv->nr; i++) |
3934 | if (priv->line[i] >= 0) | 3920 | if (priv->line[i] >= 0) |
3935 | serial8250_resume_port(priv->line[i]); | 3921 | serial8250_resume_port(priv->line[i]); |
3936 | } | 3922 | } |
3937 | EXPORT_SYMBOL_GPL(pciserial_resume_ports); | 3923 | EXPORT_SYMBOL_GPL(pciserial_resume_ports); |
3938 | 3924 | ||
3939 | /* | 3925 | /* |
3940 | * Probe one serial board. Unfortunately, there is no rhyme nor reason | 3926 | * Probe one serial board. Unfortunately, there is no rhyme nor reason |
3941 | * to the arrangement of serial ports on a PCI card. | 3927 | * to the arrangement of serial ports on a PCI card. |
3942 | */ | 3928 | */ |
3943 | static int | 3929 | static int |
3944 | pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | 3930 | pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) |
3945 | { | 3931 | { |
3946 | struct pci_serial_quirk *quirk; | 3932 | struct pci_serial_quirk *quirk; |
3947 | struct serial_private *priv; | 3933 | struct serial_private *priv; |
3948 | const struct pciserial_board *board; | 3934 | const struct pciserial_board *board; |
3949 | struct pciserial_board tmp; | 3935 | struct pciserial_board tmp; |
3950 | int rc; | 3936 | int rc; |
3951 | 3937 | ||
3952 | quirk = find_quirk(dev); | 3938 | quirk = find_quirk(dev); |
3953 | if (quirk->probe) { | 3939 | if (quirk->probe) { |
3954 | rc = quirk->probe(dev); | 3940 | rc = quirk->probe(dev); |
3955 | if (rc) | 3941 | if (rc) |
3956 | return rc; | 3942 | return rc; |
3957 | } | 3943 | } |
3958 | 3944 | ||
3959 | if (ent->driver_data >= ARRAY_SIZE(pci_boards)) { | 3945 | if (ent->driver_data >= ARRAY_SIZE(pci_boards)) { |
3960 | dev_err(&dev->dev, "invalid driver_data: %ld\n", | 3946 | dev_err(&dev->dev, "invalid driver_data: %ld\n", |
3961 | ent->driver_data); | 3947 | ent->driver_data); |
3962 | return -EINVAL; | 3948 | return -EINVAL; |
3963 | } | 3949 | } |
3964 | 3950 | ||
3965 | board = &pci_boards[ent->driver_data]; | 3951 | board = &pci_boards[ent->driver_data]; |
3966 | 3952 | ||
3967 | rc = pci_enable_device(dev); | 3953 | rc = pci_enable_device(dev); |
3968 | pci_save_state(dev); | 3954 | pci_save_state(dev); |
3969 | if (rc) | 3955 | if (rc) |
3970 | return rc; | 3956 | return rc; |
3971 | 3957 | ||
3972 | if (ent->driver_data == pbn_default) { | 3958 | if (ent->driver_data == pbn_default) { |
3973 | /* | 3959 | /* |
3974 | * Use a copy of the pci_board entry for this; | 3960 | * Use a copy of the pci_board entry for this; |
3975 | * avoid changing entries in the table. | 3961 | * avoid changing entries in the table. |
3976 | */ | 3962 | */ |
3977 | memcpy(&tmp, board, sizeof(struct pciserial_board)); | 3963 | memcpy(&tmp, board, sizeof(struct pciserial_board)); |
3978 | board = &tmp; | 3964 | board = &tmp; |
3979 | 3965 | ||
3980 | /* | 3966 | /* |
3981 | * We matched one of our class entries. Try to | 3967 | * We matched one of our class entries. Try to |
3982 | * determine the parameters of this board. | 3968 | * determine the parameters of this board. |
3983 | */ | 3969 | */ |
3984 | rc = serial_pci_guess_board(dev, &tmp); | 3970 | rc = serial_pci_guess_board(dev, &tmp); |
3985 | if (rc) | 3971 | if (rc) |
3986 | goto disable; | 3972 | goto disable; |
3987 | } else { | 3973 | } else { |
3988 | /* | 3974 | /* |
3989 | * We matched an explicit entry. If we are able to | 3975 | * We matched an explicit entry. If we are able to |
3990 | * detect this boards settings with our heuristic, | 3976 | * detect this boards settings with our heuristic, |
3991 | * then we no longer need this entry. | 3977 | * then we no longer need this entry. |
3992 | */ | 3978 | */ |
3993 | memcpy(&tmp, &pci_boards[pbn_default], | 3979 | memcpy(&tmp, &pci_boards[pbn_default], |
3994 | sizeof(struct pciserial_board)); | 3980 | sizeof(struct pciserial_board)); |
3995 | rc = serial_pci_guess_board(dev, &tmp); | 3981 | rc = serial_pci_guess_board(dev, &tmp); |
3996 | if (rc == 0 && serial_pci_matches(board, &tmp)) | 3982 | if (rc == 0 && serial_pci_matches(board, &tmp)) |
3997 | moan_device("Redundant entry in serial pci_table.", | 3983 | moan_device("Redundant entry in serial pci_table.", |
3998 | dev); | 3984 | dev); |
3999 | } | 3985 | } |
4000 | 3986 | ||
4001 | priv = pciserial_init_ports(dev, board); | 3987 | priv = pciserial_init_ports(dev, board); |
4002 | if (!IS_ERR(priv)) { | 3988 | if (!IS_ERR(priv)) { |
4003 | pci_set_drvdata(dev, priv); | 3989 | pci_set_drvdata(dev, priv); |
4004 | return 0; | 3990 | return 0; |
4005 | } | 3991 | } |
4006 | 3992 | ||
4007 | rc = PTR_ERR(priv); | 3993 | rc = PTR_ERR(priv); |
4008 | 3994 | ||
4009 | disable: | 3995 | disable: |
4010 | pci_disable_device(dev); | 3996 | pci_disable_device(dev); |
4011 | return rc; | 3997 | return rc; |
4012 | } | 3998 | } |
4013 | 3999 | ||
4014 | static void pciserial_remove_one(struct pci_dev *dev) | 4000 | static void pciserial_remove_one(struct pci_dev *dev) |
4015 | { | 4001 | { |
4016 | struct serial_private *priv = pci_get_drvdata(dev); | 4002 | struct serial_private *priv = pci_get_drvdata(dev); |
4017 | 4003 | ||
4018 | pciserial_remove_ports(priv); | 4004 | pciserial_remove_ports(priv); |
4019 | 4005 | ||
4020 | pci_disable_device(dev); | 4006 | pci_disable_device(dev); |
4021 | } | 4007 | } |
4022 | 4008 | ||
4023 | #ifdef CONFIG_PM | 4009 | #ifdef CONFIG_PM |
4024 | static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state) | 4010 | static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state) |
4025 | { | 4011 | { |
4026 | struct serial_private *priv = pci_get_drvdata(dev); | 4012 | struct serial_private *priv = pci_get_drvdata(dev); |
4027 | 4013 | ||
4028 | if (priv) | 4014 | if (priv) |
4029 | pciserial_suspend_ports(priv); | 4015 | pciserial_suspend_ports(priv); |
4030 | 4016 | ||
4031 | pci_save_state(dev); | 4017 | pci_save_state(dev); |
4032 | pci_set_power_state(dev, pci_choose_state(dev, state)); | 4018 | pci_set_power_state(dev, pci_choose_state(dev, state)); |
4033 | return 0; | 4019 | return 0; |
4034 | } | 4020 | } |
4035 | 4021 | ||
4036 | static int pciserial_resume_one(struct pci_dev *dev) | 4022 | static int pciserial_resume_one(struct pci_dev *dev) |
4037 | { | 4023 | { |
4038 | int err; | 4024 | int err; |
4039 | struct serial_private *priv = pci_get_drvdata(dev); | 4025 | struct serial_private *priv = pci_get_drvdata(dev); |
4040 | 4026 | ||
4041 | pci_set_power_state(dev, PCI_D0); | 4027 | pci_set_power_state(dev, PCI_D0); |
4042 | pci_restore_state(dev); | 4028 | pci_restore_state(dev); |
4043 | 4029 | ||
4044 | if (priv) { | 4030 | if (priv) { |
4045 | /* | 4031 | /* |
4046 | * The device may have been disabled. Re-enable it. | 4032 | * The device may have been disabled. Re-enable it. |
4047 | */ | 4033 | */ |
4048 | err = pci_enable_device(dev); | 4034 | err = pci_enable_device(dev); |
4049 | /* FIXME: We cannot simply error out here */ | 4035 | /* FIXME: We cannot simply error out here */ |
4050 | if (err) | 4036 | if (err) |
4051 | dev_err(&dev->dev, "Unable to re-enable ports, trying to continue.\n"); | 4037 | dev_err(&dev->dev, "Unable to re-enable ports, trying to continue.\n"); |
4052 | pciserial_resume_ports(priv); | 4038 | pciserial_resume_ports(priv); |
4053 | } | 4039 | } |
4054 | return 0; | 4040 | return 0; |
4055 | } | 4041 | } |
4056 | #endif | 4042 | #endif |
4057 | 4043 | ||
4058 | static struct pci_device_id serial_pci_tbl[] = { | 4044 | static struct pci_device_id serial_pci_tbl[] = { |
4059 | /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */ | 4045 | /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */ |
4060 | { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620, | 4046 | { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620, |
4061 | PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0, | 4047 | PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0, |
4062 | pbn_b2_8_921600 }, | 4048 | pbn_b2_8_921600 }, |
4063 | /* Advantech also use 0x3618 and 0xf618 */ | 4049 | /* Advantech also use 0x3618 and 0xf618 */ |
4064 | { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3618, | 4050 | { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3618, |
4065 | PCI_DEVICE_ID_ADVANTECH_PCI3618, PCI_ANY_ID, 0, 0, | 4051 | PCI_DEVICE_ID_ADVANTECH_PCI3618, PCI_ANY_ID, 0, 0, |
4066 | pbn_b0_4_921600 }, | 4052 | pbn_b0_4_921600 }, |
4067 | { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCIf618, | 4053 | { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCIf618, |
4068 | PCI_DEVICE_ID_ADVANTECH_PCI3618, PCI_ANY_ID, 0, 0, | 4054 | PCI_DEVICE_ID_ADVANTECH_PCI3618, PCI_ANY_ID, 0, 0, |
4069 | pbn_b0_4_921600 }, | 4055 | pbn_b0_4_921600 }, |
4070 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, | 4056 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, |
4071 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4057 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4072 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0, | 4058 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0, |
4073 | pbn_b1_8_1382400 }, | 4059 | pbn_b1_8_1382400 }, |
4074 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, | 4060 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, |
4075 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4061 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4076 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0, | 4062 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0, |
4077 | pbn_b1_4_1382400 }, | 4063 | pbn_b1_4_1382400 }, |
4078 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, | 4064 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, |
4079 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4065 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4080 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0, | 4066 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0, |
4081 | pbn_b1_2_1382400 }, | 4067 | pbn_b1_2_1382400 }, |
4082 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4068 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4083 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4069 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4084 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0, | 4070 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0, |
4085 | pbn_b1_8_1382400 }, | 4071 | pbn_b1_8_1382400 }, |
4086 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4072 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4087 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4073 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4088 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0, | 4074 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0, |
4089 | pbn_b1_4_1382400 }, | 4075 | pbn_b1_4_1382400 }, |
4090 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4076 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4091 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4077 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4092 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0, | 4078 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0, |
4093 | pbn_b1_2_1382400 }, | 4079 | pbn_b1_2_1382400 }, |
4094 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4080 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4095 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4081 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4096 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0, | 4082 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0, |
4097 | pbn_b1_8_921600 }, | 4083 | pbn_b1_8_921600 }, |
4098 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4084 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4099 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4085 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4100 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0, | 4086 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0, |
4101 | pbn_b1_8_921600 }, | 4087 | pbn_b1_8_921600 }, |
4102 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4088 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4103 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4089 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4104 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0, | 4090 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0, |
4105 | pbn_b1_4_921600 }, | 4091 | pbn_b1_4_921600 }, |
4106 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4092 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4107 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4093 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4108 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0, | 4094 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0, |
4109 | pbn_b1_4_921600 }, | 4095 | pbn_b1_4_921600 }, |
4110 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4096 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4111 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4097 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4112 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0, | 4098 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0, |
4113 | pbn_b1_2_921600 }, | 4099 | pbn_b1_2_921600 }, |
4114 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4100 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4115 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4101 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4116 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0, | 4102 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0, |
4117 | pbn_b1_8_921600 }, | 4103 | pbn_b1_8_921600 }, |
4118 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4104 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4119 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4105 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4120 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0, | 4106 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0, |
4121 | pbn_b1_8_921600 }, | 4107 | pbn_b1_8_921600 }, |
4122 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4108 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4123 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4109 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4124 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0, | 4110 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0, |
4125 | pbn_b1_4_921600 }, | 4111 | pbn_b1_4_921600 }, |
4126 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, | 4112 | { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, |
4127 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4113 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4128 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ, 0, 0, | 4114 | PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ, 0, 0, |
4129 | pbn_b1_2_1250000 }, | 4115 | pbn_b1_2_1250000 }, |
4130 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, | 4116 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, |
4131 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4117 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4132 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2, 0, 0, | 4118 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2, 0, 0, |
4133 | pbn_b0_2_1843200 }, | 4119 | pbn_b0_2_1843200 }, |
4134 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, | 4120 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, |
4135 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4121 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4136 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0, | 4122 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0, |
4137 | pbn_b0_4_1843200 }, | 4123 | pbn_b0_4_1843200 }, |
4138 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, | 4124 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, |
4139 | PCI_VENDOR_ID_AFAVLAB, | 4125 | PCI_VENDOR_ID_AFAVLAB, |
4140 | PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0, | 4126 | PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0, |
4141 | pbn_b0_4_1152000 }, | 4127 | pbn_b0_4_1152000 }, |
4142 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | 4128 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, |
4143 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4129 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4144 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, | 4130 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, |
4145 | pbn_b0_2_1843200_200 }, | 4131 | pbn_b0_2_1843200_200 }, |
4146 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, | 4132 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, |
4147 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4133 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4148 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232, 0, 0, | 4134 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232, 0, 0, |
4149 | pbn_b0_4_1843200_200 }, | 4135 | pbn_b0_4_1843200_200 }, |
4150 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, | 4136 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, |
4151 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4137 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4152 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232, 0, 0, | 4138 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232, 0, 0, |
4153 | pbn_b0_8_1843200_200 }, | 4139 | pbn_b0_8_1843200_200 }, |
4154 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | 4140 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, |
4155 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4141 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4156 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1, 0, 0, | 4142 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1, 0, 0, |
4157 | pbn_b0_2_1843200_200 }, | 4143 | pbn_b0_2_1843200_200 }, |
4158 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, | 4144 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, |
4159 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4145 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4160 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2, 0, 0, | 4146 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2, 0, 0, |
4161 | pbn_b0_4_1843200_200 }, | 4147 | pbn_b0_4_1843200_200 }, |
4162 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, | 4148 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, |
4163 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4149 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4164 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4, 0, 0, | 4150 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4, 0, 0, |
4165 | pbn_b0_8_1843200_200 }, | 4151 | pbn_b0_8_1843200_200 }, |
4166 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | 4152 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, |
4167 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4153 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4168 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2, 0, 0, | 4154 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2, 0, 0, |
4169 | pbn_b0_2_1843200_200 }, | 4155 | pbn_b0_2_1843200_200 }, |
4170 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, | 4156 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, |
4171 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4157 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4172 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4, 0, 0, | 4158 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4, 0, 0, |
4173 | pbn_b0_4_1843200_200 }, | 4159 | pbn_b0_4_1843200_200 }, |
4174 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, | 4160 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, |
4175 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4161 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4176 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8, 0, 0, | 4162 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8, 0, 0, |
4177 | pbn_b0_8_1843200_200 }, | 4163 | pbn_b0_8_1843200_200 }, |
4178 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | 4164 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, |
4179 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4165 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4180 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485, 0, 0, | 4166 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485, 0, 0, |
4181 | pbn_b0_2_1843200_200 }, | 4167 | pbn_b0_2_1843200_200 }, |
4182 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, | 4168 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, |
4183 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4169 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4184 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485, 0, 0, | 4170 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485, 0, 0, |
4185 | pbn_b0_4_1843200_200 }, | 4171 | pbn_b0_4_1843200_200 }, |
4186 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, | 4172 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, |
4187 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 4173 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
4188 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0, | 4174 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0, |
4189 | pbn_b0_8_1843200_200 }, | 4175 | pbn_b0_8_1843200_200 }, |
4190 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | 4176 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, |
4191 | PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT, | 4177 | PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT, |
4192 | 0, 0, pbn_exar_ibm_saturn }, | 4178 | 0, 0, pbn_exar_ibm_saturn }, |
4193 | 4179 | ||
4194 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530, | 4180 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530, |
4195 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4181 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4196 | pbn_b2_bt_1_115200 }, | 4182 | pbn_b2_bt_1_115200 }, |
4197 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2, | 4183 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2, |
4198 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4184 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4199 | pbn_b2_bt_2_115200 }, | 4185 | pbn_b2_bt_2_115200 }, |
4200 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422, | 4186 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422, |
4201 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4187 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4202 | pbn_b2_bt_4_115200 }, | 4188 | pbn_b2_bt_4_115200 }, |
4203 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232, | 4189 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232, |
4204 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4190 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4205 | pbn_b2_bt_2_115200 }, | 4191 | pbn_b2_bt_2_115200 }, |
4206 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4, | 4192 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4, |
4207 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4193 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4208 | pbn_b2_bt_4_115200 }, | 4194 | pbn_b2_bt_4_115200 }, |
4209 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8, | 4195 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8, |
4210 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4196 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4211 | pbn_b2_8_115200 }, | 4197 | pbn_b2_8_115200 }, |
4212 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_7803, | 4198 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_7803, |
4213 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4199 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4214 | pbn_b2_8_460800 }, | 4200 | pbn_b2_8_460800 }, |
4215 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8, | 4201 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8, |
4216 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4202 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4217 | pbn_b2_8_115200 }, | 4203 | pbn_b2_8_115200 }, |
4218 | 4204 | ||
4219 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2, | 4205 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2, |
4220 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4206 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4221 | pbn_b2_bt_2_115200 }, | 4207 | pbn_b2_bt_2_115200 }, |
4222 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200, | 4208 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200, |
4223 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4209 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4224 | pbn_b2_bt_2_921600 }, | 4210 | pbn_b2_bt_2_921600 }, |
4225 | /* | 4211 | /* |
4226 | * VScom SPCOM800, from sl@s.pl | 4212 | * VScom SPCOM800, from sl@s.pl |
4227 | */ | 4213 | */ |
4228 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800, | 4214 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800, |
4229 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4215 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4230 | pbn_b2_8_921600 }, | 4216 | pbn_b2_8_921600 }, |
4231 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077, | 4217 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077, |
4232 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4218 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4233 | pbn_b2_4_921600 }, | 4219 | pbn_b2_4_921600 }, |
4234 | /* Unknown card - subdevice 0x1584 */ | 4220 | /* Unknown card - subdevice 0x1584 */ |
4235 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4221 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4236 | PCI_VENDOR_ID_PLX, | 4222 | PCI_VENDOR_ID_PLX, |
4237 | PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0, | 4223 | PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0, |
4238 | pbn_b2_4_115200 }, | 4224 | pbn_b2_4_115200 }, |
4239 | /* Unknown card - subdevice 0x1588 */ | 4225 | /* Unknown card - subdevice 0x1588 */ |
4240 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4226 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4241 | PCI_VENDOR_ID_PLX, | 4227 | PCI_VENDOR_ID_PLX, |
4242 | PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0, | 4228 | PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0, |
4243 | pbn_b2_8_115200 }, | 4229 | pbn_b2_8_115200 }, |
4244 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4230 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4245 | PCI_SUBVENDOR_ID_KEYSPAN, | 4231 | PCI_SUBVENDOR_ID_KEYSPAN, |
4246 | PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0, | 4232 | PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0, |
4247 | pbn_panacom }, | 4233 | pbn_panacom }, |
4248 | { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM, | 4234 | { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM, |
4249 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4235 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4250 | pbn_panacom4 }, | 4236 | pbn_panacom4 }, |
4251 | { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM, | 4237 | { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM, |
4252 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4238 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4253 | pbn_panacom2 }, | 4239 | pbn_panacom2 }, |
4254 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, | 4240 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, |
4255 | PCI_VENDOR_ID_ESDGMBH, | 4241 | PCI_VENDOR_ID_ESDGMBH, |
4256 | PCI_DEVICE_ID_ESDGMBH_CPCIASIO4, 0, 0, | 4242 | PCI_DEVICE_ID_ESDGMBH_CPCIASIO4, 0, 0, |
4257 | pbn_b2_4_115200 }, | 4243 | pbn_b2_4_115200 }, |
4258 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4244 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4259 | PCI_SUBVENDOR_ID_CHASE_PCIFAST, | 4245 | PCI_SUBVENDOR_ID_CHASE_PCIFAST, |
4260 | PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0, | 4246 | PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0, |
4261 | pbn_b2_4_460800 }, | 4247 | pbn_b2_4_460800 }, |
4262 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4248 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4263 | PCI_SUBVENDOR_ID_CHASE_PCIFAST, | 4249 | PCI_SUBVENDOR_ID_CHASE_PCIFAST, |
4264 | PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0, | 4250 | PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0, |
4265 | pbn_b2_8_460800 }, | 4251 | pbn_b2_8_460800 }, |
4266 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4252 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4267 | PCI_SUBVENDOR_ID_CHASE_PCIFAST, | 4253 | PCI_SUBVENDOR_ID_CHASE_PCIFAST, |
4268 | PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0, | 4254 | PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0, |
4269 | pbn_b2_16_460800 }, | 4255 | pbn_b2_16_460800 }, |
4270 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4256 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4271 | PCI_SUBVENDOR_ID_CHASE_PCIFAST, | 4257 | PCI_SUBVENDOR_ID_CHASE_PCIFAST, |
4272 | PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0, | 4258 | PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0, |
4273 | pbn_b2_16_460800 }, | 4259 | pbn_b2_16_460800 }, |
4274 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4260 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4275 | PCI_SUBVENDOR_ID_CHASE_PCIRAS, | 4261 | PCI_SUBVENDOR_ID_CHASE_PCIRAS, |
4276 | PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0, | 4262 | PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0, |
4277 | pbn_b2_4_460800 }, | 4263 | pbn_b2_4_460800 }, |
4278 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4264 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4279 | PCI_SUBVENDOR_ID_CHASE_PCIRAS, | 4265 | PCI_SUBVENDOR_ID_CHASE_PCIRAS, |
4280 | PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0, | 4266 | PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0, |
4281 | pbn_b2_8_460800 }, | 4267 | pbn_b2_8_460800 }, |
4282 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 4268 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
4283 | PCI_SUBVENDOR_ID_EXSYS, | 4269 | PCI_SUBVENDOR_ID_EXSYS, |
4284 | PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0, | 4270 | PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0, |
4285 | pbn_b2_4_115200 }, | 4271 | pbn_b2_4_115200 }, |
4286 | /* | 4272 | /* |
4287 | * Megawolf Romulus PCI Serial Card, from Mike Hudson | 4273 | * Megawolf Romulus PCI Serial Card, from Mike Hudson |
4288 | * (Exoray@isys.ca) | 4274 | * (Exoray@isys.ca) |
4289 | */ | 4275 | */ |
4290 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, | 4276 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, |
4291 | 0x10b5, 0x106a, 0, 0, | 4277 | 0x10b5, 0x106a, 0, 0, |
4292 | pbn_plx_romulus }, | 4278 | pbn_plx_romulus }, |
4293 | /* | 4279 | /* |
4294 | * EndRun Technologies. PCI express device range. | 4280 | * EndRun Technologies. PCI express device range. |
4295 | * EndRun PTP/1588 has 2 Native UARTs. | 4281 | * EndRun PTP/1588 has 2 Native UARTs. |
4296 | */ | 4282 | */ |
4297 | { PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588, | 4283 | { PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588, |
4298 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4284 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4299 | pbn_endrun_2_4000000 }, | 4285 | pbn_endrun_2_4000000 }, |
4300 | /* | 4286 | /* |
4301 | * Quatech cards. These actually have configurable clocks but for | 4287 | * Quatech cards. These actually have configurable clocks but for |
4302 | * now we just use the default. | 4288 | * now we just use the default. |
4303 | * | 4289 | * |
4304 | * 100 series are RS232, 200 series RS422, | 4290 | * 100 series are RS232, 200 series RS422, |
4305 | */ | 4291 | */ |
4306 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100, | 4292 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100, |
4307 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4293 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4308 | pbn_b1_4_115200 }, | 4294 | pbn_b1_4_115200 }, |
4309 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100, | 4295 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100, |
4310 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4296 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4311 | pbn_b1_2_115200 }, | 4297 | pbn_b1_2_115200 }, |
4312 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100E, | 4298 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100E, |
4313 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4299 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4314 | pbn_b2_2_115200 }, | 4300 | pbn_b2_2_115200 }, |
4315 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200, | 4301 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200, |
4316 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4302 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4317 | pbn_b1_2_115200 }, | 4303 | pbn_b1_2_115200 }, |
4318 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200E, | 4304 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200E, |
4319 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4305 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4320 | pbn_b2_2_115200 }, | 4306 | pbn_b2_2_115200 }, |
4321 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC200, | 4307 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC200, |
4322 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4308 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4323 | pbn_b1_4_115200 }, | 4309 | pbn_b1_4_115200 }, |
4324 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D, | 4310 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D, |
4325 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4311 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4326 | pbn_b1_8_115200 }, | 4312 | pbn_b1_8_115200 }, |
4327 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M, | 4313 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M, |
4328 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4314 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4329 | pbn_b1_8_115200 }, | 4315 | pbn_b1_8_115200 }, |
4330 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP100, | 4316 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP100, |
4331 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4317 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4332 | pbn_b1_4_115200 }, | 4318 | pbn_b1_4_115200 }, |
4333 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP100, | 4319 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP100, |
4334 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4320 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4335 | pbn_b1_2_115200 }, | 4321 | pbn_b1_2_115200 }, |
4336 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP200, | 4322 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP200, |
4337 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4323 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4338 | pbn_b1_4_115200 }, | 4324 | pbn_b1_4_115200 }, |
4339 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP200, | 4325 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP200, |
4340 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4326 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4341 | pbn_b1_2_115200 }, | 4327 | pbn_b1_2_115200 }, |
4342 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP100, | 4328 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP100, |
4343 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4329 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4344 | pbn_b2_4_115200 }, | 4330 | pbn_b2_4_115200 }, |
4345 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP100, | 4331 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP100, |
4346 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4332 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4347 | pbn_b2_2_115200 }, | 4333 | pbn_b2_2_115200 }, |
4348 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP100, | 4334 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP100, |
4349 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4335 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4350 | pbn_b2_1_115200 }, | 4336 | pbn_b2_1_115200 }, |
4351 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP200, | 4337 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP200, |
4352 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4338 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4353 | pbn_b2_4_115200 }, | 4339 | pbn_b2_4_115200 }, |
4354 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP200, | 4340 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP200, |
4355 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4341 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4356 | pbn_b2_2_115200 }, | 4342 | pbn_b2_2_115200 }, |
4357 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP200, | 4343 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP200, |
4358 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4344 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4359 | pbn_b2_1_115200 }, | 4345 | pbn_b2_1_115200 }, |
4360 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESCLP100, | 4346 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESCLP100, |
4361 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4347 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4362 | pbn_b0_8_115200 }, | 4348 | pbn_b0_8_115200 }, |
4363 | 4349 | ||
4364 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954, | 4350 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954, |
4365 | PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, | 4351 | PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, |
4366 | 0, 0, | 4352 | 0, 0, |
4367 | pbn_b0_4_921600 }, | 4353 | pbn_b0_4_921600 }, |
4368 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, | 4354 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, |
4369 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL, | 4355 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL, |
4370 | 0, 0, | 4356 | 0, 0, |
4371 | pbn_b0_4_1152000 }, | 4357 | pbn_b0_4_1152000 }, |
4372 | { PCI_VENDOR_ID_OXSEMI, 0x9505, | 4358 | { PCI_VENDOR_ID_OXSEMI, 0x9505, |
4373 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4359 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4374 | pbn_b0_bt_2_921600 }, | 4360 | pbn_b0_bt_2_921600 }, |
4375 | 4361 | ||
4376 | /* | 4362 | /* |
4377 | * The below card is a little controversial since it is the | 4363 | * The below card is a little controversial since it is the |
4378 | * subject of a PCI vendor/device ID clash. (See | 4364 | * subject of a PCI vendor/device ID clash. (See |
4379 | * www.ussg.iu.edu/hypermail/linux/kernel/0303.1/0516.html). | 4365 | * www.ussg.iu.edu/hypermail/linux/kernel/0303.1/0516.html). |
4380 | * For now just used the hex ID 0x950a. | 4366 | * For now just used the hex ID 0x950a. |
4381 | */ | 4367 | */ |
4382 | { PCI_VENDOR_ID_OXSEMI, 0x950a, | 4368 | { PCI_VENDOR_ID_OXSEMI, 0x950a, |
4383 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_00, | 4369 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_00, |
4384 | 0, 0, pbn_b0_2_115200 }, | 4370 | 0, 0, pbn_b0_2_115200 }, |
4385 | { PCI_VENDOR_ID_OXSEMI, 0x950a, | 4371 | { PCI_VENDOR_ID_OXSEMI, 0x950a, |
4386 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_30, | 4372 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_30, |
4387 | 0, 0, pbn_b0_2_115200 }, | 4373 | 0, 0, pbn_b0_2_115200 }, |
4388 | { PCI_VENDOR_ID_OXSEMI, 0x950a, | 4374 | { PCI_VENDOR_ID_OXSEMI, 0x950a, |
4389 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4375 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4390 | pbn_b0_2_1130000 }, | 4376 | pbn_b0_2_1130000 }, |
4391 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_C950, | 4377 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_C950, |
4392 | PCI_VENDOR_ID_OXSEMI, PCI_SUBDEVICE_ID_OXSEMI_C950, 0, 0, | 4378 | PCI_VENDOR_ID_OXSEMI, PCI_SUBDEVICE_ID_OXSEMI_C950, 0, 0, |
4393 | pbn_b0_1_921600 }, | 4379 | pbn_b0_1_921600 }, |
4394 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, | 4380 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, |
4395 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4381 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4396 | pbn_b0_4_115200 }, | 4382 | pbn_b0_4_115200 }, |
4397 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952, | 4383 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952, |
4398 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4384 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4399 | pbn_b0_bt_2_921600 }, | 4385 | pbn_b0_bt_2_921600 }, |
4400 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958, | 4386 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958, |
4401 | PCI_ANY_ID , PCI_ANY_ID, 0, 0, | 4387 | PCI_ANY_ID , PCI_ANY_ID, 0, 0, |
4402 | pbn_b2_8_1152000 }, | 4388 | pbn_b2_8_1152000 }, |
4403 | 4389 | ||
4404 | /* | 4390 | /* |
4405 | * Oxford Semiconductor Inc. Tornado PCI express device range. | 4391 | * Oxford Semiconductor Inc. Tornado PCI express device range. |
4406 | */ | 4392 | */ |
4407 | { PCI_VENDOR_ID_OXSEMI, 0xc101, /* OXPCIe952 1 Legacy UART */ | 4393 | { PCI_VENDOR_ID_OXSEMI, 0xc101, /* OXPCIe952 1 Legacy UART */ |
4408 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4394 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4409 | pbn_b0_1_4000000 }, | 4395 | pbn_b0_1_4000000 }, |
4410 | { PCI_VENDOR_ID_OXSEMI, 0xc105, /* OXPCIe952 1 Legacy UART */ | 4396 | { PCI_VENDOR_ID_OXSEMI, 0xc105, /* OXPCIe952 1 Legacy UART */ |
4411 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4397 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4412 | pbn_b0_1_4000000 }, | 4398 | pbn_b0_1_4000000 }, |
4413 | { PCI_VENDOR_ID_OXSEMI, 0xc11b, /* OXPCIe952 1 Native UART */ | 4399 | { PCI_VENDOR_ID_OXSEMI, 0xc11b, /* OXPCIe952 1 Native UART */ |
4414 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4400 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4415 | pbn_oxsemi_1_4000000 }, | 4401 | pbn_oxsemi_1_4000000 }, |
4416 | { PCI_VENDOR_ID_OXSEMI, 0xc11f, /* OXPCIe952 1 Native UART */ | 4402 | { PCI_VENDOR_ID_OXSEMI, 0xc11f, /* OXPCIe952 1 Native UART */ |
4417 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4403 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4418 | pbn_oxsemi_1_4000000 }, | 4404 | pbn_oxsemi_1_4000000 }, |
4419 | { PCI_VENDOR_ID_OXSEMI, 0xc120, /* OXPCIe952 1 Legacy UART */ | 4405 | { PCI_VENDOR_ID_OXSEMI, 0xc120, /* OXPCIe952 1 Legacy UART */ |
4420 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4406 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4421 | pbn_b0_1_4000000 }, | 4407 | pbn_b0_1_4000000 }, |
4422 | { PCI_VENDOR_ID_OXSEMI, 0xc124, /* OXPCIe952 1 Legacy UART */ | 4408 | { PCI_VENDOR_ID_OXSEMI, 0xc124, /* OXPCIe952 1 Legacy UART */ |
4423 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4409 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4424 | pbn_b0_1_4000000 }, | 4410 | pbn_b0_1_4000000 }, |
4425 | { PCI_VENDOR_ID_OXSEMI, 0xc138, /* OXPCIe952 1 Native UART */ | 4411 | { PCI_VENDOR_ID_OXSEMI, 0xc138, /* OXPCIe952 1 Native UART */ |
4426 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4412 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4427 | pbn_oxsemi_1_4000000 }, | 4413 | pbn_oxsemi_1_4000000 }, |
4428 | { PCI_VENDOR_ID_OXSEMI, 0xc13d, /* OXPCIe952 1 Native UART */ | 4414 | { PCI_VENDOR_ID_OXSEMI, 0xc13d, /* OXPCIe952 1 Native UART */ |
4429 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4415 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4430 | pbn_oxsemi_1_4000000 }, | 4416 | pbn_oxsemi_1_4000000 }, |
4431 | { PCI_VENDOR_ID_OXSEMI, 0xc140, /* OXPCIe952 1 Legacy UART */ | 4417 | { PCI_VENDOR_ID_OXSEMI, 0xc140, /* OXPCIe952 1 Legacy UART */ |
4432 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4418 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4433 | pbn_b0_1_4000000 }, | 4419 | pbn_b0_1_4000000 }, |
4434 | { PCI_VENDOR_ID_OXSEMI, 0xc141, /* OXPCIe952 1 Legacy UART */ | 4420 | { PCI_VENDOR_ID_OXSEMI, 0xc141, /* OXPCIe952 1 Legacy UART */ |
4435 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4421 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4436 | pbn_b0_1_4000000 }, | 4422 | pbn_b0_1_4000000 }, |
4437 | { PCI_VENDOR_ID_OXSEMI, 0xc144, /* OXPCIe952 1 Legacy UART */ | 4423 | { PCI_VENDOR_ID_OXSEMI, 0xc144, /* OXPCIe952 1 Legacy UART */ |
4438 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4424 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4439 | pbn_b0_1_4000000 }, | 4425 | pbn_b0_1_4000000 }, |
4440 | { PCI_VENDOR_ID_OXSEMI, 0xc145, /* OXPCIe952 1 Legacy UART */ | 4426 | { PCI_VENDOR_ID_OXSEMI, 0xc145, /* OXPCIe952 1 Legacy UART */ |
4441 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4427 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4442 | pbn_b0_1_4000000 }, | 4428 | pbn_b0_1_4000000 }, |
4443 | { PCI_VENDOR_ID_OXSEMI, 0xc158, /* OXPCIe952 2 Native UART */ | 4429 | { PCI_VENDOR_ID_OXSEMI, 0xc158, /* OXPCIe952 2 Native UART */ |
4444 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4430 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4445 | pbn_oxsemi_2_4000000 }, | 4431 | pbn_oxsemi_2_4000000 }, |
4446 | { PCI_VENDOR_ID_OXSEMI, 0xc15d, /* OXPCIe952 2 Native UART */ | 4432 | { PCI_VENDOR_ID_OXSEMI, 0xc15d, /* OXPCIe952 2 Native UART */ |
4447 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4433 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4448 | pbn_oxsemi_2_4000000 }, | 4434 | pbn_oxsemi_2_4000000 }, |
4449 | { PCI_VENDOR_ID_OXSEMI, 0xc208, /* OXPCIe954 4 Native UART */ | 4435 | { PCI_VENDOR_ID_OXSEMI, 0xc208, /* OXPCIe954 4 Native UART */ |
4450 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4436 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4451 | pbn_oxsemi_4_4000000 }, | 4437 | pbn_oxsemi_4_4000000 }, |
4452 | { PCI_VENDOR_ID_OXSEMI, 0xc20d, /* OXPCIe954 4 Native UART */ | 4438 | { PCI_VENDOR_ID_OXSEMI, 0xc20d, /* OXPCIe954 4 Native UART */ |
4453 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4439 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4454 | pbn_oxsemi_4_4000000 }, | 4440 | pbn_oxsemi_4_4000000 }, |
4455 | { PCI_VENDOR_ID_OXSEMI, 0xc308, /* OXPCIe958 8 Native UART */ | 4441 | { PCI_VENDOR_ID_OXSEMI, 0xc308, /* OXPCIe958 8 Native UART */ |
4456 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4442 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4457 | pbn_oxsemi_8_4000000 }, | 4443 | pbn_oxsemi_8_4000000 }, |
4458 | { PCI_VENDOR_ID_OXSEMI, 0xc30d, /* OXPCIe958 8 Native UART */ | 4444 | { PCI_VENDOR_ID_OXSEMI, 0xc30d, /* OXPCIe958 8 Native UART */ |
4459 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4445 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4460 | pbn_oxsemi_8_4000000 }, | 4446 | pbn_oxsemi_8_4000000 }, |
4461 | { PCI_VENDOR_ID_OXSEMI, 0xc40b, /* OXPCIe200 1 Native UART */ | 4447 | { PCI_VENDOR_ID_OXSEMI, 0xc40b, /* OXPCIe200 1 Native UART */ |
4462 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4448 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4463 | pbn_oxsemi_1_4000000 }, | 4449 | pbn_oxsemi_1_4000000 }, |
4464 | { PCI_VENDOR_ID_OXSEMI, 0xc40f, /* OXPCIe200 1 Native UART */ | 4450 | { PCI_VENDOR_ID_OXSEMI, 0xc40f, /* OXPCIe200 1 Native UART */ |
4465 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4451 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4466 | pbn_oxsemi_1_4000000 }, | 4452 | pbn_oxsemi_1_4000000 }, |
4467 | { PCI_VENDOR_ID_OXSEMI, 0xc41b, /* OXPCIe200 1 Native UART */ | 4453 | { PCI_VENDOR_ID_OXSEMI, 0xc41b, /* OXPCIe200 1 Native UART */ |
4468 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4454 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4469 | pbn_oxsemi_1_4000000 }, | 4455 | pbn_oxsemi_1_4000000 }, |
4470 | { PCI_VENDOR_ID_OXSEMI, 0xc41f, /* OXPCIe200 1 Native UART */ | 4456 | { PCI_VENDOR_ID_OXSEMI, 0xc41f, /* OXPCIe200 1 Native UART */ |
4471 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4457 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4472 | pbn_oxsemi_1_4000000 }, | 4458 | pbn_oxsemi_1_4000000 }, |
4473 | { PCI_VENDOR_ID_OXSEMI, 0xc42b, /* OXPCIe200 1 Native UART */ | 4459 | { PCI_VENDOR_ID_OXSEMI, 0xc42b, /* OXPCIe200 1 Native UART */ |
4474 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4460 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4475 | pbn_oxsemi_1_4000000 }, | 4461 | pbn_oxsemi_1_4000000 }, |
4476 | { PCI_VENDOR_ID_OXSEMI, 0xc42f, /* OXPCIe200 1 Native UART */ | 4462 | { PCI_VENDOR_ID_OXSEMI, 0xc42f, /* OXPCIe200 1 Native UART */ |
4477 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4463 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4478 | pbn_oxsemi_1_4000000 }, | 4464 | pbn_oxsemi_1_4000000 }, |
4479 | { PCI_VENDOR_ID_OXSEMI, 0xc43b, /* OXPCIe200 1 Native UART */ | 4465 | { PCI_VENDOR_ID_OXSEMI, 0xc43b, /* OXPCIe200 1 Native UART */ |
4480 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4466 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4481 | pbn_oxsemi_1_4000000 }, | 4467 | pbn_oxsemi_1_4000000 }, |
4482 | { PCI_VENDOR_ID_OXSEMI, 0xc43f, /* OXPCIe200 1 Native UART */ | 4468 | { PCI_VENDOR_ID_OXSEMI, 0xc43f, /* OXPCIe200 1 Native UART */ |
4483 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4469 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4484 | pbn_oxsemi_1_4000000 }, | 4470 | pbn_oxsemi_1_4000000 }, |
4485 | { PCI_VENDOR_ID_OXSEMI, 0xc44b, /* OXPCIe200 1 Native UART */ | 4471 | { PCI_VENDOR_ID_OXSEMI, 0xc44b, /* OXPCIe200 1 Native UART */ |
4486 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4472 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4487 | pbn_oxsemi_1_4000000 }, | 4473 | pbn_oxsemi_1_4000000 }, |
4488 | { PCI_VENDOR_ID_OXSEMI, 0xc44f, /* OXPCIe200 1 Native UART */ | 4474 | { PCI_VENDOR_ID_OXSEMI, 0xc44f, /* OXPCIe200 1 Native UART */ |
4489 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4475 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4490 | pbn_oxsemi_1_4000000 }, | 4476 | pbn_oxsemi_1_4000000 }, |
4491 | { PCI_VENDOR_ID_OXSEMI, 0xc45b, /* OXPCIe200 1 Native UART */ | 4477 | { PCI_VENDOR_ID_OXSEMI, 0xc45b, /* OXPCIe200 1 Native UART */ |
4492 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4478 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4493 | pbn_oxsemi_1_4000000 }, | 4479 | pbn_oxsemi_1_4000000 }, |
4494 | { PCI_VENDOR_ID_OXSEMI, 0xc45f, /* OXPCIe200 1 Native UART */ | 4480 | { PCI_VENDOR_ID_OXSEMI, 0xc45f, /* OXPCIe200 1 Native UART */ |
4495 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4481 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4496 | pbn_oxsemi_1_4000000 }, | 4482 | pbn_oxsemi_1_4000000 }, |
4497 | { PCI_VENDOR_ID_OXSEMI, 0xc46b, /* OXPCIe200 1 Native UART */ | 4483 | { PCI_VENDOR_ID_OXSEMI, 0xc46b, /* OXPCIe200 1 Native UART */ |
4498 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4484 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4499 | pbn_oxsemi_1_4000000 }, | 4485 | pbn_oxsemi_1_4000000 }, |
4500 | { PCI_VENDOR_ID_OXSEMI, 0xc46f, /* OXPCIe200 1 Native UART */ | 4486 | { PCI_VENDOR_ID_OXSEMI, 0xc46f, /* OXPCIe200 1 Native UART */ |
4501 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4487 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4502 | pbn_oxsemi_1_4000000 }, | 4488 | pbn_oxsemi_1_4000000 }, |
4503 | { PCI_VENDOR_ID_OXSEMI, 0xc47b, /* OXPCIe200 1 Native UART */ | 4489 | { PCI_VENDOR_ID_OXSEMI, 0xc47b, /* OXPCIe200 1 Native UART */ |
4504 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4490 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4505 | pbn_oxsemi_1_4000000 }, | 4491 | pbn_oxsemi_1_4000000 }, |
4506 | { PCI_VENDOR_ID_OXSEMI, 0xc47f, /* OXPCIe200 1 Native UART */ | 4492 | { PCI_VENDOR_ID_OXSEMI, 0xc47f, /* OXPCIe200 1 Native UART */ |
4507 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4493 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4508 | pbn_oxsemi_1_4000000 }, | 4494 | pbn_oxsemi_1_4000000 }, |
4509 | { PCI_VENDOR_ID_OXSEMI, 0xc48b, /* OXPCIe200 1 Native UART */ | 4495 | { PCI_VENDOR_ID_OXSEMI, 0xc48b, /* OXPCIe200 1 Native UART */ |
4510 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4496 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4511 | pbn_oxsemi_1_4000000 }, | 4497 | pbn_oxsemi_1_4000000 }, |
4512 | { PCI_VENDOR_ID_OXSEMI, 0xc48f, /* OXPCIe200 1 Native UART */ | 4498 | { PCI_VENDOR_ID_OXSEMI, 0xc48f, /* OXPCIe200 1 Native UART */ |
4513 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4499 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4514 | pbn_oxsemi_1_4000000 }, | 4500 | pbn_oxsemi_1_4000000 }, |
4515 | { PCI_VENDOR_ID_OXSEMI, 0xc49b, /* OXPCIe200 1 Native UART */ | 4501 | { PCI_VENDOR_ID_OXSEMI, 0xc49b, /* OXPCIe200 1 Native UART */ |
4516 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4502 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4517 | pbn_oxsemi_1_4000000 }, | 4503 | pbn_oxsemi_1_4000000 }, |
4518 | { PCI_VENDOR_ID_OXSEMI, 0xc49f, /* OXPCIe200 1 Native UART */ | 4504 | { PCI_VENDOR_ID_OXSEMI, 0xc49f, /* OXPCIe200 1 Native UART */ |
4519 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4505 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4520 | pbn_oxsemi_1_4000000 }, | 4506 | pbn_oxsemi_1_4000000 }, |
4521 | { PCI_VENDOR_ID_OXSEMI, 0xc4ab, /* OXPCIe200 1 Native UART */ | 4507 | { PCI_VENDOR_ID_OXSEMI, 0xc4ab, /* OXPCIe200 1 Native UART */ |
4522 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4508 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4523 | pbn_oxsemi_1_4000000 }, | 4509 | pbn_oxsemi_1_4000000 }, |
4524 | { PCI_VENDOR_ID_OXSEMI, 0xc4af, /* OXPCIe200 1 Native UART */ | 4510 | { PCI_VENDOR_ID_OXSEMI, 0xc4af, /* OXPCIe200 1 Native UART */ |
4525 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4511 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4526 | pbn_oxsemi_1_4000000 }, | 4512 | pbn_oxsemi_1_4000000 }, |
4527 | { PCI_VENDOR_ID_OXSEMI, 0xc4bb, /* OXPCIe200 1 Native UART */ | 4513 | { PCI_VENDOR_ID_OXSEMI, 0xc4bb, /* OXPCIe200 1 Native UART */ |
4528 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4514 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4529 | pbn_oxsemi_1_4000000 }, | 4515 | pbn_oxsemi_1_4000000 }, |
4530 | { PCI_VENDOR_ID_OXSEMI, 0xc4bf, /* OXPCIe200 1 Native UART */ | 4516 | { PCI_VENDOR_ID_OXSEMI, 0xc4bf, /* OXPCIe200 1 Native UART */ |
4531 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4517 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4532 | pbn_oxsemi_1_4000000 }, | 4518 | pbn_oxsemi_1_4000000 }, |
4533 | { PCI_VENDOR_ID_OXSEMI, 0xc4cb, /* OXPCIe200 1 Native UART */ | 4519 | { PCI_VENDOR_ID_OXSEMI, 0xc4cb, /* OXPCIe200 1 Native UART */ |
4534 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4520 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4535 | pbn_oxsemi_1_4000000 }, | 4521 | pbn_oxsemi_1_4000000 }, |
4536 | { PCI_VENDOR_ID_OXSEMI, 0xc4cf, /* OXPCIe200 1 Native UART */ | 4522 | { PCI_VENDOR_ID_OXSEMI, 0xc4cf, /* OXPCIe200 1 Native UART */ |
4537 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4523 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4538 | pbn_oxsemi_1_4000000 }, | 4524 | pbn_oxsemi_1_4000000 }, |
4539 | /* | 4525 | /* |
4540 | * Mainpine Inc. IQ Express "Rev3" utilizing OxSemi Tornado | 4526 | * Mainpine Inc. IQ Express "Rev3" utilizing OxSemi Tornado |
4541 | */ | 4527 | */ |
4542 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 1 Port V.34 Super-G3 Fax */ | 4528 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 1 Port V.34 Super-G3 Fax */ |
4543 | PCI_VENDOR_ID_MAINPINE, 0x4001, 0, 0, | 4529 | PCI_VENDOR_ID_MAINPINE, 0x4001, 0, 0, |
4544 | pbn_oxsemi_1_4000000 }, | 4530 | pbn_oxsemi_1_4000000 }, |
4545 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 2 Port V.34 Super-G3 Fax */ | 4531 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 2 Port V.34 Super-G3 Fax */ |
4546 | PCI_VENDOR_ID_MAINPINE, 0x4002, 0, 0, | 4532 | PCI_VENDOR_ID_MAINPINE, 0x4002, 0, 0, |
4547 | pbn_oxsemi_2_4000000 }, | 4533 | pbn_oxsemi_2_4000000 }, |
4548 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 4 Port V.34 Super-G3 Fax */ | 4534 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 4 Port V.34 Super-G3 Fax */ |
4549 | PCI_VENDOR_ID_MAINPINE, 0x4004, 0, 0, | 4535 | PCI_VENDOR_ID_MAINPINE, 0x4004, 0, 0, |
4550 | pbn_oxsemi_4_4000000 }, | 4536 | pbn_oxsemi_4_4000000 }, |
4551 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */ | 4537 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */ |
4552 | PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0, | 4538 | PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0, |
4553 | pbn_oxsemi_8_4000000 }, | 4539 | pbn_oxsemi_8_4000000 }, |
4554 | 4540 | ||
4555 | /* | 4541 | /* |
4556 | * Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado | 4542 | * Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado |
4557 | */ | 4543 | */ |
4558 | { PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM, | 4544 | { PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM, |
4559 | PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0, | 4545 | PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0, |
4560 | pbn_oxsemi_2_4000000 }, | 4546 | pbn_oxsemi_2_4000000 }, |
4561 | 4547 | ||
4562 | /* | 4548 | /* |
4563 | * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards, | 4549 | * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards, |
4564 | * from skokodyn@yahoo.com | 4550 | * from skokodyn@yahoo.com |
4565 | */ | 4551 | */ |
4566 | { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO, | 4552 | { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO, |
4567 | PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO232, 0, 0, | 4553 | PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO232, 0, 0, |
4568 | pbn_sbsxrsio }, | 4554 | pbn_sbsxrsio }, |
4569 | { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO, | 4555 | { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO, |
4570 | PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO422, 0, 0, | 4556 | PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO422, 0, 0, |
4571 | pbn_sbsxrsio }, | 4557 | pbn_sbsxrsio }, |
4572 | { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO, | 4558 | { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO, |
4573 | PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL232, 0, 0, | 4559 | PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL232, 0, 0, |
4574 | pbn_sbsxrsio }, | 4560 | pbn_sbsxrsio }, |
4575 | { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO, | 4561 | { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO, |
4576 | PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL422, 0, 0, | 4562 | PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL422, 0, 0, |
4577 | pbn_sbsxrsio }, | 4563 | pbn_sbsxrsio }, |
4578 | 4564 | ||
4579 | /* | 4565 | /* |
4580 | * Digitan DS560-558, from jimd@esoft.com | 4566 | * Digitan DS560-558, from jimd@esoft.com |
4581 | */ | 4567 | */ |
4582 | { PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM, | 4568 | { PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM, |
4583 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4569 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4584 | pbn_b1_1_115200 }, | 4570 | pbn_b1_1_115200 }, |
4585 | 4571 | ||
4586 | /* | 4572 | /* |
4587 | * Titan Electronic cards | 4573 | * Titan Electronic cards |
4588 | * The 400L and 800L have a custom setup quirk. | 4574 | * The 400L and 800L have a custom setup quirk. |
4589 | */ | 4575 | */ |
4590 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100, | 4576 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100, |
4591 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4577 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4592 | pbn_b0_1_921600 }, | 4578 | pbn_b0_1_921600 }, |
4593 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200, | 4579 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200, |
4594 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4580 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4595 | pbn_b0_2_921600 }, | 4581 | pbn_b0_2_921600 }, |
4596 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400, | 4582 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400, |
4597 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4583 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4598 | pbn_b0_4_921600 }, | 4584 | pbn_b0_4_921600 }, |
4599 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B, | 4585 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B, |
4600 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4586 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4601 | pbn_b0_4_921600 }, | 4587 | pbn_b0_4_921600 }, |
4602 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L, | 4588 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L, |
4603 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4589 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4604 | pbn_b1_1_921600 }, | 4590 | pbn_b1_1_921600 }, |
4605 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L, | 4591 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L, |
4606 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4592 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4607 | pbn_b1_bt_2_921600 }, | 4593 | pbn_b1_bt_2_921600 }, |
4608 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L, | 4594 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L, |
4609 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4595 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4610 | pbn_b0_bt_4_921600 }, | 4596 | pbn_b0_bt_4_921600 }, |
4611 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L, | 4597 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L, |
4612 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4598 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4613 | pbn_b0_bt_8_921600 }, | 4599 | pbn_b0_bt_8_921600 }, |
4614 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200I, | 4600 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200I, |
4615 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4601 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4616 | pbn_b4_bt_2_921600 }, | 4602 | pbn_b4_bt_2_921600 }, |
4617 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400I, | 4603 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400I, |
4618 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4604 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4619 | pbn_b4_bt_4_921600 }, | 4605 | pbn_b4_bt_4_921600 }, |
4620 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800I, | 4606 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800I, |
4621 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4607 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4622 | pbn_b4_bt_8_921600 }, | 4608 | pbn_b4_bt_8_921600 }, |
4623 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400EH, | 4609 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400EH, |
4624 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4610 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4625 | pbn_b0_4_921600 }, | 4611 | pbn_b0_4_921600 }, |
4626 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EH, | 4612 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EH, |
4627 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4613 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4628 | pbn_b0_4_921600 }, | 4614 | pbn_b0_4_921600 }, |
4629 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EHB, | 4615 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EHB, |
4630 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4616 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4631 | pbn_b0_4_921600 }, | 4617 | pbn_b0_4_921600 }, |
4632 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100E, | 4618 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100E, |
4633 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4619 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4634 | pbn_oxsemi_1_4000000 }, | 4620 | pbn_oxsemi_1_4000000 }, |
4635 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200E, | 4621 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200E, |
4636 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4622 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4637 | pbn_oxsemi_2_4000000 }, | 4623 | pbn_oxsemi_2_4000000 }, |
4638 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400E, | 4624 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400E, |
4639 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4625 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4640 | pbn_oxsemi_4_4000000 }, | 4626 | pbn_oxsemi_4_4000000 }, |
4641 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800E, | 4627 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800E, |
4642 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4628 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4643 | pbn_oxsemi_8_4000000 }, | 4629 | pbn_oxsemi_8_4000000 }, |
4644 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EI, | 4630 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EI, |
4645 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4631 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4646 | pbn_oxsemi_2_4000000 }, | 4632 | pbn_oxsemi_2_4000000 }, |
4647 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, | 4633 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, |
4648 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4634 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4649 | pbn_oxsemi_2_4000000 }, | 4635 | pbn_oxsemi_2_4000000 }, |
4650 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200V3, | 4636 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200V3, |
4651 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4637 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4652 | pbn_b0_bt_2_921600 }, | 4638 | pbn_b0_bt_2_921600 }, |
4653 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3, | 4639 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3, |
4654 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4640 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4655 | pbn_b0_4_921600 }, | 4641 | pbn_b0_4_921600 }, |
4656 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_410V3, | 4642 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_410V3, |
4657 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4643 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4658 | pbn_b0_4_921600 }, | 4644 | pbn_b0_4_921600 }, |
4659 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3, | 4645 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3, |
4660 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4646 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4661 | pbn_b0_4_921600 }, | 4647 | pbn_b0_4_921600 }, |
4662 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3B, | 4648 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3B, |
4663 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4649 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4664 | pbn_b0_4_921600 }, | 4650 | pbn_b0_4_921600 }, |
4665 | 4651 | ||
4666 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, | 4652 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, |
4667 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4653 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4668 | pbn_b2_1_460800 }, | 4654 | pbn_b2_1_460800 }, |
4669 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650, | 4655 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650, |
4670 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4656 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4671 | pbn_b2_1_460800 }, | 4657 | pbn_b2_1_460800 }, |
4672 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850, | 4658 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850, |
4673 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4659 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4674 | pbn_b2_1_460800 }, | 4660 | pbn_b2_1_460800 }, |
4675 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550, | 4661 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550, |
4676 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4662 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4677 | pbn_b2_bt_2_921600 }, | 4663 | pbn_b2_bt_2_921600 }, |
4678 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650, | 4664 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650, |
4679 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4665 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4680 | pbn_b2_bt_2_921600 }, | 4666 | pbn_b2_bt_2_921600 }, |
4681 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850, | 4667 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850, |
4682 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4668 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4683 | pbn_b2_bt_2_921600 }, | 4669 | pbn_b2_bt_2_921600 }, |
4684 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550, | 4670 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550, |
4685 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4671 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4686 | pbn_b2_bt_4_921600 }, | 4672 | pbn_b2_bt_4_921600 }, |
4687 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650, | 4673 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650, |
4688 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4674 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4689 | pbn_b2_bt_4_921600 }, | 4675 | pbn_b2_bt_4_921600 }, |
4690 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850, | 4676 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850, |
4691 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4677 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4692 | pbn_b2_bt_4_921600 }, | 4678 | pbn_b2_bt_4_921600 }, |
4693 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550, | 4679 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550, |
4694 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4680 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4695 | pbn_b0_1_921600 }, | 4681 | pbn_b0_1_921600 }, |
4696 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650, | 4682 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650, |
4697 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4683 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4698 | pbn_b0_1_921600 }, | 4684 | pbn_b0_1_921600 }, |
4699 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850, | 4685 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850, |
4700 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4686 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4701 | pbn_b0_1_921600 }, | 4687 | pbn_b0_1_921600 }, |
4702 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550, | 4688 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550, |
4703 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4689 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4704 | pbn_b0_bt_2_921600 }, | 4690 | pbn_b0_bt_2_921600 }, |
4705 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650, | 4691 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650, |
4706 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4692 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4707 | pbn_b0_bt_2_921600 }, | 4693 | pbn_b0_bt_2_921600 }, |
4708 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850, | 4694 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850, |
4709 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4695 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4710 | pbn_b0_bt_2_921600 }, | 4696 | pbn_b0_bt_2_921600 }, |
4711 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550, | 4697 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550, |
4712 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4698 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4713 | pbn_b0_bt_4_921600 }, | 4699 | pbn_b0_bt_4_921600 }, |
4714 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650, | 4700 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650, |
4715 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4701 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4716 | pbn_b0_bt_4_921600 }, | 4702 | pbn_b0_bt_4_921600 }, |
4717 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850, | 4703 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850, |
4718 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4704 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4719 | pbn_b0_bt_4_921600 }, | 4705 | pbn_b0_bt_4_921600 }, |
4720 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_550, | 4706 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_550, |
4721 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4707 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4722 | pbn_b0_bt_8_921600 }, | 4708 | pbn_b0_bt_8_921600 }, |
4723 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_650, | 4709 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_650, |
4724 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4710 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4725 | pbn_b0_bt_8_921600 }, | 4711 | pbn_b0_bt_8_921600 }, |
4726 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_850, | 4712 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_850, |
4727 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4713 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4728 | pbn_b0_bt_8_921600 }, | 4714 | pbn_b0_bt_8_921600 }, |
4729 | 4715 | ||
4730 | /* | 4716 | /* |
4731 | * Computone devices submitted by Doug McNash dmcnash@computone.com | 4717 | * Computone devices submitted by Doug McNash dmcnash@computone.com |
4732 | */ | 4718 | */ |
4733 | { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, | 4719 | { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, |
4734 | PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4, | 4720 | PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4, |
4735 | 0, 0, pbn_computone_4 }, | 4721 | 0, 0, pbn_computone_4 }, |
4736 | { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, | 4722 | { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, |
4737 | PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8, | 4723 | PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8, |
4738 | 0, 0, pbn_computone_8 }, | 4724 | 0, 0, pbn_computone_8 }, |
4739 | { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, | 4725 | { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, |
4740 | PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6, | 4726 | PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6, |
4741 | 0, 0, pbn_computone_6 }, | 4727 | 0, 0, pbn_computone_6 }, |
4742 | 4728 | ||
4743 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N, | 4729 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N, |
4744 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4730 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4745 | pbn_oxsemi }, | 4731 | pbn_oxsemi }, |
4746 | { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889, | 4732 | { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889, |
4747 | PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0, | 4733 | PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0, |
4748 | pbn_b0_bt_1_921600 }, | 4734 | pbn_b0_bt_1_921600 }, |
4749 | 4735 | ||
4750 | /* | 4736 | /* |
4751 | * SUNIX (TIMEDIA) | 4737 | * SUNIX (TIMEDIA) |
4752 | */ | 4738 | */ |
4753 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, | 4739 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, |
4754 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, | 4740 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, |
4755 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, | 4741 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, |
4756 | pbn_b0_bt_1_921600 }, | 4742 | pbn_b0_bt_1_921600 }, |
4757 | 4743 | ||
4758 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, | 4744 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, |
4759 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, | 4745 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, |
4760 | PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, | 4746 | PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, |
4761 | pbn_b0_bt_1_921600 }, | 4747 | pbn_b0_bt_1_921600 }, |
4762 | 4748 | ||
4763 | /* | 4749 | /* |
4764 | * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> | 4750 | * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> |
4765 | */ | 4751 | */ |
4766 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, | 4752 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, |
4767 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4753 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4768 | pbn_b0_bt_8_115200 }, | 4754 | pbn_b0_bt_8_115200 }, |
4769 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P030, | 4755 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P030, |
4770 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4756 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4771 | pbn_b0_bt_8_115200 }, | 4757 | pbn_b0_bt_8_115200 }, |
4772 | 4758 | ||
4773 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL, | 4759 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL, |
4774 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4760 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4775 | pbn_b0_bt_2_115200 }, | 4761 | pbn_b0_bt_2_115200 }, |
4776 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A, | 4762 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A, |
4777 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4763 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4778 | pbn_b0_bt_2_115200 }, | 4764 | pbn_b0_bt_2_115200 }, |
4779 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B, | 4765 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B, |
4780 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4766 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4781 | pbn_b0_bt_2_115200 }, | 4767 | pbn_b0_bt_2_115200 }, |
4782 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_A, | 4768 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_A, |
4783 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4769 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4784 | pbn_b0_bt_2_115200 }, | 4770 | pbn_b0_bt_2_115200 }, |
4785 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_B, | 4771 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_B, |
4786 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4772 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4787 | pbn_b0_bt_2_115200 }, | 4773 | pbn_b0_bt_2_115200 }, |
4788 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A, | 4774 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A, |
4789 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4775 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4790 | pbn_b0_bt_4_460800 }, | 4776 | pbn_b0_bt_4_460800 }, |
4791 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_B, | 4777 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_B, |
4792 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4778 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4793 | pbn_b0_bt_4_460800 }, | 4779 | pbn_b0_bt_4_460800 }, |
4794 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS, | 4780 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS, |
4795 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4781 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4796 | pbn_b0_bt_2_460800 }, | 4782 | pbn_b0_bt_2_460800 }, |
4797 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A, | 4783 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A, |
4798 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4784 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4799 | pbn_b0_bt_2_460800 }, | 4785 | pbn_b0_bt_2_460800 }, |
4800 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B, | 4786 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B, |
4801 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4787 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4802 | pbn_b0_bt_2_460800 }, | 4788 | pbn_b0_bt_2_460800 }, |
4803 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL, | 4789 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL, |
4804 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4790 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4805 | pbn_b0_bt_1_115200 }, | 4791 | pbn_b0_bt_1_115200 }, |
4806 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650, | 4792 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650, |
4807 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4793 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4808 | pbn_b0_bt_1_460800 }, | 4794 | pbn_b0_bt_1_460800 }, |
4809 | 4795 | ||
4810 | /* | 4796 | /* |
4811 | * Korenix Jetcard F0/F1 cards (JC1204, JC1208, JC1404, JC1408). | 4797 | * Korenix Jetcard F0/F1 cards (JC1204, JC1208, JC1404, JC1408). |
4812 | * Cards are identified by their subsystem vendor IDs, which | 4798 | * Cards are identified by their subsystem vendor IDs, which |
4813 | * (in hex) match the model number. | 4799 | * (in hex) match the model number. |
4814 | * | 4800 | * |
4815 | * Note that JC140x are RS422/485 cards which require ox950 | 4801 | * Note that JC140x are RS422/485 cards which require ox950 |
4816 | * ACR = 0x10, and as such are not currently fully supported. | 4802 | * ACR = 0x10, and as such are not currently fully supported. |
4817 | */ | 4803 | */ |
4818 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0, | 4804 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0, |
4819 | 0x1204, 0x0004, 0, 0, | 4805 | 0x1204, 0x0004, 0, 0, |
4820 | pbn_b0_4_921600 }, | 4806 | pbn_b0_4_921600 }, |
4821 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0, | 4807 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0, |
4822 | 0x1208, 0x0004, 0, 0, | 4808 | 0x1208, 0x0004, 0, 0, |
4823 | pbn_b0_4_921600 }, | 4809 | pbn_b0_4_921600 }, |
4824 | /* { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0, | 4810 | /* { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0, |
4825 | 0x1402, 0x0002, 0, 0, | 4811 | 0x1402, 0x0002, 0, 0, |
4826 | pbn_b0_2_921600 }, */ | 4812 | pbn_b0_2_921600 }, */ |
4827 | /* { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0, | 4813 | /* { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0, |
4828 | 0x1404, 0x0004, 0, 0, | 4814 | 0x1404, 0x0004, 0, 0, |
4829 | pbn_b0_4_921600 }, */ | 4815 | pbn_b0_4_921600 }, */ |
4830 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF1, | 4816 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF1, |
4831 | 0x1208, 0x0004, 0, 0, | 4817 | 0x1208, 0x0004, 0, 0, |
4832 | pbn_b0_4_921600 }, | 4818 | pbn_b0_4_921600 }, |
4833 | 4819 | ||
4834 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, | 4820 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, |
4835 | 0x1204, 0x0004, 0, 0, | 4821 | 0x1204, 0x0004, 0, 0, |
4836 | pbn_b0_4_921600 }, | 4822 | pbn_b0_4_921600 }, |
4837 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, | 4823 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, |
4838 | 0x1208, 0x0004, 0, 0, | 4824 | 0x1208, 0x0004, 0, 0, |
4839 | pbn_b0_4_921600 }, | 4825 | pbn_b0_4_921600 }, |
4840 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF3, | 4826 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF3, |
4841 | 0x1208, 0x0004, 0, 0, | 4827 | 0x1208, 0x0004, 0, 0, |
4842 | pbn_b0_4_921600 }, | 4828 | pbn_b0_4_921600 }, |
4843 | /* | 4829 | /* |
4844 | * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com | 4830 | * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com |
4845 | */ | 4831 | */ |
4846 | { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RAC4, | 4832 | { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RAC4, |
4847 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4833 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4848 | pbn_b1_1_1382400 }, | 4834 | pbn_b1_1_1382400 }, |
4849 | 4835 | ||
4850 | /* | 4836 | /* |
4851 | * Dell Remote Access Card III - Tim_T_Murphy@Dell.com | 4837 | * Dell Remote Access Card III - Tim_T_Murphy@Dell.com |
4852 | */ | 4838 | */ |
4853 | { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RACIII, | 4839 | { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RACIII, |
4854 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4840 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4855 | pbn_b1_1_1382400 }, | 4841 | pbn_b1_1_1382400 }, |
4856 | 4842 | ||
4857 | /* | 4843 | /* |
4858 | * RAStel 2 port modem, gerg@moreton.com.au | 4844 | * RAStel 2 port modem, gerg@moreton.com.au |
4859 | */ | 4845 | */ |
4860 | { PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT, | 4846 | { PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT, |
4861 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4847 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4862 | pbn_b2_bt_2_115200 }, | 4848 | pbn_b2_bt_2_115200 }, |
4863 | 4849 | ||
4864 | /* | 4850 | /* |
4865 | * EKF addition for i960 Boards form EKF with serial port | 4851 | * EKF addition for i960 Boards form EKF with serial port |
4866 | */ | 4852 | */ |
4867 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80960_RP, | 4853 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80960_RP, |
4868 | 0xE4BF, PCI_ANY_ID, 0, 0, | 4854 | 0xE4BF, PCI_ANY_ID, 0, 0, |
4869 | pbn_intel_i960 }, | 4855 | pbn_intel_i960 }, |
4870 | 4856 | ||
4871 | /* | 4857 | /* |
4872 | * Xircom Cardbus/Ethernet combos | 4858 | * Xircom Cardbus/Ethernet combos |
4873 | */ | 4859 | */ |
4874 | { PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM, | 4860 | { PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM, |
4875 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4861 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4876 | pbn_b0_1_115200 }, | 4862 | pbn_b0_1_115200 }, |
4877 | /* | 4863 | /* |
4878 | * Xircom RBM56G cardbus modem - Dirk Arnold (temp entry) | 4864 | * Xircom RBM56G cardbus modem - Dirk Arnold (temp entry) |
4879 | */ | 4865 | */ |
4880 | { PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_RBM56G, | 4866 | { PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_RBM56G, |
4881 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4867 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4882 | pbn_b0_1_115200 }, | 4868 | pbn_b0_1_115200 }, |
4883 | 4869 | ||
4884 | /* | 4870 | /* |
4885 | * Untested PCI modems, sent in from various folks... | 4871 | * Untested PCI modems, sent in from various folks... |
4886 | */ | 4872 | */ |
4887 | 4873 | ||
4888 | /* | 4874 | /* |
4889 | * Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de> | 4875 | * Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de> |
4890 | */ | 4876 | */ |
4891 | { PCI_VENDOR_ID_ROCKWELL, 0x1004, | 4877 | { PCI_VENDOR_ID_ROCKWELL, 0x1004, |
4892 | 0x1048, 0x1500, 0, 0, | 4878 | 0x1048, 0x1500, 0, 0, |
4893 | pbn_b1_1_115200 }, | 4879 | pbn_b1_1_115200 }, |
4894 | 4880 | ||
4895 | { PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, | 4881 | { PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, |
4896 | 0xFF00, 0, 0, 0, | 4882 | 0xFF00, 0, 0, 0, |
4897 | pbn_sgi_ioc3 }, | 4883 | pbn_sgi_ioc3 }, |
4898 | 4884 | ||
4899 | /* | 4885 | /* |
4900 | * HP Diva card | 4886 | * HP Diva card |
4901 | */ | 4887 | */ |
4902 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA, | 4888 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA, |
4903 | PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_RMP3, 0, 0, | 4889 | PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_RMP3, 0, 0, |
4904 | pbn_b1_1_115200 }, | 4890 | pbn_b1_1_115200 }, |
4905 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA, | 4891 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA, |
4906 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4892 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4907 | pbn_b0_5_115200 }, | 4893 | pbn_b0_5_115200 }, |
4908 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX, | 4894 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX, |
4909 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4895 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4910 | pbn_b2_1_115200 }, | 4896 | pbn_b2_1_115200 }, |
4911 | 4897 | ||
4912 | { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM2, | 4898 | { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM2, |
4913 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4899 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4914 | pbn_b3_2_115200 }, | 4900 | pbn_b3_2_115200 }, |
4915 | { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM4, | 4901 | { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM4, |
4916 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4902 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4917 | pbn_b3_4_115200 }, | 4903 | pbn_b3_4_115200 }, |
4918 | { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8, | 4904 | { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8, |
4919 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4905 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4920 | pbn_b3_8_115200 }, | 4906 | pbn_b3_8_115200 }, |
4921 | 4907 | ||
4922 | /* | 4908 | /* |
4923 | * Exar Corp. XR17C15[248] Dual/Quad/Octal UART | 4909 | * Exar Corp. XR17C15[248] Dual/Quad/Octal UART |
4924 | */ | 4910 | */ |
4925 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | 4911 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, |
4926 | PCI_ANY_ID, PCI_ANY_ID, | 4912 | PCI_ANY_ID, PCI_ANY_ID, |
4927 | 0, | 4913 | 0, |
4928 | 0, pbn_exar_XR17C152 }, | 4914 | 0, pbn_exar_XR17C152 }, |
4929 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, | 4915 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, |
4930 | PCI_ANY_ID, PCI_ANY_ID, | 4916 | PCI_ANY_ID, PCI_ANY_ID, |
4931 | 0, | 4917 | 0, |
4932 | 0, pbn_exar_XR17C154 }, | 4918 | 0, pbn_exar_XR17C154 }, |
4933 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, | 4919 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, |
4934 | PCI_ANY_ID, PCI_ANY_ID, | 4920 | PCI_ANY_ID, PCI_ANY_ID, |
4935 | 0, | 4921 | 0, |
4936 | 0, pbn_exar_XR17C158 }, | 4922 | 0, pbn_exar_XR17C158 }, |
4937 | /* | 4923 | /* |
4938 | * Exar Corp. XR17V35[248] Dual/Quad/Octal PCIe UARTs | 4924 | * Exar Corp. XR17V35[248] Dual/Quad/Octal PCIe UARTs |
4939 | */ | 4925 | */ |
4940 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V352, | 4926 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V352, |
4941 | PCI_ANY_ID, PCI_ANY_ID, | 4927 | PCI_ANY_ID, PCI_ANY_ID, |
4942 | 0, | 4928 | 0, |
4943 | 0, pbn_exar_XR17V352 }, | 4929 | 0, pbn_exar_XR17V352 }, |
4944 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V354, | 4930 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V354, |
4945 | PCI_ANY_ID, PCI_ANY_ID, | 4931 | PCI_ANY_ID, PCI_ANY_ID, |
4946 | 0, | 4932 | 0, |
4947 | 0, pbn_exar_XR17V354 }, | 4933 | 0, pbn_exar_XR17V354 }, |
4948 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V358, | 4934 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V358, |
4949 | PCI_ANY_ID, PCI_ANY_ID, | 4935 | PCI_ANY_ID, PCI_ANY_ID, |
4950 | 0, | 4936 | 0, |
4951 | 0, pbn_exar_XR17V358 }, | 4937 | 0, pbn_exar_XR17V358 }, |
4952 | 4938 | ||
4953 | /* | 4939 | /* |
4954 | * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke) | 4940 | * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke) |
4955 | */ | 4941 | */ |
4956 | { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, | 4942 | { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, |
4957 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4943 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4958 | pbn_b0_1_115200 }, | 4944 | pbn_b0_1_115200 }, |
4959 | /* | 4945 | /* |
4960 | * ITE | 4946 | * ITE |
4961 | */ | 4947 | */ |
4962 | { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872, | 4948 | { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872, |
4963 | PCI_ANY_ID, PCI_ANY_ID, | 4949 | PCI_ANY_ID, PCI_ANY_ID, |
4964 | 0, 0, | 4950 | 0, 0, |
4965 | pbn_b1_bt_1_115200 }, | 4951 | pbn_b1_bt_1_115200 }, |
4966 | 4952 | ||
4967 | /* | 4953 | /* |
4968 | * IntaShield IS-200 | 4954 | * IntaShield IS-200 |
4969 | */ | 4955 | */ |
4970 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, | 4956 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, |
4971 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ | 4957 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ |
4972 | pbn_b2_2_115200 }, | 4958 | pbn_b2_2_115200 }, |
4973 | /* | 4959 | /* |
4974 | * IntaShield IS-400 | 4960 | * IntaShield IS-400 |
4975 | */ | 4961 | */ |
4976 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, | 4962 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, |
4977 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ | 4963 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ |
4978 | pbn_b2_4_115200 }, | 4964 | pbn_b2_4_115200 }, |
4979 | /* | 4965 | /* |
4980 | * Perle PCI-RAS cards | 4966 | * Perle PCI-RAS cards |
4981 | */ | 4967 | */ |
4982 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, | 4968 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, |
4983 | PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS4, | 4969 | PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS4, |
4984 | 0, 0, pbn_b2_4_921600 }, | 4970 | 0, 0, pbn_b2_4_921600 }, |
4985 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, | 4971 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, |
4986 | PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, | 4972 | PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, |
4987 | 0, 0, pbn_b2_8_921600 }, | 4973 | 0, 0, pbn_b2_8_921600 }, |
4988 | 4974 | ||
4989 | /* | 4975 | /* |
4990 | * Mainpine series cards: Fairly standard layout but fools | 4976 | * Mainpine series cards: Fairly standard layout but fools |
4991 | * parts of the autodetect in some cases and uses otherwise | 4977 | * parts of the autodetect in some cases and uses otherwise |
4992 | * unmatched communications subclasses in the PCI Express case | 4978 | * unmatched communications subclasses in the PCI Express case |
4993 | */ | 4979 | */ |
4994 | 4980 | ||
4995 | { /* RockForceDUO */ | 4981 | { /* RockForceDUO */ |
4996 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 4982 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
4997 | PCI_VENDOR_ID_MAINPINE, 0x0200, | 4983 | PCI_VENDOR_ID_MAINPINE, 0x0200, |
4998 | 0, 0, pbn_b0_2_115200 }, | 4984 | 0, 0, pbn_b0_2_115200 }, |
4999 | { /* RockForceQUATRO */ | 4985 | { /* RockForceQUATRO */ |
5000 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 4986 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5001 | PCI_VENDOR_ID_MAINPINE, 0x0300, | 4987 | PCI_VENDOR_ID_MAINPINE, 0x0300, |
5002 | 0, 0, pbn_b0_4_115200 }, | 4988 | 0, 0, pbn_b0_4_115200 }, |
5003 | { /* RockForceDUO+ */ | 4989 | { /* RockForceDUO+ */ |
5004 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 4990 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5005 | PCI_VENDOR_ID_MAINPINE, 0x0400, | 4991 | PCI_VENDOR_ID_MAINPINE, 0x0400, |
5006 | 0, 0, pbn_b0_2_115200 }, | 4992 | 0, 0, pbn_b0_2_115200 }, |
5007 | { /* RockForceQUATRO+ */ | 4993 | { /* RockForceQUATRO+ */ |
5008 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 4994 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5009 | PCI_VENDOR_ID_MAINPINE, 0x0500, | 4995 | PCI_VENDOR_ID_MAINPINE, 0x0500, |
5010 | 0, 0, pbn_b0_4_115200 }, | 4996 | 0, 0, pbn_b0_4_115200 }, |
5011 | { /* RockForce+ */ | 4997 | { /* RockForce+ */ |
5012 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 4998 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5013 | PCI_VENDOR_ID_MAINPINE, 0x0600, | 4999 | PCI_VENDOR_ID_MAINPINE, 0x0600, |
5014 | 0, 0, pbn_b0_2_115200 }, | 5000 | 0, 0, pbn_b0_2_115200 }, |
5015 | { /* RockForce+ */ | 5001 | { /* RockForce+ */ |
5016 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5002 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5017 | PCI_VENDOR_ID_MAINPINE, 0x0700, | 5003 | PCI_VENDOR_ID_MAINPINE, 0x0700, |
5018 | 0, 0, pbn_b0_4_115200 }, | 5004 | 0, 0, pbn_b0_4_115200 }, |
5019 | { /* RockForceOCTO+ */ | 5005 | { /* RockForceOCTO+ */ |
5020 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5006 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5021 | PCI_VENDOR_ID_MAINPINE, 0x0800, | 5007 | PCI_VENDOR_ID_MAINPINE, 0x0800, |
5022 | 0, 0, pbn_b0_8_115200 }, | 5008 | 0, 0, pbn_b0_8_115200 }, |
5023 | { /* RockForceDUO+ */ | 5009 | { /* RockForceDUO+ */ |
5024 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5010 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5025 | PCI_VENDOR_ID_MAINPINE, 0x0C00, | 5011 | PCI_VENDOR_ID_MAINPINE, 0x0C00, |
5026 | 0, 0, pbn_b0_2_115200 }, | 5012 | 0, 0, pbn_b0_2_115200 }, |
5027 | { /* RockForceQUARTRO+ */ | 5013 | { /* RockForceQUARTRO+ */ |
5028 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5014 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5029 | PCI_VENDOR_ID_MAINPINE, 0x0D00, | 5015 | PCI_VENDOR_ID_MAINPINE, 0x0D00, |
5030 | 0, 0, pbn_b0_4_115200 }, | 5016 | 0, 0, pbn_b0_4_115200 }, |
5031 | { /* RockForceOCTO+ */ | 5017 | { /* RockForceOCTO+ */ |
5032 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5018 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5033 | PCI_VENDOR_ID_MAINPINE, 0x1D00, | 5019 | PCI_VENDOR_ID_MAINPINE, 0x1D00, |
5034 | 0, 0, pbn_b0_8_115200 }, | 5020 | 0, 0, pbn_b0_8_115200 }, |
5035 | { /* RockForceD1 */ | 5021 | { /* RockForceD1 */ |
5036 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5022 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5037 | PCI_VENDOR_ID_MAINPINE, 0x2000, | 5023 | PCI_VENDOR_ID_MAINPINE, 0x2000, |
5038 | 0, 0, pbn_b0_1_115200 }, | 5024 | 0, 0, pbn_b0_1_115200 }, |
5039 | { /* RockForceF1 */ | 5025 | { /* RockForceF1 */ |
5040 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5026 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5041 | PCI_VENDOR_ID_MAINPINE, 0x2100, | 5027 | PCI_VENDOR_ID_MAINPINE, 0x2100, |
5042 | 0, 0, pbn_b0_1_115200 }, | 5028 | 0, 0, pbn_b0_1_115200 }, |
5043 | { /* RockForceD2 */ | 5029 | { /* RockForceD2 */ |
5044 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5030 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5045 | PCI_VENDOR_ID_MAINPINE, 0x2200, | 5031 | PCI_VENDOR_ID_MAINPINE, 0x2200, |
5046 | 0, 0, pbn_b0_2_115200 }, | 5032 | 0, 0, pbn_b0_2_115200 }, |
5047 | { /* RockForceF2 */ | 5033 | { /* RockForceF2 */ |
5048 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5034 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5049 | PCI_VENDOR_ID_MAINPINE, 0x2300, | 5035 | PCI_VENDOR_ID_MAINPINE, 0x2300, |
5050 | 0, 0, pbn_b0_2_115200 }, | 5036 | 0, 0, pbn_b0_2_115200 }, |
5051 | { /* RockForceD4 */ | 5037 | { /* RockForceD4 */ |
5052 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5038 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5053 | PCI_VENDOR_ID_MAINPINE, 0x2400, | 5039 | PCI_VENDOR_ID_MAINPINE, 0x2400, |
5054 | 0, 0, pbn_b0_4_115200 }, | 5040 | 0, 0, pbn_b0_4_115200 }, |
5055 | { /* RockForceF4 */ | 5041 | { /* RockForceF4 */ |
5056 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5042 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5057 | PCI_VENDOR_ID_MAINPINE, 0x2500, | 5043 | PCI_VENDOR_ID_MAINPINE, 0x2500, |
5058 | 0, 0, pbn_b0_4_115200 }, | 5044 | 0, 0, pbn_b0_4_115200 }, |
5059 | { /* RockForceD8 */ | 5045 | { /* RockForceD8 */ |
5060 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5046 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5061 | PCI_VENDOR_ID_MAINPINE, 0x2600, | 5047 | PCI_VENDOR_ID_MAINPINE, 0x2600, |
5062 | 0, 0, pbn_b0_8_115200 }, | 5048 | 0, 0, pbn_b0_8_115200 }, |
5063 | { /* RockForceF8 */ | 5049 | { /* RockForceF8 */ |
5064 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5050 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5065 | PCI_VENDOR_ID_MAINPINE, 0x2700, | 5051 | PCI_VENDOR_ID_MAINPINE, 0x2700, |
5066 | 0, 0, pbn_b0_8_115200 }, | 5052 | 0, 0, pbn_b0_8_115200 }, |
5067 | { /* IQ Express D1 */ | 5053 | { /* IQ Express D1 */ |
5068 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5054 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5069 | PCI_VENDOR_ID_MAINPINE, 0x3000, | 5055 | PCI_VENDOR_ID_MAINPINE, 0x3000, |
5070 | 0, 0, pbn_b0_1_115200 }, | 5056 | 0, 0, pbn_b0_1_115200 }, |
5071 | { /* IQ Express F1 */ | 5057 | { /* IQ Express F1 */ |
5072 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5058 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5073 | PCI_VENDOR_ID_MAINPINE, 0x3100, | 5059 | PCI_VENDOR_ID_MAINPINE, 0x3100, |
5074 | 0, 0, pbn_b0_1_115200 }, | 5060 | 0, 0, pbn_b0_1_115200 }, |
5075 | { /* IQ Express D2 */ | 5061 | { /* IQ Express D2 */ |
5076 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5062 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5077 | PCI_VENDOR_ID_MAINPINE, 0x3200, | 5063 | PCI_VENDOR_ID_MAINPINE, 0x3200, |
5078 | 0, 0, pbn_b0_2_115200 }, | 5064 | 0, 0, pbn_b0_2_115200 }, |
5079 | { /* IQ Express F2 */ | 5065 | { /* IQ Express F2 */ |
5080 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5066 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5081 | PCI_VENDOR_ID_MAINPINE, 0x3300, | 5067 | PCI_VENDOR_ID_MAINPINE, 0x3300, |
5082 | 0, 0, pbn_b0_2_115200 }, | 5068 | 0, 0, pbn_b0_2_115200 }, |
5083 | { /* IQ Express D4 */ | 5069 | { /* IQ Express D4 */ |
5084 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5070 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5085 | PCI_VENDOR_ID_MAINPINE, 0x3400, | 5071 | PCI_VENDOR_ID_MAINPINE, 0x3400, |
5086 | 0, 0, pbn_b0_4_115200 }, | 5072 | 0, 0, pbn_b0_4_115200 }, |
5087 | { /* IQ Express F4 */ | 5073 | { /* IQ Express F4 */ |
5088 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5074 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5089 | PCI_VENDOR_ID_MAINPINE, 0x3500, | 5075 | PCI_VENDOR_ID_MAINPINE, 0x3500, |
5090 | 0, 0, pbn_b0_4_115200 }, | 5076 | 0, 0, pbn_b0_4_115200 }, |
5091 | { /* IQ Express D8 */ | 5077 | { /* IQ Express D8 */ |
5092 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5078 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5093 | PCI_VENDOR_ID_MAINPINE, 0x3C00, | 5079 | PCI_VENDOR_ID_MAINPINE, 0x3C00, |
5094 | 0, 0, pbn_b0_8_115200 }, | 5080 | 0, 0, pbn_b0_8_115200 }, |
5095 | { /* IQ Express F8 */ | 5081 | { /* IQ Express F8 */ |
5096 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, | 5082 | PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, |
5097 | PCI_VENDOR_ID_MAINPINE, 0x3D00, | 5083 | PCI_VENDOR_ID_MAINPINE, 0x3D00, |
5098 | 0, 0, pbn_b0_8_115200 }, | 5084 | 0, 0, pbn_b0_8_115200 }, |
5099 | 5085 | ||
5100 | 5086 | ||
5101 | /* | 5087 | /* |
5102 | * PA Semi PA6T-1682M on-chip UART | 5088 | * PA Semi PA6T-1682M on-chip UART |
5103 | */ | 5089 | */ |
5104 | { PCI_VENDOR_ID_PASEMI, 0xa004, | 5090 | { PCI_VENDOR_ID_PASEMI, 0xa004, |
5105 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5091 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5106 | pbn_pasemi_1682M }, | 5092 | pbn_pasemi_1682M }, |
5107 | 5093 | ||
5108 | /* | 5094 | /* |
5109 | * National Instruments | 5095 | * National Instruments |
5110 | */ | 5096 | */ |
5111 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI23216, | 5097 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI23216, |
5112 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5098 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5113 | pbn_b1_16_115200 }, | 5099 | pbn_b1_16_115200 }, |
5114 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2328, | 5100 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2328, |
5115 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5101 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5116 | pbn_b1_8_115200 }, | 5102 | pbn_b1_8_115200 }, |
5117 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324, | 5103 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324, |
5118 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5104 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5119 | pbn_b1_bt_4_115200 }, | 5105 | pbn_b1_bt_4_115200 }, |
5120 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322, | 5106 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322, |
5121 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5107 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5122 | pbn_b1_bt_2_115200 }, | 5108 | pbn_b1_bt_2_115200 }, |
5123 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324I, | 5109 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324I, |
5124 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5110 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5125 | pbn_b1_bt_4_115200 }, | 5111 | pbn_b1_bt_4_115200 }, |
5126 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322I, | 5112 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322I, |
5127 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5113 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5128 | pbn_b1_bt_2_115200 }, | 5114 | pbn_b1_bt_2_115200 }, |
5129 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_23216, | 5115 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_23216, |
5130 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5116 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5131 | pbn_b1_16_115200 }, | 5117 | pbn_b1_16_115200 }, |
5132 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2328, | 5118 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2328, |
5133 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5119 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5134 | pbn_b1_8_115200 }, | 5120 | pbn_b1_8_115200 }, |
5135 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2324, | 5121 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2324, |
5136 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5122 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5137 | pbn_b1_bt_4_115200 }, | 5123 | pbn_b1_bt_4_115200 }, |
5138 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2322, | 5124 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2322, |
5139 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5125 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5140 | pbn_b1_bt_2_115200 }, | 5126 | pbn_b1_bt_2_115200 }, |
5141 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2324, | 5127 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2324, |
5142 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5128 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5143 | pbn_b1_bt_4_115200 }, | 5129 | pbn_b1_bt_4_115200 }, |
5144 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2322, | 5130 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2322, |
5145 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5131 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5146 | pbn_b1_bt_2_115200 }, | 5132 | pbn_b1_bt_2_115200 }, |
5147 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2322, | 5133 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2322, |
5148 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5134 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5149 | pbn_ni8430_2 }, | 5135 | pbn_ni8430_2 }, |
5150 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2322, | 5136 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2322, |
5151 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5137 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5152 | pbn_ni8430_2 }, | 5138 | pbn_ni8430_2 }, |
5153 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2324, | 5139 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2324, |
5154 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5140 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5155 | pbn_ni8430_4 }, | 5141 | pbn_ni8430_4 }, |
5156 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2324, | 5142 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2324, |
5157 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5143 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5158 | pbn_ni8430_4 }, | 5144 | pbn_ni8430_4 }, |
5159 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2328, | 5145 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2328, |
5160 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5146 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5161 | pbn_ni8430_8 }, | 5147 | pbn_ni8430_8 }, |
5162 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2328, | 5148 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2328, |
5163 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5149 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5164 | pbn_ni8430_8 }, | 5150 | pbn_ni8430_8 }, |
5165 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_23216, | 5151 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_23216, |
5166 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5152 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5167 | pbn_ni8430_16 }, | 5153 | pbn_ni8430_16 }, |
5168 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_23216, | 5154 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_23216, |
5169 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5155 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5170 | pbn_ni8430_16 }, | 5156 | pbn_ni8430_16 }, |
5171 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2322, | 5157 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2322, |
5172 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5158 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5173 | pbn_ni8430_2 }, | 5159 | pbn_ni8430_2 }, |
5174 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2322, | 5160 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2322, |
5175 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5161 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5176 | pbn_ni8430_2 }, | 5162 | pbn_ni8430_2 }, |
5177 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2324, | 5163 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2324, |
5178 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5164 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5179 | pbn_ni8430_4 }, | 5165 | pbn_ni8430_4 }, |
5180 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324, | 5166 | { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324, |
5181 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5167 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5182 | pbn_ni8430_4 }, | 5168 | pbn_ni8430_4 }, |
5183 | 5169 | ||
5184 | /* | 5170 | /* |
5185 | * ADDI-DATA GmbH communication cards <info@addi-data.com> | 5171 | * ADDI-DATA GmbH communication cards <info@addi-data.com> |
5186 | */ | 5172 | */ |
5187 | { PCI_VENDOR_ID_ADDIDATA, | 5173 | { PCI_VENDOR_ID_ADDIDATA, |
5188 | PCI_DEVICE_ID_ADDIDATA_APCI7500, | 5174 | PCI_DEVICE_ID_ADDIDATA_APCI7500, |
5189 | PCI_ANY_ID, | 5175 | PCI_ANY_ID, |
5190 | PCI_ANY_ID, | 5176 | PCI_ANY_ID, |
5191 | 0, | 5177 | 0, |
5192 | 0, | 5178 | 0, |
5193 | pbn_b0_4_115200 }, | 5179 | pbn_b0_4_115200 }, |
5194 | 5180 | ||
5195 | { PCI_VENDOR_ID_ADDIDATA, | 5181 | { PCI_VENDOR_ID_ADDIDATA, |
5196 | PCI_DEVICE_ID_ADDIDATA_APCI7420, | 5182 | PCI_DEVICE_ID_ADDIDATA_APCI7420, |
5197 | PCI_ANY_ID, | 5183 | PCI_ANY_ID, |
5198 | PCI_ANY_ID, | 5184 | PCI_ANY_ID, |
5199 | 0, | 5185 | 0, |
5200 | 0, | 5186 | 0, |
5201 | pbn_b0_2_115200 }, | 5187 | pbn_b0_2_115200 }, |
5202 | 5188 | ||
5203 | { PCI_VENDOR_ID_ADDIDATA, | 5189 | { PCI_VENDOR_ID_ADDIDATA, |
5204 | PCI_DEVICE_ID_ADDIDATA_APCI7300, | 5190 | PCI_DEVICE_ID_ADDIDATA_APCI7300, |
5205 | PCI_ANY_ID, | 5191 | PCI_ANY_ID, |
5206 | PCI_ANY_ID, | 5192 | PCI_ANY_ID, |
5207 | 0, | 5193 | 0, |
5208 | 0, | 5194 | 0, |
5209 | pbn_b0_1_115200 }, | 5195 | pbn_b0_1_115200 }, |
5210 | 5196 | ||
5211 | { PCI_VENDOR_ID_AMCC, | 5197 | { PCI_VENDOR_ID_AMCC, |
5212 | PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800, | 5198 | PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800, |
5213 | PCI_ANY_ID, | 5199 | PCI_ANY_ID, |
5214 | PCI_ANY_ID, | 5200 | PCI_ANY_ID, |
5215 | 0, | 5201 | 0, |
5216 | 0, | 5202 | 0, |
5217 | pbn_b1_8_115200 }, | 5203 | pbn_b1_8_115200 }, |
5218 | 5204 | ||
5219 | { PCI_VENDOR_ID_ADDIDATA, | 5205 | { PCI_VENDOR_ID_ADDIDATA, |
5220 | PCI_DEVICE_ID_ADDIDATA_APCI7500_2, | 5206 | PCI_DEVICE_ID_ADDIDATA_APCI7500_2, |
5221 | PCI_ANY_ID, | 5207 | PCI_ANY_ID, |
5222 | PCI_ANY_ID, | 5208 | PCI_ANY_ID, |
5223 | 0, | 5209 | 0, |
5224 | 0, | 5210 | 0, |
5225 | pbn_b0_4_115200 }, | 5211 | pbn_b0_4_115200 }, |
5226 | 5212 | ||
5227 | { PCI_VENDOR_ID_ADDIDATA, | 5213 | { PCI_VENDOR_ID_ADDIDATA, |
5228 | PCI_DEVICE_ID_ADDIDATA_APCI7420_2, | 5214 | PCI_DEVICE_ID_ADDIDATA_APCI7420_2, |
5229 | PCI_ANY_ID, | 5215 | PCI_ANY_ID, |
5230 | PCI_ANY_ID, | 5216 | PCI_ANY_ID, |
5231 | 0, | 5217 | 0, |
5232 | 0, | 5218 | 0, |
5233 | pbn_b0_2_115200 }, | 5219 | pbn_b0_2_115200 }, |
5234 | 5220 | ||
5235 | { PCI_VENDOR_ID_ADDIDATA, | 5221 | { PCI_VENDOR_ID_ADDIDATA, |
5236 | PCI_DEVICE_ID_ADDIDATA_APCI7300_2, | 5222 | PCI_DEVICE_ID_ADDIDATA_APCI7300_2, |
5237 | PCI_ANY_ID, | 5223 | PCI_ANY_ID, |
5238 | PCI_ANY_ID, | 5224 | PCI_ANY_ID, |
5239 | 0, | 5225 | 0, |
5240 | 0, | 5226 | 0, |
5241 | pbn_b0_1_115200 }, | 5227 | pbn_b0_1_115200 }, |
5242 | 5228 | ||
5243 | { PCI_VENDOR_ID_ADDIDATA, | 5229 | { PCI_VENDOR_ID_ADDIDATA, |
5244 | PCI_DEVICE_ID_ADDIDATA_APCI7500_3, | 5230 | PCI_DEVICE_ID_ADDIDATA_APCI7500_3, |
5245 | PCI_ANY_ID, | 5231 | PCI_ANY_ID, |
5246 | PCI_ANY_ID, | 5232 | PCI_ANY_ID, |
5247 | 0, | 5233 | 0, |
5248 | 0, | 5234 | 0, |
5249 | pbn_b0_4_115200 }, | 5235 | pbn_b0_4_115200 }, |
5250 | 5236 | ||
5251 | { PCI_VENDOR_ID_ADDIDATA, | 5237 | { PCI_VENDOR_ID_ADDIDATA, |
5252 | PCI_DEVICE_ID_ADDIDATA_APCI7420_3, | 5238 | PCI_DEVICE_ID_ADDIDATA_APCI7420_3, |
5253 | PCI_ANY_ID, | 5239 | PCI_ANY_ID, |
5254 | PCI_ANY_ID, | 5240 | PCI_ANY_ID, |
5255 | 0, | 5241 | 0, |
5256 | 0, | 5242 | 0, |
5257 | pbn_b0_2_115200 }, | 5243 | pbn_b0_2_115200 }, |
5258 | 5244 | ||
5259 | { PCI_VENDOR_ID_ADDIDATA, | 5245 | { PCI_VENDOR_ID_ADDIDATA, |
5260 | PCI_DEVICE_ID_ADDIDATA_APCI7300_3, | 5246 | PCI_DEVICE_ID_ADDIDATA_APCI7300_3, |
5261 | PCI_ANY_ID, | 5247 | PCI_ANY_ID, |
5262 | PCI_ANY_ID, | 5248 | PCI_ANY_ID, |
5263 | 0, | 5249 | 0, |
5264 | 0, | 5250 | 0, |
5265 | pbn_b0_1_115200 }, | 5251 | pbn_b0_1_115200 }, |
5266 | 5252 | ||
5267 | { PCI_VENDOR_ID_ADDIDATA, | 5253 | { PCI_VENDOR_ID_ADDIDATA, |
5268 | PCI_DEVICE_ID_ADDIDATA_APCI7800_3, | 5254 | PCI_DEVICE_ID_ADDIDATA_APCI7800_3, |
5269 | PCI_ANY_ID, | 5255 | PCI_ANY_ID, |
5270 | PCI_ANY_ID, | 5256 | PCI_ANY_ID, |
5271 | 0, | 5257 | 0, |
5272 | 0, | 5258 | 0, |
5273 | pbn_b0_8_115200 }, | 5259 | pbn_b0_8_115200 }, |
5274 | 5260 | ||
5275 | { PCI_VENDOR_ID_ADDIDATA, | 5261 | { PCI_VENDOR_ID_ADDIDATA, |
5276 | PCI_DEVICE_ID_ADDIDATA_APCIe7500, | 5262 | PCI_DEVICE_ID_ADDIDATA_APCIe7500, |
5277 | PCI_ANY_ID, | 5263 | PCI_ANY_ID, |
5278 | PCI_ANY_ID, | 5264 | PCI_ANY_ID, |
5279 | 0, | 5265 | 0, |
5280 | 0, | 5266 | 0, |
5281 | pbn_ADDIDATA_PCIe_4_3906250 }, | 5267 | pbn_ADDIDATA_PCIe_4_3906250 }, |
5282 | 5268 | ||
5283 | { PCI_VENDOR_ID_ADDIDATA, | 5269 | { PCI_VENDOR_ID_ADDIDATA, |
5284 | PCI_DEVICE_ID_ADDIDATA_APCIe7420, | 5270 | PCI_DEVICE_ID_ADDIDATA_APCIe7420, |
5285 | PCI_ANY_ID, | 5271 | PCI_ANY_ID, |
5286 | PCI_ANY_ID, | 5272 | PCI_ANY_ID, |
5287 | 0, | 5273 | 0, |
5288 | 0, | 5274 | 0, |
5289 | pbn_ADDIDATA_PCIe_2_3906250 }, | 5275 | pbn_ADDIDATA_PCIe_2_3906250 }, |
5290 | 5276 | ||
5291 | { PCI_VENDOR_ID_ADDIDATA, | 5277 | { PCI_VENDOR_ID_ADDIDATA, |
5292 | PCI_DEVICE_ID_ADDIDATA_APCIe7300, | 5278 | PCI_DEVICE_ID_ADDIDATA_APCIe7300, |
5293 | PCI_ANY_ID, | 5279 | PCI_ANY_ID, |
5294 | PCI_ANY_ID, | 5280 | PCI_ANY_ID, |
5295 | 0, | 5281 | 0, |
5296 | 0, | 5282 | 0, |
5297 | pbn_ADDIDATA_PCIe_1_3906250 }, | 5283 | pbn_ADDIDATA_PCIe_1_3906250 }, |
5298 | 5284 | ||
5299 | { PCI_VENDOR_ID_ADDIDATA, | 5285 | { PCI_VENDOR_ID_ADDIDATA, |
5300 | PCI_DEVICE_ID_ADDIDATA_APCIe7800, | 5286 | PCI_DEVICE_ID_ADDIDATA_APCIe7800, |
5301 | PCI_ANY_ID, | 5287 | PCI_ANY_ID, |
5302 | PCI_ANY_ID, | 5288 | PCI_ANY_ID, |
5303 | 0, | 5289 | 0, |
5304 | 0, | 5290 | 0, |
5305 | pbn_ADDIDATA_PCIe_8_3906250 }, | 5291 | pbn_ADDIDATA_PCIe_8_3906250 }, |
5306 | 5292 | ||
5307 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, | 5293 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, |
5308 | PCI_VENDOR_ID_IBM, 0x0299, | 5294 | PCI_VENDOR_ID_IBM, 0x0299, |
5309 | 0, 0, pbn_b0_bt_2_115200 }, | 5295 | 0, 0, pbn_b0_bt_2_115200 }, |
5310 | 5296 | ||
5311 | /* | 5297 | /* |
5312 | * other NetMos 9835 devices are most likely handled by the | 5298 | * other NetMos 9835 devices are most likely handled by the |
5313 | * parport_serial driver, check drivers/parport/parport_serial.c | 5299 | * parport_serial driver, check drivers/parport/parport_serial.c |
5314 | * before adding them here. | 5300 | * before adding them here. |
5315 | */ | 5301 | */ |
5316 | 5302 | ||
5317 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, | 5303 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, |
5318 | 0xA000, 0x1000, | 5304 | 0xA000, 0x1000, |
5319 | 0, 0, pbn_b0_1_115200 }, | 5305 | 0, 0, pbn_b0_1_115200 }, |
5320 | 5306 | ||
5321 | /* the 9901 is a rebranded 9912 */ | 5307 | /* the 9901 is a rebranded 9912 */ |
5322 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912, | 5308 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912, |
5323 | 0xA000, 0x1000, | 5309 | 0xA000, 0x1000, |
5324 | 0, 0, pbn_b0_1_115200 }, | 5310 | 0, 0, pbn_b0_1_115200 }, |
5325 | 5311 | ||
5326 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922, | 5312 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922, |
5327 | 0xA000, 0x1000, | 5313 | 0xA000, 0x1000, |
5328 | 0, 0, pbn_b0_1_115200 }, | 5314 | 0, 0, pbn_b0_1_115200 }, |
5329 | 5315 | ||
5330 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9904, | 5316 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9904, |
5331 | 0xA000, 0x1000, | 5317 | 0xA000, 0x1000, |
5332 | 0, 0, pbn_b0_1_115200 }, | 5318 | 0, 0, pbn_b0_1_115200 }, |
5333 | 5319 | ||
5334 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, | 5320 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, |
5335 | 0xA000, 0x1000, | 5321 | 0xA000, 0x1000, |
5336 | 0, 0, pbn_b0_1_115200 }, | 5322 | 0, 0, pbn_b0_1_115200 }, |
5337 | 5323 | ||
5338 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, | 5324 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, |
5339 | 0xA000, 0x3002, | 5325 | 0xA000, 0x3002, |
5340 | 0, 0, pbn_NETMOS9900_2s_115200 }, | 5326 | 0, 0, pbn_NETMOS9900_2s_115200 }, |
5341 | 5327 | ||
5342 | /* | 5328 | /* |
5343 | * Best Connectivity and Rosewill PCI Multi I/O cards | 5329 | * Best Connectivity and Rosewill PCI Multi I/O cards |
5344 | */ | 5330 | */ |
5345 | 5331 | ||
5346 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | 5332 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, |
5347 | 0xA000, 0x1000, | 5333 | 0xA000, 0x1000, |
5348 | 0, 0, pbn_b0_1_115200 }, | 5334 | 0, 0, pbn_b0_1_115200 }, |
5349 | 5335 | ||
5350 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | 5336 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, |
5351 | 0xA000, 0x3002, | 5337 | 0xA000, 0x3002, |
5352 | 0, 0, pbn_b0_bt_2_115200 }, | 5338 | 0, 0, pbn_b0_bt_2_115200 }, |
5353 | 5339 | ||
5354 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | 5340 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, |
5355 | 0xA000, 0x3004, | 5341 | 0xA000, 0x3004, |
5356 | 0, 0, pbn_b0_bt_4_115200 }, | 5342 | 0, 0, pbn_b0_bt_4_115200 }, |
5357 | /* Intel CE4100 */ | 5343 | /* Intel CE4100 */ |
5358 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART, | 5344 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART, |
5359 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5345 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5360 | pbn_ce4100_1_115200 }, | 5346 | pbn_ce4100_1_115200 }, |
5361 | /* Intel BayTrail */ | 5347 | /* Intel BayTrail */ |
5362 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART1, | 5348 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART1, |
5363 | PCI_ANY_ID, PCI_ANY_ID, | 5349 | PCI_ANY_ID, PCI_ANY_ID, |
5364 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, | 5350 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, |
5365 | pbn_byt }, | 5351 | pbn_byt }, |
5366 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART2, | 5352 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART2, |
5367 | PCI_ANY_ID, PCI_ANY_ID, | 5353 | PCI_ANY_ID, PCI_ANY_ID, |
5368 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, | 5354 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, |
5369 | pbn_byt }, | 5355 | pbn_byt }, |
5370 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW_UART1, | 5356 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW_UART1, |
5371 | PCI_ANY_ID, PCI_ANY_ID, | 5357 | PCI_ANY_ID, PCI_ANY_ID, |
5372 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, | 5358 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, |
5373 | pbn_byt }, | 5359 | pbn_byt }, |
5374 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW_UART2, | 5360 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW_UART2, |
5375 | PCI_ANY_ID, PCI_ANY_ID, | 5361 | PCI_ANY_ID, PCI_ANY_ID, |
5376 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, | 5362 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, |
5377 | pbn_byt }, | 5363 | pbn_byt }, |
5378 | 5364 | ||
5379 | /* | 5365 | /* |
5380 | * Intel Quark x1000 | 5366 | * Intel Quark x1000 |
5381 | */ | 5367 | */ |
5382 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_UART, | 5368 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_UART, |
5383 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5369 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5384 | pbn_qrk }, | 5370 | pbn_qrk }, |
5385 | /* | 5371 | /* |
5386 | * Cronyx Omega PCI | 5372 | * Cronyx Omega PCI |
5387 | */ | 5373 | */ |
5388 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA, | 5374 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA, |
5389 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5375 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5390 | pbn_omegapci }, | 5376 | pbn_omegapci }, |
5391 | 5377 | ||
5392 | /* | 5378 | /* |
5393 | * Broadcom TruManage | 5379 | * Broadcom TruManage |
5394 | */ | 5380 | */ |
5395 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BROADCOM_TRUMANAGE, | 5381 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BROADCOM_TRUMANAGE, |
5396 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 5382 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
5397 | pbn_brcm_trumanage }, | 5383 | pbn_brcm_trumanage }, |
5398 | 5384 | ||
5399 | /* | 5385 | /* |
5400 | * AgeStar as-prs2-009 | 5386 | * AgeStar as-prs2-009 |
5401 | */ | 5387 | */ |
5402 | { PCI_VENDOR_ID_AGESTAR, PCI_DEVICE_ID_AGESTAR_9375, | 5388 | { PCI_VENDOR_ID_AGESTAR, PCI_DEVICE_ID_AGESTAR_9375, |
5403 | PCI_ANY_ID, PCI_ANY_ID, | 5389 | PCI_ANY_ID, PCI_ANY_ID, |
5404 | 0, 0, pbn_b0_bt_2_115200 }, | 5390 | 0, 0, pbn_b0_bt_2_115200 }, |
5405 | 5391 | ||
5406 | /* | 5392 | /* |
5407 | * WCH CH353 series devices: The 2S1P is handled by parport_serial | 5393 | * WCH CH353 series devices: The 2S1P is handled by parport_serial |
5408 | * so not listed here. | 5394 | * so not listed here. |
5409 | */ | 5395 | */ |
5410 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_4S, | 5396 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_4S, |
5411 | PCI_ANY_ID, PCI_ANY_ID, | 5397 | PCI_ANY_ID, PCI_ANY_ID, |
5412 | 0, 0, pbn_b0_bt_4_115200 }, | 5398 | 0, 0, pbn_b0_bt_4_115200 }, |
5413 | 5399 | ||
5414 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_2S1PF, | 5400 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_2S1PF, |
5415 | PCI_ANY_ID, PCI_ANY_ID, | ||
5416 | 0, 0, pbn_b0_bt_2_115200 }, | ||
5417 | |||
5418 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH352_2S, | ||
5419 | PCI_ANY_ID, PCI_ANY_ID, | 5401 | PCI_ANY_ID, PCI_ANY_ID, |
5420 | 0, 0, pbn_b0_bt_2_115200 }, | 5402 | 0, 0, pbn_b0_bt_2_115200 }, |
5421 | 5403 | ||
5422 | { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S, | 5404 | { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S, |
5423 | PCI_ANY_ID, PCI_ANY_ID, | 5405 | PCI_ANY_ID, PCI_ANY_ID, |
5424 | 0, 0, pbn_wch384_4 }, | 5406 | 0, 0, pbn_wch384_4 }, |
5425 | 5407 | ||
5426 | /* | 5408 | /* |
5427 | * Commtech, Inc. Fastcom adapters | 5409 | * Commtech, Inc. Fastcom adapters |
5428 | */ | 5410 | */ |
5429 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCI335, | 5411 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCI335, |
5430 | PCI_ANY_ID, PCI_ANY_ID, | 5412 | PCI_ANY_ID, PCI_ANY_ID, |
5431 | 0, | 5413 | 0, |
5432 | 0, pbn_b0_2_1152000_200 }, | 5414 | 0, pbn_b0_2_1152000_200 }, |
5433 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCI335, | 5415 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCI335, |
5434 | PCI_ANY_ID, PCI_ANY_ID, | 5416 | PCI_ANY_ID, PCI_ANY_ID, |
5435 | 0, | 5417 | 0, |
5436 | 0, pbn_b0_4_1152000_200 }, | 5418 | 0, pbn_b0_4_1152000_200 }, |
5437 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2324PCI335, | 5419 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2324PCI335, |
5438 | PCI_ANY_ID, PCI_ANY_ID, | 5420 | PCI_ANY_ID, PCI_ANY_ID, |
5439 | 0, | 5421 | 0, |
5440 | 0, pbn_b0_4_1152000_200 }, | 5422 | 0, pbn_b0_4_1152000_200 }, |
5441 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2328PCI335, | 5423 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2328PCI335, |
5442 | PCI_ANY_ID, PCI_ANY_ID, | 5424 | PCI_ANY_ID, PCI_ANY_ID, |
5443 | 0, | 5425 | 0, |
5444 | 0, pbn_b0_8_1152000_200 }, | 5426 | 0, pbn_b0_8_1152000_200 }, |
5445 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCIE, | 5427 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCIE, |
5446 | PCI_ANY_ID, PCI_ANY_ID, | 5428 | PCI_ANY_ID, PCI_ANY_ID, |
5447 | 0, | 5429 | 0, |
5448 | 0, pbn_exar_XR17V352 }, | 5430 | 0, pbn_exar_XR17V352 }, |
5449 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCIE, | 5431 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCIE, |
5450 | PCI_ANY_ID, PCI_ANY_ID, | 5432 | PCI_ANY_ID, PCI_ANY_ID, |
5451 | 0, | 5433 | 0, |
5452 | 0, pbn_exar_XR17V354 }, | 5434 | 0, pbn_exar_XR17V354 }, |
5453 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4228PCIE, | 5435 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4228PCIE, |
5454 | PCI_ANY_ID, PCI_ANY_ID, | 5436 | PCI_ANY_ID, PCI_ANY_ID, |
5455 | 0, | 5437 | 0, |
5456 | 0, pbn_exar_XR17V358 }, | 5438 | 0, pbn_exar_XR17V358 }, |
5457 | 5439 | ||
5458 | /* Fintek PCI serial cards */ | 5440 | /* Fintek PCI serial cards */ |
5459 | { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 }, | 5441 | { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 }, |
5460 | { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 }, | 5442 | { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 }, |
5461 | { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 }, | 5443 | { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 }, |
5462 | 5444 | ||
5463 | /* | 5445 | /* |
5464 | * These entries match devices with class COMMUNICATION_SERIAL, | 5446 | * These entries match devices with class COMMUNICATION_SERIAL, |
5465 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 5447 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
5466 | */ | 5448 | */ |
5467 | { PCI_ANY_ID, PCI_ANY_ID, | 5449 | { PCI_ANY_ID, PCI_ANY_ID, |
5468 | PCI_ANY_ID, PCI_ANY_ID, | 5450 | PCI_ANY_ID, PCI_ANY_ID, |
5469 | PCI_CLASS_COMMUNICATION_SERIAL << 8, | 5451 | PCI_CLASS_COMMUNICATION_SERIAL << 8, |
5470 | 0xffff00, pbn_default }, | 5452 | 0xffff00, pbn_default }, |
5471 | { PCI_ANY_ID, PCI_ANY_ID, | 5453 | { PCI_ANY_ID, PCI_ANY_ID, |
5472 | PCI_ANY_ID, PCI_ANY_ID, | 5454 | PCI_ANY_ID, PCI_ANY_ID, |
5473 | PCI_CLASS_COMMUNICATION_MODEM << 8, | 5455 | PCI_CLASS_COMMUNICATION_MODEM << 8, |
5474 | 0xffff00, pbn_default }, | 5456 | 0xffff00, pbn_default }, |
5475 | { PCI_ANY_ID, PCI_ANY_ID, | 5457 | { PCI_ANY_ID, PCI_ANY_ID, |
5476 | PCI_ANY_ID, PCI_ANY_ID, | 5458 | PCI_ANY_ID, PCI_ANY_ID, |
5477 | PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, | 5459 | PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, |
5478 | 0xffff00, pbn_default }, | 5460 | 0xffff00, pbn_default }, |
5479 | { 0, } | 5461 | { 0, } |
5480 | }; | 5462 | }; |
5481 | 5463 | ||
5482 | static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev, | 5464 | static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev, |
5483 | pci_channel_state_t state) | 5465 | pci_channel_state_t state) |
5484 | { | 5466 | { |
5485 | struct serial_private *priv = pci_get_drvdata(dev); | 5467 | struct serial_private *priv = pci_get_drvdata(dev); |
5486 | 5468 | ||
5487 | if (state == pci_channel_io_perm_failure) | 5469 | if (state == pci_channel_io_perm_failure) |
5488 | return PCI_ERS_RESULT_DISCONNECT; | 5470 | return PCI_ERS_RESULT_DISCONNECT; |
5489 | 5471 | ||
5490 | if (priv) | 5472 | if (priv) |
5491 | pciserial_suspend_ports(priv); | 5473 | pciserial_suspend_ports(priv); |
5492 | 5474 | ||
5493 | pci_disable_device(dev); | 5475 | pci_disable_device(dev); |
5494 | 5476 | ||
5495 | return PCI_ERS_RESULT_NEED_RESET; | 5477 | return PCI_ERS_RESULT_NEED_RESET; |
5496 | } | 5478 | } |
5497 | 5479 | ||
5498 | static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev) | 5480 | static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev) |
5499 | { | 5481 | { |
5500 | int rc; | 5482 | int rc; |
5501 | 5483 | ||
5502 | rc = pci_enable_device(dev); | 5484 | rc = pci_enable_device(dev); |
5503 | 5485 | ||
5504 | if (rc) | 5486 | if (rc) |
5505 | return PCI_ERS_RESULT_DISCONNECT; | 5487 | return PCI_ERS_RESULT_DISCONNECT; |
5506 | 5488 | ||
5507 | pci_restore_state(dev); | 5489 | pci_restore_state(dev); |
5508 | pci_save_state(dev); | 5490 | pci_save_state(dev); |
5509 | 5491 | ||
5510 | return PCI_ERS_RESULT_RECOVERED; | 5492 | return PCI_ERS_RESULT_RECOVERED; |
5511 | } | 5493 | } |
5512 | 5494 | ||
5513 | static void serial8250_io_resume(struct pci_dev *dev) | 5495 | static void serial8250_io_resume(struct pci_dev *dev) |
5514 | { | 5496 | { |
5515 | struct serial_private *priv = pci_get_drvdata(dev); | 5497 | struct serial_private *priv = pci_get_drvdata(dev); |
5516 | 5498 | ||
5517 | if (priv) | 5499 | if (priv) |
5518 | pciserial_resume_ports(priv); | 5500 | pciserial_resume_ports(priv); |
5519 | } | 5501 | } |
5520 | 5502 | ||
5521 | static const struct pci_error_handlers serial8250_err_handler = { | 5503 | static const struct pci_error_handlers serial8250_err_handler = { |
5522 | .error_detected = serial8250_io_error_detected, | 5504 | .error_detected = serial8250_io_error_detected, |
5523 | .slot_reset = serial8250_io_slot_reset, | 5505 | .slot_reset = serial8250_io_slot_reset, |
5524 | .resume = serial8250_io_resume, | 5506 | .resume = serial8250_io_resume, |
5525 | }; | 5507 | }; |
5526 | 5508 | ||
5527 | static struct pci_driver serial_pci_driver = { | 5509 | static struct pci_driver serial_pci_driver = { |
5528 | .name = "serial", | 5510 | .name = "serial", |
5529 | .probe = pciserial_init_one, | 5511 | .probe = pciserial_init_one, |
5530 | .remove = pciserial_remove_one, | 5512 | .remove = pciserial_remove_one, |
5531 | #ifdef CONFIG_PM | 5513 | #ifdef CONFIG_PM |
5532 | .suspend = pciserial_suspend_one, | 5514 | .suspend = pciserial_suspend_one, |
5533 | .resume = pciserial_resume_one, | 5515 | .resume = pciserial_resume_one, |
5534 | #endif | 5516 | #endif |
5535 | .id_table = serial_pci_tbl, | 5517 | .id_table = serial_pci_tbl, |
5536 | .err_handler = &serial8250_err_handler, | 5518 | .err_handler = &serial8250_err_handler, |
5537 | }; | 5519 | }; |
5538 | 5520 | ||
5539 | module_pci_driver(serial_pci_driver); | 5521 | module_pci_driver(serial_pci_driver); |
5540 | 5522 | ||
5541 | MODULE_LICENSE("GPL"); | 5523 | MODULE_LICENSE("GPL"); |
5542 | MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module"); | 5524 | MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module"); |
5543 | MODULE_DEVICE_TABLE(pci, serial_pci_tbl); | 5525 | MODULE_DEVICE_TABLE(pci, serial_pci_tbl); |
5544 | 5526 |
drivers/tty/serial/of_serial.c
1 | /* | 1 | /* |
2 | * Serial Port driver for Open Firmware platform devices | 2 | * Serial Port driver for Open Firmware platform devices |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp. | 4 | * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | #include <linux/console.h> | 12 | #include <linux/console.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/serial_core.h> | 16 | #include <linux/serial_core.h> |
17 | #include <linux/serial_reg.h> | 17 | #include <linux/serial_reg.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
20 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
21 | #include <linux/nwpserial.h> | 21 | #include <linux/nwpserial.h> |
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | 23 | ||
24 | #include "8250/8250.h" | 24 | #include "8250/8250.h" |
25 | 25 | ||
26 | struct of_serial_info { | 26 | struct of_serial_info { |
27 | struct clk *clk; | 27 | struct clk *clk; |
28 | int type; | 28 | int type; |
29 | int line; | 29 | int line; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | #ifdef CONFIG_ARCH_TEGRA | 32 | #ifdef CONFIG_ARCH_TEGRA |
33 | void tegra_serial_handle_break(struct uart_port *p) | 33 | void tegra_serial_handle_break(struct uart_port *p) |
34 | { | 34 | { |
35 | unsigned int status, tmout = 10000; | 35 | unsigned int status, tmout = 10000; |
36 | 36 | ||
37 | do { | 37 | do { |
38 | status = p->serial_in(p, UART_LSR); | 38 | status = p->serial_in(p, UART_LSR); |
39 | if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)) | 39 | if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)) |
40 | status = p->serial_in(p, UART_RX); | 40 | status = p->serial_in(p, UART_RX); |
41 | else | 41 | else |
42 | break; | 42 | break; |
43 | if (--tmout == 0) | 43 | if (--tmout == 0) |
44 | break; | 44 | break; |
45 | udelay(1); | 45 | udelay(1); |
46 | } while (1); | 46 | } while (1); |
47 | } | 47 | } |
48 | #else | 48 | #else |
49 | static inline void tegra_serial_handle_break(struct uart_port *port) | 49 | static inline void tegra_serial_handle_break(struct uart_port *port) |
50 | { | 50 | { |
51 | } | 51 | } |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * Fill a struct uart_port for a given device node | 55 | * Fill a struct uart_port for a given device node |
56 | */ | 56 | */ |
57 | static int of_platform_serial_setup(struct platform_device *ofdev, | 57 | static int of_platform_serial_setup(struct platform_device *ofdev, |
58 | int type, struct uart_port *port, | 58 | int type, struct uart_port *port, |
59 | struct of_serial_info *info) | 59 | struct of_serial_info *info) |
60 | { | 60 | { |
61 | struct resource resource; | 61 | struct resource resource; |
62 | struct device_node *np = ofdev->dev.of_node; | 62 | struct device_node *np = ofdev->dev.of_node; |
63 | u32 clk, spd, prop; | 63 | u32 clk, spd, prop; |
64 | int ret; | 64 | int ret; |
65 | 65 | ||
66 | memset(port, 0, sizeof *port); | 66 | memset(port, 0, sizeof *port); |
67 | if (of_property_read_u32(np, "clock-frequency", &clk)) { | 67 | if (of_property_read_u32(np, "clock-frequency", &clk)) { |
68 | 68 | ||
69 | /* Get clk rate through clk driver if present */ | 69 | /* Get clk rate through clk driver if present */ |
70 | info->clk = clk_get(&ofdev->dev, NULL); | 70 | info->clk = clk_get(&ofdev->dev, NULL); |
71 | if (IS_ERR(info->clk)) { | 71 | if (IS_ERR(info->clk)) { |
72 | dev_warn(&ofdev->dev, | 72 | dev_warn(&ofdev->dev, |
73 | "clk or clock-frequency not defined\n"); | 73 | "clk or clock-frequency not defined\n"); |
74 | return PTR_ERR(info->clk); | 74 | return PTR_ERR(info->clk); |
75 | } | 75 | } |
76 | 76 | ||
77 | clk_prepare_enable(info->clk); | 77 | clk_prepare_enable(info->clk); |
78 | clk = clk_get_rate(info->clk); | 78 | clk = clk_get_rate(info->clk); |
79 | } | 79 | } |
80 | /* If current-speed was set, then try not to change it. */ | 80 | /* If current-speed was set, then try not to change it. */ |
81 | if (of_property_read_u32(np, "current-speed", &spd) == 0) | 81 | if (of_property_read_u32(np, "current-speed", &spd) == 0) |
82 | port->custom_divisor = clk / (16 * spd); | 82 | port->custom_divisor = clk / (16 * spd); |
83 | 83 | ||
84 | ret = of_address_to_resource(np, 0, &resource); | 84 | ret = of_address_to_resource(np, 0, &resource); |
85 | if (ret) { | 85 | if (ret) { |
86 | dev_warn(&ofdev->dev, "invalid address\n"); | 86 | dev_warn(&ofdev->dev, "invalid address\n"); |
87 | goto out; | 87 | goto out; |
88 | } | 88 | } |
89 | 89 | ||
90 | spin_lock_init(&port->lock); | 90 | spin_lock_init(&port->lock); |
91 | port->mapbase = resource.start; | 91 | port->mapbase = resource.start; |
92 | 92 | ||
93 | /* Check for shifted address mapping */ | 93 | /* Check for shifted address mapping */ |
94 | if (of_property_read_u32(np, "reg-offset", &prop) == 0) | 94 | if (of_property_read_u32(np, "reg-offset", &prop) == 0) |
95 | port->mapbase += prop; | 95 | port->mapbase += prop; |
96 | 96 | ||
97 | /* Check for registers offset within the devices address range */ | 97 | /* Check for registers offset within the devices address range */ |
98 | if (of_property_read_u32(np, "reg-shift", &prop) == 0) | 98 | if (of_property_read_u32(np, "reg-shift", &prop) == 0) |
99 | port->regshift = prop; | 99 | port->regshift = prop; |
100 | 100 | ||
101 | /* Check for fifo size */ | 101 | /* Check for fifo size */ |
102 | if (of_property_read_u32(np, "fifo-size", &prop) == 0) | 102 | if (of_property_read_u32(np, "fifo-size", &prop) == 0) |
103 | port->fifosize = prop; | 103 | port->fifosize = prop; |
104 | 104 | ||
105 | /* Check for a fixed line number */ | 105 | /* Check for a fixed line number */ |
106 | ret = of_alias_get_id(np, "serial"); | 106 | ret = of_alias_get_id(np, "serial"); |
107 | if (ret >= 0) | 107 | if (ret >= 0) |
108 | port->line = ret; | 108 | port->line = ret; |
109 | 109 | ||
110 | port->irq = irq_of_parse_and_map(np, 0); | 110 | port->irq = irq_of_parse_and_map(np, 0); |
111 | port->iotype = UPIO_MEM; | 111 | port->iotype = UPIO_MEM; |
112 | if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { | 112 | if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { |
113 | switch (prop) { | 113 | switch (prop) { |
114 | case 1: | 114 | case 1: |
115 | port->iotype = UPIO_MEM; | 115 | port->iotype = UPIO_MEM; |
116 | break; | 116 | break; |
117 | case 4: | 117 | case 4: |
118 | port->iotype = UPIO_MEM32; | 118 | port->iotype = UPIO_MEM32; |
119 | break; | 119 | break; |
120 | default: | 120 | default: |
121 | dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", | 121 | dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", |
122 | prop); | 122 | prop); |
123 | ret = -EINVAL; | 123 | ret = -EINVAL; |
124 | goto out; | 124 | goto out; |
125 | } | 125 | } |
126 | } | 126 | } |
127 | 127 | ||
128 | port->type = type; | 128 | port->type = type; |
129 | port->uartclk = clk; | 129 | port->uartclk = clk; |
130 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | 130 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
131 | | UPF_FIXED_PORT | UPF_FIXED_TYPE; | 131 | | UPF_FIXED_PORT | UPF_FIXED_TYPE; |
132 | 132 | ||
133 | if (of_find_property(np, "no-loopback-test", NULL)) | 133 | if (of_find_property(np, "no-loopback-test", NULL)) |
134 | port->flags |= UPF_SKIP_TEST; | 134 | port->flags |= UPF_SKIP_TEST; |
135 | 135 | ||
136 | ret = of_alias_get_id(np, "serial"); | ||
137 | if (ret >= 0) | ||
138 | port->line = ret; | ||
139 | |||
140 | port->dev = &ofdev->dev; | 136 | port->dev = &ofdev->dev; |
141 | 137 | ||
142 | switch (type) { | 138 | switch (type) { |
143 | case PORT_TEGRA: | 139 | case PORT_TEGRA: |
144 | port->handle_break = tegra_serial_handle_break; | 140 | port->handle_break = tegra_serial_handle_break; |
145 | break; | 141 | break; |
146 | 142 | ||
147 | case PORT_RT2880: | 143 | case PORT_RT2880: |
148 | port->iotype = UPIO_AU; | 144 | port->iotype = UPIO_AU; |
149 | break; | 145 | break; |
150 | } | 146 | } |
151 | 147 | ||
152 | return 0; | 148 | return 0; |
153 | out: | 149 | out: |
154 | if (info->clk) | 150 | if (info->clk) |
155 | clk_disable_unprepare(info->clk); | 151 | clk_disable_unprepare(info->clk); |
156 | return ret; | 152 | return ret; |
157 | } | 153 | } |
158 | 154 | ||
159 | /* | 155 | /* |
160 | * Try to register a serial port | 156 | * Try to register a serial port |
161 | */ | 157 | */ |
162 | static struct of_device_id of_platform_serial_table[]; | 158 | static struct of_device_id of_platform_serial_table[]; |
163 | static int of_platform_serial_probe(struct platform_device *ofdev) | 159 | static int of_platform_serial_probe(struct platform_device *ofdev) |
164 | { | 160 | { |
165 | const struct of_device_id *match; | 161 | const struct of_device_id *match; |
166 | struct of_serial_info *info; | 162 | struct of_serial_info *info; |
167 | struct uart_port port; | 163 | struct uart_port port; |
168 | int port_type; | 164 | int port_type; |
169 | int ret; | 165 | int ret; |
170 | 166 | ||
171 | match = of_match_device(of_platform_serial_table, &ofdev->dev); | 167 | match = of_match_device(of_platform_serial_table, &ofdev->dev); |
172 | if (!match) | 168 | if (!match) |
173 | return -EINVAL; | 169 | return -EINVAL; |
174 | 170 | ||
175 | if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) | 171 | if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) |
176 | return -EBUSY; | 172 | return -EBUSY; |
177 | 173 | ||
178 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 174 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
179 | if (info == NULL) | 175 | if (info == NULL) |
180 | return -ENOMEM; | 176 | return -ENOMEM; |
181 | 177 | ||
182 | port_type = (unsigned long)match->data; | 178 | port_type = (unsigned long)match->data; |
183 | ret = of_platform_serial_setup(ofdev, port_type, &port, info); | 179 | ret = of_platform_serial_setup(ofdev, port_type, &port, info); |
184 | if (ret) | 180 | if (ret) |
185 | goto out; | 181 | goto out; |
186 | 182 | ||
187 | switch (port_type) { | 183 | switch (port_type) { |
188 | #ifdef CONFIG_SERIAL_8250 | 184 | #ifdef CONFIG_SERIAL_8250 |
189 | case PORT_8250 ... PORT_MAX_8250: | 185 | case PORT_8250 ... PORT_MAX_8250: |
190 | { | 186 | { |
191 | struct uart_8250_port port8250; | 187 | struct uart_8250_port port8250; |
192 | memset(&port8250, 0, sizeof(port8250)); | 188 | memset(&port8250, 0, sizeof(port8250)); |
193 | port.type = port_type; | 189 | port.type = port_type; |
194 | port8250.port = port; | 190 | port8250.port = port; |
195 | 191 | ||
196 | if (port.fifosize) | 192 | if (port.fifosize) |
197 | port8250.capabilities = UART_CAP_FIFO; | 193 | port8250.capabilities = UART_CAP_FIFO; |
198 | 194 | ||
199 | if (of_property_read_bool(ofdev->dev.of_node, | 195 | if (of_property_read_bool(ofdev->dev.of_node, |
200 | "auto-flow-control")) | 196 | "auto-flow-control")) |
201 | port8250.capabilities |= UART_CAP_AFE; | 197 | port8250.capabilities |= UART_CAP_AFE; |
202 | 198 | ||
203 | ret = serial8250_register_8250_port(&port8250); | 199 | ret = serial8250_register_8250_port(&port8250); |
204 | break; | 200 | break; |
205 | } | 201 | } |
206 | #endif | 202 | #endif |
207 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL | 203 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL |
208 | case PORT_NWPSERIAL: | 204 | case PORT_NWPSERIAL: |
209 | ret = nwpserial_register_port(&port); | 205 | ret = nwpserial_register_port(&port); |
210 | break; | 206 | break; |
211 | #endif | 207 | #endif |
212 | default: | 208 | default: |
213 | /* need to add code for these */ | 209 | /* need to add code for these */ |
214 | case PORT_UNKNOWN: | 210 | case PORT_UNKNOWN: |
215 | dev_info(&ofdev->dev, "Unknown serial port found, ignored\n"); | 211 | dev_info(&ofdev->dev, "Unknown serial port found, ignored\n"); |
216 | ret = -ENODEV; | 212 | ret = -ENODEV; |
217 | break; | 213 | break; |
218 | } | 214 | } |
219 | if (ret < 0) | 215 | if (ret < 0) |
220 | goto out; | 216 | goto out; |
221 | 217 | ||
222 | info->type = port_type; | 218 | info->type = port_type; |
223 | info->line = ret; | 219 | info->line = ret; |
224 | platform_set_drvdata(ofdev, info); | 220 | platform_set_drvdata(ofdev, info); |
225 | return 0; | 221 | return 0; |
226 | out: | 222 | out: |
227 | kfree(info); | 223 | kfree(info); |
228 | irq_dispose_mapping(port.irq); | 224 | irq_dispose_mapping(port.irq); |
229 | return ret; | 225 | return ret; |
230 | } | 226 | } |
231 | 227 | ||
232 | /* | 228 | /* |
233 | * Release a line | 229 | * Release a line |
234 | */ | 230 | */ |
235 | static int of_platform_serial_remove(struct platform_device *ofdev) | 231 | static int of_platform_serial_remove(struct platform_device *ofdev) |
236 | { | 232 | { |
237 | struct of_serial_info *info = platform_get_drvdata(ofdev); | 233 | struct of_serial_info *info = platform_get_drvdata(ofdev); |
238 | switch (info->type) { | 234 | switch (info->type) { |
239 | #ifdef CONFIG_SERIAL_8250 | 235 | #ifdef CONFIG_SERIAL_8250 |
240 | case PORT_8250 ... PORT_MAX_8250: | 236 | case PORT_8250 ... PORT_MAX_8250: |
241 | serial8250_unregister_port(info->line); | 237 | serial8250_unregister_port(info->line); |
242 | break; | 238 | break; |
243 | #endif | 239 | #endif |
244 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL | 240 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL |
245 | case PORT_NWPSERIAL: | 241 | case PORT_NWPSERIAL: |
246 | nwpserial_unregister_port(info->line); | 242 | nwpserial_unregister_port(info->line); |
247 | break; | 243 | break; |
248 | #endif | 244 | #endif |
249 | default: | 245 | default: |
250 | /* need to add code for these */ | 246 | /* need to add code for these */ |
251 | break; | 247 | break; |
252 | } | 248 | } |
253 | 249 | ||
254 | if (info->clk) | 250 | if (info->clk) |
255 | clk_disable_unprepare(info->clk); | 251 | clk_disable_unprepare(info->clk); |
256 | kfree(info); | 252 | kfree(info); |
257 | return 0; | 253 | return 0; |
258 | } | 254 | } |
259 | 255 | ||
260 | #ifdef CONFIG_PM_SLEEP | 256 | #ifdef CONFIG_PM_SLEEP |
261 | #ifdef CONFIG_SERIAL_8250 | 257 | #ifdef CONFIG_SERIAL_8250 |
262 | static void of_serial_suspend_8250(struct of_serial_info *info) | 258 | static void of_serial_suspend_8250(struct of_serial_info *info) |
263 | { | 259 | { |
264 | struct uart_8250_port *port8250 = serial8250_get_port(info->line); | 260 | struct uart_8250_port *port8250 = serial8250_get_port(info->line); |
265 | struct uart_port *port = &port8250->port; | 261 | struct uart_port *port = &port8250->port; |
266 | 262 | ||
267 | serial8250_suspend_port(info->line); | 263 | serial8250_suspend_port(info->line); |
268 | if (info->clk && (!uart_console(port) || console_suspend_enabled)) | 264 | if (info->clk && (!uart_console(port) || console_suspend_enabled)) |
269 | clk_disable_unprepare(info->clk); | 265 | clk_disable_unprepare(info->clk); |
270 | } | 266 | } |
271 | 267 | ||
272 | static void of_serial_resume_8250(struct of_serial_info *info) | 268 | static void of_serial_resume_8250(struct of_serial_info *info) |
273 | { | 269 | { |
274 | struct uart_8250_port *port8250 = serial8250_get_port(info->line); | 270 | struct uart_8250_port *port8250 = serial8250_get_port(info->line); |
275 | struct uart_port *port = &port8250->port; | 271 | struct uart_port *port = &port8250->port; |
276 | 272 | ||
277 | if (info->clk && (!uart_console(port) || console_suspend_enabled)) | 273 | if (info->clk && (!uart_console(port) || console_suspend_enabled)) |
278 | clk_prepare_enable(info->clk); | 274 | clk_prepare_enable(info->clk); |
279 | 275 | ||
280 | serial8250_resume_port(info->line); | 276 | serial8250_resume_port(info->line); |
281 | } | 277 | } |
282 | #else | 278 | #else |
283 | static inline void of_serial_suspend_8250(struct of_serial_info *info) | 279 | static inline void of_serial_suspend_8250(struct of_serial_info *info) |
284 | { | 280 | { |
285 | } | 281 | } |
286 | 282 | ||
287 | static inline void of_serial_resume_8250(struct of_serial_info *info) | 283 | static inline void of_serial_resume_8250(struct of_serial_info *info) |
288 | { | 284 | { |
289 | } | 285 | } |
290 | #endif | 286 | #endif |
291 | 287 | ||
292 | static int of_serial_suspend(struct device *dev) | 288 | static int of_serial_suspend(struct device *dev) |
293 | { | 289 | { |
294 | struct of_serial_info *info = dev_get_drvdata(dev); | 290 | struct of_serial_info *info = dev_get_drvdata(dev); |
295 | 291 | ||
296 | switch (info->type) { | 292 | switch (info->type) { |
297 | case PORT_8250 ... PORT_MAX_8250: | 293 | case PORT_8250 ... PORT_MAX_8250: |
298 | of_serial_suspend_8250(info); | 294 | of_serial_suspend_8250(info); |
299 | break; | 295 | break; |
300 | default: | 296 | default: |
301 | break; | 297 | break; |
302 | } | 298 | } |
303 | 299 | ||
304 | return 0; | 300 | return 0; |
305 | } | 301 | } |
306 | 302 | ||
307 | static int of_serial_resume(struct device *dev) | 303 | static int of_serial_resume(struct device *dev) |
308 | { | 304 | { |
309 | struct of_serial_info *info = dev_get_drvdata(dev); | 305 | struct of_serial_info *info = dev_get_drvdata(dev); |
310 | 306 | ||
311 | switch (info->type) { | 307 | switch (info->type) { |
312 | case PORT_8250 ... PORT_MAX_8250: | 308 | case PORT_8250 ... PORT_MAX_8250: |
313 | of_serial_resume_8250(info); | 309 | of_serial_resume_8250(info); |
314 | break; | 310 | break; |
315 | default: | 311 | default: |
316 | break; | 312 | break; |
317 | } | 313 | } |
318 | 314 | ||
319 | return 0; | 315 | return 0; |
320 | } | 316 | } |
321 | #endif | 317 | #endif |
322 | static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume); | 318 | static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume); |
323 | 319 | ||
324 | /* | 320 | /* |
325 | * A few common types, add more as needed. | 321 | * A few common types, add more as needed. |
326 | */ | 322 | */ |
327 | static struct of_device_id of_platform_serial_table[] = { | 323 | static struct of_device_id of_platform_serial_table[] = { |
328 | { .compatible = "ns8250", .data = (void *)PORT_8250, }, | 324 | { .compatible = "ns8250", .data = (void *)PORT_8250, }, |
329 | { .compatible = "ns16450", .data = (void *)PORT_16450, }, | 325 | { .compatible = "ns16450", .data = (void *)PORT_16450, }, |
330 | { .compatible = "ns16550a", .data = (void *)PORT_16550A, }, | 326 | { .compatible = "ns16550a", .data = (void *)PORT_16550A, }, |
331 | { .compatible = "ns16550", .data = (void *)PORT_16550, }, | 327 | { .compatible = "ns16550", .data = (void *)PORT_16550, }, |
332 | { .compatible = "ns16750", .data = (void *)PORT_16750, }, | 328 | { .compatible = "ns16750", .data = (void *)PORT_16750, }, |
333 | { .compatible = "ns16850", .data = (void *)PORT_16850, }, | 329 | { .compatible = "ns16850", .data = (void *)PORT_16850, }, |
334 | { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, | 330 | { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, |
335 | { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, | 331 | { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, |
336 | { .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, }, | 332 | { .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, }, |
337 | { .compatible = "altr,16550-FIFO32", | 333 | { .compatible = "altr,16550-FIFO32", |
338 | .data = (void *)PORT_ALTR_16550_F32, }, | 334 | .data = (void *)PORT_ALTR_16550_F32, }, |
339 | { .compatible = "altr,16550-FIFO64", | 335 | { .compatible = "altr,16550-FIFO64", |
340 | .data = (void *)PORT_ALTR_16550_F64, }, | 336 | .data = (void *)PORT_ALTR_16550_F64, }, |
341 | { .compatible = "altr,16550-FIFO128", | 337 | { .compatible = "altr,16550-FIFO128", |
342 | .data = (void *)PORT_ALTR_16550_F128, }, | 338 | .data = (void *)PORT_ALTR_16550_F128, }, |
343 | { .compatible = "mrvl,mmp-uart", | 339 | { .compatible = "mrvl,mmp-uart", |
344 | .data = (void *)PORT_XSCALE, }, | 340 | .data = (void *)PORT_XSCALE, }, |
345 | { .compatible = "mrvl,pxa-uart", | 341 | { .compatible = "mrvl,pxa-uart", |
346 | .data = (void *)PORT_XSCALE, }, | 342 | .data = (void *)PORT_XSCALE, }, |
347 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL | 343 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL |
348 | { .compatible = "ibm,qpace-nwp-serial", | 344 | { .compatible = "ibm,qpace-nwp-serial", |
349 | .data = (void *)PORT_NWPSERIAL, }, | 345 | .data = (void *)PORT_NWPSERIAL, }, |
350 | #endif | 346 | #endif |
351 | { .type = "serial", .data = (void *)PORT_UNKNOWN, }, | 347 | { .type = "serial", .data = (void *)PORT_UNKNOWN, }, |
352 | { /* end of list */ }, | 348 | { /* end of list */ }, |
353 | }; | 349 | }; |
354 | 350 | ||
355 | static struct platform_driver of_platform_serial_driver = { | 351 | static struct platform_driver of_platform_serial_driver = { |
356 | .driver = { | 352 | .driver = { |
357 | .name = "of_serial", | 353 | .name = "of_serial", |
358 | .of_match_table = of_platform_serial_table, | 354 | .of_match_table = of_platform_serial_table, |
359 | }, | 355 | }, |
360 | .probe = of_platform_serial_probe, | 356 | .probe = of_platform_serial_probe, |
361 | .remove = of_platform_serial_remove, | 357 | .remove = of_platform_serial_remove, |
362 | }; | 358 | }; |
363 | 359 | ||
364 | module_platform_driver(of_platform_serial_driver); | 360 | module_platform_driver(of_platform_serial_driver); |
365 | 361 | ||
366 | MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>"); | 362 | MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>"); |
367 | MODULE_LICENSE("GPL"); | 363 | MODULE_LICENSE("GPL"); |
368 | MODULE_DESCRIPTION("Serial Port driver for Open Firmware platform devices"); | 364 | MODULE_DESCRIPTION("Serial Port driver for Open Firmware platform devices"); |
369 | 365 |
drivers/tty/serial/sprd_serial.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2012-2015 Spreadtrum Communications Inc. | 2 | * Copyright (C) 2012-2015 Spreadtrum Communications Inc. |
3 | * | 3 | * |
4 | * This software is licensed under the terms of the GNU General Public | 4 | * This software is licensed under the terms of the GNU General Public |
5 | * License version 2, as published by the Free Software Foundation, and | 5 | * License version 2, as published by the Free Software Foundation, and |
6 | * may be copied, distributed, and modified under those terms. | 6 | * may be copied, distributed, and modified under those terms. |
7 | * | 7 | * |
8 | * This program is distributed in the hope that it will be useful, | 8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. | 11 | * GNU General Public License for more details. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #if defined(CONFIG_SERIAL_SPRD_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 14 | #if defined(CONFIG_SERIAL_SPRD_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
15 | #define SUPPORT_SYSRQ | 15 | #define SUPPORT_SYSRQ |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/console.h> | 19 | #include <linux/console.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/of.h> | 25 | #include <linux/of.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/serial_core.h> | 27 | #include <linux/serial_core.h> |
28 | #include <linux/serial.h> | 28 | #include <linux/serial.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/tty.h> | 30 | #include <linux/tty.h> |
31 | #include <linux/tty_flip.h> | 31 | #include <linux/tty_flip.h> |
32 | 32 | ||
33 | /* device name */ | 33 | /* device name */ |
34 | #define UART_NR_MAX 8 | 34 | #define UART_NR_MAX 8 |
35 | #define SPRD_TTY_NAME "ttyS" | 35 | #define SPRD_TTY_NAME "ttyS" |
36 | #define SPRD_FIFO_SIZE 128 | 36 | #define SPRD_FIFO_SIZE 128 |
37 | #define SPRD_DEF_RATE 26000000 | 37 | #define SPRD_DEF_RATE 26000000 |
38 | #define SPRD_BAUD_IO_LIMIT 3000000 | 38 | #define SPRD_BAUD_IO_LIMIT 3000000 |
39 | #define SPRD_TIMEOUT 256 | 39 | #define SPRD_TIMEOUT 256 |
40 | 40 | ||
41 | /* the offset of serial registers and BITs for them */ | 41 | /* the offset of serial registers and BITs for them */ |
42 | /* data registers */ | 42 | /* data registers */ |
43 | #define SPRD_TXD 0x0000 | 43 | #define SPRD_TXD 0x0000 |
44 | #define SPRD_RXD 0x0004 | 44 | #define SPRD_RXD 0x0004 |
45 | 45 | ||
46 | /* line status register and its BITs */ | 46 | /* line status register and its BITs */ |
47 | #define SPRD_LSR 0x0008 | 47 | #define SPRD_LSR 0x0008 |
48 | #define SPRD_LSR_OE BIT(4) | 48 | #define SPRD_LSR_OE BIT(4) |
49 | #define SPRD_LSR_FE BIT(3) | 49 | #define SPRD_LSR_FE BIT(3) |
50 | #define SPRD_LSR_PE BIT(2) | 50 | #define SPRD_LSR_PE BIT(2) |
51 | #define SPRD_LSR_BI BIT(7) | 51 | #define SPRD_LSR_BI BIT(7) |
52 | #define SPRD_LSR_TX_OVER BIT(15) | 52 | #define SPRD_LSR_TX_OVER BIT(15) |
53 | 53 | ||
54 | /* data number in TX and RX fifo */ | 54 | /* data number in TX and RX fifo */ |
55 | #define SPRD_STS1 0x000C | 55 | #define SPRD_STS1 0x000C |
56 | 56 | ||
57 | /* interrupt enable register and its BITs */ | 57 | /* interrupt enable register and its BITs */ |
58 | #define SPRD_IEN 0x0010 | 58 | #define SPRD_IEN 0x0010 |
59 | #define SPRD_IEN_RX_FULL BIT(0) | 59 | #define SPRD_IEN_RX_FULL BIT(0) |
60 | #define SPRD_IEN_TX_EMPTY BIT(1) | 60 | #define SPRD_IEN_TX_EMPTY BIT(1) |
61 | #define SPRD_IEN_BREAK_DETECT BIT(7) | 61 | #define SPRD_IEN_BREAK_DETECT BIT(7) |
62 | #define SPRD_IEN_TIMEOUT BIT(13) | 62 | #define SPRD_IEN_TIMEOUT BIT(13) |
63 | 63 | ||
64 | /* interrupt clear register */ | 64 | /* interrupt clear register */ |
65 | #define SPRD_ICLR 0x0014 | 65 | #define SPRD_ICLR 0x0014 |
66 | 66 | ||
67 | /* line control register */ | 67 | /* line control register */ |
68 | #define SPRD_LCR 0x0018 | 68 | #define SPRD_LCR 0x0018 |
69 | #define SPRD_LCR_STOP_1BIT 0x10 | 69 | #define SPRD_LCR_STOP_1BIT 0x10 |
70 | #define SPRD_LCR_STOP_2BIT 0x30 | 70 | #define SPRD_LCR_STOP_2BIT 0x30 |
71 | #define SPRD_LCR_DATA_LEN (BIT(2) | BIT(3)) | 71 | #define SPRD_LCR_DATA_LEN (BIT(2) | BIT(3)) |
72 | #define SPRD_LCR_DATA_LEN5 0x0 | 72 | #define SPRD_LCR_DATA_LEN5 0x0 |
73 | #define SPRD_LCR_DATA_LEN6 0x4 | 73 | #define SPRD_LCR_DATA_LEN6 0x4 |
74 | #define SPRD_LCR_DATA_LEN7 0x8 | 74 | #define SPRD_LCR_DATA_LEN7 0x8 |
75 | #define SPRD_LCR_DATA_LEN8 0xc | 75 | #define SPRD_LCR_DATA_LEN8 0xc |
76 | #define SPRD_LCR_PARITY (BIT(0) | BIT(1)) | 76 | #define SPRD_LCR_PARITY (BIT(0) | BIT(1)) |
77 | #define SPRD_LCR_PARITY_EN 0x2 | 77 | #define SPRD_LCR_PARITY_EN 0x2 |
78 | #define SPRD_LCR_EVEN_PAR 0x0 | 78 | #define SPRD_LCR_EVEN_PAR 0x0 |
79 | #define SPRD_LCR_ODD_PAR 0x1 | 79 | #define SPRD_LCR_ODD_PAR 0x1 |
80 | 80 | ||
81 | /* control register 1 */ | 81 | /* control register 1 */ |
82 | #define SPRD_CTL1 0x001C | 82 | #define SPRD_CTL1 0x001C |
83 | #define RX_HW_FLOW_CTL_THLD BIT(6) | 83 | #define RX_HW_FLOW_CTL_THLD BIT(6) |
84 | #define RX_HW_FLOW_CTL_EN BIT(7) | 84 | #define RX_HW_FLOW_CTL_EN BIT(7) |
85 | #define TX_HW_FLOW_CTL_EN BIT(8) | 85 | #define TX_HW_FLOW_CTL_EN BIT(8) |
86 | #define RX_TOUT_THLD_DEF 0x3E00 | 86 | #define RX_TOUT_THLD_DEF 0x3E00 |
87 | #define RX_HFC_THLD_DEF 0x40 | 87 | #define RX_HFC_THLD_DEF 0x40 |
88 | 88 | ||
89 | /* fifo threshold register */ | 89 | /* fifo threshold register */ |
90 | #define SPRD_CTL2 0x0020 | 90 | #define SPRD_CTL2 0x0020 |
91 | #define THLD_TX_EMPTY 0x40 | 91 | #define THLD_TX_EMPTY 0x40 |
92 | #define THLD_RX_FULL 0x40 | 92 | #define THLD_RX_FULL 0x40 |
93 | 93 | ||
94 | /* config baud rate register */ | 94 | /* config baud rate register */ |
95 | #define SPRD_CLKD0 0x0024 | 95 | #define SPRD_CLKD0 0x0024 |
96 | #define SPRD_CLKD1 0x0028 | 96 | #define SPRD_CLKD1 0x0028 |
97 | 97 | ||
98 | /* interrupt mask status register */ | 98 | /* interrupt mask status register */ |
99 | #define SPRD_IMSR 0x002C | 99 | #define SPRD_IMSR 0x002C |
100 | #define SPRD_IMSR_RX_FIFO_FULL BIT(0) | 100 | #define SPRD_IMSR_RX_FIFO_FULL BIT(0) |
101 | #define SPRD_IMSR_TX_FIFO_EMPTY BIT(1) | 101 | #define SPRD_IMSR_TX_FIFO_EMPTY BIT(1) |
102 | #define SPRD_IMSR_BREAK_DETECT BIT(7) | 102 | #define SPRD_IMSR_BREAK_DETECT BIT(7) |
103 | #define SPRD_IMSR_TIMEOUT BIT(13) | 103 | #define SPRD_IMSR_TIMEOUT BIT(13) |
104 | 104 | ||
105 | struct reg_backup { | 105 | struct reg_backup { |
106 | u32 ien; | 106 | u32 ien; |
107 | u32 ctrl0; | 107 | u32 ctrl0; |
108 | u32 ctrl1; | 108 | u32 ctrl1; |
109 | u32 ctrl2; | 109 | u32 ctrl2; |
110 | u32 clkd0; | 110 | u32 clkd0; |
111 | u32 clkd1; | 111 | u32 clkd1; |
112 | u32 dspwait; | 112 | u32 dspwait; |
113 | }; | 113 | }; |
114 | 114 | ||
115 | struct sprd_uart_port { | 115 | struct sprd_uart_port { |
116 | struct uart_port port; | 116 | struct uart_port port; |
117 | struct reg_backup reg_bak; | 117 | struct reg_backup reg_bak; |
118 | char name[16]; | 118 | char name[16]; |
119 | }; | 119 | }; |
120 | 120 | ||
121 | static struct sprd_uart_port *sprd_port[UART_NR_MAX]; | 121 | static struct sprd_uart_port *sprd_port[UART_NR_MAX]; |
122 | static int sprd_ports_num; | 122 | static int sprd_ports_num; |
123 | 123 | ||
124 | static inline unsigned int serial_in(struct uart_port *port, int offset) | 124 | static inline unsigned int serial_in(struct uart_port *port, int offset) |
125 | { | 125 | { |
126 | return readl_relaxed(port->membase + offset); | 126 | return readl_relaxed(port->membase + offset); |
127 | } | 127 | } |
128 | 128 | ||
129 | static inline void serial_out(struct uart_port *port, int offset, int value) | 129 | static inline void serial_out(struct uart_port *port, int offset, int value) |
130 | { | 130 | { |
131 | writel_relaxed(value, port->membase + offset); | 131 | writel_relaxed(value, port->membase + offset); |
132 | } | 132 | } |
133 | 133 | ||
134 | static unsigned int sprd_tx_empty(struct uart_port *port) | 134 | static unsigned int sprd_tx_empty(struct uart_port *port) |
135 | { | 135 | { |
136 | if (serial_in(port, SPRD_STS1) & 0xff00) | 136 | if (serial_in(port, SPRD_STS1) & 0xff00) |
137 | return 0; | 137 | return 0; |
138 | else | 138 | else |
139 | return TIOCSER_TEMT; | 139 | return TIOCSER_TEMT; |
140 | } | 140 | } |
141 | 141 | ||
142 | static unsigned int sprd_get_mctrl(struct uart_port *port) | 142 | static unsigned int sprd_get_mctrl(struct uart_port *port) |
143 | { | 143 | { |
144 | return TIOCM_DSR | TIOCM_CTS; | 144 | return TIOCM_DSR | TIOCM_CTS; |
145 | } | 145 | } |
146 | 146 | ||
147 | static void sprd_set_mctrl(struct uart_port *port, unsigned int mctrl) | 147 | static void sprd_set_mctrl(struct uart_port *port, unsigned int mctrl) |
148 | { | 148 | { |
149 | /* nothing to do */ | 149 | /* nothing to do */ |
150 | } | 150 | } |
151 | 151 | ||
152 | static void sprd_stop_tx(struct uart_port *port) | 152 | static void sprd_stop_tx(struct uart_port *port) |
153 | { | 153 | { |
154 | unsigned int ien, iclr; | 154 | unsigned int ien, iclr; |
155 | 155 | ||
156 | iclr = serial_in(port, SPRD_ICLR); | 156 | iclr = serial_in(port, SPRD_ICLR); |
157 | ien = serial_in(port, SPRD_IEN); | 157 | ien = serial_in(port, SPRD_IEN); |
158 | 158 | ||
159 | iclr |= SPRD_IEN_TX_EMPTY; | 159 | iclr |= SPRD_IEN_TX_EMPTY; |
160 | ien &= ~SPRD_IEN_TX_EMPTY; | 160 | ien &= ~SPRD_IEN_TX_EMPTY; |
161 | 161 | ||
162 | serial_out(port, SPRD_ICLR, iclr); | 162 | serial_out(port, SPRD_ICLR, iclr); |
163 | serial_out(port, SPRD_IEN, ien); | 163 | serial_out(port, SPRD_IEN, ien); |
164 | } | 164 | } |
165 | 165 | ||
166 | static void sprd_start_tx(struct uart_port *port) | 166 | static void sprd_start_tx(struct uart_port *port) |
167 | { | 167 | { |
168 | unsigned int ien; | 168 | unsigned int ien; |
169 | 169 | ||
170 | ien = serial_in(port, SPRD_IEN); | 170 | ien = serial_in(port, SPRD_IEN); |
171 | if (!(ien & SPRD_IEN_TX_EMPTY)) { | 171 | if (!(ien & SPRD_IEN_TX_EMPTY)) { |
172 | ien |= SPRD_IEN_TX_EMPTY; | 172 | ien |= SPRD_IEN_TX_EMPTY; |
173 | serial_out(port, SPRD_IEN, ien); | 173 | serial_out(port, SPRD_IEN, ien); |
174 | } | 174 | } |
175 | } | 175 | } |
176 | 176 | ||
177 | static void sprd_stop_rx(struct uart_port *port) | 177 | static void sprd_stop_rx(struct uart_port *port) |
178 | { | 178 | { |
179 | unsigned int ien, iclr; | 179 | unsigned int ien, iclr; |
180 | 180 | ||
181 | iclr = serial_in(port, SPRD_ICLR); | 181 | iclr = serial_in(port, SPRD_ICLR); |
182 | ien = serial_in(port, SPRD_IEN); | 182 | ien = serial_in(port, SPRD_IEN); |
183 | 183 | ||
184 | ien &= ~(SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT); | 184 | ien &= ~(SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT); |
185 | iclr |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT; | 185 | iclr |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT; |
186 | 186 | ||
187 | serial_out(port, SPRD_IEN, ien); | 187 | serial_out(port, SPRD_IEN, ien); |
188 | serial_out(port, SPRD_ICLR, iclr); | 188 | serial_out(port, SPRD_ICLR, iclr); |
189 | } | 189 | } |
190 | 190 | ||
191 | /* The Sprd serial does not support this function. */ | 191 | /* The Sprd serial does not support this function. */ |
192 | static void sprd_break_ctl(struct uart_port *port, int break_state) | 192 | static void sprd_break_ctl(struct uart_port *port, int break_state) |
193 | { | 193 | { |
194 | /* nothing to do */ | 194 | /* nothing to do */ |
195 | } | 195 | } |
196 | 196 | ||
197 | static int handle_lsr_errors(struct uart_port *port, | 197 | static int handle_lsr_errors(struct uart_port *port, |
198 | unsigned int *flag, | 198 | unsigned int *flag, |
199 | unsigned int *lsr) | 199 | unsigned int *lsr) |
200 | { | 200 | { |
201 | int ret = 0; | 201 | int ret = 0; |
202 | 202 | ||
203 | /* statistics */ | 203 | /* statistics */ |
204 | if (*lsr & SPRD_LSR_BI) { | 204 | if (*lsr & SPRD_LSR_BI) { |
205 | *lsr &= ~(SPRD_LSR_FE | SPRD_LSR_PE); | 205 | *lsr &= ~(SPRD_LSR_FE | SPRD_LSR_PE); |
206 | port->icount.brk++; | 206 | port->icount.brk++; |
207 | ret = uart_handle_break(port); | 207 | ret = uart_handle_break(port); |
208 | if (ret) | 208 | if (ret) |
209 | return ret; | 209 | return ret; |
210 | } else if (*lsr & SPRD_LSR_PE) | 210 | } else if (*lsr & SPRD_LSR_PE) |
211 | port->icount.parity++; | 211 | port->icount.parity++; |
212 | else if (*lsr & SPRD_LSR_FE) | 212 | else if (*lsr & SPRD_LSR_FE) |
213 | port->icount.frame++; | 213 | port->icount.frame++; |
214 | if (*lsr & SPRD_LSR_OE) | 214 | if (*lsr & SPRD_LSR_OE) |
215 | port->icount.overrun++; | 215 | port->icount.overrun++; |
216 | 216 | ||
217 | /* mask off conditions which should be ignored */ | 217 | /* mask off conditions which should be ignored */ |
218 | *lsr &= port->read_status_mask; | 218 | *lsr &= port->read_status_mask; |
219 | if (*lsr & SPRD_LSR_BI) | 219 | if (*lsr & SPRD_LSR_BI) |
220 | *flag = TTY_BREAK; | 220 | *flag = TTY_BREAK; |
221 | else if (*lsr & SPRD_LSR_PE) | 221 | else if (*lsr & SPRD_LSR_PE) |
222 | *flag = TTY_PARITY; | 222 | *flag = TTY_PARITY; |
223 | else if (*lsr & SPRD_LSR_FE) | 223 | else if (*lsr & SPRD_LSR_FE) |
224 | *flag = TTY_FRAME; | 224 | *flag = TTY_FRAME; |
225 | 225 | ||
226 | return ret; | 226 | return ret; |
227 | } | 227 | } |
228 | 228 | ||
229 | static inline void sprd_rx(struct uart_port *port) | 229 | static inline void sprd_rx(struct uart_port *port) |
230 | { | 230 | { |
231 | struct tty_port *tty = &port->state->port; | 231 | struct tty_port *tty = &port->state->port; |
232 | unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT; | 232 | unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT; |
233 | 233 | ||
234 | while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) { | 234 | while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) { |
235 | lsr = serial_in(port, SPRD_LSR); | 235 | lsr = serial_in(port, SPRD_LSR); |
236 | ch = serial_in(port, SPRD_RXD); | 236 | ch = serial_in(port, SPRD_RXD); |
237 | flag = TTY_NORMAL; | 237 | flag = TTY_NORMAL; |
238 | port->icount.rx++; | 238 | port->icount.rx++; |
239 | 239 | ||
240 | if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE | | 240 | if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE | |
241 | SPRD_LSR_FE | SPRD_LSR_OE)) | 241 | SPRD_LSR_FE | SPRD_LSR_OE)) |
242 | if (handle_lsr_errors(port, &lsr, &flag)) | 242 | if (handle_lsr_errors(port, &lsr, &flag)) |
243 | continue; | 243 | continue; |
244 | if (uart_handle_sysrq_char(port, ch)) | 244 | if (uart_handle_sysrq_char(port, ch)) |
245 | continue; | 245 | continue; |
246 | 246 | ||
247 | uart_insert_char(port, lsr, SPRD_LSR_OE, ch, flag); | 247 | uart_insert_char(port, lsr, SPRD_LSR_OE, ch, flag); |
248 | } | 248 | } |
249 | 249 | ||
250 | tty_flip_buffer_push(tty); | 250 | tty_flip_buffer_push(tty); |
251 | } | 251 | } |
252 | 252 | ||
253 | static inline void sprd_tx(struct uart_port *port) | 253 | static inline void sprd_tx(struct uart_port *port) |
254 | { | 254 | { |
255 | struct circ_buf *xmit = &port->state->xmit; | 255 | struct circ_buf *xmit = &port->state->xmit; |
256 | int count; | 256 | int count; |
257 | 257 | ||
258 | if (port->x_char) { | 258 | if (port->x_char) { |
259 | serial_out(port, SPRD_TXD, port->x_char); | 259 | serial_out(port, SPRD_TXD, port->x_char); |
260 | port->icount.tx++; | 260 | port->icount.tx++; |
261 | port->x_char = 0; | 261 | port->x_char = 0; |
262 | return; | 262 | return; |
263 | } | 263 | } |
264 | 264 | ||
265 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | 265 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { |
266 | sprd_stop_tx(port); | 266 | sprd_stop_tx(port); |
267 | return; | 267 | return; |
268 | } | 268 | } |
269 | 269 | ||
270 | count = THLD_TX_EMPTY; | 270 | count = THLD_TX_EMPTY; |
271 | do { | 271 | do { |
272 | serial_out(port, SPRD_TXD, xmit->buf[xmit->tail]); | 272 | serial_out(port, SPRD_TXD, xmit->buf[xmit->tail]); |
273 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 273 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
274 | port->icount.tx++; | 274 | port->icount.tx++; |
275 | if (uart_circ_empty(xmit)) | 275 | if (uart_circ_empty(xmit)) |
276 | break; | 276 | break; |
277 | } while (--count > 0); | 277 | } while (--count > 0); |
278 | 278 | ||
279 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 279 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
280 | uart_write_wakeup(port); | 280 | uart_write_wakeup(port); |
281 | 281 | ||
282 | if (uart_circ_empty(xmit)) | 282 | if (uart_circ_empty(xmit)) |
283 | sprd_stop_tx(port); | 283 | sprd_stop_tx(port); |
284 | } | 284 | } |
285 | 285 | ||
286 | /* this handles the interrupt from one port */ | 286 | /* this handles the interrupt from one port */ |
287 | static irqreturn_t sprd_handle_irq(int irq, void *dev_id) | 287 | static irqreturn_t sprd_handle_irq(int irq, void *dev_id) |
288 | { | 288 | { |
289 | struct uart_port *port = dev_id; | 289 | struct uart_port *port = dev_id; |
290 | unsigned int ims; | 290 | unsigned int ims; |
291 | 291 | ||
292 | spin_lock(&port->lock); | 292 | spin_lock(&port->lock); |
293 | 293 | ||
294 | ims = serial_in(port, SPRD_IMSR); | 294 | ims = serial_in(port, SPRD_IMSR); |
295 | 295 | ||
296 | if (!ims) | 296 | if (!ims) { |
297 | spin_unlock(&port->lock); | ||
297 | return IRQ_NONE; | 298 | return IRQ_NONE; |
299 | } | ||
298 | 300 | ||
299 | serial_out(port, SPRD_ICLR, ~0); | 301 | serial_out(port, SPRD_ICLR, ~0); |
300 | 302 | ||
301 | if (ims & (SPRD_IMSR_RX_FIFO_FULL | | 303 | if (ims & (SPRD_IMSR_RX_FIFO_FULL | |
302 | SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) | 304 | SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) |
303 | sprd_rx(port); | 305 | sprd_rx(port); |
304 | 306 | ||
305 | if (ims & SPRD_IMSR_TX_FIFO_EMPTY) | 307 | if (ims & SPRD_IMSR_TX_FIFO_EMPTY) |
306 | sprd_tx(port); | 308 | sprd_tx(port); |
307 | 309 | ||
308 | spin_unlock(&port->lock); | 310 | spin_unlock(&port->lock); |
309 | 311 | ||
310 | return IRQ_HANDLED; | 312 | return IRQ_HANDLED; |
311 | } | 313 | } |
312 | 314 | ||
313 | static int sprd_startup(struct uart_port *port) | 315 | static int sprd_startup(struct uart_port *port) |
314 | { | 316 | { |
315 | int ret = 0; | 317 | int ret = 0; |
316 | unsigned int ien, fc; | 318 | unsigned int ien, fc; |
317 | unsigned int timeout; | 319 | unsigned int timeout; |
318 | struct sprd_uart_port *sp; | 320 | struct sprd_uart_port *sp; |
319 | unsigned long flags; | 321 | unsigned long flags; |
320 | 322 | ||
321 | serial_out(port, SPRD_CTL2, ((THLD_TX_EMPTY << 8) | THLD_RX_FULL)); | 323 | serial_out(port, SPRD_CTL2, ((THLD_TX_EMPTY << 8) | THLD_RX_FULL)); |
322 | 324 | ||
323 | /* clear rx fifo */ | 325 | /* clear rx fifo */ |
324 | timeout = SPRD_TIMEOUT; | 326 | timeout = SPRD_TIMEOUT; |
325 | while (timeout-- && serial_in(port, SPRD_STS1) & 0x00ff) | 327 | while (timeout-- && serial_in(port, SPRD_STS1) & 0x00ff) |
326 | serial_in(port, SPRD_RXD); | 328 | serial_in(port, SPRD_RXD); |
327 | 329 | ||
328 | /* clear tx fifo */ | 330 | /* clear tx fifo */ |
329 | timeout = SPRD_TIMEOUT; | 331 | timeout = SPRD_TIMEOUT; |
330 | while (timeout-- && serial_in(port, SPRD_STS1) & 0xff00) | 332 | while (timeout-- && serial_in(port, SPRD_STS1) & 0xff00) |
331 | cpu_relax(); | 333 | cpu_relax(); |
332 | 334 | ||
333 | /* clear interrupt */ | 335 | /* clear interrupt */ |
334 | serial_out(port, SPRD_IEN, 0); | 336 | serial_out(port, SPRD_IEN, 0); |
335 | serial_out(port, SPRD_ICLR, ~0); | 337 | serial_out(port, SPRD_ICLR, ~0); |
336 | 338 | ||
337 | /* allocate irq */ | 339 | /* allocate irq */ |
338 | sp = container_of(port, struct sprd_uart_port, port); | 340 | sp = container_of(port, struct sprd_uart_port, port); |
339 | snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line); | 341 | snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line); |
340 | ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq, | 342 | ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq, |
341 | IRQF_SHARED, sp->name, port); | 343 | IRQF_SHARED, sp->name, port); |
342 | if (ret) { | 344 | if (ret) { |
343 | dev_err(port->dev, "fail to request serial irq %d, ret=%d\n", | 345 | dev_err(port->dev, "fail to request serial irq %d, ret=%d\n", |
344 | port->irq, ret); | 346 | port->irq, ret); |
345 | return ret; | 347 | return ret; |
346 | } | 348 | } |
347 | fc = serial_in(port, SPRD_CTL1); | 349 | fc = serial_in(port, SPRD_CTL1); |
348 | fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; | 350 | fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; |
349 | serial_out(port, SPRD_CTL1, fc); | 351 | serial_out(port, SPRD_CTL1, fc); |
350 | 352 | ||
351 | /* enable interrupt */ | 353 | /* enable interrupt */ |
352 | spin_lock_irqsave(&port->lock, flags); | 354 | spin_lock_irqsave(&port->lock, flags); |
353 | ien = serial_in(port, SPRD_IEN); | 355 | ien = serial_in(port, SPRD_IEN); |
354 | ien |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT; | 356 | ien |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT; |
355 | serial_out(port, SPRD_IEN, ien); | 357 | serial_out(port, SPRD_IEN, ien); |
356 | spin_unlock_irqrestore(&port->lock, flags); | 358 | spin_unlock_irqrestore(&port->lock, flags); |
357 | 359 | ||
358 | return 0; | 360 | return 0; |
359 | } | 361 | } |
360 | 362 | ||
361 | static void sprd_shutdown(struct uart_port *port) | 363 | static void sprd_shutdown(struct uart_port *port) |
362 | { | 364 | { |
363 | serial_out(port, SPRD_IEN, 0); | 365 | serial_out(port, SPRD_IEN, 0); |
364 | serial_out(port, SPRD_ICLR, ~0); | 366 | serial_out(port, SPRD_ICLR, ~0); |
365 | devm_free_irq(port->dev, port->irq, port); | 367 | devm_free_irq(port->dev, port->irq, port); |
366 | } | 368 | } |
367 | 369 | ||
368 | static void sprd_set_termios(struct uart_port *port, | 370 | static void sprd_set_termios(struct uart_port *port, |
369 | struct ktermios *termios, | 371 | struct ktermios *termios, |
370 | struct ktermios *old) | 372 | struct ktermios *old) |
371 | { | 373 | { |
372 | unsigned int baud, quot; | 374 | unsigned int baud, quot; |
373 | unsigned int lcr = 0, fc; | 375 | unsigned int lcr = 0, fc; |
374 | unsigned long flags; | 376 | unsigned long flags; |
375 | 377 | ||
376 | /* ask the core to calculate the divisor for us */ | 378 | /* ask the core to calculate the divisor for us */ |
377 | baud = uart_get_baud_rate(port, termios, old, 0, SPRD_BAUD_IO_LIMIT); | 379 | baud = uart_get_baud_rate(port, termios, old, 0, SPRD_BAUD_IO_LIMIT); |
378 | 380 | ||
379 | quot = (unsigned int)((port->uartclk + baud / 2) / baud); | 381 | quot = (unsigned int)((port->uartclk + baud / 2) / baud); |
380 | 382 | ||
381 | /* set data length */ | 383 | /* set data length */ |
382 | switch (termios->c_cflag & CSIZE) { | 384 | switch (termios->c_cflag & CSIZE) { |
383 | case CS5: | 385 | case CS5: |
384 | lcr |= SPRD_LCR_DATA_LEN5; | 386 | lcr |= SPRD_LCR_DATA_LEN5; |
385 | break; | 387 | break; |
386 | case CS6: | 388 | case CS6: |
387 | lcr |= SPRD_LCR_DATA_LEN6; | 389 | lcr |= SPRD_LCR_DATA_LEN6; |
388 | break; | 390 | break; |
389 | case CS7: | 391 | case CS7: |
390 | lcr |= SPRD_LCR_DATA_LEN7; | 392 | lcr |= SPRD_LCR_DATA_LEN7; |
391 | break; | 393 | break; |
392 | case CS8: | 394 | case CS8: |
393 | default: | 395 | default: |
394 | lcr |= SPRD_LCR_DATA_LEN8; | 396 | lcr |= SPRD_LCR_DATA_LEN8; |
395 | break; | 397 | break; |
396 | } | 398 | } |
397 | 399 | ||
398 | /* calculate stop bits */ | 400 | /* calculate stop bits */ |
399 | lcr &= ~(SPRD_LCR_STOP_1BIT | SPRD_LCR_STOP_2BIT); | 401 | lcr &= ~(SPRD_LCR_STOP_1BIT | SPRD_LCR_STOP_2BIT); |
400 | if (termios->c_cflag & CSTOPB) | 402 | if (termios->c_cflag & CSTOPB) |
401 | lcr |= SPRD_LCR_STOP_2BIT; | 403 | lcr |= SPRD_LCR_STOP_2BIT; |
402 | else | 404 | else |
403 | lcr |= SPRD_LCR_STOP_1BIT; | 405 | lcr |= SPRD_LCR_STOP_1BIT; |
404 | 406 | ||
405 | /* calculate parity */ | 407 | /* calculate parity */ |
406 | lcr &= ~SPRD_LCR_PARITY; | 408 | lcr &= ~SPRD_LCR_PARITY; |
407 | termios->c_cflag &= ~CMSPAR; /* no support mark/space */ | 409 | termios->c_cflag &= ~CMSPAR; /* no support mark/space */ |
408 | if (termios->c_cflag & PARENB) { | 410 | if (termios->c_cflag & PARENB) { |
409 | lcr |= SPRD_LCR_PARITY_EN; | 411 | lcr |= SPRD_LCR_PARITY_EN; |
410 | if (termios->c_cflag & PARODD) | 412 | if (termios->c_cflag & PARODD) |
411 | lcr |= SPRD_LCR_ODD_PAR; | 413 | lcr |= SPRD_LCR_ODD_PAR; |
412 | else | 414 | else |
413 | lcr |= SPRD_LCR_EVEN_PAR; | 415 | lcr |= SPRD_LCR_EVEN_PAR; |
414 | } | 416 | } |
415 | 417 | ||
416 | spin_lock_irqsave(&port->lock, flags); | 418 | spin_lock_irqsave(&port->lock, flags); |
417 | 419 | ||
418 | /* update the per-port timeout */ | 420 | /* update the per-port timeout */ |
419 | uart_update_timeout(port, termios->c_cflag, baud); | 421 | uart_update_timeout(port, termios->c_cflag, baud); |
420 | 422 | ||
421 | port->read_status_mask = SPRD_LSR_OE; | 423 | port->read_status_mask = SPRD_LSR_OE; |
422 | if (termios->c_iflag & INPCK) | 424 | if (termios->c_iflag & INPCK) |
423 | port->read_status_mask |= SPRD_LSR_FE | SPRD_LSR_PE; | 425 | port->read_status_mask |= SPRD_LSR_FE | SPRD_LSR_PE; |
424 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) | 426 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) |
425 | port->read_status_mask |= SPRD_LSR_BI; | 427 | port->read_status_mask |= SPRD_LSR_BI; |
426 | 428 | ||
427 | /* characters to ignore */ | 429 | /* characters to ignore */ |
428 | port->ignore_status_mask = 0; | 430 | port->ignore_status_mask = 0; |
429 | if (termios->c_iflag & IGNPAR) | 431 | if (termios->c_iflag & IGNPAR) |
430 | port->ignore_status_mask |= SPRD_LSR_PE | SPRD_LSR_FE; | 432 | port->ignore_status_mask |= SPRD_LSR_PE | SPRD_LSR_FE; |
431 | if (termios->c_iflag & IGNBRK) { | 433 | if (termios->c_iflag & IGNBRK) { |
432 | port->ignore_status_mask |= SPRD_LSR_BI; | 434 | port->ignore_status_mask |= SPRD_LSR_BI; |
433 | /* | 435 | /* |
434 | * If we're ignoring parity and break indicators, | 436 | * If we're ignoring parity and break indicators, |
435 | * ignore overruns too (for real raw support). | 437 | * ignore overruns too (for real raw support). |
436 | */ | 438 | */ |
437 | if (termios->c_iflag & IGNPAR) | 439 | if (termios->c_iflag & IGNPAR) |
438 | port->ignore_status_mask |= SPRD_LSR_OE; | 440 | port->ignore_status_mask |= SPRD_LSR_OE; |
439 | } | 441 | } |
440 | 442 | ||
441 | /* flow control */ | 443 | /* flow control */ |
442 | fc = serial_in(port, SPRD_CTL1); | 444 | fc = serial_in(port, SPRD_CTL1); |
443 | fc &= ~(RX_HW_FLOW_CTL_THLD | RX_HW_FLOW_CTL_EN | TX_HW_FLOW_CTL_EN); | 445 | fc &= ~(RX_HW_FLOW_CTL_THLD | RX_HW_FLOW_CTL_EN | TX_HW_FLOW_CTL_EN); |
444 | if (termios->c_cflag & CRTSCTS) { | 446 | if (termios->c_cflag & CRTSCTS) { |
445 | fc |= RX_HW_FLOW_CTL_THLD; | 447 | fc |= RX_HW_FLOW_CTL_THLD; |
446 | fc |= RX_HW_FLOW_CTL_EN; | 448 | fc |= RX_HW_FLOW_CTL_EN; |
447 | fc |= TX_HW_FLOW_CTL_EN; | 449 | fc |= TX_HW_FLOW_CTL_EN; |
448 | } | 450 | } |
449 | 451 | ||
450 | /* clock divider bit0~bit15 */ | 452 | /* clock divider bit0~bit15 */ |
451 | serial_out(port, SPRD_CLKD0, quot & 0xffff); | 453 | serial_out(port, SPRD_CLKD0, quot & 0xffff); |
452 | 454 | ||
453 | /* clock divider bit16~bit20 */ | 455 | /* clock divider bit16~bit20 */ |
454 | serial_out(port, SPRD_CLKD1, (quot & 0x1f0000) >> 16); | 456 | serial_out(port, SPRD_CLKD1, (quot & 0x1f0000) >> 16); |
455 | serial_out(port, SPRD_LCR, lcr); | 457 | serial_out(port, SPRD_LCR, lcr); |
456 | fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; | 458 | fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; |
457 | serial_out(port, SPRD_CTL1, fc); | 459 | serial_out(port, SPRD_CTL1, fc); |
458 | 460 | ||
459 | spin_unlock_irqrestore(&port->lock, flags); | 461 | spin_unlock_irqrestore(&port->lock, flags); |
460 | 462 | ||
461 | /* Don't rewrite B0 */ | 463 | /* Don't rewrite B0 */ |
462 | if (tty_termios_baud_rate(termios)) | 464 | if (tty_termios_baud_rate(termios)) |
463 | tty_termios_encode_baud_rate(termios, baud, baud); | 465 | tty_termios_encode_baud_rate(termios, baud, baud); |
464 | } | 466 | } |
465 | 467 | ||
466 | static const char *sprd_type(struct uart_port *port) | 468 | static const char *sprd_type(struct uart_port *port) |
467 | { | 469 | { |
468 | return "SPX"; | 470 | return "SPX"; |
469 | } | 471 | } |
470 | 472 | ||
471 | static void sprd_release_port(struct uart_port *port) | 473 | static void sprd_release_port(struct uart_port *port) |
472 | { | 474 | { |
473 | /* nothing to do */ | 475 | /* nothing to do */ |
474 | } | 476 | } |
475 | 477 | ||
476 | static int sprd_request_port(struct uart_port *port) | 478 | static int sprd_request_port(struct uart_port *port) |
477 | { | 479 | { |
478 | return 0; | 480 | return 0; |
479 | } | 481 | } |
480 | 482 | ||
481 | static void sprd_config_port(struct uart_port *port, int flags) | 483 | static void sprd_config_port(struct uart_port *port, int flags) |
482 | { | 484 | { |
483 | if (flags & UART_CONFIG_TYPE) | 485 | if (flags & UART_CONFIG_TYPE) |
484 | port->type = PORT_SPRD; | 486 | port->type = PORT_SPRD; |
485 | } | 487 | } |
486 | 488 | ||
487 | static int sprd_verify_port(struct uart_port *port, | 489 | static int sprd_verify_port(struct uart_port *port, |
488 | struct serial_struct *ser) | 490 | struct serial_struct *ser) |
489 | { | 491 | { |
490 | if (ser->type != PORT_SPRD) | 492 | if (ser->type != PORT_SPRD) |
491 | return -EINVAL; | 493 | return -EINVAL; |
492 | if (port->irq != ser->irq) | 494 | if (port->irq != ser->irq) |
493 | return -EINVAL; | 495 | return -EINVAL; |
494 | return 0; | 496 | return 0; |
495 | } | 497 | } |
496 | 498 | ||
497 | static struct uart_ops serial_sprd_ops = { | 499 | static struct uart_ops serial_sprd_ops = { |
498 | .tx_empty = sprd_tx_empty, | 500 | .tx_empty = sprd_tx_empty, |
499 | .get_mctrl = sprd_get_mctrl, | 501 | .get_mctrl = sprd_get_mctrl, |
500 | .set_mctrl = sprd_set_mctrl, | 502 | .set_mctrl = sprd_set_mctrl, |
501 | .stop_tx = sprd_stop_tx, | 503 | .stop_tx = sprd_stop_tx, |
502 | .start_tx = sprd_start_tx, | 504 | .start_tx = sprd_start_tx, |
503 | .stop_rx = sprd_stop_rx, | 505 | .stop_rx = sprd_stop_rx, |
504 | .break_ctl = sprd_break_ctl, | 506 | .break_ctl = sprd_break_ctl, |
505 | .startup = sprd_startup, | 507 | .startup = sprd_startup, |
506 | .shutdown = sprd_shutdown, | 508 | .shutdown = sprd_shutdown, |
507 | .set_termios = sprd_set_termios, | 509 | .set_termios = sprd_set_termios, |
508 | .type = sprd_type, | 510 | .type = sprd_type, |
509 | .release_port = sprd_release_port, | 511 | .release_port = sprd_release_port, |
510 | .request_port = sprd_request_port, | 512 | .request_port = sprd_request_port, |
511 | .config_port = sprd_config_port, | 513 | .config_port = sprd_config_port, |
512 | .verify_port = sprd_verify_port, | 514 | .verify_port = sprd_verify_port, |
513 | }; | 515 | }; |
514 | 516 | ||
515 | #ifdef CONFIG_SERIAL_SPRD_CONSOLE | 517 | #ifdef CONFIG_SERIAL_SPRD_CONSOLE |
516 | static inline void wait_for_xmitr(struct uart_port *port) | 518 | static inline void wait_for_xmitr(struct uart_port *port) |
517 | { | 519 | { |
518 | unsigned int status, tmout = 10000; | 520 | unsigned int status, tmout = 10000; |
519 | 521 | ||
520 | /* wait up to 10ms for the character(s) to be sent */ | 522 | /* wait up to 10ms for the character(s) to be sent */ |
521 | do { | 523 | do { |
522 | status = serial_in(port, SPRD_STS1); | 524 | status = serial_in(port, SPRD_STS1); |
523 | if (--tmout == 0) | 525 | if (--tmout == 0) |
524 | break; | 526 | break; |
525 | udelay(1); | 527 | udelay(1); |
526 | } while (status & 0xff00); | 528 | } while (status & 0xff00); |
527 | } | 529 | } |
528 | 530 | ||
529 | static void sprd_console_putchar(struct uart_port *port, int ch) | 531 | static void sprd_console_putchar(struct uart_port *port, int ch) |
530 | { | 532 | { |
531 | wait_for_xmitr(port); | 533 | wait_for_xmitr(port); |
532 | serial_out(port, SPRD_TXD, ch); | 534 | serial_out(port, SPRD_TXD, ch); |
533 | } | 535 | } |
534 | 536 | ||
535 | static void sprd_console_write(struct console *co, const char *s, | 537 | static void sprd_console_write(struct console *co, const char *s, |
536 | unsigned int count) | 538 | unsigned int count) |
537 | { | 539 | { |
538 | struct uart_port *port = &sprd_port[co->index]->port; | 540 | struct uart_port *port = &sprd_port[co->index]->port; |
539 | int locked = 1; | 541 | int locked = 1; |
540 | unsigned long flags; | 542 | unsigned long flags; |
541 | 543 | ||
542 | if (port->sysrq) | 544 | if (port->sysrq) |
543 | locked = 0; | 545 | locked = 0; |
544 | else if (oops_in_progress) | 546 | else if (oops_in_progress) |
545 | locked = spin_trylock_irqsave(&port->lock, flags); | 547 | locked = spin_trylock_irqsave(&port->lock, flags); |
546 | else | 548 | else |
547 | spin_lock_irqsave(&port->lock, flags); | 549 | spin_lock_irqsave(&port->lock, flags); |
548 | 550 | ||
549 | uart_console_write(port, s, count, sprd_console_putchar); | 551 | uart_console_write(port, s, count, sprd_console_putchar); |
550 | 552 | ||
551 | /* wait for transmitter to become empty */ | 553 | /* wait for transmitter to become empty */ |
552 | wait_for_xmitr(port); | 554 | wait_for_xmitr(port); |
553 | 555 | ||
554 | if (locked) | 556 | if (locked) |
555 | spin_unlock_irqrestore(&port->lock, flags); | 557 | spin_unlock_irqrestore(&port->lock, flags); |
556 | } | 558 | } |
557 | 559 | ||
558 | static int __init sprd_console_setup(struct console *co, char *options) | 560 | static int __init sprd_console_setup(struct console *co, char *options) |
559 | { | 561 | { |
560 | struct uart_port *port; | 562 | struct uart_port *port; |
561 | int baud = 115200; | 563 | int baud = 115200; |
562 | int bits = 8; | 564 | int bits = 8; |
563 | int parity = 'n'; | 565 | int parity = 'n'; |
564 | int flow = 'n'; | 566 | int flow = 'n'; |
565 | 567 | ||
566 | if (co->index >= UART_NR_MAX || co->index < 0) | 568 | if (co->index >= UART_NR_MAX || co->index < 0) |
567 | co->index = 0; | 569 | co->index = 0; |
568 | 570 | ||
569 | port = &sprd_port[co->index]->port; | 571 | port = &sprd_port[co->index]->port; |
570 | if (port == NULL) { | 572 | if (port == NULL) { |
571 | pr_info("serial port %d not yet initialized\n", co->index); | 573 | pr_info("serial port %d not yet initialized\n", co->index); |
572 | return -ENODEV; | 574 | return -ENODEV; |
573 | } | 575 | } |
574 | if (options) | 576 | if (options) |
575 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 577 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
576 | 578 | ||
577 | return uart_set_options(port, co, baud, parity, bits, flow); | 579 | return uart_set_options(port, co, baud, parity, bits, flow); |
578 | } | 580 | } |
579 | 581 | ||
580 | static struct uart_driver sprd_uart_driver; | 582 | static struct uart_driver sprd_uart_driver; |
581 | static struct console sprd_console = { | 583 | static struct console sprd_console = { |
582 | .name = SPRD_TTY_NAME, | 584 | .name = SPRD_TTY_NAME, |
583 | .write = sprd_console_write, | 585 | .write = sprd_console_write, |
584 | .device = uart_console_device, | 586 | .device = uart_console_device, |
585 | .setup = sprd_console_setup, | 587 | .setup = sprd_console_setup, |
586 | .flags = CON_PRINTBUFFER, | 588 | .flags = CON_PRINTBUFFER, |
587 | .index = -1, | 589 | .index = -1, |
588 | .data = &sprd_uart_driver, | 590 | .data = &sprd_uart_driver, |
589 | }; | 591 | }; |
590 | 592 | ||
591 | #define SPRD_CONSOLE (&sprd_console) | 593 | #define SPRD_CONSOLE (&sprd_console) |
592 | 594 | ||
593 | /* Support for earlycon */ | 595 | /* Support for earlycon */ |
594 | static void sprd_putc(struct uart_port *port, int c) | 596 | static void sprd_putc(struct uart_port *port, int c) |
595 | { | 597 | { |
596 | unsigned int timeout = SPRD_TIMEOUT; | 598 | unsigned int timeout = SPRD_TIMEOUT; |
597 | 599 | ||
598 | while (timeout-- && | 600 | while (timeout-- && |
599 | !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER)) | 601 | !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER)) |
600 | cpu_relax(); | 602 | cpu_relax(); |
601 | 603 | ||
602 | writeb(c, port->membase + SPRD_TXD); | 604 | writeb(c, port->membase + SPRD_TXD); |
603 | } | 605 | } |
604 | 606 | ||
605 | static void sprd_early_write(struct console *con, const char *s, | 607 | static void sprd_early_write(struct console *con, const char *s, |
606 | unsigned n) | 608 | unsigned n) |
607 | { | 609 | { |
608 | struct earlycon_device *dev = con->data; | 610 | struct earlycon_device *dev = con->data; |
609 | 611 | ||
610 | uart_console_write(&dev->port, s, n, sprd_putc); | 612 | uart_console_write(&dev->port, s, n, sprd_putc); |
611 | } | 613 | } |
612 | 614 | ||
613 | static int __init sprd_early_console_setup( | 615 | static int __init sprd_early_console_setup( |
614 | struct earlycon_device *device, | 616 | struct earlycon_device *device, |
615 | const char *opt) | 617 | const char *opt) |
616 | { | 618 | { |
617 | if (!device->port.membase) | 619 | if (!device->port.membase) |
618 | return -ENODEV; | 620 | return -ENODEV; |
619 | 621 | ||
620 | device->con->write = sprd_early_write; | 622 | device->con->write = sprd_early_write; |
621 | return 0; | 623 | return 0; |
622 | } | 624 | } |
623 | 625 | ||
624 | EARLYCON_DECLARE(sprd_serial, sprd_early_console_setup); | 626 | EARLYCON_DECLARE(sprd_serial, sprd_early_console_setup); |
625 | OF_EARLYCON_DECLARE(sprd_serial, "sprd,sc9836-uart", | 627 | OF_EARLYCON_DECLARE(sprd_serial, "sprd,sc9836-uart", |
626 | sprd_early_console_setup); | 628 | sprd_early_console_setup); |
627 | 629 | ||
628 | #else /* !CONFIG_SERIAL_SPRD_CONSOLE */ | 630 | #else /* !CONFIG_SERIAL_SPRD_CONSOLE */ |
629 | #define SPRD_CONSOLE NULL | 631 | #define SPRD_CONSOLE NULL |
630 | #endif | 632 | #endif |
631 | 633 | ||
632 | static struct uart_driver sprd_uart_driver = { | 634 | static struct uart_driver sprd_uart_driver = { |
633 | .owner = THIS_MODULE, | 635 | .owner = THIS_MODULE, |
634 | .driver_name = "sprd_serial", | 636 | .driver_name = "sprd_serial", |
635 | .dev_name = SPRD_TTY_NAME, | 637 | .dev_name = SPRD_TTY_NAME, |
636 | .major = 0, | 638 | .major = 0, |
637 | .minor = 0, | 639 | .minor = 0, |
638 | .nr = UART_NR_MAX, | 640 | .nr = UART_NR_MAX, |
639 | .cons = SPRD_CONSOLE, | 641 | .cons = SPRD_CONSOLE, |
640 | }; | 642 | }; |
641 | 643 | ||
642 | static int sprd_probe_dt_alias(int index, struct device *dev) | 644 | static int sprd_probe_dt_alias(int index, struct device *dev) |
643 | { | 645 | { |
644 | struct device_node *np; | 646 | struct device_node *np; |
645 | int ret = index; | 647 | int ret = index; |
646 | 648 | ||
647 | if (!IS_ENABLED(CONFIG_OF)) | 649 | if (!IS_ENABLED(CONFIG_OF)) |
648 | return ret; | 650 | return ret; |
649 | 651 | ||
650 | np = dev->of_node; | 652 | np = dev->of_node; |
651 | if (!np) | 653 | if (!np) |
652 | return ret; | 654 | return ret; |
653 | 655 | ||
654 | ret = of_alias_get_id(np, "serial"); | 656 | ret = of_alias_get_id(np, "serial"); |
655 | if (IS_ERR_VALUE(ret)) | 657 | if (IS_ERR_VALUE(ret)) |
656 | ret = index; | 658 | ret = index; |
657 | else if (ret >= ARRAY_SIZE(sprd_port) || sprd_port[ret] != NULL) { | 659 | else if (ret >= ARRAY_SIZE(sprd_port) || sprd_port[ret] != NULL) { |
658 | dev_warn(dev, "requested serial port %d not available.\n", ret); | 660 | dev_warn(dev, "requested serial port %d not available.\n", ret); |
659 | ret = index; | 661 | ret = index; |
660 | } | 662 | } |
661 | 663 | ||
662 | return ret; | 664 | return ret; |
663 | } | 665 | } |
664 | 666 | ||
665 | static int sprd_remove(struct platform_device *dev) | 667 | static int sprd_remove(struct platform_device *dev) |
666 | { | 668 | { |
667 | struct sprd_uart_port *sup = platform_get_drvdata(dev); | 669 | struct sprd_uart_port *sup = platform_get_drvdata(dev); |
668 | 670 | ||
669 | if (sup) { | 671 | if (sup) { |
670 | uart_remove_one_port(&sprd_uart_driver, &sup->port); | 672 | uart_remove_one_port(&sprd_uart_driver, &sup->port); |
671 | sprd_port[sup->port.line] = NULL; | 673 | sprd_port[sup->port.line] = NULL; |
672 | sprd_ports_num--; | 674 | sprd_ports_num--; |
673 | } | 675 | } |
674 | 676 | ||
675 | if (!sprd_ports_num) | 677 | if (!sprd_ports_num) |
676 | uart_unregister_driver(&sprd_uart_driver); | 678 | uart_unregister_driver(&sprd_uart_driver); |
677 | 679 | ||
678 | return 0; | 680 | return 0; |
679 | } | 681 | } |
680 | 682 | ||
681 | static int sprd_probe(struct platform_device *pdev) | 683 | static int sprd_probe(struct platform_device *pdev) |
682 | { | 684 | { |
683 | struct resource *res; | 685 | struct resource *res; |
684 | struct uart_port *up; | 686 | struct uart_port *up; |
685 | struct clk *clk; | 687 | struct clk *clk; |
686 | int irq; | 688 | int irq; |
687 | int index; | 689 | int index; |
688 | int ret; | 690 | int ret; |
689 | 691 | ||
690 | for (index = 0; index < ARRAY_SIZE(sprd_port); index++) | 692 | for (index = 0; index < ARRAY_SIZE(sprd_port); index++) |
691 | if (sprd_port[index] == NULL) | 693 | if (sprd_port[index] == NULL) |
692 | break; | 694 | break; |
693 | 695 | ||
694 | if (index == ARRAY_SIZE(sprd_port)) | 696 | if (index == ARRAY_SIZE(sprd_port)) |
695 | return -EBUSY; | 697 | return -EBUSY; |
696 | 698 | ||
697 | index = sprd_probe_dt_alias(index, &pdev->dev); | 699 | index = sprd_probe_dt_alias(index, &pdev->dev); |
698 | 700 | ||
699 | sprd_port[index] = devm_kzalloc(&pdev->dev, | 701 | sprd_port[index] = devm_kzalloc(&pdev->dev, |
700 | sizeof(*sprd_port[index]), GFP_KERNEL); | 702 | sizeof(*sprd_port[index]), GFP_KERNEL); |
701 | if (!sprd_port[index]) | 703 | if (!sprd_port[index]) |
702 | return -ENOMEM; | 704 | return -ENOMEM; |
703 | 705 | ||
704 | up = &sprd_port[index]->port; | 706 | up = &sprd_port[index]->port; |
705 | up->dev = &pdev->dev; | 707 | up->dev = &pdev->dev; |
706 | up->line = index; | 708 | up->line = index; |
707 | up->type = PORT_SPRD; | 709 | up->type = PORT_SPRD; |
708 | up->iotype = SERIAL_IO_PORT; | 710 | up->iotype = SERIAL_IO_PORT; |
709 | up->uartclk = SPRD_DEF_RATE; | 711 | up->uartclk = SPRD_DEF_RATE; |
710 | up->fifosize = SPRD_FIFO_SIZE; | 712 | up->fifosize = SPRD_FIFO_SIZE; |
711 | up->ops = &serial_sprd_ops; | 713 | up->ops = &serial_sprd_ops; |
712 | up->flags = UPF_BOOT_AUTOCONF; | 714 | up->flags = UPF_BOOT_AUTOCONF; |
713 | 715 | ||
714 | clk = devm_clk_get(&pdev->dev, NULL); | 716 | clk = devm_clk_get(&pdev->dev, NULL); |
715 | if (!IS_ERR(clk)) | 717 | if (!IS_ERR(clk)) |
716 | up->uartclk = clk_get_rate(clk); | 718 | up->uartclk = clk_get_rate(clk); |
717 | 719 | ||
718 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 720 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
719 | if (!res) { | 721 | if (!res) { |
720 | dev_err(&pdev->dev, "not provide mem resource\n"); | 722 | dev_err(&pdev->dev, "not provide mem resource\n"); |
721 | return -ENODEV; | 723 | return -ENODEV; |
722 | } | 724 | } |
723 | up->mapbase = res->start; | 725 | up->mapbase = res->start; |
724 | up->membase = devm_ioremap_resource(&pdev->dev, res); | 726 | up->membase = devm_ioremap_resource(&pdev->dev, res); |
725 | if (IS_ERR(up->membase)) | 727 | if (IS_ERR(up->membase)) |
726 | return PTR_ERR(up->membase); | 728 | return PTR_ERR(up->membase); |
727 | 729 | ||
728 | irq = platform_get_irq(pdev, 0); | 730 | irq = platform_get_irq(pdev, 0); |
729 | if (irq < 0) { | 731 | if (irq < 0) { |
730 | dev_err(&pdev->dev, "not provide irq resource\n"); | 732 | dev_err(&pdev->dev, "not provide irq resource\n"); |
731 | return -ENODEV; | 733 | return -ENODEV; |
732 | } | 734 | } |
733 | up->irq = irq; | 735 | up->irq = irq; |
734 | 736 | ||
735 | if (!sprd_ports_num) { | 737 | if (!sprd_ports_num) { |
736 | ret = uart_register_driver(&sprd_uart_driver); | 738 | ret = uart_register_driver(&sprd_uart_driver); |
737 | if (ret < 0) { | 739 | if (ret < 0) { |
738 | pr_err("Failed to register SPRD-UART driver\n"); | 740 | pr_err("Failed to register SPRD-UART driver\n"); |
739 | return ret; | 741 | return ret; |
740 | } | 742 | } |
741 | } | 743 | } |
742 | sprd_ports_num++; | 744 | sprd_ports_num++; |
743 | 745 | ||
744 | ret = uart_add_one_port(&sprd_uart_driver, up); | 746 | ret = uart_add_one_port(&sprd_uart_driver, up); |
745 | if (ret) { | 747 | if (ret) { |
746 | sprd_port[index] = NULL; | 748 | sprd_port[index] = NULL; |
747 | sprd_remove(pdev); | 749 | sprd_remove(pdev); |
748 | } | 750 | } |
749 | 751 | ||
750 | platform_set_drvdata(pdev, up); | 752 | platform_set_drvdata(pdev, up); |
751 | 753 | ||
752 | return ret; | 754 | return ret; |
753 | } | 755 | } |
754 | 756 | ||
755 | static int sprd_suspend(struct device *dev) | 757 | static int sprd_suspend(struct device *dev) |
756 | { | 758 | { |
757 | struct sprd_uart_port *sup = dev_get_drvdata(dev); | 759 | struct sprd_uart_port *sup = dev_get_drvdata(dev); |
758 | 760 | ||
759 | uart_suspend_port(&sprd_uart_driver, &sup->port); | 761 | uart_suspend_port(&sprd_uart_driver, &sup->port); |
760 | 762 | ||
761 | return 0; | 763 | return 0; |
762 | } | 764 | } |
763 | 765 | ||
764 | static int sprd_resume(struct device *dev) | 766 | static int sprd_resume(struct device *dev) |
765 | { | 767 | { |
766 | struct sprd_uart_port *sup = dev_get_drvdata(dev); | 768 | struct sprd_uart_port *sup = dev_get_drvdata(dev); |
767 | 769 | ||
768 | uart_resume_port(&sprd_uart_driver, &sup->port); | 770 | uart_resume_port(&sprd_uart_driver, &sup->port); |
769 | 771 | ||
770 | return 0; | 772 | return 0; |
771 | } | 773 | } |
772 | 774 | ||
773 | static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume); | 775 | static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume); |
774 | 776 | ||
775 | static const struct of_device_id serial_ids[] = { | 777 | static const struct of_device_id serial_ids[] = { |
776 | {.compatible = "sprd,sc9836-uart",}, | 778 | {.compatible = "sprd,sc9836-uart",}, |
777 | {} | 779 | {} |
778 | }; | 780 | }; |
779 | 781 | ||
780 | static struct platform_driver sprd_platform_driver = { | 782 | static struct platform_driver sprd_platform_driver = { |
781 | .probe = sprd_probe, | 783 | .probe = sprd_probe, |
782 | .remove = sprd_remove, | 784 | .remove = sprd_remove, |
783 | .driver = { | 785 | .driver = { |
784 | .name = "sprd_serial", | 786 | .name = "sprd_serial", |
785 | .of_match_table = of_match_ptr(serial_ids), | 787 | .of_match_table = of_match_ptr(serial_ids), |
786 | .pm = &sprd_pm_ops, | 788 | .pm = &sprd_pm_ops, |
787 | }, | 789 | }, |
788 | }; | 790 | }; |
789 | 791 | ||
790 | module_platform_driver(sprd_platform_driver); | 792 | module_platform_driver(sprd_platform_driver); |
791 | 793 | ||
792 | MODULE_LICENSE("GPL v2"); | 794 | MODULE_LICENSE("GPL v2"); |
793 | MODULE_DESCRIPTION("Spreadtrum SoC serial driver series"); | 795 | MODULE_DESCRIPTION("Spreadtrum SoC serial driver series"); |
794 | 796 |
drivers/tty/tty_io.c
1 | /* | 1 | /* |
2 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
3 | */ | 3 | */ |
4 | 4 | ||
5 | /* | 5 | /* |
6 | * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles | 6 | * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles |
7 | * or rs-channels. It also implements echoing, cooked mode etc. | 7 | * or rs-channels. It also implements echoing, cooked mode etc. |
8 | * | 8 | * |
9 | * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0. | 9 | * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0. |
10 | * | 10 | * |
11 | * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the | 11 | * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the |
12 | * tty_struct and tty_queue structures. Previously there was an array | 12 | * tty_struct and tty_queue structures. Previously there was an array |
13 | * of 256 tty_struct's which was statically allocated, and the | 13 | * of 256 tty_struct's which was statically allocated, and the |
14 | * tty_queue structures were allocated at boot time. Both are now | 14 | * tty_queue structures were allocated at boot time. Both are now |
15 | * dynamically allocated only when the tty is open. | 15 | * dynamically allocated only when the tty is open. |
16 | * | 16 | * |
17 | * Also restructured routines so that there is more of a separation | 17 | * Also restructured routines so that there is more of a separation |
18 | * between the high-level tty routines (tty_io.c and tty_ioctl.c) and | 18 | * between the high-level tty routines (tty_io.c and tty_ioctl.c) and |
19 | * the low-level tty routines (serial.c, pty.c, console.c). This | 19 | * the low-level tty routines (serial.c, pty.c, console.c). This |
20 | * makes for cleaner and more compact code. -TYT, 9/17/92 | 20 | * makes for cleaner and more compact code. -TYT, 9/17/92 |
21 | * | 21 | * |
22 | * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines | 22 | * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines |
23 | * which can be dynamically activated and de-activated by the line | 23 | * which can be dynamically activated and de-activated by the line |
24 | * discipline handling modules (like SLIP). | 24 | * discipline handling modules (like SLIP). |
25 | * | 25 | * |
26 | * NOTE: pay no attention to the line discipline code (yet); its | 26 | * NOTE: pay no attention to the line discipline code (yet); its |
27 | * interface is still subject to change in this version... | 27 | * interface is still subject to change in this version... |
28 | * -- TYT, 1/31/92 | 28 | * -- TYT, 1/31/92 |
29 | * | 29 | * |
30 | * Added functionality to the OPOST tty handling. No delays, but all | 30 | * Added functionality to the OPOST tty handling. No delays, but all |
31 | * other bits should be there. | 31 | * other bits should be there. |
32 | * -- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993. | 32 | * -- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993. |
33 | * | 33 | * |
34 | * Rewrote canonical mode and added more termios flags. | 34 | * Rewrote canonical mode and added more termios flags. |
35 | * -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94 | 35 | * -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94 |
36 | * | 36 | * |
37 | * Reorganized FASYNC support so mouse code can share it. | 37 | * Reorganized FASYNC support so mouse code can share it. |
38 | * -- ctm@ardi.com, 9Sep95 | 38 | * -- ctm@ardi.com, 9Sep95 |
39 | * | 39 | * |
40 | * New TIOCLINUX variants added. | 40 | * New TIOCLINUX variants added. |
41 | * -- mj@k332.feld.cvut.cz, 19-Nov-95 | 41 | * -- mj@k332.feld.cvut.cz, 19-Nov-95 |
42 | * | 42 | * |
43 | * Restrict vt switching via ioctl() | 43 | * Restrict vt switching via ioctl() |
44 | * -- grif@cs.ucr.edu, 5-Dec-95 | 44 | * -- grif@cs.ucr.edu, 5-Dec-95 |
45 | * | 45 | * |
46 | * Move console and virtual terminal code to more appropriate files, | 46 | * Move console and virtual terminal code to more appropriate files, |
47 | * implement CONFIG_VT and generalize console device interface. | 47 | * implement CONFIG_VT and generalize console device interface. |
48 | * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97 | 48 | * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97 |
49 | * | 49 | * |
50 | * Rewrote tty_init_dev and tty_release_dev to eliminate races. | 50 | * Rewrote tty_init_dev and tty_release_dev to eliminate races. |
51 | * -- Bill Hawes <whawes@star.net>, June 97 | 51 | * -- Bill Hawes <whawes@star.net>, June 97 |
52 | * | 52 | * |
53 | * Added devfs support. | 53 | * Added devfs support. |
54 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 13-Jan-1998 | 54 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 13-Jan-1998 |
55 | * | 55 | * |
56 | * Added support for a Unix98-style ptmx device. | 56 | * Added support for a Unix98-style ptmx device. |
57 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 | 57 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 |
58 | * | 58 | * |
59 | * Reduced memory usage for older ARM systems | 59 | * Reduced memory usage for older ARM systems |
60 | * -- Russell King <rmk@arm.linux.org.uk> | 60 | * -- Russell King <rmk@arm.linux.org.uk> |
61 | * | 61 | * |
62 | * Move do_SAK() into process context. Less stack use in devfs functions. | 62 | * Move do_SAK() into process context. Less stack use in devfs functions. |
63 | * alloc_tty_struct() always uses kmalloc() | 63 | * alloc_tty_struct() always uses kmalloc() |
64 | * -- Andrew Morton <andrewm@uow.edu.eu> 17Mar01 | 64 | * -- Andrew Morton <andrewm@uow.edu.eu> 17Mar01 |
65 | */ | 65 | */ |
66 | 66 | ||
67 | #include <linux/types.h> | 67 | #include <linux/types.h> |
68 | #include <linux/major.h> | 68 | #include <linux/major.h> |
69 | #include <linux/errno.h> | 69 | #include <linux/errno.h> |
70 | #include <linux/signal.h> | 70 | #include <linux/signal.h> |
71 | #include <linux/fcntl.h> | 71 | #include <linux/fcntl.h> |
72 | #include <linux/sched.h> | 72 | #include <linux/sched.h> |
73 | #include <linux/interrupt.h> | 73 | #include <linux/interrupt.h> |
74 | #include <linux/tty.h> | 74 | #include <linux/tty.h> |
75 | #include <linux/tty_driver.h> | 75 | #include <linux/tty_driver.h> |
76 | #include <linux/tty_flip.h> | 76 | #include <linux/tty_flip.h> |
77 | #include <linux/devpts_fs.h> | 77 | #include <linux/devpts_fs.h> |
78 | #include <linux/file.h> | 78 | #include <linux/file.h> |
79 | #include <linux/fdtable.h> | 79 | #include <linux/fdtable.h> |
80 | #include <linux/console.h> | 80 | #include <linux/console.h> |
81 | #include <linux/timer.h> | 81 | #include <linux/timer.h> |
82 | #include <linux/ctype.h> | 82 | #include <linux/ctype.h> |
83 | #include <linux/kd.h> | 83 | #include <linux/kd.h> |
84 | #include <linux/mm.h> | 84 | #include <linux/mm.h> |
85 | #include <linux/string.h> | 85 | #include <linux/string.h> |
86 | #include <linux/slab.h> | 86 | #include <linux/slab.h> |
87 | #include <linux/poll.h> | 87 | #include <linux/poll.h> |
88 | #include <linux/proc_fs.h> | 88 | #include <linux/proc_fs.h> |
89 | #include <linux/init.h> | 89 | #include <linux/init.h> |
90 | #include <linux/module.h> | 90 | #include <linux/module.h> |
91 | #include <linux/device.h> | 91 | #include <linux/device.h> |
92 | #include <linux/wait.h> | 92 | #include <linux/wait.h> |
93 | #include <linux/bitops.h> | 93 | #include <linux/bitops.h> |
94 | #include <linux/delay.h> | 94 | #include <linux/delay.h> |
95 | #include <linux/seq_file.h> | 95 | #include <linux/seq_file.h> |
96 | #include <linux/serial.h> | 96 | #include <linux/serial.h> |
97 | #include <linux/ratelimit.h> | 97 | #include <linux/ratelimit.h> |
98 | 98 | ||
99 | #include <linux/uaccess.h> | 99 | #include <linux/uaccess.h> |
100 | 100 | ||
101 | #include <linux/kbd_kern.h> | 101 | #include <linux/kbd_kern.h> |
102 | #include <linux/vt_kern.h> | 102 | #include <linux/vt_kern.h> |
103 | #include <linux/selection.h> | 103 | #include <linux/selection.h> |
104 | 104 | ||
105 | #include <linux/kmod.h> | 105 | #include <linux/kmod.h> |
106 | #include <linux/nsproxy.h> | 106 | #include <linux/nsproxy.h> |
107 | 107 | ||
108 | #undef TTY_DEBUG_HANGUP | 108 | #undef TTY_DEBUG_HANGUP |
109 | 109 | ||
110 | #define TTY_PARANOIA_CHECK 1 | 110 | #define TTY_PARANOIA_CHECK 1 |
111 | #define CHECK_TTY_COUNT 1 | 111 | #define CHECK_TTY_COUNT 1 |
112 | 112 | ||
113 | struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ | 113 | struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ |
114 | .c_iflag = ICRNL | IXON, | 114 | .c_iflag = ICRNL | IXON, |
115 | .c_oflag = OPOST | ONLCR, | 115 | .c_oflag = OPOST | ONLCR, |
116 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, | 116 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, |
117 | .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | | 117 | .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | |
118 | ECHOCTL | ECHOKE | IEXTEN, | 118 | ECHOCTL | ECHOKE | IEXTEN, |
119 | .c_cc = INIT_C_CC, | 119 | .c_cc = INIT_C_CC, |
120 | .c_ispeed = 38400, | 120 | .c_ispeed = 38400, |
121 | .c_ospeed = 38400 | 121 | .c_ospeed = 38400 |
122 | }; | 122 | }; |
123 | 123 | ||
124 | EXPORT_SYMBOL(tty_std_termios); | 124 | EXPORT_SYMBOL(tty_std_termios); |
125 | 125 | ||
126 | /* This list gets poked at by procfs and various bits of boot up code. This | 126 | /* This list gets poked at by procfs and various bits of boot up code. This |
127 | could do with some rationalisation such as pulling the tty proc function | 127 | could do with some rationalisation such as pulling the tty proc function |
128 | into this file */ | 128 | into this file */ |
129 | 129 | ||
130 | LIST_HEAD(tty_drivers); /* linked list of tty drivers */ | 130 | LIST_HEAD(tty_drivers); /* linked list of tty drivers */ |
131 | 131 | ||
132 | /* Mutex to protect creating and releasing a tty. This is shared with | 132 | /* Mutex to protect creating and releasing a tty. This is shared with |
133 | vt.c for deeply disgusting hack reasons */ | 133 | vt.c for deeply disgusting hack reasons */ |
134 | DEFINE_MUTEX(tty_mutex); | 134 | DEFINE_MUTEX(tty_mutex); |
135 | EXPORT_SYMBOL(tty_mutex); | 135 | EXPORT_SYMBOL(tty_mutex); |
136 | 136 | ||
137 | /* Spinlock to protect the tty->tty_files list */ | 137 | /* Spinlock to protect the tty->tty_files list */ |
138 | DEFINE_SPINLOCK(tty_files_lock); | 138 | DEFINE_SPINLOCK(tty_files_lock); |
139 | 139 | ||
140 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 140 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
141 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); | 141 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
142 | ssize_t redirected_tty_write(struct file *, const char __user *, | 142 | ssize_t redirected_tty_write(struct file *, const char __user *, |
143 | size_t, loff_t *); | 143 | size_t, loff_t *); |
144 | static unsigned int tty_poll(struct file *, poll_table *); | 144 | static unsigned int tty_poll(struct file *, poll_table *); |
145 | static int tty_open(struct inode *, struct file *); | 145 | static int tty_open(struct inode *, struct file *); |
146 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 146 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
147 | #ifdef CONFIG_COMPAT | 147 | #ifdef CONFIG_COMPAT |
148 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, | 148 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, |
149 | unsigned long arg); | 149 | unsigned long arg); |
150 | #else | 150 | #else |
151 | #define tty_compat_ioctl NULL | 151 | #define tty_compat_ioctl NULL |
152 | #endif | 152 | #endif |
153 | static int __tty_fasync(int fd, struct file *filp, int on); | 153 | static int __tty_fasync(int fd, struct file *filp, int on); |
154 | static int tty_fasync(int fd, struct file *filp, int on); | 154 | static int tty_fasync(int fd, struct file *filp, int on); |
155 | static void release_tty(struct tty_struct *tty, int idx); | 155 | static void release_tty(struct tty_struct *tty, int idx); |
156 | 156 | ||
157 | /** | 157 | /** |
158 | * free_tty_struct - free a disused tty | 158 | * free_tty_struct - free a disused tty |
159 | * @tty: tty struct to free | 159 | * @tty: tty struct to free |
160 | * | 160 | * |
161 | * Free the write buffers, tty queue and tty memory itself. | 161 | * Free the write buffers, tty queue and tty memory itself. |
162 | * | 162 | * |
163 | * Locking: none. Must be called after tty is definitely unused | 163 | * Locking: none. Must be called after tty is definitely unused |
164 | */ | 164 | */ |
165 | 165 | ||
166 | void free_tty_struct(struct tty_struct *tty) | 166 | void free_tty_struct(struct tty_struct *tty) |
167 | { | 167 | { |
168 | if (!tty) | 168 | if (!tty) |
169 | return; | 169 | return; |
170 | put_device(tty->dev); | 170 | put_device(tty->dev); |
171 | kfree(tty->write_buf); | 171 | kfree(tty->write_buf); |
172 | tty->magic = 0xDEADDEAD; | 172 | tty->magic = 0xDEADDEAD; |
173 | kfree(tty); | 173 | kfree(tty); |
174 | } | 174 | } |
175 | 175 | ||
176 | static inline struct tty_struct *file_tty(struct file *file) | 176 | static inline struct tty_struct *file_tty(struct file *file) |
177 | { | 177 | { |
178 | return ((struct tty_file_private *)file->private_data)->tty; | 178 | return ((struct tty_file_private *)file->private_data)->tty; |
179 | } | 179 | } |
180 | 180 | ||
181 | int tty_alloc_file(struct file *file) | 181 | int tty_alloc_file(struct file *file) |
182 | { | 182 | { |
183 | struct tty_file_private *priv; | 183 | struct tty_file_private *priv; |
184 | 184 | ||
185 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); | 185 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); |
186 | if (!priv) | 186 | if (!priv) |
187 | return -ENOMEM; | 187 | return -ENOMEM; |
188 | 188 | ||
189 | file->private_data = priv; | 189 | file->private_data = priv; |
190 | 190 | ||
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
193 | 193 | ||
194 | /* Associate a new file with the tty structure */ | 194 | /* Associate a new file with the tty structure */ |
195 | void tty_add_file(struct tty_struct *tty, struct file *file) | 195 | void tty_add_file(struct tty_struct *tty, struct file *file) |
196 | { | 196 | { |
197 | struct tty_file_private *priv = file->private_data; | 197 | struct tty_file_private *priv = file->private_data; |
198 | 198 | ||
199 | priv->tty = tty; | 199 | priv->tty = tty; |
200 | priv->file = file; | 200 | priv->file = file; |
201 | 201 | ||
202 | spin_lock(&tty_files_lock); | 202 | spin_lock(&tty_files_lock); |
203 | list_add(&priv->list, &tty->tty_files); | 203 | list_add(&priv->list, &tty->tty_files); |
204 | spin_unlock(&tty_files_lock); | 204 | spin_unlock(&tty_files_lock); |
205 | } | 205 | } |
206 | 206 | ||
207 | /** | 207 | /** |
208 | * tty_free_file - free file->private_data | 208 | * tty_free_file - free file->private_data |
209 | * | 209 | * |
210 | * This shall be used only for fail path handling when tty_add_file was not | 210 | * This shall be used only for fail path handling when tty_add_file was not |
211 | * called yet. | 211 | * called yet. |
212 | */ | 212 | */ |
213 | void tty_free_file(struct file *file) | 213 | void tty_free_file(struct file *file) |
214 | { | 214 | { |
215 | struct tty_file_private *priv = file->private_data; | 215 | struct tty_file_private *priv = file->private_data; |
216 | 216 | ||
217 | file->private_data = NULL; | 217 | file->private_data = NULL; |
218 | kfree(priv); | 218 | kfree(priv); |
219 | } | 219 | } |
220 | 220 | ||
221 | /* Delete file from its tty */ | 221 | /* Delete file from its tty */ |
222 | static void tty_del_file(struct file *file) | 222 | static void tty_del_file(struct file *file) |
223 | { | 223 | { |
224 | struct tty_file_private *priv = file->private_data; | 224 | struct tty_file_private *priv = file->private_data; |
225 | 225 | ||
226 | spin_lock(&tty_files_lock); | 226 | spin_lock(&tty_files_lock); |
227 | list_del(&priv->list); | 227 | list_del(&priv->list); |
228 | spin_unlock(&tty_files_lock); | 228 | spin_unlock(&tty_files_lock); |
229 | tty_free_file(file); | 229 | tty_free_file(file); |
230 | } | 230 | } |
231 | 231 | ||
232 | 232 | ||
233 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) | 233 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) |
234 | 234 | ||
235 | /** | 235 | /** |
236 | * tty_name - return tty naming | 236 | * tty_name - return tty naming |
237 | * @tty: tty structure | 237 | * @tty: tty structure |
238 | * @buf: buffer for output | 238 | * @buf: buffer for output |
239 | * | 239 | * |
240 | * Convert a tty structure into a name. The name reflects the kernel | 240 | * Convert a tty structure into a name. The name reflects the kernel |
241 | * naming policy and if udev is in use may not reflect user space | 241 | * naming policy and if udev is in use may not reflect user space |
242 | * | 242 | * |
243 | * Locking: none | 243 | * Locking: none |
244 | */ | 244 | */ |
245 | 245 | ||
246 | char *tty_name(struct tty_struct *tty, char *buf) | 246 | char *tty_name(struct tty_struct *tty, char *buf) |
247 | { | 247 | { |
248 | if (!tty) /* Hmm. NULL pointer. That's fun. */ | 248 | if (!tty) /* Hmm. NULL pointer. That's fun. */ |
249 | strcpy(buf, "NULL tty"); | 249 | strcpy(buf, "NULL tty"); |
250 | else | 250 | else |
251 | strcpy(buf, tty->name); | 251 | strcpy(buf, tty->name); |
252 | return buf; | 252 | return buf; |
253 | } | 253 | } |
254 | 254 | ||
255 | EXPORT_SYMBOL(tty_name); | 255 | EXPORT_SYMBOL(tty_name); |
256 | 256 | ||
257 | int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, | 257 | int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, |
258 | const char *routine) | 258 | const char *routine) |
259 | { | 259 | { |
260 | #ifdef TTY_PARANOIA_CHECK | 260 | #ifdef TTY_PARANOIA_CHECK |
261 | if (!tty) { | 261 | if (!tty) { |
262 | printk(KERN_WARNING | 262 | printk(KERN_WARNING |
263 | "null TTY for (%d:%d) in %s\n", | 263 | "null TTY for (%d:%d) in %s\n", |
264 | imajor(inode), iminor(inode), routine); | 264 | imajor(inode), iminor(inode), routine); |
265 | return 1; | 265 | return 1; |
266 | } | 266 | } |
267 | if (tty->magic != TTY_MAGIC) { | 267 | if (tty->magic != TTY_MAGIC) { |
268 | printk(KERN_WARNING | 268 | printk(KERN_WARNING |
269 | "bad magic number for tty struct (%d:%d) in %s\n", | 269 | "bad magic number for tty struct (%d:%d) in %s\n", |
270 | imajor(inode), iminor(inode), routine); | 270 | imajor(inode), iminor(inode), routine); |
271 | return 1; | 271 | return 1; |
272 | } | 272 | } |
273 | #endif | 273 | #endif |
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
276 | 276 | ||
277 | /* Caller must hold tty_lock */ | 277 | /* Caller must hold tty_lock */ |
278 | static int check_tty_count(struct tty_struct *tty, const char *routine) | 278 | static int check_tty_count(struct tty_struct *tty, const char *routine) |
279 | { | 279 | { |
280 | #ifdef CHECK_TTY_COUNT | 280 | #ifdef CHECK_TTY_COUNT |
281 | struct list_head *p; | 281 | struct list_head *p; |
282 | int count = 0; | 282 | int count = 0; |
283 | 283 | ||
284 | spin_lock(&tty_files_lock); | 284 | spin_lock(&tty_files_lock); |
285 | list_for_each(p, &tty->tty_files) { | 285 | list_for_each(p, &tty->tty_files) { |
286 | count++; | 286 | count++; |
287 | } | 287 | } |
288 | spin_unlock(&tty_files_lock); | 288 | spin_unlock(&tty_files_lock); |
289 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 289 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
290 | tty->driver->subtype == PTY_TYPE_SLAVE && | 290 | tty->driver->subtype == PTY_TYPE_SLAVE && |
291 | tty->link && tty->link->count) | 291 | tty->link && tty->link->count) |
292 | count++; | 292 | count++; |
293 | if (tty->count != count) { | 293 | if (tty->count != count) { |
294 | printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) " | 294 | printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) " |
295 | "!= #fd's(%d) in %s\n", | 295 | "!= #fd's(%d) in %s\n", |
296 | tty->name, tty->count, count, routine); | 296 | tty->name, tty->count, count, routine); |
297 | return count; | 297 | return count; |
298 | } | 298 | } |
299 | #endif | 299 | #endif |
300 | return 0; | 300 | return 0; |
301 | } | 301 | } |
302 | 302 | ||
303 | /** | 303 | /** |
304 | * get_tty_driver - find device of a tty | 304 | * get_tty_driver - find device of a tty |
305 | * @dev_t: device identifier | 305 | * @dev_t: device identifier |
306 | * @index: returns the index of the tty | 306 | * @index: returns the index of the tty |
307 | * | 307 | * |
308 | * This routine returns a tty driver structure, given a device number | 308 | * This routine returns a tty driver structure, given a device number |
309 | * and also passes back the index number. | 309 | * and also passes back the index number. |
310 | * | 310 | * |
311 | * Locking: caller must hold tty_mutex | 311 | * Locking: caller must hold tty_mutex |
312 | */ | 312 | */ |
313 | 313 | ||
314 | static struct tty_driver *get_tty_driver(dev_t device, int *index) | 314 | static struct tty_driver *get_tty_driver(dev_t device, int *index) |
315 | { | 315 | { |
316 | struct tty_driver *p; | 316 | struct tty_driver *p; |
317 | 317 | ||
318 | list_for_each_entry(p, &tty_drivers, tty_drivers) { | 318 | list_for_each_entry(p, &tty_drivers, tty_drivers) { |
319 | dev_t base = MKDEV(p->major, p->minor_start); | 319 | dev_t base = MKDEV(p->major, p->minor_start); |
320 | if (device < base || device >= base + p->num) | 320 | if (device < base || device >= base + p->num) |
321 | continue; | 321 | continue; |
322 | *index = device - base; | 322 | *index = device - base; |
323 | return tty_driver_kref_get(p); | 323 | return tty_driver_kref_get(p); |
324 | } | 324 | } |
325 | return NULL; | 325 | return NULL; |
326 | } | 326 | } |
327 | 327 | ||
328 | #ifdef CONFIG_CONSOLE_POLL | 328 | #ifdef CONFIG_CONSOLE_POLL |
329 | 329 | ||
330 | /** | 330 | /** |
331 | * tty_find_polling_driver - find device of a polled tty | 331 | * tty_find_polling_driver - find device of a polled tty |
332 | * @name: name string to match | 332 | * @name: name string to match |
333 | * @line: pointer to resulting tty line nr | 333 | * @line: pointer to resulting tty line nr |
334 | * | 334 | * |
335 | * This routine returns a tty driver structure, given a name | 335 | * This routine returns a tty driver structure, given a name |
336 | * and the condition that the tty driver is capable of polled | 336 | * and the condition that the tty driver is capable of polled |
337 | * operation. | 337 | * operation. |
338 | */ | 338 | */ |
339 | struct tty_driver *tty_find_polling_driver(char *name, int *line) | 339 | struct tty_driver *tty_find_polling_driver(char *name, int *line) |
340 | { | 340 | { |
341 | struct tty_driver *p, *res = NULL; | 341 | struct tty_driver *p, *res = NULL; |
342 | int tty_line = 0; | 342 | int tty_line = 0; |
343 | int len; | 343 | int len; |
344 | char *str, *stp; | 344 | char *str, *stp; |
345 | 345 | ||
346 | for (str = name; *str; str++) | 346 | for (str = name; *str; str++) |
347 | if ((*str >= '0' && *str <= '9') || *str == ',') | 347 | if ((*str >= '0' && *str <= '9') || *str == ',') |
348 | break; | 348 | break; |
349 | if (!*str) | 349 | if (!*str) |
350 | return NULL; | 350 | return NULL; |
351 | 351 | ||
352 | len = str - name; | 352 | len = str - name; |
353 | tty_line = simple_strtoul(str, &str, 10); | 353 | tty_line = simple_strtoul(str, &str, 10); |
354 | 354 | ||
355 | mutex_lock(&tty_mutex); | 355 | mutex_lock(&tty_mutex); |
356 | /* Search through the tty devices to look for a match */ | 356 | /* Search through the tty devices to look for a match */ |
357 | list_for_each_entry(p, &tty_drivers, tty_drivers) { | 357 | list_for_each_entry(p, &tty_drivers, tty_drivers) { |
358 | if (strncmp(name, p->name, len) != 0) | 358 | if (strncmp(name, p->name, len) != 0) |
359 | continue; | 359 | continue; |
360 | stp = str; | 360 | stp = str; |
361 | if (*stp == ',') | 361 | if (*stp == ',') |
362 | stp++; | 362 | stp++; |
363 | if (*stp == '\0') | 363 | if (*stp == '\0') |
364 | stp = NULL; | 364 | stp = NULL; |
365 | 365 | ||
366 | if (tty_line >= 0 && tty_line < p->num && p->ops && | 366 | if (tty_line >= 0 && tty_line < p->num && p->ops && |
367 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) { | 367 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) { |
368 | res = tty_driver_kref_get(p); | 368 | res = tty_driver_kref_get(p); |
369 | *line = tty_line; | 369 | *line = tty_line; |
370 | break; | 370 | break; |
371 | } | 371 | } |
372 | } | 372 | } |
373 | mutex_unlock(&tty_mutex); | 373 | mutex_unlock(&tty_mutex); |
374 | 374 | ||
375 | return res; | 375 | return res; |
376 | } | 376 | } |
377 | EXPORT_SYMBOL_GPL(tty_find_polling_driver); | 377 | EXPORT_SYMBOL_GPL(tty_find_polling_driver); |
378 | #endif | 378 | #endif |
379 | 379 | ||
380 | /** | 380 | /** |
381 | * tty_check_change - check for POSIX terminal changes | 381 | * tty_check_change - check for POSIX terminal changes |
382 | * @tty: tty to check | 382 | * @tty: tty to check |
383 | * | 383 | * |
384 | * If we try to write to, or set the state of, a terminal and we're | 384 | * If we try to write to, or set the state of, a terminal and we're |
385 | * not in the foreground, send a SIGTTOU. If the signal is blocked or | 385 | * not in the foreground, send a SIGTTOU. If the signal is blocked or |
386 | * ignored, go ahead and perform the operation. (POSIX 7.2) | 386 | * ignored, go ahead and perform the operation. (POSIX 7.2) |
387 | * | 387 | * |
388 | * Locking: ctrl_lock | 388 | * Locking: ctrl_lock |
389 | */ | 389 | */ |
390 | 390 | ||
391 | int tty_check_change(struct tty_struct *tty) | 391 | int tty_check_change(struct tty_struct *tty) |
392 | { | 392 | { |
393 | unsigned long flags; | 393 | unsigned long flags; |
394 | int ret = 0; | 394 | int ret = 0; |
395 | 395 | ||
396 | if (current->signal->tty != tty) | 396 | if (current->signal->tty != tty) |
397 | return 0; | 397 | return 0; |
398 | 398 | ||
399 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 399 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
400 | 400 | ||
401 | if (!tty->pgrp) { | 401 | if (!tty->pgrp) { |
402 | printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n"); | 402 | printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n"); |
403 | goto out_unlock; | 403 | goto out_unlock; |
404 | } | 404 | } |
405 | if (task_pgrp(current) == tty->pgrp) | 405 | if (task_pgrp(current) == tty->pgrp) |
406 | goto out_unlock; | 406 | goto out_unlock; |
407 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 407 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
408 | if (is_ignored(SIGTTOU)) | 408 | if (is_ignored(SIGTTOU)) |
409 | goto out; | 409 | goto out; |
410 | if (is_current_pgrp_orphaned()) { | 410 | if (is_current_pgrp_orphaned()) { |
411 | ret = -EIO; | 411 | ret = -EIO; |
412 | goto out; | 412 | goto out; |
413 | } | 413 | } |
414 | kill_pgrp(task_pgrp(current), SIGTTOU, 1); | 414 | kill_pgrp(task_pgrp(current), SIGTTOU, 1); |
415 | set_thread_flag(TIF_SIGPENDING); | 415 | set_thread_flag(TIF_SIGPENDING); |
416 | ret = -ERESTARTSYS; | 416 | ret = -ERESTARTSYS; |
417 | out: | 417 | out: |
418 | return ret; | 418 | return ret; |
419 | out_unlock: | 419 | out_unlock: |
420 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 420 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
421 | return ret; | 421 | return ret; |
422 | } | 422 | } |
423 | 423 | ||
424 | EXPORT_SYMBOL(tty_check_change); | 424 | EXPORT_SYMBOL(tty_check_change); |
425 | 425 | ||
426 | static ssize_t hung_up_tty_read(struct file *file, char __user *buf, | 426 | static ssize_t hung_up_tty_read(struct file *file, char __user *buf, |
427 | size_t count, loff_t *ppos) | 427 | size_t count, loff_t *ppos) |
428 | { | 428 | { |
429 | return 0; | 429 | return 0; |
430 | } | 430 | } |
431 | 431 | ||
432 | static ssize_t hung_up_tty_write(struct file *file, const char __user *buf, | 432 | static ssize_t hung_up_tty_write(struct file *file, const char __user *buf, |
433 | size_t count, loff_t *ppos) | 433 | size_t count, loff_t *ppos) |
434 | { | 434 | { |
435 | return -EIO; | 435 | return -EIO; |
436 | } | 436 | } |
437 | 437 | ||
438 | /* No kernel lock held - none needed ;) */ | 438 | /* No kernel lock held - none needed ;) */ |
439 | static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait) | 439 | static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait) |
440 | { | 440 | { |
441 | return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; | 441 | return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; |
442 | } | 442 | } |
443 | 443 | ||
444 | static long hung_up_tty_ioctl(struct file *file, unsigned int cmd, | 444 | static long hung_up_tty_ioctl(struct file *file, unsigned int cmd, |
445 | unsigned long arg) | 445 | unsigned long arg) |
446 | { | 446 | { |
447 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; | 447 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; |
448 | } | 448 | } |
449 | 449 | ||
450 | static long hung_up_tty_compat_ioctl(struct file *file, | 450 | static long hung_up_tty_compat_ioctl(struct file *file, |
451 | unsigned int cmd, unsigned long arg) | 451 | unsigned int cmd, unsigned long arg) |
452 | { | 452 | { |
453 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; | 453 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; |
454 | } | 454 | } |
455 | 455 | ||
456 | static const struct file_operations tty_fops = { | 456 | static const struct file_operations tty_fops = { |
457 | .llseek = no_llseek, | 457 | .llseek = no_llseek, |
458 | .read = tty_read, | 458 | .read = tty_read, |
459 | .write = tty_write, | 459 | .write = tty_write, |
460 | .poll = tty_poll, | 460 | .poll = tty_poll, |
461 | .unlocked_ioctl = tty_ioctl, | 461 | .unlocked_ioctl = tty_ioctl, |
462 | .compat_ioctl = tty_compat_ioctl, | 462 | .compat_ioctl = tty_compat_ioctl, |
463 | .open = tty_open, | 463 | .open = tty_open, |
464 | .release = tty_release, | 464 | .release = tty_release, |
465 | .fasync = tty_fasync, | 465 | .fasync = tty_fasync, |
466 | }; | 466 | }; |
467 | 467 | ||
468 | static const struct file_operations console_fops = { | 468 | static const struct file_operations console_fops = { |
469 | .llseek = no_llseek, | 469 | .llseek = no_llseek, |
470 | .read = tty_read, | 470 | .read = tty_read, |
471 | .write = redirected_tty_write, | 471 | .write = redirected_tty_write, |
472 | .poll = tty_poll, | 472 | .poll = tty_poll, |
473 | .unlocked_ioctl = tty_ioctl, | 473 | .unlocked_ioctl = tty_ioctl, |
474 | .compat_ioctl = tty_compat_ioctl, | 474 | .compat_ioctl = tty_compat_ioctl, |
475 | .open = tty_open, | 475 | .open = tty_open, |
476 | .release = tty_release, | 476 | .release = tty_release, |
477 | .fasync = tty_fasync, | 477 | .fasync = tty_fasync, |
478 | }; | 478 | }; |
479 | 479 | ||
480 | static const struct file_operations hung_up_tty_fops = { | 480 | static const struct file_operations hung_up_tty_fops = { |
481 | .llseek = no_llseek, | 481 | .llseek = no_llseek, |
482 | .read = hung_up_tty_read, | 482 | .read = hung_up_tty_read, |
483 | .write = hung_up_tty_write, | 483 | .write = hung_up_tty_write, |
484 | .poll = hung_up_tty_poll, | 484 | .poll = hung_up_tty_poll, |
485 | .unlocked_ioctl = hung_up_tty_ioctl, | 485 | .unlocked_ioctl = hung_up_tty_ioctl, |
486 | .compat_ioctl = hung_up_tty_compat_ioctl, | 486 | .compat_ioctl = hung_up_tty_compat_ioctl, |
487 | .release = tty_release, | 487 | .release = tty_release, |
488 | }; | 488 | }; |
489 | 489 | ||
490 | static DEFINE_SPINLOCK(redirect_lock); | 490 | static DEFINE_SPINLOCK(redirect_lock); |
491 | static struct file *redirect; | 491 | static struct file *redirect; |
492 | 492 | ||
493 | 493 | ||
494 | void proc_clear_tty(struct task_struct *p) | 494 | void proc_clear_tty(struct task_struct *p) |
495 | { | 495 | { |
496 | unsigned long flags; | 496 | unsigned long flags; |
497 | struct tty_struct *tty; | 497 | struct tty_struct *tty; |
498 | spin_lock_irqsave(&p->sighand->siglock, flags); | 498 | spin_lock_irqsave(&p->sighand->siglock, flags); |
499 | tty = p->signal->tty; | 499 | tty = p->signal->tty; |
500 | p->signal->tty = NULL; | 500 | p->signal->tty = NULL; |
501 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | 501 | spin_unlock_irqrestore(&p->sighand->siglock, flags); |
502 | tty_kref_put(tty); | 502 | tty_kref_put(tty); |
503 | } | 503 | } |
504 | 504 | ||
505 | /** | 505 | /** |
506 | * proc_set_tty - set the controlling terminal | 506 | * proc_set_tty - set the controlling terminal |
507 | * | 507 | * |
508 | * Only callable by the session leader and only if it does not already have | 508 | * Only callable by the session leader and only if it does not already have |
509 | * a controlling terminal. | 509 | * a controlling terminal. |
510 | * | 510 | * |
511 | * Caller must hold: tty_lock() | 511 | * Caller must hold: tty_lock() |
512 | * a readlock on tasklist_lock | 512 | * a readlock on tasklist_lock |
513 | * sighand lock | 513 | * sighand lock |
514 | */ | 514 | */ |
515 | static void __proc_set_tty(struct tty_struct *tty) | 515 | static void __proc_set_tty(struct tty_struct *tty) |
516 | { | 516 | { |
517 | unsigned long flags; | 517 | unsigned long flags; |
518 | 518 | ||
519 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 519 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
520 | /* | 520 | /* |
521 | * The session and fg pgrp references will be non-NULL if | 521 | * The session and fg pgrp references will be non-NULL if |
522 | * tiocsctty() is stealing the controlling tty | 522 | * tiocsctty() is stealing the controlling tty |
523 | */ | 523 | */ |
524 | put_pid(tty->session); | 524 | put_pid(tty->session); |
525 | put_pid(tty->pgrp); | 525 | put_pid(tty->pgrp); |
526 | tty->pgrp = get_pid(task_pgrp(current)); | 526 | tty->pgrp = get_pid(task_pgrp(current)); |
527 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 527 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
528 | tty->session = get_pid(task_session(current)); | 528 | tty->session = get_pid(task_session(current)); |
529 | if (current->signal->tty) { | 529 | if (current->signal->tty) { |
530 | printk(KERN_DEBUG "tty not NULL!!\n"); | 530 | printk(KERN_DEBUG "tty not NULL!!\n"); |
531 | tty_kref_put(current->signal->tty); | 531 | tty_kref_put(current->signal->tty); |
532 | } | 532 | } |
533 | put_pid(current->signal->tty_old_pgrp); | 533 | put_pid(current->signal->tty_old_pgrp); |
534 | current->signal->tty = tty_kref_get(tty); | 534 | current->signal->tty = tty_kref_get(tty); |
535 | current->signal->tty_old_pgrp = NULL; | 535 | current->signal->tty_old_pgrp = NULL; |
536 | } | 536 | } |
537 | 537 | ||
538 | static void proc_set_tty(struct tty_struct *tty) | 538 | static void proc_set_tty(struct tty_struct *tty) |
539 | { | 539 | { |
540 | spin_lock_irq(¤t->sighand->siglock); | 540 | spin_lock_irq(¤t->sighand->siglock); |
541 | __proc_set_tty(tty); | 541 | __proc_set_tty(tty); |
542 | spin_unlock_irq(¤t->sighand->siglock); | 542 | spin_unlock_irq(¤t->sighand->siglock); |
543 | } | 543 | } |
544 | 544 | ||
545 | struct tty_struct *get_current_tty(void) | 545 | struct tty_struct *get_current_tty(void) |
546 | { | 546 | { |
547 | struct tty_struct *tty; | 547 | struct tty_struct *tty; |
548 | unsigned long flags; | 548 | unsigned long flags; |
549 | 549 | ||
550 | spin_lock_irqsave(¤t->sighand->siglock, flags); | 550 | spin_lock_irqsave(¤t->sighand->siglock, flags); |
551 | tty = tty_kref_get(current->signal->tty); | 551 | tty = tty_kref_get(current->signal->tty); |
552 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | 552 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); |
553 | return tty; | 553 | return tty; |
554 | } | 554 | } |
555 | EXPORT_SYMBOL_GPL(get_current_tty); | 555 | EXPORT_SYMBOL_GPL(get_current_tty); |
556 | 556 | ||
557 | static void session_clear_tty(struct pid *session) | 557 | static void session_clear_tty(struct pid *session) |
558 | { | 558 | { |
559 | struct task_struct *p; | 559 | struct task_struct *p; |
560 | do_each_pid_task(session, PIDTYPE_SID, p) { | 560 | do_each_pid_task(session, PIDTYPE_SID, p) { |
561 | proc_clear_tty(p); | 561 | proc_clear_tty(p); |
562 | } while_each_pid_task(session, PIDTYPE_SID, p); | 562 | } while_each_pid_task(session, PIDTYPE_SID, p); |
563 | } | 563 | } |
564 | 564 | ||
565 | /** | 565 | /** |
566 | * tty_wakeup - request more data | 566 | * tty_wakeup - request more data |
567 | * @tty: terminal | 567 | * @tty: terminal |
568 | * | 568 | * |
569 | * Internal and external helper for wakeups of tty. This function | 569 | * Internal and external helper for wakeups of tty. This function |
570 | * informs the line discipline if present that the driver is ready | 570 | * informs the line discipline if present that the driver is ready |
571 | * to receive more output data. | 571 | * to receive more output data. |
572 | */ | 572 | */ |
573 | 573 | ||
574 | void tty_wakeup(struct tty_struct *tty) | 574 | void tty_wakeup(struct tty_struct *tty) |
575 | { | 575 | { |
576 | struct tty_ldisc *ld; | 576 | struct tty_ldisc *ld; |
577 | 577 | ||
578 | if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { | 578 | if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { |
579 | ld = tty_ldisc_ref(tty); | 579 | ld = tty_ldisc_ref(tty); |
580 | if (ld) { | 580 | if (ld) { |
581 | if (ld->ops->write_wakeup) | 581 | if (ld->ops->write_wakeup) |
582 | ld->ops->write_wakeup(tty); | 582 | ld->ops->write_wakeup(tty); |
583 | tty_ldisc_deref(ld); | 583 | tty_ldisc_deref(ld); |
584 | } | 584 | } |
585 | } | 585 | } |
586 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); | 586 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
587 | } | 587 | } |
588 | 588 | ||
589 | EXPORT_SYMBOL_GPL(tty_wakeup); | 589 | EXPORT_SYMBOL_GPL(tty_wakeup); |
590 | 590 | ||
591 | /** | 591 | /** |
592 | * tty_signal_session_leader - sends SIGHUP to session leader | 592 | * tty_signal_session_leader - sends SIGHUP to session leader |
593 | * @tty controlling tty | 593 | * @tty controlling tty |
594 | * @exit_session if non-zero, signal all foreground group processes | 594 | * @exit_session if non-zero, signal all foreground group processes |
595 | * | 595 | * |
596 | * Send SIGHUP and SIGCONT to the session leader and its process group. | 596 | * Send SIGHUP and SIGCONT to the session leader and its process group. |
597 | * Optionally, signal all processes in the foreground process group. | 597 | * Optionally, signal all processes in the foreground process group. |
598 | * | 598 | * |
599 | * Returns the number of processes in the session with this tty | 599 | * Returns the number of processes in the session with this tty |
600 | * as their controlling terminal. This value is used to drop | 600 | * as their controlling terminal. This value is used to drop |
601 | * tty references for those processes. | 601 | * tty references for those processes. |
602 | */ | 602 | */ |
603 | static int tty_signal_session_leader(struct tty_struct *tty, int exit_session) | 603 | static int tty_signal_session_leader(struct tty_struct *tty, int exit_session) |
604 | { | 604 | { |
605 | struct task_struct *p; | 605 | struct task_struct *p; |
606 | int refs = 0; | 606 | int refs = 0; |
607 | struct pid *tty_pgrp = NULL; | 607 | struct pid *tty_pgrp = NULL; |
608 | 608 | ||
609 | read_lock(&tasklist_lock); | 609 | read_lock(&tasklist_lock); |
610 | if (tty->session) { | 610 | if (tty->session) { |
611 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { | 611 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { |
612 | spin_lock_irq(&p->sighand->siglock); | 612 | spin_lock_irq(&p->sighand->siglock); |
613 | if (p->signal->tty == tty) { | 613 | if (p->signal->tty == tty) { |
614 | p->signal->tty = NULL; | 614 | p->signal->tty = NULL; |
615 | /* We defer the dereferences outside fo | 615 | /* We defer the dereferences outside fo |
616 | the tasklist lock */ | 616 | the tasklist lock */ |
617 | refs++; | 617 | refs++; |
618 | } | 618 | } |
619 | if (!p->signal->leader) { | 619 | if (!p->signal->leader) { |
620 | spin_unlock_irq(&p->sighand->siglock); | 620 | spin_unlock_irq(&p->sighand->siglock); |
621 | continue; | 621 | continue; |
622 | } | 622 | } |
623 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); | 623 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); |
624 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); | 624 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); |
625 | put_pid(p->signal->tty_old_pgrp); /* A noop */ | 625 | put_pid(p->signal->tty_old_pgrp); /* A noop */ |
626 | spin_lock(&tty->ctrl_lock); | 626 | spin_lock(&tty->ctrl_lock); |
627 | tty_pgrp = get_pid(tty->pgrp); | 627 | tty_pgrp = get_pid(tty->pgrp); |
628 | if (tty->pgrp) | 628 | if (tty->pgrp) |
629 | p->signal->tty_old_pgrp = get_pid(tty->pgrp); | 629 | p->signal->tty_old_pgrp = get_pid(tty->pgrp); |
630 | spin_unlock(&tty->ctrl_lock); | 630 | spin_unlock(&tty->ctrl_lock); |
631 | spin_unlock_irq(&p->sighand->siglock); | 631 | spin_unlock_irq(&p->sighand->siglock); |
632 | } while_each_pid_task(tty->session, PIDTYPE_SID, p); | 632 | } while_each_pid_task(tty->session, PIDTYPE_SID, p); |
633 | } | 633 | } |
634 | read_unlock(&tasklist_lock); | 634 | read_unlock(&tasklist_lock); |
635 | 635 | ||
636 | if (tty_pgrp) { | 636 | if (tty_pgrp) { |
637 | if (exit_session) | 637 | if (exit_session) |
638 | kill_pgrp(tty_pgrp, SIGHUP, exit_session); | 638 | kill_pgrp(tty_pgrp, SIGHUP, exit_session); |
639 | put_pid(tty_pgrp); | 639 | put_pid(tty_pgrp); |
640 | } | 640 | } |
641 | 641 | ||
642 | return refs; | 642 | return refs; |
643 | } | 643 | } |
644 | 644 | ||
645 | /** | 645 | /** |
646 | * __tty_hangup - actual handler for hangup events | 646 | * __tty_hangup - actual handler for hangup events |
647 | * @work: tty device | 647 | * @work: tty device |
648 | * | 648 | * |
649 | * This can be called by a "kworker" kernel thread. That is process | 649 | * This can be called by a "kworker" kernel thread. That is process |
650 | * synchronous but doesn't hold any locks, so we need to make sure we | 650 | * synchronous but doesn't hold any locks, so we need to make sure we |
651 | * have the appropriate locks for what we're doing. | 651 | * have the appropriate locks for what we're doing. |
652 | * | 652 | * |
653 | * The hangup event clears any pending redirections onto the hung up | 653 | * The hangup event clears any pending redirections onto the hung up |
654 | * device. It ensures future writes will error and it does the needed | 654 | * device. It ensures future writes will error and it does the needed |
655 | * line discipline hangup and signal delivery. The tty object itself | 655 | * line discipline hangup and signal delivery. The tty object itself |
656 | * remains intact. | 656 | * remains intact. |
657 | * | 657 | * |
658 | * Locking: | 658 | * Locking: |
659 | * BTM | 659 | * BTM |
660 | * redirect lock for undoing redirection | 660 | * redirect lock for undoing redirection |
661 | * file list lock for manipulating list of ttys | 661 | * file list lock for manipulating list of ttys |
662 | * tty_ldiscs_lock from called functions | 662 | * tty_ldiscs_lock from called functions |
663 | * termios_rwsem resetting termios data | 663 | * termios_rwsem resetting termios data |
664 | * tasklist_lock to walk task list for hangup event | 664 | * tasklist_lock to walk task list for hangup event |
665 | * ->siglock to protect ->signal/->sighand | 665 | * ->siglock to protect ->signal/->sighand |
666 | */ | 666 | */ |
667 | static void __tty_hangup(struct tty_struct *tty, int exit_session) | 667 | static void __tty_hangup(struct tty_struct *tty, int exit_session) |
668 | { | 668 | { |
669 | struct file *cons_filp = NULL; | 669 | struct file *cons_filp = NULL; |
670 | struct file *filp, *f = NULL; | 670 | struct file *filp, *f = NULL; |
671 | struct tty_file_private *priv; | 671 | struct tty_file_private *priv; |
672 | int closecount = 0, n; | 672 | int closecount = 0, n; |
673 | int refs; | 673 | int refs; |
674 | 674 | ||
675 | if (!tty) | 675 | if (!tty) |
676 | return; | 676 | return; |
677 | 677 | ||
678 | 678 | ||
679 | spin_lock(&redirect_lock); | 679 | spin_lock(&redirect_lock); |
680 | if (redirect && file_tty(redirect) == tty) { | 680 | if (redirect && file_tty(redirect) == tty) { |
681 | f = redirect; | 681 | f = redirect; |
682 | redirect = NULL; | 682 | redirect = NULL; |
683 | } | 683 | } |
684 | spin_unlock(&redirect_lock); | 684 | spin_unlock(&redirect_lock); |
685 | 685 | ||
686 | tty_lock(tty); | 686 | tty_lock(tty); |
687 | 687 | ||
688 | if (test_bit(TTY_HUPPED, &tty->flags)) { | 688 | if (test_bit(TTY_HUPPED, &tty->flags)) { |
689 | tty_unlock(tty); | 689 | tty_unlock(tty); |
690 | return; | 690 | return; |
691 | } | 691 | } |
692 | 692 | ||
693 | /* inuse_filps is protected by the single tty lock, | 693 | /* inuse_filps is protected by the single tty lock, |
694 | this really needs to change if we want to flush the | 694 | this really needs to change if we want to flush the |
695 | workqueue with the lock held */ | 695 | workqueue with the lock held */ |
696 | check_tty_count(tty, "tty_hangup"); | 696 | check_tty_count(tty, "tty_hangup"); |
697 | 697 | ||
698 | spin_lock(&tty_files_lock); | 698 | spin_lock(&tty_files_lock); |
699 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ | 699 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ |
700 | list_for_each_entry(priv, &tty->tty_files, list) { | 700 | list_for_each_entry(priv, &tty->tty_files, list) { |
701 | filp = priv->file; | 701 | filp = priv->file; |
702 | if (filp->f_op->write == redirected_tty_write) | 702 | if (filp->f_op->write == redirected_tty_write) |
703 | cons_filp = filp; | 703 | cons_filp = filp; |
704 | if (filp->f_op->write != tty_write) | 704 | if (filp->f_op->write != tty_write) |
705 | continue; | 705 | continue; |
706 | closecount++; | 706 | closecount++; |
707 | __tty_fasync(-1, filp, 0); /* can't block */ | 707 | __tty_fasync(-1, filp, 0); /* can't block */ |
708 | filp->f_op = &hung_up_tty_fops; | 708 | filp->f_op = &hung_up_tty_fops; |
709 | } | 709 | } |
710 | spin_unlock(&tty_files_lock); | 710 | spin_unlock(&tty_files_lock); |
711 | 711 | ||
712 | refs = tty_signal_session_leader(tty, exit_session); | 712 | refs = tty_signal_session_leader(tty, exit_session); |
713 | /* Account for the p->signal references we killed */ | 713 | /* Account for the p->signal references we killed */ |
714 | while (refs--) | 714 | while (refs--) |
715 | tty_kref_put(tty); | 715 | tty_kref_put(tty); |
716 | 716 | ||
717 | tty_ldisc_hangup(tty); | 717 | tty_ldisc_hangup(tty); |
718 | 718 | ||
719 | spin_lock_irq(&tty->ctrl_lock); | 719 | spin_lock_irq(&tty->ctrl_lock); |
720 | clear_bit(TTY_THROTTLED, &tty->flags); | 720 | clear_bit(TTY_THROTTLED, &tty->flags); |
721 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 721 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
722 | put_pid(tty->session); | 722 | put_pid(tty->session); |
723 | put_pid(tty->pgrp); | 723 | put_pid(tty->pgrp); |
724 | tty->session = NULL; | 724 | tty->session = NULL; |
725 | tty->pgrp = NULL; | 725 | tty->pgrp = NULL; |
726 | tty->ctrl_status = 0; | 726 | tty->ctrl_status = 0; |
727 | spin_unlock_irq(&tty->ctrl_lock); | 727 | spin_unlock_irq(&tty->ctrl_lock); |
728 | 728 | ||
729 | /* | 729 | /* |
730 | * If one of the devices matches a console pointer, we | 730 | * If one of the devices matches a console pointer, we |
731 | * cannot just call hangup() because that will cause | 731 | * cannot just call hangup() because that will cause |
732 | * tty->count and state->count to go out of sync. | 732 | * tty->count and state->count to go out of sync. |
733 | * So we just call close() the right number of times. | 733 | * So we just call close() the right number of times. |
734 | */ | 734 | */ |
735 | if (cons_filp) { | 735 | if (cons_filp) { |
736 | if (tty->ops->close) | 736 | if (tty->ops->close) |
737 | for (n = 0; n < closecount; n++) | 737 | for (n = 0; n < closecount; n++) |
738 | tty->ops->close(tty, cons_filp); | 738 | tty->ops->close(tty, cons_filp); |
739 | } else if (tty->ops->hangup) | 739 | } else if (tty->ops->hangup) |
740 | tty->ops->hangup(tty); | 740 | tty->ops->hangup(tty); |
741 | /* | 741 | /* |
742 | * We don't want to have driver/ldisc interactions beyond | 742 | * We don't want to have driver/ldisc interactions beyond |
743 | * the ones we did here. The driver layer expects no | 743 | * the ones we did here. The driver layer expects no |
744 | * calls after ->hangup() from the ldisc side. However we | 744 | * calls after ->hangup() from the ldisc side. However we |
745 | * can't yet guarantee all that. | 745 | * can't yet guarantee all that. |
746 | */ | 746 | */ |
747 | set_bit(TTY_HUPPED, &tty->flags); | 747 | set_bit(TTY_HUPPED, &tty->flags); |
748 | tty_unlock(tty); | 748 | tty_unlock(tty); |
749 | 749 | ||
750 | if (f) | 750 | if (f) |
751 | fput(f); | 751 | fput(f); |
752 | } | 752 | } |
753 | 753 | ||
754 | static void do_tty_hangup(struct work_struct *work) | 754 | static void do_tty_hangup(struct work_struct *work) |
755 | { | 755 | { |
756 | struct tty_struct *tty = | 756 | struct tty_struct *tty = |
757 | container_of(work, struct tty_struct, hangup_work); | 757 | container_of(work, struct tty_struct, hangup_work); |
758 | 758 | ||
759 | __tty_hangup(tty, 0); | 759 | __tty_hangup(tty, 0); |
760 | } | 760 | } |
761 | 761 | ||
762 | /** | 762 | /** |
763 | * tty_hangup - trigger a hangup event | 763 | * tty_hangup - trigger a hangup event |
764 | * @tty: tty to hangup | 764 | * @tty: tty to hangup |
765 | * | 765 | * |
766 | * A carrier loss (virtual or otherwise) has occurred on this like | 766 | * A carrier loss (virtual or otherwise) has occurred on this like |
767 | * schedule a hangup sequence to run after this event. | 767 | * schedule a hangup sequence to run after this event. |
768 | */ | 768 | */ |
769 | 769 | ||
770 | void tty_hangup(struct tty_struct *tty) | 770 | void tty_hangup(struct tty_struct *tty) |
771 | { | 771 | { |
772 | #ifdef TTY_DEBUG_HANGUP | 772 | #ifdef TTY_DEBUG_HANGUP |
773 | char buf[64]; | 773 | char buf[64]; |
774 | printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf)); | 774 | printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf)); |
775 | #endif | 775 | #endif |
776 | schedule_work(&tty->hangup_work); | 776 | schedule_work(&tty->hangup_work); |
777 | } | 777 | } |
778 | 778 | ||
779 | EXPORT_SYMBOL(tty_hangup); | 779 | EXPORT_SYMBOL(tty_hangup); |
780 | 780 | ||
781 | /** | 781 | /** |
782 | * tty_vhangup - process vhangup | 782 | * tty_vhangup - process vhangup |
783 | * @tty: tty to hangup | 783 | * @tty: tty to hangup |
784 | * | 784 | * |
785 | * The user has asked via system call for the terminal to be hung up. | 785 | * The user has asked via system call for the terminal to be hung up. |
786 | * We do this synchronously so that when the syscall returns the process | 786 | * We do this synchronously so that when the syscall returns the process |
787 | * is complete. That guarantee is necessary for security reasons. | 787 | * is complete. That guarantee is necessary for security reasons. |
788 | */ | 788 | */ |
789 | 789 | ||
790 | void tty_vhangup(struct tty_struct *tty) | 790 | void tty_vhangup(struct tty_struct *tty) |
791 | { | 791 | { |
792 | #ifdef TTY_DEBUG_HANGUP | 792 | #ifdef TTY_DEBUG_HANGUP |
793 | char buf[64]; | 793 | char buf[64]; |
794 | 794 | ||
795 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); | 795 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); |
796 | #endif | 796 | #endif |
797 | __tty_hangup(tty, 0); | 797 | __tty_hangup(tty, 0); |
798 | } | 798 | } |
799 | 799 | ||
800 | EXPORT_SYMBOL(tty_vhangup); | 800 | EXPORT_SYMBOL(tty_vhangup); |
801 | 801 | ||
802 | 802 | ||
803 | /** | 803 | /** |
804 | * tty_vhangup_self - process vhangup for own ctty | 804 | * tty_vhangup_self - process vhangup for own ctty |
805 | * | 805 | * |
806 | * Perform a vhangup on the current controlling tty | 806 | * Perform a vhangup on the current controlling tty |
807 | */ | 807 | */ |
808 | 808 | ||
809 | void tty_vhangup_self(void) | 809 | void tty_vhangup_self(void) |
810 | { | 810 | { |
811 | struct tty_struct *tty; | 811 | struct tty_struct *tty; |
812 | 812 | ||
813 | tty = get_current_tty(); | 813 | tty = get_current_tty(); |
814 | if (tty) { | 814 | if (tty) { |
815 | tty_vhangup(tty); | 815 | tty_vhangup(tty); |
816 | tty_kref_put(tty); | 816 | tty_kref_put(tty); |
817 | } | 817 | } |
818 | } | 818 | } |
819 | 819 | ||
820 | /** | 820 | /** |
821 | * tty_vhangup_session - hangup session leader exit | 821 | * tty_vhangup_session - hangup session leader exit |
822 | * @tty: tty to hangup | 822 | * @tty: tty to hangup |
823 | * | 823 | * |
824 | * The session leader is exiting and hanging up its controlling terminal. | 824 | * The session leader is exiting and hanging up its controlling terminal. |
825 | * Every process in the foreground process group is signalled SIGHUP. | 825 | * Every process in the foreground process group is signalled SIGHUP. |
826 | * | 826 | * |
827 | * We do this synchronously so that when the syscall returns the process | 827 | * We do this synchronously so that when the syscall returns the process |
828 | * is complete. That guarantee is necessary for security reasons. | 828 | * is complete. That guarantee is necessary for security reasons. |
829 | */ | 829 | */ |
830 | 830 | ||
831 | static void tty_vhangup_session(struct tty_struct *tty) | 831 | static void tty_vhangup_session(struct tty_struct *tty) |
832 | { | 832 | { |
833 | #ifdef TTY_DEBUG_HANGUP | 833 | #ifdef TTY_DEBUG_HANGUP |
834 | char buf[64]; | 834 | char buf[64]; |
835 | 835 | ||
836 | printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty, buf)); | 836 | printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty, buf)); |
837 | #endif | 837 | #endif |
838 | __tty_hangup(tty, 1); | 838 | __tty_hangup(tty, 1); |
839 | } | 839 | } |
840 | 840 | ||
841 | /** | 841 | /** |
842 | * tty_hung_up_p - was tty hung up | 842 | * tty_hung_up_p - was tty hung up |
843 | * @filp: file pointer of tty | 843 | * @filp: file pointer of tty |
844 | * | 844 | * |
845 | * Return true if the tty has been subject to a vhangup or a carrier | 845 | * Return true if the tty has been subject to a vhangup or a carrier |
846 | * loss | 846 | * loss |
847 | */ | 847 | */ |
848 | 848 | ||
849 | int tty_hung_up_p(struct file *filp) | 849 | int tty_hung_up_p(struct file *filp) |
850 | { | 850 | { |
851 | return (filp->f_op == &hung_up_tty_fops); | 851 | return (filp->f_op == &hung_up_tty_fops); |
852 | } | 852 | } |
853 | 853 | ||
854 | EXPORT_SYMBOL(tty_hung_up_p); | 854 | EXPORT_SYMBOL(tty_hung_up_p); |
855 | 855 | ||
856 | /** | 856 | /** |
857 | * disassociate_ctty - disconnect controlling tty | 857 | * disassociate_ctty - disconnect controlling tty |
858 | * @on_exit: true if exiting so need to "hang up" the session | 858 | * @on_exit: true if exiting so need to "hang up" the session |
859 | * | 859 | * |
860 | * This function is typically called only by the session leader, when | 860 | * This function is typically called only by the session leader, when |
861 | * it wants to disassociate itself from its controlling tty. | 861 | * it wants to disassociate itself from its controlling tty. |
862 | * | 862 | * |
863 | * It performs the following functions: | 863 | * It performs the following functions: |
864 | * (1) Sends a SIGHUP and SIGCONT to the foreground process group | 864 | * (1) Sends a SIGHUP and SIGCONT to the foreground process group |
865 | * (2) Clears the tty from being controlling the session | 865 | * (2) Clears the tty from being controlling the session |
866 | * (3) Clears the controlling tty for all processes in the | 866 | * (3) Clears the controlling tty for all processes in the |
867 | * session group. | 867 | * session group. |
868 | * | 868 | * |
869 | * The argument on_exit is set to 1 if called when a process is | 869 | * The argument on_exit is set to 1 if called when a process is |
870 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. | 870 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. |
871 | * | 871 | * |
872 | * Locking: | 872 | * Locking: |
873 | * BTM is taken for hysterical raisins, and held when | 873 | * BTM is taken for hysterical raisins, and held when |
874 | * called from no_tty(). | 874 | * called from no_tty(). |
875 | * tty_mutex is taken to protect tty | 875 | * tty_mutex is taken to protect tty |
876 | * ->siglock is taken to protect ->signal/->sighand | 876 | * ->siglock is taken to protect ->signal/->sighand |
877 | * tasklist_lock is taken to walk process list for sessions | 877 | * tasklist_lock is taken to walk process list for sessions |
878 | * ->siglock is taken to protect ->signal/->sighand | 878 | * ->siglock is taken to protect ->signal/->sighand |
879 | */ | 879 | */ |
880 | 880 | ||
881 | void disassociate_ctty(int on_exit) | 881 | void disassociate_ctty(int on_exit) |
882 | { | 882 | { |
883 | struct tty_struct *tty; | 883 | struct tty_struct *tty; |
884 | 884 | ||
885 | if (!current->signal->leader) | 885 | if (!current->signal->leader) |
886 | return; | 886 | return; |
887 | 887 | ||
888 | tty = get_current_tty(); | 888 | tty = get_current_tty(); |
889 | if (tty) { | 889 | if (tty) { |
890 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) { | 890 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) { |
891 | tty_vhangup_session(tty); | 891 | tty_vhangup_session(tty); |
892 | } else { | 892 | } else { |
893 | struct pid *tty_pgrp = tty_get_pgrp(tty); | 893 | struct pid *tty_pgrp = tty_get_pgrp(tty); |
894 | if (tty_pgrp) { | 894 | if (tty_pgrp) { |
895 | kill_pgrp(tty_pgrp, SIGHUP, on_exit); | 895 | kill_pgrp(tty_pgrp, SIGHUP, on_exit); |
896 | if (!on_exit) | 896 | if (!on_exit) |
897 | kill_pgrp(tty_pgrp, SIGCONT, on_exit); | 897 | kill_pgrp(tty_pgrp, SIGCONT, on_exit); |
898 | put_pid(tty_pgrp); | 898 | put_pid(tty_pgrp); |
899 | } | 899 | } |
900 | } | 900 | } |
901 | tty_kref_put(tty); | 901 | tty_kref_put(tty); |
902 | 902 | ||
903 | } else if (on_exit) { | 903 | } else if (on_exit) { |
904 | struct pid *old_pgrp; | 904 | struct pid *old_pgrp; |
905 | spin_lock_irq(¤t->sighand->siglock); | 905 | spin_lock_irq(¤t->sighand->siglock); |
906 | old_pgrp = current->signal->tty_old_pgrp; | 906 | old_pgrp = current->signal->tty_old_pgrp; |
907 | current->signal->tty_old_pgrp = NULL; | 907 | current->signal->tty_old_pgrp = NULL; |
908 | spin_unlock_irq(¤t->sighand->siglock); | 908 | spin_unlock_irq(¤t->sighand->siglock); |
909 | if (old_pgrp) { | 909 | if (old_pgrp) { |
910 | kill_pgrp(old_pgrp, SIGHUP, on_exit); | 910 | kill_pgrp(old_pgrp, SIGHUP, on_exit); |
911 | kill_pgrp(old_pgrp, SIGCONT, on_exit); | 911 | kill_pgrp(old_pgrp, SIGCONT, on_exit); |
912 | put_pid(old_pgrp); | 912 | put_pid(old_pgrp); |
913 | } | 913 | } |
914 | return; | 914 | return; |
915 | } | 915 | } |
916 | 916 | ||
917 | spin_lock_irq(¤t->sighand->siglock); | 917 | spin_lock_irq(¤t->sighand->siglock); |
918 | put_pid(current->signal->tty_old_pgrp); | 918 | put_pid(current->signal->tty_old_pgrp); |
919 | current->signal->tty_old_pgrp = NULL; | 919 | current->signal->tty_old_pgrp = NULL; |
920 | 920 | ||
921 | tty = tty_kref_get(current->signal->tty); | 921 | tty = tty_kref_get(current->signal->tty); |
922 | if (tty) { | 922 | if (tty) { |
923 | unsigned long flags; | 923 | unsigned long flags; |
924 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 924 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
925 | put_pid(tty->session); | 925 | put_pid(tty->session); |
926 | put_pid(tty->pgrp); | 926 | put_pid(tty->pgrp); |
927 | tty->session = NULL; | 927 | tty->session = NULL; |
928 | tty->pgrp = NULL; | 928 | tty->pgrp = NULL; |
929 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 929 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
930 | tty_kref_put(tty); | 930 | tty_kref_put(tty); |
931 | } else { | 931 | } else { |
932 | #ifdef TTY_DEBUG_HANGUP | 932 | #ifdef TTY_DEBUG_HANGUP |
933 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" | 933 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" |
934 | " = NULL", tty); | 934 | " = NULL", tty); |
935 | #endif | 935 | #endif |
936 | } | 936 | } |
937 | 937 | ||
938 | spin_unlock_irq(¤t->sighand->siglock); | 938 | spin_unlock_irq(¤t->sighand->siglock); |
939 | /* Now clear signal->tty under the lock */ | 939 | /* Now clear signal->tty under the lock */ |
940 | read_lock(&tasklist_lock); | 940 | read_lock(&tasklist_lock); |
941 | session_clear_tty(task_session(current)); | 941 | session_clear_tty(task_session(current)); |
942 | read_unlock(&tasklist_lock); | 942 | read_unlock(&tasklist_lock); |
943 | } | 943 | } |
944 | 944 | ||
945 | /** | 945 | /** |
946 | * | 946 | * |
947 | * no_tty - Ensure the current process does not have a controlling tty | 947 | * no_tty - Ensure the current process does not have a controlling tty |
948 | */ | 948 | */ |
949 | void no_tty(void) | 949 | void no_tty(void) |
950 | { | 950 | { |
951 | /* FIXME: Review locking here. The tty_lock never covered any race | 951 | /* FIXME: Review locking here. The tty_lock never covered any race |
952 | between a new association and proc_clear_tty but possible we need | 952 | between a new association and proc_clear_tty but possible we need |
953 | to protect against this anyway */ | 953 | to protect against this anyway */ |
954 | struct task_struct *tsk = current; | 954 | struct task_struct *tsk = current; |
955 | disassociate_ctty(0); | 955 | disassociate_ctty(0); |
956 | proc_clear_tty(tsk); | 956 | proc_clear_tty(tsk); |
957 | } | 957 | } |
958 | 958 | ||
959 | 959 | ||
960 | /** | 960 | /** |
961 | * stop_tty - propagate flow control | 961 | * stop_tty - propagate flow control |
962 | * @tty: tty to stop | 962 | * @tty: tty to stop |
963 | * | 963 | * |
964 | * Perform flow control to the driver. May be called | 964 | * Perform flow control to the driver. May be called |
965 | * on an already stopped device and will not re-call the driver | 965 | * on an already stopped device and will not re-call the driver |
966 | * method. | 966 | * method. |
967 | * | 967 | * |
968 | * This functionality is used by both the line disciplines for | 968 | * This functionality is used by both the line disciplines for |
969 | * halting incoming flow and by the driver. It may therefore be | 969 | * halting incoming flow and by the driver. It may therefore be |
970 | * called from any context, may be under the tty atomic_write_lock | 970 | * called from any context, may be under the tty atomic_write_lock |
971 | * but not always. | 971 | * but not always. |
972 | * | 972 | * |
973 | * Locking: | 973 | * Locking: |
974 | * flow_lock | 974 | * flow_lock |
975 | */ | 975 | */ |
976 | 976 | ||
977 | void __stop_tty(struct tty_struct *tty) | 977 | void __stop_tty(struct tty_struct *tty) |
978 | { | 978 | { |
979 | if (tty->stopped) | 979 | if (tty->stopped) |
980 | return; | 980 | return; |
981 | tty->stopped = 1; | 981 | tty->stopped = 1; |
982 | if (tty->ops->stop) | 982 | if (tty->ops->stop) |
983 | tty->ops->stop(tty); | 983 | tty->ops->stop(tty); |
984 | } | 984 | } |
985 | 985 | ||
986 | void stop_tty(struct tty_struct *tty) | 986 | void stop_tty(struct tty_struct *tty) |
987 | { | 987 | { |
988 | unsigned long flags; | 988 | unsigned long flags; |
989 | 989 | ||
990 | spin_lock_irqsave(&tty->flow_lock, flags); | 990 | spin_lock_irqsave(&tty->flow_lock, flags); |
991 | __stop_tty(tty); | 991 | __stop_tty(tty); |
992 | spin_unlock_irqrestore(&tty->flow_lock, flags); | 992 | spin_unlock_irqrestore(&tty->flow_lock, flags); |
993 | } | 993 | } |
994 | EXPORT_SYMBOL(stop_tty); | 994 | EXPORT_SYMBOL(stop_tty); |
995 | 995 | ||
996 | /** | 996 | /** |
997 | * start_tty - propagate flow control | 997 | * start_tty - propagate flow control |
998 | * @tty: tty to start | 998 | * @tty: tty to start |
999 | * | 999 | * |
1000 | * Start a tty that has been stopped if at all possible. If this | 1000 | * Start a tty that has been stopped if at all possible. If this |
1001 | * tty was previous stopped and is now being started, the driver | 1001 | * tty was previous stopped and is now being started, the driver |
1002 | * start method is invoked and the line discipline woken. | 1002 | * start method is invoked and the line discipline woken. |
1003 | * | 1003 | * |
1004 | * Locking: | 1004 | * Locking: |
1005 | * flow_lock | 1005 | * flow_lock |
1006 | */ | 1006 | */ |
1007 | 1007 | ||
1008 | void __start_tty(struct tty_struct *tty) | 1008 | void __start_tty(struct tty_struct *tty) |
1009 | { | 1009 | { |
1010 | if (!tty->stopped || tty->flow_stopped) | 1010 | if (!tty->stopped || tty->flow_stopped) |
1011 | return; | 1011 | return; |
1012 | tty->stopped = 0; | 1012 | tty->stopped = 0; |
1013 | if (tty->ops->start) | 1013 | if (tty->ops->start) |
1014 | tty->ops->start(tty); | 1014 | tty->ops->start(tty); |
1015 | tty_wakeup(tty); | 1015 | tty_wakeup(tty); |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | void start_tty(struct tty_struct *tty) | 1018 | void start_tty(struct tty_struct *tty) |
1019 | { | 1019 | { |
1020 | unsigned long flags; | 1020 | unsigned long flags; |
1021 | 1021 | ||
1022 | spin_lock_irqsave(&tty->flow_lock, flags); | 1022 | spin_lock_irqsave(&tty->flow_lock, flags); |
1023 | __start_tty(tty); | 1023 | __start_tty(tty); |
1024 | spin_unlock_irqrestore(&tty->flow_lock, flags); | 1024 | spin_unlock_irqrestore(&tty->flow_lock, flags); |
1025 | } | 1025 | } |
1026 | EXPORT_SYMBOL(start_tty); | 1026 | EXPORT_SYMBOL(start_tty); |
1027 | 1027 | ||
1028 | /* We limit tty time update visibility to every 8 seconds or so. */ | 1028 | /* We limit tty time update visibility to every 8 seconds or so. */ |
1029 | static void tty_update_time(struct timespec *time) | 1029 | static void tty_update_time(struct timespec *time) |
1030 | { | 1030 | { |
1031 | unsigned long sec = get_seconds() & ~7; | 1031 | unsigned long sec = get_seconds(); |
1032 | if ((long)(sec - time->tv_sec) > 0) | 1032 | if (abs(sec - time->tv_sec) & ~7) |
1033 | time->tv_sec = sec; | 1033 | time->tv_sec = sec; |
1034 | } | 1034 | } |
1035 | 1035 | ||
1036 | /** | 1036 | /** |
1037 | * tty_read - read method for tty device files | 1037 | * tty_read - read method for tty device files |
1038 | * @file: pointer to tty file | 1038 | * @file: pointer to tty file |
1039 | * @buf: user buffer | 1039 | * @buf: user buffer |
1040 | * @count: size of user buffer | 1040 | * @count: size of user buffer |
1041 | * @ppos: unused | 1041 | * @ppos: unused |
1042 | * | 1042 | * |
1043 | * Perform the read system call function on this terminal device. Checks | 1043 | * Perform the read system call function on this terminal device. Checks |
1044 | * for hung up devices before calling the line discipline method. | 1044 | * for hung up devices before calling the line discipline method. |
1045 | * | 1045 | * |
1046 | * Locking: | 1046 | * Locking: |
1047 | * Locks the line discipline internally while needed. Multiple | 1047 | * Locks the line discipline internally while needed. Multiple |
1048 | * read calls may be outstanding in parallel. | 1048 | * read calls may be outstanding in parallel. |
1049 | */ | 1049 | */ |
1050 | 1050 | ||
1051 | static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | 1051 | static ssize_t tty_read(struct file *file, char __user *buf, size_t count, |
1052 | loff_t *ppos) | 1052 | loff_t *ppos) |
1053 | { | 1053 | { |
1054 | int i; | 1054 | int i; |
1055 | struct inode *inode = file_inode(file); | 1055 | struct inode *inode = file_inode(file); |
1056 | struct tty_struct *tty = file_tty(file); | 1056 | struct tty_struct *tty = file_tty(file); |
1057 | struct tty_ldisc *ld; | 1057 | struct tty_ldisc *ld; |
1058 | 1058 | ||
1059 | if (tty_paranoia_check(tty, inode, "tty_read")) | 1059 | if (tty_paranoia_check(tty, inode, "tty_read")) |
1060 | return -EIO; | 1060 | return -EIO; |
1061 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) | 1061 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) |
1062 | return -EIO; | 1062 | return -EIO; |
1063 | 1063 | ||
1064 | /* We want to wait for the line discipline to sort out in this | 1064 | /* We want to wait for the line discipline to sort out in this |
1065 | situation */ | 1065 | situation */ |
1066 | ld = tty_ldisc_ref_wait(tty); | 1066 | ld = tty_ldisc_ref_wait(tty); |
1067 | if (ld->ops->read) | 1067 | if (ld->ops->read) |
1068 | i = ld->ops->read(tty, file, buf, count); | 1068 | i = ld->ops->read(tty, file, buf, count); |
1069 | else | 1069 | else |
1070 | i = -EIO; | 1070 | i = -EIO; |
1071 | tty_ldisc_deref(ld); | 1071 | tty_ldisc_deref(ld); |
1072 | 1072 | ||
1073 | if (i > 0) | 1073 | if (i > 0) |
1074 | tty_update_time(&inode->i_atime); | 1074 | tty_update_time(&inode->i_atime); |
1075 | 1075 | ||
1076 | return i; | 1076 | return i; |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | static void tty_write_unlock(struct tty_struct *tty) | 1079 | static void tty_write_unlock(struct tty_struct *tty) |
1080 | { | 1080 | { |
1081 | mutex_unlock(&tty->atomic_write_lock); | 1081 | mutex_unlock(&tty->atomic_write_lock); |
1082 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); | 1082 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
1083 | } | 1083 | } |
1084 | 1084 | ||
1085 | static int tty_write_lock(struct tty_struct *tty, int ndelay) | 1085 | static int tty_write_lock(struct tty_struct *tty, int ndelay) |
1086 | { | 1086 | { |
1087 | if (!mutex_trylock(&tty->atomic_write_lock)) { | 1087 | if (!mutex_trylock(&tty->atomic_write_lock)) { |
1088 | if (ndelay) | 1088 | if (ndelay) |
1089 | return -EAGAIN; | 1089 | return -EAGAIN; |
1090 | if (mutex_lock_interruptible(&tty->atomic_write_lock)) | 1090 | if (mutex_lock_interruptible(&tty->atomic_write_lock)) |
1091 | return -ERESTARTSYS; | 1091 | return -ERESTARTSYS; |
1092 | } | 1092 | } |
1093 | return 0; | 1093 | return 0; |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | /* | 1096 | /* |
1097 | * Split writes up in sane blocksizes to avoid | 1097 | * Split writes up in sane blocksizes to avoid |
1098 | * denial-of-service type attacks | 1098 | * denial-of-service type attacks |
1099 | */ | 1099 | */ |
1100 | static inline ssize_t do_tty_write( | 1100 | static inline ssize_t do_tty_write( |
1101 | ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t), | 1101 | ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t), |
1102 | struct tty_struct *tty, | 1102 | struct tty_struct *tty, |
1103 | struct file *file, | 1103 | struct file *file, |
1104 | const char __user *buf, | 1104 | const char __user *buf, |
1105 | size_t count) | 1105 | size_t count) |
1106 | { | 1106 | { |
1107 | ssize_t ret, written = 0; | 1107 | ssize_t ret, written = 0; |
1108 | unsigned int chunk; | 1108 | unsigned int chunk; |
1109 | 1109 | ||
1110 | ret = tty_write_lock(tty, file->f_flags & O_NDELAY); | 1110 | ret = tty_write_lock(tty, file->f_flags & O_NDELAY); |
1111 | if (ret < 0) | 1111 | if (ret < 0) |
1112 | return ret; | 1112 | return ret; |
1113 | 1113 | ||
1114 | /* | 1114 | /* |
1115 | * We chunk up writes into a temporary buffer. This | 1115 | * We chunk up writes into a temporary buffer. This |
1116 | * simplifies low-level drivers immensely, since they | 1116 | * simplifies low-level drivers immensely, since they |
1117 | * don't have locking issues and user mode accesses. | 1117 | * don't have locking issues and user mode accesses. |
1118 | * | 1118 | * |
1119 | * But if TTY_NO_WRITE_SPLIT is set, we should use a | 1119 | * But if TTY_NO_WRITE_SPLIT is set, we should use a |
1120 | * big chunk-size.. | 1120 | * big chunk-size.. |
1121 | * | 1121 | * |
1122 | * The default chunk-size is 2kB, because the NTTY | 1122 | * The default chunk-size is 2kB, because the NTTY |
1123 | * layer has problems with bigger chunks. It will | 1123 | * layer has problems with bigger chunks. It will |
1124 | * claim to be able to handle more characters than | 1124 | * claim to be able to handle more characters than |
1125 | * it actually does. | 1125 | * it actually does. |
1126 | * | 1126 | * |
1127 | * FIXME: This can probably go away now except that 64K chunks | 1127 | * FIXME: This can probably go away now except that 64K chunks |
1128 | * are too likely to fail unless switched to vmalloc... | 1128 | * are too likely to fail unless switched to vmalloc... |
1129 | */ | 1129 | */ |
1130 | chunk = 2048; | 1130 | chunk = 2048; |
1131 | if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) | 1131 | if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) |
1132 | chunk = 65536; | 1132 | chunk = 65536; |
1133 | if (count < chunk) | 1133 | if (count < chunk) |
1134 | chunk = count; | 1134 | chunk = count; |
1135 | 1135 | ||
1136 | /* write_buf/write_cnt is protected by the atomic_write_lock mutex */ | 1136 | /* write_buf/write_cnt is protected by the atomic_write_lock mutex */ |
1137 | if (tty->write_cnt < chunk) { | 1137 | if (tty->write_cnt < chunk) { |
1138 | unsigned char *buf_chunk; | 1138 | unsigned char *buf_chunk; |
1139 | 1139 | ||
1140 | if (chunk < 1024) | 1140 | if (chunk < 1024) |
1141 | chunk = 1024; | 1141 | chunk = 1024; |
1142 | 1142 | ||
1143 | buf_chunk = kmalloc(chunk, GFP_KERNEL); | 1143 | buf_chunk = kmalloc(chunk, GFP_KERNEL); |
1144 | if (!buf_chunk) { | 1144 | if (!buf_chunk) { |
1145 | ret = -ENOMEM; | 1145 | ret = -ENOMEM; |
1146 | goto out; | 1146 | goto out; |
1147 | } | 1147 | } |
1148 | kfree(tty->write_buf); | 1148 | kfree(tty->write_buf); |
1149 | tty->write_cnt = chunk; | 1149 | tty->write_cnt = chunk; |
1150 | tty->write_buf = buf_chunk; | 1150 | tty->write_buf = buf_chunk; |
1151 | } | 1151 | } |
1152 | 1152 | ||
1153 | /* Do the write .. */ | 1153 | /* Do the write .. */ |
1154 | for (;;) { | 1154 | for (;;) { |
1155 | size_t size = count; | 1155 | size_t size = count; |
1156 | if (size > chunk) | 1156 | if (size > chunk) |
1157 | size = chunk; | 1157 | size = chunk; |
1158 | ret = -EFAULT; | 1158 | ret = -EFAULT; |
1159 | if (copy_from_user(tty->write_buf, buf, size)) | 1159 | if (copy_from_user(tty->write_buf, buf, size)) |
1160 | break; | 1160 | break; |
1161 | ret = write(tty, file, tty->write_buf, size); | 1161 | ret = write(tty, file, tty->write_buf, size); |
1162 | if (ret <= 0) | 1162 | if (ret <= 0) |
1163 | break; | 1163 | break; |
1164 | written += ret; | 1164 | written += ret; |
1165 | buf += ret; | 1165 | buf += ret; |
1166 | count -= ret; | 1166 | count -= ret; |
1167 | if (!count) | 1167 | if (!count) |
1168 | break; | 1168 | break; |
1169 | ret = -ERESTARTSYS; | 1169 | ret = -ERESTARTSYS; |
1170 | if (signal_pending(current)) | 1170 | if (signal_pending(current)) |
1171 | break; | 1171 | break; |
1172 | cond_resched(); | 1172 | cond_resched(); |
1173 | } | 1173 | } |
1174 | if (written) { | 1174 | if (written) { |
1175 | tty_update_time(&file_inode(file)->i_mtime); | 1175 | tty_update_time(&file_inode(file)->i_mtime); |
1176 | ret = written; | 1176 | ret = written; |
1177 | } | 1177 | } |
1178 | out: | 1178 | out: |
1179 | tty_write_unlock(tty); | 1179 | tty_write_unlock(tty); |
1180 | return ret; | 1180 | return ret; |
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | /** | 1183 | /** |
1184 | * tty_write_message - write a message to a certain tty, not just the console. | 1184 | * tty_write_message - write a message to a certain tty, not just the console. |
1185 | * @tty: the destination tty_struct | 1185 | * @tty: the destination tty_struct |
1186 | * @msg: the message to write | 1186 | * @msg: the message to write |
1187 | * | 1187 | * |
1188 | * This is used for messages that need to be redirected to a specific tty. | 1188 | * This is used for messages that need to be redirected to a specific tty. |
1189 | * We don't put it into the syslog queue right now maybe in the future if | 1189 | * We don't put it into the syslog queue right now maybe in the future if |
1190 | * really needed. | 1190 | * really needed. |
1191 | * | 1191 | * |
1192 | * We must still hold the BTM and test the CLOSING flag for the moment. | 1192 | * We must still hold the BTM and test the CLOSING flag for the moment. |
1193 | */ | 1193 | */ |
1194 | 1194 | ||
1195 | void tty_write_message(struct tty_struct *tty, char *msg) | 1195 | void tty_write_message(struct tty_struct *tty, char *msg) |
1196 | { | 1196 | { |
1197 | if (tty) { | 1197 | if (tty) { |
1198 | mutex_lock(&tty->atomic_write_lock); | 1198 | mutex_lock(&tty->atomic_write_lock); |
1199 | tty_lock(tty); | 1199 | tty_lock(tty); |
1200 | if (tty->ops->write && tty->count > 0) { | 1200 | if (tty->ops->write && tty->count > 0) { |
1201 | tty_unlock(tty); | 1201 | tty_unlock(tty); |
1202 | tty->ops->write(tty, msg, strlen(msg)); | 1202 | tty->ops->write(tty, msg, strlen(msg)); |
1203 | } else | 1203 | } else |
1204 | tty_unlock(tty); | 1204 | tty_unlock(tty); |
1205 | tty_write_unlock(tty); | 1205 | tty_write_unlock(tty); |
1206 | } | 1206 | } |
1207 | return; | 1207 | return; |
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | 1210 | ||
1211 | /** | 1211 | /** |
1212 | * tty_write - write method for tty device file | 1212 | * tty_write - write method for tty device file |
1213 | * @file: tty file pointer | 1213 | * @file: tty file pointer |
1214 | * @buf: user data to write | 1214 | * @buf: user data to write |
1215 | * @count: bytes to write | 1215 | * @count: bytes to write |
1216 | * @ppos: unused | 1216 | * @ppos: unused |
1217 | * | 1217 | * |
1218 | * Write data to a tty device via the line discipline. | 1218 | * Write data to a tty device via the line discipline. |
1219 | * | 1219 | * |
1220 | * Locking: | 1220 | * Locking: |
1221 | * Locks the line discipline as required | 1221 | * Locks the line discipline as required |
1222 | * Writes to the tty driver are serialized by the atomic_write_lock | 1222 | * Writes to the tty driver are serialized by the atomic_write_lock |
1223 | * and are then processed in chunks to the device. The line discipline | 1223 | * and are then processed in chunks to the device. The line discipline |
1224 | * write method will not be invoked in parallel for each device. | 1224 | * write method will not be invoked in parallel for each device. |
1225 | */ | 1225 | */ |
1226 | 1226 | ||
1227 | static ssize_t tty_write(struct file *file, const char __user *buf, | 1227 | static ssize_t tty_write(struct file *file, const char __user *buf, |
1228 | size_t count, loff_t *ppos) | 1228 | size_t count, loff_t *ppos) |
1229 | { | 1229 | { |
1230 | struct tty_struct *tty = file_tty(file); | 1230 | struct tty_struct *tty = file_tty(file); |
1231 | struct tty_ldisc *ld; | 1231 | struct tty_ldisc *ld; |
1232 | ssize_t ret; | 1232 | ssize_t ret; |
1233 | 1233 | ||
1234 | if (tty_paranoia_check(tty, file_inode(file), "tty_write")) | 1234 | if (tty_paranoia_check(tty, file_inode(file), "tty_write")) |
1235 | return -EIO; | 1235 | return -EIO; |
1236 | if (!tty || !tty->ops->write || | 1236 | if (!tty || !tty->ops->write || |
1237 | (test_bit(TTY_IO_ERROR, &tty->flags))) | 1237 | (test_bit(TTY_IO_ERROR, &tty->flags))) |
1238 | return -EIO; | 1238 | return -EIO; |
1239 | /* Short term debug to catch buggy drivers */ | 1239 | /* Short term debug to catch buggy drivers */ |
1240 | if (tty->ops->write_room == NULL) | 1240 | if (tty->ops->write_room == NULL) |
1241 | printk(KERN_ERR "tty driver %s lacks a write_room method.\n", | 1241 | printk(KERN_ERR "tty driver %s lacks a write_room method.\n", |
1242 | tty->driver->name); | 1242 | tty->driver->name); |
1243 | ld = tty_ldisc_ref_wait(tty); | 1243 | ld = tty_ldisc_ref_wait(tty); |
1244 | if (!ld->ops->write) | 1244 | if (!ld->ops->write) |
1245 | ret = -EIO; | 1245 | ret = -EIO; |
1246 | else | 1246 | else |
1247 | ret = do_tty_write(ld->ops->write, tty, file, buf, count); | 1247 | ret = do_tty_write(ld->ops->write, tty, file, buf, count); |
1248 | tty_ldisc_deref(ld); | 1248 | tty_ldisc_deref(ld); |
1249 | return ret; | 1249 | return ret; |
1250 | } | 1250 | } |
1251 | 1251 | ||
1252 | ssize_t redirected_tty_write(struct file *file, const char __user *buf, | 1252 | ssize_t redirected_tty_write(struct file *file, const char __user *buf, |
1253 | size_t count, loff_t *ppos) | 1253 | size_t count, loff_t *ppos) |
1254 | { | 1254 | { |
1255 | struct file *p = NULL; | 1255 | struct file *p = NULL; |
1256 | 1256 | ||
1257 | spin_lock(&redirect_lock); | 1257 | spin_lock(&redirect_lock); |
1258 | if (redirect) | 1258 | if (redirect) |
1259 | p = get_file(redirect); | 1259 | p = get_file(redirect); |
1260 | spin_unlock(&redirect_lock); | 1260 | spin_unlock(&redirect_lock); |
1261 | 1261 | ||
1262 | if (p) { | 1262 | if (p) { |
1263 | ssize_t res; | 1263 | ssize_t res; |
1264 | res = vfs_write(p, buf, count, &p->f_pos); | 1264 | res = vfs_write(p, buf, count, &p->f_pos); |
1265 | fput(p); | 1265 | fput(p); |
1266 | return res; | 1266 | return res; |
1267 | } | 1267 | } |
1268 | return tty_write(file, buf, count, ppos); | 1268 | return tty_write(file, buf, count, ppos); |
1269 | } | 1269 | } |
1270 | 1270 | ||
1271 | /** | 1271 | /** |
1272 | * tty_send_xchar - send priority character | 1272 | * tty_send_xchar - send priority character |
1273 | * | 1273 | * |
1274 | * Send a high priority character to the tty even if stopped | 1274 | * Send a high priority character to the tty even if stopped |
1275 | * | 1275 | * |
1276 | * Locking: none for xchar method, write ordering for write method. | 1276 | * Locking: none for xchar method, write ordering for write method. |
1277 | */ | 1277 | */ |
1278 | 1278 | ||
1279 | int tty_send_xchar(struct tty_struct *tty, char ch) | 1279 | int tty_send_xchar(struct tty_struct *tty, char ch) |
1280 | { | 1280 | { |
1281 | int was_stopped = tty->stopped; | 1281 | int was_stopped = tty->stopped; |
1282 | 1282 | ||
1283 | if (tty->ops->send_xchar) { | 1283 | if (tty->ops->send_xchar) { |
1284 | tty->ops->send_xchar(tty, ch); | 1284 | tty->ops->send_xchar(tty, ch); |
1285 | return 0; | 1285 | return 0; |
1286 | } | 1286 | } |
1287 | 1287 | ||
1288 | if (tty_write_lock(tty, 0) < 0) | 1288 | if (tty_write_lock(tty, 0) < 0) |
1289 | return -ERESTARTSYS; | 1289 | return -ERESTARTSYS; |
1290 | 1290 | ||
1291 | if (was_stopped) | 1291 | if (was_stopped) |
1292 | start_tty(tty); | 1292 | start_tty(tty); |
1293 | tty->ops->write(tty, &ch, 1); | 1293 | tty->ops->write(tty, &ch, 1); |
1294 | if (was_stopped) | 1294 | if (was_stopped) |
1295 | stop_tty(tty); | 1295 | stop_tty(tty); |
1296 | tty_write_unlock(tty); | 1296 | tty_write_unlock(tty); |
1297 | return 0; | 1297 | return 0; |
1298 | } | 1298 | } |
1299 | 1299 | ||
1300 | static char ptychar[] = "pqrstuvwxyzabcde"; | 1300 | static char ptychar[] = "pqrstuvwxyzabcde"; |
1301 | 1301 | ||
1302 | /** | 1302 | /** |
1303 | * pty_line_name - generate name for a pty | 1303 | * pty_line_name - generate name for a pty |
1304 | * @driver: the tty driver in use | 1304 | * @driver: the tty driver in use |
1305 | * @index: the minor number | 1305 | * @index: the minor number |
1306 | * @p: output buffer of at least 6 bytes | 1306 | * @p: output buffer of at least 6 bytes |
1307 | * | 1307 | * |
1308 | * Generate a name from a driver reference and write it to the output | 1308 | * Generate a name from a driver reference and write it to the output |
1309 | * buffer. | 1309 | * buffer. |
1310 | * | 1310 | * |
1311 | * Locking: None | 1311 | * Locking: None |
1312 | */ | 1312 | */ |
1313 | static void pty_line_name(struct tty_driver *driver, int index, char *p) | 1313 | static void pty_line_name(struct tty_driver *driver, int index, char *p) |
1314 | { | 1314 | { |
1315 | int i = index + driver->name_base; | 1315 | int i = index + driver->name_base; |
1316 | /* ->name is initialized to "ttyp", but "tty" is expected */ | 1316 | /* ->name is initialized to "ttyp", but "tty" is expected */ |
1317 | sprintf(p, "%s%c%x", | 1317 | sprintf(p, "%s%c%x", |
1318 | driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name, | 1318 | driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name, |
1319 | ptychar[i >> 4 & 0xf], i & 0xf); | 1319 | ptychar[i >> 4 & 0xf], i & 0xf); |
1320 | } | 1320 | } |
1321 | 1321 | ||
1322 | /** | 1322 | /** |
1323 | * tty_line_name - generate name for a tty | 1323 | * tty_line_name - generate name for a tty |
1324 | * @driver: the tty driver in use | 1324 | * @driver: the tty driver in use |
1325 | * @index: the minor number | 1325 | * @index: the minor number |
1326 | * @p: output buffer of at least 7 bytes | 1326 | * @p: output buffer of at least 7 bytes |
1327 | * | 1327 | * |
1328 | * Generate a name from a driver reference and write it to the output | 1328 | * Generate a name from a driver reference and write it to the output |
1329 | * buffer. | 1329 | * buffer. |
1330 | * | 1330 | * |
1331 | * Locking: None | 1331 | * Locking: None |
1332 | */ | 1332 | */ |
1333 | static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p) | 1333 | static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p) |
1334 | { | 1334 | { |
1335 | if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE) | 1335 | if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE) |
1336 | return sprintf(p, "%s", driver->name); | 1336 | return sprintf(p, "%s", driver->name); |
1337 | else | 1337 | else |
1338 | return sprintf(p, "%s%d", driver->name, | 1338 | return sprintf(p, "%s%d", driver->name, |
1339 | index + driver->name_base); | 1339 | index + driver->name_base); |
1340 | } | 1340 | } |
1341 | 1341 | ||
1342 | /** | 1342 | /** |
1343 | * tty_driver_lookup_tty() - find an existing tty, if any | 1343 | * tty_driver_lookup_tty() - find an existing tty, if any |
1344 | * @driver: the driver for the tty | 1344 | * @driver: the driver for the tty |
1345 | * @idx: the minor number | 1345 | * @idx: the minor number |
1346 | * | 1346 | * |
1347 | * Return the tty, if found. If not found, return NULL or ERR_PTR() if the | 1347 | * Return the tty, if found. If not found, return NULL or ERR_PTR() if the |
1348 | * driver lookup() method returns an error. | 1348 | * driver lookup() method returns an error. |
1349 | * | 1349 | * |
1350 | * Locking: tty_mutex must be held. If the tty is found, bump the tty kref. | 1350 | * Locking: tty_mutex must be held. If the tty is found, bump the tty kref. |
1351 | */ | 1351 | */ |
1352 | static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, | 1352 | static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, |
1353 | struct inode *inode, int idx) | 1353 | struct inode *inode, int idx) |
1354 | { | 1354 | { |
1355 | struct tty_struct *tty; | 1355 | struct tty_struct *tty; |
1356 | 1356 | ||
1357 | if (driver->ops->lookup) | 1357 | if (driver->ops->lookup) |
1358 | tty = driver->ops->lookup(driver, inode, idx); | 1358 | tty = driver->ops->lookup(driver, inode, idx); |
1359 | else | 1359 | else |
1360 | tty = driver->ttys[idx]; | 1360 | tty = driver->ttys[idx]; |
1361 | 1361 | ||
1362 | if (!IS_ERR(tty)) | 1362 | if (!IS_ERR(tty)) |
1363 | tty_kref_get(tty); | 1363 | tty_kref_get(tty); |
1364 | return tty; | 1364 | return tty; |
1365 | } | 1365 | } |
1366 | 1366 | ||
1367 | /** | 1367 | /** |
1368 | * tty_init_termios - helper for termios setup | 1368 | * tty_init_termios - helper for termios setup |
1369 | * @tty: the tty to set up | 1369 | * @tty: the tty to set up |
1370 | * | 1370 | * |
1371 | * Initialise the termios structures for this tty. Thus runs under | 1371 | * Initialise the termios structures for this tty. Thus runs under |
1372 | * the tty_mutex currently so we can be relaxed about ordering. | 1372 | * the tty_mutex currently so we can be relaxed about ordering. |
1373 | */ | 1373 | */ |
1374 | 1374 | ||
1375 | int tty_init_termios(struct tty_struct *tty) | 1375 | int tty_init_termios(struct tty_struct *tty) |
1376 | { | 1376 | { |
1377 | struct ktermios *tp; | 1377 | struct ktermios *tp; |
1378 | int idx = tty->index; | 1378 | int idx = tty->index; |
1379 | 1379 | ||
1380 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) | 1380 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1381 | tty->termios = tty->driver->init_termios; | 1381 | tty->termios = tty->driver->init_termios; |
1382 | else { | 1382 | else { |
1383 | /* Check for lazy saved data */ | 1383 | /* Check for lazy saved data */ |
1384 | tp = tty->driver->termios[idx]; | 1384 | tp = tty->driver->termios[idx]; |
1385 | if (tp != NULL) | 1385 | if (tp != NULL) |
1386 | tty->termios = *tp; | 1386 | tty->termios = *tp; |
1387 | else | 1387 | else |
1388 | tty->termios = tty->driver->init_termios; | 1388 | tty->termios = tty->driver->init_termios; |
1389 | } | 1389 | } |
1390 | /* Compatibility until drivers always set this */ | 1390 | /* Compatibility until drivers always set this */ |
1391 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); | 1391 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); |
1392 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); | 1392 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); |
1393 | return 0; | 1393 | return 0; |
1394 | } | 1394 | } |
1395 | EXPORT_SYMBOL_GPL(tty_init_termios); | 1395 | EXPORT_SYMBOL_GPL(tty_init_termios); |
1396 | 1396 | ||
1397 | int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty) | 1397 | int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty) |
1398 | { | 1398 | { |
1399 | int ret = tty_init_termios(tty); | 1399 | int ret = tty_init_termios(tty); |
1400 | if (ret) | 1400 | if (ret) |
1401 | return ret; | 1401 | return ret; |
1402 | 1402 | ||
1403 | tty_driver_kref_get(driver); | 1403 | tty_driver_kref_get(driver); |
1404 | tty->count++; | 1404 | tty->count++; |
1405 | driver->ttys[tty->index] = tty; | 1405 | driver->ttys[tty->index] = tty; |
1406 | return 0; | 1406 | return 0; |
1407 | } | 1407 | } |
1408 | EXPORT_SYMBOL_GPL(tty_standard_install); | 1408 | EXPORT_SYMBOL_GPL(tty_standard_install); |
1409 | 1409 | ||
1410 | /** | 1410 | /** |
1411 | * tty_driver_install_tty() - install a tty entry in the driver | 1411 | * tty_driver_install_tty() - install a tty entry in the driver |
1412 | * @driver: the driver for the tty | 1412 | * @driver: the driver for the tty |
1413 | * @tty: the tty | 1413 | * @tty: the tty |
1414 | * | 1414 | * |
1415 | * Install a tty object into the driver tables. The tty->index field | 1415 | * Install a tty object into the driver tables. The tty->index field |
1416 | * will be set by the time this is called. This method is responsible | 1416 | * will be set by the time this is called. This method is responsible |
1417 | * for ensuring any need additional structures are allocated and | 1417 | * for ensuring any need additional structures are allocated and |
1418 | * configured. | 1418 | * configured. |
1419 | * | 1419 | * |
1420 | * Locking: tty_mutex for now | 1420 | * Locking: tty_mutex for now |
1421 | */ | 1421 | */ |
1422 | static int tty_driver_install_tty(struct tty_driver *driver, | 1422 | static int tty_driver_install_tty(struct tty_driver *driver, |
1423 | struct tty_struct *tty) | 1423 | struct tty_struct *tty) |
1424 | { | 1424 | { |
1425 | return driver->ops->install ? driver->ops->install(driver, tty) : | 1425 | return driver->ops->install ? driver->ops->install(driver, tty) : |
1426 | tty_standard_install(driver, tty); | 1426 | tty_standard_install(driver, tty); |
1427 | } | 1427 | } |
1428 | 1428 | ||
1429 | /** | 1429 | /** |
1430 | * tty_driver_remove_tty() - remove a tty from the driver tables | 1430 | * tty_driver_remove_tty() - remove a tty from the driver tables |
1431 | * @driver: the driver for the tty | 1431 | * @driver: the driver for the tty |
1432 | * @idx: the minor number | 1432 | * @idx: the minor number |
1433 | * | 1433 | * |
1434 | * Remvoe a tty object from the driver tables. The tty->index field | 1434 | * Remvoe a tty object from the driver tables. The tty->index field |
1435 | * will be set by the time this is called. | 1435 | * will be set by the time this is called. |
1436 | * | 1436 | * |
1437 | * Locking: tty_mutex for now | 1437 | * Locking: tty_mutex for now |
1438 | */ | 1438 | */ |
1439 | void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty) | 1439 | void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty) |
1440 | { | 1440 | { |
1441 | if (driver->ops->remove) | 1441 | if (driver->ops->remove) |
1442 | driver->ops->remove(driver, tty); | 1442 | driver->ops->remove(driver, tty); |
1443 | else | 1443 | else |
1444 | driver->ttys[tty->index] = NULL; | 1444 | driver->ttys[tty->index] = NULL; |
1445 | } | 1445 | } |
1446 | 1446 | ||
1447 | /* | 1447 | /* |
1448 | * tty_reopen() - fast re-open of an open tty | 1448 | * tty_reopen() - fast re-open of an open tty |
1449 | * @tty - the tty to open | 1449 | * @tty - the tty to open |
1450 | * | 1450 | * |
1451 | * Return 0 on success, -errno on error. | 1451 | * Return 0 on success, -errno on error. |
1452 | * Re-opens on master ptys are not allowed and return -EIO. | 1452 | * Re-opens on master ptys are not allowed and return -EIO. |
1453 | * | 1453 | * |
1454 | * Locking: Caller must hold tty_lock | 1454 | * Locking: Caller must hold tty_lock |
1455 | */ | 1455 | */ |
1456 | static int tty_reopen(struct tty_struct *tty) | 1456 | static int tty_reopen(struct tty_struct *tty) |
1457 | { | 1457 | { |
1458 | struct tty_driver *driver = tty->driver; | 1458 | struct tty_driver *driver = tty->driver; |
1459 | 1459 | ||
1460 | if (!tty->count) | 1460 | if (!tty->count) |
1461 | return -EIO; | 1461 | return -EIO; |
1462 | 1462 | ||
1463 | if (driver->type == TTY_DRIVER_TYPE_PTY && | 1463 | if (driver->type == TTY_DRIVER_TYPE_PTY && |
1464 | driver->subtype == PTY_TYPE_MASTER) | 1464 | driver->subtype == PTY_TYPE_MASTER) |
1465 | return -EIO; | 1465 | return -EIO; |
1466 | 1466 | ||
1467 | if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) | 1467 | if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) |
1468 | return -EBUSY; | 1468 | return -EBUSY; |
1469 | 1469 | ||
1470 | tty->count++; | 1470 | tty->count++; |
1471 | 1471 | ||
1472 | WARN_ON(!tty->ldisc); | 1472 | WARN_ON(!tty->ldisc); |
1473 | 1473 | ||
1474 | return 0; | 1474 | return 0; |
1475 | } | 1475 | } |
1476 | 1476 | ||
1477 | /** | 1477 | /** |
1478 | * tty_init_dev - initialise a tty device | 1478 | * tty_init_dev - initialise a tty device |
1479 | * @driver: tty driver we are opening a device on | 1479 | * @driver: tty driver we are opening a device on |
1480 | * @idx: device index | 1480 | * @idx: device index |
1481 | * @ret_tty: returned tty structure | 1481 | * @ret_tty: returned tty structure |
1482 | * | 1482 | * |
1483 | * Prepare a tty device. This may not be a "new" clean device but | 1483 | * Prepare a tty device. This may not be a "new" clean device but |
1484 | * could also be an active device. The pty drivers require special | 1484 | * could also be an active device. The pty drivers require special |
1485 | * handling because of this. | 1485 | * handling because of this. |
1486 | * | 1486 | * |
1487 | * Locking: | 1487 | * Locking: |
1488 | * The function is called under the tty_mutex, which | 1488 | * The function is called under the tty_mutex, which |
1489 | * protects us from the tty struct or driver itself going away. | 1489 | * protects us from the tty struct or driver itself going away. |
1490 | * | 1490 | * |
1491 | * On exit the tty device has the line discipline attached and | 1491 | * On exit the tty device has the line discipline attached and |
1492 | * a reference count of 1. If a pair was created for pty/tty use | 1492 | * a reference count of 1. If a pair was created for pty/tty use |
1493 | * and the other was a pty master then it too has a reference count of 1. | 1493 | * and the other was a pty master then it too has a reference count of 1. |
1494 | * | 1494 | * |
1495 | * WSH 06/09/97: Rewritten to remove races and properly clean up after a | 1495 | * WSH 06/09/97: Rewritten to remove races and properly clean up after a |
1496 | * failed open. The new code protects the open with a mutex, so it's | 1496 | * failed open. The new code protects the open with a mutex, so it's |
1497 | * really quite straightforward. The mutex locking can probably be | 1497 | * really quite straightforward. The mutex locking can probably be |
1498 | * relaxed for the (most common) case of reopening a tty. | 1498 | * relaxed for the (most common) case of reopening a tty. |
1499 | */ | 1499 | */ |
1500 | 1500 | ||
1501 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | 1501 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) |
1502 | { | 1502 | { |
1503 | struct tty_struct *tty; | 1503 | struct tty_struct *tty; |
1504 | int retval; | 1504 | int retval; |
1505 | 1505 | ||
1506 | /* | 1506 | /* |
1507 | * First time open is complex, especially for PTY devices. | 1507 | * First time open is complex, especially for PTY devices. |
1508 | * This code guarantees that either everything succeeds and the | 1508 | * This code guarantees that either everything succeeds and the |
1509 | * TTY is ready for operation, or else the table slots are vacated | 1509 | * TTY is ready for operation, or else the table slots are vacated |
1510 | * and the allocated memory released. (Except that the termios | 1510 | * and the allocated memory released. (Except that the termios |
1511 | * and locked termios may be retained.) | 1511 | * and locked termios may be retained.) |
1512 | */ | 1512 | */ |
1513 | 1513 | ||
1514 | if (!try_module_get(driver->owner)) | 1514 | if (!try_module_get(driver->owner)) |
1515 | return ERR_PTR(-ENODEV); | 1515 | return ERR_PTR(-ENODEV); |
1516 | 1516 | ||
1517 | tty = alloc_tty_struct(driver, idx); | 1517 | tty = alloc_tty_struct(driver, idx); |
1518 | if (!tty) { | 1518 | if (!tty) { |
1519 | retval = -ENOMEM; | 1519 | retval = -ENOMEM; |
1520 | goto err_module_put; | 1520 | goto err_module_put; |
1521 | } | 1521 | } |
1522 | 1522 | ||
1523 | tty_lock(tty); | 1523 | tty_lock(tty); |
1524 | retval = tty_driver_install_tty(driver, tty); | 1524 | retval = tty_driver_install_tty(driver, tty); |
1525 | if (retval < 0) | 1525 | if (retval < 0) |
1526 | goto err_deinit_tty; | 1526 | goto err_deinit_tty; |
1527 | 1527 | ||
1528 | if (!tty->port) | 1528 | if (!tty->port) |
1529 | tty->port = driver->ports[idx]; | 1529 | tty->port = driver->ports[idx]; |
1530 | 1530 | ||
1531 | WARN_RATELIMIT(!tty->port, | 1531 | WARN_RATELIMIT(!tty->port, |
1532 | "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", | 1532 | "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", |
1533 | __func__, tty->driver->name); | 1533 | __func__, tty->driver->name); |
1534 | 1534 | ||
1535 | tty->port->itty = tty; | 1535 | tty->port->itty = tty; |
1536 | 1536 | ||
1537 | /* | 1537 | /* |
1538 | * Structures all installed ... call the ldisc open routines. | 1538 | * Structures all installed ... call the ldisc open routines. |
1539 | * If we fail here just call release_tty to clean up. No need | 1539 | * If we fail here just call release_tty to clean up. No need |
1540 | * to decrement the use counts, as release_tty doesn't care. | 1540 | * to decrement the use counts, as release_tty doesn't care. |
1541 | */ | 1541 | */ |
1542 | retval = tty_ldisc_setup(tty, tty->link); | 1542 | retval = tty_ldisc_setup(tty, tty->link); |
1543 | if (retval) | 1543 | if (retval) |
1544 | goto err_release_tty; | 1544 | goto err_release_tty; |
1545 | /* Return the tty locked so that it cannot vanish under the caller */ | 1545 | /* Return the tty locked so that it cannot vanish under the caller */ |
1546 | return tty; | 1546 | return tty; |
1547 | 1547 | ||
1548 | err_deinit_tty: | 1548 | err_deinit_tty: |
1549 | tty_unlock(tty); | 1549 | tty_unlock(tty); |
1550 | deinitialize_tty_struct(tty); | 1550 | deinitialize_tty_struct(tty); |
1551 | free_tty_struct(tty); | 1551 | free_tty_struct(tty); |
1552 | err_module_put: | 1552 | err_module_put: |
1553 | module_put(driver->owner); | 1553 | module_put(driver->owner); |
1554 | return ERR_PTR(retval); | 1554 | return ERR_PTR(retval); |
1555 | 1555 | ||
1556 | /* call the tty release_tty routine to clean out this slot */ | 1556 | /* call the tty release_tty routine to clean out this slot */ |
1557 | err_release_tty: | 1557 | err_release_tty: |
1558 | tty_unlock(tty); | 1558 | tty_unlock(tty); |
1559 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " | 1559 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " |
1560 | "clearing slot %d\n", idx); | 1560 | "clearing slot %d\n", idx); |
1561 | release_tty(tty, idx); | 1561 | release_tty(tty, idx); |
1562 | return ERR_PTR(retval); | 1562 | return ERR_PTR(retval); |
1563 | } | 1563 | } |
1564 | 1564 | ||
1565 | void tty_free_termios(struct tty_struct *tty) | 1565 | void tty_free_termios(struct tty_struct *tty) |
1566 | { | 1566 | { |
1567 | struct ktermios *tp; | 1567 | struct ktermios *tp; |
1568 | int idx = tty->index; | 1568 | int idx = tty->index; |
1569 | 1569 | ||
1570 | /* If the port is going to reset then it has no termios to save */ | 1570 | /* If the port is going to reset then it has no termios to save */ |
1571 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) | 1571 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1572 | return; | 1572 | return; |
1573 | 1573 | ||
1574 | /* Stash the termios data */ | 1574 | /* Stash the termios data */ |
1575 | tp = tty->driver->termios[idx]; | 1575 | tp = tty->driver->termios[idx]; |
1576 | if (tp == NULL) { | 1576 | if (tp == NULL) { |
1577 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | 1577 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
1578 | if (tp == NULL) { | 1578 | if (tp == NULL) { |
1579 | pr_warn("tty: no memory to save termios state.\n"); | 1579 | pr_warn("tty: no memory to save termios state.\n"); |
1580 | return; | 1580 | return; |
1581 | } | 1581 | } |
1582 | tty->driver->termios[idx] = tp; | 1582 | tty->driver->termios[idx] = tp; |
1583 | } | 1583 | } |
1584 | *tp = tty->termios; | 1584 | *tp = tty->termios; |
1585 | } | 1585 | } |
1586 | EXPORT_SYMBOL(tty_free_termios); | 1586 | EXPORT_SYMBOL(tty_free_termios); |
1587 | 1587 | ||
1588 | /** | 1588 | /** |
1589 | * tty_flush_works - flush all works of a tty/pty pair | 1589 | * tty_flush_works - flush all works of a tty/pty pair |
1590 | * @tty: tty device to flush works for (or either end of a pty pair) | 1590 | * @tty: tty device to flush works for (or either end of a pty pair) |
1591 | * | 1591 | * |
1592 | * Sync flush all works belonging to @tty (and the 'other' tty). | 1592 | * Sync flush all works belonging to @tty (and the 'other' tty). |
1593 | */ | 1593 | */ |
1594 | static void tty_flush_works(struct tty_struct *tty) | 1594 | static void tty_flush_works(struct tty_struct *tty) |
1595 | { | 1595 | { |
1596 | flush_work(&tty->SAK_work); | 1596 | flush_work(&tty->SAK_work); |
1597 | flush_work(&tty->hangup_work); | 1597 | flush_work(&tty->hangup_work); |
1598 | if (tty->link) { | 1598 | if (tty->link) { |
1599 | flush_work(&tty->link->SAK_work); | 1599 | flush_work(&tty->link->SAK_work); |
1600 | flush_work(&tty->link->hangup_work); | 1600 | flush_work(&tty->link->hangup_work); |
1601 | } | 1601 | } |
1602 | } | 1602 | } |
1603 | 1603 | ||
1604 | /** | 1604 | /** |
1605 | * release_one_tty - release tty structure memory | 1605 | * release_one_tty - release tty structure memory |
1606 | * @kref: kref of tty we are obliterating | 1606 | * @kref: kref of tty we are obliterating |
1607 | * | 1607 | * |
1608 | * Releases memory associated with a tty structure, and clears out the | 1608 | * Releases memory associated with a tty structure, and clears out the |
1609 | * driver table slots. This function is called when a device is no longer | 1609 | * driver table slots. This function is called when a device is no longer |
1610 | * in use. It also gets called when setup of a device fails. | 1610 | * in use. It also gets called when setup of a device fails. |
1611 | * | 1611 | * |
1612 | * Locking: | 1612 | * Locking: |
1613 | * takes the file list lock internally when working on the list | 1613 | * takes the file list lock internally when working on the list |
1614 | * of ttys that the driver keeps. | 1614 | * of ttys that the driver keeps. |
1615 | * | 1615 | * |
1616 | * This method gets called from a work queue so that the driver private | 1616 | * This method gets called from a work queue so that the driver private |
1617 | * cleanup ops can sleep (needed for USB at least) | 1617 | * cleanup ops can sleep (needed for USB at least) |
1618 | */ | 1618 | */ |
1619 | static void release_one_tty(struct work_struct *work) | 1619 | static void release_one_tty(struct work_struct *work) |
1620 | { | 1620 | { |
1621 | struct tty_struct *tty = | 1621 | struct tty_struct *tty = |
1622 | container_of(work, struct tty_struct, hangup_work); | 1622 | container_of(work, struct tty_struct, hangup_work); |
1623 | struct tty_driver *driver = tty->driver; | 1623 | struct tty_driver *driver = tty->driver; |
1624 | struct module *owner = driver->owner; | 1624 | struct module *owner = driver->owner; |
1625 | 1625 | ||
1626 | if (tty->ops->cleanup) | 1626 | if (tty->ops->cleanup) |
1627 | tty->ops->cleanup(tty); | 1627 | tty->ops->cleanup(tty); |
1628 | 1628 | ||
1629 | tty->magic = 0; | 1629 | tty->magic = 0; |
1630 | tty_driver_kref_put(driver); | 1630 | tty_driver_kref_put(driver); |
1631 | module_put(owner); | 1631 | module_put(owner); |
1632 | 1632 | ||
1633 | spin_lock(&tty_files_lock); | 1633 | spin_lock(&tty_files_lock); |
1634 | list_del_init(&tty->tty_files); | 1634 | list_del_init(&tty->tty_files); |
1635 | spin_unlock(&tty_files_lock); | 1635 | spin_unlock(&tty_files_lock); |
1636 | 1636 | ||
1637 | put_pid(tty->pgrp); | 1637 | put_pid(tty->pgrp); |
1638 | put_pid(tty->session); | 1638 | put_pid(tty->session); |
1639 | free_tty_struct(tty); | 1639 | free_tty_struct(tty); |
1640 | } | 1640 | } |
1641 | 1641 | ||
1642 | static void queue_release_one_tty(struct kref *kref) | 1642 | static void queue_release_one_tty(struct kref *kref) |
1643 | { | 1643 | { |
1644 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | 1644 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1645 | 1645 | ||
1646 | /* The hangup queue is now free so we can reuse it rather than | 1646 | /* The hangup queue is now free so we can reuse it rather than |
1647 | waste a chunk of memory for each port */ | 1647 | waste a chunk of memory for each port */ |
1648 | INIT_WORK(&tty->hangup_work, release_one_tty); | 1648 | INIT_WORK(&tty->hangup_work, release_one_tty); |
1649 | schedule_work(&tty->hangup_work); | 1649 | schedule_work(&tty->hangup_work); |
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | /** | 1652 | /** |
1653 | * tty_kref_put - release a tty kref | 1653 | * tty_kref_put - release a tty kref |
1654 | * @tty: tty device | 1654 | * @tty: tty device |
1655 | * | 1655 | * |
1656 | * Release a reference to a tty device and if need be let the kref | 1656 | * Release a reference to a tty device and if need be let the kref |
1657 | * layer destruct the object for us | 1657 | * layer destruct the object for us |
1658 | */ | 1658 | */ |
1659 | 1659 | ||
1660 | void tty_kref_put(struct tty_struct *tty) | 1660 | void tty_kref_put(struct tty_struct *tty) |
1661 | { | 1661 | { |
1662 | if (tty) | 1662 | if (tty) |
1663 | kref_put(&tty->kref, queue_release_one_tty); | 1663 | kref_put(&tty->kref, queue_release_one_tty); |
1664 | } | 1664 | } |
1665 | EXPORT_SYMBOL(tty_kref_put); | 1665 | EXPORT_SYMBOL(tty_kref_put); |
1666 | 1666 | ||
1667 | /** | 1667 | /** |
1668 | * release_tty - release tty structure memory | 1668 | * release_tty - release tty structure memory |
1669 | * | 1669 | * |
1670 | * Release both @tty and a possible linked partner (think pty pair), | 1670 | * Release both @tty and a possible linked partner (think pty pair), |
1671 | * and decrement the refcount of the backing module. | 1671 | * and decrement the refcount of the backing module. |
1672 | * | 1672 | * |
1673 | * Locking: | 1673 | * Locking: |
1674 | * tty_mutex | 1674 | * tty_mutex |
1675 | * takes the file list lock internally when working on the list | 1675 | * takes the file list lock internally when working on the list |
1676 | * of ttys that the driver keeps. | 1676 | * of ttys that the driver keeps. |
1677 | * | 1677 | * |
1678 | */ | 1678 | */ |
1679 | static void release_tty(struct tty_struct *tty, int idx) | 1679 | static void release_tty(struct tty_struct *tty, int idx) |
1680 | { | 1680 | { |
1681 | /* This should always be true but check for the moment */ | 1681 | /* This should always be true but check for the moment */ |
1682 | WARN_ON(tty->index != idx); | 1682 | WARN_ON(tty->index != idx); |
1683 | WARN_ON(!mutex_is_locked(&tty_mutex)); | 1683 | WARN_ON(!mutex_is_locked(&tty_mutex)); |
1684 | if (tty->ops->shutdown) | 1684 | if (tty->ops->shutdown) |
1685 | tty->ops->shutdown(tty); | 1685 | tty->ops->shutdown(tty); |
1686 | tty_free_termios(tty); | 1686 | tty_free_termios(tty); |
1687 | tty_driver_remove_tty(tty->driver, tty); | 1687 | tty_driver_remove_tty(tty->driver, tty); |
1688 | tty->port->itty = NULL; | 1688 | tty->port->itty = NULL; |
1689 | if (tty->link) | 1689 | if (tty->link) |
1690 | tty->link->port->itty = NULL; | 1690 | tty->link->port->itty = NULL; |
1691 | cancel_work_sync(&tty->port->buf.work); | 1691 | cancel_work_sync(&tty->port->buf.work); |
1692 | 1692 | ||
1693 | tty_kref_put(tty->link); | 1693 | tty_kref_put(tty->link); |
1694 | tty_kref_put(tty); | 1694 | tty_kref_put(tty); |
1695 | } | 1695 | } |
1696 | 1696 | ||
1697 | /** | 1697 | /** |
1698 | * tty_release_checks - check a tty before real release | 1698 | * tty_release_checks - check a tty before real release |
1699 | * @tty: tty to check | 1699 | * @tty: tty to check |
1700 | * @o_tty: link of @tty (if any) | 1700 | * @o_tty: link of @tty (if any) |
1701 | * @idx: index of the tty | 1701 | * @idx: index of the tty |
1702 | * | 1702 | * |
1703 | * Performs some paranoid checking before true release of the @tty. | 1703 | * Performs some paranoid checking before true release of the @tty. |
1704 | * This is a no-op unless TTY_PARANOIA_CHECK is defined. | 1704 | * This is a no-op unless TTY_PARANOIA_CHECK is defined. |
1705 | */ | 1705 | */ |
1706 | static int tty_release_checks(struct tty_struct *tty, int idx) | 1706 | static int tty_release_checks(struct tty_struct *tty, int idx) |
1707 | { | 1707 | { |
1708 | #ifdef TTY_PARANOIA_CHECK | 1708 | #ifdef TTY_PARANOIA_CHECK |
1709 | if (idx < 0 || idx >= tty->driver->num) { | 1709 | if (idx < 0 || idx >= tty->driver->num) { |
1710 | printk(KERN_DEBUG "%s: bad idx when trying to free (%s)\n", | 1710 | printk(KERN_DEBUG "%s: bad idx when trying to free (%s)\n", |
1711 | __func__, tty->name); | 1711 | __func__, tty->name); |
1712 | return -1; | 1712 | return -1; |
1713 | } | 1713 | } |
1714 | 1714 | ||
1715 | /* not much to check for devpts */ | 1715 | /* not much to check for devpts */ |
1716 | if (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) | 1716 | if (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) |
1717 | return 0; | 1717 | return 0; |
1718 | 1718 | ||
1719 | if (tty != tty->driver->ttys[idx]) { | 1719 | if (tty != tty->driver->ttys[idx]) { |
1720 | printk(KERN_DEBUG "%s: driver.table[%d] not tty for (%s)\n", | 1720 | printk(KERN_DEBUG "%s: driver.table[%d] not tty for (%s)\n", |
1721 | __func__, idx, tty->name); | 1721 | __func__, idx, tty->name); |
1722 | return -1; | 1722 | return -1; |
1723 | } | 1723 | } |
1724 | if (tty->driver->other) { | 1724 | if (tty->driver->other) { |
1725 | struct tty_struct *o_tty = tty->link; | 1725 | struct tty_struct *o_tty = tty->link; |
1726 | 1726 | ||
1727 | if (o_tty != tty->driver->other->ttys[idx]) { | 1727 | if (o_tty != tty->driver->other->ttys[idx]) { |
1728 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", | 1728 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", |
1729 | __func__, idx, tty->name); | 1729 | __func__, idx, tty->name); |
1730 | return -1; | 1730 | return -1; |
1731 | } | 1731 | } |
1732 | if (o_tty->link != tty) { | 1732 | if (o_tty->link != tty) { |
1733 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); | 1733 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); |
1734 | return -1; | 1734 | return -1; |
1735 | } | 1735 | } |
1736 | } | 1736 | } |
1737 | #endif | 1737 | #endif |
1738 | return 0; | 1738 | return 0; |
1739 | } | 1739 | } |
1740 | 1740 | ||
1741 | /** | 1741 | /** |
1742 | * tty_release - vfs callback for close | 1742 | * tty_release - vfs callback for close |
1743 | * @inode: inode of tty | 1743 | * @inode: inode of tty |
1744 | * @filp: file pointer for handle to tty | 1744 | * @filp: file pointer for handle to tty |
1745 | * | 1745 | * |
1746 | * Called the last time each file handle is closed that references | 1746 | * Called the last time each file handle is closed that references |
1747 | * this tty. There may however be several such references. | 1747 | * this tty. There may however be several such references. |
1748 | * | 1748 | * |
1749 | * Locking: | 1749 | * Locking: |
1750 | * Takes bkl. See tty_release_dev | 1750 | * Takes bkl. See tty_release_dev |
1751 | * | 1751 | * |
1752 | * Even releasing the tty structures is a tricky business.. We have | 1752 | * Even releasing the tty structures is a tricky business.. We have |
1753 | * to be very careful that the structures are all released at the | 1753 | * to be very careful that the structures are all released at the |
1754 | * same time, as interrupts might otherwise get the wrong pointers. | 1754 | * same time, as interrupts might otherwise get the wrong pointers. |
1755 | * | 1755 | * |
1756 | * WSH 09/09/97: rewritten to avoid some nasty race conditions that could | 1756 | * WSH 09/09/97: rewritten to avoid some nasty race conditions that could |
1757 | * lead to double frees or releasing memory still in use. | 1757 | * lead to double frees or releasing memory still in use. |
1758 | */ | 1758 | */ |
1759 | 1759 | ||
1760 | int tty_release(struct inode *inode, struct file *filp) | 1760 | int tty_release(struct inode *inode, struct file *filp) |
1761 | { | 1761 | { |
1762 | struct tty_struct *tty = file_tty(filp); | 1762 | struct tty_struct *tty = file_tty(filp); |
1763 | struct tty_struct *o_tty = NULL; | 1763 | struct tty_struct *o_tty = NULL; |
1764 | int do_sleep, final; | 1764 | int do_sleep, final; |
1765 | int idx; | 1765 | int idx; |
1766 | char buf[64]; | 1766 | char buf[64]; |
1767 | long timeout = 0; | 1767 | long timeout = 0; |
1768 | int once = 1; | 1768 | int once = 1; |
1769 | 1769 | ||
1770 | if (tty_paranoia_check(tty, inode, __func__)) | 1770 | if (tty_paranoia_check(tty, inode, __func__)) |
1771 | return 0; | 1771 | return 0; |
1772 | 1772 | ||
1773 | tty_lock(tty); | 1773 | tty_lock(tty); |
1774 | check_tty_count(tty, __func__); | 1774 | check_tty_count(tty, __func__); |
1775 | 1775 | ||
1776 | __tty_fasync(-1, filp, 0); | 1776 | __tty_fasync(-1, filp, 0); |
1777 | 1777 | ||
1778 | idx = tty->index; | 1778 | idx = tty->index; |
1779 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1779 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1780 | tty->driver->subtype == PTY_TYPE_MASTER) | 1780 | tty->driver->subtype == PTY_TYPE_MASTER) |
1781 | o_tty = tty->link; | 1781 | o_tty = tty->link; |
1782 | 1782 | ||
1783 | if (tty_release_checks(tty, idx)) { | 1783 | if (tty_release_checks(tty, idx)) { |
1784 | tty_unlock(tty); | 1784 | tty_unlock(tty); |
1785 | return 0; | 1785 | return 0; |
1786 | } | 1786 | } |
1787 | 1787 | ||
1788 | #ifdef TTY_DEBUG_HANGUP | 1788 | #ifdef TTY_DEBUG_HANGUP |
1789 | printk(KERN_DEBUG "%s: %s (tty count=%d)...\n", __func__, | 1789 | printk(KERN_DEBUG "%s: %s (tty count=%d)...\n", __func__, |
1790 | tty_name(tty, buf), tty->count); | 1790 | tty_name(tty, buf), tty->count); |
1791 | #endif | 1791 | #endif |
1792 | 1792 | ||
1793 | if (tty->ops->close) | 1793 | if (tty->ops->close) |
1794 | tty->ops->close(tty, filp); | 1794 | tty->ops->close(tty, filp); |
1795 | 1795 | ||
1796 | /* If tty is pty master, lock the slave pty (stable lock order) */ | 1796 | /* If tty is pty master, lock the slave pty (stable lock order) */ |
1797 | tty_lock_slave(o_tty); | 1797 | tty_lock_slave(o_tty); |
1798 | 1798 | ||
1799 | /* | 1799 | /* |
1800 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1800 | * Sanity check: if tty->count is going to zero, there shouldn't be |
1801 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1801 | * any waiters on tty->read_wait or tty->write_wait. We test the |
1802 | * wait queues and kick everyone out _before_ actually starting to | 1802 | * wait queues and kick everyone out _before_ actually starting to |
1803 | * close. This ensures that we won't block while releasing the tty | 1803 | * close. This ensures that we won't block while releasing the tty |
1804 | * structure. | 1804 | * structure. |
1805 | * | 1805 | * |
1806 | * The test for the o_tty closing is necessary, since the master and | 1806 | * The test for the o_tty closing is necessary, since the master and |
1807 | * slave sides may close in any order. If the slave side closes out | 1807 | * slave sides may close in any order. If the slave side closes out |
1808 | * first, its count will be one, since the master side holds an open. | 1808 | * first, its count will be one, since the master side holds an open. |
1809 | * Thus this test wouldn't be triggered at the time the slave closed, | 1809 | * Thus this test wouldn't be triggered at the time the slave closed, |
1810 | * so we do it now. | 1810 | * so we do it now. |
1811 | */ | 1811 | */ |
1812 | while (1) { | 1812 | while (1) { |
1813 | do_sleep = 0; | 1813 | do_sleep = 0; |
1814 | 1814 | ||
1815 | if (tty->count <= 1) { | 1815 | if (tty->count <= 1) { |
1816 | if (waitqueue_active(&tty->read_wait)) { | 1816 | if (waitqueue_active(&tty->read_wait)) { |
1817 | wake_up_poll(&tty->read_wait, POLLIN); | 1817 | wake_up_poll(&tty->read_wait, POLLIN); |
1818 | do_sleep++; | 1818 | do_sleep++; |
1819 | } | 1819 | } |
1820 | if (waitqueue_active(&tty->write_wait)) { | 1820 | if (waitqueue_active(&tty->write_wait)) { |
1821 | wake_up_poll(&tty->write_wait, POLLOUT); | 1821 | wake_up_poll(&tty->write_wait, POLLOUT); |
1822 | do_sleep++; | 1822 | do_sleep++; |
1823 | } | 1823 | } |
1824 | } | 1824 | } |
1825 | if (o_tty && o_tty->count <= 1) { | 1825 | if (o_tty && o_tty->count <= 1) { |
1826 | if (waitqueue_active(&o_tty->read_wait)) { | 1826 | if (waitqueue_active(&o_tty->read_wait)) { |
1827 | wake_up_poll(&o_tty->read_wait, POLLIN); | 1827 | wake_up_poll(&o_tty->read_wait, POLLIN); |
1828 | do_sleep++; | 1828 | do_sleep++; |
1829 | } | 1829 | } |
1830 | if (waitqueue_active(&o_tty->write_wait)) { | 1830 | if (waitqueue_active(&o_tty->write_wait)) { |
1831 | wake_up_poll(&o_tty->write_wait, POLLOUT); | 1831 | wake_up_poll(&o_tty->write_wait, POLLOUT); |
1832 | do_sleep++; | 1832 | do_sleep++; |
1833 | } | 1833 | } |
1834 | } | 1834 | } |
1835 | if (!do_sleep) | 1835 | if (!do_sleep) |
1836 | break; | 1836 | break; |
1837 | 1837 | ||
1838 | if (once) { | 1838 | if (once) { |
1839 | once = 0; | 1839 | once = 0; |
1840 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", | 1840 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
1841 | __func__, tty_name(tty, buf)); | 1841 | __func__, tty_name(tty, buf)); |
1842 | } | 1842 | } |
1843 | schedule_timeout_killable(timeout); | 1843 | schedule_timeout_killable(timeout); |
1844 | if (timeout < 120 * HZ) | 1844 | if (timeout < 120 * HZ) |
1845 | timeout = 2 * timeout + 1; | 1845 | timeout = 2 * timeout + 1; |
1846 | else | 1846 | else |
1847 | timeout = MAX_SCHEDULE_TIMEOUT; | 1847 | timeout = MAX_SCHEDULE_TIMEOUT; |
1848 | } | 1848 | } |
1849 | 1849 | ||
1850 | if (o_tty) { | 1850 | if (o_tty) { |
1851 | if (--o_tty->count < 0) { | 1851 | if (--o_tty->count < 0) { |
1852 | printk(KERN_WARNING "%s: bad pty slave count (%d) for %s\n", | 1852 | printk(KERN_WARNING "%s: bad pty slave count (%d) for %s\n", |
1853 | __func__, o_tty->count, tty_name(o_tty, buf)); | 1853 | __func__, o_tty->count, tty_name(o_tty, buf)); |
1854 | o_tty->count = 0; | 1854 | o_tty->count = 0; |
1855 | } | 1855 | } |
1856 | } | 1856 | } |
1857 | if (--tty->count < 0) { | 1857 | if (--tty->count < 0) { |
1858 | printk(KERN_WARNING "%s: bad tty->count (%d) for %s\n", | 1858 | printk(KERN_WARNING "%s: bad tty->count (%d) for %s\n", |
1859 | __func__, tty->count, tty_name(tty, buf)); | 1859 | __func__, tty->count, tty_name(tty, buf)); |
1860 | tty->count = 0; | 1860 | tty->count = 0; |
1861 | } | 1861 | } |
1862 | 1862 | ||
1863 | /* | 1863 | /* |
1864 | * We've decremented tty->count, so we need to remove this file | 1864 | * We've decremented tty->count, so we need to remove this file |
1865 | * descriptor off the tty->tty_files list; this serves two | 1865 | * descriptor off the tty->tty_files list; this serves two |
1866 | * purposes: | 1866 | * purposes: |
1867 | * - check_tty_count sees the correct number of file descriptors | 1867 | * - check_tty_count sees the correct number of file descriptors |
1868 | * associated with this tty. | 1868 | * associated with this tty. |
1869 | * - do_tty_hangup no longer sees this file descriptor as | 1869 | * - do_tty_hangup no longer sees this file descriptor as |
1870 | * something that needs to be handled for hangups. | 1870 | * something that needs to be handled for hangups. |
1871 | */ | 1871 | */ |
1872 | tty_del_file(filp); | 1872 | tty_del_file(filp); |
1873 | 1873 | ||
1874 | /* | 1874 | /* |
1875 | * Perform some housekeeping before deciding whether to return. | 1875 | * Perform some housekeeping before deciding whether to return. |
1876 | * | 1876 | * |
1877 | * If _either_ side is closing, make sure there aren't any | 1877 | * If _either_ side is closing, make sure there aren't any |
1878 | * processes that still think tty or o_tty is their controlling | 1878 | * processes that still think tty or o_tty is their controlling |
1879 | * tty. | 1879 | * tty. |
1880 | */ | 1880 | */ |
1881 | if (!tty->count) { | 1881 | if (!tty->count) { |
1882 | read_lock(&tasklist_lock); | 1882 | read_lock(&tasklist_lock); |
1883 | session_clear_tty(tty->session); | 1883 | session_clear_tty(tty->session); |
1884 | if (o_tty) | 1884 | if (o_tty) |
1885 | session_clear_tty(o_tty->session); | 1885 | session_clear_tty(o_tty->session); |
1886 | read_unlock(&tasklist_lock); | 1886 | read_unlock(&tasklist_lock); |
1887 | } | 1887 | } |
1888 | 1888 | ||
1889 | /* check whether both sides are closing ... */ | 1889 | /* check whether both sides are closing ... */ |
1890 | final = !tty->count && !(o_tty && o_tty->count); | 1890 | final = !tty->count && !(o_tty && o_tty->count); |
1891 | 1891 | ||
1892 | tty_unlock_slave(o_tty); | 1892 | tty_unlock_slave(o_tty); |
1893 | tty_unlock(tty); | 1893 | tty_unlock(tty); |
1894 | 1894 | ||
1895 | /* At this point, the tty->count == 0 should ensure a dead tty | 1895 | /* At this point, the tty->count == 0 should ensure a dead tty |
1896 | cannot be re-opened by a racing opener */ | 1896 | cannot be re-opened by a racing opener */ |
1897 | 1897 | ||
1898 | if (!final) | 1898 | if (!final) |
1899 | return 0; | 1899 | return 0; |
1900 | 1900 | ||
1901 | #ifdef TTY_DEBUG_HANGUP | 1901 | #ifdef TTY_DEBUG_HANGUP |
1902 | printk(KERN_DEBUG "%s: %s: final close\n", __func__, tty_name(tty, buf)); | 1902 | printk(KERN_DEBUG "%s: %s: final close\n", __func__, tty_name(tty, buf)); |
1903 | #endif | 1903 | #endif |
1904 | /* | 1904 | /* |
1905 | * Ask the line discipline code to release its structures | 1905 | * Ask the line discipline code to release its structures |
1906 | */ | 1906 | */ |
1907 | tty_ldisc_release(tty); | 1907 | tty_ldisc_release(tty); |
1908 | 1908 | ||
1909 | /* Wait for pending work before tty destruction commmences */ | 1909 | /* Wait for pending work before tty destruction commmences */ |
1910 | tty_flush_works(tty); | 1910 | tty_flush_works(tty); |
1911 | 1911 | ||
1912 | #ifdef TTY_DEBUG_HANGUP | 1912 | #ifdef TTY_DEBUG_HANGUP |
1913 | printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, tty_name(tty, buf)); | 1913 | printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, tty_name(tty, buf)); |
1914 | #endif | 1914 | #endif |
1915 | /* | 1915 | /* |
1916 | * The release_tty function takes care of the details of clearing | 1916 | * The release_tty function takes care of the details of clearing |
1917 | * the slots and preserving the termios structure. The tty_unlock_pair | 1917 | * the slots and preserving the termios structure. The tty_unlock_pair |
1918 | * should be safe as we keep a kref while the tty is locked (so the | 1918 | * should be safe as we keep a kref while the tty is locked (so the |
1919 | * unlock never unlocks a freed tty). | 1919 | * unlock never unlocks a freed tty). |
1920 | */ | 1920 | */ |
1921 | mutex_lock(&tty_mutex); | 1921 | mutex_lock(&tty_mutex); |
1922 | release_tty(tty, idx); | 1922 | release_tty(tty, idx); |
1923 | mutex_unlock(&tty_mutex); | 1923 | mutex_unlock(&tty_mutex); |
1924 | 1924 | ||
1925 | return 0; | 1925 | return 0; |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | /** | 1928 | /** |
1929 | * tty_open_current_tty - get locked tty of current task | 1929 | * tty_open_current_tty - get locked tty of current task |
1930 | * @device: device number | 1930 | * @device: device number |
1931 | * @filp: file pointer to tty | 1931 | * @filp: file pointer to tty |
1932 | * @return: locked tty of the current task iff @device is /dev/tty | 1932 | * @return: locked tty of the current task iff @device is /dev/tty |
1933 | * | 1933 | * |
1934 | * Performs a re-open of the current task's controlling tty. | 1934 | * Performs a re-open of the current task's controlling tty. |
1935 | * | 1935 | * |
1936 | * We cannot return driver and index like for the other nodes because | 1936 | * We cannot return driver and index like for the other nodes because |
1937 | * devpts will not work then. It expects inodes to be from devpts FS. | 1937 | * devpts will not work then. It expects inodes to be from devpts FS. |
1938 | */ | 1938 | */ |
1939 | static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) | 1939 | static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) |
1940 | { | 1940 | { |
1941 | struct tty_struct *tty; | 1941 | struct tty_struct *tty; |
1942 | int retval; | 1942 | int retval; |
1943 | 1943 | ||
1944 | if (device != MKDEV(TTYAUX_MAJOR, 0)) | 1944 | if (device != MKDEV(TTYAUX_MAJOR, 0)) |
1945 | return NULL; | 1945 | return NULL; |
1946 | 1946 | ||
1947 | tty = get_current_tty(); | 1947 | tty = get_current_tty(); |
1948 | if (!tty) | 1948 | if (!tty) |
1949 | return ERR_PTR(-ENXIO); | 1949 | return ERR_PTR(-ENXIO); |
1950 | 1950 | ||
1951 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | 1951 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ |
1952 | /* noctty = 1; */ | 1952 | /* noctty = 1; */ |
1953 | tty_lock(tty); | 1953 | tty_lock(tty); |
1954 | tty_kref_put(tty); /* safe to drop the kref now */ | 1954 | tty_kref_put(tty); /* safe to drop the kref now */ |
1955 | 1955 | ||
1956 | retval = tty_reopen(tty); | 1956 | retval = tty_reopen(tty); |
1957 | if (retval < 0) { | 1957 | if (retval < 0) { |
1958 | tty_unlock(tty); | 1958 | tty_unlock(tty); |
1959 | tty = ERR_PTR(retval); | 1959 | tty = ERR_PTR(retval); |
1960 | } | 1960 | } |
1961 | return tty; | 1961 | return tty; |
1962 | } | 1962 | } |
1963 | 1963 | ||
1964 | /** | 1964 | /** |
1965 | * tty_lookup_driver - lookup a tty driver for a given device file | 1965 | * tty_lookup_driver - lookup a tty driver for a given device file |
1966 | * @device: device number | 1966 | * @device: device number |
1967 | * @filp: file pointer to tty | 1967 | * @filp: file pointer to tty |
1968 | * @noctty: set if the device should not become a controlling tty | 1968 | * @noctty: set if the device should not become a controlling tty |
1969 | * @index: index for the device in the @return driver | 1969 | * @index: index for the device in the @return driver |
1970 | * @return: driver for this inode (with increased refcount) | 1970 | * @return: driver for this inode (with increased refcount) |
1971 | * | 1971 | * |
1972 | * If @return is not erroneous, the caller is responsible to decrement the | 1972 | * If @return is not erroneous, the caller is responsible to decrement the |
1973 | * refcount by tty_driver_kref_put. | 1973 | * refcount by tty_driver_kref_put. |
1974 | * | 1974 | * |
1975 | * Locking: tty_mutex protects get_tty_driver | 1975 | * Locking: tty_mutex protects get_tty_driver |
1976 | */ | 1976 | */ |
1977 | static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | 1977 | static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, |
1978 | int *noctty, int *index) | 1978 | int *noctty, int *index) |
1979 | { | 1979 | { |
1980 | struct tty_driver *driver; | 1980 | struct tty_driver *driver; |
1981 | 1981 | ||
1982 | switch (device) { | 1982 | switch (device) { |
1983 | #ifdef CONFIG_VT | 1983 | #ifdef CONFIG_VT |
1984 | case MKDEV(TTY_MAJOR, 0): { | 1984 | case MKDEV(TTY_MAJOR, 0): { |
1985 | extern struct tty_driver *console_driver; | 1985 | extern struct tty_driver *console_driver; |
1986 | driver = tty_driver_kref_get(console_driver); | 1986 | driver = tty_driver_kref_get(console_driver); |
1987 | *index = fg_console; | 1987 | *index = fg_console; |
1988 | *noctty = 1; | 1988 | *noctty = 1; |
1989 | break; | 1989 | break; |
1990 | } | 1990 | } |
1991 | #endif | 1991 | #endif |
1992 | case MKDEV(TTYAUX_MAJOR, 1): { | 1992 | case MKDEV(TTYAUX_MAJOR, 1): { |
1993 | struct tty_driver *console_driver = console_device(index); | 1993 | struct tty_driver *console_driver = console_device(index); |
1994 | if (console_driver) { | 1994 | if (console_driver) { |
1995 | driver = tty_driver_kref_get(console_driver); | 1995 | driver = tty_driver_kref_get(console_driver); |
1996 | if (driver) { | 1996 | if (driver) { |
1997 | /* Don't let /dev/console block */ | 1997 | /* Don't let /dev/console block */ |
1998 | filp->f_flags |= O_NONBLOCK; | 1998 | filp->f_flags |= O_NONBLOCK; |
1999 | *noctty = 1; | 1999 | *noctty = 1; |
2000 | break; | 2000 | break; |
2001 | } | 2001 | } |
2002 | } | 2002 | } |
2003 | return ERR_PTR(-ENODEV); | 2003 | return ERR_PTR(-ENODEV); |
2004 | } | 2004 | } |
2005 | default: | 2005 | default: |
2006 | driver = get_tty_driver(device, index); | 2006 | driver = get_tty_driver(device, index); |
2007 | if (!driver) | 2007 | if (!driver) |
2008 | return ERR_PTR(-ENODEV); | 2008 | return ERR_PTR(-ENODEV); |
2009 | break; | 2009 | break; |
2010 | } | 2010 | } |
2011 | return driver; | 2011 | return driver; |
2012 | } | 2012 | } |
2013 | 2013 | ||
2014 | /** | 2014 | /** |
2015 | * tty_open - open a tty device | 2015 | * tty_open - open a tty device |
2016 | * @inode: inode of device file | 2016 | * @inode: inode of device file |
2017 | * @filp: file pointer to tty | 2017 | * @filp: file pointer to tty |
2018 | * | 2018 | * |
2019 | * tty_open and tty_release keep up the tty count that contains the | 2019 | * tty_open and tty_release keep up the tty count that contains the |
2020 | * number of opens done on a tty. We cannot use the inode-count, as | 2020 | * number of opens done on a tty. We cannot use the inode-count, as |
2021 | * different inodes might point to the same tty. | 2021 | * different inodes might point to the same tty. |
2022 | * | 2022 | * |
2023 | * Open-counting is needed for pty masters, as well as for keeping | 2023 | * Open-counting is needed for pty masters, as well as for keeping |
2024 | * track of serial lines: DTR is dropped when the last close happens. | 2024 | * track of serial lines: DTR is dropped when the last close happens. |
2025 | * (This is not done solely through tty->count, now. - Ted 1/27/92) | 2025 | * (This is not done solely through tty->count, now. - Ted 1/27/92) |
2026 | * | 2026 | * |
2027 | * The termios state of a pty is reset on first open so that | 2027 | * The termios state of a pty is reset on first open so that |
2028 | * settings don't persist across reuse. | 2028 | * settings don't persist across reuse. |
2029 | * | 2029 | * |
2030 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. | 2030 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
2031 | * tty->count should protect the rest. | 2031 | * tty->count should protect the rest. |
2032 | * ->siglock protects ->signal/->sighand | 2032 | * ->siglock protects ->signal/->sighand |
2033 | * | 2033 | * |
2034 | * Note: the tty_unlock/lock cases without a ref are only safe due to | 2034 | * Note: the tty_unlock/lock cases without a ref are only safe due to |
2035 | * tty_mutex | 2035 | * tty_mutex |
2036 | */ | 2036 | */ |
2037 | 2037 | ||
2038 | static int tty_open(struct inode *inode, struct file *filp) | 2038 | static int tty_open(struct inode *inode, struct file *filp) |
2039 | { | 2039 | { |
2040 | struct tty_struct *tty; | 2040 | struct tty_struct *tty; |
2041 | int noctty, retval; | 2041 | int noctty, retval; |
2042 | struct tty_driver *driver = NULL; | 2042 | struct tty_driver *driver = NULL; |
2043 | int index; | 2043 | int index; |
2044 | dev_t device = inode->i_rdev; | 2044 | dev_t device = inode->i_rdev; |
2045 | unsigned saved_flags = filp->f_flags; | 2045 | unsigned saved_flags = filp->f_flags; |
2046 | 2046 | ||
2047 | nonseekable_open(inode, filp); | 2047 | nonseekable_open(inode, filp); |
2048 | 2048 | ||
2049 | retry_open: | 2049 | retry_open: |
2050 | retval = tty_alloc_file(filp); | 2050 | retval = tty_alloc_file(filp); |
2051 | if (retval) | 2051 | if (retval) |
2052 | return -ENOMEM; | 2052 | return -ENOMEM; |
2053 | 2053 | ||
2054 | noctty = filp->f_flags & O_NOCTTY; | 2054 | noctty = filp->f_flags & O_NOCTTY; |
2055 | index = -1; | 2055 | index = -1; |
2056 | retval = 0; | 2056 | retval = 0; |
2057 | 2057 | ||
2058 | tty = tty_open_current_tty(device, filp); | 2058 | tty = tty_open_current_tty(device, filp); |
2059 | if (!tty) { | 2059 | if (!tty) { |
2060 | mutex_lock(&tty_mutex); | 2060 | mutex_lock(&tty_mutex); |
2061 | driver = tty_lookup_driver(device, filp, &noctty, &index); | 2061 | driver = tty_lookup_driver(device, filp, &noctty, &index); |
2062 | if (IS_ERR(driver)) { | 2062 | if (IS_ERR(driver)) { |
2063 | retval = PTR_ERR(driver); | 2063 | retval = PTR_ERR(driver); |
2064 | goto err_unlock; | 2064 | goto err_unlock; |
2065 | } | 2065 | } |
2066 | 2066 | ||
2067 | /* check whether we're reopening an existing tty */ | 2067 | /* check whether we're reopening an existing tty */ |
2068 | tty = tty_driver_lookup_tty(driver, inode, index); | 2068 | tty = tty_driver_lookup_tty(driver, inode, index); |
2069 | if (IS_ERR(tty)) { | 2069 | if (IS_ERR(tty)) { |
2070 | retval = PTR_ERR(tty); | 2070 | retval = PTR_ERR(tty); |
2071 | goto err_unlock; | 2071 | goto err_unlock; |
2072 | } | 2072 | } |
2073 | 2073 | ||
2074 | if (tty) { | 2074 | if (tty) { |
2075 | mutex_unlock(&tty_mutex); | 2075 | mutex_unlock(&tty_mutex); |
2076 | tty_lock(tty); | 2076 | tty_lock(tty); |
2077 | /* safe to drop the kref from tty_driver_lookup_tty() */ | 2077 | /* safe to drop the kref from tty_driver_lookup_tty() */ |
2078 | tty_kref_put(tty); | 2078 | tty_kref_put(tty); |
2079 | retval = tty_reopen(tty); | 2079 | retval = tty_reopen(tty); |
2080 | if (retval < 0) { | 2080 | if (retval < 0) { |
2081 | tty_unlock(tty); | 2081 | tty_unlock(tty); |
2082 | tty = ERR_PTR(retval); | 2082 | tty = ERR_PTR(retval); |
2083 | } | 2083 | } |
2084 | } else { /* Returns with the tty_lock held for now */ | 2084 | } else { /* Returns with the tty_lock held for now */ |
2085 | tty = tty_init_dev(driver, index); | 2085 | tty = tty_init_dev(driver, index); |
2086 | mutex_unlock(&tty_mutex); | 2086 | mutex_unlock(&tty_mutex); |
2087 | } | 2087 | } |
2088 | 2088 | ||
2089 | tty_driver_kref_put(driver); | 2089 | tty_driver_kref_put(driver); |
2090 | } | 2090 | } |
2091 | 2091 | ||
2092 | if (IS_ERR(tty)) { | 2092 | if (IS_ERR(tty)) { |
2093 | retval = PTR_ERR(tty); | 2093 | retval = PTR_ERR(tty); |
2094 | goto err_file; | 2094 | goto err_file; |
2095 | } | 2095 | } |
2096 | 2096 | ||
2097 | tty_add_file(tty, filp); | 2097 | tty_add_file(tty, filp); |
2098 | 2098 | ||
2099 | check_tty_count(tty, __func__); | 2099 | check_tty_count(tty, __func__); |
2100 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 2100 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
2101 | tty->driver->subtype == PTY_TYPE_MASTER) | 2101 | tty->driver->subtype == PTY_TYPE_MASTER) |
2102 | noctty = 1; | 2102 | noctty = 1; |
2103 | #ifdef TTY_DEBUG_HANGUP | 2103 | #ifdef TTY_DEBUG_HANGUP |
2104 | printk(KERN_DEBUG "%s: opening %s...\n", __func__, tty->name); | 2104 | printk(KERN_DEBUG "%s: opening %s...\n", __func__, tty->name); |
2105 | #endif | 2105 | #endif |
2106 | if (tty->ops->open) | 2106 | if (tty->ops->open) |
2107 | retval = tty->ops->open(tty, filp); | 2107 | retval = tty->ops->open(tty, filp); |
2108 | else | 2108 | else |
2109 | retval = -ENODEV; | 2109 | retval = -ENODEV; |
2110 | filp->f_flags = saved_flags; | 2110 | filp->f_flags = saved_flags; |
2111 | 2111 | ||
2112 | if (retval) { | 2112 | if (retval) { |
2113 | #ifdef TTY_DEBUG_HANGUP | 2113 | #ifdef TTY_DEBUG_HANGUP |
2114 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, | 2114 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
2115 | retval, tty->name); | 2115 | retval, tty->name); |
2116 | #endif | 2116 | #endif |
2117 | tty_unlock(tty); /* need to call tty_release without BTM */ | 2117 | tty_unlock(tty); /* need to call tty_release without BTM */ |
2118 | tty_release(inode, filp); | 2118 | tty_release(inode, filp); |
2119 | if (retval != -ERESTARTSYS) | 2119 | if (retval != -ERESTARTSYS) |
2120 | return retval; | 2120 | return retval; |
2121 | 2121 | ||
2122 | if (signal_pending(current)) | 2122 | if (signal_pending(current)) |
2123 | return retval; | 2123 | return retval; |
2124 | 2124 | ||
2125 | schedule(); | 2125 | schedule(); |
2126 | /* | 2126 | /* |
2127 | * Need to reset f_op in case a hangup happened. | 2127 | * Need to reset f_op in case a hangup happened. |
2128 | */ | 2128 | */ |
2129 | if (tty_hung_up_p(filp)) | 2129 | if (tty_hung_up_p(filp)) |
2130 | filp->f_op = &tty_fops; | 2130 | filp->f_op = &tty_fops; |
2131 | goto retry_open; | 2131 | goto retry_open; |
2132 | } | 2132 | } |
2133 | clear_bit(TTY_HUPPED, &tty->flags); | 2133 | clear_bit(TTY_HUPPED, &tty->flags); |
2134 | 2134 | ||
2135 | 2135 | ||
2136 | read_lock(&tasklist_lock); | 2136 | read_lock(&tasklist_lock); |
2137 | spin_lock_irq(¤t->sighand->siglock); | 2137 | spin_lock_irq(¤t->sighand->siglock); |
2138 | if (!noctty && | 2138 | if (!noctty && |
2139 | current->signal->leader && | 2139 | current->signal->leader && |
2140 | !current->signal->tty && | 2140 | !current->signal->tty && |
2141 | tty->session == NULL) | 2141 | tty->session == NULL) |
2142 | __proc_set_tty(tty); | 2142 | __proc_set_tty(tty); |
2143 | spin_unlock_irq(¤t->sighand->siglock); | 2143 | spin_unlock_irq(¤t->sighand->siglock); |
2144 | read_unlock(&tasklist_lock); | 2144 | read_unlock(&tasklist_lock); |
2145 | tty_unlock(tty); | 2145 | tty_unlock(tty); |
2146 | return 0; | 2146 | return 0; |
2147 | err_unlock: | 2147 | err_unlock: |
2148 | mutex_unlock(&tty_mutex); | 2148 | mutex_unlock(&tty_mutex); |
2149 | /* after locks to avoid deadlock */ | 2149 | /* after locks to avoid deadlock */ |
2150 | if (!IS_ERR_OR_NULL(driver)) | 2150 | if (!IS_ERR_OR_NULL(driver)) |
2151 | tty_driver_kref_put(driver); | 2151 | tty_driver_kref_put(driver); |
2152 | err_file: | 2152 | err_file: |
2153 | tty_free_file(filp); | 2153 | tty_free_file(filp); |
2154 | return retval; | 2154 | return retval; |
2155 | } | 2155 | } |
2156 | 2156 | ||
2157 | 2157 | ||
2158 | 2158 | ||
2159 | /** | 2159 | /** |
2160 | * tty_poll - check tty status | 2160 | * tty_poll - check tty status |
2161 | * @filp: file being polled | 2161 | * @filp: file being polled |
2162 | * @wait: poll wait structures to update | 2162 | * @wait: poll wait structures to update |
2163 | * | 2163 | * |
2164 | * Call the line discipline polling method to obtain the poll | 2164 | * Call the line discipline polling method to obtain the poll |
2165 | * status of the device. | 2165 | * status of the device. |
2166 | * | 2166 | * |
2167 | * Locking: locks called line discipline but ldisc poll method | 2167 | * Locking: locks called line discipline but ldisc poll method |
2168 | * may be re-entered freely by other callers. | 2168 | * may be re-entered freely by other callers. |
2169 | */ | 2169 | */ |
2170 | 2170 | ||
2171 | static unsigned int tty_poll(struct file *filp, poll_table *wait) | 2171 | static unsigned int tty_poll(struct file *filp, poll_table *wait) |
2172 | { | 2172 | { |
2173 | struct tty_struct *tty = file_tty(filp); | 2173 | struct tty_struct *tty = file_tty(filp); |
2174 | struct tty_ldisc *ld; | 2174 | struct tty_ldisc *ld; |
2175 | int ret = 0; | 2175 | int ret = 0; |
2176 | 2176 | ||
2177 | if (tty_paranoia_check(tty, file_inode(filp), "tty_poll")) | 2177 | if (tty_paranoia_check(tty, file_inode(filp), "tty_poll")) |
2178 | return 0; | 2178 | return 0; |
2179 | 2179 | ||
2180 | ld = tty_ldisc_ref_wait(tty); | 2180 | ld = tty_ldisc_ref_wait(tty); |
2181 | if (ld->ops->poll) | 2181 | if (ld->ops->poll) |
2182 | ret = ld->ops->poll(tty, filp, wait); | 2182 | ret = ld->ops->poll(tty, filp, wait); |
2183 | tty_ldisc_deref(ld); | 2183 | tty_ldisc_deref(ld); |
2184 | return ret; | 2184 | return ret; |
2185 | } | 2185 | } |
2186 | 2186 | ||
2187 | static int __tty_fasync(int fd, struct file *filp, int on) | 2187 | static int __tty_fasync(int fd, struct file *filp, int on) |
2188 | { | 2188 | { |
2189 | struct tty_struct *tty = file_tty(filp); | 2189 | struct tty_struct *tty = file_tty(filp); |
2190 | struct tty_ldisc *ldisc; | 2190 | struct tty_ldisc *ldisc; |
2191 | unsigned long flags; | 2191 | unsigned long flags; |
2192 | int retval = 0; | 2192 | int retval = 0; |
2193 | 2193 | ||
2194 | if (tty_paranoia_check(tty, file_inode(filp), "tty_fasync")) | 2194 | if (tty_paranoia_check(tty, file_inode(filp), "tty_fasync")) |
2195 | goto out; | 2195 | goto out; |
2196 | 2196 | ||
2197 | retval = fasync_helper(fd, filp, on, &tty->fasync); | 2197 | retval = fasync_helper(fd, filp, on, &tty->fasync); |
2198 | if (retval <= 0) | 2198 | if (retval <= 0) |
2199 | goto out; | 2199 | goto out; |
2200 | 2200 | ||
2201 | ldisc = tty_ldisc_ref(tty); | 2201 | ldisc = tty_ldisc_ref(tty); |
2202 | if (ldisc) { | 2202 | if (ldisc) { |
2203 | if (ldisc->ops->fasync) | 2203 | if (ldisc->ops->fasync) |
2204 | ldisc->ops->fasync(tty, on); | 2204 | ldisc->ops->fasync(tty, on); |
2205 | tty_ldisc_deref(ldisc); | 2205 | tty_ldisc_deref(ldisc); |
2206 | } | 2206 | } |
2207 | 2207 | ||
2208 | if (on) { | 2208 | if (on) { |
2209 | enum pid_type type; | 2209 | enum pid_type type; |
2210 | struct pid *pid; | 2210 | struct pid *pid; |
2211 | 2211 | ||
2212 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 2212 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
2213 | if (tty->pgrp) { | 2213 | if (tty->pgrp) { |
2214 | pid = tty->pgrp; | 2214 | pid = tty->pgrp; |
2215 | type = PIDTYPE_PGID; | 2215 | type = PIDTYPE_PGID; |
2216 | } else { | 2216 | } else { |
2217 | pid = task_pid(current); | 2217 | pid = task_pid(current); |
2218 | type = PIDTYPE_PID; | 2218 | type = PIDTYPE_PID; |
2219 | } | 2219 | } |
2220 | get_pid(pid); | 2220 | get_pid(pid); |
2221 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 2221 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
2222 | __f_setown(filp, pid, type, 0); | 2222 | __f_setown(filp, pid, type, 0); |
2223 | put_pid(pid); | 2223 | put_pid(pid); |
2224 | retval = 0; | 2224 | retval = 0; |
2225 | } | 2225 | } |
2226 | out: | 2226 | out: |
2227 | return retval; | 2227 | return retval; |
2228 | } | 2228 | } |
2229 | 2229 | ||
2230 | static int tty_fasync(int fd, struct file *filp, int on) | 2230 | static int tty_fasync(int fd, struct file *filp, int on) |
2231 | { | 2231 | { |
2232 | struct tty_struct *tty = file_tty(filp); | 2232 | struct tty_struct *tty = file_tty(filp); |
2233 | int retval; | 2233 | int retval; |
2234 | 2234 | ||
2235 | tty_lock(tty); | 2235 | tty_lock(tty); |
2236 | retval = __tty_fasync(fd, filp, on); | 2236 | retval = __tty_fasync(fd, filp, on); |
2237 | tty_unlock(tty); | 2237 | tty_unlock(tty); |
2238 | 2238 | ||
2239 | return retval; | 2239 | return retval; |
2240 | } | 2240 | } |
2241 | 2241 | ||
2242 | /** | 2242 | /** |
2243 | * tiocsti - fake input character | 2243 | * tiocsti - fake input character |
2244 | * @tty: tty to fake input into | 2244 | * @tty: tty to fake input into |
2245 | * @p: pointer to character | 2245 | * @p: pointer to character |
2246 | * | 2246 | * |
2247 | * Fake input to a tty device. Does the necessary locking and | 2247 | * Fake input to a tty device. Does the necessary locking and |
2248 | * input management. | 2248 | * input management. |
2249 | * | 2249 | * |
2250 | * FIXME: does not honour flow control ?? | 2250 | * FIXME: does not honour flow control ?? |
2251 | * | 2251 | * |
2252 | * Locking: | 2252 | * Locking: |
2253 | * Called functions take tty_ldiscs_lock | 2253 | * Called functions take tty_ldiscs_lock |
2254 | * current->signal->tty check is safe without locks | 2254 | * current->signal->tty check is safe without locks |
2255 | * | 2255 | * |
2256 | * FIXME: may race normal receive processing | 2256 | * FIXME: may race normal receive processing |
2257 | */ | 2257 | */ |
2258 | 2258 | ||
2259 | static int tiocsti(struct tty_struct *tty, char __user *p) | 2259 | static int tiocsti(struct tty_struct *tty, char __user *p) |
2260 | { | 2260 | { |
2261 | char ch, mbz = 0; | 2261 | char ch, mbz = 0; |
2262 | struct tty_ldisc *ld; | 2262 | struct tty_ldisc *ld; |
2263 | 2263 | ||
2264 | if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN)) | 2264 | if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN)) |
2265 | return -EPERM; | 2265 | return -EPERM; |
2266 | if (get_user(ch, p)) | 2266 | if (get_user(ch, p)) |
2267 | return -EFAULT; | 2267 | return -EFAULT; |
2268 | tty_audit_tiocsti(tty, ch); | 2268 | tty_audit_tiocsti(tty, ch); |
2269 | ld = tty_ldisc_ref_wait(tty); | 2269 | ld = tty_ldisc_ref_wait(tty); |
2270 | ld->ops->receive_buf(tty, &ch, &mbz, 1); | 2270 | ld->ops->receive_buf(tty, &ch, &mbz, 1); |
2271 | tty_ldisc_deref(ld); | 2271 | tty_ldisc_deref(ld); |
2272 | return 0; | 2272 | return 0; |
2273 | } | 2273 | } |
2274 | 2274 | ||
2275 | /** | 2275 | /** |
2276 | * tiocgwinsz - implement window query ioctl | 2276 | * tiocgwinsz - implement window query ioctl |
2277 | * @tty; tty | 2277 | * @tty; tty |
2278 | * @arg: user buffer for result | 2278 | * @arg: user buffer for result |
2279 | * | 2279 | * |
2280 | * Copies the kernel idea of the window size into the user buffer. | 2280 | * Copies the kernel idea of the window size into the user buffer. |
2281 | * | 2281 | * |
2282 | * Locking: tty->winsize_mutex is taken to ensure the winsize data | 2282 | * Locking: tty->winsize_mutex is taken to ensure the winsize data |
2283 | * is consistent. | 2283 | * is consistent. |
2284 | */ | 2284 | */ |
2285 | 2285 | ||
2286 | static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) | 2286 | static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) |
2287 | { | 2287 | { |
2288 | int err; | 2288 | int err; |
2289 | 2289 | ||
2290 | mutex_lock(&tty->winsize_mutex); | 2290 | mutex_lock(&tty->winsize_mutex); |
2291 | err = copy_to_user(arg, &tty->winsize, sizeof(*arg)); | 2291 | err = copy_to_user(arg, &tty->winsize, sizeof(*arg)); |
2292 | mutex_unlock(&tty->winsize_mutex); | 2292 | mutex_unlock(&tty->winsize_mutex); |
2293 | 2293 | ||
2294 | return err ? -EFAULT: 0; | 2294 | return err ? -EFAULT: 0; |
2295 | } | 2295 | } |
2296 | 2296 | ||
2297 | /** | 2297 | /** |
2298 | * tty_do_resize - resize event | 2298 | * tty_do_resize - resize event |
2299 | * @tty: tty being resized | 2299 | * @tty: tty being resized |
2300 | * @rows: rows (character) | 2300 | * @rows: rows (character) |
2301 | * @cols: cols (character) | 2301 | * @cols: cols (character) |
2302 | * | 2302 | * |
2303 | * Update the termios variables and send the necessary signals to | 2303 | * Update the termios variables and send the necessary signals to |
2304 | * peform a terminal resize correctly | 2304 | * peform a terminal resize correctly |
2305 | */ | 2305 | */ |
2306 | 2306 | ||
2307 | int tty_do_resize(struct tty_struct *tty, struct winsize *ws) | 2307 | int tty_do_resize(struct tty_struct *tty, struct winsize *ws) |
2308 | { | 2308 | { |
2309 | struct pid *pgrp; | 2309 | struct pid *pgrp; |
2310 | 2310 | ||
2311 | /* Lock the tty */ | 2311 | /* Lock the tty */ |
2312 | mutex_lock(&tty->winsize_mutex); | 2312 | mutex_lock(&tty->winsize_mutex); |
2313 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) | 2313 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) |
2314 | goto done; | 2314 | goto done; |
2315 | 2315 | ||
2316 | /* Signal the foreground process group */ | 2316 | /* Signal the foreground process group */ |
2317 | pgrp = tty_get_pgrp(tty); | 2317 | pgrp = tty_get_pgrp(tty); |
2318 | if (pgrp) | 2318 | if (pgrp) |
2319 | kill_pgrp(pgrp, SIGWINCH, 1); | 2319 | kill_pgrp(pgrp, SIGWINCH, 1); |
2320 | put_pid(pgrp); | 2320 | put_pid(pgrp); |
2321 | 2321 | ||
2322 | tty->winsize = *ws; | 2322 | tty->winsize = *ws; |
2323 | done: | 2323 | done: |
2324 | mutex_unlock(&tty->winsize_mutex); | 2324 | mutex_unlock(&tty->winsize_mutex); |
2325 | return 0; | 2325 | return 0; |
2326 | } | 2326 | } |
2327 | EXPORT_SYMBOL(tty_do_resize); | 2327 | EXPORT_SYMBOL(tty_do_resize); |
2328 | 2328 | ||
2329 | /** | 2329 | /** |
2330 | * tiocswinsz - implement window size set ioctl | 2330 | * tiocswinsz - implement window size set ioctl |
2331 | * @tty; tty side of tty | 2331 | * @tty; tty side of tty |
2332 | * @arg: user buffer for result | 2332 | * @arg: user buffer for result |
2333 | * | 2333 | * |
2334 | * Copies the user idea of the window size to the kernel. Traditionally | 2334 | * Copies the user idea of the window size to the kernel. Traditionally |
2335 | * this is just advisory information but for the Linux console it | 2335 | * this is just advisory information but for the Linux console it |
2336 | * actually has driver level meaning and triggers a VC resize. | 2336 | * actually has driver level meaning and triggers a VC resize. |
2337 | * | 2337 | * |
2338 | * Locking: | 2338 | * Locking: |
2339 | * Driver dependent. The default do_resize method takes the | 2339 | * Driver dependent. The default do_resize method takes the |
2340 | * tty termios mutex and ctrl_lock. The console takes its own lock | 2340 | * tty termios mutex and ctrl_lock. The console takes its own lock |
2341 | * then calls into the default method. | 2341 | * then calls into the default method. |
2342 | */ | 2342 | */ |
2343 | 2343 | ||
2344 | static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) | 2344 | static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) |
2345 | { | 2345 | { |
2346 | struct winsize tmp_ws; | 2346 | struct winsize tmp_ws; |
2347 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) | 2347 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) |
2348 | return -EFAULT; | 2348 | return -EFAULT; |
2349 | 2349 | ||
2350 | if (tty->ops->resize) | 2350 | if (tty->ops->resize) |
2351 | return tty->ops->resize(tty, &tmp_ws); | 2351 | return tty->ops->resize(tty, &tmp_ws); |
2352 | else | 2352 | else |
2353 | return tty_do_resize(tty, &tmp_ws); | 2353 | return tty_do_resize(tty, &tmp_ws); |
2354 | } | 2354 | } |
2355 | 2355 | ||
2356 | /** | 2356 | /** |
2357 | * tioccons - allow admin to move logical console | 2357 | * tioccons - allow admin to move logical console |
2358 | * @file: the file to become console | 2358 | * @file: the file to become console |
2359 | * | 2359 | * |
2360 | * Allow the administrator to move the redirected console device | 2360 | * Allow the administrator to move the redirected console device |
2361 | * | 2361 | * |
2362 | * Locking: uses redirect_lock to guard the redirect information | 2362 | * Locking: uses redirect_lock to guard the redirect information |
2363 | */ | 2363 | */ |
2364 | 2364 | ||
2365 | static int tioccons(struct file *file) | 2365 | static int tioccons(struct file *file) |
2366 | { | 2366 | { |
2367 | if (!capable(CAP_SYS_ADMIN)) | 2367 | if (!capable(CAP_SYS_ADMIN)) |
2368 | return -EPERM; | 2368 | return -EPERM; |
2369 | if (file->f_op->write == redirected_tty_write) { | 2369 | if (file->f_op->write == redirected_tty_write) { |
2370 | struct file *f; | 2370 | struct file *f; |
2371 | spin_lock(&redirect_lock); | 2371 | spin_lock(&redirect_lock); |
2372 | f = redirect; | 2372 | f = redirect; |
2373 | redirect = NULL; | 2373 | redirect = NULL; |
2374 | spin_unlock(&redirect_lock); | 2374 | spin_unlock(&redirect_lock); |
2375 | if (f) | 2375 | if (f) |
2376 | fput(f); | 2376 | fput(f); |
2377 | return 0; | 2377 | return 0; |
2378 | } | 2378 | } |
2379 | spin_lock(&redirect_lock); | 2379 | spin_lock(&redirect_lock); |
2380 | if (redirect) { | 2380 | if (redirect) { |
2381 | spin_unlock(&redirect_lock); | 2381 | spin_unlock(&redirect_lock); |
2382 | return -EBUSY; | 2382 | return -EBUSY; |
2383 | } | 2383 | } |
2384 | redirect = get_file(file); | 2384 | redirect = get_file(file); |
2385 | spin_unlock(&redirect_lock); | 2385 | spin_unlock(&redirect_lock); |
2386 | return 0; | 2386 | return 0; |
2387 | } | 2387 | } |
2388 | 2388 | ||
2389 | /** | 2389 | /** |
2390 | * fionbio - non blocking ioctl | 2390 | * fionbio - non blocking ioctl |
2391 | * @file: file to set blocking value | 2391 | * @file: file to set blocking value |
2392 | * @p: user parameter | 2392 | * @p: user parameter |
2393 | * | 2393 | * |
2394 | * Historical tty interfaces had a blocking control ioctl before | 2394 | * Historical tty interfaces had a blocking control ioctl before |
2395 | * the generic functionality existed. This piece of history is preserved | 2395 | * the generic functionality existed. This piece of history is preserved |
2396 | * in the expected tty API of posix OS's. | 2396 | * in the expected tty API of posix OS's. |
2397 | * | 2397 | * |
2398 | * Locking: none, the open file handle ensures it won't go away. | 2398 | * Locking: none, the open file handle ensures it won't go away. |
2399 | */ | 2399 | */ |
2400 | 2400 | ||
2401 | static int fionbio(struct file *file, int __user *p) | 2401 | static int fionbio(struct file *file, int __user *p) |
2402 | { | 2402 | { |
2403 | int nonblock; | 2403 | int nonblock; |
2404 | 2404 | ||
2405 | if (get_user(nonblock, p)) | 2405 | if (get_user(nonblock, p)) |
2406 | return -EFAULT; | 2406 | return -EFAULT; |
2407 | 2407 | ||
2408 | spin_lock(&file->f_lock); | 2408 | spin_lock(&file->f_lock); |
2409 | if (nonblock) | 2409 | if (nonblock) |
2410 | file->f_flags |= O_NONBLOCK; | 2410 | file->f_flags |= O_NONBLOCK; |
2411 | else | 2411 | else |
2412 | file->f_flags &= ~O_NONBLOCK; | 2412 | file->f_flags &= ~O_NONBLOCK; |
2413 | spin_unlock(&file->f_lock); | 2413 | spin_unlock(&file->f_lock); |
2414 | return 0; | 2414 | return 0; |
2415 | } | 2415 | } |
2416 | 2416 | ||
2417 | /** | 2417 | /** |
2418 | * tiocsctty - set controlling tty | 2418 | * tiocsctty - set controlling tty |
2419 | * @tty: tty structure | 2419 | * @tty: tty structure |
2420 | * @arg: user argument | 2420 | * @arg: user argument |
2421 | * | 2421 | * |
2422 | * This ioctl is used to manage job control. It permits a session | 2422 | * This ioctl is used to manage job control. It permits a session |
2423 | * leader to set this tty as the controlling tty for the session. | 2423 | * leader to set this tty as the controlling tty for the session. |
2424 | * | 2424 | * |
2425 | * Locking: | 2425 | * Locking: |
2426 | * Takes tty_lock() to serialize proc_set_tty() for this tty | 2426 | * Takes tty_lock() to serialize proc_set_tty() for this tty |
2427 | * Takes tasklist_lock internally to walk sessions | 2427 | * Takes tasklist_lock internally to walk sessions |
2428 | * Takes ->siglock() when updating signal->tty | 2428 | * Takes ->siglock() when updating signal->tty |
2429 | */ | 2429 | */ |
2430 | 2430 | ||
2431 | static int tiocsctty(struct tty_struct *tty, int arg) | 2431 | static int tiocsctty(struct tty_struct *tty, int arg) |
2432 | { | 2432 | { |
2433 | int ret = 0; | 2433 | int ret = 0; |
2434 | 2434 | ||
2435 | tty_lock(tty); | 2435 | tty_lock(tty); |
2436 | read_lock(&tasklist_lock); | 2436 | read_lock(&tasklist_lock); |
2437 | 2437 | ||
2438 | if (current->signal->leader && (task_session(current) == tty->session)) | 2438 | if (current->signal->leader && (task_session(current) == tty->session)) |
2439 | goto unlock; | 2439 | goto unlock; |
2440 | 2440 | ||
2441 | /* | 2441 | /* |
2442 | * The process must be a session leader and | 2442 | * The process must be a session leader and |
2443 | * not have a controlling tty already. | 2443 | * not have a controlling tty already. |
2444 | */ | 2444 | */ |
2445 | if (!current->signal->leader || current->signal->tty) { | 2445 | if (!current->signal->leader || current->signal->tty) { |
2446 | ret = -EPERM; | 2446 | ret = -EPERM; |
2447 | goto unlock; | 2447 | goto unlock; |
2448 | } | 2448 | } |
2449 | 2449 | ||
2450 | if (tty->session) { | 2450 | if (tty->session) { |
2451 | /* | 2451 | /* |
2452 | * This tty is already the controlling | 2452 | * This tty is already the controlling |
2453 | * tty for another session group! | 2453 | * tty for another session group! |
2454 | */ | 2454 | */ |
2455 | if (arg == 1 && capable(CAP_SYS_ADMIN)) { | 2455 | if (arg == 1 && capable(CAP_SYS_ADMIN)) { |
2456 | /* | 2456 | /* |
2457 | * Steal it away | 2457 | * Steal it away |
2458 | */ | 2458 | */ |
2459 | session_clear_tty(tty->session); | 2459 | session_clear_tty(tty->session); |
2460 | } else { | 2460 | } else { |
2461 | ret = -EPERM; | 2461 | ret = -EPERM; |
2462 | goto unlock; | 2462 | goto unlock; |
2463 | } | 2463 | } |
2464 | } | 2464 | } |
2465 | proc_set_tty(tty); | 2465 | proc_set_tty(tty); |
2466 | unlock: | 2466 | unlock: |
2467 | read_unlock(&tasklist_lock); | 2467 | read_unlock(&tasklist_lock); |
2468 | tty_unlock(tty); | 2468 | tty_unlock(tty); |
2469 | return ret; | 2469 | return ret; |
2470 | } | 2470 | } |
2471 | 2471 | ||
2472 | /** | 2472 | /** |
2473 | * tty_get_pgrp - return a ref counted pgrp pid | 2473 | * tty_get_pgrp - return a ref counted pgrp pid |
2474 | * @tty: tty to read | 2474 | * @tty: tty to read |
2475 | * | 2475 | * |
2476 | * Returns a refcounted instance of the pid struct for the process | 2476 | * Returns a refcounted instance of the pid struct for the process |
2477 | * group controlling the tty. | 2477 | * group controlling the tty. |
2478 | */ | 2478 | */ |
2479 | 2479 | ||
2480 | struct pid *tty_get_pgrp(struct tty_struct *tty) | 2480 | struct pid *tty_get_pgrp(struct tty_struct *tty) |
2481 | { | 2481 | { |
2482 | unsigned long flags; | 2482 | unsigned long flags; |
2483 | struct pid *pgrp; | 2483 | struct pid *pgrp; |
2484 | 2484 | ||
2485 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 2485 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
2486 | pgrp = get_pid(tty->pgrp); | 2486 | pgrp = get_pid(tty->pgrp); |
2487 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 2487 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
2488 | 2488 | ||
2489 | return pgrp; | 2489 | return pgrp; |
2490 | } | 2490 | } |
2491 | EXPORT_SYMBOL_GPL(tty_get_pgrp); | 2491 | EXPORT_SYMBOL_GPL(tty_get_pgrp); |
2492 | 2492 | ||
2493 | /* | 2493 | /* |
2494 | * This checks not only the pgrp, but falls back on the pid if no | 2494 | * This checks not only the pgrp, but falls back on the pid if no |
2495 | * satisfactory pgrp is found. I dunno - gdb doesn't work correctly | 2495 | * satisfactory pgrp is found. I dunno - gdb doesn't work correctly |
2496 | * without this... | 2496 | * without this... |
2497 | * | 2497 | * |
2498 | * The caller must hold rcu lock or the tasklist lock. | 2498 | * The caller must hold rcu lock or the tasklist lock. |
2499 | */ | 2499 | */ |
2500 | static struct pid *session_of_pgrp(struct pid *pgrp) | 2500 | static struct pid *session_of_pgrp(struct pid *pgrp) |
2501 | { | 2501 | { |
2502 | struct task_struct *p; | 2502 | struct task_struct *p; |
2503 | struct pid *sid = NULL; | 2503 | struct pid *sid = NULL; |
2504 | 2504 | ||
2505 | p = pid_task(pgrp, PIDTYPE_PGID); | 2505 | p = pid_task(pgrp, PIDTYPE_PGID); |
2506 | if (p == NULL) | 2506 | if (p == NULL) |
2507 | p = pid_task(pgrp, PIDTYPE_PID); | 2507 | p = pid_task(pgrp, PIDTYPE_PID); |
2508 | if (p != NULL) | 2508 | if (p != NULL) |
2509 | sid = task_session(p); | 2509 | sid = task_session(p); |
2510 | 2510 | ||
2511 | return sid; | 2511 | return sid; |
2512 | } | 2512 | } |
2513 | 2513 | ||
2514 | /** | 2514 | /** |
2515 | * tiocgpgrp - get process group | 2515 | * tiocgpgrp - get process group |
2516 | * @tty: tty passed by user | 2516 | * @tty: tty passed by user |
2517 | * @real_tty: tty side of the tty passed by the user if a pty else the tty | 2517 | * @real_tty: tty side of the tty passed by the user if a pty else the tty |
2518 | * @p: returned pid | 2518 | * @p: returned pid |
2519 | * | 2519 | * |
2520 | * Obtain the process group of the tty. If there is no process group | 2520 | * Obtain the process group of the tty. If there is no process group |
2521 | * return an error. | 2521 | * return an error. |
2522 | * | 2522 | * |
2523 | * Locking: none. Reference to current->signal->tty is safe. | 2523 | * Locking: none. Reference to current->signal->tty is safe. |
2524 | */ | 2524 | */ |
2525 | 2525 | ||
2526 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2526 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2527 | { | 2527 | { |
2528 | struct pid *pid; | 2528 | struct pid *pid; |
2529 | int ret; | 2529 | int ret; |
2530 | /* | 2530 | /* |
2531 | * (tty == real_tty) is a cheap way of | 2531 | * (tty == real_tty) is a cheap way of |
2532 | * testing if the tty is NOT a master pty. | 2532 | * testing if the tty is NOT a master pty. |
2533 | */ | 2533 | */ |
2534 | if (tty == real_tty && current->signal->tty != real_tty) | 2534 | if (tty == real_tty && current->signal->tty != real_tty) |
2535 | return -ENOTTY; | 2535 | return -ENOTTY; |
2536 | pid = tty_get_pgrp(real_tty); | 2536 | pid = tty_get_pgrp(real_tty); |
2537 | ret = put_user(pid_vnr(pid), p); | 2537 | ret = put_user(pid_vnr(pid), p); |
2538 | put_pid(pid); | 2538 | put_pid(pid); |
2539 | return ret; | 2539 | return ret; |
2540 | } | 2540 | } |
2541 | 2541 | ||
2542 | /** | 2542 | /** |
2543 | * tiocspgrp - attempt to set process group | 2543 | * tiocspgrp - attempt to set process group |
2544 | * @tty: tty passed by user | 2544 | * @tty: tty passed by user |
2545 | * @real_tty: tty side device matching tty passed by user | 2545 | * @real_tty: tty side device matching tty passed by user |
2546 | * @p: pid pointer | 2546 | * @p: pid pointer |
2547 | * | 2547 | * |
2548 | * Set the process group of the tty to the session passed. Only | 2548 | * Set the process group of the tty to the session passed. Only |
2549 | * permitted where the tty session is our session. | 2549 | * permitted where the tty session is our session. |
2550 | * | 2550 | * |
2551 | * Locking: RCU, ctrl lock | 2551 | * Locking: RCU, ctrl lock |
2552 | */ | 2552 | */ |
2553 | 2553 | ||
2554 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2554 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2555 | { | 2555 | { |
2556 | struct pid *pgrp; | 2556 | struct pid *pgrp; |
2557 | pid_t pgrp_nr; | 2557 | pid_t pgrp_nr; |
2558 | int retval = tty_check_change(real_tty); | 2558 | int retval = tty_check_change(real_tty); |
2559 | unsigned long flags; | 2559 | unsigned long flags; |
2560 | 2560 | ||
2561 | if (retval == -EIO) | 2561 | if (retval == -EIO) |
2562 | return -ENOTTY; | 2562 | return -ENOTTY; |
2563 | if (retval) | 2563 | if (retval) |
2564 | return retval; | 2564 | return retval; |
2565 | if (!current->signal->tty || | 2565 | if (!current->signal->tty || |
2566 | (current->signal->tty != real_tty) || | 2566 | (current->signal->tty != real_tty) || |
2567 | (real_tty->session != task_session(current))) | 2567 | (real_tty->session != task_session(current))) |
2568 | return -ENOTTY; | 2568 | return -ENOTTY; |
2569 | if (get_user(pgrp_nr, p)) | 2569 | if (get_user(pgrp_nr, p)) |
2570 | return -EFAULT; | 2570 | return -EFAULT; |
2571 | if (pgrp_nr < 0) | 2571 | if (pgrp_nr < 0) |
2572 | return -EINVAL; | 2572 | return -EINVAL; |
2573 | rcu_read_lock(); | 2573 | rcu_read_lock(); |
2574 | pgrp = find_vpid(pgrp_nr); | 2574 | pgrp = find_vpid(pgrp_nr); |
2575 | retval = -ESRCH; | 2575 | retval = -ESRCH; |
2576 | if (!pgrp) | 2576 | if (!pgrp) |
2577 | goto out_unlock; | 2577 | goto out_unlock; |
2578 | retval = -EPERM; | 2578 | retval = -EPERM; |
2579 | if (session_of_pgrp(pgrp) != task_session(current)) | 2579 | if (session_of_pgrp(pgrp) != task_session(current)) |
2580 | goto out_unlock; | 2580 | goto out_unlock; |
2581 | retval = 0; | 2581 | retval = 0; |
2582 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 2582 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
2583 | put_pid(real_tty->pgrp); | 2583 | put_pid(real_tty->pgrp); |
2584 | real_tty->pgrp = get_pid(pgrp); | 2584 | real_tty->pgrp = get_pid(pgrp); |
2585 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 2585 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
2586 | out_unlock: | 2586 | out_unlock: |
2587 | rcu_read_unlock(); | 2587 | rcu_read_unlock(); |
2588 | return retval; | 2588 | return retval; |
2589 | } | 2589 | } |
2590 | 2590 | ||
2591 | /** | 2591 | /** |
2592 | * tiocgsid - get session id | 2592 | * tiocgsid - get session id |
2593 | * @tty: tty passed by user | 2593 | * @tty: tty passed by user |
2594 | * @real_tty: tty side of the tty passed by the user if a pty else the tty | 2594 | * @real_tty: tty side of the tty passed by the user if a pty else the tty |
2595 | * @p: pointer to returned session id | 2595 | * @p: pointer to returned session id |
2596 | * | 2596 | * |
2597 | * Obtain the session id of the tty. If there is no session | 2597 | * Obtain the session id of the tty. If there is no session |
2598 | * return an error. | 2598 | * return an error. |
2599 | * | 2599 | * |
2600 | * Locking: none. Reference to current->signal->tty is safe. | 2600 | * Locking: none. Reference to current->signal->tty is safe. |
2601 | */ | 2601 | */ |
2602 | 2602 | ||
2603 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2603 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2604 | { | 2604 | { |
2605 | /* | 2605 | /* |
2606 | * (tty == real_tty) is a cheap way of | 2606 | * (tty == real_tty) is a cheap way of |
2607 | * testing if the tty is NOT a master pty. | 2607 | * testing if the tty is NOT a master pty. |
2608 | */ | 2608 | */ |
2609 | if (tty == real_tty && current->signal->tty != real_tty) | 2609 | if (tty == real_tty && current->signal->tty != real_tty) |
2610 | return -ENOTTY; | 2610 | return -ENOTTY; |
2611 | if (!real_tty->session) | 2611 | if (!real_tty->session) |
2612 | return -ENOTTY; | 2612 | return -ENOTTY; |
2613 | return put_user(pid_vnr(real_tty->session), p); | 2613 | return put_user(pid_vnr(real_tty->session), p); |
2614 | } | 2614 | } |
2615 | 2615 | ||
2616 | /** | 2616 | /** |
2617 | * tiocsetd - set line discipline | 2617 | * tiocsetd - set line discipline |
2618 | * @tty: tty device | 2618 | * @tty: tty device |
2619 | * @p: pointer to user data | 2619 | * @p: pointer to user data |
2620 | * | 2620 | * |
2621 | * Set the line discipline according to user request. | 2621 | * Set the line discipline according to user request. |
2622 | * | 2622 | * |
2623 | * Locking: see tty_set_ldisc, this function is just a helper | 2623 | * Locking: see tty_set_ldisc, this function is just a helper |
2624 | */ | 2624 | */ |
2625 | 2625 | ||
2626 | static int tiocsetd(struct tty_struct *tty, int __user *p) | 2626 | static int tiocsetd(struct tty_struct *tty, int __user *p) |
2627 | { | 2627 | { |
2628 | int ldisc; | 2628 | int ldisc; |
2629 | int ret; | 2629 | int ret; |
2630 | 2630 | ||
2631 | if (get_user(ldisc, p)) | 2631 | if (get_user(ldisc, p)) |
2632 | return -EFAULT; | 2632 | return -EFAULT; |
2633 | 2633 | ||
2634 | ret = tty_set_ldisc(tty, ldisc); | 2634 | ret = tty_set_ldisc(tty, ldisc); |
2635 | 2635 | ||
2636 | return ret; | 2636 | return ret; |
2637 | } | 2637 | } |
2638 | 2638 | ||
2639 | /** | 2639 | /** |
2640 | * send_break - performed time break | 2640 | * send_break - performed time break |
2641 | * @tty: device to break on | 2641 | * @tty: device to break on |
2642 | * @duration: timeout in mS | 2642 | * @duration: timeout in mS |
2643 | * | 2643 | * |
2644 | * Perform a timed break on hardware that lacks its own driver level | 2644 | * Perform a timed break on hardware that lacks its own driver level |
2645 | * timed break functionality. | 2645 | * timed break functionality. |
2646 | * | 2646 | * |
2647 | * Locking: | 2647 | * Locking: |
2648 | * atomic_write_lock serializes | 2648 | * atomic_write_lock serializes |
2649 | * | 2649 | * |
2650 | */ | 2650 | */ |
2651 | 2651 | ||
2652 | static int send_break(struct tty_struct *tty, unsigned int duration) | 2652 | static int send_break(struct tty_struct *tty, unsigned int duration) |
2653 | { | 2653 | { |
2654 | int retval; | 2654 | int retval; |
2655 | 2655 | ||
2656 | if (tty->ops->break_ctl == NULL) | 2656 | if (tty->ops->break_ctl == NULL) |
2657 | return 0; | 2657 | return 0; |
2658 | 2658 | ||
2659 | if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) | 2659 | if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) |
2660 | retval = tty->ops->break_ctl(tty, duration); | 2660 | retval = tty->ops->break_ctl(tty, duration); |
2661 | else { | 2661 | else { |
2662 | /* Do the work ourselves */ | 2662 | /* Do the work ourselves */ |
2663 | if (tty_write_lock(tty, 0) < 0) | 2663 | if (tty_write_lock(tty, 0) < 0) |
2664 | return -EINTR; | 2664 | return -EINTR; |
2665 | retval = tty->ops->break_ctl(tty, -1); | 2665 | retval = tty->ops->break_ctl(tty, -1); |
2666 | if (retval) | 2666 | if (retval) |
2667 | goto out; | 2667 | goto out; |
2668 | if (!signal_pending(current)) | 2668 | if (!signal_pending(current)) |
2669 | msleep_interruptible(duration); | 2669 | msleep_interruptible(duration); |
2670 | retval = tty->ops->break_ctl(tty, 0); | 2670 | retval = tty->ops->break_ctl(tty, 0); |
2671 | out: | 2671 | out: |
2672 | tty_write_unlock(tty); | 2672 | tty_write_unlock(tty); |
2673 | if (signal_pending(current)) | 2673 | if (signal_pending(current)) |
2674 | retval = -EINTR; | 2674 | retval = -EINTR; |
2675 | } | 2675 | } |
2676 | return retval; | 2676 | return retval; |
2677 | } | 2677 | } |
2678 | 2678 | ||
2679 | /** | 2679 | /** |
2680 | * tty_tiocmget - get modem status | 2680 | * tty_tiocmget - get modem status |
2681 | * @tty: tty device | 2681 | * @tty: tty device |
2682 | * @file: user file pointer | 2682 | * @file: user file pointer |
2683 | * @p: pointer to result | 2683 | * @p: pointer to result |
2684 | * | 2684 | * |
2685 | * Obtain the modem status bits from the tty driver if the feature | 2685 | * Obtain the modem status bits from the tty driver if the feature |
2686 | * is supported. Return -EINVAL if it is not available. | 2686 | * is supported. Return -EINVAL if it is not available. |
2687 | * | 2687 | * |
2688 | * Locking: none (up to the driver) | 2688 | * Locking: none (up to the driver) |
2689 | */ | 2689 | */ |
2690 | 2690 | ||
2691 | static int tty_tiocmget(struct tty_struct *tty, int __user *p) | 2691 | static int tty_tiocmget(struct tty_struct *tty, int __user *p) |
2692 | { | 2692 | { |
2693 | int retval = -EINVAL; | 2693 | int retval = -EINVAL; |
2694 | 2694 | ||
2695 | if (tty->ops->tiocmget) { | 2695 | if (tty->ops->tiocmget) { |
2696 | retval = tty->ops->tiocmget(tty); | 2696 | retval = tty->ops->tiocmget(tty); |
2697 | 2697 | ||
2698 | if (retval >= 0) | 2698 | if (retval >= 0) |
2699 | retval = put_user(retval, p); | 2699 | retval = put_user(retval, p); |
2700 | } | 2700 | } |
2701 | return retval; | 2701 | return retval; |
2702 | } | 2702 | } |
2703 | 2703 | ||
2704 | /** | 2704 | /** |
2705 | * tty_tiocmset - set modem status | 2705 | * tty_tiocmset - set modem status |
2706 | * @tty: tty device | 2706 | * @tty: tty device |
2707 | * @cmd: command - clear bits, set bits or set all | 2707 | * @cmd: command - clear bits, set bits or set all |
2708 | * @p: pointer to desired bits | 2708 | * @p: pointer to desired bits |
2709 | * | 2709 | * |
2710 | * Set the modem status bits from the tty driver if the feature | 2710 | * Set the modem status bits from the tty driver if the feature |
2711 | * is supported. Return -EINVAL if it is not available. | 2711 | * is supported. Return -EINVAL if it is not available. |
2712 | * | 2712 | * |
2713 | * Locking: none (up to the driver) | 2713 | * Locking: none (up to the driver) |
2714 | */ | 2714 | */ |
2715 | 2715 | ||
2716 | static int tty_tiocmset(struct tty_struct *tty, unsigned int cmd, | 2716 | static int tty_tiocmset(struct tty_struct *tty, unsigned int cmd, |
2717 | unsigned __user *p) | 2717 | unsigned __user *p) |
2718 | { | 2718 | { |
2719 | int retval; | 2719 | int retval; |
2720 | unsigned int set, clear, val; | 2720 | unsigned int set, clear, val; |
2721 | 2721 | ||
2722 | if (tty->ops->tiocmset == NULL) | 2722 | if (tty->ops->tiocmset == NULL) |
2723 | return -EINVAL; | 2723 | return -EINVAL; |
2724 | 2724 | ||
2725 | retval = get_user(val, p); | 2725 | retval = get_user(val, p); |
2726 | if (retval) | 2726 | if (retval) |
2727 | return retval; | 2727 | return retval; |
2728 | set = clear = 0; | 2728 | set = clear = 0; |
2729 | switch (cmd) { | 2729 | switch (cmd) { |
2730 | case TIOCMBIS: | 2730 | case TIOCMBIS: |
2731 | set = val; | 2731 | set = val; |
2732 | break; | 2732 | break; |
2733 | case TIOCMBIC: | 2733 | case TIOCMBIC: |
2734 | clear = val; | 2734 | clear = val; |
2735 | break; | 2735 | break; |
2736 | case TIOCMSET: | 2736 | case TIOCMSET: |
2737 | set = val; | 2737 | set = val; |
2738 | clear = ~val; | 2738 | clear = ~val; |
2739 | break; | 2739 | break; |
2740 | } | 2740 | } |
2741 | set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; | 2741 | set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; |
2742 | clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; | 2742 | clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; |
2743 | return tty->ops->tiocmset(tty, set, clear); | 2743 | return tty->ops->tiocmset(tty, set, clear); |
2744 | } | 2744 | } |
2745 | 2745 | ||
2746 | static int tty_tiocgicount(struct tty_struct *tty, void __user *arg) | 2746 | static int tty_tiocgicount(struct tty_struct *tty, void __user *arg) |
2747 | { | 2747 | { |
2748 | int retval = -EINVAL; | 2748 | int retval = -EINVAL; |
2749 | struct serial_icounter_struct icount; | 2749 | struct serial_icounter_struct icount; |
2750 | memset(&icount, 0, sizeof(icount)); | 2750 | memset(&icount, 0, sizeof(icount)); |
2751 | if (tty->ops->get_icount) | 2751 | if (tty->ops->get_icount) |
2752 | retval = tty->ops->get_icount(tty, &icount); | 2752 | retval = tty->ops->get_icount(tty, &icount); |
2753 | if (retval != 0) | 2753 | if (retval != 0) |
2754 | return retval; | 2754 | return retval; |
2755 | if (copy_to_user(arg, &icount, sizeof(icount))) | 2755 | if (copy_to_user(arg, &icount, sizeof(icount))) |
2756 | return -EFAULT; | 2756 | return -EFAULT; |
2757 | return 0; | 2757 | return 0; |
2758 | } | 2758 | } |
2759 | 2759 | ||
2760 | static void tty_warn_deprecated_flags(struct serial_struct __user *ss) | 2760 | static void tty_warn_deprecated_flags(struct serial_struct __user *ss) |
2761 | { | 2761 | { |
2762 | static DEFINE_RATELIMIT_STATE(depr_flags, | 2762 | static DEFINE_RATELIMIT_STATE(depr_flags, |
2763 | DEFAULT_RATELIMIT_INTERVAL, | 2763 | DEFAULT_RATELIMIT_INTERVAL, |
2764 | DEFAULT_RATELIMIT_BURST); | 2764 | DEFAULT_RATELIMIT_BURST); |
2765 | char comm[TASK_COMM_LEN]; | 2765 | char comm[TASK_COMM_LEN]; |
2766 | int flags; | 2766 | int flags; |
2767 | 2767 | ||
2768 | if (get_user(flags, &ss->flags)) | 2768 | if (get_user(flags, &ss->flags)) |
2769 | return; | 2769 | return; |
2770 | 2770 | ||
2771 | flags &= ASYNC_DEPRECATED; | 2771 | flags &= ASYNC_DEPRECATED; |
2772 | 2772 | ||
2773 | if (flags && __ratelimit(&depr_flags)) | 2773 | if (flags && __ratelimit(&depr_flags)) |
2774 | pr_warning("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n", | 2774 | pr_warning("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n", |
2775 | __func__, get_task_comm(comm, current), flags); | 2775 | __func__, get_task_comm(comm, current), flags); |
2776 | } | 2776 | } |
2777 | 2777 | ||
2778 | /* | 2778 | /* |
2779 | * if pty, return the slave side (real_tty) | 2779 | * if pty, return the slave side (real_tty) |
2780 | * otherwise, return self | 2780 | * otherwise, return self |
2781 | */ | 2781 | */ |
2782 | static struct tty_struct *tty_pair_get_tty(struct tty_struct *tty) | 2782 | static struct tty_struct *tty_pair_get_tty(struct tty_struct *tty) |
2783 | { | 2783 | { |
2784 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 2784 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
2785 | tty->driver->subtype == PTY_TYPE_MASTER) | 2785 | tty->driver->subtype == PTY_TYPE_MASTER) |
2786 | tty = tty->link; | 2786 | tty = tty->link; |
2787 | return tty; | 2787 | return tty; |
2788 | } | 2788 | } |
2789 | 2789 | ||
2790 | /* | 2790 | /* |
2791 | * Split this up, as gcc can choke on it otherwise.. | 2791 | * Split this up, as gcc can choke on it otherwise.. |
2792 | */ | 2792 | */ |
2793 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 2793 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
2794 | { | 2794 | { |
2795 | struct tty_struct *tty = file_tty(file); | 2795 | struct tty_struct *tty = file_tty(file); |
2796 | struct tty_struct *real_tty; | 2796 | struct tty_struct *real_tty; |
2797 | void __user *p = (void __user *)arg; | 2797 | void __user *p = (void __user *)arg; |
2798 | int retval; | 2798 | int retval; |
2799 | struct tty_ldisc *ld; | 2799 | struct tty_ldisc *ld; |
2800 | 2800 | ||
2801 | if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl")) | 2801 | if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl")) |
2802 | return -EINVAL; | 2802 | return -EINVAL; |
2803 | 2803 | ||
2804 | real_tty = tty_pair_get_tty(tty); | 2804 | real_tty = tty_pair_get_tty(tty); |
2805 | 2805 | ||
2806 | /* | 2806 | /* |
2807 | * Factor out some common prep work | 2807 | * Factor out some common prep work |
2808 | */ | 2808 | */ |
2809 | switch (cmd) { | 2809 | switch (cmd) { |
2810 | case TIOCSETD: | 2810 | case TIOCSETD: |
2811 | case TIOCSBRK: | 2811 | case TIOCSBRK: |
2812 | case TIOCCBRK: | 2812 | case TIOCCBRK: |
2813 | case TCSBRK: | 2813 | case TCSBRK: |
2814 | case TCSBRKP: | 2814 | case TCSBRKP: |
2815 | retval = tty_check_change(tty); | 2815 | retval = tty_check_change(tty); |
2816 | if (retval) | 2816 | if (retval) |
2817 | return retval; | 2817 | return retval; |
2818 | if (cmd != TIOCCBRK) { | 2818 | if (cmd != TIOCCBRK) { |
2819 | tty_wait_until_sent(tty, 0); | 2819 | tty_wait_until_sent(tty, 0); |
2820 | if (signal_pending(current)) | 2820 | if (signal_pending(current)) |
2821 | return -EINTR; | 2821 | return -EINTR; |
2822 | } | 2822 | } |
2823 | break; | 2823 | break; |
2824 | } | 2824 | } |
2825 | 2825 | ||
2826 | /* | 2826 | /* |
2827 | * Now do the stuff. | 2827 | * Now do the stuff. |
2828 | */ | 2828 | */ |
2829 | switch (cmd) { | 2829 | switch (cmd) { |
2830 | case TIOCSTI: | 2830 | case TIOCSTI: |
2831 | return tiocsti(tty, p); | 2831 | return tiocsti(tty, p); |
2832 | case TIOCGWINSZ: | 2832 | case TIOCGWINSZ: |
2833 | return tiocgwinsz(real_tty, p); | 2833 | return tiocgwinsz(real_tty, p); |
2834 | case TIOCSWINSZ: | 2834 | case TIOCSWINSZ: |
2835 | return tiocswinsz(real_tty, p); | 2835 | return tiocswinsz(real_tty, p); |
2836 | case TIOCCONS: | 2836 | case TIOCCONS: |
2837 | return real_tty != tty ? -EINVAL : tioccons(file); | 2837 | return real_tty != tty ? -EINVAL : tioccons(file); |
2838 | case FIONBIO: | 2838 | case FIONBIO: |
2839 | return fionbio(file, p); | 2839 | return fionbio(file, p); |
2840 | case TIOCEXCL: | 2840 | case TIOCEXCL: |
2841 | set_bit(TTY_EXCLUSIVE, &tty->flags); | 2841 | set_bit(TTY_EXCLUSIVE, &tty->flags); |
2842 | return 0; | 2842 | return 0; |
2843 | case TIOCNXCL: | 2843 | case TIOCNXCL: |
2844 | clear_bit(TTY_EXCLUSIVE, &tty->flags); | 2844 | clear_bit(TTY_EXCLUSIVE, &tty->flags); |
2845 | return 0; | 2845 | return 0; |
2846 | case TIOCGEXCL: | 2846 | case TIOCGEXCL: |
2847 | { | 2847 | { |
2848 | int excl = test_bit(TTY_EXCLUSIVE, &tty->flags); | 2848 | int excl = test_bit(TTY_EXCLUSIVE, &tty->flags); |
2849 | return put_user(excl, (int __user *)p); | 2849 | return put_user(excl, (int __user *)p); |
2850 | } | 2850 | } |
2851 | case TIOCNOTTY: | 2851 | case TIOCNOTTY: |
2852 | if (current->signal->tty != tty) | 2852 | if (current->signal->tty != tty) |
2853 | return -ENOTTY; | 2853 | return -ENOTTY; |
2854 | no_tty(); | 2854 | no_tty(); |
2855 | return 0; | 2855 | return 0; |
2856 | case TIOCSCTTY: | 2856 | case TIOCSCTTY: |
2857 | return tiocsctty(tty, arg); | 2857 | return tiocsctty(tty, arg); |
2858 | case TIOCGPGRP: | 2858 | case TIOCGPGRP: |
2859 | return tiocgpgrp(tty, real_tty, p); | 2859 | return tiocgpgrp(tty, real_tty, p); |
2860 | case TIOCSPGRP: | 2860 | case TIOCSPGRP: |
2861 | return tiocspgrp(tty, real_tty, p); | 2861 | return tiocspgrp(tty, real_tty, p); |
2862 | case TIOCGSID: | 2862 | case TIOCGSID: |
2863 | return tiocgsid(tty, real_tty, p); | 2863 | return tiocgsid(tty, real_tty, p); |
2864 | case TIOCGETD: | 2864 | case TIOCGETD: |
2865 | return put_user(tty->ldisc->ops->num, (int __user *)p); | 2865 | return put_user(tty->ldisc->ops->num, (int __user *)p); |
2866 | case TIOCSETD: | 2866 | case TIOCSETD: |
2867 | return tiocsetd(tty, p); | 2867 | return tiocsetd(tty, p); |
2868 | case TIOCVHANGUP: | 2868 | case TIOCVHANGUP: |
2869 | if (!capable(CAP_SYS_ADMIN)) | 2869 | if (!capable(CAP_SYS_ADMIN)) |
2870 | return -EPERM; | 2870 | return -EPERM; |
2871 | tty_vhangup(tty); | 2871 | tty_vhangup(tty); |
2872 | return 0; | 2872 | return 0; |
2873 | case TIOCGDEV: | 2873 | case TIOCGDEV: |
2874 | { | 2874 | { |
2875 | unsigned int ret = new_encode_dev(tty_devnum(real_tty)); | 2875 | unsigned int ret = new_encode_dev(tty_devnum(real_tty)); |
2876 | return put_user(ret, (unsigned int __user *)p); | 2876 | return put_user(ret, (unsigned int __user *)p); |
2877 | } | 2877 | } |
2878 | /* | 2878 | /* |
2879 | * Break handling | 2879 | * Break handling |
2880 | */ | 2880 | */ |
2881 | case TIOCSBRK: /* Turn break on, unconditionally */ | 2881 | case TIOCSBRK: /* Turn break on, unconditionally */ |
2882 | if (tty->ops->break_ctl) | 2882 | if (tty->ops->break_ctl) |
2883 | return tty->ops->break_ctl(tty, -1); | 2883 | return tty->ops->break_ctl(tty, -1); |
2884 | return 0; | 2884 | return 0; |
2885 | case TIOCCBRK: /* Turn break off, unconditionally */ | 2885 | case TIOCCBRK: /* Turn break off, unconditionally */ |
2886 | if (tty->ops->break_ctl) | 2886 | if (tty->ops->break_ctl) |
2887 | return tty->ops->break_ctl(tty, 0); | 2887 | return tty->ops->break_ctl(tty, 0); |
2888 | return 0; | 2888 | return 0; |
2889 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 2889 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
2890 | /* non-zero arg means wait for all output data | 2890 | /* non-zero arg means wait for all output data |
2891 | * to be sent (performed above) but don't send break. | 2891 | * to be sent (performed above) but don't send break. |
2892 | * This is used by the tcdrain() termios function. | 2892 | * This is used by the tcdrain() termios function. |
2893 | */ | 2893 | */ |
2894 | if (!arg) | 2894 | if (!arg) |
2895 | return send_break(tty, 250); | 2895 | return send_break(tty, 250); |
2896 | return 0; | 2896 | return 0; |
2897 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | 2897 | case TCSBRKP: /* support for POSIX tcsendbreak() */ |
2898 | return send_break(tty, arg ? arg*100 : 250); | 2898 | return send_break(tty, arg ? arg*100 : 250); |
2899 | 2899 | ||
2900 | case TIOCMGET: | 2900 | case TIOCMGET: |
2901 | return tty_tiocmget(tty, p); | 2901 | return tty_tiocmget(tty, p); |
2902 | case TIOCMSET: | 2902 | case TIOCMSET: |
2903 | case TIOCMBIC: | 2903 | case TIOCMBIC: |
2904 | case TIOCMBIS: | 2904 | case TIOCMBIS: |
2905 | return tty_tiocmset(tty, cmd, p); | 2905 | return tty_tiocmset(tty, cmd, p); |
2906 | case TIOCGICOUNT: | 2906 | case TIOCGICOUNT: |
2907 | retval = tty_tiocgicount(tty, p); | 2907 | retval = tty_tiocgicount(tty, p); |
2908 | /* For the moment allow fall through to the old method */ | 2908 | /* For the moment allow fall through to the old method */ |
2909 | if (retval != -EINVAL) | 2909 | if (retval != -EINVAL) |
2910 | return retval; | 2910 | return retval; |
2911 | break; | 2911 | break; |
2912 | case TCFLSH: | 2912 | case TCFLSH: |
2913 | switch (arg) { | 2913 | switch (arg) { |
2914 | case TCIFLUSH: | 2914 | case TCIFLUSH: |
2915 | case TCIOFLUSH: | 2915 | case TCIOFLUSH: |
2916 | /* flush tty buffer and allow ldisc to process ioctl */ | 2916 | /* flush tty buffer and allow ldisc to process ioctl */ |
2917 | tty_buffer_flush(tty, NULL); | 2917 | tty_buffer_flush(tty, NULL); |
2918 | break; | 2918 | break; |
2919 | } | 2919 | } |
2920 | break; | 2920 | break; |
2921 | case TIOCSSERIAL: | 2921 | case TIOCSSERIAL: |
2922 | tty_warn_deprecated_flags(p); | 2922 | tty_warn_deprecated_flags(p); |
2923 | break; | 2923 | break; |
2924 | } | 2924 | } |
2925 | if (tty->ops->ioctl) { | 2925 | if (tty->ops->ioctl) { |
2926 | retval = tty->ops->ioctl(tty, cmd, arg); | 2926 | retval = tty->ops->ioctl(tty, cmd, arg); |
2927 | if (retval != -ENOIOCTLCMD) | 2927 | if (retval != -ENOIOCTLCMD) |
2928 | return retval; | 2928 | return retval; |
2929 | } | 2929 | } |
2930 | ld = tty_ldisc_ref_wait(tty); | 2930 | ld = tty_ldisc_ref_wait(tty); |
2931 | retval = -EINVAL; | 2931 | retval = -EINVAL; |
2932 | if (ld->ops->ioctl) { | 2932 | if (ld->ops->ioctl) { |
2933 | retval = ld->ops->ioctl(tty, file, cmd, arg); | 2933 | retval = ld->ops->ioctl(tty, file, cmd, arg); |
2934 | if (retval == -ENOIOCTLCMD) | 2934 | if (retval == -ENOIOCTLCMD) |
2935 | retval = -ENOTTY; | 2935 | retval = -ENOTTY; |
2936 | } | 2936 | } |
2937 | tty_ldisc_deref(ld); | 2937 | tty_ldisc_deref(ld); |
2938 | return retval; | 2938 | return retval; |
2939 | } | 2939 | } |
2940 | 2940 | ||
2941 | #ifdef CONFIG_COMPAT | 2941 | #ifdef CONFIG_COMPAT |
2942 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, | 2942 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, |
2943 | unsigned long arg) | 2943 | unsigned long arg) |
2944 | { | 2944 | { |
2945 | struct tty_struct *tty = file_tty(file); | 2945 | struct tty_struct *tty = file_tty(file); |
2946 | struct tty_ldisc *ld; | 2946 | struct tty_ldisc *ld; |
2947 | int retval = -ENOIOCTLCMD; | 2947 | int retval = -ENOIOCTLCMD; |
2948 | 2948 | ||
2949 | if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl")) | 2949 | if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl")) |
2950 | return -EINVAL; | 2950 | return -EINVAL; |
2951 | 2951 | ||
2952 | if (tty->ops->compat_ioctl) { | 2952 | if (tty->ops->compat_ioctl) { |
2953 | retval = tty->ops->compat_ioctl(tty, cmd, arg); | 2953 | retval = tty->ops->compat_ioctl(tty, cmd, arg); |
2954 | if (retval != -ENOIOCTLCMD) | 2954 | if (retval != -ENOIOCTLCMD) |
2955 | return retval; | 2955 | return retval; |
2956 | } | 2956 | } |
2957 | 2957 | ||
2958 | ld = tty_ldisc_ref_wait(tty); | 2958 | ld = tty_ldisc_ref_wait(tty); |
2959 | if (ld->ops->compat_ioctl) | 2959 | if (ld->ops->compat_ioctl) |
2960 | retval = ld->ops->compat_ioctl(tty, file, cmd, arg); | 2960 | retval = ld->ops->compat_ioctl(tty, file, cmd, arg); |
2961 | else | 2961 | else |
2962 | retval = n_tty_compat_ioctl_helper(tty, file, cmd, arg); | 2962 | retval = n_tty_compat_ioctl_helper(tty, file, cmd, arg); |
2963 | tty_ldisc_deref(ld); | 2963 | tty_ldisc_deref(ld); |
2964 | 2964 | ||
2965 | return retval; | 2965 | return retval; |
2966 | } | 2966 | } |
2967 | #endif | 2967 | #endif |
2968 | 2968 | ||
2969 | static int this_tty(const void *t, struct file *file, unsigned fd) | 2969 | static int this_tty(const void *t, struct file *file, unsigned fd) |
2970 | { | 2970 | { |
2971 | if (likely(file->f_op->read != tty_read)) | 2971 | if (likely(file->f_op->read != tty_read)) |
2972 | return 0; | 2972 | return 0; |
2973 | return file_tty(file) != t ? 0 : fd + 1; | 2973 | return file_tty(file) != t ? 0 : fd + 1; |
2974 | } | 2974 | } |
2975 | 2975 | ||
2976 | /* | 2976 | /* |
2977 | * This implements the "Secure Attention Key" --- the idea is to | 2977 | * This implements the "Secure Attention Key" --- the idea is to |
2978 | * prevent trojan horses by killing all processes associated with this | 2978 | * prevent trojan horses by killing all processes associated with this |
2979 | * tty when the user hits the "Secure Attention Key". Required for | 2979 | * tty when the user hits the "Secure Attention Key". Required for |
2980 | * super-paranoid applications --- see the Orange Book for more details. | 2980 | * super-paranoid applications --- see the Orange Book for more details. |
2981 | * | 2981 | * |
2982 | * This code could be nicer; ideally it should send a HUP, wait a few | 2982 | * This code could be nicer; ideally it should send a HUP, wait a few |
2983 | * seconds, then send a INT, and then a KILL signal. But you then | 2983 | * seconds, then send a INT, and then a KILL signal. But you then |
2984 | * have to coordinate with the init process, since all processes associated | 2984 | * have to coordinate with the init process, since all processes associated |
2985 | * with the current tty must be dead before the new getty is allowed | 2985 | * with the current tty must be dead before the new getty is allowed |
2986 | * to spawn. | 2986 | * to spawn. |
2987 | * | 2987 | * |
2988 | * Now, if it would be correct ;-/ The current code has a nasty hole - | 2988 | * Now, if it would be correct ;-/ The current code has a nasty hole - |
2989 | * it doesn't catch files in flight. We may send the descriptor to ourselves | 2989 | * it doesn't catch files in flight. We may send the descriptor to ourselves |
2990 | * via AF_UNIX socket, close it and later fetch from socket. FIXME. | 2990 | * via AF_UNIX socket, close it and later fetch from socket. FIXME. |
2991 | * | 2991 | * |
2992 | * Nasty bug: do_SAK is being called in interrupt context. This can | 2992 | * Nasty bug: do_SAK is being called in interrupt context. This can |
2993 | * deadlock. We punt it up to process context. AKPM - 16Mar2001 | 2993 | * deadlock. We punt it up to process context. AKPM - 16Mar2001 |
2994 | */ | 2994 | */ |
2995 | void __do_SAK(struct tty_struct *tty) | 2995 | void __do_SAK(struct tty_struct *tty) |
2996 | { | 2996 | { |
2997 | #ifdef TTY_SOFT_SAK | 2997 | #ifdef TTY_SOFT_SAK |
2998 | tty_hangup(tty); | 2998 | tty_hangup(tty); |
2999 | #else | 2999 | #else |
3000 | struct task_struct *g, *p; | 3000 | struct task_struct *g, *p; |
3001 | struct pid *session; | 3001 | struct pid *session; |
3002 | int i; | 3002 | int i; |
3003 | 3003 | ||
3004 | if (!tty) | 3004 | if (!tty) |
3005 | return; | 3005 | return; |
3006 | session = tty->session; | 3006 | session = tty->session; |
3007 | 3007 | ||
3008 | tty_ldisc_flush(tty); | 3008 | tty_ldisc_flush(tty); |
3009 | 3009 | ||
3010 | tty_driver_flush_buffer(tty); | 3010 | tty_driver_flush_buffer(tty); |
3011 | 3011 | ||
3012 | read_lock(&tasklist_lock); | 3012 | read_lock(&tasklist_lock); |
3013 | /* Kill the entire session */ | 3013 | /* Kill the entire session */ |
3014 | do_each_pid_task(session, PIDTYPE_SID, p) { | 3014 | do_each_pid_task(session, PIDTYPE_SID, p) { |
3015 | printk(KERN_NOTICE "SAK: killed process %d" | 3015 | printk(KERN_NOTICE "SAK: killed process %d" |
3016 | " (%s): task_session(p)==tty->session\n", | 3016 | " (%s): task_session(p)==tty->session\n", |
3017 | task_pid_nr(p), p->comm); | 3017 | task_pid_nr(p), p->comm); |
3018 | send_sig(SIGKILL, p, 1); | 3018 | send_sig(SIGKILL, p, 1); |
3019 | } while_each_pid_task(session, PIDTYPE_SID, p); | 3019 | } while_each_pid_task(session, PIDTYPE_SID, p); |
3020 | /* Now kill any processes that happen to have the | 3020 | /* Now kill any processes that happen to have the |
3021 | * tty open. | 3021 | * tty open. |
3022 | */ | 3022 | */ |
3023 | do_each_thread(g, p) { | 3023 | do_each_thread(g, p) { |
3024 | if (p->signal->tty == tty) { | 3024 | if (p->signal->tty == tty) { |
3025 | printk(KERN_NOTICE "SAK: killed process %d" | 3025 | printk(KERN_NOTICE "SAK: killed process %d" |
3026 | " (%s): task_session(p)==tty->session\n", | 3026 | " (%s): task_session(p)==tty->session\n", |
3027 | task_pid_nr(p), p->comm); | 3027 | task_pid_nr(p), p->comm); |
3028 | send_sig(SIGKILL, p, 1); | 3028 | send_sig(SIGKILL, p, 1); |
3029 | continue; | 3029 | continue; |
3030 | } | 3030 | } |
3031 | task_lock(p); | 3031 | task_lock(p); |
3032 | i = iterate_fd(p->files, 0, this_tty, tty); | 3032 | i = iterate_fd(p->files, 0, this_tty, tty); |
3033 | if (i != 0) { | 3033 | if (i != 0) { |
3034 | printk(KERN_NOTICE "SAK: killed process %d" | 3034 | printk(KERN_NOTICE "SAK: killed process %d" |
3035 | " (%s): fd#%d opened to the tty\n", | 3035 | " (%s): fd#%d opened to the tty\n", |
3036 | task_pid_nr(p), p->comm, i - 1); | 3036 | task_pid_nr(p), p->comm, i - 1); |
3037 | force_sig(SIGKILL, p); | 3037 | force_sig(SIGKILL, p); |
3038 | } | 3038 | } |
3039 | task_unlock(p); | 3039 | task_unlock(p); |
3040 | } while_each_thread(g, p); | 3040 | } while_each_thread(g, p); |
3041 | read_unlock(&tasklist_lock); | 3041 | read_unlock(&tasklist_lock); |
3042 | #endif | 3042 | #endif |
3043 | } | 3043 | } |
3044 | 3044 | ||
3045 | static void do_SAK_work(struct work_struct *work) | 3045 | static void do_SAK_work(struct work_struct *work) |
3046 | { | 3046 | { |
3047 | struct tty_struct *tty = | 3047 | struct tty_struct *tty = |
3048 | container_of(work, struct tty_struct, SAK_work); | 3048 | container_of(work, struct tty_struct, SAK_work); |
3049 | __do_SAK(tty); | 3049 | __do_SAK(tty); |
3050 | } | 3050 | } |
3051 | 3051 | ||
3052 | /* | 3052 | /* |
3053 | * The tq handling here is a little racy - tty->SAK_work may already be queued. | 3053 | * The tq handling here is a little racy - tty->SAK_work may already be queued. |
3054 | * Fortunately we don't need to worry, because if ->SAK_work is already queued, | 3054 | * Fortunately we don't need to worry, because if ->SAK_work is already queued, |
3055 | * the values which we write to it will be identical to the values which it | 3055 | * the values which we write to it will be identical to the values which it |
3056 | * already has. --akpm | 3056 | * already has. --akpm |
3057 | */ | 3057 | */ |
3058 | void do_SAK(struct tty_struct *tty) | 3058 | void do_SAK(struct tty_struct *tty) |
3059 | { | 3059 | { |
3060 | if (!tty) | 3060 | if (!tty) |
3061 | return; | 3061 | return; |
3062 | schedule_work(&tty->SAK_work); | 3062 | schedule_work(&tty->SAK_work); |
3063 | } | 3063 | } |
3064 | 3064 | ||
3065 | EXPORT_SYMBOL(do_SAK); | 3065 | EXPORT_SYMBOL(do_SAK); |
3066 | 3066 | ||
3067 | static int dev_match_devt(struct device *dev, const void *data) | 3067 | static int dev_match_devt(struct device *dev, const void *data) |
3068 | { | 3068 | { |
3069 | const dev_t *devt = data; | 3069 | const dev_t *devt = data; |
3070 | return dev->devt == *devt; | 3070 | return dev->devt == *devt; |
3071 | } | 3071 | } |
3072 | 3072 | ||
3073 | /* Must put_device() after it's unused! */ | 3073 | /* Must put_device() after it's unused! */ |
3074 | static struct device *tty_get_device(struct tty_struct *tty) | 3074 | static struct device *tty_get_device(struct tty_struct *tty) |
3075 | { | 3075 | { |
3076 | dev_t devt = tty_devnum(tty); | 3076 | dev_t devt = tty_devnum(tty); |
3077 | return class_find_device(tty_class, NULL, &devt, dev_match_devt); | 3077 | return class_find_device(tty_class, NULL, &devt, dev_match_devt); |
3078 | } | 3078 | } |
3079 | 3079 | ||
3080 | 3080 | ||
3081 | /** | 3081 | /** |
3082 | * alloc_tty_struct | 3082 | * alloc_tty_struct |
3083 | * | 3083 | * |
3084 | * This subroutine allocates and initializes a tty structure. | 3084 | * This subroutine allocates and initializes a tty structure. |
3085 | * | 3085 | * |
3086 | * Locking: none - tty in question is not exposed at this point | 3086 | * Locking: none - tty in question is not exposed at this point |
3087 | */ | 3087 | */ |
3088 | 3088 | ||
3089 | struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) | 3089 | struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) |
3090 | { | 3090 | { |
3091 | struct tty_struct *tty; | 3091 | struct tty_struct *tty; |
3092 | 3092 | ||
3093 | tty = kzalloc(sizeof(*tty), GFP_KERNEL); | 3093 | tty = kzalloc(sizeof(*tty), GFP_KERNEL); |
3094 | if (!tty) | 3094 | if (!tty) |
3095 | return NULL; | 3095 | return NULL; |
3096 | 3096 | ||
3097 | kref_init(&tty->kref); | 3097 | kref_init(&tty->kref); |
3098 | tty->magic = TTY_MAGIC; | 3098 | tty->magic = TTY_MAGIC; |
3099 | tty_ldisc_init(tty); | 3099 | tty_ldisc_init(tty); |
3100 | tty->session = NULL; | 3100 | tty->session = NULL; |
3101 | tty->pgrp = NULL; | 3101 | tty->pgrp = NULL; |
3102 | mutex_init(&tty->legacy_mutex); | 3102 | mutex_init(&tty->legacy_mutex); |
3103 | mutex_init(&tty->throttle_mutex); | 3103 | mutex_init(&tty->throttle_mutex); |
3104 | init_rwsem(&tty->termios_rwsem); | 3104 | init_rwsem(&tty->termios_rwsem); |
3105 | mutex_init(&tty->winsize_mutex); | 3105 | mutex_init(&tty->winsize_mutex); |
3106 | init_ldsem(&tty->ldisc_sem); | 3106 | init_ldsem(&tty->ldisc_sem); |
3107 | init_waitqueue_head(&tty->write_wait); | 3107 | init_waitqueue_head(&tty->write_wait); |
3108 | init_waitqueue_head(&tty->read_wait); | 3108 | init_waitqueue_head(&tty->read_wait); |
3109 | INIT_WORK(&tty->hangup_work, do_tty_hangup); | 3109 | INIT_WORK(&tty->hangup_work, do_tty_hangup); |
3110 | mutex_init(&tty->atomic_write_lock); | 3110 | mutex_init(&tty->atomic_write_lock); |
3111 | spin_lock_init(&tty->ctrl_lock); | 3111 | spin_lock_init(&tty->ctrl_lock); |
3112 | spin_lock_init(&tty->flow_lock); | 3112 | spin_lock_init(&tty->flow_lock); |
3113 | INIT_LIST_HEAD(&tty->tty_files); | 3113 | INIT_LIST_HEAD(&tty->tty_files); |
3114 | INIT_WORK(&tty->SAK_work, do_SAK_work); | 3114 | INIT_WORK(&tty->SAK_work, do_SAK_work); |
3115 | 3115 | ||
3116 | tty->driver = driver; | 3116 | tty->driver = driver; |
3117 | tty->ops = driver->ops; | 3117 | tty->ops = driver->ops; |
3118 | tty->index = idx; | 3118 | tty->index = idx; |
3119 | tty_line_name(driver, idx, tty->name); | 3119 | tty_line_name(driver, idx, tty->name); |
3120 | tty->dev = tty_get_device(tty); | 3120 | tty->dev = tty_get_device(tty); |
3121 | 3121 | ||
3122 | return tty; | 3122 | return tty; |
3123 | } | 3123 | } |
3124 | 3124 | ||
3125 | /** | 3125 | /** |
3126 | * deinitialize_tty_struct | 3126 | * deinitialize_tty_struct |
3127 | * @tty: tty to deinitialize | 3127 | * @tty: tty to deinitialize |
3128 | * | 3128 | * |
3129 | * This subroutine deinitializes a tty structure that has been newly | 3129 | * This subroutine deinitializes a tty structure that has been newly |
3130 | * allocated but tty_release cannot be called on that yet. | 3130 | * allocated but tty_release cannot be called on that yet. |
3131 | * | 3131 | * |
3132 | * Locking: none - tty in question must not be exposed at this point | 3132 | * Locking: none - tty in question must not be exposed at this point |
3133 | */ | 3133 | */ |
3134 | void deinitialize_tty_struct(struct tty_struct *tty) | 3134 | void deinitialize_tty_struct(struct tty_struct *tty) |
3135 | { | 3135 | { |
3136 | tty_ldisc_deinit(tty); | 3136 | tty_ldisc_deinit(tty); |
3137 | } | 3137 | } |
3138 | 3138 | ||
3139 | /** | 3139 | /** |
3140 | * tty_put_char - write one character to a tty | 3140 | * tty_put_char - write one character to a tty |
3141 | * @tty: tty | 3141 | * @tty: tty |
3142 | * @ch: character | 3142 | * @ch: character |
3143 | * | 3143 | * |
3144 | * Write one byte to the tty using the provided put_char method | 3144 | * Write one byte to the tty using the provided put_char method |
3145 | * if present. Returns the number of characters successfully output. | 3145 | * if present. Returns the number of characters successfully output. |
3146 | * | 3146 | * |
3147 | * Note: the specific put_char operation in the driver layer may go | 3147 | * Note: the specific put_char operation in the driver layer may go |
3148 | * away soon. Don't call it directly, use this method | 3148 | * away soon. Don't call it directly, use this method |
3149 | */ | 3149 | */ |
3150 | 3150 | ||
3151 | int tty_put_char(struct tty_struct *tty, unsigned char ch) | 3151 | int tty_put_char(struct tty_struct *tty, unsigned char ch) |
3152 | { | 3152 | { |
3153 | if (tty->ops->put_char) | 3153 | if (tty->ops->put_char) |
3154 | return tty->ops->put_char(tty, ch); | 3154 | return tty->ops->put_char(tty, ch); |
3155 | return tty->ops->write(tty, &ch, 1); | 3155 | return tty->ops->write(tty, &ch, 1); |
3156 | } | 3156 | } |
3157 | EXPORT_SYMBOL_GPL(tty_put_char); | 3157 | EXPORT_SYMBOL_GPL(tty_put_char); |
3158 | 3158 | ||
3159 | struct class *tty_class; | 3159 | struct class *tty_class; |
3160 | 3160 | ||
3161 | static int tty_cdev_add(struct tty_driver *driver, dev_t dev, | 3161 | static int tty_cdev_add(struct tty_driver *driver, dev_t dev, |
3162 | unsigned int index, unsigned int count) | 3162 | unsigned int index, unsigned int count) |
3163 | { | 3163 | { |
3164 | /* init here, since reused cdevs cause crashes */ | 3164 | /* init here, since reused cdevs cause crashes */ |
3165 | cdev_init(&driver->cdevs[index], &tty_fops); | 3165 | cdev_init(&driver->cdevs[index], &tty_fops); |
3166 | driver->cdevs[index].owner = driver->owner; | 3166 | driver->cdevs[index].owner = driver->owner; |
3167 | return cdev_add(&driver->cdevs[index], dev, count); | 3167 | return cdev_add(&driver->cdevs[index], dev, count); |
3168 | } | 3168 | } |
3169 | 3169 | ||
3170 | /** | 3170 | /** |
3171 | * tty_register_device - register a tty device | 3171 | * tty_register_device - register a tty device |
3172 | * @driver: the tty driver that describes the tty device | 3172 | * @driver: the tty driver that describes the tty device |
3173 | * @index: the index in the tty driver for this tty device | 3173 | * @index: the index in the tty driver for this tty device |
3174 | * @device: a struct device that is associated with this tty device. | 3174 | * @device: a struct device that is associated with this tty device. |
3175 | * This field is optional, if there is no known struct device | 3175 | * This field is optional, if there is no known struct device |
3176 | * for this tty device it can be set to NULL safely. | 3176 | * for this tty device it can be set to NULL safely. |
3177 | * | 3177 | * |
3178 | * Returns a pointer to the struct device for this tty device | 3178 | * Returns a pointer to the struct device for this tty device |
3179 | * (or ERR_PTR(-EFOO) on error). | 3179 | * (or ERR_PTR(-EFOO) on error). |
3180 | * | 3180 | * |
3181 | * This call is required to be made to register an individual tty device | 3181 | * This call is required to be made to register an individual tty device |
3182 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If | 3182 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If |
3183 | * that bit is not set, this function should not be called by a tty | 3183 | * that bit is not set, this function should not be called by a tty |
3184 | * driver. | 3184 | * driver. |
3185 | * | 3185 | * |
3186 | * Locking: ?? | 3186 | * Locking: ?? |
3187 | */ | 3187 | */ |
3188 | 3188 | ||
3189 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, | 3189 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, |
3190 | struct device *device) | 3190 | struct device *device) |
3191 | { | 3191 | { |
3192 | return tty_register_device_attr(driver, index, device, NULL, NULL); | 3192 | return tty_register_device_attr(driver, index, device, NULL, NULL); |
3193 | } | 3193 | } |
3194 | EXPORT_SYMBOL(tty_register_device); | 3194 | EXPORT_SYMBOL(tty_register_device); |
3195 | 3195 | ||
3196 | static void tty_device_create_release(struct device *dev) | 3196 | static void tty_device_create_release(struct device *dev) |
3197 | { | 3197 | { |
3198 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | 3198 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); |
3199 | kfree(dev); | 3199 | kfree(dev); |
3200 | } | 3200 | } |
3201 | 3201 | ||
3202 | /** | 3202 | /** |
3203 | * tty_register_device_attr - register a tty device | 3203 | * tty_register_device_attr - register a tty device |
3204 | * @driver: the tty driver that describes the tty device | 3204 | * @driver: the tty driver that describes the tty device |
3205 | * @index: the index in the tty driver for this tty device | 3205 | * @index: the index in the tty driver for this tty device |
3206 | * @device: a struct device that is associated with this tty device. | 3206 | * @device: a struct device that is associated with this tty device. |
3207 | * This field is optional, if there is no known struct device | 3207 | * This field is optional, if there is no known struct device |
3208 | * for this tty device it can be set to NULL safely. | 3208 | * for this tty device it can be set to NULL safely. |
3209 | * @drvdata: Driver data to be set to device. | 3209 | * @drvdata: Driver data to be set to device. |
3210 | * @attr_grp: Attribute group to be set on device. | 3210 | * @attr_grp: Attribute group to be set on device. |
3211 | * | 3211 | * |
3212 | * Returns a pointer to the struct device for this tty device | 3212 | * Returns a pointer to the struct device for this tty device |
3213 | * (or ERR_PTR(-EFOO) on error). | 3213 | * (or ERR_PTR(-EFOO) on error). |
3214 | * | 3214 | * |
3215 | * This call is required to be made to register an individual tty device | 3215 | * This call is required to be made to register an individual tty device |
3216 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If | 3216 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If |
3217 | * that bit is not set, this function should not be called by a tty | 3217 | * that bit is not set, this function should not be called by a tty |
3218 | * driver. | 3218 | * driver. |
3219 | * | 3219 | * |
3220 | * Locking: ?? | 3220 | * Locking: ?? |
3221 | */ | 3221 | */ |
3222 | struct device *tty_register_device_attr(struct tty_driver *driver, | 3222 | struct device *tty_register_device_attr(struct tty_driver *driver, |
3223 | unsigned index, struct device *device, | 3223 | unsigned index, struct device *device, |
3224 | void *drvdata, | 3224 | void *drvdata, |
3225 | const struct attribute_group **attr_grp) | 3225 | const struct attribute_group **attr_grp) |
3226 | { | 3226 | { |
3227 | char name[64]; | 3227 | char name[64]; |
3228 | dev_t devt = MKDEV(driver->major, driver->minor_start) + index; | 3228 | dev_t devt = MKDEV(driver->major, driver->minor_start) + index; |
3229 | struct device *dev = NULL; | 3229 | struct device *dev = NULL; |
3230 | int retval = -ENODEV; | 3230 | int retval = -ENODEV; |
3231 | bool cdev = false; | 3231 | bool cdev = false; |
3232 | 3232 | ||
3233 | if (index >= driver->num) { | 3233 | if (index >= driver->num) { |
3234 | printk(KERN_ERR "Attempt to register invalid tty line number " | 3234 | printk(KERN_ERR "Attempt to register invalid tty line number " |
3235 | " (%d).\n", index); | 3235 | " (%d).\n", index); |
3236 | return ERR_PTR(-EINVAL); | 3236 | return ERR_PTR(-EINVAL); |
3237 | } | 3237 | } |
3238 | 3238 | ||
3239 | if (driver->type == TTY_DRIVER_TYPE_PTY) | 3239 | if (driver->type == TTY_DRIVER_TYPE_PTY) |
3240 | pty_line_name(driver, index, name); | 3240 | pty_line_name(driver, index, name); |
3241 | else | 3241 | else |
3242 | tty_line_name(driver, index, name); | 3242 | tty_line_name(driver, index, name); |
3243 | 3243 | ||
3244 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { | 3244 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { |
3245 | retval = tty_cdev_add(driver, devt, index, 1); | 3245 | retval = tty_cdev_add(driver, devt, index, 1); |
3246 | if (retval) | 3246 | if (retval) |
3247 | goto error; | 3247 | goto error; |
3248 | cdev = true; | 3248 | cdev = true; |
3249 | } | 3249 | } |
3250 | 3250 | ||
3251 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 3251 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
3252 | if (!dev) { | 3252 | if (!dev) { |
3253 | retval = -ENOMEM; | 3253 | retval = -ENOMEM; |
3254 | goto error; | 3254 | goto error; |
3255 | } | 3255 | } |
3256 | 3256 | ||
3257 | dev->devt = devt; | 3257 | dev->devt = devt; |
3258 | dev->class = tty_class; | 3258 | dev->class = tty_class; |
3259 | dev->parent = device; | 3259 | dev->parent = device; |
3260 | dev->release = tty_device_create_release; | 3260 | dev->release = tty_device_create_release; |
3261 | dev_set_name(dev, "%s", name); | 3261 | dev_set_name(dev, "%s", name); |
3262 | dev->groups = attr_grp; | 3262 | dev->groups = attr_grp; |
3263 | dev_set_drvdata(dev, drvdata); | 3263 | dev_set_drvdata(dev, drvdata); |
3264 | 3264 | ||
3265 | retval = device_register(dev); | 3265 | retval = device_register(dev); |
3266 | if (retval) | 3266 | if (retval) |
3267 | goto error; | 3267 | goto error; |
3268 | 3268 | ||
3269 | return dev; | 3269 | return dev; |
3270 | 3270 | ||
3271 | error: | 3271 | error: |
3272 | put_device(dev); | 3272 | put_device(dev); |
3273 | if (cdev) | 3273 | if (cdev) |
3274 | cdev_del(&driver->cdevs[index]); | 3274 | cdev_del(&driver->cdevs[index]); |
3275 | return ERR_PTR(retval); | 3275 | return ERR_PTR(retval); |
3276 | } | 3276 | } |
3277 | EXPORT_SYMBOL_GPL(tty_register_device_attr); | 3277 | EXPORT_SYMBOL_GPL(tty_register_device_attr); |
3278 | 3278 | ||
3279 | /** | 3279 | /** |
3280 | * tty_unregister_device - unregister a tty device | 3280 | * tty_unregister_device - unregister a tty device |
3281 | * @driver: the tty driver that describes the tty device | 3281 | * @driver: the tty driver that describes the tty device |
3282 | * @index: the index in the tty driver for this tty device | 3282 | * @index: the index in the tty driver for this tty device |
3283 | * | 3283 | * |
3284 | * If a tty device is registered with a call to tty_register_device() then | 3284 | * If a tty device is registered with a call to tty_register_device() then |
3285 | * this function must be called when the tty device is gone. | 3285 | * this function must be called when the tty device is gone. |
3286 | * | 3286 | * |
3287 | * Locking: ?? | 3287 | * Locking: ?? |
3288 | */ | 3288 | */ |
3289 | 3289 | ||
3290 | void tty_unregister_device(struct tty_driver *driver, unsigned index) | 3290 | void tty_unregister_device(struct tty_driver *driver, unsigned index) |
3291 | { | 3291 | { |
3292 | device_destroy(tty_class, | 3292 | device_destroy(tty_class, |
3293 | MKDEV(driver->major, driver->minor_start) + index); | 3293 | MKDEV(driver->major, driver->minor_start) + index); |
3294 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) | 3294 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) |
3295 | cdev_del(&driver->cdevs[index]); | 3295 | cdev_del(&driver->cdevs[index]); |
3296 | } | 3296 | } |
3297 | EXPORT_SYMBOL(tty_unregister_device); | 3297 | EXPORT_SYMBOL(tty_unregister_device); |
3298 | 3298 | ||
3299 | /** | 3299 | /** |
3300 | * __tty_alloc_driver -- allocate tty driver | 3300 | * __tty_alloc_driver -- allocate tty driver |
3301 | * @lines: count of lines this driver can handle at most | 3301 | * @lines: count of lines this driver can handle at most |
3302 | * @owner: module which is repsonsible for this driver | 3302 | * @owner: module which is repsonsible for this driver |
3303 | * @flags: some of TTY_DRIVER_* flags, will be set in driver->flags | 3303 | * @flags: some of TTY_DRIVER_* flags, will be set in driver->flags |
3304 | * | 3304 | * |
3305 | * This should not be called directly, some of the provided macros should be | 3305 | * This should not be called directly, some of the provided macros should be |
3306 | * used instead. Use IS_ERR and friends on @retval. | 3306 | * used instead. Use IS_ERR and friends on @retval. |
3307 | */ | 3307 | */ |
3308 | struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, | 3308 | struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, |
3309 | unsigned long flags) | 3309 | unsigned long flags) |
3310 | { | 3310 | { |
3311 | struct tty_driver *driver; | 3311 | struct tty_driver *driver; |
3312 | unsigned int cdevs = 1; | 3312 | unsigned int cdevs = 1; |
3313 | int err; | 3313 | int err; |
3314 | 3314 | ||
3315 | if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1)) | 3315 | if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1)) |
3316 | return ERR_PTR(-EINVAL); | 3316 | return ERR_PTR(-EINVAL); |
3317 | 3317 | ||
3318 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); | 3318 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); |
3319 | if (!driver) | 3319 | if (!driver) |
3320 | return ERR_PTR(-ENOMEM); | 3320 | return ERR_PTR(-ENOMEM); |
3321 | 3321 | ||
3322 | kref_init(&driver->kref); | 3322 | kref_init(&driver->kref); |
3323 | driver->magic = TTY_DRIVER_MAGIC; | 3323 | driver->magic = TTY_DRIVER_MAGIC; |
3324 | driver->num = lines; | 3324 | driver->num = lines; |
3325 | driver->owner = owner; | 3325 | driver->owner = owner; |
3326 | driver->flags = flags; | 3326 | driver->flags = flags; |
3327 | 3327 | ||
3328 | if (!(flags & TTY_DRIVER_DEVPTS_MEM)) { | 3328 | if (!(flags & TTY_DRIVER_DEVPTS_MEM)) { |
3329 | driver->ttys = kcalloc(lines, sizeof(*driver->ttys), | 3329 | driver->ttys = kcalloc(lines, sizeof(*driver->ttys), |
3330 | GFP_KERNEL); | 3330 | GFP_KERNEL); |
3331 | driver->termios = kcalloc(lines, sizeof(*driver->termios), | 3331 | driver->termios = kcalloc(lines, sizeof(*driver->termios), |
3332 | GFP_KERNEL); | 3332 | GFP_KERNEL); |
3333 | if (!driver->ttys || !driver->termios) { | 3333 | if (!driver->ttys || !driver->termios) { |
3334 | err = -ENOMEM; | 3334 | err = -ENOMEM; |
3335 | goto err_free_all; | 3335 | goto err_free_all; |
3336 | } | 3336 | } |
3337 | } | 3337 | } |
3338 | 3338 | ||
3339 | if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) { | 3339 | if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) { |
3340 | driver->ports = kcalloc(lines, sizeof(*driver->ports), | 3340 | driver->ports = kcalloc(lines, sizeof(*driver->ports), |
3341 | GFP_KERNEL); | 3341 | GFP_KERNEL); |
3342 | if (!driver->ports) { | 3342 | if (!driver->ports) { |
3343 | err = -ENOMEM; | 3343 | err = -ENOMEM; |
3344 | goto err_free_all; | 3344 | goto err_free_all; |
3345 | } | 3345 | } |
3346 | cdevs = lines; | 3346 | cdevs = lines; |
3347 | } | 3347 | } |
3348 | 3348 | ||
3349 | driver->cdevs = kcalloc(cdevs, sizeof(*driver->cdevs), GFP_KERNEL); | 3349 | driver->cdevs = kcalloc(cdevs, sizeof(*driver->cdevs), GFP_KERNEL); |
3350 | if (!driver->cdevs) { | 3350 | if (!driver->cdevs) { |
3351 | err = -ENOMEM; | 3351 | err = -ENOMEM; |
3352 | goto err_free_all; | 3352 | goto err_free_all; |
3353 | } | 3353 | } |
3354 | 3354 | ||
3355 | return driver; | 3355 | return driver; |
3356 | err_free_all: | 3356 | err_free_all: |
3357 | kfree(driver->ports); | 3357 | kfree(driver->ports); |
3358 | kfree(driver->ttys); | 3358 | kfree(driver->ttys); |
3359 | kfree(driver->termios); | 3359 | kfree(driver->termios); |
3360 | kfree(driver); | 3360 | kfree(driver); |
3361 | return ERR_PTR(err); | 3361 | return ERR_PTR(err); |
3362 | } | 3362 | } |
3363 | EXPORT_SYMBOL(__tty_alloc_driver); | 3363 | EXPORT_SYMBOL(__tty_alloc_driver); |
3364 | 3364 | ||
3365 | static void destruct_tty_driver(struct kref *kref) | 3365 | static void destruct_tty_driver(struct kref *kref) |
3366 | { | 3366 | { |
3367 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); | 3367 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); |
3368 | int i; | 3368 | int i; |
3369 | struct ktermios *tp; | 3369 | struct ktermios *tp; |
3370 | 3370 | ||
3371 | if (driver->flags & TTY_DRIVER_INSTALLED) { | 3371 | if (driver->flags & TTY_DRIVER_INSTALLED) { |
3372 | /* | 3372 | /* |
3373 | * Free the termios and termios_locked structures because | 3373 | * Free the termios and termios_locked structures because |
3374 | * we don't want to get memory leaks when modular tty | 3374 | * we don't want to get memory leaks when modular tty |
3375 | * drivers are removed from the kernel. | 3375 | * drivers are removed from the kernel. |
3376 | */ | 3376 | */ |
3377 | for (i = 0; i < driver->num; i++) { | 3377 | for (i = 0; i < driver->num; i++) { |
3378 | tp = driver->termios[i]; | 3378 | tp = driver->termios[i]; |
3379 | if (tp) { | 3379 | if (tp) { |
3380 | driver->termios[i] = NULL; | 3380 | driver->termios[i] = NULL; |
3381 | kfree(tp); | 3381 | kfree(tp); |
3382 | } | 3382 | } |
3383 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) | 3383 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) |
3384 | tty_unregister_device(driver, i); | 3384 | tty_unregister_device(driver, i); |
3385 | } | 3385 | } |
3386 | proc_tty_unregister_driver(driver); | 3386 | proc_tty_unregister_driver(driver); |
3387 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) | 3387 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) |
3388 | cdev_del(&driver->cdevs[0]); | 3388 | cdev_del(&driver->cdevs[0]); |
3389 | } | 3389 | } |
3390 | kfree(driver->cdevs); | 3390 | kfree(driver->cdevs); |
3391 | kfree(driver->ports); | 3391 | kfree(driver->ports); |
3392 | kfree(driver->termios); | 3392 | kfree(driver->termios); |
3393 | kfree(driver->ttys); | 3393 | kfree(driver->ttys); |
3394 | kfree(driver); | 3394 | kfree(driver); |
3395 | } | 3395 | } |
3396 | 3396 | ||
3397 | void tty_driver_kref_put(struct tty_driver *driver) | 3397 | void tty_driver_kref_put(struct tty_driver *driver) |
3398 | { | 3398 | { |
3399 | kref_put(&driver->kref, destruct_tty_driver); | 3399 | kref_put(&driver->kref, destruct_tty_driver); |
3400 | } | 3400 | } |
3401 | EXPORT_SYMBOL(tty_driver_kref_put); | 3401 | EXPORT_SYMBOL(tty_driver_kref_put); |
3402 | 3402 | ||
3403 | void tty_set_operations(struct tty_driver *driver, | 3403 | void tty_set_operations(struct tty_driver *driver, |
3404 | const struct tty_operations *op) | 3404 | const struct tty_operations *op) |
3405 | { | 3405 | { |
3406 | driver->ops = op; | 3406 | driver->ops = op; |
3407 | }; | 3407 | }; |
3408 | EXPORT_SYMBOL(tty_set_operations); | 3408 | EXPORT_SYMBOL(tty_set_operations); |
3409 | 3409 | ||
3410 | void put_tty_driver(struct tty_driver *d) | 3410 | void put_tty_driver(struct tty_driver *d) |
3411 | { | 3411 | { |
3412 | tty_driver_kref_put(d); | 3412 | tty_driver_kref_put(d); |
3413 | } | 3413 | } |
3414 | EXPORT_SYMBOL(put_tty_driver); | 3414 | EXPORT_SYMBOL(put_tty_driver); |
3415 | 3415 | ||
3416 | /* | 3416 | /* |
3417 | * Called by a tty driver to register itself. | 3417 | * Called by a tty driver to register itself. |
3418 | */ | 3418 | */ |
3419 | int tty_register_driver(struct tty_driver *driver) | 3419 | int tty_register_driver(struct tty_driver *driver) |
3420 | { | 3420 | { |
3421 | int error; | 3421 | int error; |
3422 | int i; | 3422 | int i; |
3423 | dev_t dev; | 3423 | dev_t dev; |
3424 | struct device *d; | 3424 | struct device *d; |
3425 | 3425 | ||
3426 | if (!driver->major) { | 3426 | if (!driver->major) { |
3427 | error = alloc_chrdev_region(&dev, driver->minor_start, | 3427 | error = alloc_chrdev_region(&dev, driver->minor_start, |
3428 | driver->num, driver->name); | 3428 | driver->num, driver->name); |
3429 | if (!error) { | 3429 | if (!error) { |
3430 | driver->major = MAJOR(dev); | 3430 | driver->major = MAJOR(dev); |
3431 | driver->minor_start = MINOR(dev); | 3431 | driver->minor_start = MINOR(dev); |
3432 | } | 3432 | } |
3433 | } else { | 3433 | } else { |
3434 | dev = MKDEV(driver->major, driver->minor_start); | 3434 | dev = MKDEV(driver->major, driver->minor_start); |
3435 | error = register_chrdev_region(dev, driver->num, driver->name); | 3435 | error = register_chrdev_region(dev, driver->num, driver->name); |
3436 | } | 3436 | } |
3437 | if (error < 0) | 3437 | if (error < 0) |
3438 | goto err; | 3438 | goto err; |
3439 | 3439 | ||
3440 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) { | 3440 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) { |
3441 | error = tty_cdev_add(driver, dev, 0, driver->num); | 3441 | error = tty_cdev_add(driver, dev, 0, driver->num); |
3442 | if (error) | 3442 | if (error) |
3443 | goto err_unreg_char; | 3443 | goto err_unreg_char; |
3444 | } | 3444 | } |
3445 | 3445 | ||
3446 | mutex_lock(&tty_mutex); | 3446 | mutex_lock(&tty_mutex); |
3447 | list_add(&driver->tty_drivers, &tty_drivers); | 3447 | list_add(&driver->tty_drivers, &tty_drivers); |
3448 | mutex_unlock(&tty_mutex); | 3448 | mutex_unlock(&tty_mutex); |
3449 | 3449 | ||
3450 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) { | 3450 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) { |
3451 | for (i = 0; i < driver->num; i++) { | 3451 | for (i = 0; i < driver->num; i++) { |
3452 | d = tty_register_device(driver, i, NULL); | 3452 | d = tty_register_device(driver, i, NULL); |
3453 | if (IS_ERR(d)) { | 3453 | if (IS_ERR(d)) { |
3454 | error = PTR_ERR(d); | 3454 | error = PTR_ERR(d); |
3455 | goto err_unreg_devs; | 3455 | goto err_unreg_devs; |
3456 | } | 3456 | } |
3457 | } | 3457 | } |
3458 | } | 3458 | } |
3459 | proc_tty_register_driver(driver); | 3459 | proc_tty_register_driver(driver); |
3460 | driver->flags |= TTY_DRIVER_INSTALLED; | 3460 | driver->flags |= TTY_DRIVER_INSTALLED; |
3461 | return 0; | 3461 | return 0; |
3462 | 3462 | ||
3463 | err_unreg_devs: | 3463 | err_unreg_devs: |
3464 | for (i--; i >= 0; i--) | 3464 | for (i--; i >= 0; i--) |
3465 | tty_unregister_device(driver, i); | 3465 | tty_unregister_device(driver, i); |
3466 | 3466 | ||
3467 | mutex_lock(&tty_mutex); | 3467 | mutex_lock(&tty_mutex); |
3468 | list_del(&driver->tty_drivers); | 3468 | list_del(&driver->tty_drivers); |
3469 | mutex_unlock(&tty_mutex); | 3469 | mutex_unlock(&tty_mutex); |
3470 | 3470 | ||
3471 | err_unreg_char: | 3471 | err_unreg_char: |
3472 | unregister_chrdev_region(dev, driver->num); | 3472 | unregister_chrdev_region(dev, driver->num); |
3473 | err: | 3473 | err: |
3474 | return error; | 3474 | return error; |
3475 | } | 3475 | } |
3476 | EXPORT_SYMBOL(tty_register_driver); | 3476 | EXPORT_SYMBOL(tty_register_driver); |
3477 | 3477 | ||
3478 | /* | 3478 | /* |
3479 | * Called by a tty driver to unregister itself. | 3479 | * Called by a tty driver to unregister itself. |
3480 | */ | 3480 | */ |
3481 | int tty_unregister_driver(struct tty_driver *driver) | 3481 | int tty_unregister_driver(struct tty_driver *driver) |
3482 | { | 3482 | { |
3483 | #if 0 | 3483 | #if 0 |
3484 | /* FIXME */ | 3484 | /* FIXME */ |
3485 | if (driver->refcount) | 3485 | if (driver->refcount) |
3486 | return -EBUSY; | 3486 | return -EBUSY; |
3487 | #endif | 3487 | #endif |
3488 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), | 3488 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), |
3489 | driver->num); | 3489 | driver->num); |
3490 | mutex_lock(&tty_mutex); | 3490 | mutex_lock(&tty_mutex); |
3491 | list_del(&driver->tty_drivers); | 3491 | list_del(&driver->tty_drivers); |
3492 | mutex_unlock(&tty_mutex); | 3492 | mutex_unlock(&tty_mutex); |
3493 | return 0; | 3493 | return 0; |
3494 | } | 3494 | } |
3495 | 3495 | ||
3496 | EXPORT_SYMBOL(tty_unregister_driver); | 3496 | EXPORT_SYMBOL(tty_unregister_driver); |
3497 | 3497 | ||
3498 | dev_t tty_devnum(struct tty_struct *tty) | 3498 | dev_t tty_devnum(struct tty_struct *tty) |
3499 | { | 3499 | { |
3500 | return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index; | 3500 | return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index; |
3501 | } | 3501 | } |
3502 | EXPORT_SYMBOL(tty_devnum); | 3502 | EXPORT_SYMBOL(tty_devnum); |
3503 | 3503 | ||
3504 | void tty_default_fops(struct file_operations *fops) | 3504 | void tty_default_fops(struct file_operations *fops) |
3505 | { | 3505 | { |
3506 | *fops = tty_fops; | 3506 | *fops = tty_fops; |
3507 | } | 3507 | } |
3508 | 3508 | ||
3509 | /* | 3509 | /* |
3510 | * Initialize the console device. This is called *early*, so | 3510 | * Initialize the console device. This is called *early*, so |
3511 | * we can't necessarily depend on lots of kernel help here. | 3511 | * we can't necessarily depend on lots of kernel help here. |
3512 | * Just do some early initializations, and do the complex setup | 3512 | * Just do some early initializations, and do the complex setup |
3513 | * later. | 3513 | * later. |
3514 | */ | 3514 | */ |
3515 | void __init console_init(void) | 3515 | void __init console_init(void) |
3516 | { | 3516 | { |
3517 | initcall_t *call; | 3517 | initcall_t *call; |
3518 | 3518 | ||
3519 | /* Setup the default TTY line discipline. */ | 3519 | /* Setup the default TTY line discipline. */ |
3520 | tty_ldisc_begin(); | 3520 | tty_ldisc_begin(); |
3521 | 3521 | ||
3522 | /* | 3522 | /* |
3523 | * set up the console device so that later boot sequences can | 3523 | * set up the console device so that later boot sequences can |
3524 | * inform about problems etc.. | 3524 | * inform about problems etc.. |
3525 | */ | 3525 | */ |
3526 | call = __con_initcall_start; | 3526 | call = __con_initcall_start; |
3527 | while (call < __con_initcall_end) { | 3527 | while (call < __con_initcall_end) { |
3528 | (*call)(); | 3528 | (*call)(); |
3529 | call++; | 3529 | call++; |
3530 | } | 3530 | } |
3531 | } | 3531 | } |
3532 | 3532 | ||
3533 | static char *tty_devnode(struct device *dev, umode_t *mode) | 3533 | static char *tty_devnode(struct device *dev, umode_t *mode) |
3534 | { | 3534 | { |
3535 | if (!mode) | 3535 | if (!mode) |
3536 | return NULL; | 3536 | return NULL; |
3537 | if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) || | 3537 | if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) || |
3538 | dev->devt == MKDEV(TTYAUX_MAJOR, 2)) | 3538 | dev->devt == MKDEV(TTYAUX_MAJOR, 2)) |
3539 | *mode = 0666; | 3539 | *mode = 0666; |
3540 | return NULL; | 3540 | return NULL; |
3541 | } | 3541 | } |
3542 | 3542 | ||
3543 | static int __init tty_class_init(void) | 3543 | static int __init tty_class_init(void) |
3544 | { | 3544 | { |
3545 | tty_class = class_create(THIS_MODULE, "tty"); | 3545 | tty_class = class_create(THIS_MODULE, "tty"); |
3546 | if (IS_ERR(tty_class)) | 3546 | if (IS_ERR(tty_class)) |
3547 | return PTR_ERR(tty_class); | 3547 | return PTR_ERR(tty_class); |
3548 | tty_class->devnode = tty_devnode; | 3548 | tty_class->devnode = tty_devnode; |
3549 | return 0; | 3549 | return 0; |
3550 | } | 3550 | } |
3551 | 3551 | ||
3552 | postcore_initcall(tty_class_init); | 3552 | postcore_initcall(tty_class_init); |
3553 | 3553 | ||
3554 | /* 3/2004 jmc: why do these devices exist? */ | 3554 | /* 3/2004 jmc: why do these devices exist? */ |
3555 | static struct cdev tty_cdev, console_cdev; | 3555 | static struct cdev tty_cdev, console_cdev; |
3556 | 3556 | ||
3557 | static ssize_t show_cons_active(struct device *dev, | 3557 | static ssize_t show_cons_active(struct device *dev, |
3558 | struct device_attribute *attr, char *buf) | 3558 | struct device_attribute *attr, char *buf) |
3559 | { | 3559 | { |
3560 | struct console *cs[16]; | 3560 | struct console *cs[16]; |
3561 | int i = 0; | 3561 | int i = 0; |
3562 | struct console *c; | 3562 | struct console *c; |
3563 | ssize_t count = 0; | 3563 | ssize_t count = 0; |
3564 | 3564 | ||
3565 | console_lock(); | 3565 | console_lock(); |
3566 | for_each_console(c) { | 3566 | for_each_console(c) { |
3567 | if (!c->device) | 3567 | if (!c->device) |
3568 | continue; | 3568 | continue; |
3569 | if (!c->write) | 3569 | if (!c->write) |
3570 | continue; | 3570 | continue; |
3571 | if ((c->flags & CON_ENABLED) == 0) | 3571 | if ((c->flags & CON_ENABLED) == 0) |
3572 | continue; | 3572 | continue; |
3573 | cs[i++] = c; | 3573 | cs[i++] = c; |
3574 | if (i >= ARRAY_SIZE(cs)) | 3574 | if (i >= ARRAY_SIZE(cs)) |
3575 | break; | 3575 | break; |
3576 | } | 3576 | } |
3577 | while (i--) { | 3577 | while (i--) { |
3578 | int index = cs[i]->index; | 3578 | int index = cs[i]->index; |
3579 | struct tty_driver *drv = cs[i]->device(cs[i], &index); | 3579 | struct tty_driver *drv = cs[i]->device(cs[i], &index); |
3580 | 3580 | ||
3581 | /* don't resolve tty0 as some programs depend on it */ | 3581 | /* don't resolve tty0 as some programs depend on it */ |
3582 | if (drv && (cs[i]->index > 0 || drv->major != TTY_MAJOR)) | 3582 | if (drv && (cs[i]->index > 0 || drv->major != TTY_MAJOR)) |
3583 | count += tty_line_name(drv, index, buf + count); | 3583 | count += tty_line_name(drv, index, buf + count); |
3584 | else | 3584 | else |
3585 | count += sprintf(buf + count, "%s%d", | 3585 | count += sprintf(buf + count, "%s%d", |
3586 | cs[i]->name, cs[i]->index); | 3586 | cs[i]->name, cs[i]->index); |
3587 | 3587 | ||
3588 | count += sprintf(buf + count, "%c", i ? ' ':'\n'); | 3588 | count += sprintf(buf + count, "%c", i ? ' ':'\n'); |
3589 | } | 3589 | } |
3590 | console_unlock(); | 3590 | console_unlock(); |
3591 | 3591 | ||
3592 | return count; | 3592 | return count; |
3593 | } | 3593 | } |
3594 | static DEVICE_ATTR(active, S_IRUGO, show_cons_active, NULL); | 3594 | static DEVICE_ATTR(active, S_IRUGO, show_cons_active, NULL); |
3595 | 3595 | ||
3596 | static struct device *consdev; | 3596 | static struct device *consdev; |
3597 | 3597 | ||
3598 | void console_sysfs_notify(void) | 3598 | void console_sysfs_notify(void) |
3599 | { | 3599 | { |
3600 | if (consdev) | 3600 | if (consdev) |
3601 | sysfs_notify(&consdev->kobj, NULL, "active"); | 3601 | sysfs_notify(&consdev->kobj, NULL, "active"); |
3602 | } | 3602 | } |
3603 | 3603 | ||
3604 | /* | 3604 | /* |
3605 | * Ok, now we can initialize the rest of the tty devices and can count | 3605 | * Ok, now we can initialize the rest of the tty devices and can count |
3606 | * on memory allocations, interrupts etc.. | 3606 | * on memory allocations, interrupts etc.. |
3607 | */ | 3607 | */ |
3608 | int __init tty_init(void) | 3608 | int __init tty_init(void) |
3609 | { | 3609 | { |
3610 | cdev_init(&tty_cdev, &tty_fops); | 3610 | cdev_init(&tty_cdev, &tty_fops); |
3611 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || | 3611 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || |
3612 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) | 3612 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) |
3613 | panic("Couldn't register /dev/tty driver\n"); | 3613 | panic("Couldn't register /dev/tty driver\n"); |
3614 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); | 3614 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); |
3615 | 3615 | ||
3616 | cdev_init(&console_cdev, &console_fops); | 3616 | cdev_init(&console_cdev, &console_fops); |
3617 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || | 3617 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || |
3618 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) | 3618 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) |
3619 | panic("Couldn't register /dev/console driver\n"); | 3619 | panic("Couldn't register /dev/console driver\n"); |
3620 | consdev = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, | 3620 | consdev = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, |
3621 | "console"); | 3621 | "console"); |
3622 | if (IS_ERR(consdev)) | 3622 | if (IS_ERR(consdev)) |
3623 | consdev = NULL; | 3623 | consdev = NULL; |
3624 | else | 3624 | else |
3625 | WARN_ON(device_create_file(consdev, &dev_attr_active) < 0); | 3625 | WARN_ON(device_create_file(consdev, &dev_attr_active) < 0); |
3626 | 3626 | ||
3627 | #ifdef CONFIG_VT | 3627 | #ifdef CONFIG_VT |
3628 | vty_init(&console_fops); | 3628 | vty_init(&console_fops); |
3629 | #endif | 3629 | #endif |
3630 | return 0; | 3630 | return 0; |
3631 | } | 3631 | } |
3632 | 3632 | ||
3633 | 3633 |
drivers/tty/tty_ioctl.c
1 | /* | 1 | /* |
2 | * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds | 2 | * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds |
3 | * | 3 | * |
4 | * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines | 4 | * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines |
5 | * which can be dynamically activated and de-activated by the line | 5 | * which can be dynamically activated and de-activated by the line |
6 | * discipline handling modules (like SLIP). | 6 | * discipline handling modules (like SLIP). |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/termios.h> | 10 | #include <linux/termios.h> |
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/major.h> | 14 | #include <linux/major.h> |
15 | #include <linux/tty.h> | 15 | #include <linux/tty.h> |
16 | #include <linux/fcntl.h> | 16 | #include <linux/fcntl.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/compat.h> | 22 | #include <linux/compat.h> |
23 | 23 | ||
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | 26 | ||
27 | #undef TTY_DEBUG_WAIT_UNTIL_SENT | 27 | #undef TTY_DEBUG_WAIT_UNTIL_SENT |
28 | 28 | ||
29 | #undef DEBUG | 29 | #undef DEBUG |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * Internal flag options for termios setting behavior | 32 | * Internal flag options for termios setting behavior |
33 | */ | 33 | */ |
34 | #define TERMIOS_FLUSH 1 | 34 | #define TERMIOS_FLUSH 1 |
35 | #define TERMIOS_WAIT 2 | 35 | #define TERMIOS_WAIT 2 |
36 | #define TERMIOS_TERMIO 4 | 36 | #define TERMIOS_TERMIO 4 |
37 | #define TERMIOS_OLD 8 | 37 | #define TERMIOS_OLD 8 |
38 | 38 | ||
39 | 39 | ||
40 | /** | 40 | /** |
41 | * tty_chars_in_buffer - characters pending | 41 | * tty_chars_in_buffer - characters pending |
42 | * @tty: terminal | 42 | * @tty: terminal |
43 | * | 43 | * |
44 | * Return the number of bytes of data in the device private | 44 | * Return the number of bytes of data in the device private |
45 | * output queue. If no private method is supplied there is assumed | 45 | * output queue. If no private method is supplied there is assumed |
46 | * to be no queue on the device. | 46 | * to be no queue on the device. |
47 | */ | 47 | */ |
48 | 48 | ||
49 | int tty_chars_in_buffer(struct tty_struct *tty) | 49 | int tty_chars_in_buffer(struct tty_struct *tty) |
50 | { | 50 | { |
51 | if (tty->ops->chars_in_buffer) | 51 | if (tty->ops->chars_in_buffer) |
52 | return tty->ops->chars_in_buffer(tty); | 52 | return tty->ops->chars_in_buffer(tty); |
53 | else | 53 | else |
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | EXPORT_SYMBOL(tty_chars_in_buffer); | 56 | EXPORT_SYMBOL(tty_chars_in_buffer); |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * tty_write_room - write queue space | 59 | * tty_write_room - write queue space |
60 | * @tty: terminal | 60 | * @tty: terminal |
61 | * | 61 | * |
62 | * Return the number of bytes that can be queued to this device | 62 | * Return the number of bytes that can be queued to this device |
63 | * at the present time. The result should be treated as a guarantee | 63 | * at the present time. The result should be treated as a guarantee |
64 | * and the driver cannot offer a value it later shrinks by more than | 64 | * and the driver cannot offer a value it later shrinks by more than |
65 | * the number of bytes written. If no method is provided 2K is always | 65 | * the number of bytes written. If no method is provided 2K is always |
66 | * returned and data may be lost as there will be no flow control. | 66 | * returned and data may be lost as there will be no flow control. |
67 | */ | 67 | */ |
68 | 68 | ||
69 | int tty_write_room(struct tty_struct *tty) | 69 | int tty_write_room(struct tty_struct *tty) |
70 | { | 70 | { |
71 | if (tty->ops->write_room) | 71 | if (tty->ops->write_room) |
72 | return tty->ops->write_room(tty); | 72 | return tty->ops->write_room(tty); |
73 | return 2048; | 73 | return 2048; |
74 | } | 74 | } |
75 | EXPORT_SYMBOL(tty_write_room); | 75 | EXPORT_SYMBOL(tty_write_room); |
76 | 76 | ||
77 | /** | 77 | /** |
78 | * tty_driver_flush_buffer - discard internal buffer | 78 | * tty_driver_flush_buffer - discard internal buffer |
79 | * @tty: terminal | 79 | * @tty: terminal |
80 | * | 80 | * |
81 | * Discard the internal output buffer for this device. If no method | 81 | * Discard the internal output buffer for this device. If no method |
82 | * is provided then either the buffer cannot be hardware flushed or | 82 | * is provided then either the buffer cannot be hardware flushed or |
83 | * there is no buffer driver side. | 83 | * there is no buffer driver side. |
84 | */ | 84 | */ |
85 | void tty_driver_flush_buffer(struct tty_struct *tty) | 85 | void tty_driver_flush_buffer(struct tty_struct *tty) |
86 | { | 86 | { |
87 | if (tty->ops->flush_buffer) | 87 | if (tty->ops->flush_buffer) |
88 | tty->ops->flush_buffer(tty); | 88 | tty->ops->flush_buffer(tty); |
89 | } | 89 | } |
90 | EXPORT_SYMBOL(tty_driver_flush_buffer); | 90 | EXPORT_SYMBOL(tty_driver_flush_buffer); |
91 | 91 | ||
92 | /** | 92 | /** |
93 | * tty_throttle - flow control | 93 | * tty_throttle - flow control |
94 | * @tty: terminal | 94 | * @tty: terminal |
95 | * | 95 | * |
96 | * Indicate that a tty should stop transmitting data down the stack. | 96 | * Indicate that a tty should stop transmitting data down the stack. |
97 | * Takes the termios rwsem to protect against parallel throttle/unthrottle | 97 | * Takes the termios rwsem to protect against parallel throttle/unthrottle |
98 | * and also to ensure the driver can consistently reference its own | 98 | * and also to ensure the driver can consistently reference its own |
99 | * termios data at this point when implementing software flow control. | 99 | * termios data at this point when implementing software flow control. |
100 | */ | 100 | */ |
101 | 101 | ||
102 | void tty_throttle(struct tty_struct *tty) | 102 | void tty_throttle(struct tty_struct *tty) |
103 | { | 103 | { |
104 | down_write(&tty->termios_rwsem); | 104 | down_write(&tty->termios_rwsem); |
105 | /* check TTY_THROTTLED first so it indicates our state */ | 105 | /* check TTY_THROTTLED first so it indicates our state */ |
106 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && | 106 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && |
107 | tty->ops->throttle) | 107 | tty->ops->throttle) |
108 | tty->ops->throttle(tty); | 108 | tty->ops->throttle(tty); |
109 | tty->flow_change = 0; | 109 | tty->flow_change = 0; |
110 | up_write(&tty->termios_rwsem); | 110 | up_write(&tty->termios_rwsem); |
111 | } | 111 | } |
112 | EXPORT_SYMBOL(tty_throttle); | 112 | EXPORT_SYMBOL(tty_throttle); |
113 | 113 | ||
114 | /** | 114 | /** |
115 | * tty_unthrottle - flow control | 115 | * tty_unthrottle - flow control |
116 | * @tty: terminal | 116 | * @tty: terminal |
117 | * | 117 | * |
118 | * Indicate that a tty may continue transmitting data down the stack. | 118 | * Indicate that a tty may continue transmitting data down the stack. |
119 | * Takes the termios rwsem to protect against parallel throttle/unthrottle | 119 | * Takes the termios rwsem to protect against parallel throttle/unthrottle |
120 | * and also to ensure the driver can consistently reference its own | 120 | * and also to ensure the driver can consistently reference its own |
121 | * termios data at this point when implementing software flow control. | 121 | * termios data at this point when implementing software flow control. |
122 | * | 122 | * |
123 | * Drivers should however remember that the stack can issue a throttle, | 123 | * Drivers should however remember that the stack can issue a throttle, |
124 | * then change flow control method, then unthrottle. | 124 | * then change flow control method, then unthrottle. |
125 | */ | 125 | */ |
126 | 126 | ||
127 | void tty_unthrottle(struct tty_struct *tty) | 127 | void tty_unthrottle(struct tty_struct *tty) |
128 | { | 128 | { |
129 | down_write(&tty->termios_rwsem); | 129 | down_write(&tty->termios_rwsem); |
130 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && | 130 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && |
131 | tty->ops->unthrottle) | 131 | tty->ops->unthrottle) |
132 | tty->ops->unthrottle(tty); | 132 | tty->ops->unthrottle(tty); |
133 | tty->flow_change = 0; | 133 | tty->flow_change = 0; |
134 | up_write(&tty->termios_rwsem); | 134 | up_write(&tty->termios_rwsem); |
135 | } | 135 | } |
136 | EXPORT_SYMBOL(tty_unthrottle); | 136 | EXPORT_SYMBOL(tty_unthrottle); |
137 | 137 | ||
138 | /** | 138 | /** |
139 | * tty_throttle_safe - flow control | 139 | * tty_throttle_safe - flow control |
140 | * @tty: terminal | 140 | * @tty: terminal |
141 | * | 141 | * |
142 | * Similar to tty_throttle() but will only attempt throttle | 142 | * Similar to tty_throttle() but will only attempt throttle |
143 | * if tty->flow_change is TTY_THROTTLE_SAFE. Prevents an accidental | 143 | * if tty->flow_change is TTY_THROTTLE_SAFE. Prevents an accidental |
144 | * throttle due to race conditions when throttling is conditional | 144 | * throttle due to race conditions when throttling is conditional |
145 | * on factors evaluated prior to throttling. | 145 | * on factors evaluated prior to throttling. |
146 | * | 146 | * |
147 | * Returns 0 if tty is throttled (or was already throttled) | 147 | * Returns 0 if tty is throttled (or was already throttled) |
148 | */ | 148 | */ |
149 | 149 | ||
150 | int tty_throttle_safe(struct tty_struct *tty) | 150 | int tty_throttle_safe(struct tty_struct *tty) |
151 | { | 151 | { |
152 | int ret = 0; | 152 | int ret = 0; |
153 | 153 | ||
154 | mutex_lock(&tty->throttle_mutex); | 154 | mutex_lock(&tty->throttle_mutex); |
155 | if (!test_bit(TTY_THROTTLED, &tty->flags)) { | 155 | if (!test_bit(TTY_THROTTLED, &tty->flags)) { |
156 | if (tty->flow_change != TTY_THROTTLE_SAFE) | 156 | if (tty->flow_change != TTY_THROTTLE_SAFE) |
157 | ret = 1; | 157 | ret = 1; |
158 | else { | 158 | else { |
159 | set_bit(TTY_THROTTLED, &tty->flags); | 159 | set_bit(TTY_THROTTLED, &tty->flags); |
160 | if (tty->ops->throttle) | 160 | if (tty->ops->throttle) |
161 | tty->ops->throttle(tty); | 161 | tty->ops->throttle(tty); |
162 | } | 162 | } |
163 | } | 163 | } |
164 | mutex_unlock(&tty->throttle_mutex); | 164 | mutex_unlock(&tty->throttle_mutex); |
165 | 165 | ||
166 | return ret; | 166 | return ret; |
167 | } | 167 | } |
168 | 168 | ||
169 | /** | 169 | /** |
170 | * tty_unthrottle_safe - flow control | 170 | * tty_unthrottle_safe - flow control |
171 | * @tty: terminal | 171 | * @tty: terminal |
172 | * | 172 | * |
173 | * Similar to tty_unthrottle() but will only attempt unthrottle | 173 | * Similar to tty_unthrottle() but will only attempt unthrottle |
174 | * if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental | 174 | * if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental |
175 | * unthrottle due to race conditions when unthrottling is conditional | 175 | * unthrottle due to race conditions when unthrottling is conditional |
176 | * on factors evaluated prior to unthrottling. | 176 | * on factors evaluated prior to unthrottling. |
177 | * | 177 | * |
178 | * Returns 0 if tty is unthrottled (or was already unthrottled) | 178 | * Returns 0 if tty is unthrottled (or was already unthrottled) |
179 | */ | 179 | */ |
180 | 180 | ||
181 | int tty_unthrottle_safe(struct tty_struct *tty) | 181 | int tty_unthrottle_safe(struct tty_struct *tty) |
182 | { | 182 | { |
183 | int ret = 0; | 183 | int ret = 0; |
184 | 184 | ||
185 | mutex_lock(&tty->throttle_mutex); | 185 | mutex_lock(&tty->throttle_mutex); |
186 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | 186 | if (test_bit(TTY_THROTTLED, &tty->flags)) { |
187 | if (tty->flow_change != TTY_UNTHROTTLE_SAFE) | 187 | if (tty->flow_change != TTY_UNTHROTTLE_SAFE) |
188 | ret = 1; | 188 | ret = 1; |
189 | else { | 189 | else { |
190 | clear_bit(TTY_THROTTLED, &tty->flags); | 190 | clear_bit(TTY_THROTTLED, &tty->flags); |
191 | if (tty->ops->unthrottle) | 191 | if (tty->ops->unthrottle) |
192 | tty->ops->unthrottle(tty); | 192 | tty->ops->unthrottle(tty); |
193 | } | 193 | } |
194 | } | 194 | } |
195 | mutex_unlock(&tty->throttle_mutex); | 195 | mutex_unlock(&tty->throttle_mutex); |
196 | 196 | ||
197 | return ret; | 197 | return ret; |
198 | } | 198 | } |
199 | 199 | ||
200 | /** | 200 | /** |
201 | * tty_wait_until_sent - wait for I/O to finish | 201 | * tty_wait_until_sent - wait for I/O to finish |
202 | * @tty: tty we are waiting for | 202 | * @tty: tty we are waiting for |
203 | * @timeout: how long we will wait | 203 | * @timeout: how long we will wait |
204 | * | 204 | * |
205 | * Wait for characters pending in a tty driver to hit the wire, or | 205 | * Wait for characters pending in a tty driver to hit the wire, or |
206 | * for a timeout to occur (eg due to flow control) | 206 | * for a timeout to occur (eg due to flow control) |
207 | * | 207 | * |
208 | * Locking: none | 208 | * Locking: none |
209 | */ | 209 | */ |
210 | 210 | ||
211 | void tty_wait_until_sent(struct tty_struct *tty, long timeout) | 211 | void tty_wait_until_sent(struct tty_struct *tty, long timeout) |
212 | { | 212 | { |
213 | #ifdef TTY_DEBUG_WAIT_UNTIL_SENT | 213 | #ifdef TTY_DEBUG_WAIT_UNTIL_SENT |
214 | char buf[64]; | 214 | char buf[64]; |
215 | 215 | ||
216 | printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf)); | 216 | printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf)); |
217 | #endif | 217 | #endif |
218 | if (!timeout) | 218 | if (!timeout) |
219 | timeout = MAX_SCHEDULE_TIMEOUT; | 219 | timeout = MAX_SCHEDULE_TIMEOUT; |
220 | if (wait_event_interruptible_timeout(tty->write_wait, | 220 | |
221 | !tty_chars_in_buffer(tty), timeout) >= 0) { | 221 | timeout = wait_event_interruptible_timeout(tty->write_wait, |
222 | if (tty->ops->wait_until_sent) | 222 | !tty_chars_in_buffer(tty), timeout); |
223 | tty->ops->wait_until_sent(tty, timeout); | 223 | if (timeout <= 0) |
224 | } | 224 | return; |
225 | |||
226 | if (timeout == MAX_SCHEDULE_TIMEOUT) | ||
227 | timeout = 0; | ||
228 | |||
229 | if (tty->ops->wait_until_sent) | ||
230 | tty->ops->wait_until_sent(tty, timeout); | ||
225 | } | 231 | } |
226 | EXPORT_SYMBOL(tty_wait_until_sent); | 232 | EXPORT_SYMBOL(tty_wait_until_sent); |
227 | 233 | ||
228 | 234 | ||
229 | /* | 235 | /* |
230 | * Termios Helper Methods | 236 | * Termios Helper Methods |
231 | */ | 237 | */ |
232 | 238 | ||
233 | static void unset_locked_termios(struct ktermios *termios, | 239 | static void unset_locked_termios(struct ktermios *termios, |
234 | struct ktermios *old, | 240 | struct ktermios *old, |
235 | struct ktermios *locked) | 241 | struct ktermios *locked) |
236 | { | 242 | { |
237 | int i; | 243 | int i; |
238 | 244 | ||
239 | #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z))) | 245 | #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z))) |
240 | 246 | ||
241 | if (!locked) { | 247 | if (!locked) { |
242 | printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n"); | 248 | printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n"); |
243 | return; | 249 | return; |
244 | } | 250 | } |
245 | 251 | ||
246 | NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag); | 252 | NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag); |
247 | NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag); | 253 | NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag); |
248 | NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag); | 254 | NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag); |
249 | NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag); | 255 | NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag); |
250 | termios->c_line = locked->c_line ? old->c_line : termios->c_line; | 256 | termios->c_line = locked->c_line ? old->c_line : termios->c_line; |
251 | for (i = 0; i < NCCS; i++) | 257 | for (i = 0; i < NCCS; i++) |
252 | termios->c_cc[i] = locked->c_cc[i] ? | 258 | termios->c_cc[i] = locked->c_cc[i] ? |
253 | old->c_cc[i] : termios->c_cc[i]; | 259 | old->c_cc[i] : termios->c_cc[i]; |
254 | /* FIXME: What should we do for i/ospeed */ | 260 | /* FIXME: What should we do for i/ospeed */ |
255 | } | 261 | } |
256 | 262 | ||
257 | /* | 263 | /* |
258 | * Routine which returns the baud rate of the tty | 264 | * Routine which returns the baud rate of the tty |
259 | * | 265 | * |
260 | * Note that the baud_table needs to be kept in sync with the | 266 | * Note that the baud_table needs to be kept in sync with the |
261 | * include/asm/termbits.h file. | 267 | * include/asm/termbits.h file. |
262 | */ | 268 | */ |
263 | static const speed_t baud_table[] = { | 269 | static const speed_t baud_table[] = { |
264 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | 270 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, |
265 | 9600, 19200, 38400, 57600, 115200, 230400, 460800, | 271 | 9600, 19200, 38400, 57600, 115200, 230400, 460800, |
266 | #ifdef __sparc__ | 272 | #ifdef __sparc__ |
267 | 76800, 153600, 307200, 614400, 921600 | 273 | 76800, 153600, 307200, 614400, 921600 |
268 | #else | 274 | #else |
269 | 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, | 275 | 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, |
270 | 2500000, 3000000, 3500000, 4000000 | 276 | 2500000, 3000000, 3500000, 4000000 |
271 | #endif | 277 | #endif |
272 | }; | 278 | }; |
273 | 279 | ||
274 | #ifndef __sparc__ | 280 | #ifndef __sparc__ |
275 | static const tcflag_t baud_bits[] = { | 281 | static const tcflag_t baud_bits[] = { |
276 | B0, B50, B75, B110, B134, B150, B200, B300, B600, | 282 | B0, B50, B75, B110, B134, B150, B200, B300, B600, |
277 | B1200, B1800, B2400, B4800, B9600, B19200, B38400, | 283 | B1200, B1800, B2400, B4800, B9600, B19200, B38400, |
278 | B57600, B115200, B230400, B460800, B500000, B576000, | 284 | B57600, B115200, B230400, B460800, B500000, B576000, |
279 | B921600, B1000000, B1152000, B1500000, B2000000, B2500000, | 285 | B921600, B1000000, B1152000, B1500000, B2000000, B2500000, |
280 | B3000000, B3500000, B4000000 | 286 | B3000000, B3500000, B4000000 |
281 | }; | 287 | }; |
282 | #else | 288 | #else |
283 | static const tcflag_t baud_bits[] = { | 289 | static const tcflag_t baud_bits[] = { |
284 | B0, B50, B75, B110, B134, B150, B200, B300, B600, | 290 | B0, B50, B75, B110, B134, B150, B200, B300, B600, |
285 | B1200, B1800, B2400, B4800, B9600, B19200, B38400, | 291 | B1200, B1800, B2400, B4800, B9600, B19200, B38400, |
286 | B57600, B115200, B230400, B460800, B76800, B153600, | 292 | B57600, B115200, B230400, B460800, B76800, B153600, |
287 | B307200, B614400, B921600 | 293 | B307200, B614400, B921600 |
288 | }; | 294 | }; |
289 | #endif | 295 | #endif |
290 | 296 | ||
291 | static int n_baud_table = ARRAY_SIZE(baud_table); | 297 | static int n_baud_table = ARRAY_SIZE(baud_table); |
292 | 298 | ||
293 | /** | 299 | /** |
294 | * tty_termios_baud_rate | 300 | * tty_termios_baud_rate |
295 | * @termios: termios structure | 301 | * @termios: termios structure |
296 | * | 302 | * |
297 | * Convert termios baud rate data into a speed. This should be called | 303 | * Convert termios baud rate data into a speed. This should be called |
298 | * with the termios lock held if this termios is a terminal termios | 304 | * with the termios lock held if this termios is a terminal termios |
299 | * structure. May change the termios data. Device drivers can call this | 305 | * structure. May change the termios data. Device drivers can call this |
300 | * function but should use ->c_[io]speed directly as they are updated. | 306 | * function but should use ->c_[io]speed directly as they are updated. |
301 | * | 307 | * |
302 | * Locking: none | 308 | * Locking: none |
303 | */ | 309 | */ |
304 | 310 | ||
305 | speed_t tty_termios_baud_rate(struct ktermios *termios) | 311 | speed_t tty_termios_baud_rate(struct ktermios *termios) |
306 | { | 312 | { |
307 | unsigned int cbaud; | 313 | unsigned int cbaud; |
308 | 314 | ||
309 | cbaud = termios->c_cflag & CBAUD; | 315 | cbaud = termios->c_cflag & CBAUD; |
310 | 316 | ||
311 | #ifdef BOTHER | 317 | #ifdef BOTHER |
312 | /* Magic token for arbitrary speed via c_ispeed/c_ospeed */ | 318 | /* Magic token for arbitrary speed via c_ispeed/c_ospeed */ |
313 | if (cbaud == BOTHER) | 319 | if (cbaud == BOTHER) |
314 | return termios->c_ospeed; | 320 | return termios->c_ospeed; |
315 | #endif | 321 | #endif |
316 | if (cbaud & CBAUDEX) { | 322 | if (cbaud & CBAUDEX) { |
317 | cbaud &= ~CBAUDEX; | 323 | cbaud &= ~CBAUDEX; |
318 | 324 | ||
319 | if (cbaud < 1 || cbaud + 15 > n_baud_table) | 325 | if (cbaud < 1 || cbaud + 15 > n_baud_table) |
320 | termios->c_cflag &= ~CBAUDEX; | 326 | termios->c_cflag &= ~CBAUDEX; |
321 | else | 327 | else |
322 | cbaud += 15; | 328 | cbaud += 15; |
323 | } | 329 | } |
324 | return baud_table[cbaud]; | 330 | return baud_table[cbaud]; |
325 | } | 331 | } |
326 | EXPORT_SYMBOL(tty_termios_baud_rate); | 332 | EXPORT_SYMBOL(tty_termios_baud_rate); |
327 | 333 | ||
328 | /** | 334 | /** |
329 | * tty_termios_input_baud_rate | 335 | * tty_termios_input_baud_rate |
330 | * @termios: termios structure | 336 | * @termios: termios structure |
331 | * | 337 | * |
332 | * Convert termios baud rate data into a speed. This should be called | 338 | * Convert termios baud rate data into a speed. This should be called |
333 | * with the termios lock held if this termios is a terminal termios | 339 | * with the termios lock held if this termios is a terminal termios |
334 | * structure. May change the termios data. Device drivers can call this | 340 | * structure. May change the termios data. Device drivers can call this |
335 | * function but should use ->c_[io]speed directly as they are updated. | 341 | * function but should use ->c_[io]speed directly as they are updated. |
336 | * | 342 | * |
337 | * Locking: none | 343 | * Locking: none |
338 | */ | 344 | */ |
339 | 345 | ||
340 | speed_t tty_termios_input_baud_rate(struct ktermios *termios) | 346 | speed_t tty_termios_input_baud_rate(struct ktermios *termios) |
341 | { | 347 | { |
342 | #ifdef IBSHIFT | 348 | #ifdef IBSHIFT |
343 | unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD; | 349 | unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD; |
344 | 350 | ||
345 | if (cbaud == B0) | 351 | if (cbaud == B0) |
346 | return tty_termios_baud_rate(termios); | 352 | return tty_termios_baud_rate(termios); |
347 | 353 | ||
348 | /* Magic token for arbitrary speed via c_ispeed*/ | 354 | /* Magic token for arbitrary speed via c_ispeed*/ |
349 | if (cbaud == BOTHER) | 355 | if (cbaud == BOTHER) |
350 | return termios->c_ispeed; | 356 | return termios->c_ispeed; |
351 | 357 | ||
352 | if (cbaud & CBAUDEX) { | 358 | if (cbaud & CBAUDEX) { |
353 | cbaud &= ~CBAUDEX; | 359 | cbaud &= ~CBAUDEX; |
354 | 360 | ||
355 | if (cbaud < 1 || cbaud + 15 > n_baud_table) | 361 | if (cbaud < 1 || cbaud + 15 > n_baud_table) |
356 | termios->c_cflag &= ~(CBAUDEX << IBSHIFT); | 362 | termios->c_cflag &= ~(CBAUDEX << IBSHIFT); |
357 | else | 363 | else |
358 | cbaud += 15; | 364 | cbaud += 15; |
359 | } | 365 | } |
360 | return baud_table[cbaud]; | 366 | return baud_table[cbaud]; |
361 | #else | 367 | #else |
362 | return tty_termios_baud_rate(termios); | 368 | return tty_termios_baud_rate(termios); |
363 | #endif | 369 | #endif |
364 | } | 370 | } |
365 | EXPORT_SYMBOL(tty_termios_input_baud_rate); | 371 | EXPORT_SYMBOL(tty_termios_input_baud_rate); |
366 | 372 | ||
367 | /** | 373 | /** |
368 | * tty_termios_encode_baud_rate | 374 | * tty_termios_encode_baud_rate |
369 | * @termios: ktermios structure holding user requested state | 375 | * @termios: ktermios structure holding user requested state |
370 | * @ispeed: input speed | 376 | * @ispeed: input speed |
371 | * @ospeed: output speed | 377 | * @ospeed: output speed |
372 | * | 378 | * |
373 | * Encode the speeds set into the passed termios structure. This is | 379 | * Encode the speeds set into the passed termios structure. This is |
374 | * used as a library helper for drivers so that they can report back | 380 | * used as a library helper for drivers so that they can report back |
375 | * the actual speed selected when it differs from the speed requested | 381 | * the actual speed selected when it differs from the speed requested |
376 | * | 382 | * |
377 | * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour | 383 | * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour |
378 | * we need to carefully set the bits when the user does not get the | 384 | * we need to carefully set the bits when the user does not get the |
379 | * desired speed. We allow small margins and preserve as much of possible | 385 | * desired speed. We allow small margins and preserve as much of possible |
380 | * of the input intent to keep compatibility. | 386 | * of the input intent to keep compatibility. |
381 | * | 387 | * |
382 | * Locking: Caller should hold termios lock. This is already held | 388 | * Locking: Caller should hold termios lock. This is already held |
383 | * when calling this function from the driver termios handler. | 389 | * when calling this function from the driver termios handler. |
384 | * | 390 | * |
385 | * The ifdefs deal with platforms whose owners have yet to update them | 391 | * The ifdefs deal with platforms whose owners have yet to update them |
386 | * and will all go away once this is done. | 392 | * and will all go away once this is done. |
387 | */ | 393 | */ |
388 | 394 | ||
389 | void tty_termios_encode_baud_rate(struct ktermios *termios, | 395 | void tty_termios_encode_baud_rate(struct ktermios *termios, |
390 | speed_t ibaud, speed_t obaud) | 396 | speed_t ibaud, speed_t obaud) |
391 | { | 397 | { |
392 | int i = 0; | 398 | int i = 0; |
393 | int ifound = -1, ofound = -1; | 399 | int ifound = -1, ofound = -1; |
394 | int iclose = ibaud/50, oclose = obaud/50; | 400 | int iclose = ibaud/50, oclose = obaud/50; |
395 | int ibinput = 0; | 401 | int ibinput = 0; |
396 | 402 | ||
397 | if (obaud == 0) /* CD dropped */ | 403 | if (obaud == 0) /* CD dropped */ |
398 | ibaud = 0; /* Clear ibaud to be sure */ | 404 | ibaud = 0; /* Clear ibaud to be sure */ |
399 | 405 | ||
400 | termios->c_ispeed = ibaud; | 406 | termios->c_ispeed = ibaud; |
401 | termios->c_ospeed = obaud; | 407 | termios->c_ospeed = obaud; |
402 | 408 | ||
403 | #ifdef BOTHER | 409 | #ifdef BOTHER |
404 | /* If the user asked for a precise weird speed give a precise weird | 410 | /* If the user asked for a precise weird speed give a precise weird |
405 | answer. If they asked for a Bfoo speed they may have problems | 411 | answer. If they asked for a Bfoo speed they may have problems |
406 | digesting non-exact replies so fuzz a bit */ | 412 | digesting non-exact replies so fuzz a bit */ |
407 | 413 | ||
408 | if ((termios->c_cflag & CBAUD) == BOTHER) | 414 | if ((termios->c_cflag & CBAUD) == BOTHER) |
409 | oclose = 0; | 415 | oclose = 0; |
410 | if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER) | 416 | if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER) |
411 | iclose = 0; | 417 | iclose = 0; |
412 | if ((termios->c_cflag >> IBSHIFT) & CBAUD) | 418 | if ((termios->c_cflag >> IBSHIFT) & CBAUD) |
413 | ibinput = 1; /* An input speed was specified */ | 419 | ibinput = 1; /* An input speed was specified */ |
414 | #endif | 420 | #endif |
415 | termios->c_cflag &= ~CBAUD; | 421 | termios->c_cflag &= ~CBAUD; |
416 | 422 | ||
417 | /* | 423 | /* |
418 | * Our goal is to find a close match to the standard baud rate | 424 | * Our goal is to find a close match to the standard baud rate |
419 | * returned. Walk the baud rate table and if we get a very close | 425 | * returned. Walk the baud rate table and if we get a very close |
420 | * match then report back the speed as a POSIX Bxxxx value by | 426 | * match then report back the speed as a POSIX Bxxxx value by |
421 | * preference | 427 | * preference |
422 | */ | 428 | */ |
423 | 429 | ||
424 | do { | 430 | do { |
425 | if (obaud - oclose <= baud_table[i] && | 431 | if (obaud - oclose <= baud_table[i] && |
426 | obaud + oclose >= baud_table[i]) { | 432 | obaud + oclose >= baud_table[i]) { |
427 | termios->c_cflag |= baud_bits[i]; | 433 | termios->c_cflag |= baud_bits[i]; |
428 | ofound = i; | 434 | ofound = i; |
429 | } | 435 | } |
430 | if (ibaud - iclose <= baud_table[i] && | 436 | if (ibaud - iclose <= baud_table[i] && |
431 | ibaud + iclose >= baud_table[i]) { | 437 | ibaud + iclose >= baud_table[i]) { |
432 | /* For the case input == output don't set IBAUD bits | 438 | /* For the case input == output don't set IBAUD bits |
433 | if the user didn't do so */ | 439 | if the user didn't do so */ |
434 | if (ofound == i && !ibinput) | 440 | if (ofound == i && !ibinput) |
435 | ifound = i; | 441 | ifound = i; |
436 | #ifdef IBSHIFT | 442 | #ifdef IBSHIFT |
437 | else { | 443 | else { |
438 | ifound = i; | 444 | ifound = i; |
439 | termios->c_cflag |= (baud_bits[i] << IBSHIFT); | 445 | termios->c_cflag |= (baud_bits[i] << IBSHIFT); |
440 | } | 446 | } |
441 | #endif | 447 | #endif |
442 | } | 448 | } |
443 | } while (++i < n_baud_table); | 449 | } while (++i < n_baud_table); |
444 | 450 | ||
445 | /* | 451 | /* |
446 | * If we found no match then use BOTHER if provided or warn | 452 | * If we found no match then use BOTHER if provided or warn |
447 | * the user their platform maintainer needs to wake up if not. | 453 | * the user their platform maintainer needs to wake up if not. |
448 | */ | 454 | */ |
449 | #ifdef BOTHER | 455 | #ifdef BOTHER |
450 | if (ofound == -1) | 456 | if (ofound == -1) |
451 | termios->c_cflag |= BOTHER; | 457 | termios->c_cflag |= BOTHER; |
452 | /* Set exact input bits only if the input and output differ or the | 458 | /* Set exact input bits only if the input and output differ or the |
453 | user already did */ | 459 | user already did */ |
454 | if (ifound == -1 && (ibaud != obaud || ibinput)) | 460 | if (ifound == -1 && (ibaud != obaud || ibinput)) |
455 | termios->c_cflag |= (BOTHER << IBSHIFT); | 461 | termios->c_cflag |= (BOTHER << IBSHIFT); |
456 | #else | 462 | #else |
457 | if (ifound == -1 || ofound == -1) { | 463 | if (ifound == -1 || ofound == -1) { |
458 | printk_once(KERN_WARNING "tty: Unable to return correct " | 464 | printk_once(KERN_WARNING "tty: Unable to return correct " |
459 | "speed data as your architecture needs updating.\n"); | 465 | "speed data as your architecture needs updating.\n"); |
460 | } | 466 | } |
461 | #endif | 467 | #endif |
462 | } | 468 | } |
463 | EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); | 469 | EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); |
464 | 470 | ||
465 | /** | 471 | /** |
466 | * tty_encode_baud_rate - set baud rate of the tty | 472 | * tty_encode_baud_rate - set baud rate of the tty |
467 | * @ibaud: input baud rate | 473 | * @ibaud: input baud rate |
468 | * @obad: output baud rate | 474 | * @obad: output baud rate |
469 | * | 475 | * |
470 | * Update the current termios data for the tty with the new speed | 476 | * Update the current termios data for the tty with the new speed |
471 | * settings. The caller must hold the termios_rwsem for the tty in | 477 | * settings. The caller must hold the termios_rwsem for the tty in |
472 | * question. | 478 | * question. |
473 | */ | 479 | */ |
474 | 480 | ||
475 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) | 481 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) |
476 | { | 482 | { |
477 | tty_termios_encode_baud_rate(&tty->termios, ibaud, obaud); | 483 | tty_termios_encode_baud_rate(&tty->termios, ibaud, obaud); |
478 | } | 484 | } |
479 | EXPORT_SYMBOL_GPL(tty_encode_baud_rate); | 485 | EXPORT_SYMBOL_GPL(tty_encode_baud_rate); |
480 | 486 | ||
481 | /** | 487 | /** |
482 | * tty_termios_copy_hw - copy hardware settings | 488 | * tty_termios_copy_hw - copy hardware settings |
483 | * @new: New termios | 489 | * @new: New termios |
484 | * @old: Old termios | 490 | * @old: Old termios |
485 | * | 491 | * |
486 | * Propagate the hardware specific terminal setting bits from | 492 | * Propagate the hardware specific terminal setting bits from |
487 | * the old termios structure to the new one. This is used in cases | 493 | * the old termios structure to the new one. This is used in cases |
488 | * where the hardware does not support reconfiguration or as a helper | 494 | * where the hardware does not support reconfiguration or as a helper |
489 | * in some cases where only minimal reconfiguration is supported | 495 | * in some cases where only minimal reconfiguration is supported |
490 | */ | 496 | */ |
491 | 497 | ||
492 | void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old) | 498 | void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old) |
493 | { | 499 | { |
494 | /* The bits a dumb device handles in software. Smart devices need | 500 | /* The bits a dumb device handles in software. Smart devices need |
495 | to always provide a set_termios method */ | 501 | to always provide a set_termios method */ |
496 | new->c_cflag &= HUPCL | CREAD | CLOCAL; | 502 | new->c_cflag &= HUPCL | CREAD | CLOCAL; |
497 | new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL); | 503 | new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL); |
498 | new->c_ispeed = old->c_ispeed; | 504 | new->c_ispeed = old->c_ispeed; |
499 | new->c_ospeed = old->c_ospeed; | 505 | new->c_ospeed = old->c_ospeed; |
500 | } | 506 | } |
501 | EXPORT_SYMBOL(tty_termios_copy_hw); | 507 | EXPORT_SYMBOL(tty_termios_copy_hw); |
502 | 508 | ||
503 | /** | 509 | /** |
504 | * tty_termios_hw_change - check for setting change | 510 | * tty_termios_hw_change - check for setting change |
505 | * @a: termios | 511 | * @a: termios |
506 | * @b: termios to compare | 512 | * @b: termios to compare |
507 | * | 513 | * |
508 | * Check if any of the bits that affect a dumb device have changed | 514 | * Check if any of the bits that affect a dumb device have changed |
509 | * between the two termios structures, or a speed change is needed. | 515 | * between the two termios structures, or a speed change is needed. |
510 | */ | 516 | */ |
511 | 517 | ||
512 | int tty_termios_hw_change(struct ktermios *a, struct ktermios *b) | 518 | int tty_termios_hw_change(struct ktermios *a, struct ktermios *b) |
513 | { | 519 | { |
514 | if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) | 520 | if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) |
515 | return 1; | 521 | return 1; |
516 | if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL)) | 522 | if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL)) |
517 | return 1; | 523 | return 1; |
518 | return 0; | 524 | return 0; |
519 | } | 525 | } |
520 | EXPORT_SYMBOL(tty_termios_hw_change); | 526 | EXPORT_SYMBOL(tty_termios_hw_change); |
521 | 527 | ||
522 | /** | 528 | /** |
523 | * tty_set_termios - update termios values | 529 | * tty_set_termios - update termios values |
524 | * @tty: tty to update | 530 | * @tty: tty to update |
525 | * @new_termios: desired new value | 531 | * @new_termios: desired new value |
526 | * | 532 | * |
527 | * Perform updates to the termios values set on this terminal. | 533 | * Perform updates to the termios values set on this terminal. |
528 | * A master pty's termios should never be set. | 534 | * A master pty's termios should never be set. |
529 | * | 535 | * |
530 | * Locking: termios_rwsem | 536 | * Locking: termios_rwsem |
531 | */ | 537 | */ |
532 | 538 | ||
533 | static int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) | 539 | static int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) |
534 | { | 540 | { |
535 | struct ktermios old_termios; | 541 | struct ktermios old_termios; |
536 | struct tty_ldisc *ld; | 542 | struct tty_ldisc *ld; |
537 | 543 | ||
538 | WARN_ON(tty->driver->type == TTY_DRIVER_TYPE_PTY && | 544 | WARN_ON(tty->driver->type == TTY_DRIVER_TYPE_PTY && |
539 | tty->driver->subtype == PTY_TYPE_MASTER); | 545 | tty->driver->subtype == PTY_TYPE_MASTER); |
540 | /* | 546 | /* |
541 | * Perform the actual termios internal changes under lock. | 547 | * Perform the actual termios internal changes under lock. |
542 | */ | 548 | */ |
543 | 549 | ||
544 | 550 | ||
545 | /* FIXME: we need to decide on some locking/ordering semantics | 551 | /* FIXME: we need to decide on some locking/ordering semantics |
546 | for the set_termios notification eventually */ | 552 | for the set_termios notification eventually */ |
547 | down_write(&tty->termios_rwsem); | 553 | down_write(&tty->termios_rwsem); |
548 | old_termios = tty->termios; | 554 | old_termios = tty->termios; |
549 | tty->termios = *new_termios; | 555 | tty->termios = *new_termios; |
550 | unset_locked_termios(&tty->termios, &old_termios, &tty->termios_locked); | 556 | unset_locked_termios(&tty->termios, &old_termios, &tty->termios_locked); |
551 | 557 | ||
552 | if (tty->ops->set_termios) | 558 | if (tty->ops->set_termios) |
553 | tty->ops->set_termios(tty, &old_termios); | 559 | tty->ops->set_termios(tty, &old_termios); |
554 | else | 560 | else |
555 | tty_termios_copy_hw(&tty->termios, &old_termios); | 561 | tty_termios_copy_hw(&tty->termios, &old_termios); |
556 | 562 | ||
557 | ld = tty_ldisc_ref(tty); | 563 | ld = tty_ldisc_ref(tty); |
558 | if (ld != NULL) { | 564 | if (ld != NULL) { |
559 | if (ld->ops->set_termios) | 565 | if (ld->ops->set_termios) |
560 | ld->ops->set_termios(tty, &old_termios); | 566 | ld->ops->set_termios(tty, &old_termios); |
561 | tty_ldisc_deref(ld); | 567 | tty_ldisc_deref(ld); |
562 | } | 568 | } |
563 | up_write(&tty->termios_rwsem); | 569 | up_write(&tty->termios_rwsem); |
564 | return 0; | 570 | return 0; |
565 | } | 571 | } |
566 | 572 | ||
567 | /** | 573 | /** |
568 | * set_termios - set termios values for a tty | 574 | * set_termios - set termios values for a tty |
569 | * @tty: terminal device | 575 | * @tty: terminal device |
570 | * @arg: user data | 576 | * @arg: user data |
571 | * @opt: option information | 577 | * @opt: option information |
572 | * | 578 | * |
573 | * Helper function to prepare termios data and run necessary other | 579 | * Helper function to prepare termios data and run necessary other |
574 | * functions before using tty_set_termios to do the actual changes. | 580 | * functions before using tty_set_termios to do the actual changes. |
575 | * | 581 | * |
576 | * Locking: | 582 | * Locking: |
577 | * Called functions take ldisc and termios_rwsem locks | 583 | * Called functions take ldisc and termios_rwsem locks |
578 | */ | 584 | */ |
579 | 585 | ||
580 | static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | 586 | static int set_termios(struct tty_struct *tty, void __user *arg, int opt) |
581 | { | 587 | { |
582 | struct ktermios tmp_termios; | 588 | struct ktermios tmp_termios; |
583 | struct tty_ldisc *ld; | 589 | struct tty_ldisc *ld; |
584 | int retval = tty_check_change(tty); | 590 | int retval = tty_check_change(tty); |
585 | 591 | ||
586 | if (retval) | 592 | if (retval) |
587 | return retval; | 593 | return retval; |
588 | 594 | ||
589 | down_read(&tty->termios_rwsem); | 595 | down_read(&tty->termios_rwsem); |
590 | tmp_termios = tty->termios; | 596 | tmp_termios = tty->termios; |
591 | up_read(&tty->termios_rwsem); | 597 | up_read(&tty->termios_rwsem); |
592 | 598 | ||
593 | if (opt & TERMIOS_TERMIO) { | 599 | if (opt & TERMIOS_TERMIO) { |
594 | if (user_termio_to_kernel_termios(&tmp_termios, | 600 | if (user_termio_to_kernel_termios(&tmp_termios, |
595 | (struct termio __user *)arg)) | 601 | (struct termio __user *)arg)) |
596 | return -EFAULT; | 602 | return -EFAULT; |
597 | #ifdef TCGETS2 | 603 | #ifdef TCGETS2 |
598 | } else if (opt & TERMIOS_OLD) { | 604 | } else if (opt & TERMIOS_OLD) { |
599 | if (user_termios_to_kernel_termios_1(&tmp_termios, | 605 | if (user_termios_to_kernel_termios_1(&tmp_termios, |
600 | (struct termios __user *)arg)) | 606 | (struct termios __user *)arg)) |
601 | return -EFAULT; | 607 | return -EFAULT; |
602 | } else { | 608 | } else { |
603 | if (user_termios_to_kernel_termios(&tmp_termios, | 609 | if (user_termios_to_kernel_termios(&tmp_termios, |
604 | (struct termios2 __user *)arg)) | 610 | (struct termios2 __user *)arg)) |
605 | return -EFAULT; | 611 | return -EFAULT; |
606 | } | 612 | } |
607 | #else | 613 | #else |
608 | } else if (user_termios_to_kernel_termios(&tmp_termios, | 614 | } else if (user_termios_to_kernel_termios(&tmp_termios, |
609 | (struct termios __user *)arg)) | 615 | (struct termios __user *)arg)) |
610 | return -EFAULT; | 616 | return -EFAULT; |
611 | #endif | 617 | #endif |
612 | 618 | ||
613 | /* If old style Bfoo values are used then load c_ispeed/c_ospeed | 619 | /* If old style Bfoo values are used then load c_ispeed/c_ospeed |
614 | * with the real speed so its unconditionally usable */ | 620 | * with the real speed so its unconditionally usable */ |
615 | tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); | 621 | tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); |
616 | tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); | 622 | tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); |
617 | 623 | ||
618 | ld = tty_ldisc_ref(tty); | 624 | ld = tty_ldisc_ref(tty); |
619 | 625 | ||
620 | if (ld != NULL) { | 626 | if (ld != NULL) { |
621 | if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) | 627 | if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) |
622 | ld->ops->flush_buffer(tty); | 628 | ld->ops->flush_buffer(tty); |
623 | tty_ldisc_deref(ld); | 629 | tty_ldisc_deref(ld); |
624 | } | 630 | } |
625 | 631 | ||
626 | if (opt & TERMIOS_WAIT) { | 632 | if (opt & TERMIOS_WAIT) { |
627 | tty_wait_until_sent(tty, 0); | 633 | tty_wait_until_sent(tty, 0); |
628 | if (signal_pending(current)) | 634 | if (signal_pending(current)) |
629 | return -ERESTARTSYS; | 635 | return -ERESTARTSYS; |
630 | } | 636 | } |
631 | 637 | ||
632 | tty_set_termios(tty, &tmp_termios); | 638 | tty_set_termios(tty, &tmp_termios); |
633 | 639 | ||
634 | /* FIXME: Arguably if tmp_termios == tty->termios AND the | 640 | /* FIXME: Arguably if tmp_termios == tty->termios AND the |
635 | actual requested termios was not tmp_termios then we may | 641 | actual requested termios was not tmp_termios then we may |
636 | want to return an error as no user requested change has | 642 | want to return an error as no user requested change has |
637 | succeeded */ | 643 | succeeded */ |
638 | return 0; | 644 | return 0; |
639 | } | 645 | } |
640 | 646 | ||
641 | static void copy_termios(struct tty_struct *tty, struct ktermios *kterm) | 647 | static void copy_termios(struct tty_struct *tty, struct ktermios *kterm) |
642 | { | 648 | { |
643 | down_read(&tty->termios_rwsem); | 649 | down_read(&tty->termios_rwsem); |
644 | *kterm = tty->termios; | 650 | *kterm = tty->termios; |
645 | up_read(&tty->termios_rwsem); | 651 | up_read(&tty->termios_rwsem); |
646 | } | 652 | } |
647 | 653 | ||
648 | static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm) | 654 | static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm) |
649 | { | 655 | { |
650 | down_read(&tty->termios_rwsem); | 656 | down_read(&tty->termios_rwsem); |
651 | *kterm = tty->termios_locked; | 657 | *kterm = tty->termios_locked; |
652 | up_read(&tty->termios_rwsem); | 658 | up_read(&tty->termios_rwsem); |
653 | } | 659 | } |
654 | 660 | ||
655 | static int get_termio(struct tty_struct *tty, struct termio __user *termio) | 661 | static int get_termio(struct tty_struct *tty, struct termio __user *termio) |
656 | { | 662 | { |
657 | struct ktermios kterm; | 663 | struct ktermios kterm; |
658 | copy_termios(tty, &kterm); | 664 | copy_termios(tty, &kterm); |
659 | if (kernel_termios_to_user_termio(termio, &kterm)) | 665 | if (kernel_termios_to_user_termio(termio, &kterm)) |
660 | return -EFAULT; | 666 | return -EFAULT; |
661 | return 0; | 667 | return 0; |
662 | } | 668 | } |
663 | 669 | ||
664 | 670 | ||
665 | #ifdef TCGETX | 671 | #ifdef TCGETX |
666 | 672 | ||
667 | /** | 673 | /** |
668 | * set_termiox - set termiox fields if possible | 674 | * set_termiox - set termiox fields if possible |
669 | * @tty: terminal | 675 | * @tty: terminal |
670 | * @arg: termiox structure from user | 676 | * @arg: termiox structure from user |
671 | * @opt: option flags for ioctl type | 677 | * @opt: option flags for ioctl type |
672 | * | 678 | * |
673 | * Implement the device calling points for the SYS5 termiox ioctl | 679 | * Implement the device calling points for the SYS5 termiox ioctl |
674 | * interface in Linux | 680 | * interface in Linux |
675 | */ | 681 | */ |
676 | 682 | ||
677 | static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) | 683 | static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) |
678 | { | 684 | { |
679 | struct termiox tnew; | 685 | struct termiox tnew; |
680 | struct tty_ldisc *ld; | 686 | struct tty_ldisc *ld; |
681 | 687 | ||
682 | if (tty->termiox == NULL) | 688 | if (tty->termiox == NULL) |
683 | return -EINVAL; | 689 | return -EINVAL; |
684 | if (copy_from_user(&tnew, arg, sizeof(struct termiox))) | 690 | if (copy_from_user(&tnew, arg, sizeof(struct termiox))) |
685 | return -EFAULT; | 691 | return -EFAULT; |
686 | 692 | ||
687 | ld = tty_ldisc_ref(tty); | 693 | ld = tty_ldisc_ref(tty); |
688 | if (ld != NULL) { | 694 | if (ld != NULL) { |
689 | if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) | 695 | if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) |
690 | ld->ops->flush_buffer(tty); | 696 | ld->ops->flush_buffer(tty); |
691 | tty_ldisc_deref(ld); | 697 | tty_ldisc_deref(ld); |
692 | } | 698 | } |
693 | if (opt & TERMIOS_WAIT) { | 699 | if (opt & TERMIOS_WAIT) { |
694 | tty_wait_until_sent(tty, 0); | 700 | tty_wait_until_sent(tty, 0); |
695 | if (signal_pending(current)) | 701 | if (signal_pending(current)) |
696 | return -ERESTARTSYS; | 702 | return -ERESTARTSYS; |
697 | } | 703 | } |
698 | 704 | ||
699 | down_write(&tty->termios_rwsem); | 705 | down_write(&tty->termios_rwsem); |
700 | if (tty->ops->set_termiox) | 706 | if (tty->ops->set_termiox) |
701 | tty->ops->set_termiox(tty, &tnew); | 707 | tty->ops->set_termiox(tty, &tnew); |
702 | up_write(&tty->termios_rwsem); | 708 | up_write(&tty->termios_rwsem); |
703 | return 0; | 709 | return 0; |
704 | } | 710 | } |
705 | 711 | ||
706 | #endif | 712 | #endif |
707 | 713 | ||
708 | 714 | ||
709 | #ifdef TIOCGETP | 715 | #ifdef TIOCGETP |
710 | /* | 716 | /* |
711 | * These are deprecated, but there is limited support.. | 717 | * These are deprecated, but there is limited support.. |
712 | * | 718 | * |
713 | * The "sg_flags" translation is a joke.. | 719 | * The "sg_flags" translation is a joke.. |
714 | */ | 720 | */ |
715 | static int get_sgflags(struct tty_struct *tty) | 721 | static int get_sgflags(struct tty_struct *tty) |
716 | { | 722 | { |
717 | int flags = 0; | 723 | int flags = 0; |
718 | 724 | ||
719 | if (!(tty->termios.c_lflag & ICANON)) { | 725 | if (!(tty->termios.c_lflag & ICANON)) { |
720 | if (tty->termios.c_lflag & ISIG) | 726 | if (tty->termios.c_lflag & ISIG) |
721 | flags |= 0x02; /* cbreak */ | 727 | flags |= 0x02; /* cbreak */ |
722 | else | 728 | else |
723 | flags |= 0x20; /* raw */ | 729 | flags |= 0x20; /* raw */ |
724 | } | 730 | } |
725 | if (tty->termios.c_lflag & ECHO) | 731 | if (tty->termios.c_lflag & ECHO) |
726 | flags |= 0x08; /* echo */ | 732 | flags |= 0x08; /* echo */ |
727 | if (tty->termios.c_oflag & OPOST) | 733 | if (tty->termios.c_oflag & OPOST) |
728 | if (tty->termios.c_oflag & ONLCR) | 734 | if (tty->termios.c_oflag & ONLCR) |
729 | flags |= 0x10; /* crmod */ | 735 | flags |= 0x10; /* crmod */ |
730 | return flags; | 736 | return flags; |
731 | } | 737 | } |
732 | 738 | ||
733 | static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) | 739 | static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) |
734 | { | 740 | { |
735 | struct sgttyb tmp; | 741 | struct sgttyb tmp; |
736 | 742 | ||
737 | down_read(&tty->termios_rwsem); | 743 | down_read(&tty->termios_rwsem); |
738 | tmp.sg_ispeed = tty->termios.c_ispeed; | 744 | tmp.sg_ispeed = tty->termios.c_ispeed; |
739 | tmp.sg_ospeed = tty->termios.c_ospeed; | 745 | tmp.sg_ospeed = tty->termios.c_ospeed; |
740 | tmp.sg_erase = tty->termios.c_cc[VERASE]; | 746 | tmp.sg_erase = tty->termios.c_cc[VERASE]; |
741 | tmp.sg_kill = tty->termios.c_cc[VKILL]; | 747 | tmp.sg_kill = tty->termios.c_cc[VKILL]; |
742 | tmp.sg_flags = get_sgflags(tty); | 748 | tmp.sg_flags = get_sgflags(tty); |
743 | up_read(&tty->termios_rwsem); | 749 | up_read(&tty->termios_rwsem); |
744 | 750 | ||
745 | return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 751 | return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
746 | } | 752 | } |
747 | 753 | ||
748 | static void set_sgflags(struct ktermios *termios, int flags) | 754 | static void set_sgflags(struct ktermios *termios, int flags) |
749 | { | 755 | { |
750 | termios->c_iflag = ICRNL | IXON; | 756 | termios->c_iflag = ICRNL | IXON; |
751 | termios->c_oflag = 0; | 757 | termios->c_oflag = 0; |
752 | termios->c_lflag = ISIG | ICANON; | 758 | termios->c_lflag = ISIG | ICANON; |
753 | if (flags & 0x02) { /* cbreak */ | 759 | if (flags & 0x02) { /* cbreak */ |
754 | termios->c_iflag = 0; | 760 | termios->c_iflag = 0; |
755 | termios->c_lflag &= ~ICANON; | 761 | termios->c_lflag &= ~ICANON; |
756 | } | 762 | } |
757 | if (flags & 0x08) { /* echo */ | 763 | if (flags & 0x08) { /* echo */ |
758 | termios->c_lflag |= ECHO | ECHOE | ECHOK | | 764 | termios->c_lflag |= ECHO | ECHOE | ECHOK | |
759 | ECHOCTL | ECHOKE | IEXTEN; | 765 | ECHOCTL | ECHOKE | IEXTEN; |
760 | } | 766 | } |
761 | if (flags & 0x10) { /* crmod */ | 767 | if (flags & 0x10) { /* crmod */ |
762 | termios->c_oflag |= OPOST | ONLCR; | 768 | termios->c_oflag |= OPOST | ONLCR; |
763 | } | 769 | } |
764 | if (flags & 0x20) { /* raw */ | 770 | if (flags & 0x20) { /* raw */ |
765 | termios->c_iflag = 0; | 771 | termios->c_iflag = 0; |
766 | termios->c_lflag &= ~(ISIG | ICANON); | 772 | termios->c_lflag &= ~(ISIG | ICANON); |
767 | } | 773 | } |
768 | if (!(termios->c_lflag & ICANON)) { | 774 | if (!(termios->c_lflag & ICANON)) { |
769 | termios->c_cc[VMIN] = 1; | 775 | termios->c_cc[VMIN] = 1; |
770 | termios->c_cc[VTIME] = 0; | 776 | termios->c_cc[VTIME] = 0; |
771 | } | 777 | } |
772 | } | 778 | } |
773 | 779 | ||
774 | /** | 780 | /** |
775 | * set_sgttyb - set legacy terminal values | 781 | * set_sgttyb - set legacy terminal values |
776 | * @tty: tty structure | 782 | * @tty: tty structure |
777 | * @sgttyb: pointer to old style terminal structure | 783 | * @sgttyb: pointer to old style terminal structure |
778 | * | 784 | * |
779 | * Updates a terminal from the legacy BSD style terminal information | 785 | * Updates a terminal from the legacy BSD style terminal information |
780 | * structure. | 786 | * structure. |
781 | * | 787 | * |
782 | * Locking: termios_rwsem | 788 | * Locking: termios_rwsem |
783 | */ | 789 | */ |
784 | 790 | ||
785 | static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) | 791 | static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) |
786 | { | 792 | { |
787 | int retval; | 793 | int retval; |
788 | struct sgttyb tmp; | 794 | struct sgttyb tmp; |
789 | struct ktermios termios; | 795 | struct ktermios termios; |
790 | 796 | ||
791 | retval = tty_check_change(tty); | 797 | retval = tty_check_change(tty); |
792 | if (retval) | 798 | if (retval) |
793 | return retval; | 799 | return retval; |
794 | 800 | ||
795 | if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) | 801 | if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) |
796 | return -EFAULT; | 802 | return -EFAULT; |
797 | 803 | ||
798 | down_write(&tty->termios_rwsem); | 804 | down_write(&tty->termios_rwsem); |
799 | termios = tty->termios; | 805 | termios = tty->termios; |
800 | termios.c_cc[VERASE] = tmp.sg_erase; | 806 | termios.c_cc[VERASE] = tmp.sg_erase; |
801 | termios.c_cc[VKILL] = tmp.sg_kill; | 807 | termios.c_cc[VKILL] = tmp.sg_kill; |
802 | set_sgflags(&termios, tmp.sg_flags); | 808 | set_sgflags(&termios, tmp.sg_flags); |
803 | /* Try and encode into Bfoo format */ | 809 | /* Try and encode into Bfoo format */ |
804 | #ifdef BOTHER | 810 | #ifdef BOTHER |
805 | tty_termios_encode_baud_rate(&termios, termios.c_ispeed, | 811 | tty_termios_encode_baud_rate(&termios, termios.c_ispeed, |
806 | termios.c_ospeed); | 812 | termios.c_ospeed); |
807 | #endif | 813 | #endif |
808 | up_write(&tty->termios_rwsem); | 814 | up_write(&tty->termios_rwsem); |
809 | tty_set_termios(tty, &termios); | 815 | tty_set_termios(tty, &termios); |
810 | return 0; | 816 | return 0; |
811 | } | 817 | } |
812 | #endif | 818 | #endif |
813 | 819 | ||
814 | #ifdef TIOCGETC | 820 | #ifdef TIOCGETC |
815 | static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars) | 821 | static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars) |
816 | { | 822 | { |
817 | struct tchars tmp; | 823 | struct tchars tmp; |
818 | 824 | ||
819 | down_read(&tty->termios_rwsem); | 825 | down_read(&tty->termios_rwsem); |
820 | tmp.t_intrc = tty->termios.c_cc[VINTR]; | 826 | tmp.t_intrc = tty->termios.c_cc[VINTR]; |
821 | tmp.t_quitc = tty->termios.c_cc[VQUIT]; | 827 | tmp.t_quitc = tty->termios.c_cc[VQUIT]; |
822 | tmp.t_startc = tty->termios.c_cc[VSTART]; | 828 | tmp.t_startc = tty->termios.c_cc[VSTART]; |
823 | tmp.t_stopc = tty->termios.c_cc[VSTOP]; | 829 | tmp.t_stopc = tty->termios.c_cc[VSTOP]; |
824 | tmp.t_eofc = tty->termios.c_cc[VEOF]; | 830 | tmp.t_eofc = tty->termios.c_cc[VEOF]; |
825 | tmp.t_brkc = tty->termios.c_cc[VEOL2]; /* what is brkc anyway? */ | 831 | tmp.t_brkc = tty->termios.c_cc[VEOL2]; /* what is brkc anyway? */ |
826 | up_read(&tty->termios_rwsem); | 832 | up_read(&tty->termios_rwsem); |
827 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 833 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
828 | } | 834 | } |
829 | 835 | ||
830 | static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars) | 836 | static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars) |
831 | { | 837 | { |
832 | struct tchars tmp; | 838 | struct tchars tmp; |
833 | 839 | ||
834 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) | 840 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) |
835 | return -EFAULT; | 841 | return -EFAULT; |
836 | down_write(&tty->termios_rwsem); | 842 | down_write(&tty->termios_rwsem); |
837 | tty->termios.c_cc[VINTR] = tmp.t_intrc; | 843 | tty->termios.c_cc[VINTR] = tmp.t_intrc; |
838 | tty->termios.c_cc[VQUIT] = tmp.t_quitc; | 844 | tty->termios.c_cc[VQUIT] = tmp.t_quitc; |
839 | tty->termios.c_cc[VSTART] = tmp.t_startc; | 845 | tty->termios.c_cc[VSTART] = tmp.t_startc; |
840 | tty->termios.c_cc[VSTOP] = tmp.t_stopc; | 846 | tty->termios.c_cc[VSTOP] = tmp.t_stopc; |
841 | tty->termios.c_cc[VEOF] = tmp.t_eofc; | 847 | tty->termios.c_cc[VEOF] = tmp.t_eofc; |
842 | tty->termios.c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ | 848 | tty->termios.c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ |
843 | up_write(&tty->termios_rwsem); | 849 | up_write(&tty->termios_rwsem); |
844 | return 0; | 850 | return 0; |
845 | } | 851 | } |
846 | #endif | 852 | #endif |
847 | 853 | ||
848 | #ifdef TIOCGLTC | 854 | #ifdef TIOCGLTC |
849 | static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | 855 | static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) |
850 | { | 856 | { |
851 | struct ltchars tmp; | 857 | struct ltchars tmp; |
852 | 858 | ||
853 | down_read(&tty->termios_rwsem); | 859 | down_read(&tty->termios_rwsem); |
854 | tmp.t_suspc = tty->termios.c_cc[VSUSP]; | 860 | tmp.t_suspc = tty->termios.c_cc[VSUSP]; |
855 | /* what is dsuspc anyway? */ | 861 | /* what is dsuspc anyway? */ |
856 | tmp.t_dsuspc = tty->termios.c_cc[VSUSP]; | 862 | tmp.t_dsuspc = tty->termios.c_cc[VSUSP]; |
857 | tmp.t_rprntc = tty->termios.c_cc[VREPRINT]; | 863 | tmp.t_rprntc = tty->termios.c_cc[VREPRINT]; |
858 | /* what is flushc anyway? */ | 864 | /* what is flushc anyway? */ |
859 | tmp.t_flushc = tty->termios.c_cc[VEOL2]; | 865 | tmp.t_flushc = tty->termios.c_cc[VEOL2]; |
860 | tmp.t_werasc = tty->termios.c_cc[VWERASE]; | 866 | tmp.t_werasc = tty->termios.c_cc[VWERASE]; |
861 | tmp.t_lnextc = tty->termios.c_cc[VLNEXT]; | 867 | tmp.t_lnextc = tty->termios.c_cc[VLNEXT]; |
862 | up_read(&tty->termios_rwsem); | 868 | up_read(&tty->termios_rwsem); |
863 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 869 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
864 | } | 870 | } |
865 | 871 | ||
866 | static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | 872 | static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) |
867 | { | 873 | { |
868 | struct ltchars tmp; | 874 | struct ltchars tmp; |
869 | 875 | ||
870 | if (copy_from_user(&tmp, ltchars, sizeof(tmp))) | 876 | if (copy_from_user(&tmp, ltchars, sizeof(tmp))) |
871 | return -EFAULT; | 877 | return -EFAULT; |
872 | 878 | ||
873 | down_write(&tty->termios_rwsem); | 879 | down_write(&tty->termios_rwsem); |
874 | tty->termios.c_cc[VSUSP] = tmp.t_suspc; | 880 | tty->termios.c_cc[VSUSP] = tmp.t_suspc; |
875 | /* what is dsuspc anyway? */ | 881 | /* what is dsuspc anyway? */ |
876 | tty->termios.c_cc[VEOL2] = tmp.t_dsuspc; | 882 | tty->termios.c_cc[VEOL2] = tmp.t_dsuspc; |
877 | tty->termios.c_cc[VREPRINT] = tmp.t_rprntc; | 883 | tty->termios.c_cc[VREPRINT] = tmp.t_rprntc; |
878 | /* what is flushc anyway? */ | 884 | /* what is flushc anyway? */ |
879 | tty->termios.c_cc[VEOL2] = tmp.t_flushc; | 885 | tty->termios.c_cc[VEOL2] = tmp.t_flushc; |
880 | tty->termios.c_cc[VWERASE] = tmp.t_werasc; | 886 | tty->termios.c_cc[VWERASE] = tmp.t_werasc; |
881 | tty->termios.c_cc[VLNEXT] = tmp.t_lnextc; | 887 | tty->termios.c_cc[VLNEXT] = tmp.t_lnextc; |
882 | up_write(&tty->termios_rwsem); | 888 | up_write(&tty->termios_rwsem); |
883 | return 0; | 889 | return 0; |
884 | } | 890 | } |
885 | #endif | 891 | #endif |
886 | 892 | ||
887 | /** | 893 | /** |
888 | * tty_change_softcar - carrier change ioctl helper | 894 | * tty_change_softcar - carrier change ioctl helper |
889 | * @tty: tty to update | 895 | * @tty: tty to update |
890 | * @arg: enable/disable CLOCAL | 896 | * @arg: enable/disable CLOCAL |
891 | * | 897 | * |
892 | * Perform a change to the CLOCAL state and call into the driver | 898 | * Perform a change to the CLOCAL state and call into the driver |
893 | * layer to make it visible. All done with the termios rwsem | 899 | * layer to make it visible. All done with the termios rwsem |
894 | */ | 900 | */ |
895 | 901 | ||
896 | static int tty_change_softcar(struct tty_struct *tty, int arg) | 902 | static int tty_change_softcar(struct tty_struct *tty, int arg) |
897 | { | 903 | { |
898 | int ret = 0; | 904 | int ret = 0; |
899 | int bit = arg ? CLOCAL : 0; | 905 | int bit = arg ? CLOCAL : 0; |
900 | struct ktermios old; | 906 | struct ktermios old; |
901 | 907 | ||
902 | down_write(&tty->termios_rwsem); | 908 | down_write(&tty->termios_rwsem); |
903 | old = tty->termios; | 909 | old = tty->termios; |
904 | tty->termios.c_cflag &= ~CLOCAL; | 910 | tty->termios.c_cflag &= ~CLOCAL; |
905 | tty->termios.c_cflag |= bit; | 911 | tty->termios.c_cflag |= bit; |
906 | if (tty->ops->set_termios) | 912 | if (tty->ops->set_termios) |
907 | tty->ops->set_termios(tty, &old); | 913 | tty->ops->set_termios(tty, &old); |
908 | if ((tty->termios.c_cflag & CLOCAL) != bit) | 914 | if ((tty->termios.c_cflag & CLOCAL) != bit) |
909 | ret = -EINVAL; | 915 | ret = -EINVAL; |
910 | up_write(&tty->termios_rwsem); | 916 | up_write(&tty->termios_rwsem); |
911 | return ret; | 917 | return ret; |
912 | } | 918 | } |
913 | 919 | ||
914 | /** | 920 | /** |
915 | * tty_mode_ioctl - mode related ioctls | 921 | * tty_mode_ioctl - mode related ioctls |
916 | * @tty: tty for the ioctl | 922 | * @tty: tty for the ioctl |
917 | * @file: file pointer for the tty | 923 | * @file: file pointer for the tty |
918 | * @cmd: command | 924 | * @cmd: command |
919 | * @arg: ioctl argument | 925 | * @arg: ioctl argument |
920 | * | 926 | * |
921 | * Perform non line discipline specific mode control ioctls. This | 927 | * Perform non line discipline specific mode control ioctls. This |
922 | * is designed to be called by line disciplines to ensure they provide | 928 | * is designed to be called by line disciplines to ensure they provide |
923 | * consistent mode setting. | 929 | * consistent mode setting. |
924 | */ | 930 | */ |
925 | 931 | ||
926 | int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | 932 | int tty_mode_ioctl(struct tty_struct *tty, struct file *file, |
927 | unsigned int cmd, unsigned long arg) | 933 | unsigned int cmd, unsigned long arg) |
928 | { | 934 | { |
929 | struct tty_struct *real_tty; | 935 | struct tty_struct *real_tty; |
930 | void __user *p = (void __user *)arg; | 936 | void __user *p = (void __user *)arg; |
931 | int ret = 0; | 937 | int ret = 0; |
932 | struct ktermios kterm; | 938 | struct ktermios kterm; |
933 | 939 | ||
934 | BUG_ON(file == NULL); | 940 | BUG_ON(file == NULL); |
935 | 941 | ||
936 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 942 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
937 | tty->driver->subtype == PTY_TYPE_MASTER) | 943 | tty->driver->subtype == PTY_TYPE_MASTER) |
938 | real_tty = tty->link; | 944 | real_tty = tty->link; |
939 | else | 945 | else |
940 | real_tty = tty; | 946 | real_tty = tty; |
941 | 947 | ||
942 | switch (cmd) { | 948 | switch (cmd) { |
943 | #ifdef TIOCGETP | 949 | #ifdef TIOCGETP |
944 | case TIOCGETP: | 950 | case TIOCGETP: |
945 | return get_sgttyb(real_tty, (struct sgttyb __user *) arg); | 951 | return get_sgttyb(real_tty, (struct sgttyb __user *) arg); |
946 | case TIOCSETP: | 952 | case TIOCSETP: |
947 | case TIOCSETN: | 953 | case TIOCSETN: |
948 | return set_sgttyb(real_tty, (struct sgttyb __user *) arg); | 954 | return set_sgttyb(real_tty, (struct sgttyb __user *) arg); |
949 | #endif | 955 | #endif |
950 | #ifdef TIOCGETC | 956 | #ifdef TIOCGETC |
951 | case TIOCGETC: | 957 | case TIOCGETC: |
952 | return get_tchars(real_tty, p); | 958 | return get_tchars(real_tty, p); |
953 | case TIOCSETC: | 959 | case TIOCSETC: |
954 | return set_tchars(real_tty, p); | 960 | return set_tchars(real_tty, p); |
955 | #endif | 961 | #endif |
956 | #ifdef TIOCGLTC | 962 | #ifdef TIOCGLTC |
957 | case TIOCGLTC: | 963 | case TIOCGLTC: |
958 | return get_ltchars(real_tty, p); | 964 | return get_ltchars(real_tty, p); |
959 | case TIOCSLTC: | 965 | case TIOCSLTC: |
960 | return set_ltchars(real_tty, p); | 966 | return set_ltchars(real_tty, p); |
961 | #endif | 967 | #endif |
962 | case TCSETSF: | 968 | case TCSETSF: |
963 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD); | 969 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD); |
964 | case TCSETSW: | 970 | case TCSETSW: |
965 | return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD); | 971 | return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD); |
966 | case TCSETS: | 972 | case TCSETS: |
967 | return set_termios(real_tty, p, TERMIOS_OLD); | 973 | return set_termios(real_tty, p, TERMIOS_OLD); |
968 | #ifndef TCGETS2 | 974 | #ifndef TCGETS2 |
969 | case TCGETS: | 975 | case TCGETS: |
970 | copy_termios(real_tty, &kterm); | 976 | copy_termios(real_tty, &kterm); |
971 | if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm)) | 977 | if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm)) |
972 | ret = -EFAULT; | 978 | ret = -EFAULT; |
973 | return ret; | 979 | return ret; |
974 | #else | 980 | #else |
975 | case TCGETS: | 981 | case TCGETS: |
976 | copy_termios(real_tty, &kterm); | 982 | copy_termios(real_tty, &kterm); |
977 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm)) | 983 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm)) |
978 | ret = -EFAULT; | 984 | ret = -EFAULT; |
979 | return ret; | 985 | return ret; |
980 | case TCGETS2: | 986 | case TCGETS2: |
981 | copy_termios(real_tty, &kterm); | 987 | copy_termios(real_tty, &kterm); |
982 | if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm)) | 988 | if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm)) |
983 | ret = -EFAULT; | 989 | ret = -EFAULT; |
984 | return ret; | 990 | return ret; |
985 | case TCSETSF2: | 991 | case TCSETSF2: |
986 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); | 992 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); |
987 | case TCSETSW2: | 993 | case TCSETSW2: |
988 | return set_termios(real_tty, p, TERMIOS_WAIT); | 994 | return set_termios(real_tty, p, TERMIOS_WAIT); |
989 | case TCSETS2: | 995 | case TCSETS2: |
990 | return set_termios(real_tty, p, 0); | 996 | return set_termios(real_tty, p, 0); |
991 | #endif | 997 | #endif |
992 | case TCGETA: | 998 | case TCGETA: |
993 | return get_termio(real_tty, p); | 999 | return get_termio(real_tty, p); |
994 | case TCSETAF: | 1000 | case TCSETAF: |
995 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO); | 1001 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO); |
996 | case TCSETAW: | 1002 | case TCSETAW: |
997 | return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO); | 1003 | return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO); |
998 | case TCSETA: | 1004 | case TCSETA: |
999 | return set_termios(real_tty, p, TERMIOS_TERMIO); | 1005 | return set_termios(real_tty, p, TERMIOS_TERMIO); |
1000 | #ifndef TCGETS2 | 1006 | #ifndef TCGETS2 |
1001 | case TIOCGLCKTRMIOS: | 1007 | case TIOCGLCKTRMIOS: |
1002 | copy_termios_locked(real_tty, &kterm); | 1008 | copy_termios_locked(real_tty, &kterm); |
1003 | if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm)) | 1009 | if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm)) |
1004 | ret = -EFAULT; | 1010 | ret = -EFAULT; |
1005 | return ret; | 1011 | return ret; |
1006 | case TIOCSLCKTRMIOS: | 1012 | case TIOCSLCKTRMIOS: |
1007 | if (!capable(CAP_SYS_ADMIN)) | 1013 | if (!capable(CAP_SYS_ADMIN)) |
1008 | return -EPERM; | 1014 | return -EPERM; |
1009 | copy_termios_locked(real_tty, &kterm); | 1015 | copy_termios_locked(real_tty, &kterm); |
1010 | if (user_termios_to_kernel_termios(&kterm, | 1016 | if (user_termios_to_kernel_termios(&kterm, |
1011 | (struct termios __user *) arg)) | 1017 | (struct termios __user *) arg)) |
1012 | return -EFAULT; | 1018 | return -EFAULT; |
1013 | down_write(&real_tty->termios_rwsem); | 1019 | down_write(&real_tty->termios_rwsem); |
1014 | real_tty->termios_locked = kterm; | 1020 | real_tty->termios_locked = kterm; |
1015 | up_write(&real_tty->termios_rwsem); | 1021 | up_write(&real_tty->termios_rwsem); |
1016 | return 0; | 1022 | return 0; |
1017 | #else | 1023 | #else |
1018 | case TIOCGLCKTRMIOS: | 1024 | case TIOCGLCKTRMIOS: |
1019 | copy_termios_locked(real_tty, &kterm); | 1025 | copy_termios_locked(real_tty, &kterm); |
1020 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm)) | 1026 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm)) |
1021 | ret = -EFAULT; | 1027 | ret = -EFAULT; |
1022 | return ret; | 1028 | return ret; |
1023 | case TIOCSLCKTRMIOS: | 1029 | case TIOCSLCKTRMIOS: |
1024 | if (!capable(CAP_SYS_ADMIN)) | 1030 | if (!capable(CAP_SYS_ADMIN)) |
1025 | return -EPERM; | 1031 | return -EPERM; |
1026 | copy_termios_locked(real_tty, &kterm); | 1032 | copy_termios_locked(real_tty, &kterm); |
1027 | if (user_termios_to_kernel_termios_1(&kterm, | 1033 | if (user_termios_to_kernel_termios_1(&kterm, |
1028 | (struct termios __user *) arg)) | 1034 | (struct termios __user *) arg)) |
1029 | return -EFAULT; | 1035 | return -EFAULT; |
1030 | down_write(&real_tty->termios_rwsem); | 1036 | down_write(&real_tty->termios_rwsem); |
1031 | real_tty->termios_locked = kterm; | 1037 | real_tty->termios_locked = kterm; |
1032 | up_write(&real_tty->termios_rwsem); | 1038 | up_write(&real_tty->termios_rwsem); |
1033 | return ret; | 1039 | return ret; |
1034 | #endif | 1040 | #endif |
1035 | #ifdef TCGETX | 1041 | #ifdef TCGETX |
1036 | case TCGETX: { | 1042 | case TCGETX: { |
1037 | struct termiox ktermx; | 1043 | struct termiox ktermx; |
1038 | if (real_tty->termiox == NULL) | 1044 | if (real_tty->termiox == NULL) |
1039 | return -EINVAL; | 1045 | return -EINVAL; |
1040 | down_read(&real_tty->termios_rwsem); | 1046 | down_read(&real_tty->termios_rwsem); |
1041 | memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox)); | 1047 | memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox)); |
1042 | up_read(&real_tty->termios_rwsem); | 1048 | up_read(&real_tty->termios_rwsem); |
1043 | if (copy_to_user(p, &ktermx, sizeof(struct termiox))) | 1049 | if (copy_to_user(p, &ktermx, sizeof(struct termiox))) |
1044 | ret = -EFAULT; | 1050 | ret = -EFAULT; |
1045 | return ret; | 1051 | return ret; |
1046 | } | 1052 | } |
1047 | case TCSETX: | 1053 | case TCSETX: |
1048 | return set_termiox(real_tty, p, 0); | 1054 | return set_termiox(real_tty, p, 0); |
1049 | case TCSETXW: | 1055 | case TCSETXW: |
1050 | return set_termiox(real_tty, p, TERMIOS_WAIT); | 1056 | return set_termiox(real_tty, p, TERMIOS_WAIT); |
1051 | case TCSETXF: | 1057 | case TCSETXF: |
1052 | return set_termiox(real_tty, p, TERMIOS_FLUSH); | 1058 | return set_termiox(real_tty, p, TERMIOS_FLUSH); |
1053 | #endif | 1059 | #endif |
1054 | case TIOCGSOFTCAR: | 1060 | case TIOCGSOFTCAR: |
1055 | copy_termios(real_tty, &kterm); | 1061 | copy_termios(real_tty, &kterm); |
1056 | ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0, | 1062 | ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0, |
1057 | (int __user *)arg); | 1063 | (int __user *)arg); |
1058 | return ret; | 1064 | return ret; |
1059 | case TIOCSSOFTCAR: | 1065 | case TIOCSSOFTCAR: |
1060 | if (get_user(arg, (unsigned int __user *) arg)) | 1066 | if (get_user(arg, (unsigned int __user *) arg)) |
1061 | return -EFAULT; | 1067 | return -EFAULT; |
1062 | return tty_change_softcar(real_tty, arg); | 1068 | return tty_change_softcar(real_tty, arg); |
1063 | default: | 1069 | default: |
1064 | return -ENOIOCTLCMD; | 1070 | return -ENOIOCTLCMD; |
1065 | } | 1071 | } |
1066 | } | 1072 | } |
1067 | EXPORT_SYMBOL_GPL(tty_mode_ioctl); | 1073 | EXPORT_SYMBOL_GPL(tty_mode_ioctl); |
1068 | 1074 | ||
1069 | 1075 | ||
1070 | /* Caller guarantees ldisc reference is held */ | 1076 | /* Caller guarantees ldisc reference is held */ |
1071 | static int __tty_perform_flush(struct tty_struct *tty, unsigned long arg) | 1077 | static int __tty_perform_flush(struct tty_struct *tty, unsigned long arg) |
1072 | { | 1078 | { |
1073 | struct tty_ldisc *ld = tty->ldisc; | 1079 | struct tty_ldisc *ld = tty->ldisc; |
1074 | 1080 | ||
1075 | switch (arg) { | 1081 | switch (arg) { |
1076 | case TCIFLUSH: | 1082 | case TCIFLUSH: |
1077 | if (ld && ld->ops->flush_buffer) { | 1083 | if (ld && ld->ops->flush_buffer) { |
1078 | ld->ops->flush_buffer(tty); | 1084 | ld->ops->flush_buffer(tty); |
1079 | tty_unthrottle(tty); | 1085 | tty_unthrottle(tty); |
1080 | } | 1086 | } |
1081 | break; | 1087 | break; |
1082 | case TCIOFLUSH: | 1088 | case TCIOFLUSH: |
1083 | if (ld && ld->ops->flush_buffer) { | 1089 | if (ld && ld->ops->flush_buffer) { |
1084 | ld->ops->flush_buffer(tty); | 1090 | ld->ops->flush_buffer(tty); |
1085 | tty_unthrottle(tty); | 1091 | tty_unthrottle(tty); |
1086 | } | 1092 | } |
1087 | /* fall through */ | 1093 | /* fall through */ |
1088 | case TCOFLUSH: | 1094 | case TCOFLUSH: |
1089 | tty_driver_flush_buffer(tty); | 1095 | tty_driver_flush_buffer(tty); |
1090 | break; | 1096 | break; |
1091 | default: | 1097 | default: |
1092 | return -EINVAL; | 1098 | return -EINVAL; |
1093 | } | 1099 | } |
1094 | return 0; | 1100 | return 0; |
1095 | } | 1101 | } |
1096 | 1102 | ||
1097 | int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | 1103 | int tty_perform_flush(struct tty_struct *tty, unsigned long arg) |
1098 | { | 1104 | { |
1099 | struct tty_ldisc *ld; | 1105 | struct tty_ldisc *ld; |
1100 | int retval = tty_check_change(tty); | 1106 | int retval = tty_check_change(tty); |
1101 | if (retval) | 1107 | if (retval) |
1102 | return retval; | 1108 | return retval; |
1103 | 1109 | ||
1104 | ld = tty_ldisc_ref_wait(tty); | 1110 | ld = tty_ldisc_ref_wait(tty); |
1105 | retval = __tty_perform_flush(tty, arg); | 1111 | retval = __tty_perform_flush(tty, arg); |
1106 | if (ld) | 1112 | if (ld) |
1107 | tty_ldisc_deref(ld); | 1113 | tty_ldisc_deref(ld); |
1108 | return retval; | 1114 | return retval; |
1109 | } | 1115 | } |
1110 | EXPORT_SYMBOL_GPL(tty_perform_flush); | 1116 | EXPORT_SYMBOL_GPL(tty_perform_flush); |
1111 | 1117 | ||
1112 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, | 1118 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
1113 | unsigned int cmd, unsigned long arg) | 1119 | unsigned int cmd, unsigned long arg) |
1114 | { | 1120 | { |
1115 | int retval; | 1121 | int retval; |
1116 | 1122 | ||
1117 | switch (cmd) { | 1123 | switch (cmd) { |
1118 | case TCXONC: | 1124 | case TCXONC: |
1119 | retval = tty_check_change(tty); | 1125 | retval = tty_check_change(tty); |
1120 | if (retval) | 1126 | if (retval) |
1121 | return retval; | 1127 | return retval; |
1122 | switch (arg) { | 1128 | switch (arg) { |
1123 | case TCOOFF: | 1129 | case TCOOFF: |
1124 | spin_lock_irq(&tty->flow_lock); | 1130 | spin_lock_irq(&tty->flow_lock); |
1125 | if (!tty->flow_stopped) { | 1131 | if (!tty->flow_stopped) { |
1126 | tty->flow_stopped = 1; | 1132 | tty->flow_stopped = 1; |
1127 | __stop_tty(tty); | 1133 | __stop_tty(tty); |
1128 | } | 1134 | } |
1129 | spin_unlock_irq(&tty->flow_lock); | 1135 | spin_unlock_irq(&tty->flow_lock); |
1130 | break; | 1136 | break; |
1131 | case TCOON: | 1137 | case TCOON: |
1132 | spin_lock_irq(&tty->flow_lock); | 1138 | spin_lock_irq(&tty->flow_lock); |
1133 | if (tty->flow_stopped) { | 1139 | if (tty->flow_stopped) { |
1134 | tty->flow_stopped = 0; | 1140 | tty->flow_stopped = 0; |
1135 | __start_tty(tty); | 1141 | __start_tty(tty); |
1136 | } | 1142 | } |
1137 | spin_unlock_irq(&tty->flow_lock); | 1143 | spin_unlock_irq(&tty->flow_lock); |
1138 | break; | 1144 | break; |
1139 | case TCIOFF: | 1145 | case TCIOFF: |
1140 | down_read(&tty->termios_rwsem); | 1146 | down_read(&tty->termios_rwsem); |
1141 | if (STOP_CHAR(tty) != __DISABLED_CHAR) | 1147 | if (STOP_CHAR(tty) != __DISABLED_CHAR) |
1142 | retval = tty_send_xchar(tty, STOP_CHAR(tty)); | 1148 | retval = tty_send_xchar(tty, STOP_CHAR(tty)); |
1143 | up_read(&tty->termios_rwsem); | 1149 | up_read(&tty->termios_rwsem); |
1144 | break; | 1150 | break; |
1145 | case TCION: | 1151 | case TCION: |
1146 | down_read(&tty->termios_rwsem); | 1152 | down_read(&tty->termios_rwsem); |
1147 | if (START_CHAR(tty) != __DISABLED_CHAR) | 1153 | if (START_CHAR(tty) != __DISABLED_CHAR) |
1148 | retval = tty_send_xchar(tty, START_CHAR(tty)); | 1154 | retval = tty_send_xchar(tty, START_CHAR(tty)); |
1149 | up_read(&tty->termios_rwsem); | 1155 | up_read(&tty->termios_rwsem); |
1150 | break; | 1156 | break; |
1151 | default: | 1157 | default: |
1152 | return -EINVAL; | 1158 | return -EINVAL; |
1153 | } | 1159 | } |
1154 | return retval; | 1160 | return retval; |
1155 | case TCFLSH: | 1161 | case TCFLSH: |
1156 | retval = tty_check_change(tty); | 1162 | retval = tty_check_change(tty); |
1157 | if (retval) | 1163 | if (retval) |
1158 | return retval; | 1164 | return retval; |
1159 | return __tty_perform_flush(tty, arg); | 1165 | return __tty_perform_flush(tty, arg); |
1160 | default: | 1166 | default: |
1161 | /* Try the mode commands */ | 1167 | /* Try the mode commands */ |
1162 | return tty_mode_ioctl(tty, file, cmd, arg); | 1168 | return tty_mode_ioctl(tty, file, cmd, arg); |
1163 | } | 1169 | } |
1164 | } | 1170 | } |
1165 | EXPORT_SYMBOL(n_tty_ioctl_helper); | 1171 | EXPORT_SYMBOL(n_tty_ioctl_helper); |
1166 | 1172 | ||
1167 | #ifdef CONFIG_COMPAT | 1173 | #ifdef CONFIG_COMPAT |
1168 | long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file, | 1174 | long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file, |
1169 | unsigned int cmd, unsigned long arg) | 1175 | unsigned int cmd, unsigned long arg) |
1170 | { | 1176 | { |
1171 | switch (cmd) { | 1177 | switch (cmd) { |
1172 | case TIOCGLCKTRMIOS: | 1178 | case TIOCGLCKTRMIOS: |
1173 | case TIOCSLCKTRMIOS: | 1179 | case TIOCSLCKTRMIOS: |
1174 | return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg)); | 1180 | return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg)); |
1175 | default: | 1181 | default: |
1176 | return -ENOIOCTLCMD; | 1182 | return -ENOIOCTLCMD; |
1177 | } | 1183 | } |
1178 | } | 1184 | } |
1179 | EXPORT_SYMBOL(n_tty_compat_ioctl_helper); | 1185 | EXPORT_SYMBOL(n_tty_compat_ioctl_helper); |
1180 | #endif | 1186 | #endif |
1181 | 1187 | ||
1182 | 1188 |
drivers/usb/serial/generic.c
1 | /* | 1 | /* |
2 | * USB Serial Converter Generic functions | 2 | * USB Serial Converter Generic functions |
3 | * | 3 | * |
4 | * Copyright (C) 2010 - 2013 Johan Hovold (jhovold@gmail.com) | 4 | * Copyright (C) 2010 - 2013 Johan Hovold (jhovold@gmail.com) |
5 | * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) | 5 | * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License version | 8 | * modify it under the terms of the GNU General Public License version |
9 | * 2 as published by the Free Software Foundation. | 9 | * 2 as published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/sysrq.h> | 15 | #include <linux/sysrq.h> |
16 | #include <linux/tty.h> | 16 | #include <linux/tty.h> |
17 | #include <linux/tty_flip.h> | 17 | #include <linux/tty_flip.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
20 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
21 | #include <linux/usb/serial.h> | 21 | #include <linux/usb/serial.h> |
22 | #include <linux/uaccess.h> | 22 | #include <linux/uaccess.h> |
23 | #include <linux/kfifo.h> | 23 | #include <linux/kfifo.h> |
24 | #include <linux/serial.h> | 24 | #include <linux/serial.h> |
25 | 25 | ||
26 | #ifdef CONFIG_USB_SERIAL_GENERIC | 26 | #ifdef CONFIG_USB_SERIAL_GENERIC |
27 | 27 | ||
28 | static __u16 vendor = 0x05f9; | 28 | static __u16 vendor = 0x05f9; |
29 | static __u16 product = 0xffff; | 29 | static __u16 product = 0xffff; |
30 | 30 | ||
31 | module_param(vendor, ushort, 0); | 31 | module_param(vendor, ushort, 0); |
32 | MODULE_PARM_DESC(vendor, "User specified USB idVendor"); | 32 | MODULE_PARM_DESC(vendor, "User specified USB idVendor"); |
33 | 33 | ||
34 | module_param(product, ushort, 0); | 34 | module_param(product, ushort, 0); |
35 | MODULE_PARM_DESC(product, "User specified USB idProduct"); | 35 | MODULE_PARM_DESC(product, "User specified USB idProduct"); |
36 | 36 | ||
37 | static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ | 37 | static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ |
38 | 38 | ||
39 | struct usb_serial_driver usb_serial_generic_device = { | 39 | struct usb_serial_driver usb_serial_generic_device = { |
40 | .driver = { | 40 | .driver = { |
41 | .owner = THIS_MODULE, | 41 | .owner = THIS_MODULE, |
42 | .name = "generic", | 42 | .name = "generic", |
43 | }, | 43 | }, |
44 | .id_table = generic_device_ids, | 44 | .id_table = generic_device_ids, |
45 | .num_ports = 1, | 45 | .num_ports = 1, |
46 | .throttle = usb_serial_generic_throttle, | 46 | .throttle = usb_serial_generic_throttle, |
47 | .unthrottle = usb_serial_generic_unthrottle, | 47 | .unthrottle = usb_serial_generic_unthrottle, |
48 | .resume = usb_serial_generic_resume, | 48 | .resume = usb_serial_generic_resume, |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static struct usb_serial_driver * const serial_drivers[] = { | 51 | static struct usb_serial_driver * const serial_drivers[] = { |
52 | &usb_serial_generic_device, NULL | 52 | &usb_serial_generic_device, NULL |
53 | }; | 53 | }; |
54 | 54 | ||
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | int usb_serial_generic_register(void) | 57 | int usb_serial_generic_register(void) |
58 | { | 58 | { |
59 | int retval = 0; | 59 | int retval = 0; |
60 | 60 | ||
61 | #ifdef CONFIG_USB_SERIAL_GENERIC | 61 | #ifdef CONFIG_USB_SERIAL_GENERIC |
62 | generic_device_ids[0].idVendor = vendor; | 62 | generic_device_ids[0].idVendor = vendor; |
63 | generic_device_ids[0].idProduct = product; | 63 | generic_device_ids[0].idProduct = product; |
64 | generic_device_ids[0].match_flags = | 64 | generic_device_ids[0].match_flags = |
65 | USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; | 65 | USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; |
66 | 66 | ||
67 | retval = usb_serial_register_drivers(serial_drivers, | 67 | retval = usb_serial_register_drivers(serial_drivers, |
68 | "usbserial_generic", generic_device_ids); | 68 | "usbserial_generic", generic_device_ids); |
69 | #endif | 69 | #endif |
70 | return retval; | 70 | return retval; |
71 | } | 71 | } |
72 | 72 | ||
73 | void usb_serial_generic_deregister(void) | 73 | void usb_serial_generic_deregister(void) |
74 | { | 74 | { |
75 | #ifdef CONFIG_USB_SERIAL_GENERIC | 75 | #ifdef CONFIG_USB_SERIAL_GENERIC |
76 | usb_serial_deregister_drivers(serial_drivers); | 76 | usb_serial_deregister_drivers(serial_drivers); |
77 | #endif | 77 | #endif |
78 | } | 78 | } |
79 | 79 | ||
80 | int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port) | 80 | int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port) |
81 | { | 81 | { |
82 | int result = 0; | 82 | int result = 0; |
83 | unsigned long flags; | 83 | unsigned long flags; |
84 | 84 | ||
85 | spin_lock_irqsave(&port->lock, flags); | 85 | spin_lock_irqsave(&port->lock, flags); |
86 | port->throttled = 0; | 86 | port->throttled = 0; |
87 | port->throttle_req = 0; | 87 | port->throttle_req = 0; |
88 | spin_unlock_irqrestore(&port->lock, flags); | 88 | spin_unlock_irqrestore(&port->lock, flags); |
89 | 89 | ||
90 | if (port->bulk_in_size) | 90 | if (port->bulk_in_size) |
91 | result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL); | 91 | result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL); |
92 | 92 | ||
93 | return result; | 93 | return result; |
94 | } | 94 | } |
95 | EXPORT_SYMBOL_GPL(usb_serial_generic_open); | 95 | EXPORT_SYMBOL_GPL(usb_serial_generic_open); |
96 | 96 | ||
97 | void usb_serial_generic_close(struct usb_serial_port *port) | 97 | void usb_serial_generic_close(struct usb_serial_port *port) |
98 | { | 98 | { |
99 | unsigned long flags; | 99 | unsigned long flags; |
100 | int i; | 100 | int i; |
101 | 101 | ||
102 | if (port->bulk_out_size) { | 102 | if (port->bulk_out_size) { |
103 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) | 103 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) |
104 | usb_kill_urb(port->write_urbs[i]); | 104 | usb_kill_urb(port->write_urbs[i]); |
105 | 105 | ||
106 | spin_lock_irqsave(&port->lock, flags); | 106 | spin_lock_irqsave(&port->lock, flags); |
107 | kfifo_reset_out(&port->write_fifo); | 107 | kfifo_reset_out(&port->write_fifo); |
108 | spin_unlock_irqrestore(&port->lock, flags); | 108 | spin_unlock_irqrestore(&port->lock, flags); |
109 | } | 109 | } |
110 | if (port->bulk_in_size) { | 110 | if (port->bulk_in_size) { |
111 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) | 111 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) |
112 | usb_kill_urb(port->read_urbs[i]); | 112 | usb_kill_urb(port->read_urbs[i]); |
113 | } | 113 | } |
114 | } | 114 | } |
115 | EXPORT_SYMBOL_GPL(usb_serial_generic_close); | 115 | EXPORT_SYMBOL_GPL(usb_serial_generic_close); |
116 | 116 | ||
117 | int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, | 117 | int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, |
118 | void *dest, size_t size) | 118 | void *dest, size_t size) |
119 | { | 119 | { |
120 | return kfifo_out_locked(&port->write_fifo, dest, size, &port->lock); | 120 | return kfifo_out_locked(&port->write_fifo, dest, size, &port->lock); |
121 | } | 121 | } |
122 | 122 | ||
123 | /** | 123 | /** |
124 | * usb_serial_generic_write_start - start writing buffered data | 124 | * usb_serial_generic_write_start - start writing buffered data |
125 | * @port: usb-serial port | 125 | * @port: usb-serial port |
126 | * @mem_flags: flags to use for memory allocations | 126 | * @mem_flags: flags to use for memory allocations |
127 | * | 127 | * |
128 | * Serialised using USB_SERIAL_WRITE_BUSY flag. | 128 | * Serialised using USB_SERIAL_WRITE_BUSY flag. |
129 | * | 129 | * |
130 | * Return: Zero on success or if busy, otherwise a negative errno value. | 130 | * Return: Zero on success or if busy, otherwise a negative errno value. |
131 | */ | 131 | */ |
132 | int usb_serial_generic_write_start(struct usb_serial_port *port, | 132 | int usb_serial_generic_write_start(struct usb_serial_port *port, |
133 | gfp_t mem_flags) | 133 | gfp_t mem_flags) |
134 | { | 134 | { |
135 | struct urb *urb; | 135 | struct urb *urb; |
136 | int count, result; | 136 | int count, result; |
137 | unsigned long flags; | 137 | unsigned long flags; |
138 | int i; | 138 | int i; |
139 | 139 | ||
140 | if (test_and_set_bit_lock(USB_SERIAL_WRITE_BUSY, &port->flags)) | 140 | if (test_and_set_bit_lock(USB_SERIAL_WRITE_BUSY, &port->flags)) |
141 | return 0; | 141 | return 0; |
142 | retry: | 142 | retry: |
143 | spin_lock_irqsave(&port->lock, flags); | 143 | spin_lock_irqsave(&port->lock, flags); |
144 | if (!port->write_urbs_free || !kfifo_len(&port->write_fifo)) { | 144 | if (!port->write_urbs_free || !kfifo_len(&port->write_fifo)) { |
145 | clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); | 145 | clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); |
146 | spin_unlock_irqrestore(&port->lock, flags); | 146 | spin_unlock_irqrestore(&port->lock, flags); |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | i = (int)find_first_bit(&port->write_urbs_free, | 149 | i = (int)find_first_bit(&port->write_urbs_free, |
150 | ARRAY_SIZE(port->write_urbs)); | 150 | ARRAY_SIZE(port->write_urbs)); |
151 | spin_unlock_irqrestore(&port->lock, flags); | 151 | spin_unlock_irqrestore(&port->lock, flags); |
152 | 152 | ||
153 | urb = port->write_urbs[i]; | 153 | urb = port->write_urbs[i]; |
154 | count = port->serial->type->prepare_write_buffer(port, | 154 | count = port->serial->type->prepare_write_buffer(port, |
155 | urb->transfer_buffer, | 155 | urb->transfer_buffer, |
156 | port->bulk_out_size); | 156 | port->bulk_out_size); |
157 | urb->transfer_buffer_length = count; | 157 | urb->transfer_buffer_length = count; |
158 | usb_serial_debug_data(&port->dev, __func__, count, urb->transfer_buffer); | 158 | usb_serial_debug_data(&port->dev, __func__, count, urb->transfer_buffer); |
159 | spin_lock_irqsave(&port->lock, flags); | 159 | spin_lock_irqsave(&port->lock, flags); |
160 | port->tx_bytes += count; | 160 | port->tx_bytes += count; |
161 | spin_unlock_irqrestore(&port->lock, flags); | 161 | spin_unlock_irqrestore(&port->lock, flags); |
162 | 162 | ||
163 | clear_bit(i, &port->write_urbs_free); | 163 | clear_bit(i, &port->write_urbs_free); |
164 | result = usb_submit_urb(urb, mem_flags); | 164 | result = usb_submit_urb(urb, mem_flags); |
165 | if (result) { | 165 | if (result) { |
166 | dev_err_console(port, "%s - error submitting urb: %d\n", | 166 | dev_err_console(port, "%s - error submitting urb: %d\n", |
167 | __func__, result); | 167 | __func__, result); |
168 | set_bit(i, &port->write_urbs_free); | 168 | set_bit(i, &port->write_urbs_free); |
169 | spin_lock_irqsave(&port->lock, flags); | 169 | spin_lock_irqsave(&port->lock, flags); |
170 | port->tx_bytes -= count; | 170 | port->tx_bytes -= count; |
171 | spin_unlock_irqrestore(&port->lock, flags); | 171 | spin_unlock_irqrestore(&port->lock, flags); |
172 | 172 | ||
173 | clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); | 173 | clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); |
174 | return result; | 174 | return result; |
175 | } | 175 | } |
176 | 176 | ||
177 | goto retry; /* try sending off another urb */ | 177 | goto retry; /* try sending off another urb */ |
178 | } | 178 | } |
179 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_start); | 179 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_start); |
180 | 180 | ||
181 | /** | 181 | /** |
182 | * usb_serial_generic_write - generic write function | 182 | * usb_serial_generic_write - generic write function |
183 | * @tty: tty for the port | 183 | * @tty: tty for the port |
184 | * @port: usb-serial port | 184 | * @port: usb-serial port |
185 | * @buf: data to write | 185 | * @buf: data to write |
186 | * @count: number of bytes to write | 186 | * @count: number of bytes to write |
187 | * | 187 | * |
188 | * Return: The number of characters buffered, which may be anything from | 188 | * Return: The number of characters buffered, which may be anything from |
189 | * zero to @count, or a negative errno value. | 189 | * zero to @count, or a negative errno value. |
190 | */ | 190 | */ |
191 | int usb_serial_generic_write(struct tty_struct *tty, | 191 | int usb_serial_generic_write(struct tty_struct *tty, |
192 | struct usb_serial_port *port, const unsigned char *buf, int count) | 192 | struct usb_serial_port *port, const unsigned char *buf, int count) |
193 | { | 193 | { |
194 | int result; | 194 | int result; |
195 | 195 | ||
196 | if (!port->bulk_out_size) | 196 | if (!port->bulk_out_size) |
197 | return -ENODEV; | 197 | return -ENODEV; |
198 | 198 | ||
199 | if (!count) | 199 | if (!count) |
200 | return 0; | 200 | return 0; |
201 | 201 | ||
202 | count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); | 202 | count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); |
203 | result = usb_serial_generic_write_start(port, GFP_ATOMIC); | 203 | result = usb_serial_generic_write_start(port, GFP_ATOMIC); |
204 | if (result) | 204 | if (result) |
205 | return result; | 205 | return result; |
206 | 206 | ||
207 | return count; | 207 | return count; |
208 | } | 208 | } |
209 | EXPORT_SYMBOL_GPL(usb_serial_generic_write); | 209 | EXPORT_SYMBOL_GPL(usb_serial_generic_write); |
210 | 210 | ||
211 | int usb_serial_generic_write_room(struct tty_struct *tty) | 211 | int usb_serial_generic_write_room(struct tty_struct *tty) |
212 | { | 212 | { |
213 | struct usb_serial_port *port = tty->driver_data; | 213 | struct usb_serial_port *port = tty->driver_data; |
214 | unsigned long flags; | 214 | unsigned long flags; |
215 | int room; | 215 | int room; |
216 | 216 | ||
217 | if (!port->bulk_out_size) | 217 | if (!port->bulk_out_size) |
218 | return 0; | 218 | return 0; |
219 | 219 | ||
220 | spin_lock_irqsave(&port->lock, flags); | 220 | spin_lock_irqsave(&port->lock, flags); |
221 | room = kfifo_avail(&port->write_fifo); | 221 | room = kfifo_avail(&port->write_fifo); |
222 | spin_unlock_irqrestore(&port->lock, flags); | 222 | spin_unlock_irqrestore(&port->lock, flags); |
223 | 223 | ||
224 | dev_dbg(&port->dev, "%s - returns %d\n", __func__, room); | 224 | dev_dbg(&port->dev, "%s - returns %d\n", __func__, room); |
225 | return room; | 225 | return room; |
226 | } | 226 | } |
227 | 227 | ||
228 | int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | 228 | int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) |
229 | { | 229 | { |
230 | struct usb_serial_port *port = tty->driver_data; | 230 | struct usb_serial_port *port = tty->driver_data; |
231 | unsigned long flags; | 231 | unsigned long flags; |
232 | int chars; | 232 | int chars; |
233 | 233 | ||
234 | if (!port->bulk_out_size) | 234 | if (!port->bulk_out_size) |
235 | return 0; | 235 | return 0; |
236 | 236 | ||
237 | spin_lock_irqsave(&port->lock, flags); | 237 | spin_lock_irqsave(&port->lock, flags); |
238 | chars = kfifo_len(&port->write_fifo) + port->tx_bytes; | 238 | chars = kfifo_len(&port->write_fifo) + port->tx_bytes; |
239 | spin_unlock_irqrestore(&port->lock, flags); | 239 | spin_unlock_irqrestore(&port->lock, flags); |
240 | 240 | ||
241 | dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); | 241 | dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); |
242 | return chars; | 242 | return chars; |
243 | } | 243 | } |
244 | EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer); | 244 | EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer); |
245 | 245 | ||
246 | void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout) | 246 | void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout) |
247 | { | 247 | { |
248 | struct usb_serial_port *port = tty->driver_data; | 248 | struct usb_serial_port *port = tty->driver_data; |
249 | unsigned int bps; | 249 | unsigned int bps; |
250 | unsigned long period; | 250 | unsigned long period; |
251 | unsigned long expire; | 251 | unsigned long expire; |
252 | 252 | ||
253 | bps = tty_get_baud_rate(tty); | 253 | bps = tty_get_baud_rate(tty); |
254 | if (!bps) | 254 | if (!bps) |
255 | bps = 9600; /* B0 */ | 255 | bps = 9600; /* B0 */ |
256 | /* | 256 | /* |
257 | * Use a poll-period of roughly the time it takes to send one | 257 | * Use a poll-period of roughly the time it takes to send one |
258 | * character or at least one jiffy. | 258 | * character or at least one jiffy. |
259 | */ | 259 | */ |
260 | period = max_t(unsigned long, (10 * HZ / bps), 1); | 260 | period = max_t(unsigned long, (10 * HZ / bps), 1); |
261 | period = min_t(unsigned long, period, timeout); | 261 | if (timeout) |
262 | period = min_t(unsigned long, period, timeout); | ||
262 | 263 | ||
263 | dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n", | 264 | dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n", |
264 | __func__, jiffies_to_msecs(timeout), | 265 | __func__, jiffies_to_msecs(timeout), |
265 | jiffies_to_msecs(period)); | 266 | jiffies_to_msecs(period)); |
266 | expire = jiffies + timeout; | 267 | expire = jiffies + timeout; |
267 | while (!port->serial->type->tx_empty(port)) { | 268 | while (!port->serial->type->tx_empty(port)) { |
268 | schedule_timeout_interruptible(period); | 269 | schedule_timeout_interruptible(period); |
269 | if (signal_pending(current)) | 270 | if (signal_pending(current)) |
270 | break; | 271 | break; |
271 | if (time_after(jiffies, expire)) | 272 | if (timeout && time_after(jiffies, expire)) |
272 | break; | 273 | break; |
273 | } | 274 | } |
274 | } | 275 | } |
275 | EXPORT_SYMBOL_GPL(usb_serial_generic_wait_until_sent); | 276 | EXPORT_SYMBOL_GPL(usb_serial_generic_wait_until_sent); |
276 | 277 | ||
277 | static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, | 278 | static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, |
278 | int index, gfp_t mem_flags) | 279 | int index, gfp_t mem_flags) |
279 | { | 280 | { |
280 | int res; | 281 | int res; |
281 | 282 | ||
282 | if (!test_and_clear_bit(index, &port->read_urbs_free)) | 283 | if (!test_and_clear_bit(index, &port->read_urbs_free)) |
283 | return 0; | 284 | return 0; |
284 | 285 | ||
285 | dev_dbg(&port->dev, "%s - urb %d\n", __func__, index); | 286 | dev_dbg(&port->dev, "%s - urb %d\n", __func__, index); |
286 | 287 | ||
287 | res = usb_submit_urb(port->read_urbs[index], mem_flags); | 288 | res = usb_submit_urb(port->read_urbs[index], mem_flags); |
288 | if (res) { | 289 | if (res) { |
289 | if (res != -EPERM && res != -ENODEV) { | 290 | if (res != -EPERM && res != -ENODEV) { |
290 | dev_err(&port->dev, | 291 | dev_err(&port->dev, |
291 | "%s - usb_submit_urb failed: %d\n", | 292 | "%s - usb_submit_urb failed: %d\n", |
292 | __func__, res); | 293 | __func__, res); |
293 | } | 294 | } |
294 | set_bit(index, &port->read_urbs_free); | 295 | set_bit(index, &port->read_urbs_free); |
295 | return res; | 296 | return res; |
296 | } | 297 | } |
297 | 298 | ||
298 | return 0; | 299 | return 0; |
299 | } | 300 | } |
300 | 301 | ||
301 | int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, | 302 | int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, |
302 | gfp_t mem_flags) | 303 | gfp_t mem_flags) |
303 | { | 304 | { |
304 | int res; | 305 | int res; |
305 | int i; | 306 | int i; |
306 | 307 | ||
307 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { | 308 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { |
308 | res = usb_serial_generic_submit_read_urb(port, i, mem_flags); | 309 | res = usb_serial_generic_submit_read_urb(port, i, mem_flags); |
309 | if (res) | 310 | if (res) |
310 | goto err; | 311 | goto err; |
311 | } | 312 | } |
312 | 313 | ||
313 | return 0; | 314 | return 0; |
314 | err: | 315 | err: |
315 | for (; i >= 0; --i) | 316 | for (; i >= 0; --i) |
316 | usb_kill_urb(port->read_urbs[i]); | 317 | usb_kill_urb(port->read_urbs[i]); |
317 | 318 | ||
318 | return res; | 319 | return res; |
319 | } | 320 | } |
320 | EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs); | 321 | EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs); |
321 | 322 | ||
322 | void usb_serial_generic_process_read_urb(struct urb *urb) | 323 | void usb_serial_generic_process_read_urb(struct urb *urb) |
323 | { | 324 | { |
324 | struct usb_serial_port *port = urb->context; | 325 | struct usb_serial_port *port = urb->context; |
325 | char *ch = (char *)urb->transfer_buffer; | 326 | char *ch = (char *)urb->transfer_buffer; |
326 | int i; | 327 | int i; |
327 | 328 | ||
328 | if (!urb->actual_length) | 329 | if (!urb->actual_length) |
329 | return; | 330 | return; |
330 | /* | 331 | /* |
331 | * The per character mucking around with sysrq path it too slow for | 332 | * The per character mucking around with sysrq path it too slow for |
332 | * stuff like 3G modems, so shortcircuit it in the 99.9999999% of | 333 | * stuff like 3G modems, so shortcircuit it in the 99.9999999% of |
333 | * cases where the USB serial is not a console anyway. | 334 | * cases where the USB serial is not a console anyway. |
334 | */ | 335 | */ |
335 | if (!port->port.console || !port->sysrq) { | 336 | if (!port->port.console || !port->sysrq) { |
336 | tty_insert_flip_string(&port->port, ch, urb->actual_length); | 337 | tty_insert_flip_string(&port->port, ch, urb->actual_length); |
337 | } else { | 338 | } else { |
338 | for (i = 0; i < urb->actual_length; i++, ch++) { | 339 | for (i = 0; i < urb->actual_length; i++, ch++) { |
339 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 340 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
340 | tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); | 341 | tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); |
341 | } | 342 | } |
342 | } | 343 | } |
343 | tty_flip_buffer_push(&port->port); | 344 | tty_flip_buffer_push(&port->port); |
344 | } | 345 | } |
345 | EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb); | 346 | EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb); |
346 | 347 | ||
347 | void usb_serial_generic_read_bulk_callback(struct urb *urb) | 348 | void usb_serial_generic_read_bulk_callback(struct urb *urb) |
348 | { | 349 | { |
349 | struct usb_serial_port *port = urb->context; | 350 | struct usb_serial_port *port = urb->context; |
350 | unsigned char *data = urb->transfer_buffer; | 351 | unsigned char *data = urb->transfer_buffer; |
351 | unsigned long flags; | 352 | unsigned long flags; |
352 | int i; | 353 | int i; |
353 | 354 | ||
354 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { | 355 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { |
355 | if (urb == port->read_urbs[i]) | 356 | if (urb == port->read_urbs[i]) |
356 | break; | 357 | break; |
357 | } | 358 | } |
358 | set_bit(i, &port->read_urbs_free); | 359 | set_bit(i, &port->read_urbs_free); |
359 | 360 | ||
360 | dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i, | 361 | dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i, |
361 | urb->actual_length); | 362 | urb->actual_length); |
362 | switch (urb->status) { | 363 | switch (urb->status) { |
363 | case 0: | 364 | case 0: |
364 | break; | 365 | break; |
365 | case -ENOENT: | 366 | case -ENOENT: |
366 | case -ECONNRESET: | 367 | case -ECONNRESET: |
367 | case -ESHUTDOWN: | 368 | case -ESHUTDOWN: |
368 | dev_dbg(&port->dev, "%s - urb stopped: %d\n", | 369 | dev_dbg(&port->dev, "%s - urb stopped: %d\n", |
369 | __func__, urb->status); | 370 | __func__, urb->status); |
370 | return; | 371 | return; |
371 | case -EPIPE: | 372 | case -EPIPE: |
372 | dev_err(&port->dev, "%s - urb stopped: %d\n", | 373 | dev_err(&port->dev, "%s - urb stopped: %d\n", |
373 | __func__, urb->status); | 374 | __func__, urb->status); |
374 | return; | 375 | return; |
375 | default: | 376 | default: |
376 | dev_dbg(&port->dev, "%s - nonzero urb status: %d\n", | 377 | dev_dbg(&port->dev, "%s - nonzero urb status: %d\n", |
377 | __func__, urb->status); | 378 | __func__, urb->status); |
378 | goto resubmit; | 379 | goto resubmit; |
379 | } | 380 | } |
380 | 381 | ||
381 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); | 382 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); |
382 | port->serial->type->process_read_urb(urb); | 383 | port->serial->type->process_read_urb(urb); |
383 | 384 | ||
384 | resubmit: | 385 | resubmit: |
385 | /* Throttle the device if requested by tty */ | 386 | /* Throttle the device if requested by tty */ |
386 | spin_lock_irqsave(&port->lock, flags); | 387 | spin_lock_irqsave(&port->lock, flags); |
387 | port->throttled = port->throttle_req; | 388 | port->throttled = port->throttle_req; |
388 | if (!port->throttled) { | 389 | if (!port->throttled) { |
389 | spin_unlock_irqrestore(&port->lock, flags); | 390 | spin_unlock_irqrestore(&port->lock, flags); |
390 | usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC); | 391 | usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC); |
391 | } else { | 392 | } else { |
392 | spin_unlock_irqrestore(&port->lock, flags); | 393 | spin_unlock_irqrestore(&port->lock, flags); |
393 | } | 394 | } |
394 | } | 395 | } |
395 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); | 396 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); |
396 | 397 | ||
397 | void usb_serial_generic_write_bulk_callback(struct urb *urb) | 398 | void usb_serial_generic_write_bulk_callback(struct urb *urb) |
398 | { | 399 | { |
399 | unsigned long flags; | 400 | unsigned long flags; |
400 | struct usb_serial_port *port = urb->context; | 401 | struct usb_serial_port *port = urb->context; |
401 | int i; | 402 | int i; |
402 | 403 | ||
403 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { | 404 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { |
404 | if (port->write_urbs[i] == urb) | 405 | if (port->write_urbs[i] == urb) |
405 | break; | 406 | break; |
406 | } | 407 | } |
407 | spin_lock_irqsave(&port->lock, flags); | 408 | spin_lock_irqsave(&port->lock, flags); |
408 | port->tx_bytes -= urb->transfer_buffer_length; | 409 | port->tx_bytes -= urb->transfer_buffer_length; |
409 | set_bit(i, &port->write_urbs_free); | 410 | set_bit(i, &port->write_urbs_free); |
410 | spin_unlock_irqrestore(&port->lock, flags); | 411 | spin_unlock_irqrestore(&port->lock, flags); |
411 | 412 | ||
412 | switch (urb->status) { | 413 | switch (urb->status) { |
413 | case 0: | 414 | case 0: |
414 | break; | 415 | break; |
415 | case -ENOENT: | 416 | case -ENOENT: |
416 | case -ECONNRESET: | 417 | case -ECONNRESET: |
417 | case -ESHUTDOWN: | 418 | case -ESHUTDOWN: |
418 | dev_dbg(&port->dev, "%s - urb stopped: %d\n", | 419 | dev_dbg(&port->dev, "%s - urb stopped: %d\n", |
419 | __func__, urb->status); | 420 | __func__, urb->status); |
420 | return; | 421 | return; |
421 | case -EPIPE: | 422 | case -EPIPE: |
422 | dev_err_console(port, "%s - urb stopped: %d\n", | 423 | dev_err_console(port, "%s - urb stopped: %d\n", |
423 | __func__, urb->status); | 424 | __func__, urb->status); |
424 | return; | 425 | return; |
425 | default: | 426 | default: |
426 | dev_err_console(port, "%s - nonzero urb status: %d\n", | 427 | dev_err_console(port, "%s - nonzero urb status: %d\n", |
427 | __func__, urb->status); | 428 | __func__, urb->status); |
428 | goto resubmit; | 429 | goto resubmit; |
429 | } | 430 | } |
430 | 431 | ||
431 | resubmit: | 432 | resubmit: |
432 | usb_serial_generic_write_start(port, GFP_ATOMIC); | 433 | usb_serial_generic_write_start(port, GFP_ATOMIC); |
433 | usb_serial_port_softint(port); | 434 | usb_serial_port_softint(port); |
434 | } | 435 | } |
435 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | 436 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |
436 | 437 | ||
437 | void usb_serial_generic_throttle(struct tty_struct *tty) | 438 | void usb_serial_generic_throttle(struct tty_struct *tty) |
438 | { | 439 | { |
439 | struct usb_serial_port *port = tty->driver_data; | 440 | struct usb_serial_port *port = tty->driver_data; |
440 | unsigned long flags; | 441 | unsigned long flags; |
441 | 442 | ||
442 | spin_lock_irqsave(&port->lock, flags); | 443 | spin_lock_irqsave(&port->lock, flags); |
443 | port->throttle_req = 1; | 444 | port->throttle_req = 1; |
444 | spin_unlock_irqrestore(&port->lock, flags); | 445 | spin_unlock_irqrestore(&port->lock, flags); |
445 | } | 446 | } |
446 | EXPORT_SYMBOL_GPL(usb_serial_generic_throttle); | 447 | EXPORT_SYMBOL_GPL(usb_serial_generic_throttle); |
447 | 448 | ||
448 | void usb_serial_generic_unthrottle(struct tty_struct *tty) | 449 | void usb_serial_generic_unthrottle(struct tty_struct *tty) |
449 | { | 450 | { |
450 | struct usb_serial_port *port = tty->driver_data; | 451 | struct usb_serial_port *port = tty->driver_data; |
451 | int was_throttled; | 452 | int was_throttled; |
452 | 453 | ||
453 | spin_lock_irq(&port->lock); | 454 | spin_lock_irq(&port->lock); |
454 | was_throttled = port->throttled; | 455 | was_throttled = port->throttled; |
455 | port->throttled = port->throttle_req = 0; | 456 | port->throttled = port->throttle_req = 0; |
456 | spin_unlock_irq(&port->lock); | 457 | spin_unlock_irq(&port->lock); |
457 | 458 | ||
458 | if (was_throttled) | 459 | if (was_throttled) |
459 | usb_serial_generic_submit_read_urbs(port, GFP_KERNEL); | 460 | usb_serial_generic_submit_read_urbs(port, GFP_KERNEL); |
460 | } | 461 | } |
461 | EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); | 462 | EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); |
462 | 463 | ||
463 | static bool usb_serial_generic_msr_changed(struct tty_struct *tty, | 464 | static bool usb_serial_generic_msr_changed(struct tty_struct *tty, |
464 | unsigned long arg, struct async_icount *cprev) | 465 | unsigned long arg, struct async_icount *cprev) |
465 | { | 466 | { |
466 | struct usb_serial_port *port = tty->driver_data; | 467 | struct usb_serial_port *port = tty->driver_data; |
467 | struct async_icount cnow; | 468 | struct async_icount cnow; |
468 | unsigned long flags; | 469 | unsigned long flags; |
469 | bool ret; | 470 | bool ret; |
470 | 471 | ||
471 | /* | 472 | /* |
472 | * Use tty-port initialised flag to detect all hangups including the | 473 | * Use tty-port initialised flag to detect all hangups including the |
473 | * one generated at USB-device disconnect. | 474 | * one generated at USB-device disconnect. |
474 | */ | 475 | */ |
475 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | 476 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) |
476 | return true; | 477 | return true; |
477 | 478 | ||
478 | spin_lock_irqsave(&port->lock, flags); | 479 | spin_lock_irqsave(&port->lock, flags); |
479 | cnow = port->icount; /* atomic copy*/ | 480 | cnow = port->icount; /* atomic copy*/ |
480 | spin_unlock_irqrestore(&port->lock, flags); | 481 | spin_unlock_irqrestore(&port->lock, flags); |
481 | 482 | ||
482 | ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) || | 483 | ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) || |
483 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) || | 484 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) || |
484 | ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) || | 485 | ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) || |
485 | ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts)); | 486 | ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts)); |
486 | 487 | ||
487 | *cprev = cnow; | 488 | *cprev = cnow; |
488 | 489 | ||
489 | return ret; | 490 | return ret; |
490 | } | 491 | } |
491 | 492 | ||
492 | int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg) | 493 | int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg) |
493 | { | 494 | { |
494 | struct usb_serial_port *port = tty->driver_data; | 495 | struct usb_serial_port *port = tty->driver_data; |
495 | struct async_icount cnow; | 496 | struct async_icount cnow; |
496 | unsigned long flags; | 497 | unsigned long flags; |
497 | int ret; | 498 | int ret; |
498 | 499 | ||
499 | spin_lock_irqsave(&port->lock, flags); | 500 | spin_lock_irqsave(&port->lock, flags); |
500 | cnow = port->icount; /* atomic copy */ | 501 | cnow = port->icount; /* atomic copy */ |
501 | spin_unlock_irqrestore(&port->lock, flags); | 502 | spin_unlock_irqrestore(&port->lock, flags); |
502 | 503 | ||
503 | ret = wait_event_interruptible(port->port.delta_msr_wait, | 504 | ret = wait_event_interruptible(port->port.delta_msr_wait, |
504 | usb_serial_generic_msr_changed(tty, arg, &cnow)); | 505 | usb_serial_generic_msr_changed(tty, arg, &cnow)); |
505 | if (!ret && !test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | 506 | if (!ret && !test_bit(ASYNCB_INITIALIZED, &port->port.flags)) |
506 | ret = -EIO; | 507 | ret = -EIO; |
507 | 508 | ||
508 | return ret; | 509 | return ret; |
509 | } | 510 | } |
510 | EXPORT_SYMBOL_GPL(usb_serial_generic_tiocmiwait); | 511 | EXPORT_SYMBOL_GPL(usb_serial_generic_tiocmiwait); |
511 | 512 | ||
512 | int usb_serial_generic_get_icount(struct tty_struct *tty, | 513 | int usb_serial_generic_get_icount(struct tty_struct *tty, |
513 | struct serial_icounter_struct *icount) | 514 | struct serial_icounter_struct *icount) |
514 | { | 515 | { |
515 | struct usb_serial_port *port = tty->driver_data; | 516 | struct usb_serial_port *port = tty->driver_data; |
516 | struct async_icount cnow; | 517 | struct async_icount cnow; |
517 | unsigned long flags; | 518 | unsigned long flags; |
518 | 519 | ||
519 | spin_lock_irqsave(&port->lock, flags); | 520 | spin_lock_irqsave(&port->lock, flags); |
520 | cnow = port->icount; /* atomic copy */ | 521 | cnow = port->icount; /* atomic copy */ |
521 | spin_unlock_irqrestore(&port->lock, flags); | 522 | spin_unlock_irqrestore(&port->lock, flags); |
522 | 523 | ||
523 | icount->cts = cnow.cts; | 524 | icount->cts = cnow.cts; |
524 | icount->dsr = cnow.dsr; | 525 | icount->dsr = cnow.dsr; |
525 | icount->rng = cnow.rng; | 526 | icount->rng = cnow.rng; |
526 | icount->dcd = cnow.dcd; | 527 | icount->dcd = cnow.dcd; |
527 | icount->tx = cnow.tx; | 528 | icount->tx = cnow.tx; |
528 | icount->rx = cnow.rx; | 529 | icount->rx = cnow.rx; |
529 | icount->frame = cnow.frame; | 530 | icount->frame = cnow.frame; |
530 | icount->parity = cnow.parity; | 531 | icount->parity = cnow.parity; |
531 | icount->overrun = cnow.overrun; | 532 | icount->overrun = cnow.overrun; |
532 | icount->brk = cnow.brk; | 533 | icount->brk = cnow.brk; |
533 | icount->buf_overrun = cnow.buf_overrun; | 534 | icount->buf_overrun = cnow.buf_overrun; |
534 | 535 | ||
535 | return 0; | 536 | return 0; |
536 | } | 537 | } |
537 | EXPORT_SYMBOL_GPL(usb_serial_generic_get_icount); | 538 | EXPORT_SYMBOL_GPL(usb_serial_generic_get_icount); |
538 | 539 | ||
539 | #ifdef CONFIG_MAGIC_SYSRQ | 540 | #ifdef CONFIG_MAGIC_SYSRQ |
540 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) | 541 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
541 | { | 542 | { |
542 | if (port->sysrq && port->port.console) { | 543 | if (port->sysrq && port->port.console) { |
543 | if (ch && time_before(jiffies, port->sysrq)) { | 544 | if (ch && time_before(jiffies, port->sysrq)) { |
544 | handle_sysrq(ch); | 545 | handle_sysrq(ch); |
545 | port->sysrq = 0; | 546 | port->sysrq = 0; |
546 | return 1; | 547 | return 1; |
547 | } | 548 | } |
548 | port->sysrq = 0; | 549 | port->sysrq = 0; |
549 | } | 550 | } |
550 | return 0; | 551 | return 0; |
551 | } | 552 | } |
552 | #else | 553 | #else |
553 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) | 554 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
554 | { | 555 | { |
555 | return 0; | 556 | return 0; |
556 | } | 557 | } |
557 | #endif | 558 | #endif |
558 | EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char); | 559 | EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char); |
559 | 560 | ||
560 | int usb_serial_handle_break(struct usb_serial_port *port) | 561 | int usb_serial_handle_break(struct usb_serial_port *port) |
561 | { | 562 | { |
562 | if (!port->sysrq) { | 563 | if (!port->sysrq) { |
563 | port->sysrq = jiffies + HZ*5; | 564 | port->sysrq = jiffies + HZ*5; |
564 | return 1; | 565 | return 1; |
565 | } | 566 | } |
566 | port->sysrq = 0; | 567 | port->sysrq = 0; |
567 | return 0; | 568 | return 0; |
568 | } | 569 | } |
569 | EXPORT_SYMBOL_GPL(usb_serial_handle_break); | 570 | EXPORT_SYMBOL_GPL(usb_serial_handle_break); |
570 | 571 | ||
571 | /** | 572 | /** |
572 | * usb_serial_handle_dcd_change - handle a change of carrier detect state | 573 | * usb_serial_handle_dcd_change - handle a change of carrier detect state |
573 | * @port: usb-serial port | 574 | * @port: usb-serial port |
574 | * @tty: tty for the port | 575 | * @tty: tty for the port |
575 | * @status: new carrier detect status, nonzero if active | 576 | * @status: new carrier detect status, nonzero if active |
576 | */ | 577 | */ |
577 | void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, | 578 | void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, |
578 | struct tty_struct *tty, unsigned int status) | 579 | struct tty_struct *tty, unsigned int status) |
579 | { | 580 | { |
580 | struct tty_port *port = &usb_port->port; | 581 | struct tty_port *port = &usb_port->port; |
581 | 582 | ||
582 | dev_dbg(&usb_port->dev, "%s - status %d\n", __func__, status); | 583 | dev_dbg(&usb_port->dev, "%s - status %d\n", __func__, status); |
583 | 584 | ||
584 | if (tty) { | 585 | if (tty) { |
585 | struct tty_ldisc *ld = tty_ldisc_ref(tty); | 586 | struct tty_ldisc *ld = tty_ldisc_ref(tty); |
586 | 587 | ||
587 | if (ld) { | 588 | if (ld) { |
588 | if (ld->ops->dcd_change) | 589 | if (ld->ops->dcd_change) |
589 | ld->ops->dcd_change(tty, status); | 590 | ld->ops->dcd_change(tty, status); |
590 | tty_ldisc_deref(ld); | 591 | tty_ldisc_deref(ld); |
591 | } | 592 | } |
592 | } | 593 | } |
593 | 594 | ||
594 | if (status) | 595 | if (status) |
595 | wake_up_interruptible(&port->open_wait); | 596 | wake_up_interruptible(&port->open_wait); |
596 | else if (tty && !C_CLOCAL(tty)) | 597 | else if (tty && !C_CLOCAL(tty)) |
597 | tty_hangup(tty); | 598 | tty_hangup(tty); |
598 | } | 599 | } |
599 | EXPORT_SYMBOL_GPL(usb_serial_handle_dcd_change); | 600 | EXPORT_SYMBOL_GPL(usb_serial_handle_dcd_change); |
600 | 601 | ||
601 | int usb_serial_generic_resume(struct usb_serial *serial) | 602 | int usb_serial_generic_resume(struct usb_serial *serial) |
602 | { | 603 | { |
603 | struct usb_serial_port *port; | 604 | struct usb_serial_port *port; |
604 | int i, c = 0, r; | 605 | int i, c = 0, r; |
605 | 606 | ||
606 | for (i = 0; i < serial->num_ports; i++) { | 607 | for (i = 0; i < serial->num_ports; i++) { |
607 | port = serial->port[i]; | 608 | port = serial->port[i]; |
608 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | 609 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) |
609 | continue; | 610 | continue; |
610 | 611 | ||
611 | if (port->bulk_in_size) { | 612 | if (port->bulk_in_size) { |
612 | r = usb_serial_generic_submit_read_urbs(port, | 613 | r = usb_serial_generic_submit_read_urbs(port, |
613 | GFP_NOIO); | 614 | GFP_NOIO); |
614 | if (r < 0) | 615 | if (r < 0) |
615 | c++; | 616 | c++; |
616 | } | 617 | } |
617 | 618 | ||
618 | if (port->bulk_out_size) { | 619 | if (port->bulk_out_size) { |
619 | r = usb_serial_generic_write_start(port, GFP_NOIO); | 620 | r = usb_serial_generic_write_start(port, GFP_NOIO); |
620 | if (r < 0) | 621 | if (r < 0) |
621 | c++; | 622 | c++; |
622 | } | 623 | } |
623 | } | 624 | } |
624 | 625 | ||
625 | return c ? -EIO : 0; | 626 | return c ? -EIO : 0; |
626 | } | 627 | } |
627 | EXPORT_SYMBOL_GPL(usb_serial_generic_resume); | 628 | EXPORT_SYMBOL_GPL(usb_serial_generic_resume); |
628 | 629 |
include/linux/serial_core.h
1 | /* | 1 | /* |
2 | * linux/drivers/char/serial_core.h | 2 | * linux/drivers/char/serial_core.h |
3 | * | 3 | * |
4 | * Copyright (C) 2000 Deep Blue Solutions Ltd. | 4 | * Copyright (C) 2000 Deep Blue Solutions Ltd. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #ifndef LINUX_SERIAL_CORE_H | 20 | #ifndef LINUX_SERIAL_CORE_H |
21 | #define LINUX_SERIAL_CORE_H | 21 | #define LINUX_SERIAL_CORE_H |
22 | 22 | ||
23 | 23 | ||
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/circ_buf.h> | 26 | #include <linux/circ_buf.h> |
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
29 | #include <linux/tty.h> | 29 | #include <linux/tty.h> |
30 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
31 | #include <linux/sysrq.h> | 31 | #include <linux/sysrq.h> |
32 | #include <uapi/linux/serial_core.h> | 32 | #include <uapi/linux/serial_core.h> |
33 | 33 | ||
34 | #ifdef CONFIG_SERIAL_CORE_CONSOLE | 34 | #ifdef CONFIG_SERIAL_CORE_CONSOLE |
35 | #define uart_console(port) \ | 35 | #define uart_console(port) \ |
36 | ((port)->cons && (port)->cons->index == (port)->line) | 36 | ((port)->cons && (port)->cons->index == (port)->line) |
37 | #else | 37 | #else |
38 | #define uart_console(port) (0) | 38 | #define uart_console(port) (0) |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | struct uart_port; | 41 | struct uart_port; |
42 | struct serial_struct; | 42 | struct serial_struct; |
43 | struct device; | 43 | struct device; |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * This structure describes all the operations that can be done on the | 46 | * This structure describes all the operations that can be done on the |
47 | * physical hardware. See Documentation/serial/driver for details. | 47 | * physical hardware. See Documentation/serial/driver for details. |
48 | */ | 48 | */ |
49 | struct uart_ops { | 49 | struct uart_ops { |
50 | unsigned int (*tx_empty)(struct uart_port *); | 50 | unsigned int (*tx_empty)(struct uart_port *); |
51 | void (*set_mctrl)(struct uart_port *, unsigned int mctrl); | 51 | void (*set_mctrl)(struct uart_port *, unsigned int mctrl); |
52 | unsigned int (*get_mctrl)(struct uart_port *); | 52 | unsigned int (*get_mctrl)(struct uart_port *); |
53 | void (*stop_tx)(struct uart_port *); | 53 | void (*stop_tx)(struct uart_port *); |
54 | void (*start_tx)(struct uart_port *); | 54 | void (*start_tx)(struct uart_port *); |
55 | void (*throttle)(struct uart_port *); | 55 | void (*throttle)(struct uart_port *); |
56 | void (*unthrottle)(struct uart_port *); | 56 | void (*unthrottle)(struct uart_port *); |
57 | void (*send_xchar)(struct uart_port *, char ch); | 57 | void (*send_xchar)(struct uart_port *, char ch); |
58 | void (*stop_rx)(struct uart_port *); | 58 | void (*stop_rx)(struct uart_port *); |
59 | void (*enable_ms)(struct uart_port *); | 59 | void (*enable_ms)(struct uart_port *); |
60 | void (*break_ctl)(struct uart_port *, int ctl); | 60 | void (*break_ctl)(struct uart_port *, int ctl); |
61 | int (*startup)(struct uart_port *); | 61 | int (*startup)(struct uart_port *); |
62 | void (*shutdown)(struct uart_port *); | 62 | void (*shutdown)(struct uart_port *); |
63 | void (*flush_buffer)(struct uart_port *); | 63 | void (*flush_buffer)(struct uart_port *); |
64 | void (*set_termios)(struct uart_port *, struct ktermios *new, | 64 | void (*set_termios)(struct uart_port *, struct ktermios *new, |
65 | struct ktermios *old); | 65 | struct ktermios *old); |
66 | void (*set_ldisc)(struct uart_port *, struct ktermios *); | 66 | void (*set_ldisc)(struct uart_port *, struct ktermios *); |
67 | void (*pm)(struct uart_port *, unsigned int state, | 67 | void (*pm)(struct uart_port *, unsigned int state, |
68 | unsigned int oldstate); | 68 | unsigned int oldstate); |
69 | 69 | ||
70 | /* | 70 | /* |
71 | * Return a string describing the type of the port | 71 | * Return a string describing the type of the port |
72 | */ | 72 | */ |
73 | const char *(*type)(struct uart_port *); | 73 | const char *(*type)(struct uart_port *); |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * Release IO and memory resources used by the port. | 76 | * Release IO and memory resources used by the port. |
77 | * This includes iounmap if necessary. | 77 | * This includes iounmap if necessary. |
78 | */ | 78 | */ |
79 | void (*release_port)(struct uart_port *); | 79 | void (*release_port)(struct uart_port *); |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * Request IO and memory resources used by the port. | 82 | * Request IO and memory resources used by the port. |
83 | * This includes iomapping the port if necessary. | 83 | * This includes iomapping the port if necessary. |
84 | */ | 84 | */ |
85 | int (*request_port)(struct uart_port *); | 85 | int (*request_port)(struct uart_port *); |
86 | void (*config_port)(struct uart_port *, int); | 86 | void (*config_port)(struct uart_port *, int); |
87 | int (*verify_port)(struct uart_port *, struct serial_struct *); | 87 | int (*verify_port)(struct uart_port *, struct serial_struct *); |
88 | int (*ioctl)(struct uart_port *, unsigned int, unsigned long); | 88 | int (*ioctl)(struct uart_port *, unsigned int, unsigned long); |
89 | #ifdef CONFIG_CONSOLE_POLL | 89 | #ifdef CONFIG_CONSOLE_POLL |
90 | int (*poll_init)(struct uart_port *); | 90 | int (*poll_init)(struct uart_port *); |
91 | void (*poll_put_char)(struct uart_port *, unsigned char); | 91 | void (*poll_put_char)(struct uart_port *, unsigned char); |
92 | int (*poll_get_char)(struct uart_port *); | 92 | int (*poll_get_char)(struct uart_port *); |
93 | #endif | 93 | #endif |
94 | }; | 94 | }; |
95 | 95 | ||
96 | #define NO_POLL_CHAR 0x00ff0000 | 96 | #define NO_POLL_CHAR 0x00ff0000 |
97 | #define UART_CONFIG_TYPE (1 << 0) | 97 | #define UART_CONFIG_TYPE (1 << 0) |
98 | #define UART_CONFIG_IRQ (1 << 1) | 98 | #define UART_CONFIG_IRQ (1 << 1) |
99 | 99 | ||
100 | struct uart_icount { | 100 | struct uart_icount { |
101 | __u32 cts; | 101 | __u32 cts; |
102 | __u32 dsr; | 102 | __u32 dsr; |
103 | __u32 rng; | 103 | __u32 rng; |
104 | __u32 dcd; | 104 | __u32 dcd; |
105 | __u32 rx; | 105 | __u32 rx; |
106 | __u32 tx; | 106 | __u32 tx; |
107 | __u32 frame; | 107 | __u32 frame; |
108 | __u32 overrun; | 108 | __u32 overrun; |
109 | __u32 parity; | 109 | __u32 parity; |
110 | __u32 brk; | 110 | __u32 brk; |
111 | __u32 buf_overrun; | 111 | __u32 buf_overrun; |
112 | }; | 112 | }; |
113 | 113 | ||
114 | typedef unsigned int __bitwise__ upf_t; | 114 | typedef unsigned int __bitwise__ upf_t; |
115 | typedef unsigned int __bitwise__ upstat_t; | 115 | typedef unsigned int __bitwise__ upstat_t; |
116 | 116 | ||
117 | struct uart_port { | 117 | struct uart_port { |
118 | spinlock_t lock; /* port lock */ | 118 | spinlock_t lock; /* port lock */ |
119 | unsigned long iobase; /* in/out[bwl] */ | 119 | unsigned long iobase; /* in/out[bwl] */ |
120 | unsigned char __iomem *membase; /* read/write[bwl] */ | 120 | unsigned char __iomem *membase; /* read/write[bwl] */ |
121 | unsigned int (*serial_in)(struct uart_port *, int); | 121 | unsigned int (*serial_in)(struct uart_port *, int); |
122 | void (*serial_out)(struct uart_port *, int, int); | 122 | void (*serial_out)(struct uart_port *, int, int); |
123 | void (*set_termios)(struct uart_port *, | 123 | void (*set_termios)(struct uart_port *, |
124 | struct ktermios *new, | 124 | struct ktermios *new, |
125 | struct ktermios *old); | 125 | struct ktermios *old); |
126 | void (*set_mctrl)(struct uart_port *, unsigned int); | 126 | void (*set_mctrl)(struct uart_port *, unsigned int); |
127 | int (*startup)(struct uart_port *port); | 127 | int (*startup)(struct uart_port *port); |
128 | void (*shutdown)(struct uart_port *port); | 128 | void (*shutdown)(struct uart_port *port); |
129 | void (*throttle)(struct uart_port *port); | 129 | void (*throttle)(struct uart_port *port); |
130 | void (*unthrottle)(struct uart_port *port); | 130 | void (*unthrottle)(struct uart_port *port); |
131 | int (*handle_irq)(struct uart_port *); | 131 | int (*handle_irq)(struct uart_port *); |
132 | void (*pm)(struct uart_port *, unsigned int state, | 132 | void (*pm)(struct uart_port *, unsigned int state, |
133 | unsigned int old); | 133 | unsigned int old); |
134 | void (*handle_break)(struct uart_port *); | 134 | void (*handle_break)(struct uart_port *); |
135 | int (*rs485_config)(struct uart_port *, | 135 | int (*rs485_config)(struct uart_port *, |
136 | struct serial_rs485 *rs485); | 136 | struct serial_rs485 *rs485); |
137 | unsigned int irq; /* irq number */ | 137 | unsigned int irq; /* irq number */ |
138 | unsigned long irqflags; /* irq flags */ | 138 | unsigned long irqflags; /* irq flags */ |
139 | unsigned int uartclk; /* base uart clock */ | 139 | unsigned int uartclk; /* base uart clock */ |
140 | unsigned int fifosize; /* tx fifo size */ | 140 | unsigned int fifosize; /* tx fifo size */ |
141 | unsigned char x_char; /* xon/xoff char */ | 141 | unsigned char x_char; /* xon/xoff char */ |
142 | unsigned char regshift; /* reg offset shift */ | 142 | unsigned char regshift; /* reg offset shift */ |
143 | unsigned char iotype; /* io access style */ | 143 | unsigned char iotype; /* io access style */ |
144 | unsigned char unused1; | 144 | unsigned char unused1; |
145 | 145 | ||
146 | #define UPIO_PORT (0) /* 8b I/O port access */ | 146 | #define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */ |
147 | #define UPIO_HUB6 (1) /* Hub6 ISA card */ | 147 | #define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */ |
148 | #define UPIO_MEM (2) /* 8b MMIO access */ | 148 | #define UPIO_MEM (SERIAL_IO_MEM) /* 8b MMIO access */ |
149 | #define UPIO_MEM32 (3) /* 32b little endian */ | 149 | #define UPIO_MEM32 (SERIAL_IO_MEM32) /* 32b little endian */ |
150 | #define UPIO_MEM32BE (4) /* 32b big endian */ | 150 | #define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */ |
151 | #define UPIO_AU (5) /* Au1x00 and RT288x type IO */ | 151 | #define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */ |
152 | #define UPIO_TSI (6) /* Tsi108/109 type IO */ | 152 | #define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */ |
153 | 153 | ||
154 | unsigned int read_status_mask; /* driver specific */ | 154 | unsigned int read_status_mask; /* driver specific */ |
155 | unsigned int ignore_status_mask; /* driver specific */ | 155 | unsigned int ignore_status_mask; /* driver specific */ |
156 | struct uart_state *state; /* pointer to parent state */ | 156 | struct uart_state *state; /* pointer to parent state */ |
157 | struct uart_icount icount; /* statistics */ | 157 | struct uart_icount icount; /* statistics */ |
158 | 158 | ||
159 | struct console *cons; /* struct console, if any */ | 159 | struct console *cons; /* struct console, if any */ |
160 | #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ) | 160 | #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ) |
161 | unsigned long sysrq; /* sysrq timeout */ | 161 | unsigned long sysrq; /* sysrq timeout */ |
162 | #endif | 162 | #endif |
163 | 163 | ||
164 | /* flags must be updated while holding port mutex */ | 164 | /* flags must be updated while holding port mutex */ |
165 | upf_t flags; | 165 | upf_t flags; |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * These flags must be equivalent to the flags defined in | 168 | * These flags must be equivalent to the flags defined in |
169 | * include/uapi/linux/tty_flags.h which are the userspace definitions | 169 | * include/uapi/linux/tty_flags.h which are the userspace definitions |
170 | * assigned from the serial_struct flags in uart_set_info() | 170 | * assigned from the serial_struct flags in uart_set_info() |
171 | * [for bit definitions in the UPF_CHANGE_MASK] | 171 | * [for bit definitions in the UPF_CHANGE_MASK] |
172 | * | 172 | * |
173 | * Bits [0..UPF_LAST_USER] are userspace defined/visible/changeable | 173 | * Bits [0..UPF_LAST_USER] are userspace defined/visible/changeable |
174 | * except bit 15 (UPF_NO_TXEN_TEST) which is masked off. | 174 | * except bit 15 (UPF_NO_TXEN_TEST) which is masked off. |
175 | * The remaining bits are serial-core specific and not modifiable by | 175 | * The remaining bits are serial-core specific and not modifiable by |
176 | * userspace. | 176 | * userspace. |
177 | */ | 177 | */ |
178 | #define UPF_FOURPORT ((__force upf_t) ASYNC_FOURPORT /* 1 */ ) | 178 | #define UPF_FOURPORT ((__force upf_t) ASYNC_FOURPORT /* 1 */ ) |
179 | #define UPF_SAK ((__force upf_t) ASYNC_SAK /* 2 */ ) | 179 | #define UPF_SAK ((__force upf_t) ASYNC_SAK /* 2 */ ) |
180 | #define UPF_SPD_HI ((__force upf_t) ASYNC_SPD_HI /* 4 */ ) | 180 | #define UPF_SPD_HI ((__force upf_t) ASYNC_SPD_HI /* 4 */ ) |
181 | #define UPF_SPD_VHI ((__force upf_t) ASYNC_SPD_VHI /* 5 */ ) | 181 | #define UPF_SPD_VHI ((__force upf_t) ASYNC_SPD_VHI /* 5 */ ) |
182 | #define UPF_SPD_CUST ((__force upf_t) ASYNC_SPD_CUST /* 0x0030 */ ) | 182 | #define UPF_SPD_CUST ((__force upf_t) ASYNC_SPD_CUST /* 0x0030 */ ) |
183 | #define UPF_SPD_WARP ((__force upf_t) ASYNC_SPD_WARP /* 0x1010 */ ) | 183 | #define UPF_SPD_WARP ((__force upf_t) ASYNC_SPD_WARP /* 0x1010 */ ) |
184 | #define UPF_SPD_MASK ((__force upf_t) ASYNC_SPD_MASK /* 0x1030 */ ) | 184 | #define UPF_SPD_MASK ((__force upf_t) ASYNC_SPD_MASK /* 0x1030 */ ) |
185 | #define UPF_SKIP_TEST ((__force upf_t) ASYNC_SKIP_TEST /* 6 */ ) | 185 | #define UPF_SKIP_TEST ((__force upf_t) ASYNC_SKIP_TEST /* 6 */ ) |
186 | #define UPF_AUTO_IRQ ((__force upf_t) ASYNC_AUTO_IRQ /* 7 */ ) | 186 | #define UPF_AUTO_IRQ ((__force upf_t) ASYNC_AUTO_IRQ /* 7 */ ) |
187 | #define UPF_HARDPPS_CD ((__force upf_t) ASYNC_HARDPPS_CD /* 11 */ ) | 187 | #define UPF_HARDPPS_CD ((__force upf_t) ASYNC_HARDPPS_CD /* 11 */ ) |
188 | #define UPF_SPD_SHI ((__force upf_t) ASYNC_SPD_SHI /* 12 */ ) | 188 | #define UPF_SPD_SHI ((__force upf_t) ASYNC_SPD_SHI /* 12 */ ) |
189 | #define UPF_LOW_LATENCY ((__force upf_t) ASYNC_LOW_LATENCY /* 13 */ ) | 189 | #define UPF_LOW_LATENCY ((__force upf_t) ASYNC_LOW_LATENCY /* 13 */ ) |
190 | #define UPF_BUGGY_UART ((__force upf_t) ASYNC_BUGGY_UART /* 14 */ ) | 190 | #define UPF_BUGGY_UART ((__force upf_t) ASYNC_BUGGY_UART /* 14 */ ) |
191 | #define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) | 191 | #define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) |
192 | #define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ ) | 192 | #define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ ) |
193 | 193 | ||
194 | /* Port has hardware-assisted h/w flow control */ | 194 | /* Port has hardware-assisted h/w flow control */ |
195 | #define UPF_AUTO_CTS ((__force upf_t) (1 << 20)) | 195 | #define UPF_AUTO_CTS ((__force upf_t) (1 << 20)) |
196 | #define UPF_AUTO_RTS ((__force upf_t) (1 << 21)) | 196 | #define UPF_AUTO_RTS ((__force upf_t) (1 << 21)) |
197 | #define UPF_HARD_FLOW ((__force upf_t) (UPF_AUTO_CTS | UPF_AUTO_RTS)) | 197 | #define UPF_HARD_FLOW ((__force upf_t) (UPF_AUTO_CTS | UPF_AUTO_RTS)) |
198 | /* Port has hardware-assisted s/w flow control */ | 198 | /* Port has hardware-assisted s/w flow control */ |
199 | #define UPF_SOFT_FLOW ((__force upf_t) (1 << 22)) | 199 | #define UPF_SOFT_FLOW ((__force upf_t) (1 << 22)) |
200 | #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) | 200 | #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) |
201 | #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) | 201 | #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) |
202 | #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) | 202 | #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) |
203 | #define UPF_BUG_THRE ((__force upf_t) (1 << 26)) | 203 | #define UPF_BUG_THRE ((__force upf_t) (1 << 26)) |
204 | /* The exact UART type is known and should not be probed. */ | 204 | /* The exact UART type is known and should not be probed. */ |
205 | #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) | 205 | #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) |
206 | #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) | 206 | #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) |
207 | #define UPF_FIXED_PORT ((__force upf_t) (1 << 29)) | 207 | #define UPF_FIXED_PORT ((__force upf_t) (1 << 29)) |
208 | #define UPF_DEAD ((__force upf_t) (1 << 30)) | 208 | #define UPF_DEAD ((__force upf_t) (1 << 30)) |
209 | #define UPF_IOREMAP ((__force upf_t) (1 << 31)) | 209 | #define UPF_IOREMAP ((__force upf_t) (1 << 31)) |
210 | 210 | ||
211 | #define __UPF_CHANGE_MASK 0x17fff | 211 | #define __UPF_CHANGE_MASK 0x17fff |
212 | #define UPF_CHANGE_MASK ((__force upf_t) __UPF_CHANGE_MASK) | 212 | #define UPF_CHANGE_MASK ((__force upf_t) __UPF_CHANGE_MASK) |
213 | #define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY)) | 213 | #define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY)) |
214 | 214 | ||
215 | #if __UPF_CHANGE_MASK > ASYNC_FLAGS | 215 | #if __UPF_CHANGE_MASK > ASYNC_FLAGS |
216 | #error Change mask not equivalent to userspace-visible bit defines | 216 | #error Change mask not equivalent to userspace-visible bit defines |
217 | #endif | 217 | #endif |
218 | 218 | ||
219 | /* | 219 | /* |
220 | * Must hold termios_rwsem, port mutex and port lock to change; | 220 | * Must hold termios_rwsem, port mutex and port lock to change; |
221 | * can hold any one lock to read. | 221 | * can hold any one lock to read. |
222 | */ | 222 | */ |
223 | upstat_t status; | 223 | upstat_t status; |
224 | 224 | ||
225 | #define UPSTAT_CTS_ENABLE ((__force upstat_t) (1 << 0)) | 225 | #define UPSTAT_CTS_ENABLE ((__force upstat_t) (1 << 0)) |
226 | #define UPSTAT_DCD_ENABLE ((__force upstat_t) (1 << 1)) | 226 | #define UPSTAT_DCD_ENABLE ((__force upstat_t) (1 << 1)) |
227 | #define UPSTAT_AUTORTS ((__force upstat_t) (1 << 2)) | 227 | #define UPSTAT_AUTORTS ((__force upstat_t) (1 << 2)) |
228 | #define UPSTAT_AUTOCTS ((__force upstat_t) (1 << 3)) | 228 | #define UPSTAT_AUTOCTS ((__force upstat_t) (1 << 3)) |
229 | #define UPSTAT_AUTOXOFF ((__force upstat_t) (1 << 4)) | 229 | #define UPSTAT_AUTOXOFF ((__force upstat_t) (1 << 4)) |
230 | 230 | ||
231 | int hw_stopped; /* sw-assisted CTS flow state */ | 231 | int hw_stopped; /* sw-assisted CTS flow state */ |
232 | unsigned int mctrl; /* current modem ctrl settings */ | 232 | unsigned int mctrl; /* current modem ctrl settings */ |
233 | unsigned int timeout; /* character-based timeout */ | 233 | unsigned int timeout; /* character-based timeout */ |
234 | unsigned int type; /* port type */ | 234 | unsigned int type; /* port type */ |
235 | const struct uart_ops *ops; | 235 | const struct uart_ops *ops; |
236 | unsigned int custom_divisor; | 236 | unsigned int custom_divisor; |
237 | unsigned int line; /* port index */ | 237 | unsigned int line; /* port index */ |
238 | resource_size_t mapbase; /* for ioremap */ | 238 | resource_size_t mapbase; /* for ioremap */ |
239 | struct device *dev; /* parent device */ | 239 | struct device *dev; /* parent device */ |
240 | unsigned char hub6; /* this should be in the 8250 driver */ | 240 | unsigned char hub6; /* this should be in the 8250 driver */ |
241 | unsigned char suspended; | 241 | unsigned char suspended; |
242 | unsigned char irq_wake; | 242 | unsigned char irq_wake; |
243 | unsigned char unused[2]; | 243 | unsigned char unused[2]; |
244 | struct attribute_group *attr_group; /* port specific attributes */ | 244 | struct attribute_group *attr_group; /* port specific attributes */ |
245 | const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ | 245 | const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ |
246 | struct serial_rs485 rs485; | 246 | struct serial_rs485 rs485; |
247 | void *private_data; /* generic platform data pointer */ | 247 | void *private_data; /* generic platform data pointer */ |
248 | }; | 248 | }; |
249 | 249 | ||
250 | static inline int serial_port_in(struct uart_port *up, int offset) | 250 | static inline int serial_port_in(struct uart_port *up, int offset) |
251 | { | 251 | { |
252 | return up->serial_in(up, offset); | 252 | return up->serial_in(up, offset); |
253 | } | 253 | } |
254 | 254 | ||
255 | static inline void serial_port_out(struct uart_port *up, int offset, int value) | 255 | static inline void serial_port_out(struct uart_port *up, int offset, int value) |
256 | { | 256 | { |
257 | up->serial_out(up, offset, value); | 257 | up->serial_out(up, offset, value); |
258 | } | 258 | } |
259 | 259 | ||
260 | /** | 260 | /** |
261 | * enum uart_pm_state - power states for UARTs | 261 | * enum uart_pm_state - power states for UARTs |
262 | * @UART_PM_STATE_ON: UART is powered, up and operational | 262 | * @UART_PM_STATE_ON: UART is powered, up and operational |
263 | * @UART_PM_STATE_OFF: UART is powered off | 263 | * @UART_PM_STATE_OFF: UART is powered off |
264 | * @UART_PM_STATE_UNDEFINED: sentinel | 264 | * @UART_PM_STATE_UNDEFINED: sentinel |
265 | */ | 265 | */ |
266 | enum uart_pm_state { | 266 | enum uart_pm_state { |
267 | UART_PM_STATE_ON = 0, | 267 | UART_PM_STATE_ON = 0, |
268 | UART_PM_STATE_OFF = 3, /* number taken from ACPI */ | 268 | UART_PM_STATE_OFF = 3, /* number taken from ACPI */ |
269 | UART_PM_STATE_UNDEFINED, | 269 | UART_PM_STATE_UNDEFINED, |
270 | }; | 270 | }; |
271 | 271 | ||
272 | /* | 272 | /* |
273 | * This is the state information which is persistent across opens. | 273 | * This is the state information which is persistent across opens. |
274 | */ | 274 | */ |
275 | struct uart_state { | 275 | struct uart_state { |
276 | struct tty_port port; | 276 | struct tty_port port; |
277 | 277 | ||
278 | enum uart_pm_state pm_state; | 278 | enum uart_pm_state pm_state; |
279 | struct circ_buf xmit; | 279 | struct circ_buf xmit; |
280 | 280 | ||
281 | struct uart_port *uart_port; | 281 | struct uart_port *uart_port; |
282 | }; | 282 | }; |
283 | 283 | ||
284 | #define UART_XMIT_SIZE PAGE_SIZE | 284 | #define UART_XMIT_SIZE PAGE_SIZE |
285 | 285 | ||
286 | 286 | ||
287 | /* number of characters left in xmit buffer before we ask for more */ | 287 | /* number of characters left in xmit buffer before we ask for more */ |
288 | #define WAKEUP_CHARS 256 | 288 | #define WAKEUP_CHARS 256 |
289 | 289 | ||
290 | struct module; | 290 | struct module; |
291 | struct tty_driver; | 291 | struct tty_driver; |
292 | 292 | ||
293 | struct uart_driver { | 293 | struct uart_driver { |
294 | struct module *owner; | 294 | struct module *owner; |
295 | const char *driver_name; | 295 | const char *driver_name; |
296 | const char *dev_name; | 296 | const char *dev_name; |
297 | int major; | 297 | int major; |
298 | int minor; | 298 | int minor; |
299 | int nr; | 299 | int nr; |
300 | struct console *cons; | 300 | struct console *cons; |
301 | 301 | ||
302 | /* | 302 | /* |
303 | * these are private; the low level driver should not | 303 | * these are private; the low level driver should not |
304 | * touch these; they should be initialised to NULL | 304 | * touch these; they should be initialised to NULL |
305 | */ | 305 | */ |
306 | struct uart_state *state; | 306 | struct uart_state *state; |
307 | struct tty_driver *tty_driver; | 307 | struct tty_driver *tty_driver; |
308 | }; | 308 | }; |
309 | 309 | ||
310 | void uart_write_wakeup(struct uart_port *port); | 310 | void uart_write_wakeup(struct uart_port *port); |
311 | 311 | ||
312 | /* | 312 | /* |
313 | * Baud rate helpers. | 313 | * Baud rate helpers. |
314 | */ | 314 | */ |
315 | void uart_update_timeout(struct uart_port *port, unsigned int cflag, | 315 | void uart_update_timeout(struct uart_port *port, unsigned int cflag, |
316 | unsigned int baud); | 316 | unsigned int baud); |
317 | unsigned int uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, | 317 | unsigned int uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, |
318 | struct ktermios *old, unsigned int min, | 318 | struct ktermios *old, unsigned int min, |
319 | unsigned int max); | 319 | unsigned int max); |
320 | unsigned int uart_get_divisor(struct uart_port *port, unsigned int baud); | 320 | unsigned int uart_get_divisor(struct uart_port *port, unsigned int baud); |
321 | 321 | ||
322 | /* Base timer interval for polling */ | 322 | /* Base timer interval for polling */ |
323 | static inline int uart_poll_timeout(struct uart_port *port) | 323 | static inline int uart_poll_timeout(struct uart_port *port) |
324 | { | 324 | { |
325 | int timeout = port->timeout; | 325 | int timeout = port->timeout; |
326 | 326 | ||
327 | return timeout > 6 ? (timeout / 2 - 2) : 1; | 327 | return timeout > 6 ? (timeout / 2 - 2) : 1; |
328 | } | 328 | } |
329 | 329 | ||
330 | /* | 330 | /* |
331 | * Console helpers. | 331 | * Console helpers. |
332 | */ | 332 | */ |
333 | struct earlycon_device { | 333 | struct earlycon_device { |
334 | struct console *con; | 334 | struct console *con; |
335 | struct uart_port port; | 335 | struct uart_port port; |
336 | char options[16]; /* e.g., 115200n8 */ | 336 | char options[16]; /* e.g., 115200n8 */ |
337 | unsigned int baud; | 337 | unsigned int baud; |
338 | }; | 338 | }; |
339 | int setup_earlycon(char *buf, const char *match, | 339 | int setup_earlycon(char *buf, const char *match, |
340 | int (*setup)(struct earlycon_device *, const char *)); | 340 | int (*setup)(struct earlycon_device *, const char *)); |
341 | 341 | ||
342 | extern int of_setup_earlycon(unsigned long addr, | 342 | extern int of_setup_earlycon(unsigned long addr, |
343 | int (*setup)(struct earlycon_device *, const char *)); | 343 | int (*setup)(struct earlycon_device *, const char *)); |
344 | 344 | ||
345 | #define EARLYCON_DECLARE(name, func) \ | 345 | #define EARLYCON_DECLARE(name, func) \ |
346 | static int __init name ## _setup_earlycon(char *buf) \ | 346 | static int __init name ## _setup_earlycon(char *buf) \ |
347 | { \ | 347 | { \ |
348 | return setup_earlycon(buf, __stringify(name), func); \ | 348 | return setup_earlycon(buf, __stringify(name), func); \ |
349 | } \ | 349 | } \ |
350 | early_param("earlycon", name ## _setup_earlycon); | 350 | early_param("earlycon", name ## _setup_earlycon); |
351 | 351 | ||
352 | #define OF_EARLYCON_DECLARE(name, compat, fn) \ | 352 | #define OF_EARLYCON_DECLARE(name, compat, fn) \ |
353 | _OF_DECLARE(earlycon, name, compat, fn, void *) | 353 | _OF_DECLARE(earlycon, name, compat, fn, void *) |
354 | 354 | ||
355 | struct uart_port *uart_get_console(struct uart_port *ports, int nr, | 355 | struct uart_port *uart_get_console(struct uart_port *ports, int nr, |
356 | struct console *c); | 356 | struct console *c); |
357 | void uart_parse_options(char *options, int *baud, int *parity, int *bits, | 357 | void uart_parse_options(char *options, int *baud, int *parity, int *bits, |
358 | int *flow); | 358 | int *flow); |
359 | int uart_set_options(struct uart_port *port, struct console *co, int baud, | 359 | int uart_set_options(struct uart_port *port, struct console *co, int baud, |
360 | int parity, int bits, int flow); | 360 | int parity, int bits, int flow); |
361 | struct tty_driver *uart_console_device(struct console *co, int *index); | 361 | struct tty_driver *uart_console_device(struct console *co, int *index); |
362 | void uart_console_write(struct uart_port *port, const char *s, | 362 | void uart_console_write(struct uart_port *port, const char *s, |
363 | unsigned int count, | 363 | unsigned int count, |
364 | void (*putchar)(struct uart_port *, int)); | 364 | void (*putchar)(struct uart_port *, int)); |
365 | 365 | ||
366 | /* | 366 | /* |
367 | * Port/driver registration/removal | 367 | * Port/driver registration/removal |
368 | */ | 368 | */ |
369 | int uart_register_driver(struct uart_driver *uart); | 369 | int uart_register_driver(struct uart_driver *uart); |
370 | void uart_unregister_driver(struct uart_driver *uart); | 370 | void uart_unregister_driver(struct uart_driver *uart); |
371 | int uart_add_one_port(struct uart_driver *reg, struct uart_port *port); | 371 | int uart_add_one_port(struct uart_driver *reg, struct uart_port *port); |
372 | int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port); | 372 | int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port); |
373 | int uart_match_port(struct uart_port *port1, struct uart_port *port2); | 373 | int uart_match_port(struct uart_port *port1, struct uart_port *port2); |
374 | 374 | ||
375 | /* | 375 | /* |
376 | * Power Management | 376 | * Power Management |
377 | */ | 377 | */ |
378 | int uart_suspend_port(struct uart_driver *reg, struct uart_port *port); | 378 | int uart_suspend_port(struct uart_driver *reg, struct uart_port *port); |
379 | int uart_resume_port(struct uart_driver *reg, struct uart_port *port); | 379 | int uart_resume_port(struct uart_driver *reg, struct uart_port *port); |
380 | 380 | ||
381 | #define uart_circ_empty(circ) ((circ)->head == (circ)->tail) | 381 | #define uart_circ_empty(circ) ((circ)->head == (circ)->tail) |
382 | #define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0) | 382 | #define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0) |
383 | 383 | ||
384 | #define uart_circ_chars_pending(circ) \ | 384 | #define uart_circ_chars_pending(circ) \ |
385 | (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE)) | 385 | (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE)) |
386 | 386 | ||
387 | #define uart_circ_chars_free(circ) \ | 387 | #define uart_circ_chars_free(circ) \ |
388 | (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) | 388 | (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) |
389 | 389 | ||
390 | static inline int uart_tx_stopped(struct uart_port *port) | 390 | static inline int uart_tx_stopped(struct uart_port *port) |
391 | { | 391 | { |
392 | struct tty_struct *tty = port->state->port.tty; | 392 | struct tty_struct *tty = port->state->port.tty; |
393 | if (tty->stopped || port->hw_stopped) | 393 | if (tty->stopped || port->hw_stopped) |
394 | return 1; | 394 | return 1; |
395 | return 0; | 395 | return 0; |
396 | } | 396 | } |
397 | 397 | ||
398 | static inline bool uart_cts_enabled(struct uart_port *uport) | 398 | static inline bool uart_cts_enabled(struct uart_port *uport) |
399 | { | 399 | { |
400 | return !!(uport->status & UPSTAT_CTS_ENABLE); | 400 | return !!(uport->status & UPSTAT_CTS_ENABLE); |
401 | } | 401 | } |
402 | 402 | ||
403 | static inline bool uart_softcts_mode(struct uart_port *uport) | 403 | static inline bool uart_softcts_mode(struct uart_port *uport) |
404 | { | 404 | { |
405 | upstat_t mask = UPSTAT_CTS_ENABLE | UPSTAT_AUTOCTS; | 405 | upstat_t mask = UPSTAT_CTS_ENABLE | UPSTAT_AUTOCTS; |
406 | 406 | ||
407 | return ((uport->status & mask) == UPSTAT_CTS_ENABLE); | 407 | return ((uport->status & mask) == UPSTAT_CTS_ENABLE); |
408 | } | 408 | } |
409 | 409 | ||
410 | /* | 410 | /* |
411 | * The following are helper functions for the low level drivers. | 411 | * The following are helper functions for the low level drivers. |
412 | */ | 412 | */ |
413 | 413 | ||
414 | extern void uart_handle_dcd_change(struct uart_port *uport, | 414 | extern void uart_handle_dcd_change(struct uart_port *uport, |
415 | unsigned int status); | 415 | unsigned int status); |
416 | extern void uart_handle_cts_change(struct uart_port *uport, | 416 | extern void uart_handle_cts_change(struct uart_port *uport, |
417 | unsigned int status); | 417 | unsigned int status); |
418 | 418 | ||
419 | extern void uart_insert_char(struct uart_port *port, unsigned int status, | 419 | extern void uart_insert_char(struct uart_port *port, unsigned int status, |
420 | unsigned int overrun, unsigned int ch, unsigned int flag); | 420 | unsigned int overrun, unsigned int ch, unsigned int flag); |
421 | 421 | ||
422 | #ifdef SUPPORT_SYSRQ | 422 | #ifdef SUPPORT_SYSRQ |
423 | static inline int | 423 | static inline int |
424 | uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) | 424 | uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) |
425 | { | 425 | { |
426 | if (port->sysrq) { | 426 | if (port->sysrq) { |
427 | if (ch && time_before(jiffies, port->sysrq)) { | 427 | if (ch && time_before(jiffies, port->sysrq)) { |
428 | handle_sysrq(ch); | 428 | handle_sysrq(ch); |
429 | port->sysrq = 0; | 429 | port->sysrq = 0; |
430 | return 1; | 430 | return 1; |
431 | } | 431 | } |
432 | port->sysrq = 0; | 432 | port->sysrq = 0; |
433 | } | 433 | } |
434 | return 0; | 434 | return 0; |
435 | } | 435 | } |
436 | #else | 436 | #else |
437 | #define uart_handle_sysrq_char(port,ch) ({ (void)port; 0; }) | 437 | #define uart_handle_sysrq_char(port,ch) ({ (void)port; 0; }) |
438 | #endif | 438 | #endif |
439 | 439 | ||
440 | /* | 440 | /* |
441 | * We do the SysRQ and SAK checking like this... | 441 | * We do the SysRQ and SAK checking like this... |
442 | */ | 442 | */ |
443 | static inline int uart_handle_break(struct uart_port *port) | 443 | static inline int uart_handle_break(struct uart_port *port) |
444 | { | 444 | { |
445 | struct uart_state *state = port->state; | 445 | struct uart_state *state = port->state; |
446 | 446 | ||
447 | if (port->handle_break) | 447 | if (port->handle_break) |
448 | port->handle_break(port); | 448 | port->handle_break(port); |
449 | 449 | ||
450 | #ifdef SUPPORT_SYSRQ | 450 | #ifdef SUPPORT_SYSRQ |
451 | if (port->cons && port->cons->index == port->line) { | 451 | if (port->cons && port->cons->index == port->line) { |
452 | if (!port->sysrq) { | 452 | if (!port->sysrq) { |
453 | port->sysrq = jiffies + HZ*5; | 453 | port->sysrq = jiffies + HZ*5; |
454 | return 1; | 454 | return 1; |
455 | } | 455 | } |
456 | port->sysrq = 0; | 456 | port->sysrq = 0; |
457 | } | 457 | } |
458 | #endif | 458 | #endif |
459 | if (port->flags & UPF_SAK) | 459 | if (port->flags & UPF_SAK) |
460 | do_SAK(state->port.tty); | 460 | do_SAK(state->port.tty); |
461 | return 0; | 461 | return 0; |
462 | } | 462 | } |
463 | 463 | ||
464 | /* | 464 | /* |
465 | * UART_ENABLE_MS - determine if port should enable modem status irqs | 465 | * UART_ENABLE_MS - determine if port should enable modem status irqs |
466 | */ | 466 | */ |
467 | #define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \ | 467 | #define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \ |
468 | (cflag) & CRTSCTS || \ | 468 | (cflag) & CRTSCTS || \ |
469 | !((cflag) & CLOCAL)) | 469 | !((cflag) & CLOCAL)) |
470 | 470 | ||
471 | #endif /* LINUX_SERIAL_CORE_H */ | 471 | #endif /* LINUX_SERIAL_CORE_H */ |
472 | 472 |
include/uapi/linux/serial.h
1 | /* | 1 | /* |
2 | * include/linux/serial.h | 2 | * include/linux/serial.h |
3 | * | 3 | * |
4 | * Copyright (C) 1992 by Theodore Ts'o. | 4 | * Copyright (C) 1992 by Theodore Ts'o. |
5 | * | 5 | * |
6 | * Redistribution of this file is permitted under the terms of the GNU | 6 | * Redistribution of this file is permitted under the terms of the GNU |
7 | * Public License (GPL) | 7 | * Public License (GPL) |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #ifndef _UAPI_LINUX_SERIAL_H | 10 | #ifndef _UAPI_LINUX_SERIAL_H |
11 | #define _UAPI_LINUX_SERIAL_H | 11 | #define _UAPI_LINUX_SERIAL_H |
12 | 12 | ||
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | 14 | ||
15 | #include <linux/tty_flags.h> | 15 | #include <linux/tty_flags.h> |
16 | 16 | ||
17 | 17 | ||
18 | struct serial_struct { | 18 | struct serial_struct { |
19 | int type; | 19 | int type; |
20 | int line; | 20 | int line; |
21 | unsigned int port; | 21 | unsigned int port; |
22 | int irq; | 22 | int irq; |
23 | int flags; | 23 | int flags; |
24 | int xmit_fifo_size; | 24 | int xmit_fifo_size; |
25 | int custom_divisor; | 25 | int custom_divisor; |
26 | int baud_base; | 26 | int baud_base; |
27 | unsigned short close_delay; | 27 | unsigned short close_delay; |
28 | char io_type; | 28 | char io_type; |
29 | char reserved_char[1]; | 29 | char reserved_char[1]; |
30 | int hub6; | 30 | int hub6; |
31 | unsigned short closing_wait; /* time to wait before closing */ | 31 | unsigned short closing_wait; /* time to wait before closing */ |
32 | unsigned short closing_wait2; /* no longer used... */ | 32 | unsigned short closing_wait2; /* no longer used... */ |
33 | unsigned char *iomem_base; | 33 | unsigned char *iomem_base; |
34 | unsigned short iomem_reg_shift; | 34 | unsigned short iomem_reg_shift; |
35 | unsigned int port_high; | 35 | unsigned int port_high; |
36 | unsigned long iomap_base; /* cookie passed into ioremap */ | 36 | unsigned long iomap_base; /* cookie passed into ioremap */ |
37 | }; | 37 | }; |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * For the close wait times, 0 means wait forever for serial port to | 40 | * For the close wait times, 0 means wait forever for serial port to |
41 | * flush its output. 65535 means don't wait at all. | 41 | * flush its output. 65535 means don't wait at all. |
42 | */ | 42 | */ |
43 | #define ASYNC_CLOSING_WAIT_INF 0 | 43 | #define ASYNC_CLOSING_WAIT_INF 0 |
44 | #define ASYNC_CLOSING_WAIT_NONE 65535 | 44 | #define ASYNC_CLOSING_WAIT_NONE 65535 |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * These are the supported serial types. | 47 | * These are the supported serial types. |
48 | */ | 48 | */ |
49 | #define PORT_UNKNOWN 0 | 49 | #define PORT_UNKNOWN 0 |
50 | #define PORT_8250 1 | 50 | #define PORT_8250 1 |
51 | #define PORT_16450 2 | 51 | #define PORT_16450 2 |
52 | #define PORT_16550 3 | 52 | #define PORT_16550 3 |
53 | #define PORT_16550A 4 | 53 | #define PORT_16550A 4 |
54 | #define PORT_CIRRUS 5 /* usurped by cyclades.c */ | 54 | #define PORT_CIRRUS 5 /* usurped by cyclades.c */ |
55 | #define PORT_16650 6 | 55 | #define PORT_16650 6 |
56 | #define PORT_16650V2 7 | 56 | #define PORT_16650V2 7 |
57 | #define PORT_16750 8 | 57 | #define PORT_16750 8 |
58 | #define PORT_STARTECH 9 /* usurped by cyclades.c */ | 58 | #define PORT_STARTECH 9 /* usurped by cyclades.c */ |
59 | #define PORT_16C950 10 /* Oxford Semiconductor */ | 59 | #define PORT_16C950 10 /* Oxford Semiconductor */ |
60 | #define PORT_16654 11 | 60 | #define PORT_16654 11 |
61 | #define PORT_16850 12 | 61 | #define PORT_16850 12 |
62 | #define PORT_RSA 13 /* RSA-DV II/S card */ | 62 | #define PORT_RSA 13 /* RSA-DV II/S card */ |
63 | #define PORT_MAX 13 | 63 | #define PORT_MAX 13 |
64 | 64 | ||
65 | #define SERIAL_IO_PORT 0 | 65 | #define SERIAL_IO_PORT 0 |
66 | #define SERIAL_IO_HUB6 1 | 66 | #define SERIAL_IO_HUB6 1 |
67 | #define SERIAL_IO_MEM 2 | 67 | #define SERIAL_IO_MEM 2 |
68 | #define SERIAL_IO_MEM32 3 | ||
69 | #define SERIAL_IO_AU 4 | ||
70 | #define SERIAL_IO_TSI 5 | ||
71 | #define SERIAL_IO_MEM32BE 6 | ||
68 | 72 | ||
69 | #define UART_CLEAR_FIFO 0x01 | 73 | #define UART_CLEAR_FIFO 0x01 |
70 | #define UART_USE_FIFO 0x02 | 74 | #define UART_USE_FIFO 0x02 |
71 | #define UART_STARTECH 0x04 | 75 | #define UART_STARTECH 0x04 |
72 | #define UART_NATSEMI 0x08 | 76 | #define UART_NATSEMI 0x08 |
73 | 77 | ||
74 | 78 | ||
75 | /* | 79 | /* |
76 | * Multiport serial configuration structure --- external structure | 80 | * Multiport serial configuration structure --- external structure |
77 | */ | 81 | */ |
78 | struct serial_multiport_struct { | 82 | struct serial_multiport_struct { |
79 | int irq; | 83 | int irq; |
80 | int port1; | 84 | int port1; |
81 | unsigned char mask1, match1; | 85 | unsigned char mask1, match1; |
82 | int port2; | 86 | int port2; |
83 | unsigned char mask2, match2; | 87 | unsigned char mask2, match2; |
84 | int port3; | 88 | int port3; |
85 | unsigned char mask3, match3; | 89 | unsigned char mask3, match3; |
86 | int port4; | 90 | int port4; |
87 | unsigned char mask4, match4; | 91 | unsigned char mask4, match4; |
88 | int port_monitor; | 92 | int port_monitor; |
89 | int reserved[32]; | 93 | int reserved[32]; |
90 | }; | 94 | }; |
91 | 95 | ||
92 | /* | 96 | /* |
93 | * Serial input interrupt line counters -- external structure | 97 | * Serial input interrupt line counters -- external structure |
94 | * Four lines can interrupt: CTS, DSR, RI, DCD | 98 | * Four lines can interrupt: CTS, DSR, RI, DCD |
95 | */ | 99 | */ |
96 | struct serial_icounter_struct { | 100 | struct serial_icounter_struct { |
97 | int cts, dsr, rng, dcd; | 101 | int cts, dsr, rng, dcd; |
98 | int rx, tx; | 102 | int rx, tx; |
99 | int frame, overrun, parity, brk; | 103 | int frame, overrun, parity, brk; |
100 | int buf_overrun; | 104 | int buf_overrun; |
101 | int reserved[9]; | 105 | int reserved[9]; |
102 | }; | 106 | }; |
103 | 107 | ||
104 | /* | 108 | /* |
105 | * Serial interface for controlling RS485 settings on chips with suitable | 109 | * Serial interface for controlling RS485 settings on chips with suitable |
106 | * support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your | 110 | * support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your |
107 | * platform. The set function returns the new state, with any unsupported bits | 111 | * platform. The set function returns the new state, with any unsupported bits |
108 | * reverted appropriately. | 112 | * reverted appropriately. |
109 | */ | 113 | */ |
110 | 114 | ||
111 | struct serial_rs485 { | 115 | struct serial_rs485 { |
112 | __u32 flags; /* RS485 feature flags */ | 116 | __u32 flags; /* RS485 feature flags */ |
113 | #define SER_RS485_ENABLED (1 << 0) /* If enabled */ | 117 | #define SER_RS485_ENABLED (1 << 0) /* If enabled */ |
114 | #define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for | 118 | #define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for |
115 | RTS pin when | 119 | RTS pin when |
116 | sending */ | 120 | sending */ |
117 | #define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for | 121 | #define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for |
118 | RTS pin after sent*/ | 122 | RTS pin after sent*/ |
119 | #define SER_RS485_RX_DURING_TX (1 << 4) | 123 | #define SER_RS485_RX_DURING_TX (1 << 4) |
120 | __u32 delay_rts_before_send; /* Delay before send (milliseconds) */ | 124 | __u32 delay_rts_before_send; /* Delay before send (milliseconds) */ |
121 | __u32 delay_rts_after_send; /* Delay after send (milliseconds) */ | 125 | __u32 delay_rts_after_send; /* Delay after send (milliseconds) */ |
122 | __u32 padding[5]; /* Memory is cheap, new structs | 126 | __u32 padding[5]; /* Memory is cheap, new structs |
123 | are a royal PITA .. */ | 127 | are a royal PITA .. */ |
124 | }; | 128 | }; |
125 | 129 | ||
126 | #endif /* _UAPI_LINUX_SERIAL_H */ | 130 | #endif /* _UAPI_LINUX_SERIAL_H */ |
127 | 131 |
kernel/printk/console_cmdline.h
1 | #ifndef _CONSOLE_CMDLINE_H | 1 | #ifndef _CONSOLE_CMDLINE_H |
2 | #define _CONSOLE_CMDLINE_H | 2 | #define _CONSOLE_CMDLINE_H |
3 | 3 | ||
4 | struct console_cmdline | 4 | struct console_cmdline |
5 | { | 5 | { |
6 | char name[8]; /* Name of the driver */ | 6 | char name[16]; /* Name of the driver */ |
7 | int index; /* Minor dev. to use */ | 7 | int index; /* Minor dev. to use */ |
8 | char *options; /* Options for the driver */ | 8 | char *options; /* Options for the driver */ |
9 | #ifdef CONFIG_A11Y_BRAILLE_CONSOLE | 9 | #ifdef CONFIG_A11Y_BRAILLE_CONSOLE |
10 | char *brl_options; /* Options for braille driver */ | 10 | char *brl_options; /* Options for braille driver */ |
11 | #endif | 11 | #endif |
12 | }; | 12 | }; |
13 | 13 | ||
14 | #endif | 14 | #endif |
15 | 15 |
kernel/printk/printk.c
1 | /* | 1 | /* |
2 | * linux/kernel/printk.c | 2 | * linux/kernel/printk.c |
3 | * | 3 | * |
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 4 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * | 5 | * |
6 | * Modified to make sys_syslog() more flexible: added commands to | 6 | * Modified to make sys_syslog() more flexible: added commands to |
7 | * return the last 4k of kernel messages, regardless of whether | 7 | * return the last 4k of kernel messages, regardless of whether |
8 | * they've been read or not. Added option to suppress kernel printk's | 8 | * they've been read or not. Added option to suppress kernel printk's |
9 | * to the console. Added hook for sending the console messages | 9 | * to the console. Added hook for sending the console messages |
10 | * elsewhere, in preparation for a serial line console (someday). | 10 | * elsewhere, in preparation for a serial line console (someday). |
11 | * Ted Ts'o, 2/11/93. | 11 | * Ted Ts'o, 2/11/93. |
12 | * Modified for sysctl support, 1/8/97, Chris Horn. | 12 | * Modified for sysctl support, 1/8/97, Chris Horn. |
13 | * Fixed SMP synchronization, 08/08/99, Manfred Spraul | 13 | * Fixed SMP synchronization, 08/08/99, Manfred Spraul |
14 | * manfred@colorfullife.com | 14 | * manfred@colorfullife.com |
15 | * Rewrote bits to get rid of console_lock | 15 | * Rewrote bits to get rid of console_lock |
16 | * 01Mar01 Andrew Morton | 16 | * 01Mar01 Andrew Morton |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | #include <linux/tty.h> | 21 | #include <linux/tty.h> |
22 | #include <linux/tty_driver.h> | 22 | #include <linux/tty_driver.h> |
23 | #include <linux/console.h> | 23 | #include <linux/console.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/jiffies.h> | 25 | #include <linux/jiffies.h> |
26 | #include <linux/nmi.h> | 26 | #include <linux/nmi.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/interrupt.h> /* For in_interrupt() */ | 29 | #include <linux/interrupt.h> /* For in_interrupt() */ |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/smp.h> | 31 | #include <linux/smp.h> |
32 | #include <linux/security.h> | 32 | #include <linux/security.h> |
33 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
34 | #include <linux/memblock.h> | 34 | #include <linux/memblock.h> |
35 | #include <linux/aio.h> | 35 | #include <linux/aio.h> |
36 | #include <linux/syscalls.h> | 36 | #include <linux/syscalls.h> |
37 | #include <linux/kexec.h> | 37 | #include <linux/kexec.h> |
38 | #include <linux/kdb.h> | 38 | #include <linux/kdb.h> |
39 | #include <linux/ratelimit.h> | 39 | #include <linux/ratelimit.h> |
40 | #include <linux/kmsg_dump.h> | 40 | #include <linux/kmsg_dump.h> |
41 | #include <linux/syslog.h> | 41 | #include <linux/syslog.h> |
42 | #include <linux/cpu.h> | 42 | #include <linux/cpu.h> |
43 | #include <linux/notifier.h> | 43 | #include <linux/notifier.h> |
44 | #include <linux/rculist.h> | 44 | #include <linux/rculist.h> |
45 | #include <linux/poll.h> | 45 | #include <linux/poll.h> |
46 | #include <linux/irq_work.h> | 46 | #include <linux/irq_work.h> |
47 | #include <linux/utsname.h> | 47 | #include <linux/utsname.h> |
48 | #include <linux/ctype.h> | 48 | #include <linux/ctype.h> |
49 | 49 | ||
50 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
51 | 51 | ||
52 | #define CREATE_TRACE_POINTS | 52 | #define CREATE_TRACE_POINTS |
53 | #include <trace/events/printk.h> | 53 | #include <trace/events/printk.h> |
54 | 54 | ||
55 | #include "console_cmdline.h" | 55 | #include "console_cmdline.h" |
56 | #include "braille.h" | 56 | #include "braille.h" |
57 | 57 | ||
58 | int console_printk[4] = { | 58 | int console_printk[4] = { |
59 | CONSOLE_LOGLEVEL_DEFAULT, /* console_loglevel */ | 59 | CONSOLE_LOGLEVEL_DEFAULT, /* console_loglevel */ |
60 | MESSAGE_LOGLEVEL_DEFAULT, /* default_message_loglevel */ | 60 | MESSAGE_LOGLEVEL_DEFAULT, /* default_message_loglevel */ |
61 | CONSOLE_LOGLEVEL_MIN, /* minimum_console_loglevel */ | 61 | CONSOLE_LOGLEVEL_MIN, /* minimum_console_loglevel */ |
62 | CONSOLE_LOGLEVEL_DEFAULT, /* default_console_loglevel */ | 62 | CONSOLE_LOGLEVEL_DEFAULT, /* default_console_loglevel */ |
63 | }; | 63 | }; |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * Low level drivers may need that to know if they can schedule in | 66 | * Low level drivers may need that to know if they can schedule in |
67 | * their unblank() callback or not. So let's export it. | 67 | * their unblank() callback or not. So let's export it. |
68 | */ | 68 | */ |
69 | int oops_in_progress; | 69 | int oops_in_progress; |
70 | EXPORT_SYMBOL(oops_in_progress); | 70 | EXPORT_SYMBOL(oops_in_progress); |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * console_sem protects the console_drivers list, and also | 73 | * console_sem protects the console_drivers list, and also |
74 | * provides serialisation for access to the entire console | 74 | * provides serialisation for access to the entire console |
75 | * driver system. | 75 | * driver system. |
76 | */ | 76 | */ |
77 | static DEFINE_SEMAPHORE(console_sem); | 77 | static DEFINE_SEMAPHORE(console_sem); |
78 | struct console *console_drivers; | 78 | struct console *console_drivers; |
79 | EXPORT_SYMBOL_GPL(console_drivers); | 79 | EXPORT_SYMBOL_GPL(console_drivers); |
80 | 80 | ||
81 | #ifdef CONFIG_LOCKDEP | 81 | #ifdef CONFIG_LOCKDEP |
82 | static struct lockdep_map console_lock_dep_map = { | 82 | static struct lockdep_map console_lock_dep_map = { |
83 | .name = "console_lock" | 83 | .name = "console_lock" |
84 | }; | 84 | }; |
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | /* | 87 | /* |
88 | * Helper macros to handle lockdep when locking/unlocking console_sem. We use | 88 | * Helper macros to handle lockdep when locking/unlocking console_sem. We use |
89 | * macros instead of functions so that _RET_IP_ contains useful information. | 89 | * macros instead of functions so that _RET_IP_ contains useful information. |
90 | */ | 90 | */ |
91 | #define down_console_sem() do { \ | 91 | #define down_console_sem() do { \ |
92 | down(&console_sem);\ | 92 | down(&console_sem);\ |
93 | mutex_acquire(&console_lock_dep_map, 0, 0, _RET_IP_);\ | 93 | mutex_acquire(&console_lock_dep_map, 0, 0, _RET_IP_);\ |
94 | } while (0) | 94 | } while (0) |
95 | 95 | ||
96 | static int __down_trylock_console_sem(unsigned long ip) | 96 | static int __down_trylock_console_sem(unsigned long ip) |
97 | { | 97 | { |
98 | if (down_trylock(&console_sem)) | 98 | if (down_trylock(&console_sem)) |
99 | return 1; | 99 | return 1; |
100 | mutex_acquire(&console_lock_dep_map, 0, 1, ip); | 100 | mutex_acquire(&console_lock_dep_map, 0, 1, ip); |
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | #define down_trylock_console_sem() __down_trylock_console_sem(_RET_IP_) | 103 | #define down_trylock_console_sem() __down_trylock_console_sem(_RET_IP_) |
104 | 104 | ||
105 | #define up_console_sem() do { \ | 105 | #define up_console_sem() do { \ |
106 | mutex_release(&console_lock_dep_map, 1, _RET_IP_);\ | 106 | mutex_release(&console_lock_dep_map, 1, _RET_IP_);\ |
107 | up(&console_sem);\ | 107 | up(&console_sem);\ |
108 | } while (0) | 108 | } while (0) |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * This is used for debugging the mess that is the VT code by | 111 | * This is used for debugging the mess that is the VT code by |
112 | * keeping track if we have the console semaphore held. It's | 112 | * keeping track if we have the console semaphore held. It's |
113 | * definitely not the perfect debug tool (we don't know if _WE_ | 113 | * definitely not the perfect debug tool (we don't know if _WE_ |
114 | * hold it and are racing, but it helps tracking those weird code | 114 | * hold it and are racing, but it helps tracking those weird code |
115 | * paths in the console code where we end up in places I want | 115 | * paths in the console code where we end up in places I want |
116 | * locked without the console sempahore held). | 116 | * locked without the console sempahore held). |
117 | */ | 117 | */ |
118 | static int console_locked, console_suspended; | 118 | static int console_locked, console_suspended; |
119 | 119 | ||
120 | /* | 120 | /* |
121 | * If exclusive_console is non-NULL then only this console is to be printed to. | 121 | * If exclusive_console is non-NULL then only this console is to be printed to. |
122 | */ | 122 | */ |
123 | static struct console *exclusive_console; | 123 | static struct console *exclusive_console; |
124 | 124 | ||
125 | /* | 125 | /* |
126 | * Array of consoles built from command line options (console=) | 126 | * Array of consoles built from command line options (console=) |
127 | */ | 127 | */ |
128 | 128 | ||
129 | #define MAX_CMDLINECONSOLES 8 | 129 | #define MAX_CMDLINECONSOLES 8 |
130 | 130 | ||
131 | static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES]; | 131 | static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES]; |
132 | 132 | ||
133 | static int selected_console = -1; | 133 | static int selected_console = -1; |
134 | static int preferred_console = -1; | 134 | static int preferred_console = -1; |
135 | int console_set_on_cmdline; | 135 | int console_set_on_cmdline; |
136 | EXPORT_SYMBOL(console_set_on_cmdline); | 136 | EXPORT_SYMBOL(console_set_on_cmdline); |
137 | 137 | ||
138 | /* Flag: console code may call schedule() */ | 138 | /* Flag: console code may call schedule() */ |
139 | static int console_may_schedule; | 139 | static int console_may_schedule; |
140 | 140 | ||
141 | /* | 141 | /* |
142 | * The printk log buffer consists of a chain of concatenated variable | 142 | * The printk log buffer consists of a chain of concatenated variable |
143 | * length records. Every record starts with a record header, containing | 143 | * length records. Every record starts with a record header, containing |
144 | * the overall length of the record. | 144 | * the overall length of the record. |
145 | * | 145 | * |
146 | * The heads to the first and last entry in the buffer, as well as the | 146 | * The heads to the first and last entry in the buffer, as well as the |
147 | * sequence numbers of these entries are maintained when messages are | 147 | * sequence numbers of these entries are maintained when messages are |
148 | * stored. | 148 | * stored. |
149 | * | 149 | * |
150 | * If the heads indicate available messages, the length in the header | 150 | * If the heads indicate available messages, the length in the header |
151 | * tells the start next message. A length == 0 for the next message | 151 | * tells the start next message. A length == 0 for the next message |
152 | * indicates a wrap-around to the beginning of the buffer. | 152 | * indicates a wrap-around to the beginning of the buffer. |
153 | * | 153 | * |
154 | * Every record carries the monotonic timestamp in microseconds, as well as | 154 | * Every record carries the monotonic timestamp in microseconds, as well as |
155 | * the standard userspace syslog level and syslog facility. The usual | 155 | * the standard userspace syslog level and syslog facility. The usual |
156 | * kernel messages use LOG_KERN; userspace-injected messages always carry | 156 | * kernel messages use LOG_KERN; userspace-injected messages always carry |
157 | * a matching syslog facility, by default LOG_USER. The origin of every | 157 | * a matching syslog facility, by default LOG_USER. The origin of every |
158 | * message can be reliably determined that way. | 158 | * message can be reliably determined that way. |
159 | * | 159 | * |
160 | * The human readable log message directly follows the message header. The | 160 | * The human readable log message directly follows the message header. The |
161 | * length of the message text is stored in the header, the stored message | 161 | * length of the message text is stored in the header, the stored message |
162 | * is not terminated. | 162 | * is not terminated. |
163 | * | 163 | * |
164 | * Optionally, a message can carry a dictionary of properties (key/value pairs), | 164 | * Optionally, a message can carry a dictionary of properties (key/value pairs), |
165 | * to provide userspace with a machine-readable message context. | 165 | * to provide userspace with a machine-readable message context. |
166 | * | 166 | * |
167 | * Examples for well-defined, commonly used property names are: | 167 | * Examples for well-defined, commonly used property names are: |
168 | * DEVICE=b12:8 device identifier | 168 | * DEVICE=b12:8 device identifier |
169 | * b12:8 block dev_t | 169 | * b12:8 block dev_t |
170 | * c127:3 char dev_t | 170 | * c127:3 char dev_t |
171 | * n8 netdev ifindex | 171 | * n8 netdev ifindex |
172 | * +sound:card0 subsystem:devname | 172 | * +sound:card0 subsystem:devname |
173 | * SUBSYSTEM=pci driver-core subsystem name | 173 | * SUBSYSTEM=pci driver-core subsystem name |
174 | * | 174 | * |
175 | * Valid characters in property names are [a-zA-Z0-9.-_]. The plain text value | 175 | * Valid characters in property names are [a-zA-Z0-9.-_]. The plain text value |
176 | * follows directly after a '=' character. Every property is terminated by | 176 | * follows directly after a '=' character. Every property is terminated by |
177 | * a '\0' character. The last property is not terminated. | 177 | * a '\0' character. The last property is not terminated. |
178 | * | 178 | * |
179 | * Example of a message structure: | 179 | * Example of a message structure: |
180 | * 0000 ff 8f 00 00 00 00 00 00 monotonic time in nsec | 180 | * 0000 ff 8f 00 00 00 00 00 00 monotonic time in nsec |
181 | * 0008 34 00 record is 52 bytes long | 181 | * 0008 34 00 record is 52 bytes long |
182 | * 000a 0b 00 text is 11 bytes long | 182 | * 000a 0b 00 text is 11 bytes long |
183 | * 000c 1f 00 dictionary is 23 bytes long | 183 | * 000c 1f 00 dictionary is 23 bytes long |
184 | * 000e 03 00 LOG_KERN (facility) LOG_ERR (level) | 184 | * 000e 03 00 LOG_KERN (facility) LOG_ERR (level) |
185 | * 0010 69 74 27 73 20 61 20 6c "it's a l" | 185 | * 0010 69 74 27 73 20 61 20 6c "it's a l" |
186 | * 69 6e 65 "ine" | 186 | * 69 6e 65 "ine" |
187 | * 001b 44 45 56 49 43 "DEVIC" | 187 | * 001b 44 45 56 49 43 "DEVIC" |
188 | * 45 3d 62 38 3a 32 00 44 "E=b8:2\0D" | 188 | * 45 3d 62 38 3a 32 00 44 "E=b8:2\0D" |
189 | * 52 49 56 45 52 3d 62 75 "RIVER=bu" | 189 | * 52 49 56 45 52 3d 62 75 "RIVER=bu" |
190 | * 67 "g" | 190 | * 67 "g" |
191 | * 0032 00 00 00 padding to next message header | 191 | * 0032 00 00 00 padding to next message header |
192 | * | 192 | * |
193 | * The 'struct printk_log' buffer header must never be directly exported to | 193 | * The 'struct printk_log' buffer header must never be directly exported to |
194 | * userspace, it is a kernel-private implementation detail that might | 194 | * userspace, it is a kernel-private implementation detail that might |
195 | * need to be changed in the future, when the requirements change. | 195 | * need to be changed in the future, when the requirements change. |
196 | * | 196 | * |
197 | * /dev/kmsg exports the structured data in the following line format: | 197 | * /dev/kmsg exports the structured data in the following line format: |
198 | * "level,sequnum,timestamp;<message text>\n" | 198 | * "level,sequnum,timestamp;<message text>\n" |
199 | * | 199 | * |
200 | * The optional key/value pairs are attached as continuation lines starting | 200 | * The optional key/value pairs are attached as continuation lines starting |
201 | * with a space character and terminated by a newline. All possible | 201 | * with a space character and terminated by a newline. All possible |
202 | * non-prinatable characters are escaped in the "\xff" notation. | 202 | * non-prinatable characters are escaped in the "\xff" notation. |
203 | * | 203 | * |
204 | * Users of the export format should ignore possible additional values | 204 | * Users of the export format should ignore possible additional values |
205 | * separated by ',', and find the message after the ';' character. | 205 | * separated by ',', and find the message after the ';' character. |
206 | */ | 206 | */ |
207 | 207 | ||
208 | enum log_flags { | 208 | enum log_flags { |
209 | LOG_NOCONS = 1, /* already flushed, do not print to console */ | 209 | LOG_NOCONS = 1, /* already flushed, do not print to console */ |
210 | LOG_NEWLINE = 2, /* text ended with a newline */ | 210 | LOG_NEWLINE = 2, /* text ended with a newline */ |
211 | LOG_PREFIX = 4, /* text started with a prefix */ | 211 | LOG_PREFIX = 4, /* text started with a prefix */ |
212 | LOG_CONT = 8, /* text is a fragment of a continuation line */ | 212 | LOG_CONT = 8, /* text is a fragment of a continuation line */ |
213 | }; | 213 | }; |
214 | 214 | ||
215 | struct printk_log { | 215 | struct printk_log { |
216 | u64 ts_nsec; /* timestamp in nanoseconds */ | 216 | u64 ts_nsec; /* timestamp in nanoseconds */ |
217 | u16 len; /* length of entire record */ | 217 | u16 len; /* length of entire record */ |
218 | u16 text_len; /* length of text buffer */ | 218 | u16 text_len; /* length of text buffer */ |
219 | u16 dict_len; /* length of dictionary buffer */ | 219 | u16 dict_len; /* length of dictionary buffer */ |
220 | u8 facility; /* syslog facility */ | 220 | u8 facility; /* syslog facility */ |
221 | u8 flags:5; /* internal record flags */ | 221 | u8 flags:5; /* internal record flags */ |
222 | u8 level:3; /* syslog level */ | 222 | u8 level:3; /* syslog level */ |
223 | }; | 223 | }; |
224 | 224 | ||
225 | /* | 225 | /* |
226 | * The logbuf_lock protects kmsg buffer, indices, counters. This can be taken | 226 | * The logbuf_lock protects kmsg buffer, indices, counters. This can be taken |
227 | * within the scheduler's rq lock. It must be released before calling | 227 | * within the scheduler's rq lock. It must be released before calling |
228 | * console_unlock() or anything else that might wake up a process. | 228 | * console_unlock() or anything else that might wake up a process. |
229 | */ | 229 | */ |
230 | static DEFINE_RAW_SPINLOCK(logbuf_lock); | 230 | static DEFINE_RAW_SPINLOCK(logbuf_lock); |
231 | 231 | ||
232 | #ifdef CONFIG_PRINTK | 232 | #ifdef CONFIG_PRINTK |
233 | DECLARE_WAIT_QUEUE_HEAD(log_wait); | 233 | DECLARE_WAIT_QUEUE_HEAD(log_wait); |
234 | /* the next printk record to read by syslog(READ) or /proc/kmsg */ | 234 | /* the next printk record to read by syslog(READ) or /proc/kmsg */ |
235 | static u64 syslog_seq; | 235 | static u64 syslog_seq; |
236 | static u32 syslog_idx; | 236 | static u32 syslog_idx; |
237 | static enum log_flags syslog_prev; | 237 | static enum log_flags syslog_prev; |
238 | static size_t syslog_partial; | 238 | static size_t syslog_partial; |
239 | 239 | ||
240 | /* index and sequence number of the first record stored in the buffer */ | 240 | /* index and sequence number of the first record stored in the buffer */ |
241 | static u64 log_first_seq; | 241 | static u64 log_first_seq; |
242 | static u32 log_first_idx; | 242 | static u32 log_first_idx; |
243 | 243 | ||
244 | /* index and sequence number of the next record to store in the buffer */ | 244 | /* index and sequence number of the next record to store in the buffer */ |
245 | static u64 log_next_seq; | 245 | static u64 log_next_seq; |
246 | static u32 log_next_idx; | 246 | static u32 log_next_idx; |
247 | 247 | ||
248 | /* the next printk record to write to the console */ | 248 | /* the next printk record to write to the console */ |
249 | static u64 console_seq; | 249 | static u64 console_seq; |
250 | static u32 console_idx; | 250 | static u32 console_idx; |
251 | static enum log_flags console_prev; | 251 | static enum log_flags console_prev; |
252 | 252 | ||
253 | /* the next printk record to read after the last 'clear' command */ | 253 | /* the next printk record to read after the last 'clear' command */ |
254 | static u64 clear_seq; | 254 | static u64 clear_seq; |
255 | static u32 clear_idx; | 255 | static u32 clear_idx; |
256 | 256 | ||
257 | #define PREFIX_MAX 32 | 257 | #define PREFIX_MAX 32 |
258 | #define LOG_LINE_MAX (1024 - PREFIX_MAX) | 258 | #define LOG_LINE_MAX (1024 - PREFIX_MAX) |
259 | 259 | ||
260 | /* record buffer */ | 260 | /* record buffer */ |
261 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | 261 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |
262 | #define LOG_ALIGN 4 | 262 | #define LOG_ALIGN 4 |
263 | #else | 263 | #else |
264 | #define LOG_ALIGN __alignof__(struct printk_log) | 264 | #define LOG_ALIGN __alignof__(struct printk_log) |
265 | #endif | 265 | #endif |
266 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) | 266 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) |
267 | static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); | 267 | static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); |
268 | static char *log_buf = __log_buf; | 268 | static char *log_buf = __log_buf; |
269 | static u32 log_buf_len = __LOG_BUF_LEN; | 269 | static u32 log_buf_len = __LOG_BUF_LEN; |
270 | 270 | ||
271 | /* Return log buffer address */ | 271 | /* Return log buffer address */ |
272 | char *log_buf_addr_get(void) | 272 | char *log_buf_addr_get(void) |
273 | { | 273 | { |
274 | return log_buf; | 274 | return log_buf; |
275 | } | 275 | } |
276 | 276 | ||
277 | /* Return log buffer size */ | 277 | /* Return log buffer size */ |
278 | u32 log_buf_len_get(void) | 278 | u32 log_buf_len_get(void) |
279 | { | 279 | { |
280 | return log_buf_len; | 280 | return log_buf_len; |
281 | } | 281 | } |
282 | 282 | ||
283 | /* human readable text of the record */ | 283 | /* human readable text of the record */ |
284 | static char *log_text(const struct printk_log *msg) | 284 | static char *log_text(const struct printk_log *msg) |
285 | { | 285 | { |
286 | return (char *)msg + sizeof(struct printk_log); | 286 | return (char *)msg + sizeof(struct printk_log); |
287 | } | 287 | } |
288 | 288 | ||
289 | /* optional key/value pair dictionary attached to the record */ | 289 | /* optional key/value pair dictionary attached to the record */ |
290 | static char *log_dict(const struct printk_log *msg) | 290 | static char *log_dict(const struct printk_log *msg) |
291 | { | 291 | { |
292 | return (char *)msg + sizeof(struct printk_log) + msg->text_len; | 292 | return (char *)msg + sizeof(struct printk_log) + msg->text_len; |
293 | } | 293 | } |
294 | 294 | ||
295 | /* get record by index; idx must point to valid msg */ | 295 | /* get record by index; idx must point to valid msg */ |
296 | static struct printk_log *log_from_idx(u32 idx) | 296 | static struct printk_log *log_from_idx(u32 idx) |
297 | { | 297 | { |
298 | struct printk_log *msg = (struct printk_log *)(log_buf + idx); | 298 | struct printk_log *msg = (struct printk_log *)(log_buf + idx); |
299 | 299 | ||
300 | /* | 300 | /* |
301 | * A length == 0 record is the end of buffer marker. Wrap around and | 301 | * A length == 0 record is the end of buffer marker. Wrap around and |
302 | * read the message at the start of the buffer. | 302 | * read the message at the start of the buffer. |
303 | */ | 303 | */ |
304 | if (!msg->len) | 304 | if (!msg->len) |
305 | return (struct printk_log *)log_buf; | 305 | return (struct printk_log *)log_buf; |
306 | return msg; | 306 | return msg; |
307 | } | 307 | } |
308 | 308 | ||
309 | /* get next record; idx must point to valid msg */ | 309 | /* get next record; idx must point to valid msg */ |
310 | static u32 log_next(u32 idx) | 310 | static u32 log_next(u32 idx) |
311 | { | 311 | { |
312 | struct printk_log *msg = (struct printk_log *)(log_buf + idx); | 312 | struct printk_log *msg = (struct printk_log *)(log_buf + idx); |
313 | 313 | ||
314 | /* length == 0 indicates the end of the buffer; wrap */ | 314 | /* length == 0 indicates the end of the buffer; wrap */ |
315 | /* | 315 | /* |
316 | * A length == 0 record is the end of buffer marker. Wrap around and | 316 | * A length == 0 record is the end of buffer marker. Wrap around and |
317 | * read the message at the start of the buffer as *this* one, and | 317 | * read the message at the start of the buffer as *this* one, and |
318 | * return the one after that. | 318 | * return the one after that. |
319 | */ | 319 | */ |
320 | if (!msg->len) { | 320 | if (!msg->len) { |
321 | msg = (struct printk_log *)log_buf; | 321 | msg = (struct printk_log *)log_buf; |
322 | return msg->len; | 322 | return msg->len; |
323 | } | 323 | } |
324 | return idx + msg->len; | 324 | return idx + msg->len; |
325 | } | 325 | } |
326 | 326 | ||
327 | /* | 327 | /* |
328 | * Check whether there is enough free space for the given message. | 328 | * Check whether there is enough free space for the given message. |
329 | * | 329 | * |
330 | * The same values of first_idx and next_idx mean that the buffer | 330 | * The same values of first_idx and next_idx mean that the buffer |
331 | * is either empty or full. | 331 | * is either empty or full. |
332 | * | 332 | * |
333 | * If the buffer is empty, we must respect the position of the indexes. | 333 | * If the buffer is empty, we must respect the position of the indexes. |
334 | * They cannot be reset to the beginning of the buffer. | 334 | * They cannot be reset to the beginning of the buffer. |
335 | */ | 335 | */ |
336 | static int logbuf_has_space(u32 msg_size, bool empty) | 336 | static int logbuf_has_space(u32 msg_size, bool empty) |
337 | { | 337 | { |
338 | u32 free; | 338 | u32 free; |
339 | 339 | ||
340 | if (log_next_idx > log_first_idx || empty) | 340 | if (log_next_idx > log_first_idx || empty) |
341 | free = max(log_buf_len - log_next_idx, log_first_idx); | 341 | free = max(log_buf_len - log_next_idx, log_first_idx); |
342 | else | 342 | else |
343 | free = log_first_idx - log_next_idx; | 343 | free = log_first_idx - log_next_idx; |
344 | 344 | ||
345 | /* | 345 | /* |
346 | * We need space also for an empty header that signalizes wrapping | 346 | * We need space also for an empty header that signalizes wrapping |
347 | * of the buffer. | 347 | * of the buffer. |
348 | */ | 348 | */ |
349 | return free >= msg_size + sizeof(struct printk_log); | 349 | return free >= msg_size + sizeof(struct printk_log); |
350 | } | 350 | } |
351 | 351 | ||
352 | static int log_make_free_space(u32 msg_size) | 352 | static int log_make_free_space(u32 msg_size) |
353 | { | 353 | { |
354 | while (log_first_seq < log_next_seq) { | 354 | while (log_first_seq < log_next_seq) { |
355 | if (logbuf_has_space(msg_size, false)) | 355 | if (logbuf_has_space(msg_size, false)) |
356 | return 0; | 356 | return 0; |
357 | /* drop old messages until we have enough contiguous space */ | 357 | /* drop old messages until we have enough contiguous space */ |
358 | log_first_idx = log_next(log_first_idx); | 358 | log_first_idx = log_next(log_first_idx); |
359 | log_first_seq++; | 359 | log_first_seq++; |
360 | } | 360 | } |
361 | 361 | ||
362 | /* sequence numbers are equal, so the log buffer is empty */ | 362 | /* sequence numbers are equal, so the log buffer is empty */ |
363 | if (logbuf_has_space(msg_size, true)) | 363 | if (logbuf_has_space(msg_size, true)) |
364 | return 0; | 364 | return 0; |
365 | 365 | ||
366 | return -ENOMEM; | 366 | return -ENOMEM; |
367 | } | 367 | } |
368 | 368 | ||
369 | /* compute the message size including the padding bytes */ | 369 | /* compute the message size including the padding bytes */ |
370 | static u32 msg_used_size(u16 text_len, u16 dict_len, u32 *pad_len) | 370 | static u32 msg_used_size(u16 text_len, u16 dict_len, u32 *pad_len) |
371 | { | 371 | { |
372 | u32 size; | 372 | u32 size; |
373 | 373 | ||
374 | size = sizeof(struct printk_log) + text_len + dict_len; | 374 | size = sizeof(struct printk_log) + text_len + dict_len; |
375 | *pad_len = (-size) & (LOG_ALIGN - 1); | 375 | *pad_len = (-size) & (LOG_ALIGN - 1); |
376 | size += *pad_len; | 376 | size += *pad_len; |
377 | 377 | ||
378 | return size; | 378 | return size; |
379 | } | 379 | } |
380 | 380 | ||
381 | /* | 381 | /* |
382 | * Define how much of the log buffer we could take at maximum. The value | 382 | * Define how much of the log buffer we could take at maximum. The value |
383 | * must be greater than two. Note that only half of the buffer is available | 383 | * must be greater than two. Note that only half of the buffer is available |
384 | * when the index points to the middle. | 384 | * when the index points to the middle. |
385 | */ | 385 | */ |
386 | #define MAX_LOG_TAKE_PART 4 | 386 | #define MAX_LOG_TAKE_PART 4 |
387 | static const char trunc_msg[] = "<truncated>"; | 387 | static const char trunc_msg[] = "<truncated>"; |
388 | 388 | ||
389 | static u32 truncate_msg(u16 *text_len, u16 *trunc_msg_len, | 389 | static u32 truncate_msg(u16 *text_len, u16 *trunc_msg_len, |
390 | u16 *dict_len, u32 *pad_len) | 390 | u16 *dict_len, u32 *pad_len) |
391 | { | 391 | { |
392 | /* | 392 | /* |
393 | * The message should not take the whole buffer. Otherwise, it might | 393 | * The message should not take the whole buffer. Otherwise, it might |
394 | * get removed too soon. | 394 | * get removed too soon. |
395 | */ | 395 | */ |
396 | u32 max_text_len = log_buf_len / MAX_LOG_TAKE_PART; | 396 | u32 max_text_len = log_buf_len / MAX_LOG_TAKE_PART; |
397 | if (*text_len > max_text_len) | 397 | if (*text_len > max_text_len) |
398 | *text_len = max_text_len; | 398 | *text_len = max_text_len; |
399 | /* enable the warning message */ | 399 | /* enable the warning message */ |
400 | *trunc_msg_len = strlen(trunc_msg); | 400 | *trunc_msg_len = strlen(trunc_msg); |
401 | /* disable the "dict" completely */ | 401 | /* disable the "dict" completely */ |
402 | *dict_len = 0; | 402 | *dict_len = 0; |
403 | /* compute the size again, count also the warning message */ | 403 | /* compute the size again, count also the warning message */ |
404 | return msg_used_size(*text_len + *trunc_msg_len, 0, pad_len); | 404 | return msg_used_size(*text_len + *trunc_msg_len, 0, pad_len); |
405 | } | 405 | } |
406 | 406 | ||
407 | /* insert record into the buffer, discard old ones, update heads */ | 407 | /* insert record into the buffer, discard old ones, update heads */ |
408 | static int log_store(int facility, int level, | 408 | static int log_store(int facility, int level, |
409 | enum log_flags flags, u64 ts_nsec, | 409 | enum log_flags flags, u64 ts_nsec, |
410 | const char *dict, u16 dict_len, | 410 | const char *dict, u16 dict_len, |
411 | const char *text, u16 text_len) | 411 | const char *text, u16 text_len) |
412 | { | 412 | { |
413 | struct printk_log *msg; | 413 | struct printk_log *msg; |
414 | u32 size, pad_len; | 414 | u32 size, pad_len; |
415 | u16 trunc_msg_len = 0; | 415 | u16 trunc_msg_len = 0; |
416 | 416 | ||
417 | /* number of '\0' padding bytes to next message */ | 417 | /* number of '\0' padding bytes to next message */ |
418 | size = msg_used_size(text_len, dict_len, &pad_len); | 418 | size = msg_used_size(text_len, dict_len, &pad_len); |
419 | 419 | ||
420 | if (log_make_free_space(size)) { | 420 | if (log_make_free_space(size)) { |
421 | /* truncate the message if it is too long for empty buffer */ | 421 | /* truncate the message if it is too long for empty buffer */ |
422 | size = truncate_msg(&text_len, &trunc_msg_len, | 422 | size = truncate_msg(&text_len, &trunc_msg_len, |
423 | &dict_len, &pad_len); | 423 | &dict_len, &pad_len); |
424 | /* survive when the log buffer is too small for trunc_msg */ | 424 | /* survive when the log buffer is too small for trunc_msg */ |
425 | if (log_make_free_space(size)) | 425 | if (log_make_free_space(size)) |
426 | return 0; | 426 | return 0; |
427 | } | 427 | } |
428 | 428 | ||
429 | if (log_next_idx + size + sizeof(struct printk_log) > log_buf_len) { | 429 | if (log_next_idx + size + sizeof(struct printk_log) > log_buf_len) { |
430 | /* | 430 | /* |
431 | * This message + an additional empty header does not fit | 431 | * This message + an additional empty header does not fit |
432 | * at the end of the buffer. Add an empty header with len == 0 | 432 | * at the end of the buffer. Add an empty header with len == 0 |
433 | * to signify a wrap around. | 433 | * to signify a wrap around. |
434 | */ | 434 | */ |
435 | memset(log_buf + log_next_idx, 0, sizeof(struct printk_log)); | 435 | memset(log_buf + log_next_idx, 0, sizeof(struct printk_log)); |
436 | log_next_idx = 0; | 436 | log_next_idx = 0; |
437 | } | 437 | } |
438 | 438 | ||
439 | /* fill message */ | 439 | /* fill message */ |
440 | msg = (struct printk_log *)(log_buf + log_next_idx); | 440 | msg = (struct printk_log *)(log_buf + log_next_idx); |
441 | memcpy(log_text(msg), text, text_len); | 441 | memcpy(log_text(msg), text, text_len); |
442 | msg->text_len = text_len; | 442 | msg->text_len = text_len; |
443 | if (trunc_msg_len) { | 443 | if (trunc_msg_len) { |
444 | memcpy(log_text(msg) + text_len, trunc_msg, trunc_msg_len); | 444 | memcpy(log_text(msg) + text_len, trunc_msg, trunc_msg_len); |
445 | msg->text_len += trunc_msg_len; | 445 | msg->text_len += trunc_msg_len; |
446 | } | 446 | } |
447 | memcpy(log_dict(msg), dict, dict_len); | 447 | memcpy(log_dict(msg), dict, dict_len); |
448 | msg->dict_len = dict_len; | 448 | msg->dict_len = dict_len; |
449 | msg->facility = facility; | 449 | msg->facility = facility; |
450 | msg->level = level & 7; | 450 | msg->level = level & 7; |
451 | msg->flags = flags & 0x1f; | 451 | msg->flags = flags & 0x1f; |
452 | if (ts_nsec > 0) | 452 | if (ts_nsec > 0) |
453 | msg->ts_nsec = ts_nsec; | 453 | msg->ts_nsec = ts_nsec; |
454 | else | 454 | else |
455 | msg->ts_nsec = local_clock(); | 455 | msg->ts_nsec = local_clock(); |
456 | memset(log_dict(msg) + dict_len, 0, pad_len); | 456 | memset(log_dict(msg) + dict_len, 0, pad_len); |
457 | msg->len = size; | 457 | msg->len = size; |
458 | 458 | ||
459 | /* insert message */ | 459 | /* insert message */ |
460 | log_next_idx += msg->len; | 460 | log_next_idx += msg->len; |
461 | log_next_seq++; | 461 | log_next_seq++; |
462 | 462 | ||
463 | return msg->text_len; | 463 | return msg->text_len; |
464 | } | 464 | } |
465 | 465 | ||
466 | int dmesg_restrict = IS_ENABLED(CONFIG_SECURITY_DMESG_RESTRICT); | 466 | int dmesg_restrict = IS_ENABLED(CONFIG_SECURITY_DMESG_RESTRICT); |
467 | 467 | ||
468 | static int syslog_action_restricted(int type) | 468 | static int syslog_action_restricted(int type) |
469 | { | 469 | { |
470 | if (dmesg_restrict) | 470 | if (dmesg_restrict) |
471 | return 1; | 471 | return 1; |
472 | /* | 472 | /* |
473 | * Unless restricted, we allow "read all" and "get buffer size" | 473 | * Unless restricted, we allow "read all" and "get buffer size" |
474 | * for everybody. | 474 | * for everybody. |
475 | */ | 475 | */ |
476 | return type != SYSLOG_ACTION_READ_ALL && | 476 | return type != SYSLOG_ACTION_READ_ALL && |
477 | type != SYSLOG_ACTION_SIZE_BUFFER; | 477 | type != SYSLOG_ACTION_SIZE_BUFFER; |
478 | } | 478 | } |
479 | 479 | ||
480 | int check_syslog_permissions(int type, bool from_file) | 480 | int check_syslog_permissions(int type, bool from_file) |
481 | { | 481 | { |
482 | /* | 482 | /* |
483 | * If this is from /proc/kmsg and we've already opened it, then we've | 483 | * If this is from /proc/kmsg and we've already opened it, then we've |
484 | * already done the capabilities checks at open time. | 484 | * already done the capabilities checks at open time. |
485 | */ | 485 | */ |
486 | if (from_file && type != SYSLOG_ACTION_OPEN) | 486 | if (from_file && type != SYSLOG_ACTION_OPEN) |
487 | return 0; | 487 | return 0; |
488 | 488 | ||
489 | if (syslog_action_restricted(type)) { | 489 | if (syslog_action_restricted(type)) { |
490 | if (capable(CAP_SYSLOG)) | 490 | if (capable(CAP_SYSLOG)) |
491 | return 0; | 491 | return 0; |
492 | /* | 492 | /* |
493 | * For historical reasons, accept CAP_SYS_ADMIN too, with | 493 | * For historical reasons, accept CAP_SYS_ADMIN too, with |
494 | * a warning. | 494 | * a warning. |
495 | */ | 495 | */ |
496 | if (capable(CAP_SYS_ADMIN)) { | 496 | if (capable(CAP_SYS_ADMIN)) { |
497 | pr_warn_once("%s (%d): Attempt to access syslog with " | 497 | pr_warn_once("%s (%d): Attempt to access syslog with " |
498 | "CAP_SYS_ADMIN but no CAP_SYSLOG " | 498 | "CAP_SYS_ADMIN but no CAP_SYSLOG " |
499 | "(deprecated).\n", | 499 | "(deprecated).\n", |
500 | current->comm, task_pid_nr(current)); | 500 | current->comm, task_pid_nr(current)); |
501 | return 0; | 501 | return 0; |
502 | } | 502 | } |
503 | return -EPERM; | 503 | return -EPERM; |
504 | } | 504 | } |
505 | return security_syslog(type); | 505 | return security_syslog(type); |
506 | } | 506 | } |
507 | 507 | ||
508 | 508 | ||
509 | /* /dev/kmsg - userspace message inject/listen interface */ | 509 | /* /dev/kmsg - userspace message inject/listen interface */ |
510 | struct devkmsg_user { | 510 | struct devkmsg_user { |
511 | u64 seq; | 511 | u64 seq; |
512 | u32 idx; | 512 | u32 idx; |
513 | enum log_flags prev; | 513 | enum log_flags prev; |
514 | struct mutex lock; | 514 | struct mutex lock; |
515 | char buf[8192]; | 515 | char buf[8192]; |
516 | }; | 516 | }; |
517 | 517 | ||
518 | static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) | 518 | static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) |
519 | { | 519 | { |
520 | char *buf, *line; | 520 | char *buf, *line; |
521 | int i; | 521 | int i; |
522 | int level = default_message_loglevel; | 522 | int level = default_message_loglevel; |
523 | int facility = 1; /* LOG_USER */ | 523 | int facility = 1; /* LOG_USER */ |
524 | size_t len = iocb->ki_nbytes; | 524 | size_t len = iocb->ki_nbytes; |
525 | ssize_t ret = len; | 525 | ssize_t ret = len; |
526 | 526 | ||
527 | if (len > LOG_LINE_MAX) | 527 | if (len > LOG_LINE_MAX) |
528 | return -EINVAL; | 528 | return -EINVAL; |
529 | buf = kmalloc(len+1, GFP_KERNEL); | 529 | buf = kmalloc(len+1, GFP_KERNEL); |
530 | if (buf == NULL) | 530 | if (buf == NULL) |
531 | return -ENOMEM; | 531 | return -ENOMEM; |
532 | 532 | ||
533 | buf[len] = '\0'; | 533 | buf[len] = '\0'; |
534 | if (copy_from_iter(buf, len, from) != len) { | 534 | if (copy_from_iter(buf, len, from) != len) { |
535 | kfree(buf); | 535 | kfree(buf); |
536 | return -EFAULT; | 536 | return -EFAULT; |
537 | } | 537 | } |
538 | 538 | ||
539 | /* | 539 | /* |
540 | * Extract and skip the syslog prefix <[0-9]*>. Coming from userspace | 540 | * Extract and skip the syslog prefix <[0-9]*>. Coming from userspace |
541 | * the decimal value represents 32bit, the lower 3 bit are the log | 541 | * the decimal value represents 32bit, the lower 3 bit are the log |
542 | * level, the rest are the log facility. | 542 | * level, the rest are the log facility. |
543 | * | 543 | * |
544 | * If no prefix or no userspace facility is specified, we | 544 | * If no prefix or no userspace facility is specified, we |
545 | * enforce LOG_USER, to be able to reliably distinguish | 545 | * enforce LOG_USER, to be able to reliably distinguish |
546 | * kernel-generated messages from userspace-injected ones. | 546 | * kernel-generated messages from userspace-injected ones. |
547 | */ | 547 | */ |
548 | line = buf; | 548 | line = buf; |
549 | if (line[0] == '<') { | 549 | if (line[0] == '<') { |
550 | char *endp = NULL; | 550 | char *endp = NULL; |
551 | 551 | ||
552 | i = simple_strtoul(line+1, &endp, 10); | 552 | i = simple_strtoul(line+1, &endp, 10); |
553 | if (endp && endp[0] == '>') { | 553 | if (endp && endp[0] == '>') { |
554 | level = i & 7; | 554 | level = i & 7; |
555 | if (i >> 3) | 555 | if (i >> 3) |
556 | facility = i >> 3; | 556 | facility = i >> 3; |
557 | endp++; | 557 | endp++; |
558 | len -= endp - line; | 558 | len -= endp - line; |
559 | line = endp; | 559 | line = endp; |
560 | } | 560 | } |
561 | } | 561 | } |
562 | 562 | ||
563 | printk_emit(facility, level, NULL, 0, "%s", line); | 563 | printk_emit(facility, level, NULL, 0, "%s", line); |
564 | kfree(buf); | 564 | kfree(buf); |
565 | return ret; | 565 | return ret; |
566 | } | 566 | } |
567 | 567 | ||
568 | static ssize_t devkmsg_read(struct file *file, char __user *buf, | 568 | static ssize_t devkmsg_read(struct file *file, char __user *buf, |
569 | size_t count, loff_t *ppos) | 569 | size_t count, loff_t *ppos) |
570 | { | 570 | { |
571 | struct devkmsg_user *user = file->private_data; | 571 | struct devkmsg_user *user = file->private_data; |
572 | struct printk_log *msg; | 572 | struct printk_log *msg; |
573 | u64 ts_usec; | 573 | u64 ts_usec; |
574 | size_t i; | 574 | size_t i; |
575 | char cont = '-'; | 575 | char cont = '-'; |
576 | size_t len; | 576 | size_t len; |
577 | ssize_t ret; | 577 | ssize_t ret; |
578 | 578 | ||
579 | if (!user) | 579 | if (!user) |
580 | return -EBADF; | 580 | return -EBADF; |
581 | 581 | ||
582 | ret = mutex_lock_interruptible(&user->lock); | 582 | ret = mutex_lock_interruptible(&user->lock); |
583 | if (ret) | 583 | if (ret) |
584 | return ret; | 584 | return ret; |
585 | raw_spin_lock_irq(&logbuf_lock); | 585 | raw_spin_lock_irq(&logbuf_lock); |
586 | while (user->seq == log_next_seq) { | 586 | while (user->seq == log_next_seq) { |
587 | if (file->f_flags & O_NONBLOCK) { | 587 | if (file->f_flags & O_NONBLOCK) { |
588 | ret = -EAGAIN; | 588 | ret = -EAGAIN; |
589 | raw_spin_unlock_irq(&logbuf_lock); | 589 | raw_spin_unlock_irq(&logbuf_lock); |
590 | goto out; | 590 | goto out; |
591 | } | 591 | } |
592 | 592 | ||
593 | raw_spin_unlock_irq(&logbuf_lock); | 593 | raw_spin_unlock_irq(&logbuf_lock); |
594 | ret = wait_event_interruptible(log_wait, | 594 | ret = wait_event_interruptible(log_wait, |
595 | user->seq != log_next_seq); | 595 | user->seq != log_next_seq); |
596 | if (ret) | 596 | if (ret) |
597 | goto out; | 597 | goto out; |
598 | raw_spin_lock_irq(&logbuf_lock); | 598 | raw_spin_lock_irq(&logbuf_lock); |
599 | } | 599 | } |
600 | 600 | ||
601 | if (user->seq < log_first_seq) { | 601 | if (user->seq < log_first_seq) { |
602 | /* our last seen message is gone, return error and reset */ | 602 | /* our last seen message is gone, return error and reset */ |
603 | user->idx = log_first_idx; | 603 | user->idx = log_first_idx; |
604 | user->seq = log_first_seq; | 604 | user->seq = log_first_seq; |
605 | ret = -EPIPE; | 605 | ret = -EPIPE; |
606 | raw_spin_unlock_irq(&logbuf_lock); | 606 | raw_spin_unlock_irq(&logbuf_lock); |
607 | goto out; | 607 | goto out; |
608 | } | 608 | } |
609 | 609 | ||
610 | msg = log_from_idx(user->idx); | 610 | msg = log_from_idx(user->idx); |
611 | ts_usec = msg->ts_nsec; | 611 | ts_usec = msg->ts_nsec; |
612 | do_div(ts_usec, 1000); | 612 | do_div(ts_usec, 1000); |
613 | 613 | ||
614 | /* | 614 | /* |
615 | * If we couldn't merge continuation line fragments during the print, | 615 | * If we couldn't merge continuation line fragments during the print, |
616 | * export the stored flags to allow an optional external merge of the | 616 | * export the stored flags to allow an optional external merge of the |
617 | * records. Merging the records isn't always neccessarily correct, like | 617 | * records. Merging the records isn't always neccessarily correct, like |
618 | * when we hit a race during printing. In most cases though, it produces | 618 | * when we hit a race during printing. In most cases though, it produces |
619 | * better readable output. 'c' in the record flags mark the first | 619 | * better readable output. 'c' in the record flags mark the first |
620 | * fragment of a line, '+' the following. | 620 | * fragment of a line, '+' the following. |
621 | */ | 621 | */ |
622 | if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT)) | 622 | if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT)) |
623 | cont = 'c'; | 623 | cont = 'c'; |
624 | else if ((msg->flags & LOG_CONT) || | 624 | else if ((msg->flags & LOG_CONT) || |
625 | ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))) | 625 | ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))) |
626 | cont = '+'; | 626 | cont = '+'; |
627 | 627 | ||
628 | len = sprintf(user->buf, "%u,%llu,%llu,%c;", | 628 | len = sprintf(user->buf, "%u,%llu,%llu,%c;", |
629 | (msg->facility << 3) | msg->level, | 629 | (msg->facility << 3) | msg->level, |
630 | user->seq, ts_usec, cont); | 630 | user->seq, ts_usec, cont); |
631 | user->prev = msg->flags; | 631 | user->prev = msg->flags; |
632 | 632 | ||
633 | /* escape non-printable characters */ | 633 | /* escape non-printable characters */ |
634 | for (i = 0; i < msg->text_len; i++) { | 634 | for (i = 0; i < msg->text_len; i++) { |
635 | unsigned char c = log_text(msg)[i]; | 635 | unsigned char c = log_text(msg)[i]; |
636 | 636 | ||
637 | if (c < ' ' || c >= 127 || c == '\\') | 637 | if (c < ' ' || c >= 127 || c == '\\') |
638 | len += sprintf(user->buf + len, "\\x%02x", c); | 638 | len += sprintf(user->buf + len, "\\x%02x", c); |
639 | else | 639 | else |
640 | user->buf[len++] = c; | 640 | user->buf[len++] = c; |
641 | } | 641 | } |
642 | user->buf[len++] = '\n'; | 642 | user->buf[len++] = '\n'; |
643 | 643 | ||
644 | if (msg->dict_len) { | 644 | if (msg->dict_len) { |
645 | bool line = true; | 645 | bool line = true; |
646 | 646 | ||
647 | for (i = 0; i < msg->dict_len; i++) { | 647 | for (i = 0; i < msg->dict_len; i++) { |
648 | unsigned char c = log_dict(msg)[i]; | 648 | unsigned char c = log_dict(msg)[i]; |
649 | 649 | ||
650 | if (line) { | 650 | if (line) { |
651 | user->buf[len++] = ' '; | 651 | user->buf[len++] = ' '; |
652 | line = false; | 652 | line = false; |
653 | } | 653 | } |
654 | 654 | ||
655 | if (c == '\0') { | 655 | if (c == '\0') { |
656 | user->buf[len++] = '\n'; | 656 | user->buf[len++] = '\n'; |
657 | line = true; | 657 | line = true; |
658 | continue; | 658 | continue; |
659 | } | 659 | } |
660 | 660 | ||
661 | if (c < ' ' || c >= 127 || c == '\\') { | 661 | if (c < ' ' || c >= 127 || c == '\\') { |
662 | len += sprintf(user->buf + len, "\\x%02x", c); | 662 | len += sprintf(user->buf + len, "\\x%02x", c); |
663 | continue; | 663 | continue; |
664 | } | 664 | } |
665 | 665 | ||
666 | user->buf[len++] = c; | 666 | user->buf[len++] = c; |
667 | } | 667 | } |
668 | user->buf[len++] = '\n'; | 668 | user->buf[len++] = '\n'; |
669 | } | 669 | } |
670 | 670 | ||
671 | user->idx = log_next(user->idx); | 671 | user->idx = log_next(user->idx); |
672 | user->seq++; | 672 | user->seq++; |
673 | raw_spin_unlock_irq(&logbuf_lock); | 673 | raw_spin_unlock_irq(&logbuf_lock); |
674 | 674 | ||
675 | if (len > count) { | 675 | if (len > count) { |
676 | ret = -EINVAL; | 676 | ret = -EINVAL; |
677 | goto out; | 677 | goto out; |
678 | } | 678 | } |
679 | 679 | ||
680 | if (copy_to_user(buf, user->buf, len)) { | 680 | if (copy_to_user(buf, user->buf, len)) { |
681 | ret = -EFAULT; | 681 | ret = -EFAULT; |
682 | goto out; | 682 | goto out; |
683 | } | 683 | } |
684 | ret = len; | 684 | ret = len; |
685 | out: | 685 | out: |
686 | mutex_unlock(&user->lock); | 686 | mutex_unlock(&user->lock); |
687 | return ret; | 687 | return ret; |
688 | } | 688 | } |
689 | 689 | ||
690 | static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence) | 690 | static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence) |
691 | { | 691 | { |
692 | struct devkmsg_user *user = file->private_data; | 692 | struct devkmsg_user *user = file->private_data; |
693 | loff_t ret = 0; | 693 | loff_t ret = 0; |
694 | 694 | ||
695 | if (!user) | 695 | if (!user) |
696 | return -EBADF; | 696 | return -EBADF; |
697 | if (offset) | 697 | if (offset) |
698 | return -ESPIPE; | 698 | return -ESPIPE; |
699 | 699 | ||
700 | raw_spin_lock_irq(&logbuf_lock); | 700 | raw_spin_lock_irq(&logbuf_lock); |
701 | switch (whence) { | 701 | switch (whence) { |
702 | case SEEK_SET: | 702 | case SEEK_SET: |
703 | /* the first record */ | 703 | /* the first record */ |
704 | user->idx = log_first_idx; | 704 | user->idx = log_first_idx; |
705 | user->seq = log_first_seq; | 705 | user->seq = log_first_seq; |
706 | break; | 706 | break; |
707 | case SEEK_DATA: | 707 | case SEEK_DATA: |
708 | /* | 708 | /* |
709 | * The first record after the last SYSLOG_ACTION_CLEAR, | 709 | * The first record after the last SYSLOG_ACTION_CLEAR, |
710 | * like issued by 'dmesg -c'. Reading /dev/kmsg itself | 710 | * like issued by 'dmesg -c'. Reading /dev/kmsg itself |
711 | * changes no global state, and does not clear anything. | 711 | * changes no global state, and does not clear anything. |
712 | */ | 712 | */ |
713 | user->idx = clear_idx; | 713 | user->idx = clear_idx; |
714 | user->seq = clear_seq; | 714 | user->seq = clear_seq; |
715 | break; | 715 | break; |
716 | case SEEK_END: | 716 | case SEEK_END: |
717 | /* after the last record */ | 717 | /* after the last record */ |
718 | user->idx = log_next_idx; | 718 | user->idx = log_next_idx; |
719 | user->seq = log_next_seq; | 719 | user->seq = log_next_seq; |
720 | break; | 720 | break; |
721 | default: | 721 | default: |
722 | ret = -EINVAL; | 722 | ret = -EINVAL; |
723 | } | 723 | } |
724 | raw_spin_unlock_irq(&logbuf_lock); | 724 | raw_spin_unlock_irq(&logbuf_lock); |
725 | return ret; | 725 | return ret; |
726 | } | 726 | } |
727 | 727 | ||
728 | static unsigned int devkmsg_poll(struct file *file, poll_table *wait) | 728 | static unsigned int devkmsg_poll(struct file *file, poll_table *wait) |
729 | { | 729 | { |
730 | struct devkmsg_user *user = file->private_data; | 730 | struct devkmsg_user *user = file->private_data; |
731 | int ret = 0; | 731 | int ret = 0; |
732 | 732 | ||
733 | if (!user) | 733 | if (!user) |
734 | return POLLERR|POLLNVAL; | 734 | return POLLERR|POLLNVAL; |
735 | 735 | ||
736 | poll_wait(file, &log_wait, wait); | 736 | poll_wait(file, &log_wait, wait); |
737 | 737 | ||
738 | raw_spin_lock_irq(&logbuf_lock); | 738 | raw_spin_lock_irq(&logbuf_lock); |
739 | if (user->seq < log_next_seq) { | 739 | if (user->seq < log_next_seq) { |
740 | /* return error when data has vanished underneath us */ | 740 | /* return error when data has vanished underneath us */ |
741 | if (user->seq < log_first_seq) | 741 | if (user->seq < log_first_seq) |
742 | ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI; | 742 | ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI; |
743 | else | 743 | else |
744 | ret = POLLIN|POLLRDNORM; | 744 | ret = POLLIN|POLLRDNORM; |
745 | } | 745 | } |
746 | raw_spin_unlock_irq(&logbuf_lock); | 746 | raw_spin_unlock_irq(&logbuf_lock); |
747 | 747 | ||
748 | return ret; | 748 | return ret; |
749 | } | 749 | } |
750 | 750 | ||
751 | static int devkmsg_open(struct inode *inode, struct file *file) | 751 | static int devkmsg_open(struct inode *inode, struct file *file) |
752 | { | 752 | { |
753 | struct devkmsg_user *user; | 753 | struct devkmsg_user *user; |
754 | int err; | 754 | int err; |
755 | 755 | ||
756 | /* write-only does not need any file context */ | 756 | /* write-only does not need any file context */ |
757 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 757 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
758 | return 0; | 758 | return 0; |
759 | 759 | ||
760 | err = check_syslog_permissions(SYSLOG_ACTION_READ_ALL, | 760 | err = check_syslog_permissions(SYSLOG_ACTION_READ_ALL, |
761 | SYSLOG_FROM_READER); | 761 | SYSLOG_FROM_READER); |
762 | if (err) | 762 | if (err) |
763 | return err; | 763 | return err; |
764 | 764 | ||
765 | user = kmalloc(sizeof(struct devkmsg_user), GFP_KERNEL); | 765 | user = kmalloc(sizeof(struct devkmsg_user), GFP_KERNEL); |
766 | if (!user) | 766 | if (!user) |
767 | return -ENOMEM; | 767 | return -ENOMEM; |
768 | 768 | ||
769 | mutex_init(&user->lock); | 769 | mutex_init(&user->lock); |
770 | 770 | ||
771 | raw_spin_lock_irq(&logbuf_lock); | 771 | raw_spin_lock_irq(&logbuf_lock); |
772 | user->idx = log_first_idx; | 772 | user->idx = log_first_idx; |
773 | user->seq = log_first_seq; | 773 | user->seq = log_first_seq; |
774 | raw_spin_unlock_irq(&logbuf_lock); | 774 | raw_spin_unlock_irq(&logbuf_lock); |
775 | 775 | ||
776 | file->private_data = user; | 776 | file->private_data = user; |
777 | return 0; | 777 | return 0; |
778 | } | 778 | } |
779 | 779 | ||
780 | static int devkmsg_release(struct inode *inode, struct file *file) | 780 | static int devkmsg_release(struct inode *inode, struct file *file) |
781 | { | 781 | { |
782 | struct devkmsg_user *user = file->private_data; | 782 | struct devkmsg_user *user = file->private_data; |
783 | 783 | ||
784 | if (!user) | 784 | if (!user) |
785 | return 0; | 785 | return 0; |
786 | 786 | ||
787 | mutex_destroy(&user->lock); | 787 | mutex_destroy(&user->lock); |
788 | kfree(user); | 788 | kfree(user); |
789 | return 0; | 789 | return 0; |
790 | } | 790 | } |
791 | 791 | ||
792 | const struct file_operations kmsg_fops = { | 792 | const struct file_operations kmsg_fops = { |
793 | .open = devkmsg_open, | 793 | .open = devkmsg_open, |
794 | .read = devkmsg_read, | 794 | .read = devkmsg_read, |
795 | .write_iter = devkmsg_write, | 795 | .write_iter = devkmsg_write, |
796 | .llseek = devkmsg_llseek, | 796 | .llseek = devkmsg_llseek, |
797 | .poll = devkmsg_poll, | 797 | .poll = devkmsg_poll, |
798 | .release = devkmsg_release, | 798 | .release = devkmsg_release, |
799 | }; | 799 | }; |
800 | 800 | ||
801 | #ifdef CONFIG_KEXEC | 801 | #ifdef CONFIG_KEXEC |
802 | /* | 802 | /* |
803 | * This appends the listed symbols to /proc/vmcore | 803 | * This appends the listed symbols to /proc/vmcore |
804 | * | 804 | * |
805 | * /proc/vmcore is used by various utilities, like crash and makedumpfile to | 805 | * /proc/vmcore is used by various utilities, like crash and makedumpfile to |
806 | * obtain access to symbols that are otherwise very difficult to locate. These | 806 | * obtain access to symbols that are otherwise very difficult to locate. These |
807 | * symbols are specifically used so that utilities can access and extract the | 807 | * symbols are specifically used so that utilities can access and extract the |
808 | * dmesg log from a vmcore file after a crash. | 808 | * dmesg log from a vmcore file after a crash. |
809 | */ | 809 | */ |
810 | void log_buf_kexec_setup(void) | 810 | void log_buf_kexec_setup(void) |
811 | { | 811 | { |
812 | VMCOREINFO_SYMBOL(log_buf); | 812 | VMCOREINFO_SYMBOL(log_buf); |
813 | VMCOREINFO_SYMBOL(log_buf_len); | 813 | VMCOREINFO_SYMBOL(log_buf_len); |
814 | VMCOREINFO_SYMBOL(log_first_idx); | 814 | VMCOREINFO_SYMBOL(log_first_idx); |
815 | VMCOREINFO_SYMBOL(log_next_idx); | 815 | VMCOREINFO_SYMBOL(log_next_idx); |
816 | /* | 816 | /* |
817 | * Export struct printk_log size and field offsets. User space tools can | 817 | * Export struct printk_log size and field offsets. User space tools can |
818 | * parse it and detect any changes to structure down the line. | 818 | * parse it and detect any changes to structure down the line. |
819 | */ | 819 | */ |
820 | VMCOREINFO_STRUCT_SIZE(printk_log); | 820 | VMCOREINFO_STRUCT_SIZE(printk_log); |
821 | VMCOREINFO_OFFSET(printk_log, ts_nsec); | 821 | VMCOREINFO_OFFSET(printk_log, ts_nsec); |
822 | VMCOREINFO_OFFSET(printk_log, len); | 822 | VMCOREINFO_OFFSET(printk_log, len); |
823 | VMCOREINFO_OFFSET(printk_log, text_len); | 823 | VMCOREINFO_OFFSET(printk_log, text_len); |
824 | VMCOREINFO_OFFSET(printk_log, dict_len); | 824 | VMCOREINFO_OFFSET(printk_log, dict_len); |
825 | } | 825 | } |
826 | #endif | 826 | #endif |
827 | 827 | ||
828 | /* requested log_buf_len from kernel cmdline */ | 828 | /* requested log_buf_len from kernel cmdline */ |
829 | static unsigned long __initdata new_log_buf_len; | 829 | static unsigned long __initdata new_log_buf_len; |
830 | 830 | ||
831 | /* we practice scaling the ring buffer by powers of 2 */ | 831 | /* we practice scaling the ring buffer by powers of 2 */ |
832 | static void __init log_buf_len_update(unsigned size) | 832 | static void __init log_buf_len_update(unsigned size) |
833 | { | 833 | { |
834 | if (size) | 834 | if (size) |
835 | size = roundup_pow_of_two(size); | 835 | size = roundup_pow_of_two(size); |
836 | if (size > log_buf_len) | 836 | if (size > log_buf_len) |
837 | new_log_buf_len = size; | 837 | new_log_buf_len = size; |
838 | } | 838 | } |
839 | 839 | ||
840 | /* save requested log_buf_len since it's too early to process it */ | 840 | /* save requested log_buf_len since it's too early to process it */ |
841 | static int __init log_buf_len_setup(char *str) | 841 | static int __init log_buf_len_setup(char *str) |
842 | { | 842 | { |
843 | unsigned size = memparse(str, &str); | 843 | unsigned size = memparse(str, &str); |
844 | 844 | ||
845 | log_buf_len_update(size); | 845 | log_buf_len_update(size); |
846 | 846 | ||
847 | return 0; | 847 | return 0; |
848 | } | 848 | } |
849 | early_param("log_buf_len", log_buf_len_setup); | 849 | early_param("log_buf_len", log_buf_len_setup); |
850 | 850 | ||
851 | #ifdef CONFIG_SMP | 851 | #ifdef CONFIG_SMP |
852 | #define __LOG_CPU_MAX_BUF_LEN (1 << CONFIG_LOG_CPU_MAX_BUF_SHIFT) | 852 | #define __LOG_CPU_MAX_BUF_LEN (1 << CONFIG_LOG_CPU_MAX_BUF_SHIFT) |
853 | 853 | ||
854 | static void __init log_buf_add_cpu(void) | 854 | static void __init log_buf_add_cpu(void) |
855 | { | 855 | { |
856 | unsigned int cpu_extra; | 856 | unsigned int cpu_extra; |
857 | 857 | ||
858 | /* | 858 | /* |
859 | * archs should set up cpu_possible_bits properly with | 859 | * archs should set up cpu_possible_bits properly with |
860 | * set_cpu_possible() after setup_arch() but just in | 860 | * set_cpu_possible() after setup_arch() but just in |
861 | * case lets ensure this is valid. | 861 | * case lets ensure this is valid. |
862 | */ | 862 | */ |
863 | if (num_possible_cpus() == 1) | 863 | if (num_possible_cpus() == 1) |
864 | return; | 864 | return; |
865 | 865 | ||
866 | cpu_extra = (num_possible_cpus() - 1) * __LOG_CPU_MAX_BUF_LEN; | 866 | cpu_extra = (num_possible_cpus() - 1) * __LOG_CPU_MAX_BUF_LEN; |
867 | 867 | ||
868 | /* by default this will only continue through for large > 64 CPUs */ | 868 | /* by default this will only continue through for large > 64 CPUs */ |
869 | if (cpu_extra <= __LOG_BUF_LEN / 2) | 869 | if (cpu_extra <= __LOG_BUF_LEN / 2) |
870 | return; | 870 | return; |
871 | 871 | ||
872 | pr_info("log_buf_len individual max cpu contribution: %d bytes\n", | 872 | pr_info("log_buf_len individual max cpu contribution: %d bytes\n", |
873 | __LOG_CPU_MAX_BUF_LEN); | 873 | __LOG_CPU_MAX_BUF_LEN); |
874 | pr_info("log_buf_len total cpu_extra contributions: %d bytes\n", | 874 | pr_info("log_buf_len total cpu_extra contributions: %d bytes\n", |
875 | cpu_extra); | 875 | cpu_extra); |
876 | pr_info("log_buf_len min size: %d bytes\n", __LOG_BUF_LEN); | 876 | pr_info("log_buf_len min size: %d bytes\n", __LOG_BUF_LEN); |
877 | 877 | ||
878 | log_buf_len_update(cpu_extra + __LOG_BUF_LEN); | 878 | log_buf_len_update(cpu_extra + __LOG_BUF_LEN); |
879 | } | 879 | } |
880 | #else /* !CONFIG_SMP */ | 880 | #else /* !CONFIG_SMP */ |
881 | static inline void log_buf_add_cpu(void) {} | 881 | static inline void log_buf_add_cpu(void) {} |
882 | #endif /* CONFIG_SMP */ | 882 | #endif /* CONFIG_SMP */ |
883 | 883 | ||
884 | void __init setup_log_buf(int early) | 884 | void __init setup_log_buf(int early) |
885 | { | 885 | { |
886 | unsigned long flags; | 886 | unsigned long flags; |
887 | char *new_log_buf; | 887 | char *new_log_buf; |
888 | int free; | 888 | int free; |
889 | 889 | ||
890 | if (log_buf != __log_buf) | 890 | if (log_buf != __log_buf) |
891 | return; | 891 | return; |
892 | 892 | ||
893 | if (!early && !new_log_buf_len) | 893 | if (!early && !new_log_buf_len) |
894 | log_buf_add_cpu(); | 894 | log_buf_add_cpu(); |
895 | 895 | ||
896 | if (!new_log_buf_len) | 896 | if (!new_log_buf_len) |
897 | return; | 897 | return; |
898 | 898 | ||
899 | if (early) { | 899 | if (early) { |
900 | new_log_buf = | 900 | new_log_buf = |
901 | memblock_virt_alloc(new_log_buf_len, LOG_ALIGN); | 901 | memblock_virt_alloc(new_log_buf_len, LOG_ALIGN); |
902 | } else { | 902 | } else { |
903 | new_log_buf = memblock_virt_alloc_nopanic(new_log_buf_len, | 903 | new_log_buf = memblock_virt_alloc_nopanic(new_log_buf_len, |
904 | LOG_ALIGN); | 904 | LOG_ALIGN); |
905 | } | 905 | } |
906 | 906 | ||
907 | if (unlikely(!new_log_buf)) { | 907 | if (unlikely(!new_log_buf)) { |
908 | pr_err("log_buf_len: %ld bytes not available\n", | 908 | pr_err("log_buf_len: %ld bytes not available\n", |
909 | new_log_buf_len); | 909 | new_log_buf_len); |
910 | return; | 910 | return; |
911 | } | 911 | } |
912 | 912 | ||
913 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 913 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
914 | log_buf_len = new_log_buf_len; | 914 | log_buf_len = new_log_buf_len; |
915 | log_buf = new_log_buf; | 915 | log_buf = new_log_buf; |
916 | new_log_buf_len = 0; | 916 | new_log_buf_len = 0; |
917 | free = __LOG_BUF_LEN - log_next_idx; | 917 | free = __LOG_BUF_LEN - log_next_idx; |
918 | memcpy(log_buf, __log_buf, __LOG_BUF_LEN); | 918 | memcpy(log_buf, __log_buf, __LOG_BUF_LEN); |
919 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 919 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
920 | 920 | ||
921 | pr_info("log_buf_len: %d bytes\n", log_buf_len); | 921 | pr_info("log_buf_len: %d bytes\n", log_buf_len); |
922 | pr_info("early log buf free: %d(%d%%)\n", | 922 | pr_info("early log buf free: %d(%d%%)\n", |
923 | free, (free * 100) / __LOG_BUF_LEN); | 923 | free, (free * 100) / __LOG_BUF_LEN); |
924 | } | 924 | } |
925 | 925 | ||
926 | static bool __read_mostly ignore_loglevel; | 926 | static bool __read_mostly ignore_loglevel; |
927 | 927 | ||
928 | static int __init ignore_loglevel_setup(char *str) | 928 | static int __init ignore_loglevel_setup(char *str) |
929 | { | 929 | { |
930 | ignore_loglevel = true; | 930 | ignore_loglevel = true; |
931 | pr_info("debug: ignoring loglevel setting.\n"); | 931 | pr_info("debug: ignoring loglevel setting.\n"); |
932 | 932 | ||
933 | return 0; | 933 | return 0; |
934 | } | 934 | } |
935 | 935 | ||
936 | early_param("ignore_loglevel", ignore_loglevel_setup); | 936 | early_param("ignore_loglevel", ignore_loglevel_setup); |
937 | module_param(ignore_loglevel, bool, S_IRUGO | S_IWUSR); | 937 | module_param(ignore_loglevel, bool, S_IRUGO | S_IWUSR); |
938 | MODULE_PARM_DESC(ignore_loglevel, | 938 | MODULE_PARM_DESC(ignore_loglevel, |
939 | "ignore loglevel setting (prints all kernel messages to the console)"); | 939 | "ignore loglevel setting (prints all kernel messages to the console)"); |
940 | 940 | ||
941 | #ifdef CONFIG_BOOT_PRINTK_DELAY | 941 | #ifdef CONFIG_BOOT_PRINTK_DELAY |
942 | 942 | ||
943 | static int boot_delay; /* msecs delay after each printk during bootup */ | 943 | static int boot_delay; /* msecs delay after each printk during bootup */ |
944 | static unsigned long long loops_per_msec; /* based on boot_delay */ | 944 | static unsigned long long loops_per_msec; /* based on boot_delay */ |
945 | 945 | ||
946 | static int __init boot_delay_setup(char *str) | 946 | static int __init boot_delay_setup(char *str) |
947 | { | 947 | { |
948 | unsigned long lpj; | 948 | unsigned long lpj; |
949 | 949 | ||
950 | lpj = preset_lpj ? preset_lpj : 1000000; /* some guess */ | 950 | lpj = preset_lpj ? preset_lpj : 1000000; /* some guess */ |
951 | loops_per_msec = (unsigned long long)lpj / 1000 * HZ; | 951 | loops_per_msec = (unsigned long long)lpj / 1000 * HZ; |
952 | 952 | ||
953 | get_option(&str, &boot_delay); | 953 | get_option(&str, &boot_delay); |
954 | if (boot_delay > 10 * 1000) | 954 | if (boot_delay > 10 * 1000) |
955 | boot_delay = 0; | 955 | boot_delay = 0; |
956 | 956 | ||
957 | pr_debug("boot_delay: %u, preset_lpj: %ld, lpj: %lu, " | 957 | pr_debug("boot_delay: %u, preset_lpj: %ld, lpj: %lu, " |
958 | "HZ: %d, loops_per_msec: %llu\n", | 958 | "HZ: %d, loops_per_msec: %llu\n", |
959 | boot_delay, preset_lpj, lpj, HZ, loops_per_msec); | 959 | boot_delay, preset_lpj, lpj, HZ, loops_per_msec); |
960 | return 0; | 960 | return 0; |
961 | } | 961 | } |
962 | early_param("boot_delay", boot_delay_setup); | 962 | early_param("boot_delay", boot_delay_setup); |
963 | 963 | ||
964 | static void boot_delay_msec(int level) | 964 | static void boot_delay_msec(int level) |
965 | { | 965 | { |
966 | unsigned long long k; | 966 | unsigned long long k; |
967 | unsigned long timeout; | 967 | unsigned long timeout; |
968 | 968 | ||
969 | if ((boot_delay == 0 || system_state != SYSTEM_BOOTING) | 969 | if ((boot_delay == 0 || system_state != SYSTEM_BOOTING) |
970 | || (level >= console_loglevel && !ignore_loglevel)) { | 970 | || (level >= console_loglevel && !ignore_loglevel)) { |
971 | return; | 971 | return; |
972 | } | 972 | } |
973 | 973 | ||
974 | k = (unsigned long long)loops_per_msec * boot_delay; | 974 | k = (unsigned long long)loops_per_msec * boot_delay; |
975 | 975 | ||
976 | timeout = jiffies + msecs_to_jiffies(boot_delay); | 976 | timeout = jiffies + msecs_to_jiffies(boot_delay); |
977 | while (k) { | 977 | while (k) { |
978 | k--; | 978 | k--; |
979 | cpu_relax(); | 979 | cpu_relax(); |
980 | /* | 980 | /* |
981 | * use (volatile) jiffies to prevent | 981 | * use (volatile) jiffies to prevent |
982 | * compiler reduction; loop termination via jiffies | 982 | * compiler reduction; loop termination via jiffies |
983 | * is secondary and may or may not happen. | 983 | * is secondary and may or may not happen. |
984 | */ | 984 | */ |
985 | if (time_after(jiffies, timeout)) | 985 | if (time_after(jiffies, timeout)) |
986 | break; | 986 | break; |
987 | touch_nmi_watchdog(); | 987 | touch_nmi_watchdog(); |
988 | } | 988 | } |
989 | } | 989 | } |
990 | #else | 990 | #else |
991 | static inline void boot_delay_msec(int level) | 991 | static inline void boot_delay_msec(int level) |
992 | { | 992 | { |
993 | } | 993 | } |
994 | #endif | 994 | #endif |
995 | 995 | ||
996 | static bool printk_time = IS_ENABLED(CONFIG_PRINTK_TIME); | 996 | static bool printk_time = IS_ENABLED(CONFIG_PRINTK_TIME); |
997 | module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); | 997 | module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); |
998 | 998 | ||
999 | static size_t print_time(u64 ts, char *buf) | 999 | static size_t print_time(u64 ts, char *buf) |
1000 | { | 1000 | { |
1001 | unsigned long rem_nsec; | 1001 | unsigned long rem_nsec; |
1002 | 1002 | ||
1003 | if (!printk_time) | 1003 | if (!printk_time) |
1004 | return 0; | 1004 | return 0; |
1005 | 1005 | ||
1006 | rem_nsec = do_div(ts, 1000000000); | 1006 | rem_nsec = do_div(ts, 1000000000); |
1007 | 1007 | ||
1008 | if (!buf) | 1008 | if (!buf) |
1009 | return snprintf(NULL, 0, "[%5lu.000000] ", (unsigned long)ts); | 1009 | return snprintf(NULL, 0, "[%5lu.000000] ", (unsigned long)ts); |
1010 | 1010 | ||
1011 | return sprintf(buf, "[%5lu.%06lu] ", | 1011 | return sprintf(buf, "[%5lu.%06lu] ", |
1012 | (unsigned long)ts, rem_nsec / 1000); | 1012 | (unsigned long)ts, rem_nsec / 1000); |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf) | 1015 | static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf) |
1016 | { | 1016 | { |
1017 | size_t len = 0; | 1017 | size_t len = 0; |
1018 | unsigned int prefix = (msg->facility << 3) | msg->level; | 1018 | unsigned int prefix = (msg->facility << 3) | msg->level; |
1019 | 1019 | ||
1020 | if (syslog) { | 1020 | if (syslog) { |
1021 | if (buf) { | 1021 | if (buf) { |
1022 | len += sprintf(buf, "<%u>", prefix); | 1022 | len += sprintf(buf, "<%u>", prefix); |
1023 | } else { | 1023 | } else { |
1024 | len += 3; | 1024 | len += 3; |
1025 | if (prefix > 999) | 1025 | if (prefix > 999) |
1026 | len += 3; | 1026 | len += 3; |
1027 | else if (prefix > 99) | 1027 | else if (prefix > 99) |
1028 | len += 2; | 1028 | len += 2; |
1029 | else if (prefix > 9) | 1029 | else if (prefix > 9) |
1030 | len++; | 1030 | len++; |
1031 | } | 1031 | } |
1032 | } | 1032 | } |
1033 | 1033 | ||
1034 | len += print_time(msg->ts_nsec, buf ? buf + len : NULL); | 1034 | len += print_time(msg->ts_nsec, buf ? buf + len : NULL); |
1035 | return len; | 1035 | return len; |
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, | 1038 | static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, |
1039 | bool syslog, char *buf, size_t size) | 1039 | bool syslog, char *buf, size_t size) |
1040 | { | 1040 | { |
1041 | const char *text = log_text(msg); | 1041 | const char *text = log_text(msg); |
1042 | size_t text_size = msg->text_len; | 1042 | size_t text_size = msg->text_len; |
1043 | bool prefix = true; | 1043 | bool prefix = true; |
1044 | bool newline = true; | 1044 | bool newline = true; |
1045 | size_t len = 0; | 1045 | size_t len = 0; |
1046 | 1046 | ||
1047 | if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)) | 1047 | if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)) |
1048 | prefix = false; | 1048 | prefix = false; |
1049 | 1049 | ||
1050 | if (msg->flags & LOG_CONT) { | 1050 | if (msg->flags & LOG_CONT) { |
1051 | if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE)) | 1051 | if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE)) |
1052 | prefix = false; | 1052 | prefix = false; |
1053 | 1053 | ||
1054 | if (!(msg->flags & LOG_NEWLINE)) | 1054 | if (!(msg->flags & LOG_NEWLINE)) |
1055 | newline = false; | 1055 | newline = false; |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | do { | 1058 | do { |
1059 | const char *next = memchr(text, '\n', text_size); | 1059 | const char *next = memchr(text, '\n', text_size); |
1060 | size_t text_len; | 1060 | size_t text_len; |
1061 | 1061 | ||
1062 | if (next) { | 1062 | if (next) { |
1063 | text_len = next - text; | 1063 | text_len = next - text; |
1064 | next++; | 1064 | next++; |
1065 | text_size -= next - text; | 1065 | text_size -= next - text; |
1066 | } else { | 1066 | } else { |
1067 | text_len = text_size; | 1067 | text_len = text_size; |
1068 | } | 1068 | } |
1069 | 1069 | ||
1070 | if (buf) { | 1070 | if (buf) { |
1071 | if (print_prefix(msg, syslog, NULL) + | 1071 | if (print_prefix(msg, syslog, NULL) + |
1072 | text_len + 1 >= size - len) | 1072 | text_len + 1 >= size - len) |
1073 | break; | 1073 | break; |
1074 | 1074 | ||
1075 | if (prefix) | 1075 | if (prefix) |
1076 | len += print_prefix(msg, syslog, buf + len); | 1076 | len += print_prefix(msg, syslog, buf + len); |
1077 | memcpy(buf + len, text, text_len); | 1077 | memcpy(buf + len, text, text_len); |
1078 | len += text_len; | 1078 | len += text_len; |
1079 | if (next || newline) | 1079 | if (next || newline) |
1080 | buf[len++] = '\n'; | 1080 | buf[len++] = '\n'; |
1081 | } else { | 1081 | } else { |
1082 | /* SYSLOG_ACTION_* buffer size only calculation */ | 1082 | /* SYSLOG_ACTION_* buffer size only calculation */ |
1083 | if (prefix) | 1083 | if (prefix) |
1084 | len += print_prefix(msg, syslog, NULL); | 1084 | len += print_prefix(msg, syslog, NULL); |
1085 | len += text_len; | 1085 | len += text_len; |
1086 | if (next || newline) | 1086 | if (next || newline) |
1087 | len++; | 1087 | len++; |
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | prefix = true; | 1090 | prefix = true; |
1091 | text = next; | 1091 | text = next; |
1092 | } while (text); | 1092 | } while (text); |
1093 | 1093 | ||
1094 | return len; | 1094 | return len; |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | static int syslog_print(char __user *buf, int size) | 1097 | static int syslog_print(char __user *buf, int size) |
1098 | { | 1098 | { |
1099 | char *text; | 1099 | char *text; |
1100 | struct printk_log *msg; | 1100 | struct printk_log *msg; |
1101 | int len = 0; | 1101 | int len = 0; |
1102 | 1102 | ||
1103 | text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); | 1103 | text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); |
1104 | if (!text) | 1104 | if (!text) |
1105 | return -ENOMEM; | 1105 | return -ENOMEM; |
1106 | 1106 | ||
1107 | while (size > 0) { | 1107 | while (size > 0) { |
1108 | size_t n; | 1108 | size_t n; |
1109 | size_t skip; | 1109 | size_t skip; |
1110 | 1110 | ||
1111 | raw_spin_lock_irq(&logbuf_lock); | 1111 | raw_spin_lock_irq(&logbuf_lock); |
1112 | if (syslog_seq < log_first_seq) { | 1112 | if (syslog_seq < log_first_seq) { |
1113 | /* messages are gone, move to first one */ | 1113 | /* messages are gone, move to first one */ |
1114 | syslog_seq = log_first_seq; | 1114 | syslog_seq = log_first_seq; |
1115 | syslog_idx = log_first_idx; | 1115 | syslog_idx = log_first_idx; |
1116 | syslog_prev = 0; | 1116 | syslog_prev = 0; |
1117 | syslog_partial = 0; | 1117 | syslog_partial = 0; |
1118 | } | 1118 | } |
1119 | if (syslog_seq == log_next_seq) { | 1119 | if (syslog_seq == log_next_seq) { |
1120 | raw_spin_unlock_irq(&logbuf_lock); | 1120 | raw_spin_unlock_irq(&logbuf_lock); |
1121 | break; | 1121 | break; |
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | skip = syslog_partial; | 1124 | skip = syslog_partial; |
1125 | msg = log_from_idx(syslog_idx); | 1125 | msg = log_from_idx(syslog_idx); |
1126 | n = msg_print_text(msg, syslog_prev, true, text, | 1126 | n = msg_print_text(msg, syslog_prev, true, text, |
1127 | LOG_LINE_MAX + PREFIX_MAX); | 1127 | LOG_LINE_MAX + PREFIX_MAX); |
1128 | if (n - syslog_partial <= size) { | 1128 | if (n - syslog_partial <= size) { |
1129 | /* message fits into buffer, move forward */ | 1129 | /* message fits into buffer, move forward */ |
1130 | syslog_idx = log_next(syslog_idx); | 1130 | syslog_idx = log_next(syslog_idx); |
1131 | syslog_seq++; | 1131 | syslog_seq++; |
1132 | syslog_prev = msg->flags; | 1132 | syslog_prev = msg->flags; |
1133 | n -= syslog_partial; | 1133 | n -= syslog_partial; |
1134 | syslog_partial = 0; | 1134 | syslog_partial = 0; |
1135 | } else if (!len){ | 1135 | } else if (!len){ |
1136 | /* partial read(), remember position */ | 1136 | /* partial read(), remember position */ |
1137 | n = size; | 1137 | n = size; |
1138 | syslog_partial += n; | 1138 | syslog_partial += n; |
1139 | } else | 1139 | } else |
1140 | n = 0; | 1140 | n = 0; |
1141 | raw_spin_unlock_irq(&logbuf_lock); | 1141 | raw_spin_unlock_irq(&logbuf_lock); |
1142 | 1142 | ||
1143 | if (!n) | 1143 | if (!n) |
1144 | break; | 1144 | break; |
1145 | 1145 | ||
1146 | if (copy_to_user(buf, text + skip, n)) { | 1146 | if (copy_to_user(buf, text + skip, n)) { |
1147 | if (!len) | 1147 | if (!len) |
1148 | len = -EFAULT; | 1148 | len = -EFAULT; |
1149 | break; | 1149 | break; |
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | len += n; | 1152 | len += n; |
1153 | size -= n; | 1153 | size -= n; |
1154 | buf += n; | 1154 | buf += n; |
1155 | } | 1155 | } |
1156 | 1156 | ||
1157 | kfree(text); | 1157 | kfree(text); |
1158 | return len; | 1158 | return len; |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | static int syslog_print_all(char __user *buf, int size, bool clear) | 1161 | static int syslog_print_all(char __user *buf, int size, bool clear) |
1162 | { | 1162 | { |
1163 | char *text; | 1163 | char *text; |
1164 | int len = 0; | 1164 | int len = 0; |
1165 | 1165 | ||
1166 | text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); | 1166 | text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); |
1167 | if (!text) | 1167 | if (!text) |
1168 | return -ENOMEM; | 1168 | return -ENOMEM; |
1169 | 1169 | ||
1170 | raw_spin_lock_irq(&logbuf_lock); | 1170 | raw_spin_lock_irq(&logbuf_lock); |
1171 | if (buf) { | 1171 | if (buf) { |
1172 | u64 next_seq; | 1172 | u64 next_seq; |
1173 | u64 seq; | 1173 | u64 seq; |
1174 | u32 idx; | 1174 | u32 idx; |
1175 | enum log_flags prev; | 1175 | enum log_flags prev; |
1176 | 1176 | ||
1177 | if (clear_seq < log_first_seq) { | 1177 | if (clear_seq < log_first_seq) { |
1178 | /* messages are gone, move to first available one */ | 1178 | /* messages are gone, move to first available one */ |
1179 | clear_seq = log_first_seq; | 1179 | clear_seq = log_first_seq; |
1180 | clear_idx = log_first_idx; | 1180 | clear_idx = log_first_idx; |
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | /* | 1183 | /* |
1184 | * Find first record that fits, including all following records, | 1184 | * Find first record that fits, including all following records, |
1185 | * into the user-provided buffer for this dump. | 1185 | * into the user-provided buffer for this dump. |
1186 | */ | 1186 | */ |
1187 | seq = clear_seq; | 1187 | seq = clear_seq; |
1188 | idx = clear_idx; | 1188 | idx = clear_idx; |
1189 | prev = 0; | 1189 | prev = 0; |
1190 | while (seq < log_next_seq) { | 1190 | while (seq < log_next_seq) { |
1191 | struct printk_log *msg = log_from_idx(idx); | 1191 | struct printk_log *msg = log_from_idx(idx); |
1192 | 1192 | ||
1193 | len += msg_print_text(msg, prev, true, NULL, 0); | 1193 | len += msg_print_text(msg, prev, true, NULL, 0); |
1194 | prev = msg->flags; | 1194 | prev = msg->flags; |
1195 | idx = log_next(idx); | 1195 | idx = log_next(idx); |
1196 | seq++; | 1196 | seq++; |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | /* move first record forward until length fits into the buffer */ | 1199 | /* move first record forward until length fits into the buffer */ |
1200 | seq = clear_seq; | 1200 | seq = clear_seq; |
1201 | idx = clear_idx; | 1201 | idx = clear_idx; |
1202 | prev = 0; | 1202 | prev = 0; |
1203 | while (len > size && seq < log_next_seq) { | 1203 | while (len > size && seq < log_next_seq) { |
1204 | struct printk_log *msg = log_from_idx(idx); | 1204 | struct printk_log *msg = log_from_idx(idx); |
1205 | 1205 | ||
1206 | len -= msg_print_text(msg, prev, true, NULL, 0); | 1206 | len -= msg_print_text(msg, prev, true, NULL, 0); |
1207 | prev = msg->flags; | 1207 | prev = msg->flags; |
1208 | idx = log_next(idx); | 1208 | idx = log_next(idx); |
1209 | seq++; | 1209 | seq++; |
1210 | } | 1210 | } |
1211 | 1211 | ||
1212 | /* last message fitting into this dump */ | 1212 | /* last message fitting into this dump */ |
1213 | next_seq = log_next_seq; | 1213 | next_seq = log_next_seq; |
1214 | 1214 | ||
1215 | len = 0; | 1215 | len = 0; |
1216 | while (len >= 0 && seq < next_seq) { | 1216 | while (len >= 0 && seq < next_seq) { |
1217 | struct printk_log *msg = log_from_idx(idx); | 1217 | struct printk_log *msg = log_from_idx(idx); |
1218 | int textlen; | 1218 | int textlen; |
1219 | 1219 | ||
1220 | textlen = msg_print_text(msg, prev, true, text, | 1220 | textlen = msg_print_text(msg, prev, true, text, |
1221 | LOG_LINE_MAX + PREFIX_MAX); | 1221 | LOG_LINE_MAX + PREFIX_MAX); |
1222 | if (textlen < 0) { | 1222 | if (textlen < 0) { |
1223 | len = textlen; | 1223 | len = textlen; |
1224 | break; | 1224 | break; |
1225 | } | 1225 | } |
1226 | idx = log_next(idx); | 1226 | idx = log_next(idx); |
1227 | seq++; | 1227 | seq++; |
1228 | prev = msg->flags; | 1228 | prev = msg->flags; |
1229 | 1229 | ||
1230 | raw_spin_unlock_irq(&logbuf_lock); | 1230 | raw_spin_unlock_irq(&logbuf_lock); |
1231 | if (copy_to_user(buf + len, text, textlen)) | 1231 | if (copy_to_user(buf + len, text, textlen)) |
1232 | len = -EFAULT; | 1232 | len = -EFAULT; |
1233 | else | 1233 | else |
1234 | len += textlen; | 1234 | len += textlen; |
1235 | raw_spin_lock_irq(&logbuf_lock); | 1235 | raw_spin_lock_irq(&logbuf_lock); |
1236 | 1236 | ||
1237 | if (seq < log_first_seq) { | 1237 | if (seq < log_first_seq) { |
1238 | /* messages are gone, move to next one */ | 1238 | /* messages are gone, move to next one */ |
1239 | seq = log_first_seq; | 1239 | seq = log_first_seq; |
1240 | idx = log_first_idx; | 1240 | idx = log_first_idx; |
1241 | prev = 0; | 1241 | prev = 0; |
1242 | } | 1242 | } |
1243 | } | 1243 | } |
1244 | } | 1244 | } |
1245 | 1245 | ||
1246 | if (clear) { | 1246 | if (clear) { |
1247 | clear_seq = log_next_seq; | 1247 | clear_seq = log_next_seq; |
1248 | clear_idx = log_next_idx; | 1248 | clear_idx = log_next_idx; |
1249 | } | 1249 | } |
1250 | raw_spin_unlock_irq(&logbuf_lock); | 1250 | raw_spin_unlock_irq(&logbuf_lock); |
1251 | 1251 | ||
1252 | kfree(text); | 1252 | kfree(text); |
1253 | return len; | 1253 | return len; |
1254 | } | 1254 | } |
1255 | 1255 | ||
1256 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 1256 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
1257 | { | 1257 | { |
1258 | bool clear = false; | 1258 | bool clear = false; |
1259 | static int saved_console_loglevel = LOGLEVEL_DEFAULT; | 1259 | static int saved_console_loglevel = LOGLEVEL_DEFAULT; |
1260 | int error; | 1260 | int error; |
1261 | 1261 | ||
1262 | error = check_syslog_permissions(type, from_file); | 1262 | error = check_syslog_permissions(type, from_file); |
1263 | if (error) | 1263 | if (error) |
1264 | goto out; | 1264 | goto out; |
1265 | 1265 | ||
1266 | error = security_syslog(type); | 1266 | error = security_syslog(type); |
1267 | if (error) | 1267 | if (error) |
1268 | return error; | 1268 | return error; |
1269 | 1269 | ||
1270 | switch (type) { | 1270 | switch (type) { |
1271 | case SYSLOG_ACTION_CLOSE: /* Close log */ | 1271 | case SYSLOG_ACTION_CLOSE: /* Close log */ |
1272 | break; | 1272 | break; |
1273 | case SYSLOG_ACTION_OPEN: /* Open log */ | 1273 | case SYSLOG_ACTION_OPEN: /* Open log */ |
1274 | break; | 1274 | break; |
1275 | case SYSLOG_ACTION_READ: /* Read from log */ | 1275 | case SYSLOG_ACTION_READ: /* Read from log */ |
1276 | error = -EINVAL; | 1276 | error = -EINVAL; |
1277 | if (!buf || len < 0) | 1277 | if (!buf || len < 0) |
1278 | goto out; | 1278 | goto out; |
1279 | error = 0; | 1279 | error = 0; |
1280 | if (!len) | 1280 | if (!len) |
1281 | goto out; | 1281 | goto out; |
1282 | if (!access_ok(VERIFY_WRITE, buf, len)) { | 1282 | if (!access_ok(VERIFY_WRITE, buf, len)) { |
1283 | error = -EFAULT; | 1283 | error = -EFAULT; |
1284 | goto out; | 1284 | goto out; |
1285 | } | 1285 | } |
1286 | error = wait_event_interruptible(log_wait, | 1286 | error = wait_event_interruptible(log_wait, |
1287 | syslog_seq != log_next_seq); | 1287 | syslog_seq != log_next_seq); |
1288 | if (error) | 1288 | if (error) |
1289 | goto out; | 1289 | goto out; |
1290 | error = syslog_print(buf, len); | 1290 | error = syslog_print(buf, len); |
1291 | break; | 1291 | break; |
1292 | /* Read/clear last kernel messages */ | 1292 | /* Read/clear last kernel messages */ |
1293 | case SYSLOG_ACTION_READ_CLEAR: | 1293 | case SYSLOG_ACTION_READ_CLEAR: |
1294 | clear = true; | 1294 | clear = true; |
1295 | /* FALL THRU */ | 1295 | /* FALL THRU */ |
1296 | /* Read last kernel messages */ | 1296 | /* Read last kernel messages */ |
1297 | case SYSLOG_ACTION_READ_ALL: | 1297 | case SYSLOG_ACTION_READ_ALL: |
1298 | error = -EINVAL; | 1298 | error = -EINVAL; |
1299 | if (!buf || len < 0) | 1299 | if (!buf || len < 0) |
1300 | goto out; | 1300 | goto out; |
1301 | error = 0; | 1301 | error = 0; |
1302 | if (!len) | 1302 | if (!len) |
1303 | goto out; | 1303 | goto out; |
1304 | if (!access_ok(VERIFY_WRITE, buf, len)) { | 1304 | if (!access_ok(VERIFY_WRITE, buf, len)) { |
1305 | error = -EFAULT; | 1305 | error = -EFAULT; |
1306 | goto out; | 1306 | goto out; |
1307 | } | 1307 | } |
1308 | error = syslog_print_all(buf, len, clear); | 1308 | error = syslog_print_all(buf, len, clear); |
1309 | break; | 1309 | break; |
1310 | /* Clear ring buffer */ | 1310 | /* Clear ring buffer */ |
1311 | case SYSLOG_ACTION_CLEAR: | 1311 | case SYSLOG_ACTION_CLEAR: |
1312 | syslog_print_all(NULL, 0, true); | 1312 | syslog_print_all(NULL, 0, true); |
1313 | break; | 1313 | break; |
1314 | /* Disable logging to console */ | 1314 | /* Disable logging to console */ |
1315 | case SYSLOG_ACTION_CONSOLE_OFF: | 1315 | case SYSLOG_ACTION_CONSOLE_OFF: |
1316 | if (saved_console_loglevel == LOGLEVEL_DEFAULT) | 1316 | if (saved_console_loglevel == LOGLEVEL_DEFAULT) |
1317 | saved_console_loglevel = console_loglevel; | 1317 | saved_console_loglevel = console_loglevel; |
1318 | console_loglevel = minimum_console_loglevel; | 1318 | console_loglevel = minimum_console_loglevel; |
1319 | break; | 1319 | break; |
1320 | /* Enable logging to console */ | 1320 | /* Enable logging to console */ |
1321 | case SYSLOG_ACTION_CONSOLE_ON: | 1321 | case SYSLOG_ACTION_CONSOLE_ON: |
1322 | if (saved_console_loglevel != LOGLEVEL_DEFAULT) { | 1322 | if (saved_console_loglevel != LOGLEVEL_DEFAULT) { |
1323 | console_loglevel = saved_console_loglevel; | 1323 | console_loglevel = saved_console_loglevel; |
1324 | saved_console_loglevel = LOGLEVEL_DEFAULT; | 1324 | saved_console_loglevel = LOGLEVEL_DEFAULT; |
1325 | } | 1325 | } |
1326 | break; | 1326 | break; |
1327 | /* Set level of messages printed to console */ | 1327 | /* Set level of messages printed to console */ |
1328 | case SYSLOG_ACTION_CONSOLE_LEVEL: | 1328 | case SYSLOG_ACTION_CONSOLE_LEVEL: |
1329 | error = -EINVAL; | 1329 | error = -EINVAL; |
1330 | if (len < 1 || len > 8) | 1330 | if (len < 1 || len > 8) |
1331 | goto out; | 1331 | goto out; |
1332 | if (len < minimum_console_loglevel) | 1332 | if (len < minimum_console_loglevel) |
1333 | len = minimum_console_loglevel; | 1333 | len = minimum_console_loglevel; |
1334 | console_loglevel = len; | 1334 | console_loglevel = len; |
1335 | /* Implicitly re-enable logging to console */ | 1335 | /* Implicitly re-enable logging to console */ |
1336 | saved_console_loglevel = LOGLEVEL_DEFAULT; | 1336 | saved_console_loglevel = LOGLEVEL_DEFAULT; |
1337 | error = 0; | 1337 | error = 0; |
1338 | break; | 1338 | break; |
1339 | /* Number of chars in the log buffer */ | 1339 | /* Number of chars in the log buffer */ |
1340 | case SYSLOG_ACTION_SIZE_UNREAD: | 1340 | case SYSLOG_ACTION_SIZE_UNREAD: |
1341 | raw_spin_lock_irq(&logbuf_lock); | 1341 | raw_spin_lock_irq(&logbuf_lock); |
1342 | if (syslog_seq < log_first_seq) { | 1342 | if (syslog_seq < log_first_seq) { |
1343 | /* messages are gone, move to first one */ | 1343 | /* messages are gone, move to first one */ |
1344 | syslog_seq = log_first_seq; | 1344 | syslog_seq = log_first_seq; |
1345 | syslog_idx = log_first_idx; | 1345 | syslog_idx = log_first_idx; |
1346 | syslog_prev = 0; | 1346 | syslog_prev = 0; |
1347 | syslog_partial = 0; | 1347 | syslog_partial = 0; |
1348 | } | 1348 | } |
1349 | if (from_file) { | 1349 | if (from_file) { |
1350 | /* | 1350 | /* |
1351 | * Short-cut for poll(/"proc/kmsg") which simply checks | 1351 | * Short-cut for poll(/"proc/kmsg") which simply checks |
1352 | * for pending data, not the size; return the count of | 1352 | * for pending data, not the size; return the count of |
1353 | * records, not the length. | 1353 | * records, not the length. |
1354 | */ | 1354 | */ |
1355 | error = log_next_seq - syslog_seq; | 1355 | error = log_next_seq - syslog_seq; |
1356 | } else { | 1356 | } else { |
1357 | u64 seq = syslog_seq; | 1357 | u64 seq = syslog_seq; |
1358 | u32 idx = syslog_idx; | 1358 | u32 idx = syslog_idx; |
1359 | enum log_flags prev = syslog_prev; | 1359 | enum log_flags prev = syslog_prev; |
1360 | 1360 | ||
1361 | error = 0; | 1361 | error = 0; |
1362 | while (seq < log_next_seq) { | 1362 | while (seq < log_next_seq) { |
1363 | struct printk_log *msg = log_from_idx(idx); | 1363 | struct printk_log *msg = log_from_idx(idx); |
1364 | 1364 | ||
1365 | error += msg_print_text(msg, prev, true, NULL, 0); | 1365 | error += msg_print_text(msg, prev, true, NULL, 0); |
1366 | idx = log_next(idx); | 1366 | idx = log_next(idx); |
1367 | seq++; | 1367 | seq++; |
1368 | prev = msg->flags; | 1368 | prev = msg->flags; |
1369 | } | 1369 | } |
1370 | error -= syslog_partial; | 1370 | error -= syslog_partial; |
1371 | } | 1371 | } |
1372 | raw_spin_unlock_irq(&logbuf_lock); | 1372 | raw_spin_unlock_irq(&logbuf_lock); |
1373 | break; | 1373 | break; |
1374 | /* Size of the log buffer */ | 1374 | /* Size of the log buffer */ |
1375 | case SYSLOG_ACTION_SIZE_BUFFER: | 1375 | case SYSLOG_ACTION_SIZE_BUFFER: |
1376 | error = log_buf_len; | 1376 | error = log_buf_len; |
1377 | break; | 1377 | break; |
1378 | default: | 1378 | default: |
1379 | error = -EINVAL; | 1379 | error = -EINVAL; |
1380 | break; | 1380 | break; |
1381 | } | 1381 | } |
1382 | out: | 1382 | out: |
1383 | return error; | 1383 | return error; |
1384 | } | 1384 | } |
1385 | 1385 | ||
1386 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) | 1386 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) |
1387 | { | 1387 | { |
1388 | return do_syslog(type, buf, len, SYSLOG_FROM_READER); | 1388 | return do_syslog(type, buf, len, SYSLOG_FROM_READER); |
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | /* | 1391 | /* |
1392 | * Call the console drivers, asking them to write out | 1392 | * Call the console drivers, asking them to write out |
1393 | * log_buf[start] to log_buf[end - 1]. | 1393 | * log_buf[start] to log_buf[end - 1]. |
1394 | * The console_lock must be held. | 1394 | * The console_lock must be held. |
1395 | */ | 1395 | */ |
1396 | static void call_console_drivers(int level, const char *text, size_t len) | 1396 | static void call_console_drivers(int level, const char *text, size_t len) |
1397 | { | 1397 | { |
1398 | struct console *con; | 1398 | struct console *con; |
1399 | 1399 | ||
1400 | trace_console(text, len); | 1400 | trace_console(text, len); |
1401 | 1401 | ||
1402 | if (level >= console_loglevel && !ignore_loglevel) | 1402 | if (level >= console_loglevel && !ignore_loglevel) |
1403 | return; | 1403 | return; |
1404 | if (!console_drivers) | 1404 | if (!console_drivers) |
1405 | return; | 1405 | return; |
1406 | 1406 | ||
1407 | for_each_console(con) { | 1407 | for_each_console(con) { |
1408 | if (exclusive_console && con != exclusive_console) | 1408 | if (exclusive_console && con != exclusive_console) |
1409 | continue; | 1409 | continue; |
1410 | if (!(con->flags & CON_ENABLED)) | 1410 | if (!(con->flags & CON_ENABLED)) |
1411 | continue; | 1411 | continue; |
1412 | if (!con->write) | 1412 | if (!con->write) |
1413 | continue; | 1413 | continue; |
1414 | if (!cpu_online(smp_processor_id()) && | 1414 | if (!cpu_online(smp_processor_id()) && |
1415 | !(con->flags & CON_ANYTIME)) | 1415 | !(con->flags & CON_ANYTIME)) |
1416 | continue; | 1416 | continue; |
1417 | con->write(con, text, len); | 1417 | con->write(con, text, len); |
1418 | } | 1418 | } |
1419 | } | 1419 | } |
1420 | 1420 | ||
1421 | /* | 1421 | /* |
1422 | * Zap console related locks when oopsing. | 1422 | * Zap console related locks when oopsing. |
1423 | * To leave time for slow consoles to print a full oops, | 1423 | * To leave time for slow consoles to print a full oops, |
1424 | * only zap at most once every 30 seconds. | 1424 | * only zap at most once every 30 seconds. |
1425 | */ | 1425 | */ |
1426 | static void zap_locks(void) | 1426 | static void zap_locks(void) |
1427 | { | 1427 | { |
1428 | static unsigned long oops_timestamp; | 1428 | static unsigned long oops_timestamp; |
1429 | 1429 | ||
1430 | if (time_after_eq(jiffies, oops_timestamp) && | 1430 | if (time_after_eq(jiffies, oops_timestamp) && |
1431 | !time_after(jiffies, oops_timestamp + 30 * HZ)) | 1431 | !time_after(jiffies, oops_timestamp + 30 * HZ)) |
1432 | return; | 1432 | return; |
1433 | 1433 | ||
1434 | oops_timestamp = jiffies; | 1434 | oops_timestamp = jiffies; |
1435 | 1435 | ||
1436 | debug_locks_off(); | 1436 | debug_locks_off(); |
1437 | /* If a crash is occurring, make sure we can't deadlock */ | 1437 | /* If a crash is occurring, make sure we can't deadlock */ |
1438 | raw_spin_lock_init(&logbuf_lock); | 1438 | raw_spin_lock_init(&logbuf_lock); |
1439 | /* And make sure that we print immediately */ | 1439 | /* And make sure that we print immediately */ |
1440 | sema_init(&console_sem, 1); | 1440 | sema_init(&console_sem, 1); |
1441 | } | 1441 | } |
1442 | 1442 | ||
1443 | /* | 1443 | /* |
1444 | * Check if we have any console that is capable of printing while cpu is | 1444 | * Check if we have any console that is capable of printing while cpu is |
1445 | * booting or shutting down. Requires console_sem. | 1445 | * booting or shutting down. Requires console_sem. |
1446 | */ | 1446 | */ |
1447 | static int have_callable_console(void) | 1447 | static int have_callable_console(void) |
1448 | { | 1448 | { |
1449 | struct console *con; | 1449 | struct console *con; |
1450 | 1450 | ||
1451 | for_each_console(con) | 1451 | for_each_console(con) |
1452 | if (con->flags & CON_ANYTIME) | 1452 | if (con->flags & CON_ANYTIME) |
1453 | return 1; | 1453 | return 1; |
1454 | 1454 | ||
1455 | return 0; | 1455 | return 0; |
1456 | } | 1456 | } |
1457 | 1457 | ||
1458 | /* | 1458 | /* |
1459 | * Can we actually use the console at this time on this cpu? | 1459 | * Can we actually use the console at this time on this cpu? |
1460 | * | 1460 | * |
1461 | * Console drivers may assume that per-cpu resources have been allocated. So | 1461 | * Console drivers may assume that per-cpu resources have been allocated. So |
1462 | * unless they're explicitly marked as being able to cope (CON_ANYTIME) don't | 1462 | * unless they're explicitly marked as being able to cope (CON_ANYTIME) don't |
1463 | * call them until this CPU is officially up. | 1463 | * call them until this CPU is officially up. |
1464 | */ | 1464 | */ |
1465 | static inline int can_use_console(unsigned int cpu) | 1465 | static inline int can_use_console(unsigned int cpu) |
1466 | { | 1466 | { |
1467 | return cpu_online(cpu) || have_callable_console(); | 1467 | return cpu_online(cpu) || have_callable_console(); |
1468 | } | 1468 | } |
1469 | 1469 | ||
1470 | /* | 1470 | /* |
1471 | * Try to get console ownership to actually show the kernel | 1471 | * Try to get console ownership to actually show the kernel |
1472 | * messages from a 'printk'. Return true (and with the | 1472 | * messages from a 'printk'. Return true (and with the |
1473 | * console_lock held, and 'console_locked' set) if it | 1473 | * console_lock held, and 'console_locked' set) if it |
1474 | * is successful, false otherwise. | 1474 | * is successful, false otherwise. |
1475 | */ | 1475 | */ |
1476 | static int console_trylock_for_printk(void) | 1476 | static int console_trylock_for_printk(void) |
1477 | { | 1477 | { |
1478 | unsigned int cpu = smp_processor_id(); | 1478 | unsigned int cpu = smp_processor_id(); |
1479 | 1479 | ||
1480 | if (!console_trylock()) | 1480 | if (!console_trylock()) |
1481 | return 0; | 1481 | return 0; |
1482 | /* | 1482 | /* |
1483 | * If we can't use the console, we need to release the console | 1483 | * If we can't use the console, we need to release the console |
1484 | * semaphore by hand to avoid flushing the buffer. We need to hold the | 1484 | * semaphore by hand to avoid flushing the buffer. We need to hold the |
1485 | * console semaphore in order to do this test safely. | 1485 | * console semaphore in order to do this test safely. |
1486 | */ | 1486 | */ |
1487 | if (!can_use_console(cpu)) { | 1487 | if (!can_use_console(cpu)) { |
1488 | console_locked = 0; | 1488 | console_locked = 0; |
1489 | up_console_sem(); | 1489 | up_console_sem(); |
1490 | return 0; | 1490 | return 0; |
1491 | } | 1491 | } |
1492 | return 1; | 1492 | return 1; |
1493 | } | 1493 | } |
1494 | 1494 | ||
1495 | int printk_delay_msec __read_mostly; | 1495 | int printk_delay_msec __read_mostly; |
1496 | 1496 | ||
1497 | static inline void printk_delay(void) | 1497 | static inline void printk_delay(void) |
1498 | { | 1498 | { |
1499 | if (unlikely(printk_delay_msec)) { | 1499 | if (unlikely(printk_delay_msec)) { |
1500 | int m = printk_delay_msec; | 1500 | int m = printk_delay_msec; |
1501 | 1501 | ||
1502 | while (m--) { | 1502 | while (m--) { |
1503 | mdelay(1); | 1503 | mdelay(1); |
1504 | touch_nmi_watchdog(); | 1504 | touch_nmi_watchdog(); |
1505 | } | 1505 | } |
1506 | } | 1506 | } |
1507 | } | 1507 | } |
1508 | 1508 | ||
1509 | /* | 1509 | /* |
1510 | * Continuation lines are buffered, and not committed to the record buffer | 1510 | * Continuation lines are buffered, and not committed to the record buffer |
1511 | * until the line is complete, or a race forces it. The line fragments | 1511 | * until the line is complete, or a race forces it. The line fragments |
1512 | * though, are printed immediately to the consoles to ensure everything has | 1512 | * though, are printed immediately to the consoles to ensure everything has |
1513 | * reached the console in case of a kernel crash. | 1513 | * reached the console in case of a kernel crash. |
1514 | */ | 1514 | */ |
1515 | static struct cont { | 1515 | static struct cont { |
1516 | char buf[LOG_LINE_MAX]; | 1516 | char buf[LOG_LINE_MAX]; |
1517 | size_t len; /* length == 0 means unused buffer */ | 1517 | size_t len; /* length == 0 means unused buffer */ |
1518 | size_t cons; /* bytes written to console */ | 1518 | size_t cons; /* bytes written to console */ |
1519 | struct task_struct *owner; /* task of first print*/ | 1519 | struct task_struct *owner; /* task of first print*/ |
1520 | u64 ts_nsec; /* time of first print */ | 1520 | u64 ts_nsec; /* time of first print */ |
1521 | u8 level; /* log level of first message */ | 1521 | u8 level; /* log level of first message */ |
1522 | u8 facility; /* log facility of first message */ | 1522 | u8 facility; /* log facility of first message */ |
1523 | enum log_flags flags; /* prefix, newline flags */ | 1523 | enum log_flags flags; /* prefix, newline flags */ |
1524 | bool flushed:1; /* buffer sealed and committed */ | 1524 | bool flushed:1; /* buffer sealed and committed */ |
1525 | } cont; | 1525 | } cont; |
1526 | 1526 | ||
1527 | static void cont_flush(enum log_flags flags) | 1527 | static void cont_flush(enum log_flags flags) |
1528 | { | 1528 | { |
1529 | if (cont.flushed) | 1529 | if (cont.flushed) |
1530 | return; | 1530 | return; |
1531 | if (cont.len == 0) | 1531 | if (cont.len == 0) |
1532 | return; | 1532 | return; |
1533 | 1533 | ||
1534 | if (cont.cons) { | 1534 | if (cont.cons) { |
1535 | /* | 1535 | /* |
1536 | * If a fragment of this line was directly flushed to the | 1536 | * If a fragment of this line was directly flushed to the |
1537 | * console; wait for the console to pick up the rest of the | 1537 | * console; wait for the console to pick up the rest of the |
1538 | * line. LOG_NOCONS suppresses a duplicated output. | 1538 | * line. LOG_NOCONS suppresses a duplicated output. |
1539 | */ | 1539 | */ |
1540 | log_store(cont.facility, cont.level, flags | LOG_NOCONS, | 1540 | log_store(cont.facility, cont.level, flags | LOG_NOCONS, |
1541 | cont.ts_nsec, NULL, 0, cont.buf, cont.len); | 1541 | cont.ts_nsec, NULL, 0, cont.buf, cont.len); |
1542 | cont.flags = flags; | 1542 | cont.flags = flags; |
1543 | cont.flushed = true; | 1543 | cont.flushed = true; |
1544 | } else { | 1544 | } else { |
1545 | /* | 1545 | /* |
1546 | * If no fragment of this line ever reached the console, | 1546 | * If no fragment of this line ever reached the console, |
1547 | * just submit it to the store and free the buffer. | 1547 | * just submit it to the store and free the buffer. |
1548 | */ | 1548 | */ |
1549 | log_store(cont.facility, cont.level, flags, 0, | 1549 | log_store(cont.facility, cont.level, flags, 0, |
1550 | NULL, 0, cont.buf, cont.len); | 1550 | NULL, 0, cont.buf, cont.len); |
1551 | cont.len = 0; | 1551 | cont.len = 0; |
1552 | } | 1552 | } |
1553 | } | 1553 | } |
1554 | 1554 | ||
1555 | static bool cont_add(int facility, int level, const char *text, size_t len) | 1555 | static bool cont_add(int facility, int level, const char *text, size_t len) |
1556 | { | 1556 | { |
1557 | if (cont.len && cont.flushed) | 1557 | if (cont.len && cont.flushed) |
1558 | return false; | 1558 | return false; |
1559 | 1559 | ||
1560 | if (cont.len + len > sizeof(cont.buf)) { | 1560 | if (cont.len + len > sizeof(cont.buf)) { |
1561 | /* the line gets too long, split it up in separate records */ | 1561 | /* the line gets too long, split it up in separate records */ |
1562 | cont_flush(LOG_CONT); | 1562 | cont_flush(LOG_CONT); |
1563 | return false; | 1563 | return false; |
1564 | } | 1564 | } |
1565 | 1565 | ||
1566 | if (!cont.len) { | 1566 | if (!cont.len) { |
1567 | cont.facility = facility; | 1567 | cont.facility = facility; |
1568 | cont.level = level; | 1568 | cont.level = level; |
1569 | cont.owner = current; | 1569 | cont.owner = current; |
1570 | cont.ts_nsec = local_clock(); | 1570 | cont.ts_nsec = local_clock(); |
1571 | cont.flags = 0; | 1571 | cont.flags = 0; |
1572 | cont.cons = 0; | 1572 | cont.cons = 0; |
1573 | cont.flushed = false; | 1573 | cont.flushed = false; |
1574 | } | 1574 | } |
1575 | 1575 | ||
1576 | memcpy(cont.buf + cont.len, text, len); | 1576 | memcpy(cont.buf + cont.len, text, len); |
1577 | cont.len += len; | 1577 | cont.len += len; |
1578 | 1578 | ||
1579 | if (cont.len > (sizeof(cont.buf) * 80) / 100) | 1579 | if (cont.len > (sizeof(cont.buf) * 80) / 100) |
1580 | cont_flush(LOG_CONT); | 1580 | cont_flush(LOG_CONT); |
1581 | 1581 | ||
1582 | return true; | 1582 | return true; |
1583 | } | 1583 | } |
1584 | 1584 | ||
1585 | static size_t cont_print_text(char *text, size_t size) | 1585 | static size_t cont_print_text(char *text, size_t size) |
1586 | { | 1586 | { |
1587 | size_t textlen = 0; | 1587 | size_t textlen = 0; |
1588 | size_t len; | 1588 | size_t len; |
1589 | 1589 | ||
1590 | if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) { | 1590 | if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) { |
1591 | textlen += print_time(cont.ts_nsec, text); | 1591 | textlen += print_time(cont.ts_nsec, text); |
1592 | size -= textlen; | 1592 | size -= textlen; |
1593 | } | 1593 | } |
1594 | 1594 | ||
1595 | len = cont.len - cont.cons; | 1595 | len = cont.len - cont.cons; |
1596 | if (len > 0) { | 1596 | if (len > 0) { |
1597 | if (len+1 > size) | 1597 | if (len+1 > size) |
1598 | len = size-1; | 1598 | len = size-1; |
1599 | memcpy(text + textlen, cont.buf + cont.cons, len); | 1599 | memcpy(text + textlen, cont.buf + cont.cons, len); |
1600 | textlen += len; | 1600 | textlen += len; |
1601 | cont.cons = cont.len; | 1601 | cont.cons = cont.len; |
1602 | } | 1602 | } |
1603 | 1603 | ||
1604 | if (cont.flushed) { | 1604 | if (cont.flushed) { |
1605 | if (cont.flags & LOG_NEWLINE) | 1605 | if (cont.flags & LOG_NEWLINE) |
1606 | text[textlen++] = '\n'; | 1606 | text[textlen++] = '\n'; |
1607 | /* got everything, release buffer */ | 1607 | /* got everything, release buffer */ |
1608 | cont.len = 0; | 1608 | cont.len = 0; |
1609 | } | 1609 | } |
1610 | return textlen; | 1610 | return textlen; |
1611 | } | 1611 | } |
1612 | 1612 | ||
1613 | asmlinkage int vprintk_emit(int facility, int level, | 1613 | asmlinkage int vprintk_emit(int facility, int level, |
1614 | const char *dict, size_t dictlen, | 1614 | const char *dict, size_t dictlen, |
1615 | const char *fmt, va_list args) | 1615 | const char *fmt, va_list args) |
1616 | { | 1616 | { |
1617 | static int recursion_bug; | 1617 | static int recursion_bug; |
1618 | static char textbuf[LOG_LINE_MAX]; | 1618 | static char textbuf[LOG_LINE_MAX]; |
1619 | char *text = textbuf; | 1619 | char *text = textbuf; |
1620 | size_t text_len = 0; | 1620 | size_t text_len = 0; |
1621 | enum log_flags lflags = 0; | 1621 | enum log_flags lflags = 0; |
1622 | unsigned long flags; | 1622 | unsigned long flags; |
1623 | int this_cpu; | 1623 | int this_cpu; |
1624 | int printed_len = 0; | 1624 | int printed_len = 0; |
1625 | bool in_sched = false; | 1625 | bool in_sched = false; |
1626 | /* cpu currently holding logbuf_lock in this function */ | 1626 | /* cpu currently holding logbuf_lock in this function */ |
1627 | static unsigned int logbuf_cpu = UINT_MAX; | 1627 | static unsigned int logbuf_cpu = UINT_MAX; |
1628 | 1628 | ||
1629 | if (level == LOGLEVEL_SCHED) { | 1629 | if (level == LOGLEVEL_SCHED) { |
1630 | level = LOGLEVEL_DEFAULT; | 1630 | level = LOGLEVEL_DEFAULT; |
1631 | in_sched = true; | 1631 | in_sched = true; |
1632 | } | 1632 | } |
1633 | 1633 | ||
1634 | boot_delay_msec(level); | 1634 | boot_delay_msec(level); |
1635 | printk_delay(); | 1635 | printk_delay(); |
1636 | 1636 | ||
1637 | /* This stops the holder of console_sem just where we want him */ | 1637 | /* This stops the holder of console_sem just where we want him */ |
1638 | local_irq_save(flags); | 1638 | local_irq_save(flags); |
1639 | this_cpu = smp_processor_id(); | 1639 | this_cpu = smp_processor_id(); |
1640 | 1640 | ||
1641 | /* | 1641 | /* |
1642 | * Ouch, printk recursed into itself! | 1642 | * Ouch, printk recursed into itself! |
1643 | */ | 1643 | */ |
1644 | if (unlikely(logbuf_cpu == this_cpu)) { | 1644 | if (unlikely(logbuf_cpu == this_cpu)) { |
1645 | /* | 1645 | /* |
1646 | * If a crash is occurring during printk() on this CPU, | 1646 | * If a crash is occurring during printk() on this CPU, |
1647 | * then try to get the crash message out but make sure | 1647 | * then try to get the crash message out but make sure |
1648 | * we can't deadlock. Otherwise just return to avoid the | 1648 | * we can't deadlock. Otherwise just return to avoid the |
1649 | * recursion and return - but flag the recursion so that | 1649 | * recursion and return - but flag the recursion so that |
1650 | * it can be printed at the next appropriate moment: | 1650 | * it can be printed at the next appropriate moment: |
1651 | */ | 1651 | */ |
1652 | if (!oops_in_progress && !lockdep_recursing(current)) { | 1652 | if (!oops_in_progress && !lockdep_recursing(current)) { |
1653 | recursion_bug = 1; | 1653 | recursion_bug = 1; |
1654 | local_irq_restore(flags); | 1654 | local_irq_restore(flags); |
1655 | return 0; | 1655 | return 0; |
1656 | } | 1656 | } |
1657 | zap_locks(); | 1657 | zap_locks(); |
1658 | } | 1658 | } |
1659 | 1659 | ||
1660 | lockdep_off(); | 1660 | lockdep_off(); |
1661 | raw_spin_lock(&logbuf_lock); | 1661 | raw_spin_lock(&logbuf_lock); |
1662 | logbuf_cpu = this_cpu; | 1662 | logbuf_cpu = this_cpu; |
1663 | 1663 | ||
1664 | if (unlikely(recursion_bug)) { | 1664 | if (unlikely(recursion_bug)) { |
1665 | static const char recursion_msg[] = | 1665 | static const char recursion_msg[] = |
1666 | "BUG: recent printk recursion!"; | 1666 | "BUG: recent printk recursion!"; |
1667 | 1667 | ||
1668 | recursion_bug = 0; | 1668 | recursion_bug = 0; |
1669 | /* emit KERN_CRIT message */ | 1669 | /* emit KERN_CRIT message */ |
1670 | printed_len += log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0, | 1670 | printed_len += log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0, |
1671 | NULL, 0, recursion_msg, | 1671 | NULL, 0, recursion_msg, |
1672 | strlen(recursion_msg)); | 1672 | strlen(recursion_msg)); |
1673 | } | 1673 | } |
1674 | 1674 | ||
1675 | /* | 1675 | /* |
1676 | * The printf needs to come first; we need the syslog | 1676 | * The printf needs to come first; we need the syslog |
1677 | * prefix which might be passed-in as a parameter. | 1677 | * prefix which might be passed-in as a parameter. |
1678 | */ | 1678 | */ |
1679 | text_len = vscnprintf(text, sizeof(textbuf), fmt, args); | 1679 | text_len = vscnprintf(text, sizeof(textbuf), fmt, args); |
1680 | 1680 | ||
1681 | /* mark and strip a trailing newline */ | 1681 | /* mark and strip a trailing newline */ |
1682 | if (text_len && text[text_len-1] == '\n') { | 1682 | if (text_len && text[text_len-1] == '\n') { |
1683 | text_len--; | 1683 | text_len--; |
1684 | lflags |= LOG_NEWLINE; | 1684 | lflags |= LOG_NEWLINE; |
1685 | } | 1685 | } |
1686 | 1686 | ||
1687 | /* strip kernel syslog prefix and extract log level or control flags */ | 1687 | /* strip kernel syslog prefix and extract log level or control flags */ |
1688 | if (facility == 0) { | 1688 | if (facility == 0) { |
1689 | int kern_level = printk_get_level(text); | 1689 | int kern_level = printk_get_level(text); |
1690 | 1690 | ||
1691 | if (kern_level) { | 1691 | if (kern_level) { |
1692 | const char *end_of_header = printk_skip_level(text); | 1692 | const char *end_of_header = printk_skip_level(text); |
1693 | switch (kern_level) { | 1693 | switch (kern_level) { |
1694 | case '0' ... '7': | 1694 | case '0' ... '7': |
1695 | if (level == LOGLEVEL_DEFAULT) | 1695 | if (level == LOGLEVEL_DEFAULT) |
1696 | level = kern_level - '0'; | 1696 | level = kern_level - '0'; |
1697 | /* fallthrough */ | 1697 | /* fallthrough */ |
1698 | case 'd': /* KERN_DEFAULT */ | 1698 | case 'd': /* KERN_DEFAULT */ |
1699 | lflags |= LOG_PREFIX; | 1699 | lflags |= LOG_PREFIX; |
1700 | } | 1700 | } |
1701 | /* | 1701 | /* |
1702 | * No need to check length here because vscnprintf | 1702 | * No need to check length here because vscnprintf |
1703 | * put '\0' at the end of the string. Only valid and | 1703 | * put '\0' at the end of the string. Only valid and |
1704 | * newly printed level is detected. | 1704 | * newly printed level is detected. |
1705 | */ | 1705 | */ |
1706 | text_len -= end_of_header - text; | 1706 | text_len -= end_of_header - text; |
1707 | text = (char *)end_of_header; | 1707 | text = (char *)end_of_header; |
1708 | } | 1708 | } |
1709 | } | 1709 | } |
1710 | 1710 | ||
1711 | if (level == LOGLEVEL_DEFAULT) | 1711 | if (level == LOGLEVEL_DEFAULT) |
1712 | level = default_message_loglevel; | 1712 | level = default_message_loglevel; |
1713 | 1713 | ||
1714 | if (dict) | 1714 | if (dict) |
1715 | lflags |= LOG_PREFIX|LOG_NEWLINE; | 1715 | lflags |= LOG_PREFIX|LOG_NEWLINE; |
1716 | 1716 | ||
1717 | if (!(lflags & LOG_NEWLINE)) { | 1717 | if (!(lflags & LOG_NEWLINE)) { |
1718 | /* | 1718 | /* |
1719 | * Flush the conflicting buffer. An earlier newline was missing, | 1719 | * Flush the conflicting buffer. An earlier newline was missing, |
1720 | * or another task also prints continuation lines. | 1720 | * or another task also prints continuation lines. |
1721 | */ | 1721 | */ |
1722 | if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) | 1722 | if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) |
1723 | cont_flush(LOG_NEWLINE); | 1723 | cont_flush(LOG_NEWLINE); |
1724 | 1724 | ||
1725 | /* buffer line if possible, otherwise store it right away */ | 1725 | /* buffer line if possible, otherwise store it right away */ |
1726 | if (cont_add(facility, level, text, text_len)) | 1726 | if (cont_add(facility, level, text, text_len)) |
1727 | printed_len += text_len; | 1727 | printed_len += text_len; |
1728 | else | 1728 | else |
1729 | printed_len += log_store(facility, level, | 1729 | printed_len += log_store(facility, level, |
1730 | lflags | LOG_CONT, 0, | 1730 | lflags | LOG_CONT, 0, |
1731 | dict, dictlen, text, text_len); | 1731 | dict, dictlen, text, text_len); |
1732 | } else { | 1732 | } else { |
1733 | bool stored = false; | 1733 | bool stored = false; |
1734 | 1734 | ||
1735 | /* | 1735 | /* |
1736 | * If an earlier newline was missing and it was the same task, | 1736 | * If an earlier newline was missing and it was the same task, |
1737 | * either merge it with the current buffer and flush, or if | 1737 | * either merge it with the current buffer and flush, or if |
1738 | * there was a race with interrupts (prefix == true) then just | 1738 | * there was a race with interrupts (prefix == true) then just |
1739 | * flush it out and store this line separately. | 1739 | * flush it out and store this line separately. |
1740 | * If the preceding printk was from a different task and missed | 1740 | * If the preceding printk was from a different task and missed |
1741 | * a newline, flush and append the newline. | 1741 | * a newline, flush and append the newline. |
1742 | */ | 1742 | */ |
1743 | if (cont.len) { | 1743 | if (cont.len) { |
1744 | if (cont.owner == current && !(lflags & LOG_PREFIX)) | 1744 | if (cont.owner == current && !(lflags & LOG_PREFIX)) |
1745 | stored = cont_add(facility, level, text, | 1745 | stored = cont_add(facility, level, text, |
1746 | text_len); | 1746 | text_len); |
1747 | cont_flush(LOG_NEWLINE); | 1747 | cont_flush(LOG_NEWLINE); |
1748 | } | 1748 | } |
1749 | 1749 | ||
1750 | if (stored) | 1750 | if (stored) |
1751 | printed_len += text_len; | 1751 | printed_len += text_len; |
1752 | else | 1752 | else |
1753 | printed_len += log_store(facility, level, lflags, 0, | 1753 | printed_len += log_store(facility, level, lflags, 0, |
1754 | dict, dictlen, text, text_len); | 1754 | dict, dictlen, text, text_len); |
1755 | } | 1755 | } |
1756 | 1756 | ||
1757 | logbuf_cpu = UINT_MAX; | 1757 | logbuf_cpu = UINT_MAX; |
1758 | raw_spin_unlock(&logbuf_lock); | 1758 | raw_spin_unlock(&logbuf_lock); |
1759 | lockdep_on(); | 1759 | lockdep_on(); |
1760 | local_irq_restore(flags); | 1760 | local_irq_restore(flags); |
1761 | 1761 | ||
1762 | /* If called from the scheduler, we can not call up(). */ | 1762 | /* If called from the scheduler, we can not call up(). */ |
1763 | if (!in_sched) { | 1763 | if (!in_sched) { |
1764 | lockdep_off(); | 1764 | lockdep_off(); |
1765 | /* | 1765 | /* |
1766 | * Disable preemption to avoid being preempted while holding | 1766 | * Disable preemption to avoid being preempted while holding |
1767 | * console_sem which would prevent anyone from printing to | 1767 | * console_sem which would prevent anyone from printing to |
1768 | * console | 1768 | * console |
1769 | */ | 1769 | */ |
1770 | preempt_disable(); | 1770 | preempt_disable(); |
1771 | 1771 | ||
1772 | /* | 1772 | /* |
1773 | * Try to acquire and then immediately release the console | 1773 | * Try to acquire and then immediately release the console |
1774 | * semaphore. The release will print out buffers and wake up | 1774 | * semaphore. The release will print out buffers and wake up |
1775 | * /dev/kmsg and syslog() users. | 1775 | * /dev/kmsg and syslog() users. |
1776 | */ | 1776 | */ |
1777 | if (console_trylock_for_printk()) | 1777 | if (console_trylock_for_printk()) |
1778 | console_unlock(); | 1778 | console_unlock(); |
1779 | preempt_enable(); | 1779 | preempt_enable(); |
1780 | lockdep_on(); | 1780 | lockdep_on(); |
1781 | } | 1781 | } |
1782 | 1782 | ||
1783 | return printed_len; | 1783 | return printed_len; |
1784 | } | 1784 | } |
1785 | EXPORT_SYMBOL(vprintk_emit); | 1785 | EXPORT_SYMBOL(vprintk_emit); |
1786 | 1786 | ||
1787 | asmlinkage int vprintk(const char *fmt, va_list args) | 1787 | asmlinkage int vprintk(const char *fmt, va_list args) |
1788 | { | 1788 | { |
1789 | return vprintk_emit(0, LOGLEVEL_DEFAULT, NULL, 0, fmt, args); | 1789 | return vprintk_emit(0, LOGLEVEL_DEFAULT, NULL, 0, fmt, args); |
1790 | } | 1790 | } |
1791 | EXPORT_SYMBOL(vprintk); | 1791 | EXPORT_SYMBOL(vprintk); |
1792 | 1792 | ||
1793 | asmlinkage int printk_emit(int facility, int level, | 1793 | asmlinkage int printk_emit(int facility, int level, |
1794 | const char *dict, size_t dictlen, | 1794 | const char *dict, size_t dictlen, |
1795 | const char *fmt, ...) | 1795 | const char *fmt, ...) |
1796 | { | 1796 | { |
1797 | va_list args; | 1797 | va_list args; |
1798 | int r; | 1798 | int r; |
1799 | 1799 | ||
1800 | va_start(args, fmt); | 1800 | va_start(args, fmt); |
1801 | r = vprintk_emit(facility, level, dict, dictlen, fmt, args); | 1801 | r = vprintk_emit(facility, level, dict, dictlen, fmt, args); |
1802 | va_end(args); | 1802 | va_end(args); |
1803 | 1803 | ||
1804 | return r; | 1804 | return r; |
1805 | } | 1805 | } |
1806 | EXPORT_SYMBOL(printk_emit); | 1806 | EXPORT_SYMBOL(printk_emit); |
1807 | 1807 | ||
1808 | int vprintk_default(const char *fmt, va_list args) | 1808 | int vprintk_default(const char *fmt, va_list args) |
1809 | { | 1809 | { |
1810 | int r; | 1810 | int r; |
1811 | 1811 | ||
1812 | #ifdef CONFIG_KGDB_KDB | 1812 | #ifdef CONFIG_KGDB_KDB |
1813 | if (unlikely(kdb_trap_printk)) { | 1813 | if (unlikely(kdb_trap_printk)) { |
1814 | r = vkdb_printf(KDB_MSGSRC_PRINTK, fmt, args); | 1814 | r = vkdb_printf(KDB_MSGSRC_PRINTK, fmt, args); |
1815 | return r; | 1815 | return r; |
1816 | } | 1816 | } |
1817 | #endif | 1817 | #endif |
1818 | r = vprintk_emit(0, LOGLEVEL_DEFAULT, NULL, 0, fmt, args); | 1818 | r = vprintk_emit(0, LOGLEVEL_DEFAULT, NULL, 0, fmt, args); |
1819 | 1819 | ||
1820 | return r; | 1820 | return r; |
1821 | } | 1821 | } |
1822 | EXPORT_SYMBOL_GPL(vprintk_default); | 1822 | EXPORT_SYMBOL_GPL(vprintk_default); |
1823 | 1823 | ||
1824 | /* | 1824 | /* |
1825 | * This allows printk to be diverted to another function per cpu. | 1825 | * This allows printk to be diverted to another function per cpu. |
1826 | * This is useful for calling printk functions from within NMI | 1826 | * This is useful for calling printk functions from within NMI |
1827 | * without worrying about race conditions that can lock up the | 1827 | * without worrying about race conditions that can lock up the |
1828 | * box. | 1828 | * box. |
1829 | */ | 1829 | */ |
1830 | DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default; | 1830 | DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default; |
1831 | 1831 | ||
1832 | /** | 1832 | /** |
1833 | * printk - print a kernel message | 1833 | * printk - print a kernel message |
1834 | * @fmt: format string | 1834 | * @fmt: format string |
1835 | * | 1835 | * |
1836 | * This is printk(). It can be called from any context. We want it to work. | 1836 | * This is printk(). It can be called from any context. We want it to work. |
1837 | * | 1837 | * |
1838 | * We try to grab the console_lock. If we succeed, it's easy - we log the | 1838 | * We try to grab the console_lock. If we succeed, it's easy - we log the |
1839 | * output and call the console drivers. If we fail to get the semaphore, we | 1839 | * output and call the console drivers. If we fail to get the semaphore, we |
1840 | * place the output into the log buffer and return. The current holder of | 1840 | * place the output into the log buffer and return. The current holder of |
1841 | * the console_sem will notice the new output in console_unlock(); and will | 1841 | * the console_sem will notice the new output in console_unlock(); and will |
1842 | * send it to the consoles before releasing the lock. | 1842 | * send it to the consoles before releasing the lock. |
1843 | * | 1843 | * |
1844 | * One effect of this deferred printing is that code which calls printk() and | 1844 | * One effect of this deferred printing is that code which calls printk() and |
1845 | * then changes console_loglevel may break. This is because console_loglevel | 1845 | * then changes console_loglevel may break. This is because console_loglevel |
1846 | * is inspected when the actual printing occurs. | 1846 | * is inspected when the actual printing occurs. |
1847 | * | 1847 | * |
1848 | * See also: | 1848 | * See also: |
1849 | * printf(3) | 1849 | * printf(3) |
1850 | * | 1850 | * |
1851 | * See the vsnprintf() documentation for format string extensions over C99. | 1851 | * See the vsnprintf() documentation for format string extensions over C99. |
1852 | */ | 1852 | */ |
1853 | asmlinkage __visible int printk(const char *fmt, ...) | 1853 | asmlinkage __visible int printk(const char *fmt, ...) |
1854 | { | 1854 | { |
1855 | printk_func_t vprintk_func; | 1855 | printk_func_t vprintk_func; |
1856 | va_list args; | 1856 | va_list args; |
1857 | int r; | 1857 | int r; |
1858 | 1858 | ||
1859 | va_start(args, fmt); | 1859 | va_start(args, fmt); |
1860 | 1860 | ||
1861 | /* | 1861 | /* |
1862 | * If a caller overrides the per_cpu printk_func, then it needs | 1862 | * If a caller overrides the per_cpu printk_func, then it needs |
1863 | * to disable preemption when calling printk(). Otherwise | 1863 | * to disable preemption when calling printk(). Otherwise |
1864 | * the printk_func should be set to the default. No need to | 1864 | * the printk_func should be set to the default. No need to |
1865 | * disable preemption here. | 1865 | * disable preemption here. |
1866 | */ | 1866 | */ |
1867 | vprintk_func = this_cpu_read(printk_func); | 1867 | vprintk_func = this_cpu_read(printk_func); |
1868 | r = vprintk_func(fmt, args); | 1868 | r = vprintk_func(fmt, args); |
1869 | 1869 | ||
1870 | va_end(args); | 1870 | va_end(args); |
1871 | 1871 | ||
1872 | return r; | 1872 | return r; |
1873 | } | 1873 | } |
1874 | EXPORT_SYMBOL(printk); | 1874 | EXPORT_SYMBOL(printk); |
1875 | 1875 | ||
1876 | #else /* CONFIG_PRINTK */ | 1876 | #else /* CONFIG_PRINTK */ |
1877 | 1877 | ||
1878 | #define LOG_LINE_MAX 0 | 1878 | #define LOG_LINE_MAX 0 |
1879 | #define PREFIX_MAX 0 | 1879 | #define PREFIX_MAX 0 |
1880 | 1880 | ||
1881 | static u64 syslog_seq; | 1881 | static u64 syslog_seq; |
1882 | static u32 syslog_idx; | 1882 | static u32 syslog_idx; |
1883 | static u64 console_seq; | 1883 | static u64 console_seq; |
1884 | static u32 console_idx; | 1884 | static u32 console_idx; |
1885 | static enum log_flags syslog_prev; | 1885 | static enum log_flags syslog_prev; |
1886 | static u64 log_first_seq; | 1886 | static u64 log_first_seq; |
1887 | static u32 log_first_idx; | 1887 | static u32 log_first_idx; |
1888 | static u64 log_next_seq; | 1888 | static u64 log_next_seq; |
1889 | static enum log_flags console_prev; | 1889 | static enum log_flags console_prev; |
1890 | static struct cont { | 1890 | static struct cont { |
1891 | size_t len; | 1891 | size_t len; |
1892 | size_t cons; | 1892 | size_t cons; |
1893 | u8 level; | 1893 | u8 level; |
1894 | bool flushed:1; | 1894 | bool flushed:1; |
1895 | } cont; | 1895 | } cont; |
1896 | static struct printk_log *log_from_idx(u32 idx) { return NULL; } | 1896 | static struct printk_log *log_from_idx(u32 idx) { return NULL; } |
1897 | static u32 log_next(u32 idx) { return 0; } | 1897 | static u32 log_next(u32 idx) { return 0; } |
1898 | static void call_console_drivers(int level, const char *text, size_t len) {} | 1898 | static void call_console_drivers(int level, const char *text, size_t len) {} |
1899 | static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, | 1899 | static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, |
1900 | bool syslog, char *buf, size_t size) { return 0; } | 1900 | bool syslog, char *buf, size_t size) { return 0; } |
1901 | static size_t cont_print_text(char *text, size_t size) { return 0; } | 1901 | static size_t cont_print_text(char *text, size_t size) { return 0; } |
1902 | 1902 | ||
1903 | /* Still needs to be defined for users */ | 1903 | /* Still needs to be defined for users */ |
1904 | DEFINE_PER_CPU(printk_func_t, printk_func); | 1904 | DEFINE_PER_CPU(printk_func_t, printk_func); |
1905 | 1905 | ||
1906 | #endif /* CONFIG_PRINTK */ | 1906 | #endif /* CONFIG_PRINTK */ |
1907 | 1907 | ||
1908 | #ifdef CONFIG_EARLY_PRINTK | 1908 | #ifdef CONFIG_EARLY_PRINTK |
1909 | struct console *early_console; | 1909 | struct console *early_console; |
1910 | 1910 | ||
1911 | asmlinkage __visible void early_printk(const char *fmt, ...) | 1911 | asmlinkage __visible void early_printk(const char *fmt, ...) |
1912 | { | 1912 | { |
1913 | va_list ap; | 1913 | va_list ap; |
1914 | char buf[512]; | 1914 | char buf[512]; |
1915 | int n; | 1915 | int n; |
1916 | 1916 | ||
1917 | if (!early_console) | 1917 | if (!early_console) |
1918 | return; | 1918 | return; |
1919 | 1919 | ||
1920 | va_start(ap, fmt); | 1920 | va_start(ap, fmt); |
1921 | n = vscnprintf(buf, sizeof(buf), fmt, ap); | 1921 | n = vscnprintf(buf, sizeof(buf), fmt, ap); |
1922 | va_end(ap); | 1922 | va_end(ap); |
1923 | 1923 | ||
1924 | early_console->write(early_console, buf, n); | 1924 | early_console->write(early_console, buf, n); |
1925 | } | 1925 | } |
1926 | #endif | 1926 | #endif |
1927 | 1927 | ||
1928 | static int __add_preferred_console(char *name, int idx, char *options, | 1928 | static int __add_preferred_console(char *name, int idx, char *options, |
1929 | char *brl_options) | 1929 | char *brl_options) |
1930 | { | 1930 | { |
1931 | struct console_cmdline *c; | 1931 | struct console_cmdline *c; |
1932 | int i; | 1932 | int i; |
1933 | 1933 | ||
1934 | /* | 1934 | /* |
1935 | * See if this tty is not yet registered, and | 1935 | * See if this tty is not yet registered, and |
1936 | * if we have a slot free. | 1936 | * if we have a slot free. |
1937 | */ | 1937 | */ |
1938 | for (i = 0, c = console_cmdline; | 1938 | for (i = 0, c = console_cmdline; |
1939 | i < MAX_CMDLINECONSOLES && c->name[0]; | 1939 | i < MAX_CMDLINECONSOLES && c->name[0]; |
1940 | i++, c++) { | 1940 | i++, c++) { |
1941 | if (strcmp(c->name, name) == 0 && c->index == idx) { | 1941 | if (strcmp(c->name, name) == 0 && c->index == idx) { |
1942 | if (!brl_options) | 1942 | if (!brl_options) |
1943 | selected_console = i; | 1943 | selected_console = i; |
1944 | return 0; | 1944 | return 0; |
1945 | } | 1945 | } |
1946 | } | 1946 | } |
1947 | if (i == MAX_CMDLINECONSOLES) | 1947 | if (i == MAX_CMDLINECONSOLES) |
1948 | return -E2BIG; | 1948 | return -E2BIG; |
1949 | if (!brl_options) | 1949 | if (!brl_options) |
1950 | selected_console = i; | 1950 | selected_console = i; |
1951 | strlcpy(c->name, name, sizeof(c->name)); | 1951 | strlcpy(c->name, name, sizeof(c->name)); |
1952 | c->options = options; | 1952 | c->options = options; |
1953 | braille_set_options(c, brl_options); | 1953 | braille_set_options(c, brl_options); |
1954 | 1954 | ||
1955 | c->index = idx; | 1955 | c->index = idx; |
1956 | return 0; | 1956 | return 0; |
1957 | } | 1957 | } |
1958 | /* | 1958 | /* |
1959 | * Set up a console. Called via do_early_param() in init/main.c | 1959 | * Set up a console. Called via do_early_param() in init/main.c |
1960 | * for each "console=" parameter in the boot command line. | 1960 | * for each "console=" parameter in the boot command line. |
1961 | */ | 1961 | */ |
1962 | static int __init console_setup(char *str) | 1962 | static int __init console_setup(char *str) |
1963 | { | 1963 | { |
1964 | char buf[sizeof(console_cmdline[0].name) + 4]; /* 4 for "ttyS" */ | 1964 | char buf[sizeof(console_cmdline[0].name) + 4]; /* 4 for "ttyS" */ |
1965 | char *s, *options, *brl_options = NULL; | 1965 | char *s, *options, *brl_options = NULL; |
1966 | int idx; | 1966 | int idx; |
1967 | 1967 | ||
1968 | if (_braille_console_setup(&str, &brl_options)) | 1968 | if (_braille_console_setup(&str, &brl_options)) |
1969 | return 1; | 1969 | return 1; |
1970 | 1970 | ||
1971 | /* | 1971 | /* |
1972 | * Decode str into name, index, options. | 1972 | * Decode str into name, index, options. |
1973 | */ | 1973 | */ |
1974 | if (str[0] >= '0' && str[0] <= '9') { | 1974 | if (str[0] >= '0' && str[0] <= '9') { |
1975 | strcpy(buf, "ttyS"); | 1975 | strcpy(buf, "ttyS"); |
1976 | strncpy(buf + 4, str, sizeof(buf) - 5); | 1976 | strncpy(buf + 4, str, sizeof(buf) - 5); |
1977 | } else { | 1977 | } else { |
1978 | strncpy(buf, str, sizeof(buf) - 1); | 1978 | strncpy(buf, str, sizeof(buf) - 1); |
1979 | } | 1979 | } |
1980 | buf[sizeof(buf) - 1] = 0; | 1980 | buf[sizeof(buf) - 1] = 0; |
1981 | options = strchr(str, ','); | 1981 | options = strchr(str, ','); |
1982 | if (options) | 1982 | if (options) |
1983 | *(options++) = 0; | 1983 | *(options++) = 0; |
1984 | #ifdef __sparc__ | 1984 | #ifdef __sparc__ |
1985 | if (!strcmp(str, "ttya")) | 1985 | if (!strcmp(str, "ttya")) |
1986 | strcpy(buf, "ttyS0"); | 1986 | strcpy(buf, "ttyS0"); |
1987 | if (!strcmp(str, "ttyb")) | 1987 | if (!strcmp(str, "ttyb")) |
1988 | strcpy(buf, "ttyS1"); | 1988 | strcpy(buf, "ttyS1"); |
1989 | #endif | 1989 | #endif |
1990 | for (s = buf; *s; s++) | 1990 | for (s = buf; *s; s++) |
1991 | if (isdigit(*s) || *s == ',') | 1991 | if (isdigit(*s) || *s == ',') |
1992 | break; | 1992 | break; |
1993 | idx = simple_strtoul(s, NULL, 10); | 1993 | idx = simple_strtoul(s, NULL, 10); |
1994 | *s = 0; | 1994 | *s = 0; |
1995 | 1995 | ||
1996 | __add_preferred_console(buf, idx, options, brl_options); | 1996 | __add_preferred_console(buf, idx, options, brl_options); |
1997 | console_set_on_cmdline = 1; | 1997 | console_set_on_cmdline = 1; |
1998 | return 1; | 1998 | return 1; |
1999 | } | 1999 | } |
2000 | __setup("console=", console_setup); | 2000 | __setup("console=", console_setup); |
2001 | 2001 | ||
2002 | /** | 2002 | /** |
2003 | * add_preferred_console - add a device to the list of preferred consoles. | 2003 | * add_preferred_console - add a device to the list of preferred consoles. |
2004 | * @name: device name | 2004 | * @name: device name |
2005 | * @idx: device index | 2005 | * @idx: device index |
2006 | * @options: options for this console | 2006 | * @options: options for this console |
2007 | * | 2007 | * |
2008 | * The last preferred console added will be used for kernel messages | 2008 | * The last preferred console added will be used for kernel messages |
2009 | * and stdin/out/err for init. Normally this is used by console_setup | 2009 | * and stdin/out/err for init. Normally this is used by console_setup |
2010 | * above to handle user-supplied console arguments; however it can also | 2010 | * above to handle user-supplied console arguments; however it can also |
2011 | * be used by arch-specific code either to override the user or more | 2011 | * be used by arch-specific code either to override the user or more |
2012 | * commonly to provide a default console (ie from PROM variables) when | 2012 | * commonly to provide a default console (ie from PROM variables) when |
2013 | * the user has not supplied one. | 2013 | * the user has not supplied one. |
2014 | */ | 2014 | */ |
2015 | int add_preferred_console(char *name, int idx, char *options) | 2015 | int add_preferred_console(char *name, int idx, char *options) |
2016 | { | 2016 | { |
2017 | return __add_preferred_console(name, idx, options, NULL); | 2017 | return __add_preferred_console(name, idx, options, NULL); |
2018 | } | 2018 | } |
2019 | 2019 | ||
2020 | int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options) | 2020 | int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options) |
2021 | { | 2021 | { |
2022 | struct console_cmdline *c; | 2022 | struct console_cmdline *c; |
2023 | int i; | 2023 | int i; |
2024 | 2024 | ||
2025 | for (i = 0, c = console_cmdline; | 2025 | for (i = 0, c = console_cmdline; |
2026 | i < MAX_CMDLINECONSOLES && c->name[0]; | 2026 | i < MAX_CMDLINECONSOLES && c->name[0]; |
2027 | i++, c++) | 2027 | i++, c++) |
2028 | if (strcmp(c->name, name) == 0 && c->index == idx) { | 2028 | if (strcmp(c->name, name) == 0 && c->index == idx) { |
2029 | strlcpy(c->name, name_new, sizeof(c->name)); | 2029 | strlcpy(c->name, name_new, sizeof(c->name)); |
2030 | c->options = options; | 2030 | c->options = options; |
2031 | c->index = idx_new; | 2031 | c->index = idx_new; |
2032 | return i; | 2032 | return i; |
2033 | } | 2033 | } |
2034 | /* not found */ | 2034 | /* not found */ |
2035 | return -1; | 2035 | return -1; |
2036 | } | 2036 | } |
2037 | 2037 | ||
2038 | bool console_suspend_enabled = true; | 2038 | bool console_suspend_enabled = true; |
2039 | EXPORT_SYMBOL(console_suspend_enabled); | 2039 | EXPORT_SYMBOL(console_suspend_enabled); |
2040 | 2040 | ||
2041 | static int __init console_suspend_disable(char *str) | 2041 | static int __init console_suspend_disable(char *str) |
2042 | { | 2042 | { |
2043 | console_suspend_enabled = false; | 2043 | console_suspend_enabled = false; |
2044 | return 1; | 2044 | return 1; |
2045 | } | 2045 | } |
2046 | __setup("no_console_suspend", console_suspend_disable); | 2046 | __setup("no_console_suspend", console_suspend_disable); |
2047 | module_param_named(console_suspend, console_suspend_enabled, | 2047 | module_param_named(console_suspend, console_suspend_enabled, |
2048 | bool, S_IRUGO | S_IWUSR); | 2048 | bool, S_IRUGO | S_IWUSR); |
2049 | MODULE_PARM_DESC(console_suspend, "suspend console during suspend" | 2049 | MODULE_PARM_DESC(console_suspend, "suspend console during suspend" |
2050 | " and hibernate operations"); | 2050 | " and hibernate operations"); |
2051 | 2051 | ||
2052 | /** | 2052 | /** |
2053 | * suspend_console - suspend the console subsystem | 2053 | * suspend_console - suspend the console subsystem |
2054 | * | 2054 | * |
2055 | * This disables printk() while we go into suspend states | 2055 | * This disables printk() while we go into suspend states |
2056 | */ | 2056 | */ |
2057 | void suspend_console(void) | 2057 | void suspend_console(void) |
2058 | { | 2058 | { |
2059 | if (!console_suspend_enabled) | 2059 | if (!console_suspend_enabled) |
2060 | return; | 2060 | return; |
2061 | printk("Suspending console(s) (use no_console_suspend to debug)\n"); | 2061 | printk("Suspending console(s) (use no_console_suspend to debug)\n"); |
2062 | console_lock(); | 2062 | console_lock(); |
2063 | console_suspended = 1; | 2063 | console_suspended = 1; |
2064 | up_console_sem(); | 2064 | up_console_sem(); |
2065 | } | 2065 | } |
2066 | 2066 | ||
2067 | void resume_console(void) | 2067 | void resume_console(void) |
2068 | { | 2068 | { |
2069 | if (!console_suspend_enabled) | 2069 | if (!console_suspend_enabled) |
2070 | return; | 2070 | return; |
2071 | down_console_sem(); | 2071 | down_console_sem(); |
2072 | console_suspended = 0; | 2072 | console_suspended = 0; |
2073 | console_unlock(); | 2073 | console_unlock(); |
2074 | } | 2074 | } |
2075 | 2075 | ||
2076 | /** | 2076 | /** |
2077 | * console_cpu_notify - print deferred console messages after CPU hotplug | 2077 | * console_cpu_notify - print deferred console messages after CPU hotplug |
2078 | * @self: notifier struct | 2078 | * @self: notifier struct |
2079 | * @action: CPU hotplug event | 2079 | * @action: CPU hotplug event |
2080 | * @hcpu: unused | 2080 | * @hcpu: unused |
2081 | * | 2081 | * |
2082 | * If printk() is called from a CPU that is not online yet, the messages | 2082 | * If printk() is called from a CPU that is not online yet, the messages |
2083 | * will be spooled but will not show up on the console. This function is | 2083 | * will be spooled but will not show up on the console. This function is |
2084 | * called when a new CPU comes online (or fails to come up), and ensures | 2084 | * called when a new CPU comes online (or fails to come up), and ensures |
2085 | * that any such output gets printed. | 2085 | * that any such output gets printed. |
2086 | */ | 2086 | */ |
2087 | static int console_cpu_notify(struct notifier_block *self, | 2087 | static int console_cpu_notify(struct notifier_block *self, |
2088 | unsigned long action, void *hcpu) | 2088 | unsigned long action, void *hcpu) |
2089 | { | 2089 | { |
2090 | switch (action) { | 2090 | switch (action) { |
2091 | case CPU_ONLINE: | 2091 | case CPU_ONLINE: |
2092 | case CPU_DEAD: | 2092 | case CPU_DEAD: |
2093 | case CPU_DOWN_FAILED: | 2093 | case CPU_DOWN_FAILED: |
2094 | case CPU_UP_CANCELED: | 2094 | case CPU_UP_CANCELED: |
2095 | console_lock(); | 2095 | console_lock(); |
2096 | console_unlock(); | 2096 | console_unlock(); |
2097 | } | 2097 | } |
2098 | return NOTIFY_OK; | 2098 | return NOTIFY_OK; |
2099 | } | 2099 | } |
2100 | 2100 | ||
2101 | /** | 2101 | /** |
2102 | * console_lock - lock the console system for exclusive use. | 2102 | * console_lock - lock the console system for exclusive use. |
2103 | * | 2103 | * |
2104 | * Acquires a lock which guarantees that the caller has | 2104 | * Acquires a lock which guarantees that the caller has |
2105 | * exclusive access to the console system and the console_drivers list. | 2105 | * exclusive access to the console system and the console_drivers list. |
2106 | * | 2106 | * |
2107 | * Can sleep, returns nothing. | 2107 | * Can sleep, returns nothing. |
2108 | */ | 2108 | */ |
2109 | void console_lock(void) | 2109 | void console_lock(void) |
2110 | { | 2110 | { |
2111 | might_sleep(); | 2111 | might_sleep(); |
2112 | 2112 | ||
2113 | down_console_sem(); | 2113 | down_console_sem(); |
2114 | if (console_suspended) | 2114 | if (console_suspended) |
2115 | return; | 2115 | return; |
2116 | console_locked = 1; | 2116 | console_locked = 1; |
2117 | console_may_schedule = 1; | 2117 | console_may_schedule = 1; |
2118 | } | 2118 | } |
2119 | EXPORT_SYMBOL(console_lock); | 2119 | EXPORT_SYMBOL(console_lock); |
2120 | 2120 | ||
2121 | /** | 2121 | /** |
2122 | * console_trylock - try to lock the console system for exclusive use. | 2122 | * console_trylock - try to lock the console system for exclusive use. |
2123 | * | 2123 | * |
2124 | * Try to acquire a lock which guarantees that the caller has exclusive | 2124 | * Try to acquire a lock which guarantees that the caller has exclusive |
2125 | * access to the console system and the console_drivers list. | 2125 | * access to the console system and the console_drivers list. |
2126 | * | 2126 | * |
2127 | * returns 1 on success, and 0 on failure to acquire the lock. | 2127 | * returns 1 on success, and 0 on failure to acquire the lock. |
2128 | */ | 2128 | */ |
2129 | int console_trylock(void) | 2129 | int console_trylock(void) |
2130 | { | 2130 | { |
2131 | if (down_trylock_console_sem()) | 2131 | if (down_trylock_console_sem()) |
2132 | return 0; | 2132 | return 0; |
2133 | if (console_suspended) { | 2133 | if (console_suspended) { |
2134 | up_console_sem(); | 2134 | up_console_sem(); |
2135 | return 0; | 2135 | return 0; |
2136 | } | 2136 | } |
2137 | console_locked = 1; | 2137 | console_locked = 1; |
2138 | console_may_schedule = 0; | 2138 | console_may_schedule = 0; |
2139 | return 1; | 2139 | return 1; |
2140 | } | 2140 | } |
2141 | EXPORT_SYMBOL(console_trylock); | 2141 | EXPORT_SYMBOL(console_trylock); |
2142 | 2142 | ||
2143 | int is_console_locked(void) | 2143 | int is_console_locked(void) |
2144 | { | 2144 | { |
2145 | return console_locked; | 2145 | return console_locked; |
2146 | } | 2146 | } |
2147 | 2147 | ||
2148 | static void console_cont_flush(char *text, size_t size) | 2148 | static void console_cont_flush(char *text, size_t size) |
2149 | { | 2149 | { |
2150 | unsigned long flags; | 2150 | unsigned long flags; |
2151 | size_t len; | 2151 | size_t len; |
2152 | 2152 | ||
2153 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2153 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
2154 | 2154 | ||
2155 | if (!cont.len) | 2155 | if (!cont.len) |
2156 | goto out; | 2156 | goto out; |
2157 | 2157 | ||
2158 | /* | 2158 | /* |
2159 | * We still queue earlier records, likely because the console was | 2159 | * We still queue earlier records, likely because the console was |
2160 | * busy. The earlier ones need to be printed before this one, we | 2160 | * busy. The earlier ones need to be printed before this one, we |
2161 | * did not flush any fragment so far, so just let it queue up. | 2161 | * did not flush any fragment so far, so just let it queue up. |
2162 | */ | 2162 | */ |
2163 | if (console_seq < log_next_seq && !cont.cons) | 2163 | if (console_seq < log_next_seq && !cont.cons) |
2164 | goto out; | 2164 | goto out; |
2165 | 2165 | ||
2166 | len = cont_print_text(text, size); | 2166 | len = cont_print_text(text, size); |
2167 | raw_spin_unlock(&logbuf_lock); | 2167 | raw_spin_unlock(&logbuf_lock); |
2168 | stop_critical_timings(); | 2168 | stop_critical_timings(); |
2169 | call_console_drivers(cont.level, text, len); | 2169 | call_console_drivers(cont.level, text, len); |
2170 | start_critical_timings(); | 2170 | start_critical_timings(); |
2171 | local_irq_restore(flags); | 2171 | local_irq_restore(flags); |
2172 | return; | 2172 | return; |
2173 | out: | 2173 | out: |
2174 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2174 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
2175 | } | 2175 | } |
2176 | 2176 | ||
2177 | /** | 2177 | /** |
2178 | * console_unlock - unlock the console system | 2178 | * console_unlock - unlock the console system |
2179 | * | 2179 | * |
2180 | * Releases the console_lock which the caller holds on the console system | 2180 | * Releases the console_lock which the caller holds on the console system |
2181 | * and the console driver list. | 2181 | * and the console driver list. |
2182 | * | 2182 | * |
2183 | * While the console_lock was held, console output may have been buffered | 2183 | * While the console_lock was held, console output may have been buffered |
2184 | * by printk(). If this is the case, console_unlock(); emits | 2184 | * by printk(). If this is the case, console_unlock(); emits |
2185 | * the output prior to releasing the lock. | 2185 | * the output prior to releasing the lock. |
2186 | * | 2186 | * |
2187 | * If there is output waiting, we wake /dev/kmsg and syslog() users. | 2187 | * If there is output waiting, we wake /dev/kmsg and syslog() users. |
2188 | * | 2188 | * |
2189 | * console_unlock(); may be called from any context. | 2189 | * console_unlock(); may be called from any context. |
2190 | */ | 2190 | */ |
2191 | void console_unlock(void) | 2191 | void console_unlock(void) |
2192 | { | 2192 | { |
2193 | static char text[LOG_LINE_MAX + PREFIX_MAX]; | 2193 | static char text[LOG_LINE_MAX + PREFIX_MAX]; |
2194 | static u64 seen_seq; | 2194 | static u64 seen_seq; |
2195 | unsigned long flags; | 2195 | unsigned long flags; |
2196 | bool wake_klogd = false; | 2196 | bool wake_klogd = false; |
2197 | bool retry; | 2197 | bool retry; |
2198 | 2198 | ||
2199 | if (console_suspended) { | 2199 | if (console_suspended) { |
2200 | up_console_sem(); | 2200 | up_console_sem(); |
2201 | return; | 2201 | return; |
2202 | } | 2202 | } |
2203 | 2203 | ||
2204 | console_may_schedule = 0; | 2204 | console_may_schedule = 0; |
2205 | 2205 | ||
2206 | /* flush buffered message fragment immediately to console */ | 2206 | /* flush buffered message fragment immediately to console */ |
2207 | console_cont_flush(text, sizeof(text)); | 2207 | console_cont_flush(text, sizeof(text)); |
2208 | again: | 2208 | again: |
2209 | for (;;) { | 2209 | for (;;) { |
2210 | struct printk_log *msg; | 2210 | struct printk_log *msg; |
2211 | size_t len; | 2211 | size_t len; |
2212 | int level; | 2212 | int level; |
2213 | 2213 | ||
2214 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2214 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
2215 | if (seen_seq != log_next_seq) { | 2215 | if (seen_seq != log_next_seq) { |
2216 | wake_klogd = true; | 2216 | wake_klogd = true; |
2217 | seen_seq = log_next_seq; | 2217 | seen_seq = log_next_seq; |
2218 | } | 2218 | } |
2219 | 2219 | ||
2220 | if (console_seq < log_first_seq) { | 2220 | if (console_seq < log_first_seq) { |
2221 | len = sprintf(text, "** %u printk messages dropped ** ", | 2221 | len = sprintf(text, "** %u printk messages dropped ** ", |
2222 | (unsigned)(log_first_seq - console_seq)); | 2222 | (unsigned)(log_first_seq - console_seq)); |
2223 | 2223 | ||
2224 | /* messages are gone, move to first one */ | 2224 | /* messages are gone, move to first one */ |
2225 | console_seq = log_first_seq; | 2225 | console_seq = log_first_seq; |
2226 | console_idx = log_first_idx; | 2226 | console_idx = log_first_idx; |
2227 | console_prev = 0; | 2227 | console_prev = 0; |
2228 | } else { | 2228 | } else { |
2229 | len = 0; | 2229 | len = 0; |
2230 | } | 2230 | } |
2231 | skip: | 2231 | skip: |
2232 | if (console_seq == log_next_seq) | 2232 | if (console_seq == log_next_seq) |
2233 | break; | 2233 | break; |
2234 | 2234 | ||
2235 | msg = log_from_idx(console_idx); | 2235 | msg = log_from_idx(console_idx); |
2236 | if (msg->flags & LOG_NOCONS) { | 2236 | if (msg->flags & LOG_NOCONS) { |
2237 | /* | 2237 | /* |
2238 | * Skip record we have buffered and already printed | 2238 | * Skip record we have buffered and already printed |
2239 | * directly to the console when we received it. | 2239 | * directly to the console when we received it. |
2240 | */ | 2240 | */ |
2241 | console_idx = log_next(console_idx); | 2241 | console_idx = log_next(console_idx); |
2242 | console_seq++; | 2242 | console_seq++; |
2243 | /* | 2243 | /* |
2244 | * We will get here again when we register a new | 2244 | * We will get here again when we register a new |
2245 | * CON_PRINTBUFFER console. Clear the flag so we | 2245 | * CON_PRINTBUFFER console. Clear the flag so we |
2246 | * will properly dump everything later. | 2246 | * will properly dump everything later. |
2247 | */ | 2247 | */ |
2248 | msg->flags &= ~LOG_NOCONS; | 2248 | msg->flags &= ~LOG_NOCONS; |
2249 | console_prev = msg->flags; | 2249 | console_prev = msg->flags; |
2250 | goto skip; | 2250 | goto skip; |
2251 | } | 2251 | } |
2252 | 2252 | ||
2253 | level = msg->level; | 2253 | level = msg->level; |
2254 | len += msg_print_text(msg, console_prev, false, | 2254 | len += msg_print_text(msg, console_prev, false, |
2255 | text + len, sizeof(text) - len); | 2255 | text + len, sizeof(text) - len); |
2256 | console_idx = log_next(console_idx); | 2256 | console_idx = log_next(console_idx); |
2257 | console_seq++; | 2257 | console_seq++; |
2258 | console_prev = msg->flags; | 2258 | console_prev = msg->flags; |
2259 | raw_spin_unlock(&logbuf_lock); | 2259 | raw_spin_unlock(&logbuf_lock); |
2260 | 2260 | ||
2261 | stop_critical_timings(); /* don't trace print latency */ | 2261 | stop_critical_timings(); /* don't trace print latency */ |
2262 | call_console_drivers(level, text, len); | 2262 | call_console_drivers(level, text, len); |
2263 | start_critical_timings(); | 2263 | start_critical_timings(); |
2264 | local_irq_restore(flags); | 2264 | local_irq_restore(flags); |
2265 | } | 2265 | } |
2266 | console_locked = 0; | 2266 | console_locked = 0; |
2267 | 2267 | ||
2268 | /* Release the exclusive_console once it is used */ | 2268 | /* Release the exclusive_console once it is used */ |
2269 | if (unlikely(exclusive_console)) | 2269 | if (unlikely(exclusive_console)) |
2270 | exclusive_console = NULL; | 2270 | exclusive_console = NULL; |
2271 | 2271 | ||
2272 | raw_spin_unlock(&logbuf_lock); | 2272 | raw_spin_unlock(&logbuf_lock); |
2273 | 2273 | ||
2274 | up_console_sem(); | 2274 | up_console_sem(); |
2275 | 2275 | ||
2276 | /* | 2276 | /* |
2277 | * Someone could have filled up the buffer again, so re-check if there's | 2277 | * Someone could have filled up the buffer again, so re-check if there's |
2278 | * something to flush. In case we cannot trylock the console_sem again, | 2278 | * something to flush. In case we cannot trylock the console_sem again, |
2279 | * there's a new owner and the console_unlock() from them will do the | 2279 | * there's a new owner and the console_unlock() from them will do the |
2280 | * flush, no worries. | 2280 | * flush, no worries. |
2281 | */ | 2281 | */ |
2282 | raw_spin_lock(&logbuf_lock); | 2282 | raw_spin_lock(&logbuf_lock); |
2283 | retry = console_seq != log_next_seq; | 2283 | retry = console_seq != log_next_seq; |
2284 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2284 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
2285 | 2285 | ||
2286 | if (retry && console_trylock()) | 2286 | if (retry && console_trylock()) |
2287 | goto again; | 2287 | goto again; |
2288 | 2288 | ||
2289 | if (wake_klogd) | 2289 | if (wake_klogd) |
2290 | wake_up_klogd(); | 2290 | wake_up_klogd(); |
2291 | } | 2291 | } |
2292 | EXPORT_SYMBOL(console_unlock); | 2292 | EXPORT_SYMBOL(console_unlock); |
2293 | 2293 | ||
2294 | /** | 2294 | /** |
2295 | * console_conditional_schedule - yield the CPU if required | 2295 | * console_conditional_schedule - yield the CPU if required |
2296 | * | 2296 | * |
2297 | * If the console code is currently allowed to sleep, and | 2297 | * If the console code is currently allowed to sleep, and |
2298 | * if this CPU should yield the CPU to another task, do | 2298 | * if this CPU should yield the CPU to another task, do |
2299 | * so here. | 2299 | * so here. |
2300 | * | 2300 | * |
2301 | * Must be called within console_lock();. | 2301 | * Must be called within console_lock();. |
2302 | */ | 2302 | */ |
2303 | void __sched console_conditional_schedule(void) | 2303 | void __sched console_conditional_schedule(void) |
2304 | { | 2304 | { |
2305 | if (console_may_schedule) | 2305 | if (console_may_schedule) |
2306 | cond_resched(); | 2306 | cond_resched(); |
2307 | } | 2307 | } |
2308 | EXPORT_SYMBOL(console_conditional_schedule); | 2308 | EXPORT_SYMBOL(console_conditional_schedule); |
2309 | 2309 | ||
2310 | void console_unblank(void) | 2310 | void console_unblank(void) |
2311 | { | 2311 | { |
2312 | struct console *c; | 2312 | struct console *c; |
2313 | 2313 | ||
2314 | /* | 2314 | /* |
2315 | * console_unblank can no longer be called in interrupt context unless | 2315 | * console_unblank can no longer be called in interrupt context unless |
2316 | * oops_in_progress is set to 1.. | 2316 | * oops_in_progress is set to 1.. |
2317 | */ | 2317 | */ |
2318 | if (oops_in_progress) { | 2318 | if (oops_in_progress) { |
2319 | if (down_trylock_console_sem() != 0) | 2319 | if (down_trylock_console_sem() != 0) |
2320 | return; | 2320 | return; |
2321 | } else | 2321 | } else |
2322 | console_lock(); | 2322 | console_lock(); |
2323 | 2323 | ||
2324 | console_locked = 1; | 2324 | console_locked = 1; |
2325 | console_may_schedule = 0; | 2325 | console_may_schedule = 0; |
2326 | for_each_console(c) | 2326 | for_each_console(c) |
2327 | if ((c->flags & CON_ENABLED) && c->unblank) | 2327 | if ((c->flags & CON_ENABLED) && c->unblank) |
2328 | c->unblank(); | 2328 | c->unblank(); |
2329 | console_unlock(); | 2329 | console_unlock(); |
2330 | } | 2330 | } |
2331 | 2331 | ||
2332 | /* | 2332 | /* |
2333 | * Return the console tty driver structure and its associated index | 2333 | * Return the console tty driver structure and its associated index |
2334 | */ | 2334 | */ |
2335 | struct tty_driver *console_device(int *index) | 2335 | struct tty_driver *console_device(int *index) |
2336 | { | 2336 | { |
2337 | struct console *c; | 2337 | struct console *c; |
2338 | struct tty_driver *driver = NULL; | 2338 | struct tty_driver *driver = NULL; |
2339 | 2339 | ||
2340 | console_lock(); | 2340 | console_lock(); |
2341 | for_each_console(c) { | 2341 | for_each_console(c) { |
2342 | if (!c->device) | 2342 | if (!c->device) |
2343 | continue; | 2343 | continue; |
2344 | driver = c->device(c, index); | 2344 | driver = c->device(c, index); |
2345 | if (driver) | 2345 | if (driver) |
2346 | break; | 2346 | break; |
2347 | } | 2347 | } |
2348 | console_unlock(); | 2348 | console_unlock(); |
2349 | return driver; | 2349 | return driver; |
2350 | } | 2350 | } |
2351 | 2351 | ||
2352 | /* | 2352 | /* |
2353 | * Prevent further output on the passed console device so that (for example) | 2353 | * Prevent further output on the passed console device so that (for example) |
2354 | * serial drivers can disable console output before suspending a port, and can | 2354 | * serial drivers can disable console output before suspending a port, and can |
2355 | * re-enable output afterwards. | 2355 | * re-enable output afterwards. |
2356 | */ | 2356 | */ |
2357 | void console_stop(struct console *console) | 2357 | void console_stop(struct console *console) |
2358 | { | 2358 | { |
2359 | console_lock(); | 2359 | console_lock(); |
2360 | console->flags &= ~CON_ENABLED; | 2360 | console->flags &= ~CON_ENABLED; |
2361 | console_unlock(); | 2361 | console_unlock(); |
2362 | } | 2362 | } |
2363 | EXPORT_SYMBOL(console_stop); | 2363 | EXPORT_SYMBOL(console_stop); |
2364 | 2364 | ||
2365 | void console_start(struct console *console) | 2365 | void console_start(struct console *console) |
2366 | { | 2366 | { |
2367 | console_lock(); | 2367 | console_lock(); |
2368 | console->flags |= CON_ENABLED; | 2368 | console->flags |= CON_ENABLED; |
2369 | console_unlock(); | 2369 | console_unlock(); |
2370 | } | 2370 | } |
2371 | EXPORT_SYMBOL(console_start); | 2371 | EXPORT_SYMBOL(console_start); |
2372 | 2372 | ||
2373 | static int __read_mostly keep_bootcon; | 2373 | static int __read_mostly keep_bootcon; |
2374 | 2374 | ||
2375 | static int __init keep_bootcon_setup(char *str) | 2375 | static int __init keep_bootcon_setup(char *str) |
2376 | { | 2376 | { |
2377 | keep_bootcon = 1; | 2377 | keep_bootcon = 1; |
2378 | pr_info("debug: skip boot console de-registration.\n"); | 2378 | pr_info("debug: skip boot console de-registration.\n"); |
2379 | 2379 | ||
2380 | return 0; | 2380 | return 0; |
2381 | } | 2381 | } |
2382 | 2382 | ||
2383 | early_param("keep_bootcon", keep_bootcon_setup); | 2383 | early_param("keep_bootcon", keep_bootcon_setup); |
2384 | 2384 | ||
2385 | /* | 2385 | /* |
2386 | * The console driver calls this routine during kernel initialization | 2386 | * The console driver calls this routine during kernel initialization |
2387 | * to register the console printing procedure with printk() and to | 2387 | * to register the console printing procedure with printk() and to |
2388 | * print any messages that were printed by the kernel before the | 2388 | * print any messages that were printed by the kernel before the |
2389 | * console driver was initialized. | 2389 | * console driver was initialized. |
2390 | * | 2390 | * |
2391 | * This can happen pretty early during the boot process (because of | 2391 | * This can happen pretty early during the boot process (because of |
2392 | * early_printk) - sometimes before setup_arch() completes - be careful | 2392 | * early_printk) - sometimes before setup_arch() completes - be careful |
2393 | * of what kernel features are used - they may not be initialised yet. | 2393 | * of what kernel features are used - they may not be initialised yet. |
2394 | * | 2394 | * |
2395 | * There are two types of consoles - bootconsoles (early_printk) and | 2395 | * There are two types of consoles - bootconsoles (early_printk) and |
2396 | * "real" consoles (everything which is not a bootconsole) which are | 2396 | * "real" consoles (everything which is not a bootconsole) which are |
2397 | * handled differently. | 2397 | * handled differently. |
2398 | * - Any number of bootconsoles can be registered at any time. | 2398 | * - Any number of bootconsoles can be registered at any time. |
2399 | * - As soon as a "real" console is registered, all bootconsoles | 2399 | * - As soon as a "real" console is registered, all bootconsoles |
2400 | * will be unregistered automatically. | 2400 | * will be unregistered automatically. |
2401 | * - Once a "real" console is registered, any attempt to register a | 2401 | * - Once a "real" console is registered, any attempt to register a |
2402 | * bootconsoles will be rejected | 2402 | * bootconsoles will be rejected |
2403 | */ | 2403 | */ |
2404 | void register_console(struct console *newcon) | 2404 | void register_console(struct console *newcon) |
2405 | { | 2405 | { |
2406 | int i; | 2406 | int i; |
2407 | unsigned long flags; | 2407 | unsigned long flags; |
2408 | struct console *bcon = NULL; | 2408 | struct console *bcon = NULL; |
2409 | struct console_cmdline *c; | 2409 | struct console_cmdline *c; |
2410 | 2410 | ||
2411 | if (console_drivers) | 2411 | if (console_drivers) |
2412 | for_each_console(bcon) | 2412 | for_each_console(bcon) |
2413 | if (WARN(bcon == newcon, | 2413 | if (WARN(bcon == newcon, |
2414 | "console '%s%d' already registered\n", | 2414 | "console '%s%d' already registered\n", |
2415 | bcon->name, bcon->index)) | 2415 | bcon->name, bcon->index)) |
2416 | return; | 2416 | return; |
2417 | 2417 | ||
2418 | /* | 2418 | /* |
2419 | * before we register a new CON_BOOT console, make sure we don't | 2419 | * before we register a new CON_BOOT console, make sure we don't |
2420 | * already have a valid console | 2420 | * already have a valid console |
2421 | */ | 2421 | */ |
2422 | if (console_drivers && newcon->flags & CON_BOOT) { | 2422 | if (console_drivers && newcon->flags & CON_BOOT) { |
2423 | /* find the last or real console */ | 2423 | /* find the last or real console */ |
2424 | for_each_console(bcon) { | 2424 | for_each_console(bcon) { |
2425 | if (!(bcon->flags & CON_BOOT)) { | 2425 | if (!(bcon->flags & CON_BOOT)) { |
2426 | pr_info("Too late to register bootconsole %s%d\n", | 2426 | pr_info("Too late to register bootconsole %s%d\n", |
2427 | newcon->name, newcon->index); | 2427 | newcon->name, newcon->index); |
2428 | return; | 2428 | return; |
2429 | } | 2429 | } |
2430 | } | 2430 | } |
2431 | } | 2431 | } |
2432 | 2432 | ||
2433 | if (console_drivers && console_drivers->flags & CON_BOOT) | 2433 | if (console_drivers && console_drivers->flags & CON_BOOT) |
2434 | bcon = console_drivers; | 2434 | bcon = console_drivers; |
2435 | 2435 | ||
2436 | if (preferred_console < 0 || bcon || !console_drivers) | 2436 | if (preferred_console < 0 || bcon || !console_drivers) |
2437 | preferred_console = selected_console; | 2437 | preferred_console = selected_console; |
2438 | 2438 | ||
2439 | if (newcon->early_setup) | 2439 | if (newcon->early_setup) |
2440 | newcon->early_setup(); | 2440 | newcon->early_setup(); |
2441 | 2441 | ||
2442 | /* | 2442 | /* |
2443 | * See if we want to use this console driver. If we | 2443 | * See if we want to use this console driver. If we |
2444 | * didn't select a console we take the first one | 2444 | * didn't select a console we take the first one |
2445 | * that registers here. | 2445 | * that registers here. |
2446 | */ | 2446 | */ |
2447 | if (preferred_console < 0) { | 2447 | if (preferred_console < 0) { |
2448 | if (newcon->index < 0) | 2448 | if (newcon->index < 0) |
2449 | newcon->index = 0; | 2449 | newcon->index = 0; |
2450 | if (newcon->setup == NULL || | 2450 | if (newcon->setup == NULL || |
2451 | newcon->setup(newcon, NULL) == 0) { | 2451 | newcon->setup(newcon, NULL) == 0) { |
2452 | newcon->flags |= CON_ENABLED; | 2452 | newcon->flags |= CON_ENABLED; |
2453 | if (newcon->device) { | 2453 | if (newcon->device) { |
2454 | newcon->flags |= CON_CONSDEV; | 2454 | newcon->flags |= CON_CONSDEV; |
2455 | preferred_console = 0; | 2455 | preferred_console = 0; |
2456 | } | 2456 | } |
2457 | } | 2457 | } |
2458 | } | 2458 | } |
2459 | 2459 | ||
2460 | /* | 2460 | /* |
2461 | * See if this console matches one we selected on | 2461 | * See if this console matches one we selected on |
2462 | * the command line. | 2462 | * the command line. |
2463 | */ | 2463 | */ |
2464 | for (i = 0, c = console_cmdline; | 2464 | for (i = 0, c = console_cmdline; |
2465 | i < MAX_CMDLINECONSOLES && c->name[0]; | 2465 | i < MAX_CMDLINECONSOLES && c->name[0]; |
2466 | i++, c++) { | 2466 | i++, c++) { |
2467 | BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name)); | ||
2467 | if (strcmp(c->name, newcon->name) != 0) | 2468 | if (strcmp(c->name, newcon->name) != 0) |
2468 | continue; | 2469 | continue; |
2469 | if (newcon->index >= 0 && | 2470 | if (newcon->index >= 0 && |
2470 | newcon->index != c->index) | 2471 | newcon->index != c->index) |
2471 | continue; | 2472 | continue; |
2472 | if (newcon->index < 0) | 2473 | if (newcon->index < 0) |
2473 | newcon->index = c->index; | 2474 | newcon->index = c->index; |
2474 | 2475 | ||
2475 | if (_braille_register_console(newcon, c)) | 2476 | if (_braille_register_console(newcon, c)) |
2476 | return; | 2477 | return; |
2477 | 2478 | ||
2478 | if (newcon->setup && | 2479 | if (newcon->setup && |
2479 | newcon->setup(newcon, console_cmdline[i].options) != 0) | 2480 | newcon->setup(newcon, console_cmdline[i].options) != 0) |
2480 | break; | 2481 | break; |
2481 | newcon->flags |= CON_ENABLED; | 2482 | newcon->flags |= CON_ENABLED; |
2482 | newcon->index = c->index; | 2483 | newcon->index = c->index; |
2483 | if (i == selected_console) { | 2484 | if (i == selected_console) { |
2484 | newcon->flags |= CON_CONSDEV; | 2485 | newcon->flags |= CON_CONSDEV; |
2485 | preferred_console = selected_console; | 2486 | preferred_console = selected_console; |
2486 | } | 2487 | } |
2487 | break; | 2488 | break; |
2488 | } | 2489 | } |
2489 | 2490 | ||
2490 | if (!(newcon->flags & CON_ENABLED)) | 2491 | if (!(newcon->flags & CON_ENABLED)) |
2491 | return; | 2492 | return; |
2492 | 2493 | ||
2493 | /* | 2494 | /* |
2494 | * If we have a bootconsole, and are switching to a real console, | 2495 | * If we have a bootconsole, and are switching to a real console, |
2495 | * don't print everything out again, since when the boot console, and | 2496 | * don't print everything out again, since when the boot console, and |
2496 | * the real console are the same physical device, it's annoying to | 2497 | * the real console are the same physical device, it's annoying to |
2497 | * see the beginning boot messages twice | 2498 | * see the beginning boot messages twice |
2498 | */ | 2499 | */ |
2499 | if (bcon && ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV)) | 2500 | if (bcon && ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV)) |
2500 | newcon->flags &= ~CON_PRINTBUFFER; | 2501 | newcon->flags &= ~CON_PRINTBUFFER; |
2501 | 2502 | ||
2502 | /* | 2503 | /* |
2503 | * Put this console in the list - keep the | 2504 | * Put this console in the list - keep the |
2504 | * preferred driver at the head of the list. | 2505 | * preferred driver at the head of the list. |
2505 | */ | 2506 | */ |
2506 | console_lock(); | 2507 | console_lock(); |
2507 | if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) { | 2508 | if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) { |
2508 | newcon->next = console_drivers; | 2509 | newcon->next = console_drivers; |
2509 | console_drivers = newcon; | 2510 | console_drivers = newcon; |
2510 | if (newcon->next) | 2511 | if (newcon->next) |
2511 | newcon->next->flags &= ~CON_CONSDEV; | 2512 | newcon->next->flags &= ~CON_CONSDEV; |
2512 | } else { | 2513 | } else { |
2513 | newcon->next = console_drivers->next; | 2514 | newcon->next = console_drivers->next; |
2514 | console_drivers->next = newcon; | 2515 | console_drivers->next = newcon; |
2515 | } | 2516 | } |
2516 | if (newcon->flags & CON_PRINTBUFFER) { | 2517 | if (newcon->flags & CON_PRINTBUFFER) { |
2517 | /* | 2518 | /* |
2518 | * console_unlock(); will print out the buffered messages | 2519 | * console_unlock(); will print out the buffered messages |
2519 | * for us. | 2520 | * for us. |
2520 | */ | 2521 | */ |
2521 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2522 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
2522 | console_seq = syslog_seq; | 2523 | console_seq = syslog_seq; |
2523 | console_idx = syslog_idx; | 2524 | console_idx = syslog_idx; |
2524 | console_prev = syslog_prev; | 2525 | console_prev = syslog_prev; |
2525 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2526 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
2526 | /* | 2527 | /* |
2527 | * We're about to replay the log buffer. Only do this to the | 2528 | * We're about to replay the log buffer. Only do this to the |
2528 | * just-registered console to avoid excessive message spam to | 2529 | * just-registered console to avoid excessive message spam to |
2529 | * the already-registered consoles. | 2530 | * the already-registered consoles. |
2530 | */ | 2531 | */ |
2531 | exclusive_console = newcon; | 2532 | exclusive_console = newcon; |
2532 | } | 2533 | } |
2533 | console_unlock(); | 2534 | console_unlock(); |
2534 | console_sysfs_notify(); | 2535 | console_sysfs_notify(); |
2535 | 2536 | ||
2536 | /* | 2537 | /* |
2537 | * By unregistering the bootconsoles after we enable the real console | 2538 | * By unregistering the bootconsoles after we enable the real console |
2538 | * we get the "console xxx enabled" message on all the consoles - | 2539 | * we get the "console xxx enabled" message on all the consoles - |
2539 | * boot consoles, real consoles, etc - this is to ensure that end | 2540 | * boot consoles, real consoles, etc - this is to ensure that end |
2540 | * users know there might be something in the kernel's log buffer that | 2541 | * users know there might be something in the kernel's log buffer that |
2541 | * went to the bootconsole (that they do not see on the real console) | 2542 | * went to the bootconsole (that they do not see on the real console) |
2542 | */ | 2543 | */ |
2543 | pr_info("%sconsole [%s%d] enabled\n", | 2544 | pr_info("%sconsole [%s%d] enabled\n", |
2544 | (newcon->flags & CON_BOOT) ? "boot" : "" , | 2545 | (newcon->flags & CON_BOOT) ? "boot" : "" , |
2545 | newcon->name, newcon->index); | 2546 | newcon->name, newcon->index); |
2546 | if (bcon && | 2547 | if (bcon && |
2547 | ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) && | 2548 | ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) && |
2548 | !keep_bootcon) { | 2549 | !keep_bootcon) { |
2549 | /* We need to iterate through all boot consoles, to make | 2550 | /* We need to iterate through all boot consoles, to make |
2550 | * sure we print everything out, before we unregister them. | 2551 | * sure we print everything out, before we unregister them. |
2551 | */ | 2552 | */ |
2552 | for_each_console(bcon) | 2553 | for_each_console(bcon) |
2553 | if (bcon->flags & CON_BOOT) | 2554 | if (bcon->flags & CON_BOOT) |
2554 | unregister_console(bcon); | 2555 | unregister_console(bcon); |
2555 | } | 2556 | } |
2556 | } | 2557 | } |
2557 | EXPORT_SYMBOL(register_console); | 2558 | EXPORT_SYMBOL(register_console); |
2558 | 2559 | ||
2559 | int unregister_console(struct console *console) | 2560 | int unregister_console(struct console *console) |
2560 | { | 2561 | { |
2561 | struct console *a, *b; | 2562 | struct console *a, *b; |
2562 | int res; | 2563 | int res; |
2563 | 2564 | ||
2564 | pr_info("%sconsole [%s%d] disabled\n", | 2565 | pr_info("%sconsole [%s%d] disabled\n", |
2565 | (console->flags & CON_BOOT) ? "boot" : "" , | 2566 | (console->flags & CON_BOOT) ? "boot" : "" , |
2566 | console->name, console->index); | 2567 | console->name, console->index); |
2567 | 2568 | ||
2568 | res = _braille_unregister_console(console); | 2569 | res = _braille_unregister_console(console); |
2569 | if (res) | 2570 | if (res) |
2570 | return res; | 2571 | return res; |
2571 | 2572 | ||
2572 | res = 1; | 2573 | res = 1; |
2573 | console_lock(); | 2574 | console_lock(); |
2574 | if (console_drivers == console) { | 2575 | if (console_drivers == console) { |
2575 | console_drivers=console->next; | 2576 | console_drivers=console->next; |
2576 | res = 0; | 2577 | res = 0; |
2577 | } else if (console_drivers) { | 2578 | } else if (console_drivers) { |
2578 | for (a=console_drivers->next, b=console_drivers ; | 2579 | for (a=console_drivers->next, b=console_drivers ; |
2579 | a; b=a, a=b->next) { | 2580 | a; b=a, a=b->next) { |
2580 | if (a == console) { | 2581 | if (a == console) { |
2581 | b->next = a->next; | 2582 | b->next = a->next; |
2582 | res = 0; | 2583 | res = 0; |
2583 | break; | 2584 | break; |
2584 | } | 2585 | } |
2585 | } | 2586 | } |
2586 | } | 2587 | } |
2587 | 2588 | ||
2588 | /* | 2589 | /* |
2589 | * If this isn't the last console and it has CON_CONSDEV set, we | 2590 | * If this isn't the last console and it has CON_CONSDEV set, we |
2590 | * need to set it on the next preferred console. | 2591 | * need to set it on the next preferred console. |
2591 | */ | 2592 | */ |
2592 | if (console_drivers != NULL && console->flags & CON_CONSDEV) | 2593 | if (console_drivers != NULL && console->flags & CON_CONSDEV) |
2593 | console_drivers->flags |= CON_CONSDEV; | 2594 | console_drivers->flags |= CON_CONSDEV; |
2594 | 2595 | ||
2595 | console->flags &= ~CON_ENABLED; | 2596 | console->flags &= ~CON_ENABLED; |
2596 | console_unlock(); | 2597 | console_unlock(); |
2597 | console_sysfs_notify(); | 2598 | console_sysfs_notify(); |
2598 | return res; | 2599 | return res; |
2599 | } | 2600 | } |
2600 | EXPORT_SYMBOL(unregister_console); | 2601 | EXPORT_SYMBOL(unregister_console); |
2601 | 2602 | ||
2602 | static int __init printk_late_init(void) | 2603 | static int __init printk_late_init(void) |
2603 | { | 2604 | { |
2604 | struct console *con; | 2605 | struct console *con; |
2605 | 2606 | ||
2606 | for_each_console(con) { | 2607 | for_each_console(con) { |
2607 | if (!keep_bootcon && con->flags & CON_BOOT) { | 2608 | if (!keep_bootcon && con->flags & CON_BOOT) { |
2608 | unregister_console(con); | 2609 | unregister_console(con); |
2609 | } | 2610 | } |
2610 | } | 2611 | } |
2611 | hotcpu_notifier(console_cpu_notify, 0); | 2612 | hotcpu_notifier(console_cpu_notify, 0); |
2612 | return 0; | 2613 | return 0; |
2613 | } | 2614 | } |
2614 | late_initcall(printk_late_init); | 2615 | late_initcall(printk_late_init); |
2615 | 2616 | ||
2616 | #if defined CONFIG_PRINTK | 2617 | #if defined CONFIG_PRINTK |
2617 | /* | 2618 | /* |
2618 | * Delayed printk version, for scheduler-internal messages: | 2619 | * Delayed printk version, for scheduler-internal messages: |
2619 | */ | 2620 | */ |
2620 | #define PRINTK_PENDING_WAKEUP 0x01 | 2621 | #define PRINTK_PENDING_WAKEUP 0x01 |
2621 | #define PRINTK_PENDING_OUTPUT 0x02 | 2622 | #define PRINTK_PENDING_OUTPUT 0x02 |
2622 | 2623 | ||
2623 | static DEFINE_PER_CPU(int, printk_pending); | 2624 | static DEFINE_PER_CPU(int, printk_pending); |
2624 | 2625 | ||
2625 | static void wake_up_klogd_work_func(struct irq_work *irq_work) | 2626 | static void wake_up_klogd_work_func(struct irq_work *irq_work) |
2626 | { | 2627 | { |
2627 | int pending = __this_cpu_xchg(printk_pending, 0); | 2628 | int pending = __this_cpu_xchg(printk_pending, 0); |
2628 | 2629 | ||
2629 | if (pending & PRINTK_PENDING_OUTPUT) { | 2630 | if (pending & PRINTK_PENDING_OUTPUT) { |
2630 | /* If trylock fails, someone else is doing the printing */ | 2631 | /* If trylock fails, someone else is doing the printing */ |
2631 | if (console_trylock()) | 2632 | if (console_trylock()) |
2632 | console_unlock(); | 2633 | console_unlock(); |
2633 | } | 2634 | } |
2634 | 2635 | ||
2635 | if (pending & PRINTK_PENDING_WAKEUP) | 2636 | if (pending & PRINTK_PENDING_WAKEUP) |
2636 | wake_up_interruptible(&log_wait); | 2637 | wake_up_interruptible(&log_wait); |
2637 | } | 2638 | } |
2638 | 2639 | ||
2639 | static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = { | 2640 | static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = { |
2640 | .func = wake_up_klogd_work_func, | 2641 | .func = wake_up_klogd_work_func, |
2641 | .flags = IRQ_WORK_LAZY, | 2642 | .flags = IRQ_WORK_LAZY, |
2642 | }; | 2643 | }; |
2643 | 2644 | ||
2644 | void wake_up_klogd(void) | 2645 | void wake_up_klogd(void) |
2645 | { | 2646 | { |
2646 | preempt_disable(); | 2647 | preempt_disable(); |
2647 | if (waitqueue_active(&log_wait)) { | 2648 | if (waitqueue_active(&log_wait)) { |
2648 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); | 2649 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); |
2649 | irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); | 2650 | irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); |
2650 | } | 2651 | } |
2651 | preempt_enable(); | 2652 | preempt_enable(); |
2652 | } | 2653 | } |
2653 | 2654 | ||
2654 | int printk_deferred(const char *fmt, ...) | 2655 | int printk_deferred(const char *fmt, ...) |
2655 | { | 2656 | { |
2656 | va_list args; | 2657 | va_list args; |
2657 | int r; | 2658 | int r; |
2658 | 2659 | ||
2659 | preempt_disable(); | 2660 | preempt_disable(); |
2660 | va_start(args, fmt); | 2661 | va_start(args, fmt); |
2661 | r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, 0, fmt, args); | 2662 | r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, 0, fmt, args); |
2662 | va_end(args); | 2663 | va_end(args); |
2663 | 2664 | ||
2664 | __this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT); | 2665 | __this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT); |
2665 | irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); | 2666 | irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); |
2666 | preempt_enable(); | 2667 | preempt_enable(); |
2667 | 2668 | ||
2668 | return r; | 2669 | return r; |
2669 | } | 2670 | } |
2670 | 2671 | ||
2671 | /* | 2672 | /* |
2672 | * printk rate limiting, lifted from the networking subsystem. | 2673 | * printk rate limiting, lifted from the networking subsystem. |
2673 | * | 2674 | * |
2674 | * This enforces a rate limit: not more than 10 kernel messages | 2675 | * This enforces a rate limit: not more than 10 kernel messages |
2675 | * every 5s to make a denial-of-service attack impossible. | 2676 | * every 5s to make a denial-of-service attack impossible. |
2676 | */ | 2677 | */ |
2677 | DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10); | 2678 | DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10); |
2678 | 2679 | ||
2679 | int __printk_ratelimit(const char *func) | 2680 | int __printk_ratelimit(const char *func) |
2680 | { | 2681 | { |
2681 | return ___ratelimit(&printk_ratelimit_state, func); | 2682 | return ___ratelimit(&printk_ratelimit_state, func); |
2682 | } | 2683 | } |
2683 | EXPORT_SYMBOL(__printk_ratelimit); | 2684 | EXPORT_SYMBOL(__printk_ratelimit); |
2684 | 2685 | ||
2685 | /** | 2686 | /** |
2686 | * printk_timed_ratelimit - caller-controlled printk ratelimiting | 2687 | * printk_timed_ratelimit - caller-controlled printk ratelimiting |
2687 | * @caller_jiffies: pointer to caller's state | 2688 | * @caller_jiffies: pointer to caller's state |
2688 | * @interval_msecs: minimum interval between prints | 2689 | * @interval_msecs: minimum interval between prints |
2689 | * | 2690 | * |
2690 | * printk_timed_ratelimit() returns true if more than @interval_msecs | 2691 | * printk_timed_ratelimit() returns true if more than @interval_msecs |
2691 | * milliseconds have elapsed since the last time printk_timed_ratelimit() | 2692 | * milliseconds have elapsed since the last time printk_timed_ratelimit() |
2692 | * returned true. | 2693 | * returned true. |
2693 | */ | 2694 | */ |
2694 | bool printk_timed_ratelimit(unsigned long *caller_jiffies, | 2695 | bool printk_timed_ratelimit(unsigned long *caller_jiffies, |
2695 | unsigned int interval_msecs) | 2696 | unsigned int interval_msecs) |
2696 | { | 2697 | { |
2697 | unsigned long elapsed = jiffies - *caller_jiffies; | 2698 | unsigned long elapsed = jiffies - *caller_jiffies; |
2698 | 2699 | ||
2699 | if (*caller_jiffies && elapsed <= msecs_to_jiffies(interval_msecs)) | 2700 | if (*caller_jiffies && elapsed <= msecs_to_jiffies(interval_msecs)) |
2700 | return false; | 2701 | return false; |
2701 | 2702 | ||
2702 | *caller_jiffies = jiffies; | 2703 | *caller_jiffies = jiffies; |
2703 | return true; | 2704 | return true; |
2704 | } | 2705 | } |
2705 | EXPORT_SYMBOL(printk_timed_ratelimit); | 2706 | EXPORT_SYMBOL(printk_timed_ratelimit); |
2706 | 2707 | ||
2707 | static DEFINE_SPINLOCK(dump_list_lock); | 2708 | static DEFINE_SPINLOCK(dump_list_lock); |
2708 | static LIST_HEAD(dump_list); | 2709 | static LIST_HEAD(dump_list); |
2709 | 2710 | ||
2710 | /** | 2711 | /** |
2711 | * kmsg_dump_register - register a kernel log dumper. | 2712 | * kmsg_dump_register - register a kernel log dumper. |
2712 | * @dumper: pointer to the kmsg_dumper structure | 2713 | * @dumper: pointer to the kmsg_dumper structure |
2713 | * | 2714 | * |
2714 | * Adds a kernel log dumper to the system. The dump callback in the | 2715 | * Adds a kernel log dumper to the system. The dump callback in the |
2715 | * structure will be called when the kernel oopses or panics and must be | 2716 | * structure will be called when the kernel oopses or panics and must be |
2716 | * set. Returns zero on success and %-EINVAL or %-EBUSY otherwise. | 2717 | * set. Returns zero on success and %-EINVAL or %-EBUSY otherwise. |
2717 | */ | 2718 | */ |
2718 | int kmsg_dump_register(struct kmsg_dumper *dumper) | 2719 | int kmsg_dump_register(struct kmsg_dumper *dumper) |
2719 | { | 2720 | { |
2720 | unsigned long flags; | 2721 | unsigned long flags; |
2721 | int err = -EBUSY; | 2722 | int err = -EBUSY; |
2722 | 2723 | ||
2723 | /* The dump callback needs to be set */ | 2724 | /* The dump callback needs to be set */ |
2724 | if (!dumper->dump) | 2725 | if (!dumper->dump) |
2725 | return -EINVAL; | 2726 | return -EINVAL; |
2726 | 2727 | ||
2727 | spin_lock_irqsave(&dump_list_lock, flags); | 2728 | spin_lock_irqsave(&dump_list_lock, flags); |
2728 | /* Don't allow registering multiple times */ | 2729 | /* Don't allow registering multiple times */ |
2729 | if (!dumper->registered) { | 2730 | if (!dumper->registered) { |
2730 | dumper->registered = 1; | 2731 | dumper->registered = 1; |
2731 | list_add_tail_rcu(&dumper->list, &dump_list); | 2732 | list_add_tail_rcu(&dumper->list, &dump_list); |
2732 | err = 0; | 2733 | err = 0; |
2733 | } | 2734 | } |
2734 | spin_unlock_irqrestore(&dump_list_lock, flags); | 2735 | spin_unlock_irqrestore(&dump_list_lock, flags); |
2735 | 2736 | ||
2736 | return err; | 2737 | return err; |
2737 | } | 2738 | } |
2738 | EXPORT_SYMBOL_GPL(kmsg_dump_register); | 2739 | EXPORT_SYMBOL_GPL(kmsg_dump_register); |
2739 | 2740 | ||
2740 | /** | 2741 | /** |
2741 | * kmsg_dump_unregister - unregister a kmsg dumper. | 2742 | * kmsg_dump_unregister - unregister a kmsg dumper. |
2742 | * @dumper: pointer to the kmsg_dumper structure | 2743 | * @dumper: pointer to the kmsg_dumper structure |
2743 | * | 2744 | * |
2744 | * Removes a dump device from the system. Returns zero on success and | 2745 | * Removes a dump device from the system. Returns zero on success and |
2745 | * %-EINVAL otherwise. | 2746 | * %-EINVAL otherwise. |
2746 | */ | 2747 | */ |
2747 | int kmsg_dump_unregister(struct kmsg_dumper *dumper) | 2748 | int kmsg_dump_unregister(struct kmsg_dumper *dumper) |
2748 | { | 2749 | { |
2749 | unsigned long flags; | 2750 | unsigned long flags; |
2750 | int err = -EINVAL; | 2751 | int err = -EINVAL; |
2751 | 2752 | ||
2752 | spin_lock_irqsave(&dump_list_lock, flags); | 2753 | spin_lock_irqsave(&dump_list_lock, flags); |
2753 | if (dumper->registered) { | 2754 | if (dumper->registered) { |
2754 | dumper->registered = 0; | 2755 | dumper->registered = 0; |
2755 | list_del_rcu(&dumper->list); | 2756 | list_del_rcu(&dumper->list); |
2756 | err = 0; | 2757 | err = 0; |
2757 | } | 2758 | } |
2758 | spin_unlock_irqrestore(&dump_list_lock, flags); | 2759 | spin_unlock_irqrestore(&dump_list_lock, flags); |
2759 | synchronize_rcu(); | 2760 | synchronize_rcu(); |
2760 | 2761 | ||
2761 | return err; | 2762 | return err; |
2762 | } | 2763 | } |
2763 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); | 2764 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); |
2764 | 2765 | ||
2765 | static bool always_kmsg_dump; | 2766 | static bool always_kmsg_dump; |
2766 | module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR); | 2767 | module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR); |
2767 | 2768 | ||
2768 | /** | 2769 | /** |
2769 | * kmsg_dump - dump kernel log to kernel message dumpers. | 2770 | * kmsg_dump - dump kernel log to kernel message dumpers. |
2770 | * @reason: the reason (oops, panic etc) for dumping | 2771 | * @reason: the reason (oops, panic etc) for dumping |
2771 | * | 2772 | * |
2772 | * Call each of the registered dumper's dump() callback, which can | 2773 | * Call each of the registered dumper's dump() callback, which can |
2773 | * retrieve the kmsg records with kmsg_dump_get_line() or | 2774 | * retrieve the kmsg records with kmsg_dump_get_line() or |
2774 | * kmsg_dump_get_buffer(). | 2775 | * kmsg_dump_get_buffer(). |
2775 | */ | 2776 | */ |
2776 | void kmsg_dump(enum kmsg_dump_reason reason) | 2777 | void kmsg_dump(enum kmsg_dump_reason reason) |
2777 | { | 2778 | { |
2778 | struct kmsg_dumper *dumper; | 2779 | struct kmsg_dumper *dumper; |
2779 | unsigned long flags; | 2780 | unsigned long flags; |
2780 | 2781 | ||
2781 | if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump) | 2782 | if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump) |
2782 | return; | 2783 | return; |
2783 | 2784 | ||
2784 | rcu_read_lock(); | 2785 | rcu_read_lock(); |
2785 | list_for_each_entry_rcu(dumper, &dump_list, list) { | 2786 | list_for_each_entry_rcu(dumper, &dump_list, list) { |
2786 | if (dumper->max_reason && reason > dumper->max_reason) | 2787 | if (dumper->max_reason && reason > dumper->max_reason) |
2787 | continue; | 2788 | continue; |
2788 | 2789 | ||
2789 | /* initialize iterator with data about the stored records */ | 2790 | /* initialize iterator with data about the stored records */ |
2790 | dumper->active = true; | 2791 | dumper->active = true; |
2791 | 2792 | ||
2792 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2793 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
2793 | dumper->cur_seq = clear_seq; | 2794 | dumper->cur_seq = clear_seq; |
2794 | dumper->cur_idx = clear_idx; | 2795 | dumper->cur_idx = clear_idx; |
2795 | dumper->next_seq = log_next_seq; | 2796 | dumper->next_seq = log_next_seq; |
2796 | dumper->next_idx = log_next_idx; | 2797 | dumper->next_idx = log_next_idx; |
2797 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2798 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
2798 | 2799 | ||
2799 | /* invoke dumper which will iterate over records */ | 2800 | /* invoke dumper which will iterate over records */ |
2800 | dumper->dump(dumper, reason); | 2801 | dumper->dump(dumper, reason); |
2801 | 2802 | ||
2802 | /* reset iterator */ | 2803 | /* reset iterator */ |
2803 | dumper->active = false; | 2804 | dumper->active = false; |
2804 | } | 2805 | } |
2805 | rcu_read_unlock(); | 2806 | rcu_read_unlock(); |
2806 | } | 2807 | } |
2807 | 2808 | ||
2808 | /** | 2809 | /** |
2809 | * kmsg_dump_get_line_nolock - retrieve one kmsg log line (unlocked version) | 2810 | * kmsg_dump_get_line_nolock - retrieve one kmsg log line (unlocked version) |
2810 | * @dumper: registered kmsg dumper | 2811 | * @dumper: registered kmsg dumper |
2811 | * @syslog: include the "<4>" prefixes | 2812 | * @syslog: include the "<4>" prefixes |
2812 | * @line: buffer to copy the line to | 2813 | * @line: buffer to copy the line to |
2813 | * @size: maximum size of the buffer | 2814 | * @size: maximum size of the buffer |
2814 | * @len: length of line placed into buffer | 2815 | * @len: length of line placed into buffer |
2815 | * | 2816 | * |
2816 | * Start at the beginning of the kmsg buffer, with the oldest kmsg | 2817 | * Start at the beginning of the kmsg buffer, with the oldest kmsg |
2817 | * record, and copy one record into the provided buffer. | 2818 | * record, and copy one record into the provided buffer. |
2818 | * | 2819 | * |
2819 | * Consecutive calls will return the next available record moving | 2820 | * Consecutive calls will return the next available record moving |
2820 | * towards the end of the buffer with the youngest messages. | 2821 | * towards the end of the buffer with the youngest messages. |
2821 | * | 2822 | * |
2822 | * A return value of FALSE indicates that there are no more records to | 2823 | * A return value of FALSE indicates that there are no more records to |
2823 | * read. | 2824 | * read. |
2824 | * | 2825 | * |
2825 | * The function is similar to kmsg_dump_get_line(), but grabs no locks. | 2826 | * The function is similar to kmsg_dump_get_line(), but grabs no locks. |
2826 | */ | 2827 | */ |
2827 | bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog, | 2828 | bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog, |
2828 | char *line, size_t size, size_t *len) | 2829 | char *line, size_t size, size_t *len) |
2829 | { | 2830 | { |
2830 | struct printk_log *msg; | 2831 | struct printk_log *msg; |
2831 | size_t l = 0; | 2832 | size_t l = 0; |
2832 | bool ret = false; | 2833 | bool ret = false; |
2833 | 2834 | ||
2834 | if (!dumper->active) | 2835 | if (!dumper->active) |
2835 | goto out; | 2836 | goto out; |
2836 | 2837 | ||
2837 | if (dumper->cur_seq < log_first_seq) { | 2838 | if (dumper->cur_seq < log_first_seq) { |
2838 | /* messages are gone, move to first available one */ | 2839 | /* messages are gone, move to first available one */ |
2839 | dumper->cur_seq = log_first_seq; | 2840 | dumper->cur_seq = log_first_seq; |
2840 | dumper->cur_idx = log_first_idx; | 2841 | dumper->cur_idx = log_first_idx; |
2841 | } | 2842 | } |
2842 | 2843 | ||
2843 | /* last entry */ | 2844 | /* last entry */ |
2844 | if (dumper->cur_seq >= log_next_seq) | 2845 | if (dumper->cur_seq >= log_next_seq) |
2845 | goto out; | 2846 | goto out; |
2846 | 2847 | ||
2847 | msg = log_from_idx(dumper->cur_idx); | 2848 | msg = log_from_idx(dumper->cur_idx); |
2848 | l = msg_print_text(msg, 0, syslog, line, size); | 2849 | l = msg_print_text(msg, 0, syslog, line, size); |
2849 | 2850 | ||
2850 | dumper->cur_idx = log_next(dumper->cur_idx); | 2851 | dumper->cur_idx = log_next(dumper->cur_idx); |
2851 | dumper->cur_seq++; | 2852 | dumper->cur_seq++; |
2852 | ret = true; | 2853 | ret = true; |
2853 | out: | 2854 | out: |
2854 | if (len) | 2855 | if (len) |
2855 | *len = l; | 2856 | *len = l; |
2856 | return ret; | 2857 | return ret; |
2857 | } | 2858 | } |
2858 | 2859 | ||
2859 | /** | 2860 | /** |
2860 | * kmsg_dump_get_line - retrieve one kmsg log line | 2861 | * kmsg_dump_get_line - retrieve one kmsg log line |
2861 | * @dumper: registered kmsg dumper | 2862 | * @dumper: registered kmsg dumper |
2862 | * @syslog: include the "<4>" prefixes | 2863 | * @syslog: include the "<4>" prefixes |
2863 | * @line: buffer to copy the line to | 2864 | * @line: buffer to copy the line to |
2864 | * @size: maximum size of the buffer | 2865 | * @size: maximum size of the buffer |
2865 | * @len: length of line placed into buffer | 2866 | * @len: length of line placed into buffer |
2866 | * | 2867 | * |
2867 | * Start at the beginning of the kmsg buffer, with the oldest kmsg | 2868 | * Start at the beginning of the kmsg buffer, with the oldest kmsg |
2868 | * record, and copy one record into the provided buffer. | 2869 | * record, and copy one record into the provided buffer. |
2869 | * | 2870 | * |
2870 | * Consecutive calls will return the next available record moving | 2871 | * Consecutive calls will return the next available record moving |
2871 | * towards the end of the buffer with the youngest messages. | 2872 | * towards the end of the buffer with the youngest messages. |
2872 | * | 2873 | * |
2873 | * A return value of FALSE indicates that there are no more records to | 2874 | * A return value of FALSE indicates that there are no more records to |
2874 | * read. | 2875 | * read. |
2875 | */ | 2876 | */ |
2876 | bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, | 2877 | bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, |
2877 | char *line, size_t size, size_t *len) | 2878 | char *line, size_t size, size_t *len) |
2878 | { | 2879 | { |
2879 | unsigned long flags; | 2880 | unsigned long flags; |
2880 | bool ret; | 2881 | bool ret; |
2881 | 2882 | ||
2882 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2883 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
2883 | ret = kmsg_dump_get_line_nolock(dumper, syslog, line, size, len); | 2884 | ret = kmsg_dump_get_line_nolock(dumper, syslog, line, size, len); |
2884 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2885 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
2885 | 2886 | ||
2886 | return ret; | 2887 | return ret; |
2887 | } | 2888 | } |
2888 | EXPORT_SYMBOL_GPL(kmsg_dump_get_line); | 2889 | EXPORT_SYMBOL_GPL(kmsg_dump_get_line); |
2889 | 2890 | ||
2890 | /** | 2891 | /** |
2891 | * kmsg_dump_get_buffer - copy kmsg log lines | 2892 | * kmsg_dump_get_buffer - copy kmsg log lines |
2892 | * @dumper: registered kmsg dumper | 2893 | * @dumper: registered kmsg dumper |
2893 | * @syslog: include the "<4>" prefixes | 2894 | * @syslog: include the "<4>" prefixes |
2894 | * @buf: buffer to copy the line to | 2895 | * @buf: buffer to copy the line to |
2895 | * @size: maximum size of the buffer | 2896 | * @size: maximum size of the buffer |
2896 | * @len: length of line placed into buffer | 2897 | * @len: length of line placed into buffer |
2897 | * | 2898 | * |
2898 | * Start at the end of the kmsg buffer and fill the provided buffer | 2899 | * Start at the end of the kmsg buffer and fill the provided buffer |
2899 | * with as many of the the *youngest* kmsg records that fit into it. | 2900 | * with as many of the the *youngest* kmsg records that fit into it. |
2900 | * If the buffer is large enough, all available kmsg records will be | 2901 | * If the buffer is large enough, all available kmsg records will be |
2901 | * copied with a single call. | 2902 | * copied with a single call. |
2902 | * | 2903 | * |
2903 | * Consecutive calls will fill the buffer with the next block of | 2904 | * Consecutive calls will fill the buffer with the next block of |
2904 | * available older records, not including the earlier retrieved ones. | 2905 | * available older records, not including the earlier retrieved ones. |
2905 | * | 2906 | * |
2906 | * A return value of FALSE indicates that there are no more records to | 2907 | * A return value of FALSE indicates that there are no more records to |
2907 | * read. | 2908 | * read. |
2908 | */ | 2909 | */ |
2909 | bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, | 2910 | bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, |
2910 | char *buf, size_t size, size_t *len) | 2911 | char *buf, size_t size, size_t *len) |
2911 | { | 2912 | { |
2912 | unsigned long flags; | 2913 | unsigned long flags; |
2913 | u64 seq; | 2914 | u64 seq; |
2914 | u32 idx; | 2915 | u32 idx; |
2915 | u64 next_seq; | 2916 | u64 next_seq; |
2916 | u32 next_idx; | 2917 | u32 next_idx; |
2917 | enum log_flags prev; | 2918 | enum log_flags prev; |
2918 | size_t l = 0; | 2919 | size_t l = 0; |
2919 | bool ret = false; | 2920 | bool ret = false; |
2920 | 2921 | ||
2921 | if (!dumper->active) | 2922 | if (!dumper->active) |
2922 | goto out; | 2923 | goto out; |
2923 | 2924 | ||
2924 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2925 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
2925 | if (dumper->cur_seq < log_first_seq) { | 2926 | if (dumper->cur_seq < log_first_seq) { |
2926 | /* messages are gone, move to first available one */ | 2927 | /* messages are gone, move to first available one */ |
2927 | dumper->cur_seq = log_first_seq; | 2928 | dumper->cur_seq = log_first_seq; |
2928 | dumper->cur_idx = log_first_idx; | 2929 | dumper->cur_idx = log_first_idx; |
2929 | } | 2930 | } |
2930 | 2931 | ||
2931 | /* last entry */ | 2932 | /* last entry */ |
2932 | if (dumper->cur_seq >= dumper->next_seq) { | 2933 | if (dumper->cur_seq >= dumper->next_seq) { |
2933 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2934 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
2934 | goto out; | 2935 | goto out; |
2935 | } | 2936 | } |
2936 | 2937 | ||
2937 | /* calculate length of entire buffer */ | 2938 | /* calculate length of entire buffer */ |
2938 | seq = dumper->cur_seq; | 2939 | seq = dumper->cur_seq; |
2939 | idx = dumper->cur_idx; | 2940 | idx = dumper->cur_idx; |
2940 | prev = 0; | 2941 | prev = 0; |
2941 | while (seq < dumper->next_seq) { | 2942 | while (seq < dumper->next_seq) { |
2942 | struct printk_log *msg = log_from_idx(idx); | 2943 | struct printk_log *msg = log_from_idx(idx); |
2943 | 2944 | ||
2944 | l += msg_print_text(msg, prev, true, NULL, 0); | 2945 | l += msg_print_text(msg, prev, true, NULL, 0); |
2945 | idx = log_next(idx); | 2946 | idx = log_next(idx); |
2946 | seq++; | 2947 | seq++; |
2947 | prev = msg->flags; | 2948 | prev = msg->flags; |
2948 | } | 2949 | } |
2949 | 2950 | ||
2950 | /* move first record forward until length fits into the buffer */ | 2951 | /* move first record forward until length fits into the buffer */ |
2951 | seq = dumper->cur_seq; | 2952 | seq = dumper->cur_seq; |
2952 | idx = dumper->cur_idx; | 2953 | idx = dumper->cur_idx; |
2953 | prev = 0; | 2954 | prev = 0; |
2954 | while (l > size && seq < dumper->next_seq) { | 2955 | while (l > size && seq < dumper->next_seq) { |
2955 | struct printk_log *msg = log_from_idx(idx); | 2956 | struct printk_log *msg = log_from_idx(idx); |
2956 | 2957 | ||
2957 | l -= msg_print_text(msg, prev, true, NULL, 0); | 2958 | l -= msg_print_text(msg, prev, true, NULL, 0); |
2958 | idx = log_next(idx); | 2959 | idx = log_next(idx); |
2959 | seq++; | 2960 | seq++; |
2960 | prev = msg->flags; | 2961 | prev = msg->flags; |
2961 | } | 2962 | } |
2962 | 2963 | ||
2963 | /* last message in next interation */ | 2964 | /* last message in next interation */ |
2964 | next_seq = seq; | 2965 | next_seq = seq; |
2965 | next_idx = idx; | 2966 | next_idx = idx; |
2966 | 2967 | ||
2967 | l = 0; | 2968 | l = 0; |
2968 | while (seq < dumper->next_seq) { | 2969 | while (seq < dumper->next_seq) { |
2969 | struct printk_log *msg = log_from_idx(idx); | 2970 | struct printk_log *msg = log_from_idx(idx); |
2970 | 2971 | ||
2971 | l += msg_print_text(msg, prev, syslog, buf + l, size - l); | 2972 | l += msg_print_text(msg, prev, syslog, buf + l, size - l); |
2972 | idx = log_next(idx); | 2973 | idx = log_next(idx); |
2973 | seq++; | 2974 | seq++; |
2974 | prev = msg->flags; | 2975 | prev = msg->flags; |
2975 | } | 2976 | } |
2976 | 2977 | ||
2977 | dumper->next_seq = next_seq; | 2978 | dumper->next_seq = next_seq; |
2978 | dumper->next_idx = next_idx; | 2979 | dumper->next_idx = next_idx; |
2979 | ret = true; | 2980 | ret = true; |
2980 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2981 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
2981 | out: | 2982 | out: |
2982 | if (len) | 2983 | if (len) |
2983 | *len = l; | 2984 | *len = l; |
2984 | return ret; | 2985 | return ret; |
2985 | } | 2986 | } |
2986 | EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer); | 2987 | EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer); |
2987 | 2988 | ||
2988 | /** | 2989 | /** |
2989 | * kmsg_dump_rewind_nolock - reset the interator (unlocked version) | 2990 | * kmsg_dump_rewind_nolock - reset the interator (unlocked version) |
2990 | * @dumper: registered kmsg dumper | 2991 | * @dumper: registered kmsg dumper |
2991 | * | 2992 | * |
2992 | * Reset the dumper's iterator so that kmsg_dump_get_line() and | 2993 | * Reset the dumper's iterator so that kmsg_dump_get_line() and |
2993 | * kmsg_dump_get_buffer() can be called again and used multiple | 2994 | * kmsg_dump_get_buffer() can be called again and used multiple |
2994 | * times within the same dumper.dump() callback. | 2995 | * times within the same dumper.dump() callback. |
2995 | * | 2996 | * |
2996 | * The function is similar to kmsg_dump_rewind(), but grabs no locks. | 2997 | * The function is similar to kmsg_dump_rewind(), but grabs no locks. |
2997 | */ | 2998 | */ |
2998 | void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper) | 2999 | void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper) |
2999 | { | 3000 | { |
3000 | dumper->cur_seq = clear_seq; | 3001 | dumper->cur_seq = clear_seq; |
3001 | dumper->cur_idx = clear_idx; | 3002 | dumper->cur_idx = clear_idx; |
3002 | dumper->next_seq = log_next_seq; | 3003 | dumper->next_seq = log_next_seq; |
3003 | dumper->next_idx = log_next_idx; | 3004 | dumper->next_idx = log_next_idx; |
3004 | } | 3005 | } |
3005 | 3006 | ||
3006 | /** | 3007 | /** |
3007 | * kmsg_dump_rewind - reset the interator | 3008 | * kmsg_dump_rewind - reset the interator |
3008 | * @dumper: registered kmsg dumper | 3009 | * @dumper: registered kmsg dumper |
3009 | * | 3010 | * |
3010 | * Reset the dumper's iterator so that kmsg_dump_get_line() and | 3011 | * Reset the dumper's iterator so that kmsg_dump_get_line() and |
3011 | * kmsg_dump_get_buffer() can be called again and used multiple | 3012 | * kmsg_dump_get_buffer() can be called again and used multiple |
3012 | * times within the same dumper.dump() callback. | 3013 | * times within the same dumper.dump() callback. |
3013 | */ | 3014 | */ |
3014 | void kmsg_dump_rewind(struct kmsg_dumper *dumper) | 3015 | void kmsg_dump_rewind(struct kmsg_dumper *dumper) |
3015 | { | 3016 | { |
3016 | unsigned long flags; | 3017 | unsigned long flags; |
3017 | 3018 | ||
3018 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 3019 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
3019 | kmsg_dump_rewind_nolock(dumper); | 3020 | kmsg_dump_rewind_nolock(dumper); |
3020 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 3021 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
3021 | } | 3022 | } |
3022 | EXPORT_SYMBOL_GPL(kmsg_dump_rewind); | 3023 | EXPORT_SYMBOL_GPL(kmsg_dump_rewind); |
3023 | 3024 | ||
3024 | static char dump_stack_arch_desc_str[128]; | 3025 | static char dump_stack_arch_desc_str[128]; |
3025 | 3026 | ||
3026 | /** | 3027 | /** |
3027 | * dump_stack_set_arch_desc - set arch-specific str to show with task dumps | 3028 | * dump_stack_set_arch_desc - set arch-specific str to show with task dumps |
3028 | * @fmt: printf-style format string | 3029 | * @fmt: printf-style format string |
3029 | * @...: arguments for the format string | 3030 | * @...: arguments for the format string |
3030 | * | 3031 | * |
3031 | * The configured string will be printed right after utsname during task | 3032 | * The configured string will be printed right after utsname during task |
3032 | * dumps. Usually used to add arch-specific system identifiers. If an | 3033 | * dumps. Usually used to add arch-specific system identifiers. If an |
3033 | * arch wants to make use of such an ID string, it should initialize this | 3034 | * arch wants to make use of such an ID string, it should initialize this |
3034 | * as soon as possible during boot. | 3035 | * as soon as possible during boot. |
3035 | */ | 3036 | */ |
3036 | void __init dump_stack_set_arch_desc(const char *fmt, ...) | 3037 | void __init dump_stack_set_arch_desc(const char *fmt, ...) |
3037 | { | 3038 | { |
3038 | va_list args; | 3039 | va_list args; |
3039 | 3040 | ||
3040 | va_start(args, fmt); | 3041 | va_start(args, fmt); |
3041 | vsnprintf(dump_stack_arch_desc_str, sizeof(dump_stack_arch_desc_str), | 3042 | vsnprintf(dump_stack_arch_desc_str, sizeof(dump_stack_arch_desc_str), |
3042 | fmt, args); | 3043 | fmt, args); |
3043 | va_end(args); | 3044 | va_end(args); |
3044 | } | 3045 | } |
3045 | 3046 | ||
3046 | /** | 3047 | /** |
3047 | * dump_stack_print_info - print generic debug info for dump_stack() | 3048 | * dump_stack_print_info - print generic debug info for dump_stack() |
3048 | * @log_lvl: log level | 3049 | * @log_lvl: log level |
3049 | * | 3050 | * |
3050 | * Arch-specific dump_stack() implementations can use this function to | 3051 | * Arch-specific dump_stack() implementations can use this function to |
3051 | * print out the same debug information as the generic dump_stack(). | 3052 | * print out the same debug information as the generic dump_stack(). |
3052 | */ | 3053 | */ |
3053 | void dump_stack_print_info(const char *log_lvl) | 3054 | void dump_stack_print_info(const char *log_lvl) |
3054 | { | 3055 | { |
3055 | printk("%sCPU: %d PID: %d Comm: %.20s %s %s %.*s\n", | 3056 | printk("%sCPU: %d PID: %d Comm: %.20s %s %s %.*s\n", |
3056 | log_lvl, raw_smp_processor_id(), current->pid, current->comm, | 3057 | log_lvl, raw_smp_processor_id(), current->pid, current->comm, |
3057 | print_tainted(), init_utsname()->release, | 3058 | print_tainted(), init_utsname()->release, |
3058 | (int)strcspn(init_utsname()->version, " "), | 3059 | (int)strcspn(init_utsname()->version, " "), |
3059 | init_utsname()->version); | 3060 | init_utsname()->version); |
3060 | 3061 | ||
3061 | if (dump_stack_arch_desc_str[0] != '\0') | 3062 | if (dump_stack_arch_desc_str[0] != '\0') |
3062 | printk("%sHardware name: %s\n", | 3063 | printk("%sHardware name: %s\n", |
3063 | log_lvl, dump_stack_arch_desc_str); | 3064 | log_lvl, dump_stack_arch_desc_str); |
3064 | 3065 | ||
3065 | print_worker_info(log_lvl, current); | 3066 | print_worker_info(log_lvl, current); |
3066 | } | 3067 | } |
3067 | 3068 | ||
3068 | /** | 3069 | /** |
3069 | * show_regs_print_info - print generic debug info for show_regs() | 3070 | * show_regs_print_info - print generic debug info for show_regs() |
3070 | * @log_lvl: log level | 3071 | * @log_lvl: log level |
3071 | * | 3072 | * |
3072 | * show_regs() implementations can use this function to print out generic | 3073 | * show_regs() implementations can use this function to print out generic |
3073 | * debug information. | 3074 | * debug information. |
3074 | */ | 3075 | */ |
3075 | void show_regs_print_info(const char *log_lvl) | 3076 | void show_regs_print_info(const char *log_lvl) |
3076 | { | 3077 | { |
3077 | dump_stack_print_info(log_lvl); | 3078 | dump_stack_print_info(log_lvl); |
3078 | 3079 | ||
3079 | printk("%stask: %p ti: %p task.ti: %p\n", | 3080 | printk("%stask: %p ti: %p task.ti: %p\n", |
3080 | log_lvl, current, current_thread_info(), | 3081 | log_lvl, current, current_thread_info(), |
3081 | task_thread_info(current)); | 3082 | task_thread_info(current)); |
3082 | } | 3083 | } |
3083 | 3084 | ||
3084 | #endif | 3085 | #endif |
3085 | 3086 |
net/irda/ircomm/ircomm_tty.c
1 | /********************************************************************* | 1 | /********************************************************************* |
2 | * | 2 | * |
3 | * Filename: ircomm_tty.c | 3 | * Filename: ircomm_tty.c |
4 | * Version: 1.0 | 4 | * Version: 1.0 |
5 | * Description: IrCOMM serial TTY driver | 5 | * Description: IrCOMM serial TTY driver |
6 | * Status: Experimental. | 6 | * Status: Experimental. |
7 | * Author: Dag Brattli <dagb@cs.uit.no> | 7 | * Author: Dag Brattli <dagb@cs.uit.no> |
8 | * Created at: Sun Jun 6 21:00:56 1999 | 8 | * Created at: Sun Jun 6 21:00:56 1999 |
9 | * Modified at: Wed Feb 23 00:09:02 2000 | 9 | * Modified at: Wed Feb 23 00:09:02 2000 |
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | 10 | * Modified by: Dag Brattli <dagb@cs.uit.no> |
11 | * Sources: serial.c and previous IrCOMM work by Takahide Higuchi | 11 | * Sources: serial.c and previous IrCOMM work by Takahide Higuchi |
12 | * | 12 | * |
13 | * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. | 13 | * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. |
14 | * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com> | 14 | * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com> |
15 | * | 15 | * |
16 | * This program is free software; you can redistribute it and/or | 16 | * This program is free software; you can redistribute it and/or |
17 | * modify it under the terms of the GNU General Public License as | 17 | * modify it under the terms of the GNU General Public License as |
18 | * published by the Free Software Foundation; either version 2 of | 18 | * published by the Free Software Foundation; either version 2 of |
19 | * the License, or (at your option) any later version. | 19 | * the License, or (at your option) any later version. |
20 | * | 20 | * |
21 | * This program is distributed in the hope that it will be useful, | 21 | * This program is distributed in the hope that it will be useful, |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
24 | * GNU General Public License for more details. | 24 | * GNU General Public License for more details. |
25 | * | 25 | * |
26 | * You should have received a copy of the GNU General Public License | 26 | * You should have received a copy of the GNU General Public License |
27 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | 27 | * along with this program; if not, see <http://www.gnu.org/licenses/>. |
28 | * | 28 | * |
29 | ********************************************************************/ | 29 | ********************************************************************/ |
30 | 30 | ||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/fs.h> | 33 | #include <linux/fs.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/seq_file.h> | 36 | #include <linux/seq_file.h> |
37 | #include <linux/termios.h> | 37 | #include <linux/termios.h> |
38 | #include <linux/tty.h> | 38 | #include <linux/tty.h> |
39 | #include <linux/tty_flip.h> | 39 | #include <linux/tty_flip.h> |
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <linux/device.h> /* for MODULE_ALIAS_CHARDEV_MAJOR */ | 41 | #include <linux/device.h> /* for MODULE_ALIAS_CHARDEV_MAJOR */ |
42 | 42 | ||
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | 44 | ||
45 | #include <net/irda/irda.h> | 45 | #include <net/irda/irda.h> |
46 | #include <net/irda/irmod.h> | 46 | #include <net/irda/irmod.h> |
47 | 47 | ||
48 | #include <net/irda/ircomm_core.h> | 48 | #include <net/irda/ircomm_core.h> |
49 | #include <net/irda/ircomm_param.h> | 49 | #include <net/irda/ircomm_param.h> |
50 | #include <net/irda/ircomm_tty_attach.h> | 50 | #include <net/irda/ircomm_tty_attach.h> |
51 | #include <net/irda/ircomm_tty.h> | 51 | #include <net/irda/ircomm_tty.h> |
52 | 52 | ||
53 | static int ircomm_tty_install(struct tty_driver *driver, | 53 | static int ircomm_tty_install(struct tty_driver *driver, |
54 | struct tty_struct *tty); | 54 | struct tty_struct *tty); |
55 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp); | 55 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp); |
56 | static void ircomm_tty_close(struct tty_struct * tty, struct file *filp); | 56 | static void ircomm_tty_close(struct tty_struct * tty, struct file *filp); |
57 | static int ircomm_tty_write(struct tty_struct * tty, | 57 | static int ircomm_tty_write(struct tty_struct * tty, |
58 | const unsigned char *buf, int count); | 58 | const unsigned char *buf, int count); |
59 | static int ircomm_tty_write_room(struct tty_struct *tty); | 59 | static int ircomm_tty_write_room(struct tty_struct *tty); |
60 | static void ircomm_tty_throttle(struct tty_struct *tty); | 60 | static void ircomm_tty_throttle(struct tty_struct *tty); |
61 | static void ircomm_tty_unthrottle(struct tty_struct *tty); | 61 | static void ircomm_tty_unthrottle(struct tty_struct *tty); |
62 | static int ircomm_tty_chars_in_buffer(struct tty_struct *tty); | 62 | static int ircomm_tty_chars_in_buffer(struct tty_struct *tty); |
63 | static void ircomm_tty_flush_buffer(struct tty_struct *tty); | 63 | static void ircomm_tty_flush_buffer(struct tty_struct *tty); |
64 | static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch); | 64 | static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch); |
65 | static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout); | 65 | static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout); |
66 | static void ircomm_tty_hangup(struct tty_struct *tty); | 66 | static void ircomm_tty_hangup(struct tty_struct *tty); |
67 | static void ircomm_tty_do_softint(struct work_struct *work); | 67 | static void ircomm_tty_do_softint(struct work_struct *work); |
68 | static void ircomm_tty_shutdown(struct ircomm_tty_cb *self); | 68 | static void ircomm_tty_shutdown(struct ircomm_tty_cb *self); |
69 | static void ircomm_tty_stop(struct tty_struct *tty); | 69 | static void ircomm_tty_stop(struct tty_struct *tty); |
70 | 70 | ||
71 | static int ircomm_tty_data_indication(void *instance, void *sap, | 71 | static int ircomm_tty_data_indication(void *instance, void *sap, |
72 | struct sk_buff *skb); | 72 | struct sk_buff *skb); |
73 | static int ircomm_tty_control_indication(void *instance, void *sap, | 73 | static int ircomm_tty_control_indication(void *instance, void *sap, |
74 | struct sk_buff *skb); | 74 | struct sk_buff *skb); |
75 | static void ircomm_tty_flow_indication(void *instance, void *sap, | 75 | static void ircomm_tty_flow_indication(void *instance, void *sap, |
76 | LOCAL_FLOW cmd); | 76 | LOCAL_FLOW cmd); |
77 | #ifdef CONFIG_PROC_FS | 77 | #ifdef CONFIG_PROC_FS |
78 | static const struct file_operations ircomm_tty_proc_fops; | 78 | static const struct file_operations ircomm_tty_proc_fops; |
79 | #endif /* CONFIG_PROC_FS */ | 79 | #endif /* CONFIG_PROC_FS */ |
80 | static struct tty_driver *driver; | 80 | static struct tty_driver *driver; |
81 | 81 | ||
82 | static hashbin_t *ircomm_tty = NULL; | 82 | static hashbin_t *ircomm_tty = NULL; |
83 | 83 | ||
84 | static const struct tty_operations ops = { | 84 | static const struct tty_operations ops = { |
85 | .install = ircomm_tty_install, | 85 | .install = ircomm_tty_install, |
86 | .open = ircomm_tty_open, | 86 | .open = ircomm_tty_open, |
87 | .close = ircomm_tty_close, | 87 | .close = ircomm_tty_close, |
88 | .write = ircomm_tty_write, | 88 | .write = ircomm_tty_write, |
89 | .write_room = ircomm_tty_write_room, | 89 | .write_room = ircomm_tty_write_room, |
90 | .chars_in_buffer = ircomm_tty_chars_in_buffer, | 90 | .chars_in_buffer = ircomm_tty_chars_in_buffer, |
91 | .flush_buffer = ircomm_tty_flush_buffer, | 91 | .flush_buffer = ircomm_tty_flush_buffer, |
92 | .ioctl = ircomm_tty_ioctl, /* ircomm_tty_ioctl.c */ | 92 | .ioctl = ircomm_tty_ioctl, /* ircomm_tty_ioctl.c */ |
93 | .tiocmget = ircomm_tty_tiocmget, /* ircomm_tty_ioctl.c */ | 93 | .tiocmget = ircomm_tty_tiocmget, /* ircomm_tty_ioctl.c */ |
94 | .tiocmset = ircomm_tty_tiocmset, /* ircomm_tty_ioctl.c */ | 94 | .tiocmset = ircomm_tty_tiocmset, /* ircomm_tty_ioctl.c */ |
95 | .throttle = ircomm_tty_throttle, | 95 | .throttle = ircomm_tty_throttle, |
96 | .unthrottle = ircomm_tty_unthrottle, | 96 | .unthrottle = ircomm_tty_unthrottle, |
97 | .send_xchar = ircomm_tty_send_xchar, | 97 | .send_xchar = ircomm_tty_send_xchar, |
98 | .set_termios = ircomm_tty_set_termios, | 98 | .set_termios = ircomm_tty_set_termios, |
99 | .stop = ircomm_tty_stop, | 99 | .stop = ircomm_tty_stop, |
100 | .start = ircomm_tty_start, | 100 | .start = ircomm_tty_start, |
101 | .hangup = ircomm_tty_hangup, | 101 | .hangup = ircomm_tty_hangup, |
102 | .wait_until_sent = ircomm_tty_wait_until_sent, | 102 | .wait_until_sent = ircomm_tty_wait_until_sent, |
103 | #ifdef CONFIG_PROC_FS | 103 | #ifdef CONFIG_PROC_FS |
104 | .proc_fops = &ircomm_tty_proc_fops, | 104 | .proc_fops = &ircomm_tty_proc_fops, |
105 | #endif /* CONFIG_PROC_FS */ | 105 | #endif /* CONFIG_PROC_FS */ |
106 | }; | 106 | }; |
107 | 107 | ||
108 | static void ircomm_port_raise_dtr_rts(struct tty_port *port, int raise) | 108 | static void ircomm_port_raise_dtr_rts(struct tty_port *port, int raise) |
109 | { | 109 | { |
110 | struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb, | 110 | struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb, |
111 | port); | 111 | port); |
112 | /* | 112 | /* |
113 | * Here, we use to lock those two guys, but as ircomm_param_request() | 113 | * Here, we use to lock those two guys, but as ircomm_param_request() |
114 | * does it itself, I don't see the point (and I see the deadlock). | 114 | * does it itself, I don't see the point (and I see the deadlock). |
115 | * Jean II | 115 | * Jean II |
116 | */ | 116 | */ |
117 | if (raise) | 117 | if (raise) |
118 | self->settings.dte |= IRCOMM_RTS | IRCOMM_DTR; | 118 | self->settings.dte |= IRCOMM_RTS | IRCOMM_DTR; |
119 | else | 119 | else |
120 | self->settings.dte &= ~(IRCOMM_RTS | IRCOMM_DTR); | 120 | self->settings.dte &= ~(IRCOMM_RTS | IRCOMM_DTR); |
121 | 121 | ||
122 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | 122 | ircomm_param_request(self, IRCOMM_DTE, TRUE); |
123 | } | 123 | } |
124 | 124 | ||
125 | static int ircomm_port_carrier_raised(struct tty_port *port) | 125 | static int ircomm_port_carrier_raised(struct tty_port *port) |
126 | { | 126 | { |
127 | struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb, | 127 | struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb, |
128 | port); | 128 | port); |
129 | return self->settings.dce & IRCOMM_CD; | 129 | return self->settings.dce & IRCOMM_CD; |
130 | } | 130 | } |
131 | 131 | ||
132 | static const struct tty_port_operations ircomm_port_ops = { | 132 | static const struct tty_port_operations ircomm_port_ops = { |
133 | .dtr_rts = ircomm_port_raise_dtr_rts, | 133 | .dtr_rts = ircomm_port_raise_dtr_rts, |
134 | .carrier_raised = ircomm_port_carrier_raised, | 134 | .carrier_raised = ircomm_port_carrier_raised, |
135 | }; | 135 | }; |
136 | 136 | ||
137 | /* | 137 | /* |
138 | * Function ircomm_tty_init() | 138 | * Function ircomm_tty_init() |
139 | * | 139 | * |
140 | * Init IrCOMM TTY layer/driver | 140 | * Init IrCOMM TTY layer/driver |
141 | * | 141 | * |
142 | */ | 142 | */ |
143 | static int __init ircomm_tty_init(void) | 143 | static int __init ircomm_tty_init(void) |
144 | { | 144 | { |
145 | driver = alloc_tty_driver(IRCOMM_TTY_PORTS); | 145 | driver = alloc_tty_driver(IRCOMM_TTY_PORTS); |
146 | if (!driver) | 146 | if (!driver) |
147 | return -ENOMEM; | 147 | return -ENOMEM; |
148 | ircomm_tty = hashbin_new(HB_LOCK); | 148 | ircomm_tty = hashbin_new(HB_LOCK); |
149 | if (ircomm_tty == NULL) { | 149 | if (ircomm_tty == NULL) { |
150 | net_err_ratelimited("%s(), can't allocate hashbin!\n", | 150 | net_err_ratelimited("%s(), can't allocate hashbin!\n", |
151 | __func__); | 151 | __func__); |
152 | put_tty_driver(driver); | 152 | put_tty_driver(driver); |
153 | return -ENOMEM; | 153 | return -ENOMEM; |
154 | } | 154 | } |
155 | 155 | ||
156 | driver->driver_name = "ircomm"; | 156 | driver->driver_name = "ircomm"; |
157 | driver->name = "ircomm"; | 157 | driver->name = "ircomm"; |
158 | driver->major = IRCOMM_TTY_MAJOR; | 158 | driver->major = IRCOMM_TTY_MAJOR; |
159 | driver->minor_start = IRCOMM_TTY_MINOR; | 159 | driver->minor_start = IRCOMM_TTY_MINOR; |
160 | driver->type = TTY_DRIVER_TYPE_SERIAL; | 160 | driver->type = TTY_DRIVER_TYPE_SERIAL; |
161 | driver->subtype = SERIAL_TYPE_NORMAL; | 161 | driver->subtype = SERIAL_TYPE_NORMAL; |
162 | driver->init_termios = tty_std_termios; | 162 | driver->init_termios = tty_std_termios; |
163 | driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 163 | driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
164 | driver->flags = TTY_DRIVER_REAL_RAW; | 164 | driver->flags = TTY_DRIVER_REAL_RAW; |
165 | tty_set_operations(driver, &ops); | 165 | tty_set_operations(driver, &ops); |
166 | if (tty_register_driver(driver)) { | 166 | if (tty_register_driver(driver)) { |
167 | net_err_ratelimited("%s(): Couldn't register serial driver\n", | 167 | net_err_ratelimited("%s(): Couldn't register serial driver\n", |
168 | __func__); | 168 | __func__); |
169 | put_tty_driver(driver); | 169 | put_tty_driver(driver); |
170 | return -1; | 170 | return -1; |
171 | } | 171 | } |
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
174 | 174 | ||
175 | static void __exit __ircomm_tty_cleanup(struct ircomm_tty_cb *self) | 175 | static void __exit __ircomm_tty_cleanup(struct ircomm_tty_cb *self) |
176 | { | 176 | { |
177 | IRDA_ASSERT(self != NULL, return;); | 177 | IRDA_ASSERT(self != NULL, return;); |
178 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 178 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
179 | 179 | ||
180 | ircomm_tty_shutdown(self); | 180 | ircomm_tty_shutdown(self); |
181 | 181 | ||
182 | self->magic = 0; | 182 | self->magic = 0; |
183 | tty_port_destroy(&self->port); | 183 | tty_port_destroy(&self->port); |
184 | kfree(self); | 184 | kfree(self); |
185 | } | 185 | } |
186 | 186 | ||
187 | /* | 187 | /* |
188 | * Function ircomm_tty_cleanup () | 188 | * Function ircomm_tty_cleanup () |
189 | * | 189 | * |
190 | * Remove IrCOMM TTY layer/driver | 190 | * Remove IrCOMM TTY layer/driver |
191 | * | 191 | * |
192 | */ | 192 | */ |
193 | static void __exit ircomm_tty_cleanup(void) | 193 | static void __exit ircomm_tty_cleanup(void) |
194 | { | 194 | { |
195 | int ret; | 195 | int ret; |
196 | 196 | ||
197 | ret = tty_unregister_driver(driver); | 197 | ret = tty_unregister_driver(driver); |
198 | if (ret) { | 198 | if (ret) { |
199 | net_err_ratelimited("%s(), failed to unregister driver\n", | 199 | net_err_ratelimited("%s(), failed to unregister driver\n", |
200 | __func__); | 200 | __func__); |
201 | return; | 201 | return; |
202 | } | 202 | } |
203 | 203 | ||
204 | hashbin_delete(ircomm_tty, (FREE_FUNC) __ircomm_tty_cleanup); | 204 | hashbin_delete(ircomm_tty, (FREE_FUNC) __ircomm_tty_cleanup); |
205 | put_tty_driver(driver); | 205 | put_tty_driver(driver); |
206 | } | 206 | } |
207 | 207 | ||
208 | /* | 208 | /* |
209 | * Function ircomm_startup (self) | 209 | * Function ircomm_startup (self) |
210 | * | 210 | * |
211 | * | 211 | * |
212 | * | 212 | * |
213 | */ | 213 | */ |
214 | static int ircomm_tty_startup(struct ircomm_tty_cb *self) | 214 | static int ircomm_tty_startup(struct ircomm_tty_cb *self) |
215 | { | 215 | { |
216 | notify_t notify; | 216 | notify_t notify; |
217 | int ret = -ENODEV; | 217 | int ret = -ENODEV; |
218 | 218 | ||
219 | IRDA_ASSERT(self != NULL, return -1;); | 219 | IRDA_ASSERT(self != NULL, return -1;); |
220 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 220 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
221 | 221 | ||
222 | /* Check if already open */ | 222 | /* Check if already open */ |
223 | if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) { | 223 | if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) { |
224 | pr_debug("%s(), already open so break out!\n", __func__); | 224 | pr_debug("%s(), already open so break out!\n", __func__); |
225 | return 0; | 225 | return 0; |
226 | } | 226 | } |
227 | 227 | ||
228 | /* Register with IrCOMM */ | 228 | /* Register with IrCOMM */ |
229 | irda_notify_init(¬ify); | 229 | irda_notify_init(¬ify); |
230 | /* These callbacks we must handle ourselves */ | 230 | /* These callbacks we must handle ourselves */ |
231 | notify.data_indication = ircomm_tty_data_indication; | 231 | notify.data_indication = ircomm_tty_data_indication; |
232 | notify.udata_indication = ircomm_tty_control_indication; | 232 | notify.udata_indication = ircomm_tty_control_indication; |
233 | notify.flow_indication = ircomm_tty_flow_indication; | 233 | notify.flow_indication = ircomm_tty_flow_indication; |
234 | 234 | ||
235 | /* Use the ircomm_tty interface for these ones */ | 235 | /* Use the ircomm_tty interface for these ones */ |
236 | notify.disconnect_indication = ircomm_tty_disconnect_indication; | 236 | notify.disconnect_indication = ircomm_tty_disconnect_indication; |
237 | notify.connect_confirm = ircomm_tty_connect_confirm; | 237 | notify.connect_confirm = ircomm_tty_connect_confirm; |
238 | notify.connect_indication = ircomm_tty_connect_indication; | 238 | notify.connect_indication = ircomm_tty_connect_indication; |
239 | strlcpy(notify.name, "ircomm_tty", sizeof(notify.name)); | 239 | strlcpy(notify.name, "ircomm_tty", sizeof(notify.name)); |
240 | notify.instance = self; | 240 | notify.instance = self; |
241 | 241 | ||
242 | if (!self->ircomm) { | 242 | if (!self->ircomm) { |
243 | self->ircomm = ircomm_open(¬ify, self->service_type, | 243 | self->ircomm = ircomm_open(¬ify, self->service_type, |
244 | self->line); | 244 | self->line); |
245 | } | 245 | } |
246 | if (!self->ircomm) | 246 | if (!self->ircomm) |
247 | goto err; | 247 | goto err; |
248 | 248 | ||
249 | self->slsap_sel = self->ircomm->slsap_sel; | 249 | self->slsap_sel = self->ircomm->slsap_sel; |
250 | 250 | ||
251 | /* Connect IrCOMM link with remote device */ | 251 | /* Connect IrCOMM link with remote device */ |
252 | ret = ircomm_tty_attach_cable(self); | 252 | ret = ircomm_tty_attach_cable(self); |
253 | if (ret < 0) { | 253 | if (ret < 0) { |
254 | net_err_ratelimited("%s(), error attaching cable!\n", __func__); | 254 | net_err_ratelimited("%s(), error attaching cable!\n", __func__); |
255 | goto err; | 255 | goto err; |
256 | } | 256 | } |
257 | 257 | ||
258 | return 0; | 258 | return 0; |
259 | err: | 259 | err: |
260 | clear_bit(ASYNCB_INITIALIZED, &self->port.flags); | 260 | clear_bit(ASYNCB_INITIALIZED, &self->port.flags); |
261 | return ret; | 261 | return ret; |
262 | } | 262 | } |
263 | 263 | ||
264 | /* | 264 | /* |
265 | * Function ircomm_block_til_ready (self, filp) | 265 | * Function ircomm_block_til_ready (self, filp) |
266 | * | 266 | * |
267 | * | 267 | * |
268 | * | 268 | * |
269 | */ | 269 | */ |
270 | static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | 270 | static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, |
271 | struct tty_struct *tty, struct file *filp) | 271 | struct tty_struct *tty, struct file *filp) |
272 | { | 272 | { |
273 | struct tty_port *port = &self->port; | 273 | struct tty_port *port = &self->port; |
274 | DECLARE_WAITQUEUE(wait, current); | 274 | DECLARE_WAITQUEUE(wait, current); |
275 | int retval; | 275 | int retval; |
276 | int do_clocal = 0; | 276 | int do_clocal = 0; |
277 | unsigned long flags; | 277 | unsigned long flags; |
278 | 278 | ||
279 | /* | 279 | /* |
280 | * If non-blocking mode is set, or the port is not enabled, | 280 | * If non-blocking mode is set, or the port is not enabled, |
281 | * then make the check up front and then exit. | 281 | * then make the check up front and then exit. |
282 | */ | 282 | */ |
283 | if (test_bit(TTY_IO_ERROR, &tty->flags)) { | 283 | if (test_bit(TTY_IO_ERROR, &tty->flags)) { |
284 | port->flags |= ASYNC_NORMAL_ACTIVE; | 284 | port->flags |= ASYNC_NORMAL_ACTIVE; |
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
287 | 287 | ||
288 | if (filp->f_flags & O_NONBLOCK) { | 288 | if (filp->f_flags & O_NONBLOCK) { |
289 | /* nonblock mode is set */ | 289 | /* nonblock mode is set */ |
290 | if (tty->termios.c_cflag & CBAUD) | 290 | if (tty->termios.c_cflag & CBAUD) |
291 | tty_port_raise_dtr_rts(port); | 291 | tty_port_raise_dtr_rts(port); |
292 | port->flags |= ASYNC_NORMAL_ACTIVE; | 292 | port->flags |= ASYNC_NORMAL_ACTIVE; |
293 | pr_debug("%s(), O_NONBLOCK requested!\n", __func__); | 293 | pr_debug("%s(), O_NONBLOCK requested!\n", __func__); |
294 | return 0; | 294 | return 0; |
295 | } | 295 | } |
296 | 296 | ||
297 | if (tty->termios.c_cflag & CLOCAL) { | 297 | if (tty->termios.c_cflag & CLOCAL) { |
298 | pr_debug("%s(), doing CLOCAL!\n", __func__); | 298 | pr_debug("%s(), doing CLOCAL!\n", __func__); |
299 | do_clocal = 1; | 299 | do_clocal = 1; |
300 | } | 300 | } |
301 | 301 | ||
302 | /* Wait for carrier detect and the line to become | 302 | /* Wait for carrier detect and the line to become |
303 | * free (i.e., not in use by the callout). While we are in | 303 | * free (i.e., not in use by the callout). While we are in |
304 | * this loop, port->count is dropped by one, so that | 304 | * this loop, port->count is dropped by one, so that |
305 | * mgsl_close() knows when to free things. We restore it upon | 305 | * mgsl_close() knows when to free things. We restore it upon |
306 | * exit, either normal or abnormal. | 306 | * exit, either normal or abnormal. |
307 | */ | 307 | */ |
308 | 308 | ||
309 | retval = 0; | 309 | retval = 0; |
310 | add_wait_queue(&port->open_wait, &wait); | 310 | add_wait_queue(&port->open_wait, &wait); |
311 | 311 | ||
312 | pr_debug("%s(%d):block_til_ready before block on %s open_count=%d\n", | 312 | pr_debug("%s(%d):block_til_ready before block on %s open_count=%d\n", |
313 | __FILE__, __LINE__, tty->driver->name, port->count); | 313 | __FILE__, __LINE__, tty->driver->name, port->count); |
314 | 314 | ||
315 | spin_lock_irqsave(&port->lock, flags); | 315 | spin_lock_irqsave(&port->lock, flags); |
316 | port->count--; | 316 | port->count--; |
317 | port->blocked_open++; | 317 | port->blocked_open++; |
318 | spin_unlock_irqrestore(&port->lock, flags); | 318 | spin_unlock_irqrestore(&port->lock, flags); |
319 | 319 | ||
320 | while (1) { | 320 | while (1) { |
321 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) | 321 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) |
322 | tty_port_raise_dtr_rts(port); | 322 | tty_port_raise_dtr_rts(port); |
323 | 323 | ||
324 | set_current_state(TASK_INTERRUPTIBLE); | 324 | set_current_state(TASK_INTERRUPTIBLE); |
325 | 325 | ||
326 | if (tty_hung_up_p(filp) || | 326 | if (tty_hung_up_p(filp) || |
327 | !test_bit(ASYNCB_INITIALIZED, &port->flags)) { | 327 | !test_bit(ASYNCB_INITIALIZED, &port->flags)) { |
328 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? | 328 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
329 | -EAGAIN : -ERESTARTSYS; | 329 | -EAGAIN : -ERESTARTSYS; |
330 | break; | 330 | break; |
331 | } | 331 | } |
332 | 332 | ||
333 | /* | 333 | /* |
334 | * Check if link is ready now. Even if CLOCAL is | 334 | * Check if link is ready now. Even if CLOCAL is |
335 | * specified, we cannot return before the IrCOMM link is | 335 | * specified, we cannot return before the IrCOMM link is |
336 | * ready | 336 | * ready |
337 | */ | 337 | */ |
338 | if (!test_bit(ASYNCB_CLOSING, &port->flags) && | 338 | if (!test_bit(ASYNCB_CLOSING, &port->flags) && |
339 | (do_clocal || tty_port_carrier_raised(port)) && | 339 | (do_clocal || tty_port_carrier_raised(port)) && |
340 | self->state == IRCOMM_TTY_READY) | 340 | self->state == IRCOMM_TTY_READY) |
341 | { | 341 | { |
342 | break; | 342 | break; |
343 | } | 343 | } |
344 | 344 | ||
345 | if (signal_pending(current)) { | 345 | if (signal_pending(current)) { |
346 | retval = -ERESTARTSYS; | 346 | retval = -ERESTARTSYS; |
347 | break; | 347 | break; |
348 | } | 348 | } |
349 | 349 | ||
350 | pr_debug("%s(%d):block_til_ready blocking on %s open_count=%d\n", | 350 | pr_debug("%s(%d):block_til_ready blocking on %s open_count=%d\n", |
351 | __FILE__, __LINE__, tty->driver->name, port->count); | 351 | __FILE__, __LINE__, tty->driver->name, port->count); |
352 | 352 | ||
353 | schedule(); | 353 | schedule(); |
354 | } | 354 | } |
355 | 355 | ||
356 | __set_current_state(TASK_RUNNING); | 356 | __set_current_state(TASK_RUNNING); |
357 | remove_wait_queue(&port->open_wait, &wait); | 357 | remove_wait_queue(&port->open_wait, &wait); |
358 | 358 | ||
359 | spin_lock_irqsave(&port->lock, flags); | 359 | spin_lock_irqsave(&port->lock, flags); |
360 | if (!tty_hung_up_p(filp)) | 360 | if (!tty_hung_up_p(filp)) |
361 | port->count++; | 361 | port->count++; |
362 | port->blocked_open--; | 362 | port->blocked_open--; |
363 | spin_unlock_irqrestore(&port->lock, flags); | 363 | spin_unlock_irqrestore(&port->lock, flags); |
364 | 364 | ||
365 | pr_debug("%s(%d):block_til_ready after blocking on %s open_count=%d\n", | 365 | pr_debug("%s(%d):block_til_ready after blocking on %s open_count=%d\n", |
366 | __FILE__, __LINE__, tty->driver->name, port->count); | 366 | __FILE__, __LINE__, tty->driver->name, port->count); |
367 | 367 | ||
368 | if (!retval) | 368 | if (!retval) |
369 | port->flags |= ASYNC_NORMAL_ACTIVE; | 369 | port->flags |= ASYNC_NORMAL_ACTIVE; |
370 | 370 | ||
371 | return retval; | 371 | return retval; |
372 | } | 372 | } |
373 | 373 | ||
374 | 374 | ||
375 | static int ircomm_tty_install(struct tty_driver *driver, struct tty_struct *tty) | 375 | static int ircomm_tty_install(struct tty_driver *driver, struct tty_struct *tty) |
376 | { | 376 | { |
377 | struct ircomm_tty_cb *self; | 377 | struct ircomm_tty_cb *self; |
378 | unsigned int line = tty->index; | 378 | unsigned int line = tty->index; |
379 | 379 | ||
380 | /* Check if instance already exists */ | 380 | /* Check if instance already exists */ |
381 | self = hashbin_lock_find(ircomm_tty, line, NULL); | 381 | self = hashbin_lock_find(ircomm_tty, line, NULL); |
382 | if (!self) { | 382 | if (!self) { |
383 | /* No, so make new instance */ | 383 | /* No, so make new instance */ |
384 | self = kzalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL); | 384 | self = kzalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL); |
385 | if (self == NULL) | 385 | if (self == NULL) |
386 | return -ENOMEM; | 386 | return -ENOMEM; |
387 | 387 | ||
388 | tty_port_init(&self->port); | 388 | tty_port_init(&self->port); |
389 | self->port.ops = &ircomm_port_ops; | 389 | self->port.ops = &ircomm_port_ops; |
390 | self->magic = IRCOMM_TTY_MAGIC; | 390 | self->magic = IRCOMM_TTY_MAGIC; |
391 | self->flow = FLOW_STOP; | 391 | self->flow = FLOW_STOP; |
392 | 392 | ||
393 | self->line = line; | 393 | self->line = line; |
394 | INIT_WORK(&self->tqueue, ircomm_tty_do_softint); | 394 | INIT_WORK(&self->tqueue, ircomm_tty_do_softint); |
395 | self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED; | 395 | self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED; |
396 | self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED; | 396 | self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED; |
397 | 397 | ||
398 | /* Init some important stuff */ | 398 | /* Init some important stuff */ |
399 | init_timer(&self->watchdog_timer); | 399 | init_timer(&self->watchdog_timer); |
400 | spin_lock_init(&self->spinlock); | 400 | spin_lock_init(&self->spinlock); |
401 | 401 | ||
402 | /* | 402 | /* |
403 | * Force TTY into raw mode by default which is usually what | 403 | * Force TTY into raw mode by default which is usually what |
404 | * we want for IrCOMM and IrLPT. This way applications will | 404 | * we want for IrCOMM and IrLPT. This way applications will |
405 | * not have to twiddle with printcap etc. | 405 | * not have to twiddle with printcap etc. |
406 | * | 406 | * |
407 | * Note this is completely usafe and doesn't work properly | 407 | * Note this is completely usafe and doesn't work properly |
408 | */ | 408 | */ |
409 | tty->termios.c_iflag = 0; | 409 | tty->termios.c_iflag = 0; |
410 | tty->termios.c_oflag = 0; | 410 | tty->termios.c_oflag = 0; |
411 | 411 | ||
412 | /* Insert into hash */ | 412 | /* Insert into hash */ |
413 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); | 413 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); |
414 | } | 414 | } |
415 | 415 | ||
416 | tty->driver_data = self; | 416 | tty->driver_data = self; |
417 | 417 | ||
418 | return tty_port_install(&self->port, driver, tty); | 418 | return tty_port_install(&self->port, driver, tty); |
419 | } | 419 | } |
420 | 420 | ||
421 | /* | 421 | /* |
422 | * Function ircomm_tty_open (tty, filp) | 422 | * Function ircomm_tty_open (tty, filp) |
423 | * | 423 | * |
424 | * This routine is called when a particular tty device is opened. This | 424 | * This routine is called when a particular tty device is opened. This |
425 | * routine is mandatory; if this routine is not filled in, the attempted | 425 | * routine is mandatory; if this routine is not filled in, the attempted |
426 | * open will fail with ENODEV. | 426 | * open will fail with ENODEV. |
427 | */ | 427 | */ |
428 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | 428 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) |
429 | { | 429 | { |
430 | struct ircomm_tty_cb *self = tty->driver_data; | 430 | struct ircomm_tty_cb *self = tty->driver_data; |
431 | unsigned long flags; | 431 | unsigned long flags; |
432 | int ret; | 432 | int ret; |
433 | 433 | ||
434 | /* ++ is not atomic, so this should be protected - Jean II */ | 434 | /* ++ is not atomic, so this should be protected - Jean II */ |
435 | spin_lock_irqsave(&self->port.lock, flags); | 435 | spin_lock_irqsave(&self->port.lock, flags); |
436 | self->port.count++; | 436 | self->port.count++; |
437 | spin_unlock_irqrestore(&self->port.lock, flags); | 437 | spin_unlock_irqrestore(&self->port.lock, flags); |
438 | tty_port_tty_set(&self->port, tty); | 438 | tty_port_tty_set(&self->port, tty); |
439 | 439 | ||
440 | pr_debug("%s(), %s%d, count = %d\n", __func__ , tty->driver->name, | 440 | pr_debug("%s(), %s%d, count = %d\n", __func__ , tty->driver->name, |
441 | self->line, self->port.count); | 441 | self->line, self->port.count); |
442 | 442 | ||
443 | /* Not really used by us, but lets do it anyway */ | 443 | /* Not really used by us, but lets do it anyway */ |
444 | self->port.low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 444 | self->port.low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
445 | 445 | ||
446 | /* | 446 | /* |
447 | * If the port is the middle of closing, bail out now | 447 | * If the port is the middle of closing, bail out now |
448 | */ | 448 | */ |
449 | if (test_bit(ASYNCB_CLOSING, &self->port.flags)) { | 449 | if (test_bit(ASYNCB_CLOSING, &self->port.flags)) { |
450 | 450 | ||
451 | /* Hm, why are we blocking on ASYNC_CLOSING if we | 451 | /* Hm, why are we blocking on ASYNC_CLOSING if we |
452 | * do return -EAGAIN/-ERESTARTSYS below anyway? | 452 | * do return -EAGAIN/-ERESTARTSYS below anyway? |
453 | * IMHO it's either not needed in the first place | 453 | * IMHO it's either not needed in the first place |
454 | * or for some reason we need to make sure the async | 454 | * or for some reason we need to make sure the async |
455 | * closing has been finished - if so, wouldn't we | 455 | * closing has been finished - if so, wouldn't we |
456 | * probably better sleep uninterruptible? | 456 | * probably better sleep uninterruptible? |
457 | */ | 457 | */ |
458 | 458 | ||
459 | if (wait_event_interruptible(self->port.close_wait, | 459 | if (wait_event_interruptible(self->port.close_wait, |
460 | !test_bit(ASYNCB_CLOSING, &self->port.flags))) { | 460 | !test_bit(ASYNCB_CLOSING, &self->port.flags))) { |
461 | net_warn_ratelimited("%s - got signal while blocking on ASYNC_CLOSING!\n", | 461 | net_warn_ratelimited("%s - got signal while blocking on ASYNC_CLOSING!\n", |
462 | __func__); | 462 | __func__); |
463 | return -ERESTARTSYS; | 463 | return -ERESTARTSYS; |
464 | } | 464 | } |
465 | 465 | ||
466 | #ifdef SERIAL_DO_RESTART | 466 | #ifdef SERIAL_DO_RESTART |
467 | return (self->port.flags & ASYNC_HUP_NOTIFY) ? | 467 | return (self->port.flags & ASYNC_HUP_NOTIFY) ? |
468 | -EAGAIN : -ERESTARTSYS; | 468 | -EAGAIN : -ERESTARTSYS; |
469 | #else | 469 | #else |
470 | return -EAGAIN; | 470 | return -EAGAIN; |
471 | #endif | 471 | #endif |
472 | } | 472 | } |
473 | 473 | ||
474 | /* Check if this is a "normal" ircomm device, or an irlpt device */ | 474 | /* Check if this is a "normal" ircomm device, or an irlpt device */ |
475 | if (self->line < 0x10) { | 475 | if (self->line < 0x10) { |
476 | self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; | 476 | self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; |
477 | self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */ | 477 | self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */ |
478 | /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */ | 478 | /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */ |
479 | self->settings.dce = IRCOMM_CTS | IRCOMM_CD | IRCOMM_DSR | IRCOMM_RI; /* Default line settings */ | 479 | self->settings.dce = IRCOMM_CTS | IRCOMM_CD | IRCOMM_DSR | IRCOMM_RI; /* Default line settings */ |
480 | pr_debug("%s(), IrCOMM device\n", __func__); | 480 | pr_debug("%s(), IrCOMM device\n", __func__); |
481 | } else { | 481 | } else { |
482 | pr_debug("%s(), IrLPT device\n", __func__); | 482 | pr_debug("%s(), IrLPT device\n", __func__); |
483 | self->service_type = IRCOMM_3_WIRE_RAW; | 483 | self->service_type = IRCOMM_3_WIRE_RAW; |
484 | self->settings.service_type = IRCOMM_3_WIRE_RAW; /* Default */ | 484 | self->settings.service_type = IRCOMM_3_WIRE_RAW; /* Default */ |
485 | } | 485 | } |
486 | 486 | ||
487 | ret = ircomm_tty_startup(self); | 487 | ret = ircomm_tty_startup(self); |
488 | if (ret) | 488 | if (ret) |
489 | return ret; | 489 | return ret; |
490 | 490 | ||
491 | ret = ircomm_tty_block_til_ready(self, tty, filp); | 491 | ret = ircomm_tty_block_til_ready(self, tty, filp); |
492 | if (ret) { | 492 | if (ret) { |
493 | pr_debug("%s(), returning after block_til_ready with %d\n", | 493 | pr_debug("%s(), returning after block_til_ready with %d\n", |
494 | __func__, ret); | 494 | __func__, ret); |
495 | 495 | ||
496 | return ret; | 496 | return ret; |
497 | } | 497 | } |
498 | return 0; | 498 | return 0; |
499 | } | 499 | } |
500 | 500 | ||
501 | /* | 501 | /* |
502 | * Function ircomm_tty_close (tty, filp) | 502 | * Function ircomm_tty_close (tty, filp) |
503 | * | 503 | * |
504 | * This routine is called when a particular tty device is closed. | 504 | * This routine is called when a particular tty device is closed. |
505 | * | 505 | * |
506 | */ | 506 | */ |
507 | static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) | 507 | static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) |
508 | { | 508 | { |
509 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 509 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
510 | struct tty_port *port = &self->port; | 510 | struct tty_port *port = &self->port; |
511 | 511 | ||
512 | IRDA_ASSERT(self != NULL, return;); | 512 | IRDA_ASSERT(self != NULL, return;); |
513 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 513 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
514 | 514 | ||
515 | if (tty_port_close_start(port, tty, filp) == 0) | 515 | if (tty_port_close_start(port, tty, filp) == 0) |
516 | return; | 516 | return; |
517 | 517 | ||
518 | ircomm_tty_shutdown(self); | 518 | ircomm_tty_shutdown(self); |
519 | 519 | ||
520 | tty_driver_flush_buffer(tty); | 520 | tty_driver_flush_buffer(tty); |
521 | 521 | ||
522 | tty_port_close_end(port, tty); | 522 | tty_port_close_end(port, tty); |
523 | tty_port_tty_set(port, NULL); | 523 | tty_port_tty_set(port, NULL); |
524 | } | 524 | } |
525 | 525 | ||
526 | /* | 526 | /* |
527 | * Function ircomm_tty_flush_buffer (tty) | 527 | * Function ircomm_tty_flush_buffer (tty) |
528 | * | 528 | * |
529 | * | 529 | * |
530 | * | 530 | * |
531 | */ | 531 | */ |
532 | static void ircomm_tty_flush_buffer(struct tty_struct *tty) | 532 | static void ircomm_tty_flush_buffer(struct tty_struct *tty) |
533 | { | 533 | { |
534 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 534 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
535 | 535 | ||
536 | IRDA_ASSERT(self != NULL, return;); | 536 | IRDA_ASSERT(self != NULL, return;); |
537 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 537 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
538 | 538 | ||
539 | /* | 539 | /* |
540 | * Let do_softint() do this to avoid race condition with | 540 | * Let do_softint() do this to avoid race condition with |
541 | * do_softint() ;-) | 541 | * do_softint() ;-) |
542 | */ | 542 | */ |
543 | schedule_work(&self->tqueue); | 543 | schedule_work(&self->tqueue); |
544 | } | 544 | } |
545 | 545 | ||
546 | /* | 546 | /* |
547 | * Function ircomm_tty_do_softint (work) | 547 | * Function ircomm_tty_do_softint (work) |
548 | * | 548 | * |
549 | * We use this routine to give the write wakeup to the user at at a | 549 | * We use this routine to give the write wakeup to the user at at a |
550 | * safe time (as fast as possible after write have completed). This | 550 | * safe time (as fast as possible after write have completed). This |
551 | * can be compared to the Tx interrupt. | 551 | * can be compared to the Tx interrupt. |
552 | */ | 552 | */ |
553 | static void ircomm_tty_do_softint(struct work_struct *work) | 553 | static void ircomm_tty_do_softint(struct work_struct *work) |
554 | { | 554 | { |
555 | struct ircomm_tty_cb *self = | 555 | struct ircomm_tty_cb *self = |
556 | container_of(work, struct ircomm_tty_cb, tqueue); | 556 | container_of(work, struct ircomm_tty_cb, tqueue); |
557 | struct tty_struct *tty; | 557 | struct tty_struct *tty; |
558 | unsigned long flags; | 558 | unsigned long flags; |
559 | struct sk_buff *skb, *ctrl_skb; | 559 | struct sk_buff *skb, *ctrl_skb; |
560 | 560 | ||
561 | if (!self || self->magic != IRCOMM_TTY_MAGIC) | 561 | if (!self || self->magic != IRCOMM_TTY_MAGIC) |
562 | return; | 562 | return; |
563 | 563 | ||
564 | tty = tty_port_tty_get(&self->port); | 564 | tty = tty_port_tty_get(&self->port); |
565 | if (!tty) | 565 | if (!tty) |
566 | return; | 566 | return; |
567 | 567 | ||
568 | /* Unlink control buffer */ | 568 | /* Unlink control buffer */ |
569 | spin_lock_irqsave(&self->spinlock, flags); | 569 | spin_lock_irqsave(&self->spinlock, flags); |
570 | 570 | ||
571 | ctrl_skb = self->ctrl_skb; | 571 | ctrl_skb = self->ctrl_skb; |
572 | self->ctrl_skb = NULL; | 572 | self->ctrl_skb = NULL; |
573 | 573 | ||
574 | spin_unlock_irqrestore(&self->spinlock, flags); | 574 | spin_unlock_irqrestore(&self->spinlock, flags); |
575 | 575 | ||
576 | /* Flush control buffer if any */ | 576 | /* Flush control buffer if any */ |
577 | if(ctrl_skb) { | 577 | if(ctrl_skb) { |
578 | if(self->flow == FLOW_START) | 578 | if(self->flow == FLOW_START) |
579 | ircomm_control_request(self->ircomm, ctrl_skb); | 579 | ircomm_control_request(self->ircomm, ctrl_skb); |
580 | /* Drop reference count - see ircomm_ttp_data_request(). */ | 580 | /* Drop reference count - see ircomm_ttp_data_request(). */ |
581 | dev_kfree_skb(ctrl_skb); | 581 | dev_kfree_skb(ctrl_skb); |
582 | } | 582 | } |
583 | 583 | ||
584 | if (tty->hw_stopped) | 584 | if (tty->hw_stopped) |
585 | goto put; | 585 | goto put; |
586 | 586 | ||
587 | /* Unlink transmit buffer */ | 587 | /* Unlink transmit buffer */ |
588 | spin_lock_irqsave(&self->spinlock, flags); | 588 | spin_lock_irqsave(&self->spinlock, flags); |
589 | 589 | ||
590 | skb = self->tx_skb; | 590 | skb = self->tx_skb; |
591 | self->tx_skb = NULL; | 591 | self->tx_skb = NULL; |
592 | 592 | ||
593 | spin_unlock_irqrestore(&self->spinlock, flags); | 593 | spin_unlock_irqrestore(&self->spinlock, flags); |
594 | 594 | ||
595 | /* Flush transmit buffer if any */ | 595 | /* Flush transmit buffer if any */ |
596 | if (skb) { | 596 | if (skb) { |
597 | ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, skb, NULL); | 597 | ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, skb, NULL); |
598 | /* Drop reference count - see ircomm_ttp_data_request(). */ | 598 | /* Drop reference count - see ircomm_ttp_data_request(). */ |
599 | dev_kfree_skb(skb); | 599 | dev_kfree_skb(skb); |
600 | } | 600 | } |
601 | 601 | ||
602 | /* Check if user (still) wants to be waken up */ | 602 | /* Check if user (still) wants to be waken up */ |
603 | tty_wakeup(tty); | 603 | tty_wakeup(tty); |
604 | put: | 604 | put: |
605 | tty_kref_put(tty); | 605 | tty_kref_put(tty); |
606 | } | 606 | } |
607 | 607 | ||
608 | /* | 608 | /* |
609 | * Function ircomm_tty_write (tty, buf, count) | 609 | * Function ircomm_tty_write (tty, buf, count) |
610 | * | 610 | * |
611 | * This routine is called by the kernel to write a series of characters | 611 | * This routine is called by the kernel to write a series of characters |
612 | * to the tty device. The characters may come from user space or kernel | 612 | * to the tty device. The characters may come from user space or kernel |
613 | * space. This routine will return the number of characters actually | 613 | * space. This routine will return the number of characters actually |
614 | * accepted for writing. This routine is mandatory. | 614 | * accepted for writing. This routine is mandatory. |
615 | */ | 615 | */ |
616 | static int ircomm_tty_write(struct tty_struct *tty, | 616 | static int ircomm_tty_write(struct tty_struct *tty, |
617 | const unsigned char *buf, int count) | 617 | const unsigned char *buf, int count) |
618 | { | 618 | { |
619 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 619 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
620 | unsigned long flags; | 620 | unsigned long flags; |
621 | struct sk_buff *skb; | 621 | struct sk_buff *skb; |
622 | int tailroom = 0; | 622 | int tailroom = 0; |
623 | int len = 0; | 623 | int len = 0; |
624 | int size; | 624 | int size; |
625 | 625 | ||
626 | pr_debug("%s(), count=%d, hw_stopped=%d\n", __func__ , count, | 626 | pr_debug("%s(), count=%d, hw_stopped=%d\n", __func__ , count, |
627 | tty->hw_stopped); | 627 | tty->hw_stopped); |
628 | 628 | ||
629 | IRDA_ASSERT(self != NULL, return -1;); | 629 | IRDA_ASSERT(self != NULL, return -1;); |
630 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 630 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
631 | 631 | ||
632 | /* We may receive packets from the TTY even before we have finished | 632 | /* We may receive packets from the TTY even before we have finished |
633 | * our setup. Not cool. | 633 | * our setup. Not cool. |
634 | * The problem is that we don't know the final header and data size | 634 | * The problem is that we don't know the final header and data size |
635 | * to create the proper skb, so any skb we would create would have | 635 | * to create the proper skb, so any skb we would create would have |
636 | * bogus header and data size, so need care. | 636 | * bogus header and data size, so need care. |
637 | * We use a bogus header size to safely detect this condition. | 637 | * We use a bogus header size to safely detect this condition. |
638 | * Another problem is that hw_stopped was set to 0 way before it | 638 | * Another problem is that hw_stopped was set to 0 way before it |
639 | * should be, so we would drop this skb. It should now be fixed. | 639 | * should be, so we would drop this skb. It should now be fixed. |
640 | * One option is to not accept data until we are properly setup. | 640 | * One option is to not accept data until we are properly setup. |
641 | * But, I suspect that when it happens, the ppp line discipline | 641 | * But, I suspect that when it happens, the ppp line discipline |
642 | * just "drops" the data, which might screw up connect scripts. | 642 | * just "drops" the data, which might screw up connect scripts. |
643 | * The second option is to create a "safe skb", with large header | 643 | * The second option is to create a "safe skb", with large header |
644 | * and small size (see ircomm_tty_open() for values). | 644 | * and small size (see ircomm_tty_open() for values). |
645 | * We just need to make sure that when the real values get filled, | 645 | * We just need to make sure that when the real values get filled, |
646 | * we don't mess up the original "safe skb" (see tx_data_size). | 646 | * we don't mess up the original "safe skb" (see tx_data_size). |
647 | * Jean II */ | 647 | * Jean II */ |
648 | if (self->max_header_size == IRCOMM_TTY_HDR_UNINITIALISED) { | 648 | if (self->max_header_size == IRCOMM_TTY_HDR_UNINITIALISED) { |
649 | pr_debug("%s() : not initialised\n", __func__); | 649 | pr_debug("%s() : not initialised\n", __func__); |
650 | #ifdef IRCOMM_NO_TX_BEFORE_INIT | 650 | #ifdef IRCOMM_NO_TX_BEFORE_INIT |
651 | /* We didn't consume anything, TTY will retry */ | 651 | /* We didn't consume anything, TTY will retry */ |
652 | return 0; | 652 | return 0; |
653 | #endif | 653 | #endif |
654 | } | 654 | } |
655 | 655 | ||
656 | if (count < 1) | 656 | if (count < 1) |
657 | return 0; | 657 | return 0; |
658 | 658 | ||
659 | /* Protect our manipulation of self->tx_skb and related */ | 659 | /* Protect our manipulation of self->tx_skb and related */ |
660 | spin_lock_irqsave(&self->spinlock, flags); | 660 | spin_lock_irqsave(&self->spinlock, flags); |
661 | 661 | ||
662 | /* Fetch current transmit buffer */ | 662 | /* Fetch current transmit buffer */ |
663 | skb = self->tx_skb; | 663 | skb = self->tx_skb; |
664 | 664 | ||
665 | /* | 665 | /* |
666 | * Send out all the data we get, possibly as multiple fragmented | 666 | * Send out all the data we get, possibly as multiple fragmented |
667 | * frames, but this will only happen if the data is larger than the | 667 | * frames, but this will only happen if the data is larger than the |
668 | * max data size. The normal case however is just the opposite, and | 668 | * max data size. The normal case however is just the opposite, and |
669 | * this function may be called multiple times, and will then actually | 669 | * this function may be called multiple times, and will then actually |
670 | * defragment the data and send it out as one packet as soon as | 670 | * defragment the data and send it out as one packet as soon as |
671 | * possible, but at a safer point in time | 671 | * possible, but at a safer point in time |
672 | */ | 672 | */ |
673 | while (count) { | 673 | while (count) { |
674 | size = count; | 674 | size = count; |
675 | 675 | ||
676 | /* Adjust data size to the max data size */ | 676 | /* Adjust data size to the max data size */ |
677 | if (size > self->max_data_size) | 677 | if (size > self->max_data_size) |
678 | size = self->max_data_size; | 678 | size = self->max_data_size; |
679 | 679 | ||
680 | /* | 680 | /* |
681 | * Do we already have a buffer ready for transmit, or do | 681 | * Do we already have a buffer ready for transmit, or do |
682 | * we need to allocate a new frame | 682 | * we need to allocate a new frame |
683 | */ | 683 | */ |
684 | if (skb) { | 684 | if (skb) { |
685 | /* | 685 | /* |
686 | * Any room for more data at the end of the current | 686 | * Any room for more data at the end of the current |
687 | * transmit buffer? Cannot use skb_tailroom, since | 687 | * transmit buffer? Cannot use skb_tailroom, since |
688 | * dev_alloc_skb gives us a larger skb than we | 688 | * dev_alloc_skb gives us a larger skb than we |
689 | * requested | 689 | * requested |
690 | * Note : use tx_data_size, because max_data_size | 690 | * Note : use tx_data_size, because max_data_size |
691 | * may have changed and we don't want to overwrite | 691 | * may have changed and we don't want to overwrite |
692 | * the skb. - Jean II | 692 | * the skb. - Jean II |
693 | */ | 693 | */ |
694 | if ((tailroom = (self->tx_data_size - skb->len)) > 0) { | 694 | if ((tailroom = (self->tx_data_size - skb->len)) > 0) { |
695 | /* Adjust data to tailroom */ | 695 | /* Adjust data to tailroom */ |
696 | if (size > tailroom) | 696 | if (size > tailroom) |
697 | size = tailroom; | 697 | size = tailroom; |
698 | } else { | 698 | } else { |
699 | /* | 699 | /* |
700 | * Current transmit frame is full, so break | 700 | * Current transmit frame is full, so break |
701 | * out, so we can send it as soon as possible | 701 | * out, so we can send it as soon as possible |
702 | */ | 702 | */ |
703 | break; | 703 | break; |
704 | } | 704 | } |
705 | } else { | 705 | } else { |
706 | /* Prepare a full sized frame */ | 706 | /* Prepare a full sized frame */ |
707 | skb = alloc_skb(self->max_data_size+ | 707 | skb = alloc_skb(self->max_data_size+ |
708 | self->max_header_size, | 708 | self->max_header_size, |
709 | GFP_ATOMIC); | 709 | GFP_ATOMIC); |
710 | if (!skb) { | 710 | if (!skb) { |
711 | spin_unlock_irqrestore(&self->spinlock, flags); | 711 | spin_unlock_irqrestore(&self->spinlock, flags); |
712 | return -ENOBUFS; | 712 | return -ENOBUFS; |
713 | } | 713 | } |
714 | skb_reserve(skb, self->max_header_size); | 714 | skb_reserve(skb, self->max_header_size); |
715 | self->tx_skb = skb; | 715 | self->tx_skb = skb; |
716 | /* Remember skb size because max_data_size may | 716 | /* Remember skb size because max_data_size may |
717 | * change later on - Jean II */ | 717 | * change later on - Jean II */ |
718 | self->tx_data_size = self->max_data_size; | 718 | self->tx_data_size = self->max_data_size; |
719 | } | 719 | } |
720 | 720 | ||
721 | /* Copy data */ | 721 | /* Copy data */ |
722 | memcpy(skb_put(skb,size), buf + len, size); | 722 | memcpy(skb_put(skb,size), buf + len, size); |
723 | 723 | ||
724 | count -= size; | 724 | count -= size; |
725 | len += size; | 725 | len += size; |
726 | } | 726 | } |
727 | 727 | ||
728 | spin_unlock_irqrestore(&self->spinlock, flags); | 728 | spin_unlock_irqrestore(&self->spinlock, flags); |
729 | 729 | ||
730 | /* | 730 | /* |
731 | * Schedule a new thread which will transmit the frame as soon | 731 | * Schedule a new thread which will transmit the frame as soon |
732 | * as possible, but at a safe point in time. We do this so the | 732 | * as possible, but at a safe point in time. We do this so the |
733 | * "user" can give us data multiple times, as PPP does (because of | 733 | * "user" can give us data multiple times, as PPP does (because of |
734 | * its 256 byte tx buffer). We will then defragment and send out | 734 | * its 256 byte tx buffer). We will then defragment and send out |
735 | * all this data as one single packet. | 735 | * all this data as one single packet. |
736 | */ | 736 | */ |
737 | schedule_work(&self->tqueue); | 737 | schedule_work(&self->tqueue); |
738 | 738 | ||
739 | return len; | 739 | return len; |
740 | } | 740 | } |
741 | 741 | ||
742 | /* | 742 | /* |
743 | * Function ircomm_tty_write_room (tty) | 743 | * Function ircomm_tty_write_room (tty) |
744 | * | 744 | * |
745 | * This routine returns the numbers of characters the tty driver will | 745 | * This routine returns the numbers of characters the tty driver will |
746 | * accept for queuing to be written. This number is subject to change as | 746 | * accept for queuing to be written. This number is subject to change as |
747 | * output buffers get emptied, or if the output flow control is acted. | 747 | * output buffers get emptied, or if the output flow control is acted. |
748 | */ | 748 | */ |
749 | static int ircomm_tty_write_room(struct tty_struct *tty) | 749 | static int ircomm_tty_write_room(struct tty_struct *tty) |
750 | { | 750 | { |
751 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 751 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
752 | unsigned long flags; | 752 | unsigned long flags; |
753 | int ret; | 753 | int ret; |
754 | 754 | ||
755 | IRDA_ASSERT(self != NULL, return -1;); | 755 | IRDA_ASSERT(self != NULL, return -1;); |
756 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 756 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
757 | 757 | ||
758 | #ifdef IRCOMM_NO_TX_BEFORE_INIT | 758 | #ifdef IRCOMM_NO_TX_BEFORE_INIT |
759 | /* max_header_size tells us if the channel is initialised or not. */ | 759 | /* max_header_size tells us if the channel is initialised or not. */ |
760 | if (self->max_header_size == IRCOMM_TTY_HDR_UNINITIALISED) | 760 | if (self->max_header_size == IRCOMM_TTY_HDR_UNINITIALISED) |
761 | /* Don't bother us yet */ | 761 | /* Don't bother us yet */ |
762 | return 0; | 762 | return 0; |
763 | #endif | 763 | #endif |
764 | 764 | ||
765 | /* Check if we are allowed to transmit any data. | 765 | /* Check if we are allowed to transmit any data. |
766 | * hw_stopped is the regular flow control. | 766 | * hw_stopped is the regular flow control. |
767 | * Jean II */ | 767 | * Jean II */ |
768 | if (tty->hw_stopped) | 768 | if (tty->hw_stopped) |
769 | ret = 0; | 769 | ret = 0; |
770 | else { | 770 | else { |
771 | spin_lock_irqsave(&self->spinlock, flags); | 771 | spin_lock_irqsave(&self->spinlock, flags); |
772 | if (self->tx_skb) | 772 | if (self->tx_skb) |
773 | ret = self->tx_data_size - self->tx_skb->len; | 773 | ret = self->tx_data_size - self->tx_skb->len; |
774 | else | 774 | else |
775 | ret = self->max_data_size; | 775 | ret = self->max_data_size; |
776 | spin_unlock_irqrestore(&self->spinlock, flags); | 776 | spin_unlock_irqrestore(&self->spinlock, flags); |
777 | } | 777 | } |
778 | pr_debug("%s(), ret=%d\n", __func__ , ret); | 778 | pr_debug("%s(), ret=%d\n", __func__ , ret); |
779 | 779 | ||
780 | return ret; | 780 | return ret; |
781 | } | 781 | } |
782 | 782 | ||
783 | /* | 783 | /* |
784 | * Function ircomm_tty_wait_until_sent (tty, timeout) | 784 | * Function ircomm_tty_wait_until_sent (tty, timeout) |
785 | * | 785 | * |
786 | * This routine waits until the device has written out all of the | 786 | * This routine waits until the device has written out all of the |
787 | * characters in its transmitter FIFO. | 787 | * characters in its transmitter FIFO. |
788 | */ | 788 | */ |
789 | static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) | 789 | static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) |
790 | { | 790 | { |
791 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 791 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
792 | unsigned long orig_jiffies, poll_time; | 792 | unsigned long orig_jiffies, poll_time; |
793 | unsigned long flags; | 793 | unsigned long flags; |
794 | 794 | ||
795 | IRDA_ASSERT(self != NULL, return;); | 795 | IRDA_ASSERT(self != NULL, return;); |
796 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 796 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
797 | 797 | ||
798 | orig_jiffies = jiffies; | 798 | orig_jiffies = jiffies; |
799 | 799 | ||
800 | /* Set poll time to 200 ms */ | 800 | /* Set poll time to 200 ms */ |
801 | poll_time = IRDA_MIN(timeout, msecs_to_jiffies(200)); | 801 | poll_time = msecs_to_jiffies(200); |
802 | if (timeout) | ||
803 | poll_time = min_t(unsigned long, timeout, poll_time); | ||
802 | 804 | ||
803 | spin_lock_irqsave(&self->spinlock, flags); | 805 | spin_lock_irqsave(&self->spinlock, flags); |
804 | while (self->tx_skb && self->tx_skb->len) { | 806 | while (self->tx_skb && self->tx_skb->len) { |
805 | spin_unlock_irqrestore(&self->spinlock, flags); | 807 | spin_unlock_irqrestore(&self->spinlock, flags); |
806 | schedule_timeout_interruptible(poll_time); | 808 | schedule_timeout_interruptible(poll_time); |
807 | spin_lock_irqsave(&self->spinlock, flags); | 809 | spin_lock_irqsave(&self->spinlock, flags); |
808 | if (signal_pending(current)) | 810 | if (signal_pending(current)) |
809 | break; | 811 | break; |
810 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 812 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) |
811 | break; | 813 | break; |
812 | } | 814 | } |
813 | spin_unlock_irqrestore(&self->spinlock, flags); | 815 | spin_unlock_irqrestore(&self->spinlock, flags); |
814 | __set_current_state(TASK_RUNNING); | 816 | __set_current_state(TASK_RUNNING); |
815 | } | 817 | } |
816 | 818 | ||
817 | /* | 819 | /* |
818 | * Function ircomm_tty_throttle (tty) | 820 | * Function ircomm_tty_throttle (tty) |
819 | * | 821 | * |
820 | * This routine notifies the tty driver that input buffers for the line | 822 | * This routine notifies the tty driver that input buffers for the line |
821 | * discipline are close to full, and it should somehow signal that no | 823 | * discipline are close to full, and it should somehow signal that no |
822 | * more characters should be sent to the tty. | 824 | * more characters should be sent to the tty. |
823 | */ | 825 | */ |
824 | static void ircomm_tty_throttle(struct tty_struct *tty) | 826 | static void ircomm_tty_throttle(struct tty_struct *tty) |
825 | { | 827 | { |
826 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 828 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
827 | 829 | ||
828 | IRDA_ASSERT(self != NULL, return;); | 830 | IRDA_ASSERT(self != NULL, return;); |
829 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 831 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
830 | 832 | ||
831 | /* Software flow control? */ | 833 | /* Software flow control? */ |
832 | if (I_IXOFF(tty)) | 834 | if (I_IXOFF(tty)) |
833 | ircomm_tty_send_xchar(tty, STOP_CHAR(tty)); | 835 | ircomm_tty_send_xchar(tty, STOP_CHAR(tty)); |
834 | 836 | ||
835 | /* Hardware flow control? */ | 837 | /* Hardware flow control? */ |
836 | if (tty->termios.c_cflag & CRTSCTS) { | 838 | if (tty->termios.c_cflag & CRTSCTS) { |
837 | self->settings.dte &= ~IRCOMM_RTS; | 839 | self->settings.dte &= ~IRCOMM_RTS; |
838 | self->settings.dte |= IRCOMM_DELTA_RTS; | 840 | self->settings.dte |= IRCOMM_DELTA_RTS; |
839 | 841 | ||
840 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | 842 | ircomm_param_request(self, IRCOMM_DTE, TRUE); |
841 | } | 843 | } |
842 | 844 | ||
843 | ircomm_flow_request(self->ircomm, FLOW_STOP); | 845 | ircomm_flow_request(self->ircomm, FLOW_STOP); |
844 | } | 846 | } |
845 | 847 | ||
846 | /* | 848 | /* |
847 | * Function ircomm_tty_unthrottle (tty) | 849 | * Function ircomm_tty_unthrottle (tty) |
848 | * | 850 | * |
849 | * This routine notifies the tty drivers that it should signals that | 851 | * This routine notifies the tty drivers that it should signals that |
850 | * characters can now be sent to the tty without fear of overrunning the | 852 | * characters can now be sent to the tty without fear of overrunning the |
851 | * input buffers of the line disciplines. | 853 | * input buffers of the line disciplines. |
852 | */ | 854 | */ |
853 | static void ircomm_tty_unthrottle(struct tty_struct *tty) | 855 | static void ircomm_tty_unthrottle(struct tty_struct *tty) |
854 | { | 856 | { |
855 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 857 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
856 | 858 | ||
857 | IRDA_ASSERT(self != NULL, return;); | 859 | IRDA_ASSERT(self != NULL, return;); |
858 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 860 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
859 | 861 | ||
860 | /* Using software flow control? */ | 862 | /* Using software flow control? */ |
861 | if (I_IXOFF(tty)) { | 863 | if (I_IXOFF(tty)) { |
862 | ircomm_tty_send_xchar(tty, START_CHAR(tty)); | 864 | ircomm_tty_send_xchar(tty, START_CHAR(tty)); |
863 | } | 865 | } |
864 | 866 | ||
865 | /* Using hardware flow control? */ | 867 | /* Using hardware flow control? */ |
866 | if (tty->termios.c_cflag & CRTSCTS) { | 868 | if (tty->termios.c_cflag & CRTSCTS) { |
867 | self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); | 869 | self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); |
868 | 870 | ||
869 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | 871 | ircomm_param_request(self, IRCOMM_DTE, TRUE); |
870 | pr_debug("%s(), FLOW_START\n", __func__); | 872 | pr_debug("%s(), FLOW_START\n", __func__); |
871 | } | 873 | } |
872 | ircomm_flow_request(self->ircomm, FLOW_START); | 874 | ircomm_flow_request(self->ircomm, FLOW_START); |
873 | } | 875 | } |
874 | 876 | ||
875 | /* | 877 | /* |
876 | * Function ircomm_tty_chars_in_buffer (tty) | 878 | * Function ircomm_tty_chars_in_buffer (tty) |
877 | * | 879 | * |
878 | * Indicates if there are any data in the buffer | 880 | * Indicates if there are any data in the buffer |
879 | * | 881 | * |
880 | */ | 882 | */ |
881 | static int ircomm_tty_chars_in_buffer(struct tty_struct *tty) | 883 | static int ircomm_tty_chars_in_buffer(struct tty_struct *tty) |
882 | { | 884 | { |
883 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 885 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
884 | unsigned long flags; | 886 | unsigned long flags; |
885 | int len = 0; | 887 | int len = 0; |
886 | 888 | ||
887 | IRDA_ASSERT(self != NULL, return -1;); | 889 | IRDA_ASSERT(self != NULL, return -1;); |
888 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 890 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
889 | 891 | ||
890 | spin_lock_irqsave(&self->spinlock, flags); | 892 | spin_lock_irqsave(&self->spinlock, flags); |
891 | 893 | ||
892 | if (self->tx_skb) | 894 | if (self->tx_skb) |
893 | len = self->tx_skb->len; | 895 | len = self->tx_skb->len; |
894 | 896 | ||
895 | spin_unlock_irqrestore(&self->spinlock, flags); | 897 | spin_unlock_irqrestore(&self->spinlock, flags); |
896 | 898 | ||
897 | return len; | 899 | return len; |
898 | } | 900 | } |
899 | 901 | ||
900 | static void ircomm_tty_shutdown(struct ircomm_tty_cb *self) | 902 | static void ircomm_tty_shutdown(struct ircomm_tty_cb *self) |
901 | { | 903 | { |
902 | unsigned long flags; | 904 | unsigned long flags; |
903 | 905 | ||
904 | IRDA_ASSERT(self != NULL, return;); | 906 | IRDA_ASSERT(self != NULL, return;); |
905 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 907 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
906 | 908 | ||
907 | if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags)) | 909 | if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags)) |
908 | return; | 910 | return; |
909 | 911 | ||
910 | ircomm_tty_detach_cable(self); | 912 | ircomm_tty_detach_cable(self); |
911 | 913 | ||
912 | spin_lock_irqsave(&self->spinlock, flags); | 914 | spin_lock_irqsave(&self->spinlock, flags); |
913 | 915 | ||
914 | del_timer(&self->watchdog_timer); | 916 | del_timer(&self->watchdog_timer); |
915 | 917 | ||
916 | /* Free parameter buffer */ | 918 | /* Free parameter buffer */ |
917 | if (self->ctrl_skb) { | 919 | if (self->ctrl_skb) { |
918 | dev_kfree_skb(self->ctrl_skb); | 920 | dev_kfree_skb(self->ctrl_skb); |
919 | self->ctrl_skb = NULL; | 921 | self->ctrl_skb = NULL; |
920 | } | 922 | } |
921 | 923 | ||
922 | /* Free transmit buffer */ | 924 | /* Free transmit buffer */ |
923 | if (self->tx_skb) { | 925 | if (self->tx_skb) { |
924 | dev_kfree_skb(self->tx_skb); | 926 | dev_kfree_skb(self->tx_skb); |
925 | self->tx_skb = NULL; | 927 | self->tx_skb = NULL; |
926 | } | 928 | } |
927 | 929 | ||
928 | if (self->ircomm) { | 930 | if (self->ircomm) { |
929 | ircomm_close(self->ircomm); | 931 | ircomm_close(self->ircomm); |
930 | self->ircomm = NULL; | 932 | self->ircomm = NULL; |
931 | } | 933 | } |
932 | 934 | ||
933 | spin_unlock_irqrestore(&self->spinlock, flags); | 935 | spin_unlock_irqrestore(&self->spinlock, flags); |
934 | } | 936 | } |
935 | 937 | ||
936 | /* | 938 | /* |
937 | * Function ircomm_tty_hangup (tty) | 939 | * Function ircomm_tty_hangup (tty) |
938 | * | 940 | * |
939 | * This routine notifies the tty driver that it should hangup the tty | 941 | * This routine notifies the tty driver that it should hangup the tty |
940 | * device. | 942 | * device. |
941 | * | 943 | * |
942 | */ | 944 | */ |
943 | static void ircomm_tty_hangup(struct tty_struct *tty) | 945 | static void ircomm_tty_hangup(struct tty_struct *tty) |
944 | { | 946 | { |
945 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 947 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
946 | struct tty_port *port = &self->port; | 948 | struct tty_port *port = &self->port; |
947 | unsigned long flags; | 949 | unsigned long flags; |
948 | 950 | ||
949 | IRDA_ASSERT(self != NULL, return;); | 951 | IRDA_ASSERT(self != NULL, return;); |
950 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 952 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
951 | 953 | ||
952 | /* ircomm_tty_flush_buffer(tty); */ | 954 | /* ircomm_tty_flush_buffer(tty); */ |
953 | ircomm_tty_shutdown(self); | 955 | ircomm_tty_shutdown(self); |
954 | 956 | ||
955 | spin_lock_irqsave(&port->lock, flags); | 957 | spin_lock_irqsave(&port->lock, flags); |
956 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | 958 | port->flags &= ~ASYNC_NORMAL_ACTIVE; |
957 | if (port->tty) { | 959 | if (port->tty) { |
958 | set_bit(TTY_IO_ERROR, &port->tty->flags); | 960 | set_bit(TTY_IO_ERROR, &port->tty->flags); |
959 | tty_kref_put(port->tty); | 961 | tty_kref_put(port->tty); |
960 | } | 962 | } |
961 | port->tty = NULL; | 963 | port->tty = NULL; |
962 | port->count = 0; | 964 | port->count = 0; |
963 | spin_unlock_irqrestore(&port->lock, flags); | 965 | spin_unlock_irqrestore(&port->lock, flags); |
964 | 966 | ||
965 | wake_up_interruptible(&port->open_wait); | 967 | wake_up_interruptible(&port->open_wait); |
966 | } | 968 | } |
967 | 969 | ||
968 | /* | 970 | /* |
969 | * Function ircomm_tty_send_xchar (tty, ch) | 971 | * Function ircomm_tty_send_xchar (tty, ch) |
970 | * | 972 | * |
971 | * This routine is used to send a high-priority XON/XOFF character to | 973 | * This routine is used to send a high-priority XON/XOFF character to |
972 | * the device. | 974 | * the device. |
973 | */ | 975 | */ |
974 | static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch) | 976 | static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch) |
975 | { | 977 | { |
976 | pr_debug("%s(), not impl\n", __func__); | 978 | pr_debug("%s(), not impl\n", __func__); |
977 | } | 979 | } |
978 | 980 | ||
979 | /* | 981 | /* |
980 | * Function ircomm_tty_start (tty) | 982 | * Function ircomm_tty_start (tty) |
981 | * | 983 | * |
982 | * This routine notifies the tty driver that it resume sending | 984 | * This routine notifies the tty driver that it resume sending |
983 | * characters to the tty device. | 985 | * characters to the tty device. |
984 | */ | 986 | */ |
985 | void ircomm_tty_start(struct tty_struct *tty) | 987 | void ircomm_tty_start(struct tty_struct *tty) |
986 | { | 988 | { |
987 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 989 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
988 | 990 | ||
989 | ircomm_flow_request(self->ircomm, FLOW_START); | 991 | ircomm_flow_request(self->ircomm, FLOW_START); |
990 | } | 992 | } |
991 | 993 | ||
992 | /* | 994 | /* |
993 | * Function ircomm_tty_stop (tty) | 995 | * Function ircomm_tty_stop (tty) |
994 | * | 996 | * |
995 | * This routine notifies the tty driver that it should stop outputting | 997 | * This routine notifies the tty driver that it should stop outputting |
996 | * characters to the tty device. | 998 | * characters to the tty device. |
997 | */ | 999 | */ |
998 | static void ircomm_tty_stop(struct tty_struct *tty) | 1000 | static void ircomm_tty_stop(struct tty_struct *tty) |
999 | { | 1001 | { |
1000 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 1002 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
1001 | 1003 | ||
1002 | IRDA_ASSERT(self != NULL, return;); | 1004 | IRDA_ASSERT(self != NULL, return;); |
1003 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 1005 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
1004 | 1006 | ||
1005 | ircomm_flow_request(self->ircomm, FLOW_STOP); | 1007 | ircomm_flow_request(self->ircomm, FLOW_STOP); |
1006 | } | 1008 | } |
1007 | 1009 | ||
1008 | /* | 1010 | /* |
1009 | * Function ircomm_check_modem_status (self) | 1011 | * Function ircomm_check_modem_status (self) |
1010 | * | 1012 | * |
1011 | * Check for any changes in the DCE's line settings. This function should | 1013 | * Check for any changes in the DCE's line settings. This function should |
1012 | * be called whenever the dce parameter settings changes, to update the | 1014 | * be called whenever the dce parameter settings changes, to update the |
1013 | * flow control settings and other things | 1015 | * flow control settings and other things |
1014 | */ | 1016 | */ |
1015 | void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | 1017 | void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) |
1016 | { | 1018 | { |
1017 | struct tty_struct *tty; | 1019 | struct tty_struct *tty; |
1018 | int status; | 1020 | int status; |
1019 | 1021 | ||
1020 | IRDA_ASSERT(self != NULL, return;); | 1022 | IRDA_ASSERT(self != NULL, return;); |
1021 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 1023 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
1022 | 1024 | ||
1023 | tty = tty_port_tty_get(&self->port); | 1025 | tty = tty_port_tty_get(&self->port); |
1024 | 1026 | ||
1025 | status = self->settings.dce; | 1027 | status = self->settings.dce; |
1026 | 1028 | ||
1027 | if (status & IRCOMM_DCE_DELTA_ANY) { | 1029 | if (status & IRCOMM_DCE_DELTA_ANY) { |
1028 | /*wake_up_interruptible(&self->delta_msr_wait);*/ | 1030 | /*wake_up_interruptible(&self->delta_msr_wait);*/ |
1029 | } | 1031 | } |
1030 | if ((self->port.flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) { | 1032 | if ((self->port.flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) { |
1031 | pr_debug("%s(), ircomm%d CD now %s...\n", __func__ , self->line, | 1033 | pr_debug("%s(), ircomm%d CD now %s...\n", __func__ , self->line, |
1032 | (status & IRCOMM_CD) ? "on" : "off"); | 1034 | (status & IRCOMM_CD) ? "on" : "off"); |
1033 | 1035 | ||
1034 | if (status & IRCOMM_CD) { | 1036 | if (status & IRCOMM_CD) { |
1035 | wake_up_interruptible(&self->port.open_wait); | 1037 | wake_up_interruptible(&self->port.open_wait); |
1036 | } else { | 1038 | } else { |
1037 | pr_debug("%s(), Doing serial hangup..\n", __func__); | 1039 | pr_debug("%s(), Doing serial hangup..\n", __func__); |
1038 | if (tty) | 1040 | if (tty) |
1039 | tty_hangup(tty); | 1041 | tty_hangup(tty); |
1040 | 1042 | ||
1041 | /* Hangup will remote the tty, so better break out */ | 1043 | /* Hangup will remote the tty, so better break out */ |
1042 | goto put; | 1044 | goto put; |
1043 | } | 1045 | } |
1044 | } | 1046 | } |
1045 | if (tty && tty_port_cts_enabled(&self->port)) { | 1047 | if (tty && tty_port_cts_enabled(&self->port)) { |
1046 | if (tty->hw_stopped) { | 1048 | if (tty->hw_stopped) { |
1047 | if (status & IRCOMM_CTS) { | 1049 | if (status & IRCOMM_CTS) { |
1048 | pr_debug("%s(), CTS tx start...\n", __func__); | 1050 | pr_debug("%s(), CTS tx start...\n", __func__); |
1049 | tty->hw_stopped = 0; | 1051 | tty->hw_stopped = 0; |
1050 | 1052 | ||
1051 | /* Wake up processes blocked on open */ | 1053 | /* Wake up processes blocked on open */ |
1052 | wake_up_interruptible(&self->port.open_wait); | 1054 | wake_up_interruptible(&self->port.open_wait); |
1053 | 1055 | ||
1054 | schedule_work(&self->tqueue); | 1056 | schedule_work(&self->tqueue); |
1055 | goto put; | 1057 | goto put; |
1056 | } | 1058 | } |
1057 | } else { | 1059 | } else { |
1058 | if (!(status & IRCOMM_CTS)) { | 1060 | if (!(status & IRCOMM_CTS)) { |
1059 | pr_debug("%s(), CTS tx stop...\n", __func__); | 1061 | pr_debug("%s(), CTS tx stop...\n", __func__); |
1060 | tty->hw_stopped = 1; | 1062 | tty->hw_stopped = 1; |
1061 | } | 1063 | } |
1062 | } | 1064 | } |
1063 | } | 1065 | } |
1064 | put: | 1066 | put: |
1065 | tty_kref_put(tty); | 1067 | tty_kref_put(tty); |
1066 | } | 1068 | } |
1067 | 1069 | ||
1068 | /* | 1070 | /* |
1069 | * Function ircomm_tty_data_indication (instance, sap, skb) | 1071 | * Function ircomm_tty_data_indication (instance, sap, skb) |
1070 | * | 1072 | * |
1071 | * Handle incoming data, and deliver it to the line discipline | 1073 | * Handle incoming data, and deliver it to the line discipline |
1072 | * | 1074 | * |
1073 | */ | 1075 | */ |
1074 | static int ircomm_tty_data_indication(void *instance, void *sap, | 1076 | static int ircomm_tty_data_indication(void *instance, void *sap, |
1075 | struct sk_buff *skb) | 1077 | struct sk_buff *skb) |
1076 | { | 1078 | { |
1077 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; | 1079 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; |
1078 | struct tty_struct *tty; | 1080 | struct tty_struct *tty; |
1079 | 1081 | ||
1080 | IRDA_ASSERT(self != NULL, return -1;); | 1082 | IRDA_ASSERT(self != NULL, return -1;); |
1081 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 1083 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
1082 | IRDA_ASSERT(skb != NULL, return -1;); | 1084 | IRDA_ASSERT(skb != NULL, return -1;); |
1083 | 1085 | ||
1084 | tty = tty_port_tty_get(&self->port); | 1086 | tty = tty_port_tty_get(&self->port); |
1085 | if (!tty) { | 1087 | if (!tty) { |
1086 | pr_debug("%s(), no tty!\n", __func__); | 1088 | pr_debug("%s(), no tty!\n", __func__); |
1087 | return 0; | 1089 | return 0; |
1088 | } | 1090 | } |
1089 | 1091 | ||
1090 | /* | 1092 | /* |
1091 | * If we receive data when hardware is stopped then something is wrong. | 1093 | * If we receive data when hardware is stopped then something is wrong. |
1092 | * We try to poll the peers line settings to check if we are up todate. | 1094 | * We try to poll the peers line settings to check if we are up todate. |
1093 | * Devices like WinCE can do this, and since they don't send any | 1095 | * Devices like WinCE can do this, and since they don't send any |
1094 | * params, we can just as well declare the hardware for running. | 1096 | * params, we can just as well declare the hardware for running. |
1095 | */ | 1097 | */ |
1096 | if (tty->hw_stopped && (self->flow == FLOW_START)) { | 1098 | if (tty->hw_stopped && (self->flow == FLOW_START)) { |
1097 | pr_debug("%s(), polling for line settings!\n", __func__); | 1099 | pr_debug("%s(), polling for line settings!\n", __func__); |
1098 | ircomm_param_request(self, IRCOMM_POLL, TRUE); | 1100 | ircomm_param_request(self, IRCOMM_POLL, TRUE); |
1099 | 1101 | ||
1100 | /* We can just as well declare the hardware for running */ | 1102 | /* We can just as well declare the hardware for running */ |
1101 | ircomm_tty_send_initial_parameters(self); | 1103 | ircomm_tty_send_initial_parameters(self); |
1102 | ircomm_tty_link_established(self); | 1104 | ircomm_tty_link_established(self); |
1103 | } | 1105 | } |
1104 | tty_kref_put(tty); | 1106 | tty_kref_put(tty); |
1105 | 1107 | ||
1106 | /* | 1108 | /* |
1107 | * Use flip buffer functions since the code may be called from interrupt | 1109 | * Use flip buffer functions since the code may be called from interrupt |
1108 | * context | 1110 | * context |
1109 | */ | 1111 | */ |
1110 | tty_insert_flip_string(&self->port, skb->data, skb->len); | 1112 | tty_insert_flip_string(&self->port, skb->data, skb->len); |
1111 | tty_flip_buffer_push(&self->port); | 1113 | tty_flip_buffer_push(&self->port); |
1112 | 1114 | ||
1113 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ | 1115 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ |
1114 | 1116 | ||
1115 | return 0; | 1117 | return 0; |
1116 | } | 1118 | } |
1117 | 1119 | ||
1118 | /* | 1120 | /* |
1119 | * Function ircomm_tty_control_indication (instance, sap, skb) | 1121 | * Function ircomm_tty_control_indication (instance, sap, skb) |
1120 | * | 1122 | * |
1121 | * Parse all incoming parameters (easy!) | 1123 | * Parse all incoming parameters (easy!) |
1122 | * | 1124 | * |
1123 | */ | 1125 | */ |
1124 | static int ircomm_tty_control_indication(void *instance, void *sap, | 1126 | static int ircomm_tty_control_indication(void *instance, void *sap, |
1125 | struct sk_buff *skb) | 1127 | struct sk_buff *skb) |
1126 | { | 1128 | { |
1127 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; | 1129 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; |
1128 | int clen; | 1130 | int clen; |
1129 | 1131 | ||
1130 | IRDA_ASSERT(self != NULL, return -1;); | 1132 | IRDA_ASSERT(self != NULL, return -1;); |
1131 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 1133 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
1132 | IRDA_ASSERT(skb != NULL, return -1;); | 1134 | IRDA_ASSERT(skb != NULL, return -1;); |
1133 | 1135 | ||
1134 | clen = skb->data[0]; | 1136 | clen = skb->data[0]; |
1135 | 1137 | ||
1136 | irda_param_extract_all(self, skb->data+1, IRDA_MIN(skb->len-1, clen), | 1138 | irda_param_extract_all(self, skb->data+1, IRDA_MIN(skb->len-1, clen), |
1137 | &ircomm_param_info); | 1139 | &ircomm_param_info); |
1138 | 1140 | ||
1139 | /* No need to kfree_skb - see ircomm_control_indication() */ | 1141 | /* No need to kfree_skb - see ircomm_control_indication() */ |
1140 | 1142 | ||
1141 | return 0; | 1143 | return 0; |
1142 | } | 1144 | } |
1143 | 1145 | ||
1144 | /* | 1146 | /* |
1145 | * Function ircomm_tty_flow_indication (instance, sap, cmd) | 1147 | * Function ircomm_tty_flow_indication (instance, sap, cmd) |
1146 | * | 1148 | * |
1147 | * This function is called by IrTTP when it wants us to slow down the | 1149 | * This function is called by IrTTP when it wants us to slow down the |
1148 | * transmission of data. We just mark the hardware as stopped, and wait | 1150 | * transmission of data. We just mark the hardware as stopped, and wait |
1149 | * for IrTTP to notify us that things are OK again. | 1151 | * for IrTTP to notify us that things are OK again. |
1150 | */ | 1152 | */ |
1151 | static void ircomm_tty_flow_indication(void *instance, void *sap, | 1153 | static void ircomm_tty_flow_indication(void *instance, void *sap, |
1152 | LOCAL_FLOW cmd) | 1154 | LOCAL_FLOW cmd) |
1153 | { | 1155 | { |
1154 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; | 1156 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; |
1155 | struct tty_struct *tty; | 1157 | struct tty_struct *tty; |
1156 | 1158 | ||
1157 | IRDA_ASSERT(self != NULL, return;); | 1159 | IRDA_ASSERT(self != NULL, return;); |
1158 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 1160 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
1159 | 1161 | ||
1160 | tty = tty_port_tty_get(&self->port); | 1162 | tty = tty_port_tty_get(&self->port); |
1161 | 1163 | ||
1162 | switch (cmd) { | 1164 | switch (cmd) { |
1163 | case FLOW_START: | 1165 | case FLOW_START: |
1164 | pr_debug("%s(), hw start!\n", __func__); | 1166 | pr_debug("%s(), hw start!\n", __func__); |
1165 | if (tty) | 1167 | if (tty) |
1166 | tty->hw_stopped = 0; | 1168 | tty->hw_stopped = 0; |
1167 | 1169 | ||
1168 | /* ircomm_tty_do_softint will take care of the rest */ | 1170 | /* ircomm_tty_do_softint will take care of the rest */ |
1169 | schedule_work(&self->tqueue); | 1171 | schedule_work(&self->tqueue); |
1170 | break; | 1172 | break; |
1171 | default: /* If we get here, something is very wrong, better stop */ | 1173 | default: /* If we get here, something is very wrong, better stop */ |
1172 | case FLOW_STOP: | 1174 | case FLOW_STOP: |
1173 | pr_debug("%s(), hw stopped!\n", __func__); | 1175 | pr_debug("%s(), hw stopped!\n", __func__); |
1174 | if (tty) | 1176 | if (tty) |
1175 | tty->hw_stopped = 1; | 1177 | tty->hw_stopped = 1; |
1176 | break; | 1178 | break; |
1177 | } | 1179 | } |
1178 | 1180 | ||
1179 | tty_kref_put(tty); | 1181 | tty_kref_put(tty); |
1180 | self->flow = cmd; | 1182 | self->flow = cmd; |
1181 | } | 1183 | } |
1182 | 1184 | ||
1183 | #ifdef CONFIG_PROC_FS | 1185 | #ifdef CONFIG_PROC_FS |
1184 | static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | 1186 | static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) |
1185 | { | 1187 | { |
1186 | struct tty_struct *tty; | 1188 | struct tty_struct *tty; |
1187 | char sep; | 1189 | char sep; |
1188 | 1190 | ||
1189 | seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]); | 1191 | seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]); |
1190 | 1192 | ||
1191 | seq_puts(m, "Service type: "); | 1193 | seq_puts(m, "Service type: "); |
1192 | if (self->service_type & IRCOMM_9_WIRE) | 1194 | if (self->service_type & IRCOMM_9_WIRE) |
1193 | seq_puts(m, "9_WIRE"); | 1195 | seq_puts(m, "9_WIRE"); |
1194 | else if (self->service_type & IRCOMM_3_WIRE) | 1196 | else if (self->service_type & IRCOMM_3_WIRE) |
1195 | seq_puts(m, "3_WIRE"); | 1197 | seq_puts(m, "3_WIRE"); |
1196 | else if (self->service_type & IRCOMM_3_WIRE_RAW) | 1198 | else if (self->service_type & IRCOMM_3_WIRE_RAW) |
1197 | seq_puts(m, "3_WIRE_RAW"); | 1199 | seq_puts(m, "3_WIRE_RAW"); |
1198 | else | 1200 | else |
1199 | seq_puts(m, "No common service type!\n"); | 1201 | seq_puts(m, "No common service type!\n"); |
1200 | seq_putc(m, '\n'); | 1202 | seq_putc(m, '\n'); |
1201 | 1203 | ||
1202 | seq_printf(m, "Port name: %s\n", self->settings.port_name); | 1204 | seq_printf(m, "Port name: %s\n", self->settings.port_name); |
1203 | 1205 | ||
1204 | seq_printf(m, "DTE status:"); | 1206 | seq_printf(m, "DTE status:"); |
1205 | sep = ' '; | 1207 | sep = ' '; |
1206 | if (self->settings.dte & IRCOMM_RTS) { | 1208 | if (self->settings.dte & IRCOMM_RTS) { |
1207 | seq_printf(m, "%cRTS", sep); | 1209 | seq_printf(m, "%cRTS", sep); |
1208 | sep = '|'; | 1210 | sep = '|'; |
1209 | } | 1211 | } |
1210 | if (self->settings.dte & IRCOMM_DTR) { | 1212 | if (self->settings.dte & IRCOMM_DTR) { |
1211 | seq_printf(m, "%cDTR", sep); | 1213 | seq_printf(m, "%cDTR", sep); |
1212 | sep = '|'; | 1214 | sep = '|'; |
1213 | } | 1215 | } |
1214 | seq_putc(m, '\n'); | 1216 | seq_putc(m, '\n'); |
1215 | 1217 | ||
1216 | seq_puts(m, "DCE status:"); | 1218 | seq_puts(m, "DCE status:"); |
1217 | sep = ' '; | 1219 | sep = ' '; |
1218 | if (self->settings.dce & IRCOMM_CTS) { | 1220 | if (self->settings.dce & IRCOMM_CTS) { |
1219 | seq_printf(m, "%cCTS", sep); | 1221 | seq_printf(m, "%cCTS", sep); |
1220 | sep = '|'; | 1222 | sep = '|'; |
1221 | } | 1223 | } |
1222 | if (self->settings.dce & IRCOMM_DSR) { | 1224 | if (self->settings.dce & IRCOMM_DSR) { |
1223 | seq_printf(m, "%cDSR", sep); | 1225 | seq_printf(m, "%cDSR", sep); |
1224 | sep = '|'; | 1226 | sep = '|'; |
1225 | } | 1227 | } |
1226 | if (self->settings.dce & IRCOMM_CD) { | 1228 | if (self->settings.dce & IRCOMM_CD) { |
1227 | seq_printf(m, "%cCD", sep); | 1229 | seq_printf(m, "%cCD", sep); |
1228 | sep = '|'; | 1230 | sep = '|'; |
1229 | } | 1231 | } |
1230 | if (self->settings.dce & IRCOMM_RI) { | 1232 | if (self->settings.dce & IRCOMM_RI) { |
1231 | seq_printf(m, "%cRI", sep); | 1233 | seq_printf(m, "%cRI", sep); |
1232 | sep = '|'; | 1234 | sep = '|'; |
1233 | } | 1235 | } |
1234 | seq_putc(m, '\n'); | 1236 | seq_putc(m, '\n'); |
1235 | 1237 | ||
1236 | seq_puts(m, "Configuration: "); | 1238 | seq_puts(m, "Configuration: "); |
1237 | if (!self->settings.null_modem) | 1239 | if (!self->settings.null_modem) |
1238 | seq_puts(m, "DTE <-> DCE\n"); | 1240 | seq_puts(m, "DTE <-> DCE\n"); |
1239 | else | 1241 | else |
1240 | seq_puts(m, "DTE <-> DTE (null modem emulation)\n"); | 1242 | seq_puts(m, "DTE <-> DTE (null modem emulation)\n"); |
1241 | 1243 | ||
1242 | seq_printf(m, "Data rate: %d\n", self->settings.data_rate); | 1244 | seq_printf(m, "Data rate: %d\n", self->settings.data_rate); |
1243 | 1245 | ||
1244 | seq_puts(m, "Flow control:"); | 1246 | seq_puts(m, "Flow control:"); |
1245 | sep = ' '; | 1247 | sep = ' '; |
1246 | if (self->settings.flow_control & IRCOMM_XON_XOFF_IN) { | 1248 | if (self->settings.flow_control & IRCOMM_XON_XOFF_IN) { |
1247 | seq_printf(m, "%cXON_XOFF_IN", sep); | 1249 | seq_printf(m, "%cXON_XOFF_IN", sep); |
1248 | sep = '|'; | 1250 | sep = '|'; |
1249 | } | 1251 | } |
1250 | if (self->settings.flow_control & IRCOMM_XON_XOFF_OUT) { | 1252 | if (self->settings.flow_control & IRCOMM_XON_XOFF_OUT) { |
1251 | seq_printf(m, "%cXON_XOFF_OUT", sep); | 1253 | seq_printf(m, "%cXON_XOFF_OUT", sep); |
1252 | sep = '|'; | 1254 | sep = '|'; |
1253 | } | 1255 | } |
1254 | if (self->settings.flow_control & IRCOMM_RTS_CTS_IN) { | 1256 | if (self->settings.flow_control & IRCOMM_RTS_CTS_IN) { |
1255 | seq_printf(m, "%cRTS_CTS_IN", sep); | 1257 | seq_printf(m, "%cRTS_CTS_IN", sep); |
1256 | sep = '|'; | 1258 | sep = '|'; |
1257 | } | 1259 | } |
1258 | if (self->settings.flow_control & IRCOMM_RTS_CTS_OUT) { | 1260 | if (self->settings.flow_control & IRCOMM_RTS_CTS_OUT) { |
1259 | seq_printf(m, "%cRTS_CTS_OUT", sep); | 1261 | seq_printf(m, "%cRTS_CTS_OUT", sep); |
1260 | sep = '|'; | 1262 | sep = '|'; |
1261 | } | 1263 | } |
1262 | if (self->settings.flow_control & IRCOMM_DSR_DTR_IN) { | 1264 | if (self->settings.flow_control & IRCOMM_DSR_DTR_IN) { |
1263 | seq_printf(m, "%cDSR_DTR_IN", sep); | 1265 | seq_printf(m, "%cDSR_DTR_IN", sep); |
1264 | sep = '|'; | 1266 | sep = '|'; |
1265 | } | 1267 | } |
1266 | if (self->settings.flow_control & IRCOMM_DSR_DTR_OUT) { | 1268 | if (self->settings.flow_control & IRCOMM_DSR_DTR_OUT) { |
1267 | seq_printf(m, "%cDSR_DTR_OUT", sep); | 1269 | seq_printf(m, "%cDSR_DTR_OUT", sep); |
1268 | sep = '|'; | 1270 | sep = '|'; |
1269 | } | 1271 | } |
1270 | if (self->settings.flow_control & IRCOMM_ENQ_ACK_IN) { | 1272 | if (self->settings.flow_control & IRCOMM_ENQ_ACK_IN) { |
1271 | seq_printf(m, "%cENQ_ACK_IN", sep); | 1273 | seq_printf(m, "%cENQ_ACK_IN", sep); |
1272 | sep = '|'; | 1274 | sep = '|'; |
1273 | } | 1275 | } |
1274 | if (self->settings.flow_control & IRCOMM_ENQ_ACK_OUT) { | 1276 | if (self->settings.flow_control & IRCOMM_ENQ_ACK_OUT) { |
1275 | seq_printf(m, "%cENQ_ACK_OUT", sep); | 1277 | seq_printf(m, "%cENQ_ACK_OUT", sep); |
1276 | sep = '|'; | 1278 | sep = '|'; |
1277 | } | 1279 | } |
1278 | seq_putc(m, '\n'); | 1280 | seq_putc(m, '\n'); |
1279 | 1281 | ||
1280 | seq_puts(m, "Flags:"); | 1282 | seq_puts(m, "Flags:"); |
1281 | sep = ' '; | 1283 | sep = ' '; |
1282 | if (tty_port_cts_enabled(&self->port)) { | 1284 | if (tty_port_cts_enabled(&self->port)) { |
1283 | seq_printf(m, "%cASYNC_CTS_FLOW", sep); | 1285 | seq_printf(m, "%cASYNC_CTS_FLOW", sep); |
1284 | sep = '|'; | 1286 | sep = '|'; |
1285 | } | 1287 | } |
1286 | if (self->port.flags & ASYNC_CHECK_CD) { | 1288 | if (self->port.flags & ASYNC_CHECK_CD) { |
1287 | seq_printf(m, "%cASYNC_CHECK_CD", sep); | 1289 | seq_printf(m, "%cASYNC_CHECK_CD", sep); |
1288 | sep = '|'; | 1290 | sep = '|'; |
1289 | } | 1291 | } |
1290 | if (self->port.flags & ASYNC_INITIALIZED) { | 1292 | if (self->port.flags & ASYNC_INITIALIZED) { |
1291 | seq_printf(m, "%cASYNC_INITIALIZED", sep); | 1293 | seq_printf(m, "%cASYNC_INITIALIZED", sep); |
1292 | sep = '|'; | 1294 | sep = '|'; |
1293 | } | 1295 | } |
1294 | if (self->port.flags & ASYNC_LOW_LATENCY) { | 1296 | if (self->port.flags & ASYNC_LOW_LATENCY) { |
1295 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); | 1297 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); |
1296 | sep = '|'; | 1298 | sep = '|'; |
1297 | } | 1299 | } |
1298 | if (self->port.flags & ASYNC_CLOSING) { | 1300 | if (self->port.flags & ASYNC_CLOSING) { |
1299 | seq_printf(m, "%cASYNC_CLOSING", sep); | 1301 | seq_printf(m, "%cASYNC_CLOSING", sep); |
1300 | sep = '|'; | 1302 | sep = '|'; |
1301 | } | 1303 | } |
1302 | if (self->port.flags & ASYNC_NORMAL_ACTIVE) { | 1304 | if (self->port.flags & ASYNC_NORMAL_ACTIVE) { |
1303 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); | 1305 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); |
1304 | sep = '|'; | 1306 | sep = '|'; |
1305 | } | 1307 | } |
1306 | seq_putc(m, '\n'); | 1308 | seq_putc(m, '\n'); |
1307 | 1309 | ||
1308 | seq_printf(m, "Role: %s\n", self->client ? "client" : "server"); | 1310 | seq_printf(m, "Role: %s\n", self->client ? "client" : "server"); |
1309 | seq_printf(m, "Open count: %d\n", self->port.count); | 1311 | seq_printf(m, "Open count: %d\n", self->port.count); |
1310 | seq_printf(m, "Max data size: %d\n", self->max_data_size); | 1312 | seq_printf(m, "Max data size: %d\n", self->max_data_size); |
1311 | seq_printf(m, "Max header size: %d\n", self->max_header_size); | 1313 | seq_printf(m, "Max header size: %d\n", self->max_header_size); |
1312 | 1314 | ||
1313 | tty = tty_port_tty_get(&self->port); | 1315 | tty = tty_port_tty_get(&self->port); |
1314 | if (tty) { | 1316 | if (tty) { |
1315 | seq_printf(m, "Hardware: %s\n", | 1317 | seq_printf(m, "Hardware: %s\n", |
1316 | tty->hw_stopped ? "Stopped" : "Running"); | 1318 | tty->hw_stopped ? "Stopped" : "Running"); |
1317 | tty_kref_put(tty); | 1319 | tty_kref_put(tty); |
1318 | } | 1320 | } |
1319 | } | 1321 | } |
1320 | 1322 | ||
1321 | static int ircomm_tty_proc_show(struct seq_file *m, void *v) | 1323 | static int ircomm_tty_proc_show(struct seq_file *m, void *v) |
1322 | { | 1324 | { |
1323 | struct ircomm_tty_cb *self; | 1325 | struct ircomm_tty_cb *self; |
1324 | unsigned long flags; | 1326 | unsigned long flags; |
1325 | 1327 | ||
1326 | spin_lock_irqsave(&ircomm_tty->hb_spinlock, flags); | 1328 | spin_lock_irqsave(&ircomm_tty->hb_spinlock, flags); |
1327 | 1329 | ||
1328 | self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty); | 1330 | self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty); |
1329 | while (self != NULL) { | 1331 | while (self != NULL) { |
1330 | if (self->magic != IRCOMM_TTY_MAGIC) | 1332 | if (self->magic != IRCOMM_TTY_MAGIC) |
1331 | break; | 1333 | break; |
1332 | 1334 | ||
1333 | ircomm_tty_line_info(self, m); | 1335 | ircomm_tty_line_info(self, m); |
1334 | self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty); | 1336 | self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty); |
1335 | } | 1337 | } |
1336 | spin_unlock_irqrestore(&ircomm_tty->hb_spinlock, flags); | 1338 | spin_unlock_irqrestore(&ircomm_tty->hb_spinlock, flags); |
1337 | return 0; | 1339 | return 0; |
1338 | } | 1340 | } |
1339 | 1341 | ||
1340 | static int ircomm_tty_proc_open(struct inode *inode, struct file *file) | 1342 | static int ircomm_tty_proc_open(struct inode *inode, struct file *file) |
1341 | { | 1343 | { |
1342 | return single_open(file, ircomm_tty_proc_show, NULL); | 1344 | return single_open(file, ircomm_tty_proc_show, NULL); |
1343 | } | 1345 | } |
1344 | 1346 | ||
1345 | static const struct file_operations ircomm_tty_proc_fops = { | 1347 | static const struct file_operations ircomm_tty_proc_fops = { |
1346 | .owner = THIS_MODULE, | 1348 | .owner = THIS_MODULE, |
1347 | .open = ircomm_tty_proc_open, | 1349 | .open = ircomm_tty_proc_open, |
1348 | .read = seq_read, | 1350 | .read = seq_read, |
1349 | .llseek = seq_lseek, | 1351 | .llseek = seq_lseek, |
1350 | .release = single_release, | 1352 | .release = single_release, |
1351 | }; | 1353 | }; |
1352 | #endif /* CONFIG_PROC_FS */ | 1354 | #endif /* CONFIG_PROC_FS */ |
1353 | 1355 | ||
1354 | MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); | 1356 | MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); |
1355 | MODULE_DESCRIPTION("IrCOMM serial TTY driver"); | 1357 | MODULE_DESCRIPTION("IrCOMM serial TTY driver"); |
1356 | MODULE_LICENSE("GPL"); | 1358 | MODULE_LICENSE("GPL"); |
1357 | MODULE_ALIAS_CHARDEV_MAJOR(IRCOMM_TTY_MAJOR); | 1359 | MODULE_ALIAS_CHARDEV_MAJOR(IRCOMM_TTY_MAJOR); |
1358 | 1360 | ||
1359 | module_init(ircomm_tty_init); | 1361 | module_init(ircomm_tty_init); |
1360 | module_exit(ircomm_tty_cleanup); | 1362 | module_exit(ircomm_tty_cleanup); |
1361 | 1363 |