diff options
Diffstat (limited to 'arch/ia64')
26 files changed, 235 insertions, 686 deletions
diff --git a/arch/ia64/hp/sim/boot/fw-emu.c b/arch/ia64/hp/sim/boot/fw-emu.c index bf6d9d8c802f..0216e28300fa 100644 --- a/arch/ia64/hp/sim/boot/fw-emu.c +++ b/arch/ia64/hp/sim/boot/fw-emu.c | |||
@@ -160,28 +160,19 @@ sal_emulator (long index, unsigned long in1, unsigned long in2, | |||
160 | */ | 160 | */ |
161 | status = 0; | 161 | status = 0; |
162 | if (index == SAL_FREQ_BASE) { | 162 | if (index == SAL_FREQ_BASE) { |
163 | switch (in1) { | 163 | if (in1 == SAL_FREQ_BASE_PLATFORM) |
164 | case SAL_FREQ_BASE_PLATFORM: | ||
165 | r9 = 200000000; | 164 | r9 = 200000000; |
166 | break; | 165 | else if (in1 == SAL_FREQ_BASE_INTERVAL_TIMER) { |
167 | |||
168 | case SAL_FREQ_BASE_INTERVAL_TIMER: | ||
169 | /* | 166 | /* |
170 | * Is this supposed to be the cr.itc frequency | 167 | * Is this supposed to be the cr.itc frequency |
171 | * or something platform specific? The SAL | 168 | * or something platform specific? The SAL |
172 | * doc ain't exactly clear on this... | 169 | * doc ain't exactly clear on this... |
173 | */ | 170 | */ |
174 | r9 = 700000000; | 171 | r9 = 700000000; |
175 | break; | 172 | } else if (in1 == SAL_FREQ_BASE_REALTIME_CLOCK) |
176 | |||
177 | case SAL_FREQ_BASE_REALTIME_CLOCK: | ||
178 | r9 = 1; | 173 | r9 = 1; |
179 | break; | 174 | else |
180 | |||
181 | default: | ||
182 | status = -1; | 175 | status = -1; |
183 | break; | ||
184 | } | ||
185 | } else if (index == SAL_SET_VECTORS) { | 176 | } else if (index == SAL_SET_VECTORS) { |
186 | ; | 177 | ; |
187 | } else if (index == SAL_GET_STATE_INFO) { | 178 | } else if (index == SAL_GET_STATE_INFO) { |
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c index 4bd9a63260ee..0aa70ebda49d 100644 --- a/arch/ia64/hp/sim/hpsim_irq.c +++ b/arch/ia64/hp/sim/hpsim_irq.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | 12 | ||
13 | #include "hpsim_ssc.h" | ||
14 | |||
13 | static unsigned int | 15 | static unsigned int |
14 | hpsim_irq_startup(struct irq_data *data) | 16 | hpsim_irq_startup(struct irq_data *data) |
15 | { | 17 | { |
@@ -37,15 +39,37 @@ static struct irq_chip irq_type_hp_sim = { | |||
37 | .irq_set_affinity = hpsim_set_affinity_noop, | 39 | .irq_set_affinity = hpsim_set_affinity_noop, |
38 | }; | 40 | }; |
39 | 41 | ||
42 | static void hpsim_irq_set_chip(int irq) | ||
43 | { | ||
44 | struct irq_chip *chip = irq_get_chip(irq); | ||
45 | |||
46 | if (chip == &no_irq_chip) | ||
47 | irq_set_chip(irq, &irq_type_hp_sim); | ||
48 | } | ||
49 | |||
50 | static void hpsim_connect_irq(int intr, int irq) | ||
51 | { | ||
52 | ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT); | ||
53 | } | ||
54 | |||
55 | int hpsim_get_irq(int intr) | ||
56 | { | ||
57 | int irq = assign_irq_vector(AUTO_ASSIGN); | ||
58 | |||
59 | if (irq >= 0) { | ||
60 | hpsim_irq_set_chip(irq); | ||
61 | irq_set_handler(irq, handle_simple_irq); | ||
62 | hpsim_connect_irq(intr, irq); | ||
63 | } | ||
64 | |||
65 | return irq; | ||
66 | } | ||
67 | |||
40 | void __init | 68 | void __init |
41 | hpsim_irq_init (void) | 69 | hpsim_irq_init (void) |
42 | { | 70 | { |
43 | int i; | 71 | int i; |
44 | 72 | ||
45 | for_each_active_irq(i) { | 73 | for_each_active_irq(i) |
46 | struct irq_chip *chip = irq_get_chip(i); | 74 | hpsim_irq_set_chip(i); |
47 | |||
48 | if (chip == &no_irq_chip) | ||
49 | irq_set_chip(i, &irq_type_hp_sim); | ||
50 | } | ||
51 | } | 75 | } |
diff --git a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c index f629e903ebc7..664a5402a695 100644 --- a/arch/ia64/hp/sim/hpsim_setup.c +++ b/arch/ia64/hp/sim/hpsim_setup.c | |||
@@ -26,12 +26,6 @@ | |||
26 | #include "hpsim_ssc.h" | 26 | #include "hpsim_ssc.h" |
27 | 27 | ||
28 | void | 28 | void |
29 | ia64_ssc_connect_irq (long intr, long irq) | ||
30 | { | ||
31 | ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT); | ||
32 | } | ||
33 | |||
34 | void | ||
35 | ia64_ctl_trace (long on) | 29 | ia64_ctl_trace (long on) |
36 | { | 30 | { |
37 | ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE); | 31 | ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE); |
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index 47afcc61f6e5..a63218e1f6c9 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c | |||
@@ -129,17 +129,6 @@ netdev_probe(char *name, unsigned char *ether) | |||
129 | 129 | ||
130 | 130 | ||
131 | static inline int | 131 | static inline int |
132 | netdev_connect(int irq) | ||
133 | { | ||
134 | /* XXX Fix me | ||
135 | * this does not support multiple cards | ||
136 | * also no return value | ||
137 | */ | ||
138 | ia64_ssc_connect_irq(NETWORK_INTR, irq); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static inline int | ||
143 | netdev_attach(int fd, int irq, unsigned int ipaddr) | 132 | netdev_attach(int fd, int irq, unsigned int ipaddr) |
144 | { | 133 | { |
145 | /* this puts the host interface in the right mode (start interrupting) */ | 134 | /* this puts the host interface in the right mode (start interrupting) */ |
@@ -193,7 +182,7 @@ simeth_probe1(void) | |||
193 | unsigned char mac_addr[ETH_ALEN]; | 182 | unsigned char mac_addr[ETH_ALEN]; |
194 | struct simeth_local *local; | 183 | struct simeth_local *local; |
195 | struct net_device *dev; | 184 | struct net_device *dev; |
196 | int fd, i, err, rc; | 185 | int fd, err, rc; |
197 | 186 | ||
198 | /* | 187 | /* |
199 | * XXX Fix me | 188 | * XXX Fix me |
@@ -226,22 +215,16 @@ simeth_probe1(void) | |||
226 | return err; | 215 | return err; |
227 | } | 216 | } |
228 | 217 | ||
229 | if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) | ||
230 | panic("%s: out of interrupt vectors!\n", __func__); | ||
231 | dev->irq = rc; | ||
232 | |||
233 | /* | 218 | /* |
234 | * attach the interrupt in the simulator, this does enable interrupts | 219 | * attach the interrupt in the simulator, this does enable interrupts |
235 | * until a netdev_attach() is called | 220 | * until a netdev_attach() is called |
236 | */ | 221 | */ |
237 | netdev_connect(dev->irq); | 222 | if ((rc = hpsim_get_irq(NETWORK_INTR)) < 0) |
223 | panic("%s: out of interrupt vectors!\n", __func__); | ||
224 | dev->irq = rc; | ||
238 | 225 | ||
239 | printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr", | 226 | printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr=%pm, IRQ %d\n", |
240 | dev->name, simeth_device, local->simfd); | 227 | dev->name, simeth_device, local->simfd, dev->dev_addr, dev->irq); |
241 | for(i = 0; i < ETH_ALEN; i++) { | ||
242 | printk(" %2.2x", dev->dev_addr[i]); | ||
243 | } | ||
244 | printk(", IRQ %d\n", dev->irq); | ||
245 | 228 | ||
246 | return 0; | 229 | return 0; |
247 | } | 230 | } |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index bff0824cf8a4..c34785dca92b 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -4,16 +4,11 @@ | |||
4 | * This driver is mostly used for bringup purposes and will go away. | 4 | * This driver is mostly used for bringup purposes and will go away. |
5 | * It has a strong dependency on the system console. All outputs | 5 | * It has a strong dependency on the system console. All outputs |
6 | * are rerouted to the same facility as the one used by printk which, in our | 6 | * are rerouted to the same facility as the one used by printk which, in our |
7 | * case means sys_sim.c console (goes via the simulator). The code hereafter | 7 | * case means sys_sim.c console (goes via the simulator). |
8 | * is completely leveraged from the serial.c driver. | ||
9 | * | 8 | * |
10 | * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co | 9 | * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co |
11 | * Stephane Eranian <eranian@hpl.hp.com> | 10 | * Stephane Eranian <eranian@hpl.hp.com> |
12 | * David Mosberger-Tang <davidm@hpl.hp.com> | 11 | * David Mosberger-Tang <davidm@hpl.hp.com> |
13 | * | ||
14 | * 02/04/00 D. Mosberger Merged in serial.c bug fixes in rs_close(). | ||
15 | * 02/25/00 D. Mosberger Synced up with 2.3.99pre-5 version of serial.c. | ||
16 | * 07/30/02 D. Mosberger Replace sti()/cli() with explicit spinlocks & local irq masking | ||
17 | */ | 12 | */ |
18 | 13 | ||
19 | #include <linux/init.h> | 14 | #include <linux/init.h> |
@@ -27,15 +22,17 @@ | |||
27 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
28 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
29 | #include <linux/capability.h> | 24 | #include <linux/capability.h> |
25 | #include <linux/circ_buf.h> | ||
30 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/irq.h> | ||
31 | #include <linux/module.h> | 28 | #include <linux/module.h> |
32 | #include <linux/serial.h> | 29 | #include <linux/serial.h> |
33 | #include <linux/serialP.h> | ||
34 | #include <linux/sysrq.h> | 30 | #include <linux/sysrq.h> |
31 | #include <linux/uaccess.h> | ||
32 | |||
33 | #include <asm/hpsim.h> | ||
35 | 34 | ||
36 | #include <asm/irq.h> | 35 | #include "hpsim_ssc.h" |
37 | #include <asm/hw_irq.h> | ||
38 | #include <asm/uaccess.h> | ||
39 | 36 | ||
40 | #undef SIMSERIAL_DEBUG /* define this to get some debug information */ | 37 | #undef SIMSERIAL_DEBUG /* define this to get some debug information */ |
41 | 38 | ||
@@ -43,118 +40,44 @@ | |||
43 | 40 | ||
44 | #define NR_PORTS 1 /* only one port for now */ | 41 | #define NR_PORTS 1 /* only one port for now */ |
45 | 42 | ||
46 | #define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : IRQF_DISABLED) | 43 | struct serial_state { |
47 | 44 | struct tty_port port; | |
48 | #define SSC_GETCHAR 21 | 45 | struct circ_buf xmit; |
49 | 46 | int irq; | |
50 | extern long ia64_ssc (long, long, long, long, int); | 47 | int x_char; |
51 | extern void ia64_ssc_connect_irq (long intr, long irq); | ||
52 | |||
53 | static char *serial_name = "SimSerial driver"; | ||
54 | static char *serial_version = "0.6"; | ||
55 | |||
56 | /* | ||
57 | * This has been extracted from asm/serial.h. We need one eventually but | ||
58 | * I don't know exactly what we're going to put in it so just fake one | ||
59 | * for now. | ||
60 | */ | ||
61 | #define BASE_BAUD ( 1843200 / 16 ) | ||
62 | |||
63 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | ||
64 | |||
65 | /* | ||
66 | * Most of the values here are meaningless to this particular driver. | ||
67 | * However some values must be preserved for the code (leveraged from serial.c | ||
68 | * to work correctly). | ||
69 | * port must not be 0 | ||
70 | * type must not be UNKNOWN | ||
71 | * So I picked arbitrary (guess from where?) values instead | ||
72 | */ | ||
73 | static struct serial_state rs_table[NR_PORTS]={ | ||
74 | /* UART CLK PORT IRQ FLAGS */ | ||
75 | { 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 } /* ttyS0 */ | ||
76 | }; | 48 | }; |
77 | 49 | ||
78 | /* | 50 | static struct serial_state rs_table[NR_PORTS]; |
79 | * Just for the fun of it ! | ||
80 | */ | ||
81 | static struct serial_uart_config uart_config[] = { | ||
82 | { "unknown", 1, 0 }, | ||
83 | { "8250", 1, 0 }, | ||
84 | { "16450", 1, 0 }, | ||
85 | { "16550", 1, 0 }, | ||
86 | { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, | ||
87 | { "cirrus", 1, 0 }, | ||
88 | { "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH }, | ||
89 | { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO | | ||
90 | UART_STARTECH }, | ||
91 | { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO}, | ||
92 | { NULL, 0} | ||
93 | }; | ||
94 | 51 | ||
95 | struct tty_driver *hp_simserial_driver; | 52 | struct tty_driver *hp_simserial_driver; |
96 | 53 | ||
97 | static struct async_struct *IRQ_ports[NR_IRQS]; | ||
98 | |||
99 | static struct console *console; | 54 | static struct console *console; |
100 | 55 | ||
101 | static unsigned char *tmp_buf; | 56 | static void receive_chars(struct tty_struct *tty) |
102 | |||
103 | extern struct console *console_drivers; /* from kernel/printk.c */ | ||
104 | |||
105 | /* | ||
106 | * ------------------------------------------------------------ | ||
107 | * rs_stop() and rs_start() | ||
108 | * | ||
109 | * This routines are called before setting or resetting tty->stopped. | ||
110 | * They enable or disable transmitter interrupts, as necessary. | ||
111 | * ------------------------------------------------------------ | ||
112 | */ | ||
113 | static void rs_stop(struct tty_struct *tty) | ||
114 | { | ||
115 | #ifdef SIMSERIAL_DEBUG | ||
116 | printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n", | ||
117 | tty->stopped, tty->hw_stopped, tty->flow_stopped); | ||
118 | #endif | ||
119 | |||
120 | } | ||
121 | |||
122 | static void rs_start(struct tty_struct *tty) | ||
123 | { | ||
124 | #ifdef SIMSERIAL_DEBUG | ||
125 | printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n", | ||
126 | tty->stopped, tty->hw_stopped, tty->flow_stopped); | ||
127 | #endif | ||
128 | } | ||
129 | |||
130 | static void receive_chars(struct tty_struct *tty) | ||
131 | { | 57 | { |
132 | unsigned char ch; | 58 | unsigned char ch; |
133 | static unsigned char seen_esc = 0; | 59 | static unsigned char seen_esc = 0; |
134 | 60 | ||
135 | while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) { | 61 | while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) { |
136 | if ( ch == 27 && seen_esc == 0 ) { | 62 | if (ch == 27 && seen_esc == 0) { |
137 | seen_esc = 1; | 63 | seen_esc = 1; |
138 | continue; | 64 | continue; |
139 | } else { | 65 | } else if (seen_esc == 1 && ch == 'O') { |
140 | if ( seen_esc==1 && ch == 'O' ) { | 66 | seen_esc = 2; |
141 | seen_esc = 2; | 67 | continue; |
142 | continue; | 68 | } else if (seen_esc == 2) { |
143 | } else if ( seen_esc == 2 ) { | 69 | if (ch == 'P') /* F1 */ |
144 | if ( ch == 'P' ) /* F1 */ | 70 | show_state(); |
145 | show_state(); | ||
146 | #ifdef CONFIG_MAGIC_SYSRQ | 71 | #ifdef CONFIG_MAGIC_SYSRQ |
147 | if ( ch == 'S' ) { /* F4 */ | 72 | if (ch == 'S') { /* F4 */ |
148 | do | 73 | do { |
149 | ch = ia64_ssc(0, 0, 0, 0, | 74 | ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR); |
150 | SSC_GETCHAR); | 75 | } while (!ch); |
151 | while (!ch); | 76 | handle_sysrq(ch); |
152 | handle_sysrq(ch); | ||
153 | } | ||
154 | #endif | ||
155 | seen_esc = 0; | ||
156 | continue; | ||
157 | } | 77 | } |
78 | #endif | ||
79 | seen_esc = 0; | ||
80 | continue; | ||
158 | } | 81 | } |
159 | seen_esc = 0; | 82 | seen_esc = 0; |
160 | 83 | ||
@@ -169,22 +92,19 @@ static void receive_chars(struct tty_struct *tty) | |||
169 | */ | 92 | */ |
170 | static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | 93 | static irqreturn_t rs_interrupt_single(int irq, void *dev_id) |
171 | { | 94 | { |
172 | struct async_struct * info; | 95 | struct serial_state *info = dev_id; |
96 | struct tty_struct *tty = tty_port_tty_get(&info->port); | ||
173 | 97 | ||
174 | /* | 98 | if (!tty) { |
175 | * I don't know exactly why they don't use the dev_id opaque data | 99 | printk(KERN_INFO "%s: tty=0 problem\n", __func__); |
176 | * pointer instead of this extra lookup table | ||
177 | */ | ||
178 | info = IRQ_ports[irq]; | ||
179 | if (!info || !info->tty) { | ||
180 | printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info); | ||
181 | return IRQ_NONE; | 100 | return IRQ_NONE; |
182 | } | 101 | } |
183 | /* | 102 | /* |
184 | * pretty simple in our case, because we only get interrupts | 103 | * pretty simple in our case, because we only get interrupts |
185 | * on inbound traffic | 104 | * on inbound traffic |
186 | */ | 105 | */ |
187 | receive_chars(info->tty); | 106 | receive_chars(tty); |
107 | tty_kref_put(tty); | ||
188 | return IRQ_HANDLED; | 108 | return IRQ_HANDLED; |
189 | } | 109 | } |
190 | 110 | ||
@@ -194,17 +114,12 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | |||
194 | * ------------------------------------------------------------------- | 114 | * ------------------------------------------------------------------- |
195 | */ | 115 | */ |
196 | 116 | ||
197 | static void do_softint(struct work_struct *private_) | ||
198 | { | ||
199 | printk(KERN_ERR "simserial: do_softint called\n"); | ||
200 | } | ||
201 | |||
202 | static int rs_put_char(struct tty_struct *tty, unsigned char ch) | 117 | static int rs_put_char(struct tty_struct *tty, unsigned char ch) |
203 | { | 118 | { |
204 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 119 | struct serial_state *info = tty->driver_data; |
205 | unsigned long flags; | 120 | unsigned long flags; |
206 | 121 | ||
207 | if (!tty || !info->xmit.buf) | 122 | if (!info->xmit.buf) |
208 | return 0; | 123 | return 0; |
209 | 124 | ||
210 | local_irq_save(flags); | 125 | local_irq_save(flags); |
@@ -218,12 +133,12 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch) | |||
218 | return 1; | 133 | return 1; |
219 | } | 134 | } |
220 | 135 | ||
221 | static void transmit_chars(struct async_struct *info, int *intr_done) | 136 | static void transmit_chars(struct tty_struct *tty, struct serial_state *info, |
137 | int *intr_done) | ||
222 | { | 138 | { |
223 | int count; | 139 | int count; |
224 | unsigned long flags; | 140 | unsigned long flags; |
225 | 141 | ||
226 | |||
227 | local_irq_save(flags); | 142 | local_irq_save(flags); |
228 | 143 | ||
229 | if (info->x_char) { | 144 | if (info->x_char) { |
@@ -231,16 +146,16 @@ static void transmit_chars(struct async_struct *info, int *intr_done) | |||
231 | 146 | ||
232 | console->write(console, &c, 1); | 147 | console->write(console, &c, 1); |
233 | 148 | ||
234 | info->state->icount.tx++; | ||
235 | info->x_char = 0; | 149 | info->x_char = 0; |
236 | 150 | ||
237 | goto out; | 151 | goto out; |
238 | } | 152 | } |
239 | 153 | ||
240 | if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) { | 154 | if (info->xmit.head == info->xmit.tail || tty->stopped || |
155 | tty->hw_stopped) { | ||
241 | #ifdef SIMSERIAL_DEBUG | 156 | #ifdef SIMSERIAL_DEBUG |
242 | printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", | 157 | printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", |
243 | info->xmit.head, info->xmit.tail, info->tty->stopped); | 158 | info->xmit.head, info->xmit.tail, tty->stopped); |
244 | #endif | 159 | #endif |
245 | goto out; | 160 | goto out; |
246 | } | 161 | } |
@@ -272,24 +187,24 @@ out: | |||
272 | 187 | ||
273 | static void rs_flush_chars(struct tty_struct *tty) | 188 | static void rs_flush_chars(struct tty_struct *tty) |
274 | { | 189 | { |
275 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 190 | struct serial_state *info = tty->driver_data; |
276 | 191 | ||
277 | if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped || | 192 | if (info->xmit.head == info->xmit.tail || tty->stopped || |
278 | !info->xmit.buf) | 193 | tty->hw_stopped || !info->xmit.buf) |
279 | return; | 194 | return; |
280 | 195 | ||
281 | transmit_chars(info, NULL); | 196 | transmit_chars(tty, info, NULL); |
282 | } | 197 | } |
283 | 198 | ||
284 | |||
285 | static int rs_write(struct tty_struct * tty, | 199 | static int rs_write(struct tty_struct * tty, |
286 | const unsigned char *buf, int count) | 200 | const unsigned char *buf, int count) |
287 | { | 201 | { |
202 | struct serial_state *info = tty->driver_data; | ||
288 | int c, ret = 0; | 203 | int c, ret = 0; |
289 | struct async_struct *info = (struct async_struct *)tty->driver_data; | ||
290 | unsigned long flags; | 204 | unsigned long flags; |
291 | 205 | ||
292 | if (!tty || !info->xmit.buf || !tmp_buf) return 0; | 206 | if (!info->xmit.buf) |
207 | return 0; | ||
293 | 208 | ||
294 | local_irq_save(flags); | 209 | local_irq_save(flags); |
295 | while (1) { | 210 | while (1) { |
@@ -310,30 +225,30 @@ static int rs_write(struct tty_struct * tty, | |||
310 | /* | 225 | /* |
311 | * Hey, we transmit directly from here in our case | 226 | * Hey, we transmit directly from here in our case |
312 | */ | 227 | */ |
313 | if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) | 228 | if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) && |
314 | && !tty->stopped && !tty->hw_stopped) { | 229 | !tty->stopped && !tty->hw_stopped) |
315 | transmit_chars(info, NULL); | 230 | transmit_chars(tty, info, NULL); |
316 | } | 231 | |
317 | return ret; | 232 | return ret; |
318 | } | 233 | } |
319 | 234 | ||
320 | static int rs_write_room(struct tty_struct *tty) | 235 | static int rs_write_room(struct tty_struct *tty) |
321 | { | 236 | { |
322 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 237 | struct serial_state *info = tty->driver_data; |
323 | 238 | ||
324 | return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); | 239 | return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); |
325 | } | 240 | } |
326 | 241 | ||
327 | static int rs_chars_in_buffer(struct tty_struct *tty) | 242 | static int rs_chars_in_buffer(struct tty_struct *tty) |
328 | { | 243 | { |
329 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 244 | struct serial_state *info = tty->driver_data; |
330 | 245 | ||
331 | return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); | 246 | return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); |
332 | } | 247 | } |
333 | 248 | ||
334 | static void rs_flush_buffer(struct tty_struct *tty) | 249 | static void rs_flush_buffer(struct tty_struct *tty) |
335 | { | 250 | { |
336 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 251 | struct serial_state *info = tty->driver_data; |
337 | unsigned long flags; | 252 | unsigned long flags; |
338 | 253 | ||
339 | local_irq_save(flags); | 254 | local_irq_save(flags); |
@@ -349,7 +264,7 @@ static void rs_flush_buffer(struct tty_struct *tty) | |||
349 | */ | 264 | */ |
350 | static void rs_send_xchar(struct tty_struct *tty, char ch) | 265 | static void rs_send_xchar(struct tty_struct *tty, char ch) |
351 | { | 266 | { |
352 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 267 | struct serial_state *info = tty->driver_data; |
353 | 268 | ||
354 | info->x_char = ch; | 269 | info->x_char = ch; |
355 | if (ch) { | 270 | if (ch) { |
@@ -357,7 +272,7 @@ static void rs_send_xchar(struct tty_struct *tty, char ch) | |||
357 | * I guess we could call console->write() directly but | 272 | * I guess we could call console->write() directly but |
358 | * let's do that for now. | 273 | * let's do that for now. |
359 | */ | 274 | */ |
360 | transmit_chars(info, NULL); | 275 | transmit_chars(tty, info, NULL); |
361 | } | 276 | } |
362 | } | 277 | } |
363 | 278 | ||
@@ -371,14 +286,15 @@ static void rs_send_xchar(struct tty_struct *tty, char ch) | |||
371 | */ | 286 | */ |
372 | static void rs_throttle(struct tty_struct * tty) | 287 | static void rs_throttle(struct tty_struct * tty) |
373 | { | 288 | { |
374 | if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); | 289 | if (I_IXOFF(tty)) |
290 | rs_send_xchar(tty, STOP_CHAR(tty)); | ||
375 | 291 | ||
376 | printk(KERN_INFO "simrs_throttle called\n"); | 292 | printk(KERN_INFO "simrs_throttle called\n"); |
377 | } | 293 | } |
378 | 294 | ||
379 | static void rs_unthrottle(struct tty_struct * tty) | 295 | static void rs_unthrottle(struct tty_struct * tty) |
380 | { | 296 | { |
381 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 297 | struct serial_state *info = tty->driver_data; |
382 | 298 | ||
383 | if (I_IXOFF(tty)) { | 299 | if (I_IXOFF(tty)) { |
384 | if (info->x_char) | 300 | if (info->x_char) |
@@ -389,7 +305,6 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
389 | printk(KERN_INFO "simrs_unthrottle called\n"); | 305 | printk(KERN_INFO "simrs_unthrottle called\n"); |
390 | } | 306 | } |
391 | 307 | ||
392 | |||
393 | static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) | 308 | static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) |
394 | { | 309 | { |
395 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 310 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
@@ -400,48 +315,21 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) | |||
400 | } | 315 | } |
401 | 316 | ||
402 | switch (cmd) { | 317 | switch (cmd) { |
403 | case TIOCGSERIAL: | 318 | case TIOCGSERIAL: |
404 | printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n"); | 319 | case TIOCSSERIAL: |
405 | return 0; | 320 | case TIOCSERGSTRUCT: |
406 | case TIOCSSERIAL: | 321 | case TIOCMIWAIT: |
407 | printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n"); | 322 | return 0; |
408 | return 0; | 323 | case TIOCSERCONFIG: |
409 | case TIOCSERCONFIG: | 324 | case TIOCSERGETLSR: /* Get line status register */ |
410 | printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n"); | 325 | return -EINVAL; |
411 | return -EINVAL; | 326 | case TIOCSERGWILD: |
412 | 327 | case TIOCSERSWILD: | |
413 | case TIOCSERGETLSR: /* Get line status register */ | 328 | /* "setserial -W" is called in Debian boot */ |
414 | printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n"); | 329 | printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n"); |
415 | return -EINVAL; | 330 | return 0; |
416 | 331 | } | |
417 | case TIOCSERGSTRUCT: | 332 | return -ENOIOCTLCMD; |
418 | printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n"); | ||
419 | #if 0 | ||
420 | if (copy_to_user((struct async_struct *) arg, | ||
421 | info, sizeof(struct async_struct))) | ||
422 | return -EFAULT; | ||
423 | #endif | ||
424 | return 0; | ||
425 | |||
426 | /* | ||
427 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change | ||
428 | * - mask passed in arg for lines of interest | ||
429 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) | ||
430 | * Caller should use TIOCGICOUNT to see which one it was | ||
431 | */ | ||
432 | case TIOCMIWAIT: | ||
433 | printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n"); | ||
434 | return 0; | ||
435 | case TIOCSERGWILD: | ||
436 | case TIOCSERSWILD: | ||
437 | /* "setserial -W" is called in Debian boot */ | ||
438 | printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n"); | ||
439 | return 0; | ||
440 | |||
441 | default: | ||
442 | return -ENOIOCTLCMD; | ||
443 | } | ||
444 | return 0; | ||
445 | } | 333 | } |
446 | 334 | ||
447 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | 335 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) |
@@ -452,220 +340,50 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
452 | if ((old_termios->c_cflag & CRTSCTS) && | 340 | if ((old_termios->c_cflag & CRTSCTS) && |
453 | !(tty->termios->c_cflag & CRTSCTS)) { | 341 | !(tty->termios->c_cflag & CRTSCTS)) { |
454 | tty->hw_stopped = 0; | 342 | tty->hw_stopped = 0; |
455 | rs_start(tty); | ||
456 | } | 343 | } |
457 | } | 344 | } |
458 | /* | 345 | /* |
459 | * This routine will shutdown a serial port; interrupts are disabled, and | 346 | * This routine will shutdown a serial port; interrupts are disabled, and |
460 | * DTR is dropped if the hangup on close termio flag is on. | 347 | * DTR is dropped if the hangup on close termio flag is on. |
461 | */ | 348 | */ |
462 | static void shutdown(struct async_struct * info) | 349 | static void shutdown(struct tty_port *port) |
463 | { | 350 | { |
464 | unsigned long flags; | 351 | struct serial_state *info = container_of(port, struct serial_state, |
465 | struct serial_state *state; | 352 | port); |
466 | int retval; | 353 | unsigned long flags; |
467 | |||
468 | if (!(info->flags & ASYNC_INITIALIZED)) return; | ||
469 | |||
470 | state = info->state; | ||
471 | |||
472 | #ifdef SIMSERIAL_DEBUG | ||
473 | printk("Shutting down serial port %d (irq %d)....", info->line, | ||
474 | state->irq); | ||
475 | #endif | ||
476 | 354 | ||
477 | local_irq_save(flags); | 355 | local_irq_save(flags); |
478 | { | 356 | if (info->irq) |
479 | /* | 357 | free_irq(info->irq, info); |
480 | * First unlink the serial port from the IRQ chain... | ||
481 | */ | ||
482 | if (info->next_port) | ||
483 | info->next_port->prev_port = info->prev_port; | ||
484 | if (info->prev_port) | ||
485 | info->prev_port->next_port = info->next_port; | ||
486 | else | ||
487 | IRQ_ports[state->irq] = info->next_port; | ||
488 | |||
489 | /* | ||
490 | * Free the IRQ, if necessary | ||
491 | */ | ||
492 | if (state->irq && (!IRQ_ports[state->irq] || | ||
493 | !IRQ_ports[state->irq]->next_port)) { | ||
494 | if (IRQ_ports[state->irq]) { | ||
495 | free_irq(state->irq, NULL); | ||
496 | retval = request_irq(state->irq, rs_interrupt_single, | ||
497 | IRQ_T(info), "serial", NULL); | ||
498 | |||
499 | if (retval) | ||
500 | printk(KERN_ERR "serial shutdown: request_irq: error %d" | ||
501 | " Couldn't reacquire IRQ.\n", retval); | ||
502 | } else | ||
503 | free_irq(state->irq, NULL); | ||
504 | } | ||
505 | |||
506 | if (info->xmit.buf) { | ||
507 | free_page((unsigned long) info->xmit.buf); | ||
508 | info->xmit.buf = NULL; | ||
509 | } | ||
510 | |||
511 | if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
512 | 358 | ||
513 | info->flags &= ~ASYNC_INITIALIZED; | 359 | if (info->xmit.buf) { |
360 | free_page((unsigned long) info->xmit.buf); | ||
361 | info->xmit.buf = NULL; | ||
514 | } | 362 | } |
515 | local_irq_restore(flags); | 363 | local_irq_restore(flags); |
516 | } | 364 | } |
517 | 365 | ||
518 | /* | ||
519 | * ------------------------------------------------------------ | ||
520 | * rs_close() | ||
521 | * | ||
522 | * This routine is called when the serial port gets closed. First, we | ||
523 | * wait for the last remaining data to be sent. Then, we unlink its | ||
524 | * async structure from the interrupt chain if necessary, and we free | ||
525 | * that IRQ if nothing is left in the chain. | ||
526 | * ------------------------------------------------------------ | ||
527 | */ | ||
528 | static void rs_close(struct tty_struct *tty, struct file * filp) | 366 | static void rs_close(struct tty_struct *tty, struct file * filp) |
529 | { | 367 | { |
530 | struct async_struct * info = (struct async_struct *)tty->driver_data; | 368 | struct serial_state *info = tty->driver_data; |
531 | struct serial_state *state; | ||
532 | unsigned long flags; | ||
533 | |||
534 | if (!info ) return; | ||
535 | |||
536 | state = info->state; | ||
537 | |||
538 | local_irq_save(flags); | ||
539 | if (tty_hung_up_p(filp)) { | ||
540 | #ifdef SIMSERIAL_DEBUG | ||
541 | printk("rs_close: hung_up\n"); | ||
542 | #endif | ||
543 | local_irq_restore(flags); | ||
544 | return; | ||
545 | } | ||
546 | #ifdef SIMSERIAL_DEBUG | ||
547 | printk("rs_close ttys%d, count = %d\n", info->line, state->count); | ||
548 | #endif | ||
549 | if ((tty->count == 1) && (state->count != 1)) { | ||
550 | /* | ||
551 | * Uh, oh. tty->count is 1, which means that the tty | ||
552 | * structure will be freed. state->count should always | ||
553 | * be one in these conditions. If it's greater than | ||
554 | * one, we've got real problems, since it means the | ||
555 | * serial port won't be shutdown. | ||
556 | */ | ||
557 | printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, " | ||
558 | "state->count is %d\n", state->count); | ||
559 | state->count = 1; | ||
560 | } | ||
561 | if (--state->count < 0) { | ||
562 | printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", | ||
563 | info->line, state->count); | ||
564 | state->count = 0; | ||
565 | } | ||
566 | if (state->count) { | ||
567 | local_irq_restore(flags); | ||
568 | return; | ||
569 | } | ||
570 | info->flags |= ASYNC_CLOSING; | ||
571 | local_irq_restore(flags); | ||
572 | 369 | ||
573 | /* | 370 | tty_port_close(&info->port, tty, filp); |
574 | * Now we wait for the transmit buffer to clear; and we notify | ||
575 | * the line discipline to only process XON/XOFF characters. | ||
576 | */ | ||
577 | shutdown(info); | ||
578 | rs_flush_buffer(tty); | ||
579 | tty_ldisc_flush(tty); | ||
580 | info->event = 0; | ||
581 | info->tty = NULL; | ||
582 | if (info->blocked_open) { | ||
583 | if (info->close_delay) | ||
584 | schedule_timeout_interruptible(info->close_delay); | ||
585 | wake_up_interruptible(&info->open_wait); | ||
586 | } | ||
587 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | ||
588 | wake_up_interruptible(&info->close_wait); | ||
589 | } | 371 | } |
590 | 372 | ||
591 | /* | ||
592 | * rs_wait_until_sent() --- wait until the transmitter is empty | ||
593 | */ | ||
594 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | ||
595 | { | ||
596 | } | ||
597 | |||
598 | |||
599 | /* | ||
600 | * rs_hangup() --- called by tty_hangup() when a hangup is signaled. | ||
601 | */ | ||
602 | static void rs_hangup(struct tty_struct *tty) | 373 | static void rs_hangup(struct tty_struct *tty) |
603 | { | 374 | { |
604 | struct async_struct * info = (struct async_struct *)tty->driver_data; | 375 | struct serial_state *info = tty->driver_data; |
605 | struct serial_state *state = info->state; | ||
606 | |||
607 | #ifdef SIMSERIAL_DEBUG | ||
608 | printk("rs_hangup: called\n"); | ||
609 | #endif | ||
610 | |||
611 | state = info->state; | ||
612 | 376 | ||
613 | rs_flush_buffer(tty); | 377 | rs_flush_buffer(tty); |
614 | if (info->flags & ASYNC_CLOSING) | 378 | tty_port_hangup(&info->port); |
615 | return; | ||
616 | shutdown(info); | ||
617 | |||
618 | info->event = 0; | ||
619 | state->count = 0; | ||
620 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
621 | info->tty = NULL; | ||
622 | wake_up_interruptible(&info->open_wait); | ||
623 | } | 379 | } |
624 | 380 | ||
625 | 381 | static int activate(struct tty_port *port, struct tty_struct *tty) | |
626 | static int get_async_struct(int line, struct async_struct **ret_info) | ||
627 | { | 382 | { |
628 | struct async_struct *info; | 383 | struct serial_state *state = container_of(port, struct serial_state, |
629 | struct serial_state *sstate; | 384 | port); |
630 | 385 | unsigned long flags, page; | |
631 | sstate = rs_table + line; | 386 | int retval = 0; |
632 | sstate->count++; | ||
633 | if (sstate->info) { | ||
634 | *ret_info = sstate->info; | ||
635 | return 0; | ||
636 | } | ||
637 | info = kzalloc(sizeof(struct async_struct), GFP_KERNEL); | ||
638 | if (!info) { | ||
639 | sstate->count--; | ||
640 | return -ENOMEM; | ||
641 | } | ||
642 | init_waitqueue_head(&info->open_wait); | ||
643 | init_waitqueue_head(&info->close_wait); | ||
644 | init_waitqueue_head(&info->delta_msr_wait); | ||
645 | info->magic = SERIAL_MAGIC; | ||
646 | info->port = sstate->port; | ||
647 | info->flags = sstate->flags; | ||
648 | info->xmit_fifo_size = sstate->xmit_fifo_size; | ||
649 | info->line = line; | ||
650 | INIT_WORK(&info->work, do_softint); | ||
651 | info->state = sstate; | ||
652 | if (sstate->info) { | ||
653 | kfree(info); | ||
654 | *ret_info = sstate->info; | ||
655 | return 0; | ||
656 | } | ||
657 | *ret_info = sstate->info = info; | ||
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static int | ||
662 | startup(struct async_struct *info) | ||
663 | { | ||
664 | unsigned long flags; | ||
665 | int retval=0; | ||
666 | irq_handler_t handler; | ||
667 | struct serial_state *state= info->state; | ||
668 | unsigned long page; | ||
669 | 387 | ||
670 | page = get_zeroed_page(GFP_KERNEL); | 388 | page = get_zeroed_page(GFP_KERNEL); |
671 | if (!page) | 389 | if (!page) |
@@ -673,86 +391,31 @@ startup(struct async_struct *info) | |||
673 | 391 | ||
674 | local_irq_save(flags); | 392 | local_irq_save(flags); |
675 | 393 | ||
676 | if (info->flags & ASYNC_INITIALIZED) { | 394 | if (state->xmit.buf) |
677 | free_page(page); | ||
678 | goto errout; | ||
679 | } | ||
680 | |||
681 | if (!state->port || !state->type) { | ||
682 | if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
683 | free_page(page); | ||
684 | goto errout; | ||
685 | } | ||
686 | if (info->xmit.buf) | ||
687 | free_page(page); | 395 | free_page(page); |
688 | else | 396 | else |
689 | info->xmit.buf = (unsigned char *) page; | 397 | state->xmit.buf = (unsigned char *) page; |
690 | |||
691 | #ifdef SIMSERIAL_DEBUG | ||
692 | printk("startup: ttys%d (irq %d)...", info->line, state->irq); | ||
693 | #endif | ||
694 | 398 | ||
695 | /* | 399 | if (state->irq) { |
696 | * Allocate the IRQ if necessary | 400 | retval = request_irq(state->irq, rs_interrupt_single, 0, |
697 | */ | 401 | "simserial", state); |
698 | if (state->irq && (!IRQ_ports[state->irq] || | 402 | if (retval) |
699 | !IRQ_ports[state->irq]->next_port)) { | ||
700 | if (IRQ_ports[state->irq]) { | ||
701 | retval = -EBUSY; | ||
702 | goto errout; | ||
703 | } else | ||
704 | handler = rs_interrupt_single; | ||
705 | |||
706 | retval = request_irq(state->irq, handler, IRQ_T(info), "simserial", NULL); | ||
707 | if (retval) { | ||
708 | if (capable(CAP_SYS_ADMIN)) { | ||
709 | if (info->tty) | ||
710 | set_bit(TTY_IO_ERROR, | ||
711 | &info->tty->flags); | ||
712 | retval = 0; | ||
713 | } | ||
714 | goto errout; | 403 | goto errout; |
715 | } | ||
716 | } | 404 | } |
717 | 405 | ||
718 | /* | 406 | state->xmit.head = state->xmit.tail = 0; |
719 | * Insert serial port into IRQ chain. | ||
720 | */ | ||
721 | info->prev_port = NULL; | ||
722 | info->next_port = IRQ_ports[state->irq]; | ||
723 | if (info->next_port) | ||
724 | info->next_port->prev_port = info; | ||
725 | IRQ_ports[state->irq] = info; | ||
726 | |||
727 | if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); | ||
728 | |||
729 | info->xmit.head = info->xmit.tail = 0; | ||
730 | |||
731 | #if 0 | ||
732 | /* | ||
733 | * Set up serial timers... | ||
734 | */ | ||
735 | timer_table[RS_TIMER].expires = jiffies + 2*HZ/100; | ||
736 | timer_active |= 1 << RS_TIMER; | ||
737 | #endif | ||
738 | 407 | ||
739 | /* | 408 | /* |
740 | * Set up the tty->alt_speed kludge | 409 | * Set up the tty->alt_speed kludge |
741 | */ | 410 | */ |
742 | if (info->tty) { | 411 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
743 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 412 | tty->alt_speed = 57600; |
744 | info->tty->alt_speed = 57600; | 413 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
745 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 414 | tty->alt_speed = 115200; |
746 | info->tty->alt_speed = 115200; | 415 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) |
747 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | 416 | tty->alt_speed = 230400; |
748 | info->tty->alt_speed = 230400; | 417 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) |
749 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | 418 | tty->alt_speed = 460800; |
750 | info->tty->alt_speed = 460800; | ||
751 | } | ||
752 | |||
753 | info->flags |= ASYNC_INITIALIZED; | ||
754 | local_irq_restore(flags); | ||
755 | return 0; | ||
756 | 419 | ||
757 | errout: | 420 | errout: |
758 | local_irq_restore(flags); | 421 | local_irq_restore(flags); |
@@ -768,56 +431,11 @@ errout: | |||
768 | */ | 431 | */ |
769 | static int rs_open(struct tty_struct *tty, struct file * filp) | 432 | static int rs_open(struct tty_struct *tty, struct file * filp) |
770 | { | 433 | { |
771 | struct async_struct *info; | 434 | struct serial_state *info = rs_table + tty->index; |
772 | int retval, line; | 435 | struct tty_port *port = &info->port; |
773 | unsigned long page; | ||
774 | 436 | ||
775 | line = tty->index; | ||
776 | if ((line < 0) || (line >= NR_PORTS)) | ||
777 | return -ENODEV; | ||
778 | retval = get_async_struct(line, &info); | ||
779 | if (retval) | ||
780 | return retval; | ||
781 | tty->driver_data = info; | 437 | tty->driver_data = info; |
782 | info->tty = tty; | 438 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
783 | |||
784 | #ifdef SIMSERIAL_DEBUG | ||
785 | printk("rs_open %s, count = %d\n", tty->name, info->state->count); | ||
786 | #endif | ||
787 | info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | ||
788 | |||
789 | if (!tmp_buf) { | ||
790 | page = get_zeroed_page(GFP_KERNEL); | ||
791 | if (!page) | ||
792 | return -ENOMEM; | ||
793 | if (tmp_buf) | ||
794 | free_page(page); | ||
795 | else | ||
796 | tmp_buf = (unsigned char *) page; | ||
797 | } | ||
798 | |||
799 | /* | ||
800 | * If the port is the middle of closing, bail out now | ||
801 | */ | ||
802 | if (tty_hung_up_p(filp) || | ||
803 | (info->flags & ASYNC_CLOSING)) { | ||
804 | if (info->flags & ASYNC_CLOSING) | ||
805 | interruptible_sleep_on(&info->close_wait); | ||
806 | #ifdef SERIAL_DO_RESTART | ||
807 | return ((info->flags & ASYNC_HUP_NOTIFY) ? | ||
808 | -EAGAIN : -ERESTARTSYS); | ||
809 | #else | ||
810 | return -EAGAIN; | ||
811 | #endif | ||
812 | } | ||
813 | |||
814 | /* | ||
815 | * Start up serial port | ||
816 | */ | ||
817 | retval = startup(info); | ||
818 | if (retval) { | ||
819 | return retval; | ||
820 | } | ||
821 | 439 | ||
822 | /* | 440 | /* |
823 | * figure out which console to use (should be one already) | 441 | * figure out which console to use (should be one already) |
@@ -828,30 +446,21 @@ static int rs_open(struct tty_struct *tty, struct file * filp) | |||
828 | console = console->next; | 446 | console = console->next; |
829 | } | 447 | } |
830 | 448 | ||
831 | #ifdef SIMSERIAL_DEBUG | 449 | return tty_port_open(port, tty, filp); |
832 | printk("rs_open ttys%d successful\n", info->line); | ||
833 | #endif | ||
834 | return 0; | ||
835 | } | 450 | } |
836 | 451 | ||
837 | /* | 452 | /* |
838 | * /proc fs routines.... | 453 | * /proc fs routines.... |
839 | */ | 454 | */ |
840 | 455 | ||
841 | static inline void line_info(struct seq_file *m, struct serial_state *state) | ||
842 | { | ||
843 | seq_printf(m, "%d: uart:%s port:%lX irq:%d\n", | ||
844 | state->line, uart_config[state->type].name, | ||
845 | state->port, state->irq); | ||
846 | } | ||
847 | |||
848 | static int rs_proc_show(struct seq_file *m, void *v) | 456 | static int rs_proc_show(struct seq_file *m, void *v) |
849 | { | 457 | { |
850 | int i; | 458 | int i; |
851 | 459 | ||
852 | seq_printf(m, "simserinfo:1.0 driver:%s\n", serial_version); | 460 | seq_printf(m, "simserinfo:1.0\n"); |
853 | for (i = 0; i < NR_PORTS; i++) | 461 | for (i = 0; i < NR_PORTS; i++) |
854 | line_info(m, &rs_table[i]); | 462 | seq_printf(m, "%d: uart:16550 port:3F8 irq:%d\n", |
463 | i, rs_table[i].irq); | ||
855 | return 0; | 464 | return 0; |
856 | } | 465 | } |
857 | 466 | ||
@@ -868,25 +477,6 @@ static const struct file_operations rs_proc_fops = { | |||
868 | .release = single_release, | 477 | .release = single_release, |
869 | }; | 478 | }; |
870 | 479 | ||
871 | /* | ||
872 | * --------------------------------------------------------------------- | ||
873 | * rs_init() and friends | ||
874 | * | ||
875 | * rs_init() is called at boot-time to initialize the serial driver. | ||
876 | * --------------------------------------------------------------------- | ||
877 | */ | ||
878 | |||
879 | /* | ||
880 | * This routine prints out the appropriate serial driver version | ||
881 | * number, and identifies which options were configured into this | ||
882 | * driver. | ||
883 | */ | ||
884 | static inline void show_serial_version(void) | ||
885 | { | ||
886 | printk(KERN_INFO "%s version %s with", serial_name, serial_version); | ||
887 | printk(KERN_INFO " no serial options enabled\n"); | ||
888 | } | ||
889 | |||
890 | static const struct tty_operations hp_ops = { | 480 | static const struct tty_operations hp_ops = { |
891 | .open = rs_open, | 481 | .open = rs_open, |
892 | .close = rs_close, | 482 | .close = rs_close, |
@@ -901,34 +491,31 @@ static const struct tty_operations hp_ops = { | |||
901 | .unthrottle = rs_unthrottle, | 491 | .unthrottle = rs_unthrottle, |
902 | .send_xchar = rs_send_xchar, | 492 | .send_xchar = rs_send_xchar, |
903 | .set_termios = rs_set_termios, | 493 | .set_termios = rs_set_termios, |
904 | .stop = rs_stop, | ||
905 | .start = rs_start, | ||
906 | .hangup = rs_hangup, | 494 | .hangup = rs_hangup, |
907 | .wait_until_sent = rs_wait_until_sent, | ||
908 | .proc_fops = &rs_proc_fops, | 495 | .proc_fops = &rs_proc_fops, |
909 | }; | 496 | }; |
910 | 497 | ||
911 | /* | 498 | static const struct tty_port_operations hp_port_ops = { |
912 | * The serial driver boot-time initialization code! | 499 | .activate = activate, |
913 | */ | 500 | .shutdown = shutdown, |
914 | static int __init | 501 | }; |
915 | simrs_init (void) | 502 | |
503 | static int __init simrs_init(void) | ||
916 | { | 504 | { |
917 | int i, rc; | 505 | struct serial_state *state; |
918 | struct serial_state *state; | 506 | int retval; |
919 | 507 | ||
920 | if (!ia64_platform_is("hpsim")) | 508 | if (!ia64_platform_is("hpsim")) |
921 | return -ENODEV; | 509 | return -ENODEV; |
922 | 510 | ||
923 | hp_simserial_driver = alloc_tty_driver(1); | 511 | hp_simserial_driver = alloc_tty_driver(NR_PORTS); |
924 | if (!hp_simserial_driver) | 512 | if (!hp_simserial_driver) |
925 | return -ENOMEM; | 513 | return -ENOMEM; |
926 | 514 | ||
927 | show_serial_version(); | 515 | printk(KERN_INFO "SimSerial driver with no serial options enabled\n"); |
928 | 516 | ||
929 | /* Initialize the tty_driver structure */ | 517 | /* Initialize the tty_driver structure */ |
930 | 518 | ||
931 | hp_simserial_driver->owner = THIS_MODULE; | ||
932 | hp_simserial_driver->driver_name = "simserial"; | 519 | hp_simserial_driver->driver_name = "simserial"; |
933 | hp_simserial_driver->name = "ttyS"; | 520 | hp_simserial_driver->name = "ttyS"; |
934 | hp_simserial_driver->major = TTY_MAJOR; | 521 | hp_simserial_driver->major = TTY_MAJOR; |
@@ -941,31 +528,33 @@ simrs_init (void) | |||
941 | hp_simserial_driver->flags = TTY_DRIVER_REAL_RAW; | 528 | hp_simserial_driver->flags = TTY_DRIVER_REAL_RAW; |
942 | tty_set_operations(hp_simserial_driver, &hp_ops); | 529 | tty_set_operations(hp_simserial_driver, &hp_ops); |
943 | 530 | ||
944 | /* | 531 | state = rs_table; |
945 | * Let's have a little bit of fun ! | 532 | tty_port_init(&state->port); |
946 | */ | 533 | state->port.ops = &hp_port_ops; |
947 | for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { | 534 | state->port.close_delay = 0; /* XXX really 0? */ |
948 | 535 | ||
949 | if (state->type == PORT_UNKNOWN) continue; | 536 | retval = hpsim_get_irq(KEYBOARD_INTR); |
537 | if (retval < 0) { | ||
538 | printk(KERN_ERR "%s: out of interrupt vectors!\n", | ||
539 | __func__); | ||
540 | goto err_free_tty; | ||
541 | } | ||
950 | 542 | ||
951 | if (!state->irq) { | 543 | state->irq = retval; |
952 | if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) | ||
953 | panic("%s: out of interrupt vectors!\n", | ||
954 | __func__); | ||
955 | state->irq = rc; | ||
956 | ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); | ||
957 | } | ||
958 | 544 | ||
959 | printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n", | 545 | /* the port is imaginary */ |
960 | state->line, | 546 | printk(KERN_INFO "ttyS0 at 0x03f8 (irq = %d) is a 16550\n", state->irq); |
961 | state->port, state->irq, | ||
962 | uart_config[state->type].name); | ||
963 | } | ||
964 | 547 | ||
965 | if (tty_register_driver(hp_simserial_driver)) | 548 | retval = tty_register_driver(hp_simserial_driver); |
966 | panic("Couldn't register simserial driver\n"); | 549 | if (retval) { |
550 | printk(KERN_ERR "Couldn't register simserial driver\n"); | ||
551 | goto err_free_tty; | ||
552 | } | ||
967 | 553 | ||
968 | return 0; | 554 | return 0; |
555 | err_free_tty: | ||
556 | put_tty_driver(hp_simserial_driver); | ||
557 | return retval; | ||
969 | } | 558 | } |
970 | 559 | ||
971 | #ifndef MODULE | 560 | #ifndef MODULE |
diff --git a/arch/ia64/include/asm/hpsim.h b/arch/ia64/include/asm/hpsim.h index 892ab198a9da..0fe50225daa4 100644 --- a/arch/ia64/include/asm/hpsim.h +++ b/arch/ia64/include/asm/hpsim.h | |||
@@ -10,7 +10,7 @@ int simcons_register(void); | |||
10 | struct tty_driver; | 10 | struct tty_driver; |
11 | extern struct tty_driver *hp_simserial_driver; | 11 | extern struct tty_driver *hp_simserial_driver; |
12 | 12 | ||
13 | void ia64_ssc_connect_irq(long intr, long irq); | 13 | extern int hpsim_get_irq(int intr); |
14 | void ia64_ctl_trace(long on); | 14 | void ia64_ctl_trace(long on); |
15 | 15 | ||
16 | #endif | 16 | #endif |
diff --git a/arch/ia64/include/asm/paravirt.h b/arch/ia64/include/asm/paravirt.h index 32551d304cd7..b149b88ea795 100644 --- a/arch/ia64/include/asm/paravirt.h +++ b/arch/ia64/include/asm/paravirt.h | |||
@@ -281,9 +281,9 @@ paravirt_init_missing_ticks_accounting(int cpu) | |||
281 | pv_time_ops.init_missing_ticks_accounting(cpu); | 281 | pv_time_ops.init_missing_ticks_accounting(cpu); |
282 | } | 282 | } |
283 | 283 | ||
284 | struct jump_label_key; | 284 | struct static_key; |
285 | extern struct jump_label_key paravirt_steal_enabled; | 285 | extern struct static_key paravirt_steal_enabled; |
286 | extern struct jump_label_key paravirt_steal_rq_enabled; | 286 | extern struct static_key paravirt_steal_rq_enabled; |
287 | 287 | ||
288 | static inline int | 288 | static inline int |
289 | paravirt_do_steal_accounting(unsigned long *new_itm) | 289 | paravirt_do_steal_accounting(unsigned long *new_itm) |
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 279b38ae74aa..b22e5f5fa593 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h | |||
@@ -108,12 +108,6 @@ static inline int pci_proc_domain(struct pci_bus *bus) | |||
108 | return (pci_domain_nr(bus) != 0); | 108 | return (pci_domain_nr(bus) != 0); |
109 | } | 109 | } |
110 | 110 | ||
111 | extern void pcibios_resource_to_bus(struct pci_dev *dev, | ||
112 | struct pci_bus_region *region, struct resource *res); | ||
113 | |||
114 | extern void pcibios_bus_to_resource(struct pci_dev *dev, | ||
115 | struct resource *res, struct pci_bus_region *region); | ||
116 | |||
117 | static inline struct resource * | 111 | static inline struct resource * |
118 | pcibios_select_root(struct pci_dev *pdev, struct resource *res) | 112 | pcibios_select_root(struct pci_dev *pdev, struct resource *res) |
119 | { | 113 | { |
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h index 4b03664e3fb5..41fc28a4a18a 100644 --- a/arch/ia64/include/asm/socket.h +++ b/arch/ia64/include/asm/socket.h | |||
@@ -73,5 +73,9 @@ | |||
73 | 73 | ||
74 | #define SO_WIFI_STATUS 41 | 74 | #define SO_WIFI_STATUS 41 |
75 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | 75 | #define SCM_WIFI_STATUS SO_WIFI_STATUS |
76 | #define SO_PEEK_OFF 42 | ||
77 | |||
78 | /* Instruct lower device to use last 4-bytes of skb data as FCS */ | ||
79 | #define SO_NOFCS 43 | ||
76 | 80 | ||
77 | #endif /* _ASM_IA64_SOCKET_H */ | 81 | #endif /* _ASM_IA64_SOCKET_H */ |
diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h index fbb519828aa1..09d5f7fd9db1 100644 --- a/arch/ia64/include/asm/xen/interface.h +++ b/arch/ia64/include/asm/xen/interface.h | |||
@@ -77,6 +77,7 @@ DEFINE_GUEST_HANDLE(int); | |||
77 | DEFINE_GUEST_HANDLE(long); | 77 | DEFINE_GUEST_HANDLE(long); |
78 | DEFINE_GUEST_HANDLE(void); | 78 | DEFINE_GUEST_HANDLE(void); |
79 | DEFINE_GUEST_HANDLE(uint64_t); | 79 | DEFINE_GUEST_HANDLE(uint64_t); |
80 | DEFINE_GUEST_HANDLE(uint32_t); | ||
80 | 81 | ||
81 | typedef unsigned long xen_pfn_t; | 82 | typedef unsigned long xen_pfn_t; |
82 | DEFINE_GUEST_HANDLE(xen_pfn_t); | 83 | DEFINE_GUEST_HANDLE(xen_pfn_t); |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 5207035dc061..2d801bfe16ac 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -349,11 +349,11 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, | |||
349 | 349 | ||
350 | iosapic_override_isa_irq(p->source_irq, p->global_irq, | 350 | iosapic_override_isa_irq(p->source_irq, p->global_irq, |
351 | ((p->inti_flags & ACPI_MADT_POLARITY_MASK) == | 351 | ((p->inti_flags & ACPI_MADT_POLARITY_MASK) == |
352 | ACPI_MADT_POLARITY_ACTIVE_HIGH) ? | 352 | ACPI_MADT_POLARITY_ACTIVE_LOW) ? |
353 | IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, | 353 | IOSAPIC_POL_LOW : IOSAPIC_POL_HIGH, |
354 | ((p->inti_flags & ACPI_MADT_TRIGGER_MASK) == | 354 | ((p->inti_flags & ACPI_MADT_TRIGGER_MASK) == |
355 | ACPI_MADT_TRIGGER_EDGE) ? | 355 | ACPI_MADT_TRIGGER_LEVEL) ? |
356 | IOSAPIC_EDGE : IOSAPIC_LEVEL); | 356 | IOSAPIC_LEVEL : IOSAPIC_EDGE); |
357 | return 0; | 357 | return 0; |
358 | } | 358 | } |
359 | 359 | ||
diff --git a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c index 4eed35814994..070e8effa175 100644 --- a/arch/ia64/kernel/machine_kexec.c +++ b/arch/ia64/kernel/machine_kexec.c | |||
@@ -157,7 +157,7 @@ void arch_crash_save_vmcoreinfo(void) | |||
157 | #endif | 157 | #endif |
158 | #ifdef CONFIG_PGTABLE_3 | 158 | #ifdef CONFIG_PGTABLE_3 |
159 | VMCOREINFO_CONFIG(PGTABLE_3); | 159 | VMCOREINFO_CONFIG(PGTABLE_3); |
160 | #elif CONFIG_PGTABLE_4 | 160 | #elif defined(CONFIG_PGTABLE_4) |
161 | VMCOREINFO_CONFIG(PGTABLE_4); | 161 | VMCOREINFO_CONFIG(PGTABLE_4); |
162 | #endif | 162 | #endif |
163 | } | 163 | } |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 84fb405eee87..8192009cb924 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -1447,6 +1447,8 @@ out: | |||
1447 | /* Get the CMC error record and log it */ | 1447 | /* Get the CMC error record and log it */ |
1448 | ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC); | 1448 | ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC); |
1449 | 1449 | ||
1450 | local_irq_disable(); | ||
1451 | |||
1450 | return IRQ_HANDLED; | 1452 | return IRQ_HANDLED; |
1451 | } | 1453 | } |
1452 | 1454 | ||
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c index 100868216c55..1b22f6de2932 100644 --- a/arch/ia64/kernel/paravirt.c +++ b/arch/ia64/kernel/paravirt.c | |||
@@ -634,8 +634,8 @@ struct pv_irq_ops pv_irq_ops = { | |||
634 | * pv_time_ops | 634 | * pv_time_ops |
635 | * time operations | 635 | * time operations |
636 | */ | 636 | */ |
637 | struct jump_label_key paravirt_steal_enabled; | 637 | struct static_key paravirt_steal_enabled; |
638 | struct jump_label_key paravirt_steal_rq_enabled; | 638 | struct static_key paravirt_steal_rq_enabled; |
639 | 639 | ||
640 | static int | 640 | static int |
641 | ia64_native_do_steal_accounting(unsigned long *new_itm) | 641 | ia64_native_do_steal_accounting(unsigned long *new_itm) |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 6d33c5cc94f0..9dc52b63fc87 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -330,9 +330,7 @@ cpu_idle (void) | |||
330 | normal_xtp(); | 330 | normal_xtp(); |
331 | #endif | 331 | #endif |
332 | } | 332 | } |
333 | preempt_enable_no_resched(); | 333 | schedule_preempt_disabled(); |
334 | schedule(); | ||
335 | preempt_disable(); | ||
336 | check_pgt_cache(); | 334 | check_pgt_cache(); |
337 | if (cpu_is_offline(cpu)) | 335 | if (cpu_is_offline(cpu)) |
338 | play_dead(); | 336 | play_dead(); |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index f82f5d4b65fd..d1ce3200147c 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -320,7 +320,8 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | |||
320 | * Ignore these tiny memory ranges */ | 320 | * Ignore these tiny memory ranges */ |
321 | if (!((window->resource.flags & IORESOURCE_MEM) && | 321 | if (!((window->resource.flags & IORESOURCE_MEM) && |
322 | (window->resource.end - window->resource.start < 16))) | 322 | (window->resource.end - window->resource.start < 16))) |
323 | pci_add_resource(&info->resources, &window->resource); | 323 | pci_add_resource_offset(&info->resources, &window->resource, |
324 | window->offset); | ||
324 | 325 | ||
325 | return AE_OK; | 326 | return AE_OK; |
326 | } | 327 | } |
@@ -395,54 +396,6 @@ out1: | |||
395 | return NULL; | 396 | return NULL; |
396 | } | 397 | } |
397 | 398 | ||
398 | void pcibios_resource_to_bus(struct pci_dev *dev, | ||
399 | struct pci_bus_region *region, struct resource *res) | ||
400 | { | ||
401 | struct pci_controller *controller = PCI_CONTROLLER(dev); | ||
402 | unsigned long offset = 0; | ||
403 | int i; | ||
404 | |||
405 | for (i = 0; i < controller->windows; i++) { | ||
406 | struct pci_window *window = &controller->window[i]; | ||
407 | if (!(window->resource.flags & res->flags)) | ||
408 | continue; | ||
409 | if (window->resource.start > res->start) | ||
410 | continue; | ||
411 | if (window->resource.end < res->end) | ||
412 | continue; | ||
413 | offset = window->offset; | ||
414 | break; | ||
415 | } | ||
416 | |||
417 | region->start = res->start - offset; | ||
418 | region->end = res->end - offset; | ||
419 | } | ||
420 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
421 | |||
422 | void pcibios_bus_to_resource(struct pci_dev *dev, | ||
423 | struct resource *res, struct pci_bus_region *region) | ||
424 | { | ||
425 | struct pci_controller *controller = PCI_CONTROLLER(dev); | ||
426 | unsigned long offset = 0; | ||
427 | int i; | ||
428 | |||
429 | for (i = 0; i < controller->windows; i++) { | ||
430 | struct pci_window *window = &controller->window[i]; | ||
431 | if (!(window->resource.flags & res->flags)) | ||
432 | continue; | ||
433 | if (window->resource.start - window->offset > region->start) | ||
434 | continue; | ||
435 | if (window->resource.end - window->offset < region->end) | ||
436 | continue; | ||
437 | offset = window->offset; | ||
438 | break; | ||
439 | } | ||
440 | |||
441 | res->start = region->start + offset; | ||
442 | res->end = region->end + offset; | ||
443 | } | ||
444 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
445 | |||
446 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | 399 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) |
447 | { | 400 | { |
448 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; | 401 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; |
@@ -464,15 +417,11 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | |||
464 | static void __devinit | 417 | static void __devinit |
465 | pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) | 418 | pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) |
466 | { | 419 | { |
467 | struct pci_bus_region region; | ||
468 | int i; | 420 | int i; |
469 | 421 | ||
470 | for (i = start; i < limit; i++) { | 422 | for (i = start; i < limit; i++) { |
471 | if (!dev->resource[i].flags) | 423 | if (!dev->resource[i].flags) |
472 | continue; | 424 | continue; |
473 | region.start = dev->resource[i].start; | ||
474 | region.end = dev->resource[i].end; | ||
475 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); | ||
476 | if ((is_valid_resource(dev, i))) | 425 | if ((is_valid_resource(dev, i))) |
477 | pci_claim_resource(dev, i); | 426 | pci_claim_resource(dev, i); |
478 | } | 427 | } |
diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c index 08b0d9bb62ec..f925dec2da92 100644 --- a/arch/ia64/sn/kernel/huberror.c +++ b/arch/ia64/sn/kernel/huberror.c | |||
@@ -192,6 +192,7 @@ void hub_error_init(struct hubdev_info *hubdev_info) | |||
192 | hubdev_info); | 192 | hubdev_info); |
193 | return; | 193 | return; |
194 | } | 194 | } |
195 | irq_set_handler(SGI_II_ERROR, handle_level_irq); | ||
195 | sn_set_err_irq_affinity(SGI_II_ERROR); | 196 | sn_set_err_irq_affinity(SGI_II_ERROR); |
196 | } | 197 | } |
197 | 198 | ||
@@ -213,6 +214,7 @@ void ice_error_init(struct hubdev_info *hubdev_info) | |||
213 | hubdev_info); | 214 | hubdev_info); |
214 | return; | 215 | return; |
215 | } | 216 | } |
217 | irq_set_handler(SGI_TIO_ERROR, handle_level_irq); | ||
216 | sn_set_err_irq_affinity(SGI_TIO_ERROR); | 218 | sn_set_err_irq_affinity(SGI_TIO_ERROR); |
217 | } | 219 | } |
218 | 220 | ||
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index 4433dd019d3c..fbb5f2f87eed 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/bootmem.h> | 9 | #include <linux/bootmem.h> |
10 | #include <linux/export.h> | ||
10 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
11 | #include <asm/sn/types.h> | 12 | #include <asm/sn/types.h> |
12 | #include <asm/sn/addrs.h> | 13 | #include <asm/sn/addrs.h> |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 0a36f082eaf1..238e2c511d94 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -297,7 +297,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
297 | s64 status = 0; | 297 | s64 status = 0; |
298 | struct pci_controller *controller; | 298 | struct pci_controller *controller; |
299 | struct pcibus_bussoft *prom_bussoft_ptr; | 299 | struct pcibus_bussoft *prom_bussoft_ptr; |
300 | 300 | LIST_HEAD(resources); | |
301 | int i; | ||
301 | 302 | ||
302 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, | 303 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, |
303 | (u64) ia64_tpa(&prom_bussoft_ptr)); | 304 | (u64) ia64_tpa(&prom_bussoft_ptr)); |
@@ -315,7 +316,15 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
315 | */ | 316 | */ |
316 | controller->platform_data = prom_bussoft_ptr; | 317 | controller->platform_data = prom_bussoft_ptr; |
317 | 318 | ||
318 | bus = pci_scan_bus(busnum, &pci_root_ops, controller); | 319 | sn_legacy_pci_window_fixup(controller, |
320 | prom_bussoft_ptr->bs_legacy_io, | ||
321 | prom_bussoft_ptr->bs_legacy_mem); | ||
322 | for (i = 0; i < controller->windows; i++) | ||
323 | pci_add_resource_offset(&resources, | ||
324 | &controller->window[i].resource, | ||
325 | controller->window[i].offset); | ||
326 | bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, | ||
327 | &resources); | ||
319 | if (bus == NULL) | 328 | if (bus == NULL) |
320 | goto error_return; /* error, or bus already scanned */ | 329 | goto error_return; /* error, or bus already scanned */ |
321 | 330 | ||
@@ -348,9 +357,6 @@ sn_bus_fixup(struct pci_bus *bus) | |||
348 | return; | 357 | return; |
349 | } | 358 | } |
350 | sn_common_bus_fixup(bus, prom_bussoft_ptr); | 359 | sn_common_bus_fixup(bus, prom_bussoft_ptr); |
351 | sn_legacy_pci_window_fixup(PCI_CONTROLLER(bus), | ||
352 | prom_bussoft_ptr->bs_legacy_io, | ||
353 | prom_bussoft_ptr->bs_legacy_mem); | ||
354 | } | 360 | } |
355 | list_for_each_entry(pci_dev, &bus->devices, bus_list) { | 361 | list_for_each_entry(pci_dev, &bus->devices, bus_list) { |
356 | sn_io_slot_fixup(pci_dev); | 362 | sn_io_slot_fixup(pci_dev); |
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index dfac09ab027a..62cf4dde6a04 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
@@ -352,6 +352,8 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) | |||
352 | spin_lock(&sn_irq_info_lock); | 352 | spin_lock(&sn_irq_info_lock); |
353 | list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); | 353 | list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); |
354 | reserve_irq_vector(sn_irq_info->irq_irq); | 354 | reserve_irq_vector(sn_irq_info->irq_irq); |
355 | if (sn_irq_info->irq_int_bit != -1) | ||
356 | irq_set_handler(sn_irq_info->irq_irq, handle_level_irq); | ||
355 | spin_unlock(&sn_irq_info_lock); | 357 | spin_unlock(&sn_irq_info_lock); |
356 | 358 | ||
357 | register_intr_pda(sn_irq_info); | 359 | register_intr_pda(sn_irq_info); |
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 2de41d44266e..4554f68b7865 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/export.h> | ||
28 | #include <linux/vmalloc.h> | 29 | #include <linux/vmalloc.h> |
29 | #include <linux/seq_file.h> | 30 | #include <linux/seq_file.h> |
30 | #include <linux/miscdevice.h> | 31 | #include <linux/miscdevice.h> |
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index c1bd1cfda327..2f406f509d44 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c | |||
@@ -191,6 +191,7 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, | |||
191 | struct hubdev_info *hubdev, int bt) | 191 | struct hubdev_info *hubdev, int bt) |
192 | { | 192 | { |
193 | struct cx_dev *cx_dev; | 193 | struct cx_dev *cx_dev; |
194 | int r; | ||
194 | 195 | ||
195 | cx_dev = kzalloc(sizeof(struct cx_dev), GFP_KERNEL); | 196 | cx_dev = kzalloc(sizeof(struct cx_dev), GFP_KERNEL); |
196 | DBG("cx_dev= 0x%p\n", cx_dev); | 197 | DBG("cx_dev= 0x%p\n", cx_dev); |
@@ -207,7 +208,11 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, | |||
207 | cx_dev->dev.bus = &tiocx_bus_type; | 208 | cx_dev->dev.bus = &tiocx_bus_type; |
208 | cx_dev->dev.release = tiocx_bus_release; | 209 | cx_dev->dev.release = tiocx_bus_release; |
209 | dev_set_name(&cx_dev->dev, "%d", cx_dev->cx_id.nasid); | 210 | dev_set_name(&cx_dev->dev, "%d", cx_dev->cx_id.nasid); |
210 | device_register(&cx_dev->dev); | 211 | r = device_register(&cx_dev->dev); |
212 | if (r) { | ||
213 | kfree(cx_dev); | ||
214 | return r; | ||
215 | } | ||
211 | get_device(&cx_dev->dev); | 216 | get_device(&cx_dev->dev); |
212 | 217 | ||
213 | device_create_file(&cx_dev->dev, &dev_attr_cxdev_control); | 218 | device_create_file(&cx_dev->dev, &dev_attr_cxdev_control); |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 8886a0bc4a11..8dbbef4a4f47 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
@@ -146,6 +146,7 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
146 | printk(KERN_WARNING | 146 | printk(KERN_WARNING |
147 | "pcibr cannot allocate interrupt for error handler\n"); | 147 | "pcibr cannot allocate interrupt for error handler\n"); |
148 | } | 148 | } |
149 | irq_set_handler(SGI_PCIASIC_ERROR, handle_level_irq); | ||
149 | sn_set_err_irq_affinity(SGI_PCIASIC_ERROR); | 150 | sn_set_err_irq_affinity(SGI_PCIASIC_ERROR); |
150 | 151 | ||
151 | /* | 152 | /* |
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index e77c477245fd..a70b11fd57d6 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c | |||
@@ -649,6 +649,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
649 | __func__, SGI_TIOCA_ERROR, | 649 | __func__, SGI_TIOCA_ERROR, |
650 | (int)tioca_common->ca_common.bs_persist_busnum); | 650 | (int)tioca_common->ca_common.bs_persist_busnum); |
651 | 651 | ||
652 | irq_set_handler(SGI_TIOCA_ERROR, handle_level_irq); | ||
652 | sn_set_err_irq_affinity(SGI_TIOCA_ERROR); | 653 | sn_set_err_irq_affinity(SGI_TIOCA_ERROR); |
653 | 654 | ||
654 | /* Setup locality information */ | 655 | /* Setup locality information */ |
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 27faba035f3a..46d3df4b03a1 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c | |||
@@ -1037,6 +1037,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
1037 | tioce_common->ce_pcibus.bs_persist_segment, | 1037 | tioce_common->ce_pcibus.bs_persist_segment, |
1038 | tioce_common->ce_pcibus.bs_persist_busnum); | 1038 | tioce_common->ce_pcibus.bs_persist_busnum); |
1039 | 1039 | ||
1040 | irq_set_handler(SGI_PCIASIC_ERROR, handle_level_irq); | ||
1040 | sn_set_err_irq_affinity(SGI_PCIASIC_ERROR); | 1041 | sn_set_err_irq_affinity(SGI_PCIASIC_ERROR); |
1041 | return tioce_common; | 1042 | return tioce_common; |
1042 | } | 1043 | } |
diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c index b279e142c633..3bb12230721f 100644 --- a/arch/ia64/xen/irq_xen.c +++ b/arch/ia64/xen/irq_xen.c | |||
@@ -58,7 +58,7 @@ xen_free_irq_vector(int vector) | |||
58 | 58 | ||
59 | irq_op.vector = vector; | 59 | irq_op.vector = vector; |
60 | if (HYPERVISOR_physdev_op(PHYSDEVOP_free_irq_vector, &irq_op)) | 60 | if (HYPERVISOR_physdev_op(PHYSDEVOP_free_irq_vector, &irq_op)) |
61 | printk(KERN_WARNING "%s: xen_free_irq_vecotr fail vector=%d\n", | 61 | printk(KERN_WARNING "%s: xen_free_irq_vector fail vector=%d\n", |
62 | __func__, vector); | 62 | __func__, vector); |
63 | } | 63 | } |
64 | 64 | ||