diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/riscom8.c | 644 |
1 files changed, 304 insertions, 340 deletions
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 221b5a292076..45e73bd8bd11 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -4,9 +4,9 @@ | |||
4 | * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) | 4 | * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) |
5 | * | 5 | * |
6 | * This code is loosely based on the Linux serial driver, written by | 6 | * This code is loosely based on the Linux serial driver, written by |
7 | * Linus Torvalds, Theodore T'so and others. The RISCom/8 card | 7 | * Linus Torvalds, Theodore T'so and others. The RISCom/8 card |
8 | * programming info was obtained from various drivers for other OSes | 8 | * programming info was obtained from various drivers for other OSes |
9 | * (FreeBSD, ISC, etc), but no source code from those drivers were | 9 | * (FreeBSD, ISC, etc), but no source code from those drivers were |
10 | * directly included in this driver. | 10 | * directly included in this driver. |
11 | * | 11 | * |
12 | * | 12 | * |
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | 35 | ||
36 | #include <asm/io.h> | 36 | #include <linux/io.h> |
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <linux/ioport.h> | 39 | #include <linux/ioport.h> |
@@ -49,7 +49,7 @@ | |||
49 | #include <linux/tty_flip.h> | 49 | #include <linux/tty_flip.h> |
50 | #include <linux/spinlock.h> | 50 | #include <linux/spinlock.h> |
51 | 51 | ||
52 | #include <asm/uaccess.h> | 52 | #include <linux/uaccess.h> |
53 | 53 | ||
54 | #include "riscom8.h" | 54 | #include "riscom8.h" |
55 | #include "riscom8_reg.h" | 55 | #include "riscom8_reg.h" |
@@ -57,15 +57,15 @@ | |||
57 | /* Am I paranoid or not ? ;-) */ | 57 | /* Am I paranoid or not ? ;-) */ |
58 | #define RISCOM_PARANOIA_CHECK | 58 | #define RISCOM_PARANOIA_CHECK |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Crazy InteliCom/8 boards sometimes has swapped CTS & DSR signals. | 61 | * Crazy InteliCom/8 boards sometimes have swapped CTS & DSR signals. |
62 | * You can slightly speed up things by #undefing the following option, | 62 | * You can slightly speed up things by #undefing the following option, |
63 | * if you are REALLY sure that your board is correct one. | 63 | * if you are REALLY sure that your board is correct one. |
64 | */ | 64 | */ |
65 | 65 | ||
66 | #define RISCOM_BRAIN_DAMAGED_CTS | 66 | #define RISCOM_BRAIN_DAMAGED_CTS |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * The following defines are mostly for testing purposes. But if you need | 69 | * The following defines are mostly for testing purposes. But if you need |
70 | * some nice reporting in your syslog, you can define them also. | 70 | * some nice reporting in your syslog, you can define them also. |
71 | */ | 71 | */ |
@@ -112,7 +112,7 @@ static unsigned short rc_ioport[] = { | |||
112 | #define RC_NIOPORT ARRAY_SIZE(rc_ioport) | 112 | #define RC_NIOPORT ARRAY_SIZE(rc_ioport) |
113 | 113 | ||
114 | 114 | ||
115 | static inline int rc_paranoia_check(struct riscom_port const * port, | 115 | static int rc_paranoia_check(struct riscom_port const *port, |
116 | char *name, const char *routine) | 116 | char *name, const char *routine) |
117 | { | 117 | { |
118 | #ifdef RISCOM_PARANOIA_CHECK | 118 | #ifdef RISCOM_PARANOIA_CHECK |
@@ -134,52 +134,53 @@ static inline int rc_paranoia_check(struct riscom_port const * port, | |||
134 | } | 134 | } |
135 | 135 | ||
136 | /* | 136 | /* |
137 | * | 137 | * |
138 | * Service functions for RISCom/8 driver. | 138 | * Service functions for RISCom/8 driver. |
139 | * | 139 | * |
140 | */ | 140 | */ |
141 | 141 | ||
142 | /* Get board number from pointer */ | 142 | /* Get board number from pointer */ |
143 | static inline int board_No (struct riscom_board const * bp) | 143 | static inline int board_No(struct riscom_board const *bp) |
144 | { | 144 | { |
145 | return bp - rc_board; | 145 | return bp - rc_board; |
146 | } | 146 | } |
147 | 147 | ||
148 | /* Get port number from pointer */ | 148 | /* Get port number from pointer */ |
149 | static inline int port_No (struct riscom_port const * port) | 149 | static inline int port_No(struct riscom_port const *port) |
150 | { | 150 | { |
151 | return RC_PORT(port - rc_port); | 151 | return RC_PORT(port - rc_port); |
152 | } | 152 | } |
153 | 153 | ||
154 | /* Get pointer to board from pointer to port */ | 154 | /* Get pointer to board from pointer to port */ |
155 | static inline struct riscom_board * port_Board(struct riscom_port const * port) | 155 | static inline struct riscom_board *port_Board(struct riscom_port const *port) |
156 | { | 156 | { |
157 | return &rc_board[RC_BOARD(port - rc_port)]; | 157 | return &rc_board[RC_BOARD(port - rc_port)]; |
158 | } | 158 | } |
159 | 159 | ||
160 | /* Input Byte from CL CD180 register */ | 160 | /* Input Byte from CL CD180 register */ |
161 | static inline unsigned char rc_in(struct riscom_board const * bp, unsigned short reg) | 161 | static inline unsigned char rc_in(struct riscom_board const *bp, |
162 | unsigned short reg) | ||
162 | { | 163 | { |
163 | return inb(bp->base + RC_TO_ISA(reg)); | 164 | return inb(bp->base + RC_TO_ISA(reg)); |
164 | } | 165 | } |
165 | 166 | ||
166 | /* Output Byte to CL CD180 register */ | 167 | /* Output Byte to CL CD180 register */ |
167 | static inline void rc_out(struct riscom_board const * bp, unsigned short reg, | 168 | static inline void rc_out(struct riscom_board const *bp, unsigned short reg, |
168 | unsigned char val) | 169 | unsigned char val) |
169 | { | 170 | { |
170 | outb(val, bp->base + RC_TO_ISA(reg)); | 171 | outb(val, bp->base + RC_TO_ISA(reg)); |
171 | } | 172 | } |
172 | 173 | ||
173 | /* Wait for Channel Command Register ready */ | 174 | /* Wait for Channel Command Register ready */ |
174 | static inline void rc_wait_CCR(struct riscom_board const * bp) | 175 | static void rc_wait_CCR(struct riscom_board const *bp) |
175 | { | 176 | { |
176 | unsigned long delay; | 177 | unsigned long delay; |
177 | 178 | ||
178 | /* FIXME: need something more descriptive then 100000 :) */ | 179 | /* FIXME: need something more descriptive then 100000 :) */ |
179 | for (delay = 100000; delay; delay--) | 180 | for (delay = 100000; delay; delay--) |
180 | if (!rc_in(bp, CD180_CCR)) | 181 | if (!rc_in(bp, CD180_CCR)) |
181 | return; | 182 | return; |
182 | 183 | ||
183 | printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp)); | 184 | printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp)); |
184 | } | 185 | } |
185 | 186 | ||
@@ -187,11 +188,11 @@ static inline void rc_wait_CCR(struct riscom_board const * bp) | |||
187 | * RISCom/8 probe functions. | 188 | * RISCom/8 probe functions. |
188 | */ | 189 | */ |
189 | 190 | ||
190 | static inline int rc_request_io_range(struct riscom_board * const bp) | 191 | static int rc_request_io_range(struct riscom_board * const bp) |
191 | { | 192 | { |
192 | int i; | 193 | int i; |
193 | 194 | ||
194 | for (i = 0; i < RC_NIOPORT; i++) | 195 | for (i = 0; i < RC_NIOPORT; i++) |
195 | if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1, | 196 | if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1, |
196 | "RISCom/8")) { | 197 | "RISCom/8")) { |
197 | goto out_release; | 198 | goto out_release; |
@@ -200,42 +201,42 @@ static inline int rc_request_io_range(struct riscom_board * const bp) | |||
200 | out_release: | 201 | out_release: |
201 | printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n", | 202 | printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n", |
202 | board_No(bp), bp->base); | 203 | board_No(bp), bp->base); |
203 | while(--i >= 0) | 204 | while (--i >= 0) |
204 | release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); | 205 | release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); |
205 | return 1; | 206 | return 1; |
206 | } | 207 | } |
207 | 208 | ||
208 | static inline void rc_release_io_range(struct riscom_board * const bp) | 209 | static void rc_release_io_range(struct riscom_board * const bp) |
209 | { | 210 | { |
210 | int i; | 211 | int i; |
211 | 212 | ||
212 | for (i = 0; i < RC_NIOPORT; i++) | 213 | for (i = 0; i < RC_NIOPORT; i++) |
213 | release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); | 214 | release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); |
214 | } | 215 | } |
215 | 216 | ||
216 | /* Reset and setup CD180 chip */ | 217 | /* Reset and setup CD180 chip */ |
217 | static void __init rc_init_CD180(struct riscom_board const * bp) | 218 | static void __init rc_init_CD180(struct riscom_board const *bp) |
218 | { | 219 | { |
219 | unsigned long flags; | 220 | unsigned long flags; |
220 | 221 | ||
221 | spin_lock_irqsave(&riscom_lock, flags); | 222 | spin_lock_irqsave(&riscom_lock, flags); |
222 | 223 | ||
223 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ | 224 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ |
224 | rc_wait_CCR(bp); /* Wait for CCR ready */ | 225 | rc_wait_CCR(bp); /* Wait for CCR ready */ |
225 | rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ | 226 | rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ |
226 | spin_unlock_irqrestore(&riscom_lock, flags); | 227 | spin_unlock_irqrestore(&riscom_lock, flags); |
227 | msleep(50); /* Delay 0.05 sec */ | 228 | msleep(50); /* Delay 0.05 sec */ |
228 | spin_lock_irqsave(&riscom_lock, flags); | 229 | spin_lock_irqsave(&riscom_lock, flags); |
229 | rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ | 230 | rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ |
230 | rc_out(bp, CD180_GICR, 0); /* Clear all bits */ | 231 | rc_out(bp, CD180_GICR, 0); /* Clear all bits */ |
231 | rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ | 232 | rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ |
232 | rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for transmitter intr */ | 233 | rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for tx intr */ |
233 | rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for receiver intr */ | 234 | rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for rx intr */ |
234 | 235 | ||
235 | /* Setting up prescaler. We need 4 ticks per 1 ms */ | 236 | /* Setting up prescaler. We need 4 ticks per 1 ms */ |
236 | rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); | 237 | rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); |
237 | rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); | 238 | rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); |
238 | 239 | ||
239 | spin_unlock_irqrestore(&riscom_lock, flags); | 240 | spin_unlock_irqrestore(&riscom_lock, flags); |
240 | } | 241 | } |
241 | 242 | ||
@@ -245,12 +246,12 @@ static int __init rc_probe(struct riscom_board *bp) | |||
245 | unsigned char val1, val2; | 246 | unsigned char val1, val2; |
246 | int irqs = 0; | 247 | int irqs = 0; |
247 | int retries; | 248 | int retries; |
248 | 249 | ||
249 | bp->irq = 0; | 250 | bp->irq = 0; |
250 | 251 | ||
251 | if (rc_request_io_range(bp)) | 252 | if (rc_request_io_range(bp)) |
252 | return 1; | 253 | return 1; |
253 | 254 | ||
254 | /* Are the I/O ports here ? */ | 255 | /* Are the I/O ports here ? */ |
255 | rc_out(bp, CD180_PPRL, 0x5a); | 256 | rc_out(bp, CD180_PPRL, 0x5a); |
256 | outb(0xff, 0x80); | 257 | outb(0xff, 0x80); |
@@ -258,34 +259,34 @@ static int __init rc_probe(struct riscom_board *bp) | |||
258 | rc_out(bp, CD180_PPRL, 0xa5); | 259 | rc_out(bp, CD180_PPRL, 0xa5); |
259 | outb(0x00, 0x80); | 260 | outb(0x00, 0x80); |
260 | val2 = rc_in(bp, CD180_PPRL); | 261 | val2 = rc_in(bp, CD180_PPRL); |
261 | 262 | ||
262 | if ((val1 != 0x5a) || (val2 != 0xa5)) { | 263 | if ((val1 != 0x5a) || (val2 != 0xa5)) { |
263 | printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n", | 264 | printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n", |
264 | board_No(bp), bp->base); | 265 | board_No(bp), bp->base); |
265 | goto out_release; | 266 | goto out_release; |
266 | } | 267 | } |
267 | 268 | ||
268 | /* It's time to find IRQ for this board */ | 269 | /* It's time to find IRQ for this board */ |
269 | for (retries = 0; retries < 5 && irqs <= 0; retries++) { | 270 | for (retries = 0; retries < 5 && irqs <= 0; retries++) { |
270 | irqs = probe_irq_on(); | 271 | irqs = probe_irq_on(); |
271 | rc_init_CD180(bp); /* Reset CD180 chip */ | 272 | rc_init_CD180(bp); /* Reset CD180 chip */ |
272 | rc_out(bp, CD180_CAR, 2); /* Select port 2 */ | 273 | rc_out(bp, CD180_CAR, 2); /* Select port 2 */ |
273 | rc_wait_CCR(bp); | 274 | rc_wait_CCR(bp); |
274 | rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */ | 275 | rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */ |
275 | rc_out(bp, CD180_IER, IER_TXRDY); /* Enable tx empty intr */ | 276 | rc_out(bp, CD180_IER, IER_TXRDY);/* Enable tx empty intr */ |
276 | msleep(50); | 277 | msleep(50); |
277 | irqs = probe_irq_off(irqs); | 278 | irqs = probe_irq_off(irqs); |
278 | val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */ | 279 | val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */ |
279 | val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */ | 280 | val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */ |
280 | rc_init_CD180(bp); /* Reset CD180 again */ | 281 | rc_init_CD180(bp); /* Reset CD180 again */ |
281 | 282 | ||
282 | if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) { | 283 | if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) { |
283 | printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not " | 284 | printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not " |
284 | "found.\n", board_No(bp), bp->base); | 285 | "found.\n", board_No(bp), bp->base); |
285 | goto out_release; | 286 | goto out_release; |
286 | } | 287 | } |
287 | } | 288 | } |
288 | 289 | ||
289 | if (irqs <= 0) { | 290 | if (irqs <= 0) { |
290 | printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board " | 291 | printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board " |
291 | "at 0x%03x.\n", board_No(bp), bp->base); | 292 | "at 0x%03x.\n", board_No(bp), bp->base); |
@@ -293,113 +294,112 @@ static int __init rc_probe(struct riscom_board *bp) | |||
293 | } | 294 | } |
294 | bp->irq = irqs; | 295 | bp->irq = irqs; |
295 | bp->flags |= RC_BOARD_PRESENT; | 296 | bp->flags |= RC_BOARD_PRESENT; |
296 | 297 | ||
297 | printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at " | 298 | printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at " |
298 | "0x%03x, IRQ %d.\n", | 299 | "0x%03x, IRQ %d.\n", |
299 | board_No(bp), | 300 | board_No(bp), |
300 | (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */ | 301 | (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */ |
301 | bp->base, bp->irq); | 302 | bp->base, bp->irq); |
302 | 303 | ||
303 | return 0; | 304 | return 0; |
304 | out_release: | 305 | out_release: |
305 | rc_release_io_range(bp); | 306 | rc_release_io_range(bp); |
306 | return 1; | 307 | return 1; |
307 | } | 308 | } |
308 | 309 | ||
309 | /* | 310 | /* |
310 | * | 311 | * |
311 | * Interrupt processing routines. | 312 | * Interrupt processing routines. |
312 | * | 313 | * |
313 | */ | 314 | */ |
314 | 315 | ||
315 | static inline struct riscom_port * rc_get_port(struct riscom_board const * bp, | 316 | static struct riscom_port *rc_get_port(struct riscom_board const *bp, |
316 | unsigned char const * what) | 317 | unsigned char const *what) |
317 | { | 318 | { |
318 | unsigned char channel; | 319 | unsigned char channel; |
319 | struct riscom_port * port; | 320 | struct riscom_port *port; |
320 | 321 | ||
321 | channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF; | 322 | channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF; |
322 | if (channel < CD180_NCH) { | 323 | if (channel < CD180_NCH) { |
323 | port = &rc_port[board_No(bp) * RC_NPORT + channel]; | 324 | port = &rc_port[board_No(bp) * RC_NPORT + channel]; |
324 | if (port->flags & ASYNC_INITIALIZED) { | 325 | if (port->flags & ASYNC_INITIALIZED) |
325 | return port; | 326 | return port; |
326 | } | ||
327 | } | 327 | } |
328 | printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n", | 328 | printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n", |
329 | board_No(bp), what, channel); | 329 | board_No(bp), what, channel); |
330 | return NULL; | 330 | return NULL; |
331 | } | 331 | } |
332 | 332 | ||
333 | static inline void rc_receive_exc(struct riscom_board const * bp) | 333 | static void rc_receive_exc(struct riscom_board const *bp) |
334 | { | 334 | { |
335 | struct riscom_port *port; | 335 | struct riscom_port *port; |
336 | struct tty_struct *tty; | 336 | struct tty_struct *tty; |
337 | unsigned char status; | 337 | unsigned char status; |
338 | unsigned char ch, flag; | 338 | unsigned char ch, flag; |
339 | 339 | ||
340 | if (!(port = rc_get_port(bp, "Receive"))) | 340 | port = rc_get_port(bp, "Receive"); |
341 | if (port == NULL) | ||
341 | return; | 342 | return; |
342 | 343 | ||
343 | tty = port->tty; | 344 | tty = port->tty; |
344 | 345 | ||
345 | #ifdef RC_REPORT_OVERRUN | 346 | #ifdef RC_REPORT_OVERRUN |
346 | status = rc_in(bp, CD180_RCSR); | 347 | status = rc_in(bp, CD180_RCSR); |
347 | if (status & RCSR_OE) | 348 | if (status & RCSR_OE) |
348 | port->overrun++; | 349 | port->overrun++; |
349 | status &= port->mark_mask; | 350 | status &= port->mark_mask; |
350 | #else | 351 | #else |
351 | status = rc_in(bp, CD180_RCSR) & port->mark_mask; | 352 | status = rc_in(bp, CD180_RCSR) & port->mark_mask; |
352 | #endif | 353 | #endif |
353 | ch = rc_in(bp, CD180_RDR); | 354 | ch = rc_in(bp, CD180_RDR); |
354 | if (!status) { | 355 | if (!status) |
355 | return; | 356 | return; |
356 | } | ||
357 | if (status & RCSR_TOUT) { | 357 | if (status & RCSR_TOUT) { |
358 | printk(KERN_WARNING "rc%d: port %d: Receiver timeout. " | 358 | printk(KERN_WARNING "rc%d: port %d: Receiver timeout. " |
359 | "Hardware problems ?\n", | 359 | "Hardware problems ?\n", |
360 | board_No(bp), port_No(port)); | 360 | board_No(bp), port_No(port)); |
361 | return; | 361 | return; |
362 | 362 | ||
363 | } else if (status & RCSR_BREAK) { | 363 | } else if (status & RCSR_BREAK) { |
364 | printk(KERN_INFO "rc%d: port %d: Handling break...\n", | 364 | printk(KERN_INFO "rc%d: port %d: Handling break...\n", |
365 | board_No(bp), port_No(port)); | 365 | board_No(bp), port_No(port)); |
366 | flag = TTY_BREAK; | 366 | flag = TTY_BREAK; |
367 | if (port->flags & ASYNC_SAK) | 367 | if (port->flags & ASYNC_SAK) |
368 | do_SAK(tty); | 368 | do_SAK(tty); |
369 | 369 | ||
370 | } else if (status & RCSR_PE) | 370 | } else if (status & RCSR_PE) |
371 | flag = TTY_PARITY; | 371 | flag = TTY_PARITY; |
372 | 372 | ||
373 | else if (status & RCSR_FE) | 373 | else if (status & RCSR_FE) |
374 | flag = TTY_FRAME; | 374 | flag = TTY_FRAME; |
375 | 375 | ||
376 | else if (status & RCSR_OE) | 376 | else if (status & RCSR_OE) |
377 | flag = TTY_OVERRUN; | 377 | flag = TTY_OVERRUN; |
378 | |||
379 | else | 378 | else |
380 | flag = TTY_NORMAL; | 379 | flag = TTY_NORMAL; |
381 | 380 | ||
382 | tty_insert_flip_char(tty, ch, flag); | 381 | tty_insert_flip_char(tty, ch, flag); |
383 | tty_flip_buffer_push(tty); | 382 | tty_flip_buffer_push(tty); |
384 | } | 383 | } |
385 | 384 | ||
386 | static inline void rc_receive(struct riscom_board const * bp) | 385 | static void rc_receive(struct riscom_board const *bp) |
387 | { | 386 | { |
388 | struct riscom_port *port; | 387 | struct riscom_port *port; |
389 | struct tty_struct *tty; | 388 | struct tty_struct *tty; |
390 | unsigned char count; | 389 | unsigned char count; |
391 | 390 | ||
392 | if (!(port = rc_get_port(bp, "Receive"))) | 391 | port = rc_get_port(bp, "Receive"); |
392 | if (port == NULL) | ||
393 | return; | 393 | return; |
394 | 394 | ||
395 | tty = port->tty; | 395 | tty = port->tty; |
396 | 396 | ||
397 | count = rc_in(bp, CD180_RDCR); | 397 | count = rc_in(bp, CD180_RDCR); |
398 | 398 | ||
399 | #ifdef RC_REPORT_FIFO | 399 | #ifdef RC_REPORT_FIFO |
400 | port->hits[count > 8 ? 9 : count]++; | 400 | port->hits[count > 8 ? 9 : count]++; |
401 | #endif | 401 | #endif |
402 | 402 | ||
403 | while (count--) { | 403 | while (count--) { |
404 | if (tty_buffer_request_room(tty, 1) == 0) { | 404 | if (tty_buffer_request_room(tty, 1) == 0) { |
405 | printk(KERN_WARNING "rc%d: port %d: Working around " | 405 | printk(KERN_WARNING "rc%d: port %d: Working around " |
@@ -412,26 +412,26 @@ static inline void rc_receive(struct riscom_board const * bp) | |||
412 | tty_flip_buffer_push(tty); | 412 | tty_flip_buffer_push(tty); |
413 | } | 413 | } |
414 | 414 | ||
415 | static inline void rc_transmit(struct riscom_board const * bp) | 415 | static void rc_transmit(struct riscom_board const *bp) |
416 | { | 416 | { |
417 | struct riscom_port *port; | 417 | struct riscom_port *port; |
418 | struct tty_struct *tty; | 418 | struct tty_struct *tty; |
419 | unsigned char count; | 419 | unsigned char count; |
420 | 420 | ||
421 | 421 | port = rc_get_port(bp, "Transmit"); | |
422 | if (!(port = rc_get_port(bp, "Transmit"))) | 422 | if (port == NULL) |
423 | return; | 423 | return; |
424 | 424 | ||
425 | tty = port->tty; | 425 | tty = port->tty; |
426 | 426 | ||
427 | if (port->IER & IER_TXEMPTY) { | 427 | if (port->IER & IER_TXEMPTY) { |
428 | /* FIFO drained */ | 428 | /* FIFO drained */ |
429 | rc_out(bp, CD180_CAR, port_No(port)); | 429 | rc_out(bp, CD180_CAR, port_No(port)); |
430 | port->IER &= ~IER_TXEMPTY; | 430 | port->IER &= ~IER_TXEMPTY; |
431 | rc_out(bp, CD180_IER, port->IER); | 431 | rc_out(bp, CD180_IER, port->IER); |
432 | return; | 432 | return; |
433 | } | 433 | } |
434 | 434 | ||
435 | if ((port->xmit_cnt <= 0 && !port->break_length) | 435 | if ((port->xmit_cnt <= 0 && !port->break_length) |
436 | || tty->stopped || tty->hw_stopped) { | 436 | || tty->stopped || tty->hw_stopped) { |
437 | rc_out(bp, CD180_CAR, port_No(port)); | 437 | rc_out(bp, CD180_CAR, port_No(port)); |
@@ -439,7 +439,7 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
439 | rc_out(bp, CD180_IER, port->IER); | 439 | rc_out(bp, CD180_IER, port->IER); |
440 | return; | 440 | return; |
441 | } | 441 | } |
442 | 442 | ||
443 | if (port->break_length) { | 443 | if (port->break_length) { |
444 | if (port->break_length > 0) { | 444 | if (port->break_length > 0) { |
445 | if (port->COR2 & COR2_ETC) { | 445 | if (port->COR2 & COR2_ETC) { |
@@ -451,7 +451,8 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
451 | rc_out(bp, CD180_TDR, CD180_C_ESC); | 451 | rc_out(bp, CD180_TDR, CD180_C_ESC); |
452 | rc_out(bp, CD180_TDR, CD180_C_DELAY); | 452 | rc_out(bp, CD180_TDR, CD180_C_DELAY); |
453 | rc_out(bp, CD180_TDR, count); | 453 | rc_out(bp, CD180_TDR, count); |
454 | if (!(port->break_length -= count)) | 454 | port->break_length -= count; |
455 | if (port->break_length == 0) | ||
455 | port->break_length--; | 456 | port->break_length--; |
456 | } else { | 457 | } else { |
457 | rc_out(bp, CD180_TDR, CD180_C_ESC); | 458 | rc_out(bp, CD180_TDR, CD180_C_ESC); |
@@ -463,7 +464,7 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
463 | } | 464 | } |
464 | return; | 465 | return; |
465 | } | 466 | } |
466 | 467 | ||
467 | count = CD180_NFIFO; | 468 | count = CD180_NFIFO; |
468 | do { | 469 | do { |
469 | rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]); | 470 | rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]); |
@@ -471,7 +472,7 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
471 | if (--port->xmit_cnt <= 0) | 472 | if (--port->xmit_cnt <= 0) |
472 | break; | 473 | break; |
473 | } while (--count > 0); | 474 | } while (--count > 0); |
474 | 475 | ||
475 | if (port->xmit_cnt <= 0) { | 476 | if (port->xmit_cnt <= 0) { |
476 | rc_out(bp, CD180_CAR, port_No(port)); | 477 | rc_out(bp, CD180_CAR, port_No(port)); |
477 | port->IER &= ~IER_TXRDY; | 478 | port->IER &= ~IER_TXRDY; |
@@ -481,25 +482,26 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
481 | tty_wakeup(tty); | 482 | tty_wakeup(tty); |
482 | } | 483 | } |
483 | 484 | ||
484 | static inline void rc_check_modem(struct riscom_board const * bp) | 485 | static void rc_check_modem(struct riscom_board const *bp) |
485 | { | 486 | { |
486 | struct riscom_port *port; | 487 | struct riscom_port *port; |
487 | struct tty_struct *tty; | 488 | struct tty_struct *tty; |
488 | unsigned char mcr; | 489 | unsigned char mcr; |
489 | 490 | ||
490 | if (!(port = rc_get_port(bp, "Modem"))) | 491 | port = rc_get_port(bp, "Modem"); |
492 | if (port == NULL) | ||
491 | return; | 493 | return; |
492 | 494 | ||
493 | tty = port->tty; | 495 | tty = port->tty; |
494 | 496 | ||
495 | mcr = rc_in(bp, CD180_MCR); | 497 | mcr = rc_in(bp, CD180_MCR); |
496 | if (mcr & MCR_CDCHG) { | 498 | if (mcr & MCR_CDCHG) { |
497 | if (rc_in(bp, CD180_MSVR) & MSVR_CD) | 499 | if (rc_in(bp, CD180_MSVR) & MSVR_CD) |
498 | wake_up_interruptible(&port->open_wait); | 500 | wake_up_interruptible(&port->open_wait); |
499 | else | 501 | else |
500 | tty_hangup(tty); | 502 | tty_hangup(tty); |
501 | } | 503 | } |
502 | 504 | ||
503 | #ifdef RISCOM_BRAIN_DAMAGED_CTS | 505 | #ifdef RISCOM_BRAIN_DAMAGED_CTS |
504 | if (mcr & MCR_CTSCHG) { | 506 | if (mcr & MCR_CTSCHG) { |
505 | if (rc_in(bp, CD180_MSVR) & MSVR_CTS) { | 507 | if (rc_in(bp, CD180_MSVR) & MSVR_CTS) { |
@@ -526,13 +528,13 @@ static inline void rc_check_modem(struct riscom_board const * bp) | |||
526 | rc_out(bp, CD180_IER, port->IER); | 528 | rc_out(bp, CD180_IER, port->IER); |
527 | } | 529 | } |
528 | #endif /* RISCOM_BRAIN_DAMAGED_CTS */ | 530 | #endif /* RISCOM_BRAIN_DAMAGED_CTS */ |
529 | 531 | ||
530 | /* Clear change bits */ | 532 | /* Clear change bits */ |
531 | rc_out(bp, CD180_MCR, 0); | 533 | rc_out(bp, CD180_MCR, 0); |
532 | } | 534 | } |
533 | 535 | ||
534 | /* The main interrupt processing routine */ | 536 | /* The main interrupt processing routine */ |
535 | static irqreturn_t rc_interrupt(int dummy, void * dev_id) | 537 | static irqreturn_t rc_interrupt(int dummy, void *dev_id) |
536 | { | 538 | { |
537 | unsigned char status; | 539 | unsigned char status; |
538 | unsigned char ack; | 540 | unsigned char ack; |
@@ -547,13 +549,11 @@ static irqreturn_t rc_interrupt(int dummy, void * dev_id) | |||
547 | (RC_BSR_TOUT | RC_BSR_TINT | | 549 | (RC_BSR_TOUT | RC_BSR_TINT | |
548 | RC_BSR_MINT | RC_BSR_RINT))) { | 550 | RC_BSR_MINT | RC_BSR_RINT))) { |
549 | handled = 1; | 551 | handled = 1; |
550 | if (status & RC_BSR_TOUT) | 552 | if (status & RC_BSR_TOUT) |
551 | printk(KERN_WARNING "rc%d: Got timeout. Hardware " | 553 | printk(KERN_WARNING "rc%d: Got timeout. Hardware " |
552 | "error?\n", board_No(bp)); | 554 | "error?\n", board_No(bp)); |
553 | |||
554 | else if (status & RC_BSR_RINT) { | 555 | else if (status & RC_BSR_RINT) { |
555 | ack = rc_in(bp, RC_ACK_RINT); | 556 | ack = rc_in(bp, RC_ACK_RINT); |
556 | |||
557 | if (ack == (RC_ID | GIVR_IT_RCV)) | 557 | if (ack == (RC_ID | GIVR_IT_RCV)) |
558 | rc_receive(bp); | 558 | rc_receive(bp); |
559 | else if (ack == (RC_ID | GIVR_IT_REXC)) | 559 | else if (ack == (RC_ID | GIVR_IT_REXC)) |
@@ -562,29 +562,23 @@ static irqreturn_t rc_interrupt(int dummy, void * dev_id) | |||
562 | printk(KERN_WARNING "rc%d: Bad receive ack " | 562 | printk(KERN_WARNING "rc%d: Bad receive ack " |
563 | "0x%02x.\n", | 563 | "0x%02x.\n", |
564 | board_No(bp), ack); | 564 | board_No(bp), ack); |
565 | |||
566 | } else if (status & RC_BSR_TINT) { | 565 | } else if (status & RC_BSR_TINT) { |
567 | ack = rc_in(bp, RC_ACK_TINT); | 566 | ack = rc_in(bp, RC_ACK_TINT); |
568 | |||
569 | if (ack == (RC_ID | GIVR_IT_TX)) | 567 | if (ack == (RC_ID | GIVR_IT_TX)) |
570 | rc_transmit(bp); | 568 | rc_transmit(bp); |
571 | else | 569 | else |
572 | printk(KERN_WARNING "rc%d: Bad transmit ack " | 570 | printk(KERN_WARNING "rc%d: Bad transmit ack " |
573 | "0x%02x.\n", | 571 | "0x%02x.\n", |
574 | board_No(bp), ack); | 572 | board_No(bp), ack); |
575 | |||
576 | } else /* if (status & RC_BSR_MINT) */ { | 573 | } else /* if (status & RC_BSR_MINT) */ { |
577 | ack = rc_in(bp, RC_ACK_MINT); | 574 | ack = rc_in(bp, RC_ACK_MINT); |
578 | 575 | if (ack == (RC_ID | GIVR_IT_MODEM)) | |
579 | if (ack == (RC_ID | GIVR_IT_MODEM)) | ||
580 | rc_check_modem(bp); | 576 | rc_check_modem(bp); |
581 | else | 577 | else |
582 | printk(KERN_WARNING "rc%d: Bad modem ack " | 578 | printk(KERN_WARNING "rc%d: Bad modem ack " |
583 | "0x%02x.\n", | 579 | "0x%02x.\n", |
584 | board_No(bp), ack); | 580 | board_No(bp), ack); |
585 | 581 | } | |
586 | } | ||
587 | |||
588 | rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */ | 582 | rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */ |
589 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */ | 583 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */ |
590 | } | 584 | } |
@@ -596,24 +590,24 @@ static irqreturn_t rc_interrupt(int dummy, void * dev_id) | |||
596 | */ | 590 | */ |
597 | 591 | ||
598 | /* Called with disabled interrupts */ | 592 | /* Called with disabled interrupts */ |
599 | static int rc_setup_board(struct riscom_board * bp) | 593 | static int rc_setup_board(struct riscom_board *bp) |
600 | { | 594 | { |
601 | int error; | 595 | int error; |
602 | 596 | ||
603 | if (bp->flags & RC_BOARD_ACTIVE) | 597 | if (bp->flags & RC_BOARD_ACTIVE) |
604 | return 0; | 598 | return 0; |
605 | 599 | ||
606 | error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED, | 600 | error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED, |
607 | "RISCom/8", bp); | 601 | "RISCom/8", bp); |
608 | if (error) | 602 | if (error) |
609 | return error; | 603 | return error; |
610 | 604 | ||
611 | rc_out(bp, RC_CTOUT, 0); /* Just in case */ | 605 | rc_out(bp, RC_CTOUT, 0); /* Just in case */ |
612 | bp->DTR = ~0; | 606 | bp->DTR = ~0; |
613 | rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ | 607 | rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ |
614 | 608 | ||
615 | bp->flags |= RC_BOARD_ACTIVE; | 609 | bp->flags |= RC_BOARD_ACTIVE; |
616 | 610 | ||
617 | return 0; | 611 | return 0; |
618 | } | 612 | } |
619 | 613 | ||
@@ -622,40 +616,40 @@ static void rc_shutdown_board(struct riscom_board *bp) | |||
622 | { | 616 | { |
623 | if (!(bp->flags & RC_BOARD_ACTIVE)) | 617 | if (!(bp->flags & RC_BOARD_ACTIVE)) |
624 | return; | 618 | return; |
625 | 619 | ||
626 | bp->flags &= ~RC_BOARD_ACTIVE; | 620 | bp->flags &= ~RC_BOARD_ACTIVE; |
627 | 621 | ||
628 | free_irq(bp->irq, NULL); | 622 | free_irq(bp->irq, NULL); |
629 | 623 | ||
630 | bp->DTR = ~0; | 624 | bp->DTR = ~0; |
631 | rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ | 625 | rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ |
632 | 626 | ||
633 | } | 627 | } |
634 | 628 | ||
635 | /* | 629 | /* |
636 | * Setting up port characteristics. | 630 | * Setting up port characteristics. |
637 | * Must be called with disabled interrupts | 631 | * Must be called with disabled interrupts |
638 | */ | 632 | */ |
639 | static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | 633 | static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) |
640 | { | 634 | { |
641 | struct tty_struct *tty; | 635 | struct tty_struct *tty = port->tty; |
642 | unsigned long baud; | 636 | unsigned long baud; |
643 | long tmp; | 637 | long tmp; |
644 | unsigned char cor1 = 0, cor3 = 0; | 638 | unsigned char cor1 = 0, cor3 = 0; |
645 | unsigned char mcor1 = 0, mcor2 = 0; | 639 | unsigned char mcor1 = 0, mcor2 = 0; |
646 | 640 | ||
647 | if (!(tty = port->tty) || !tty->termios) | 641 | if (tty == NULL || tty->termios == NULL) |
648 | return; | 642 | return; |
649 | 643 | ||
650 | port->IER = 0; | 644 | port->IER = 0; |
651 | port->COR2 = 0; | 645 | port->COR2 = 0; |
652 | port->MSVR = MSVR_RTS; | 646 | port->MSVR = MSVR_RTS; |
653 | 647 | ||
654 | baud = tty_get_baud_rate(tty); | 648 | baud = tty_get_baud_rate(tty); |
655 | 649 | ||
656 | /* Select port on the board */ | 650 | /* Select port on the board */ |
657 | rc_out(bp, CD180_CAR, port_No(port)); | 651 | rc_out(bp, CD180_CAR, port_No(port)); |
658 | 652 | ||
659 | if (!baud) { | 653 | if (!baud) { |
660 | /* Drop DTR & exit */ | 654 | /* Drop DTR & exit */ |
661 | bp->DTR |= (1u << port_No(port)); | 655 | bp->DTR |= (1u << port_No(port)); |
@@ -666,69 +660,68 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | |||
666 | bp->DTR &= ~(1u << port_No(port)); | 660 | bp->DTR &= ~(1u << port_No(port)); |
667 | rc_out(bp, RC_DTR, bp->DTR); | 661 | rc_out(bp, RC_DTR, bp->DTR); |
668 | } | 662 | } |
669 | 663 | ||
670 | /* | 664 | /* |
671 | * Now we must calculate some speed depended things | 665 | * Now we must calculate some speed depended things |
672 | */ | 666 | */ |
673 | 667 | ||
674 | /* Set baud rate for port */ | 668 | /* Set baud rate for port */ |
675 | tmp = (((RC_OSCFREQ + baud/2) / baud + | 669 | tmp = (((RC_OSCFREQ + baud/2) / baud + |
676 | CD180_TPC/2) / CD180_TPC); | 670 | CD180_TPC/2) / CD180_TPC); |
677 | 671 | ||
678 | rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff); | 672 | rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff); |
679 | rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff); | 673 | rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff); |
680 | rc_out(bp, CD180_RBPRL, tmp & 0xff); | 674 | rc_out(bp, CD180_RBPRL, tmp & 0xff); |
681 | rc_out(bp, CD180_TBPRL, tmp & 0xff); | 675 | rc_out(bp, CD180_TBPRL, tmp & 0xff); |
682 | 676 | ||
683 | baud = (baud + 5) / 10; /* Estimated CPS */ | 677 | baud = (baud + 5) / 10; /* Estimated CPS */ |
684 | 678 | ||
685 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ | 679 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ |
686 | tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO; | 680 | tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO; |
687 | port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? | 681 | port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? |
688 | SERIAL_XMIT_SIZE - 1 : tmp); | 682 | SERIAL_XMIT_SIZE - 1 : tmp); |
689 | 683 | ||
690 | /* Receiver timeout will be transmission time for 1.5 chars */ | 684 | /* Receiver timeout will be transmission time for 1.5 chars */ |
691 | tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud; | 685 | tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud; |
692 | tmp = (tmp > 0xff) ? 0xff : tmp; | 686 | tmp = (tmp > 0xff) ? 0xff : tmp; |
693 | rc_out(bp, CD180_RTPR, tmp); | 687 | rc_out(bp, CD180_RTPR, tmp); |
694 | 688 | ||
695 | switch (C_CSIZE(tty)) { | 689 | switch (C_CSIZE(tty)) { |
696 | case CS5: | 690 | case CS5: |
697 | cor1 |= COR1_5BITS; | 691 | cor1 |= COR1_5BITS; |
698 | break; | 692 | break; |
699 | case CS6: | 693 | case CS6: |
700 | cor1 |= COR1_6BITS; | 694 | cor1 |= COR1_6BITS; |
701 | break; | 695 | break; |
702 | case CS7: | 696 | case CS7: |
703 | cor1 |= COR1_7BITS; | 697 | cor1 |= COR1_7BITS; |
704 | break; | 698 | break; |
705 | case CS8: | 699 | case CS8: |
706 | cor1 |= COR1_8BITS; | 700 | cor1 |= COR1_8BITS; |
707 | break; | 701 | break; |
708 | } | 702 | } |
709 | 703 | if (C_CSTOPB(tty)) | |
710 | if (C_CSTOPB(tty)) | ||
711 | cor1 |= COR1_2SB; | 704 | cor1 |= COR1_2SB; |
712 | 705 | ||
713 | cor1 |= COR1_IGNORE; | 706 | cor1 |= COR1_IGNORE; |
714 | if (C_PARENB(tty)) { | 707 | if (C_PARENB(tty)) { |
715 | cor1 |= COR1_NORMPAR; | 708 | cor1 |= COR1_NORMPAR; |
716 | if (C_PARODD(tty)) | 709 | if (C_PARODD(tty)) |
717 | cor1 |= COR1_ODDP; | 710 | cor1 |= COR1_ODDP; |
718 | if (I_INPCK(tty)) | 711 | if (I_INPCK(tty)) |
719 | cor1 &= ~COR1_IGNORE; | 712 | cor1 &= ~COR1_IGNORE; |
720 | } | 713 | } |
721 | /* Set marking of some errors */ | 714 | /* Set marking of some errors */ |
722 | port->mark_mask = RCSR_OE | RCSR_TOUT; | 715 | port->mark_mask = RCSR_OE | RCSR_TOUT; |
723 | if (I_INPCK(tty)) | 716 | if (I_INPCK(tty)) |
724 | port->mark_mask |= RCSR_FE | RCSR_PE; | 717 | port->mark_mask |= RCSR_FE | RCSR_PE; |
725 | if (I_BRKINT(tty) || I_PARMRK(tty)) | 718 | if (I_BRKINT(tty) || I_PARMRK(tty)) |
726 | port->mark_mask |= RCSR_BREAK; | 719 | port->mark_mask |= RCSR_BREAK; |
727 | if (I_IGNPAR(tty)) | 720 | if (I_IGNPAR(tty)) |
728 | port->mark_mask &= ~(RCSR_FE | RCSR_PE); | 721 | port->mark_mask &= ~(RCSR_FE | RCSR_PE); |
729 | if (I_IGNBRK(tty)) { | 722 | if (I_IGNBRK(tty)) { |
730 | port->mark_mask &= ~RCSR_BREAK; | 723 | port->mark_mask &= ~RCSR_BREAK; |
731 | if (I_IGNPAR(tty)) | 724 | if (I_IGNPAR(tty)) |
732 | /* Real raw mode. Ignore all */ | 725 | /* Real raw mode. Ignore all */ |
733 | port->mark_mask &= ~RCSR_OE; | 726 | port->mark_mask &= ~RCSR_OE; |
734 | } | 727 | } |
@@ -738,7 +731,8 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | |||
738 | port->IER |= IER_DSR | IER_CTS; | 731 | port->IER |= IER_DSR | IER_CTS; |
739 | mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; | 732 | mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; |
740 | mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; | 733 | mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; |
741 | tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR)); | 734 | tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & |
735 | (MSVR_CTS|MSVR_DSR)); | ||
742 | #else | 736 | #else |
743 | port->COR2 |= COR2_CTSAE; | 737 | port->COR2 |= COR2_CTSAE; |
744 | #endif | 738 | #endif |
@@ -761,13 +755,13 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | |||
761 | mcor1 |= MCOR1_CDZD; | 755 | mcor1 |= MCOR1_CDZD; |
762 | mcor2 |= MCOR2_CDOD; | 756 | mcor2 |= MCOR2_CDOD; |
763 | } | 757 | } |
764 | 758 | ||
765 | if (C_CREAD(tty)) | 759 | if (C_CREAD(tty)) |
766 | /* Enable receiver */ | 760 | /* Enable receiver */ |
767 | port->IER |= IER_RXD; | 761 | port->IER |= IER_RXD; |
768 | 762 | ||
769 | /* Set input FIFO size (1-8 bytes) */ | 763 | /* Set input FIFO size (1-8 bytes) */ |
770 | cor3 |= RISCOM_RXFIFO; | 764 | cor3 |= RISCOM_RXFIFO; |
771 | /* Setting up CD180 channel registers */ | 765 | /* Setting up CD180 channel registers */ |
772 | rc_out(bp, CD180_COR1, cor1); | 766 | rc_out(bp, CD180_COR1, cor1); |
773 | rc_out(bp, CD180_COR2, port->COR2); | 767 | rc_out(bp, CD180_COR2, port->COR2); |
@@ -791,36 +785,30 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | |||
791 | static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) | 785 | static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) |
792 | { | 786 | { |
793 | unsigned long flags; | 787 | unsigned long flags; |
794 | 788 | ||
795 | if (port->flags & ASYNC_INITIALIZED) | 789 | if (port->flags & ASYNC_INITIALIZED) |
796 | return 0; | 790 | return 0; |
797 | 791 | ||
798 | if (!port->xmit_buf) { | 792 | if (!port->xmit_buf) { |
799 | /* We may sleep in get_zeroed_page() */ | 793 | /* We may sleep in get_zeroed_page() */ |
800 | unsigned long tmp; | 794 | unsigned long tmp = get_zeroed_page(GFP_KERNEL); |
801 | 795 | if (tmp == 0) | |
802 | if (!(tmp = get_zeroed_page(GFP_KERNEL))) | ||
803 | return -ENOMEM; | 796 | return -ENOMEM; |
804 | 797 | if (port->xmit_buf) | |
805 | if (port->xmit_buf) { | ||
806 | free_page(tmp); | 798 | free_page(tmp); |
807 | return -ERESTARTSYS; | 799 | else |
808 | } | 800 | port->xmit_buf = (unsigned char *) tmp; |
809 | port->xmit_buf = (unsigned char *) tmp; | ||
810 | } | 801 | } |
811 | |||
812 | spin_lock_irqsave(&riscom_lock, flags); | 802 | spin_lock_irqsave(&riscom_lock, flags); |
813 | 803 | ||
814 | if (port->tty) | 804 | if (port->tty) |
815 | clear_bit(TTY_IO_ERROR, &port->tty->flags); | 805 | clear_bit(TTY_IO_ERROR, &port->tty->flags); |
816 | 806 | if (port->count == 1) | |
817 | if (port->count == 1) | ||
818 | bp->count++; | 807 | bp->count++; |
819 | |||
820 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 808 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; |
821 | rc_change_speed(bp, port); | 809 | rc_change_speed(bp, port); |
822 | port->flags |= ASYNC_INITIALIZED; | 810 | port->flags |= ASYNC_INITIALIZED; |
823 | 811 | ||
824 | spin_unlock_irqrestore(&riscom_lock, flags); | 812 | spin_unlock_irqrestore(&riscom_lock, flags); |
825 | return 0; | 813 | return 0; |
826 | } | 814 | } |
@@ -829,38 +817,39 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) | |||
829 | static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port) | 817 | static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port) |
830 | { | 818 | { |
831 | struct tty_struct *tty; | 819 | struct tty_struct *tty; |
832 | 820 | ||
833 | if (!(port->flags & ASYNC_INITIALIZED)) | 821 | if (!(port->flags & ASYNC_INITIALIZED)) |
834 | return; | 822 | return; |
835 | 823 | ||
836 | #ifdef RC_REPORT_OVERRUN | 824 | #ifdef RC_REPORT_OVERRUN |
837 | printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", | 825 | printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", |
838 | board_No(bp), port_No(port), port->overrun); | 826 | board_No(bp), port_No(port), port->overrun); |
839 | #endif | 827 | #endif |
840 | #ifdef RC_REPORT_FIFO | 828 | #ifdef RC_REPORT_FIFO |
841 | { | 829 | { |
842 | int i; | 830 | int i; |
843 | 831 | ||
844 | printk(KERN_INFO "rc%d: port %d: FIFO hits [ ", | 832 | printk(KERN_INFO "rc%d: port %d: FIFO hits [ ", |
845 | board_No(bp), port_No(port)); | 833 | board_No(bp), port_No(port)); |
846 | for (i = 0; i < 10; i++) { | 834 | for (i = 0; i < 10; i++) |
847 | printk("%ld ", port->hits[i]); | 835 | printk("%ld ", port->hits[i]); |
848 | } | ||
849 | printk("].\n"); | 836 | printk("].\n"); |
850 | } | 837 | } |
851 | #endif | 838 | #endif |
852 | if (port->xmit_buf) { | 839 | if (port->xmit_buf) { |
853 | free_page((unsigned long) port->xmit_buf); | 840 | free_page((unsigned long) port->xmit_buf); |
854 | port->xmit_buf = NULL; | 841 | port->xmit_buf = NULL; |
855 | } | 842 | } |
856 | 843 | ||
857 | if (!(tty = port->tty) || C_HUPCL(tty)) { | 844 | tty = port->tty; |
845 | |||
846 | if (tty == NULL || C_HUPCL(tty)) { | ||
858 | /* Drop DTR */ | 847 | /* Drop DTR */ |
859 | bp->DTR |= (1u << port_No(port)); | 848 | bp->DTR |= (1u << port_No(port)); |
860 | rc_out(bp, RC_DTR, bp->DTR); | 849 | rc_out(bp, RC_DTR, bp->DTR); |
861 | } | 850 | } |
862 | 851 | ||
863 | /* Select port */ | 852 | /* Select port */ |
864 | rc_out(bp, CD180_CAR, port_No(port)); | 853 | rc_out(bp, CD180_CAR, port_No(port)); |
865 | /* Reset port */ | 854 | /* Reset port */ |
866 | rc_wait_CCR(bp); | 855 | rc_wait_CCR(bp); |
@@ -868,28 +857,26 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port) | |||
868 | /* Disable all interrupts from this port */ | 857 | /* Disable all interrupts from this port */ |
869 | port->IER = 0; | 858 | port->IER = 0; |
870 | rc_out(bp, CD180_IER, port->IER); | 859 | rc_out(bp, CD180_IER, port->IER); |
871 | 860 | ||
872 | if (tty) | 861 | if (tty) |
873 | set_bit(TTY_IO_ERROR, &tty->flags); | 862 | set_bit(TTY_IO_ERROR, &tty->flags); |
874 | port->flags &= ~ASYNC_INITIALIZED; | 863 | port->flags &= ~ASYNC_INITIALIZED; |
875 | 864 | ||
876 | if (--bp->count < 0) { | 865 | if (--bp->count < 0) { |
877 | printk(KERN_INFO "rc%d: rc_shutdown_port: " | 866 | printk(KERN_INFO "rc%d: rc_shutdown_port: " |
878 | "bad board count: %d\n", | 867 | "bad board count: %d\n", |
879 | board_No(bp), bp->count); | 868 | board_No(bp), bp->count); |
880 | bp->count = 0; | 869 | bp->count = 0; |
881 | } | 870 | } |
882 | |||
883 | /* | 871 | /* |
884 | * If this is the last opened port on the board | 872 | * If this is the last opened port on the board |
885 | * shutdown whole board | 873 | * shutdown whole board |
886 | */ | 874 | */ |
887 | if (!bp->count) | 875 | if (!bp->count) |
888 | rc_shutdown_board(bp); | 876 | rc_shutdown_board(bp); |
889 | } | 877 | } |
890 | 878 | ||
891 | 879 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | |
892 | static int block_til_ready(struct tty_struct *tty, struct file * filp, | ||
893 | struct riscom_port *port) | 880 | struct riscom_port *port) |
894 | { | 881 | { |
895 | DECLARE_WAITQUEUE(wait, current); | 882 | DECLARE_WAITQUEUE(wait, current); |
@@ -921,7 +908,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
921 | return 0; | 908 | return 0; |
922 | } | 909 | } |
923 | 910 | ||
924 | if (C_CLOCAL(tty)) | 911 | if (C_CLOCAL(tty)) |
925 | do_clocal = 1; | 912 | do_clocal = 1; |
926 | 913 | ||
927 | /* | 914 | /* |
@@ -959,7 +946,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
959 | if (port->flags & ASYNC_HUP_NOTIFY) | 946 | if (port->flags & ASYNC_HUP_NOTIFY) |
960 | retval = -EAGAIN; | 947 | retval = -EAGAIN; |
961 | else | 948 | else |
962 | retval = -ERESTARTSYS; | 949 | retval = -ERESTARTSYS; |
963 | break; | 950 | break; |
964 | } | 951 | } |
965 | if (!(port->flags & ASYNC_CLOSING) && | 952 | if (!(port->flags & ASYNC_CLOSING) && |
@@ -978,41 +965,39 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
978 | port->blocked_open--; | 965 | port->blocked_open--; |
979 | if (retval) | 966 | if (retval) |
980 | return retval; | 967 | return retval; |
981 | 968 | ||
982 | port->flags |= ASYNC_NORMAL_ACTIVE; | 969 | port->flags |= ASYNC_NORMAL_ACTIVE; |
983 | return 0; | 970 | return 0; |
984 | } | 971 | } |
985 | 972 | ||
986 | static int rc_open(struct tty_struct * tty, struct file * filp) | 973 | static int rc_open(struct tty_struct *tty, struct file *filp) |
987 | { | 974 | { |
988 | int board; | 975 | int board; |
989 | int error; | 976 | int error; |
990 | struct riscom_port * port; | 977 | struct riscom_port *port; |
991 | struct riscom_board * bp; | 978 | struct riscom_board *bp; |
992 | 979 | ||
993 | board = RC_BOARD(tty->index); | 980 | board = RC_BOARD(tty->index); |
994 | if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) | 981 | if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) |
995 | return -ENODEV; | 982 | return -ENODEV; |
996 | 983 | ||
997 | bp = &rc_board[board]; | 984 | bp = &rc_board[board]; |
998 | port = rc_port + board * RC_NPORT + RC_PORT(tty->index); | 985 | port = rc_port + board * RC_NPORT + RC_PORT(tty->index); |
999 | if (rc_paranoia_check(port, tty->name, "rc_open")) | 986 | if (rc_paranoia_check(port, tty->name, "rc_open")) |
1000 | return -ENODEV; | 987 | return -ENODEV; |
1001 | 988 | ||
1002 | if ((error = rc_setup_board(bp))) | 989 | error = rc_setup_board(bp); |
990 | if (error) | ||
1003 | return error; | 991 | return error; |
1004 | 992 | ||
1005 | port->count++; | 993 | port->count++; |
1006 | tty->driver_data = port; | 994 | tty->driver_data = port; |
1007 | port->tty = tty; | 995 | port->tty = tty; |
1008 | 996 | ||
1009 | if ((error = rc_setup_port(bp, port))) | 997 | error = rc_setup_port(bp, port); |
1010 | return error; | 998 | if (error == 0) |
1011 | 999 | error = block_til_ready(tty, filp, port); | |
1012 | if ((error = block_til_ready(tty, filp, port))) | 1000 | return error; |
1013 | return error; | ||
1014 | |||
1015 | return 0; | ||
1016 | } | 1001 | } |
1017 | 1002 | ||
1018 | static void rc_flush_buffer(struct tty_struct *tty) | 1003 | static void rc_flush_buffer(struct tty_struct *tty) |
@@ -1024,22 +1009,19 @@ static void rc_flush_buffer(struct tty_struct *tty) | |||
1024 | return; | 1009 | return; |
1025 | 1010 | ||
1026 | spin_lock_irqsave(&riscom_lock, flags); | 1011 | spin_lock_irqsave(&riscom_lock, flags); |
1027 | |||
1028 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 1012 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; |
1029 | |||
1030 | spin_unlock_irqrestore(&riscom_lock, flags); | 1013 | spin_unlock_irqrestore(&riscom_lock, flags); |
1031 | 1014 | ||
1032 | tty_wakeup(tty); | 1015 | tty_wakeup(tty); |
1033 | } | 1016 | } |
1034 | 1017 | ||
1035 | 1018 | static void rc_close(struct tty_struct *tty, struct file *filp) | |
1036 | static void rc_close(struct tty_struct * tty, struct file * filp) | ||
1037 | { | 1019 | { |
1038 | struct riscom_port *port = (struct riscom_port *) tty->driver_data; | 1020 | struct riscom_port *port = (struct riscom_port *) tty->driver_data; |
1039 | struct riscom_board *bp; | 1021 | struct riscom_board *bp; |
1040 | unsigned long flags; | 1022 | unsigned long flags; |
1041 | unsigned long timeout; | 1023 | unsigned long timeout; |
1042 | 1024 | ||
1043 | if (!port || rc_paranoia_check(port, tty->name, "close")) | 1025 | if (!port || rc_paranoia_check(port, tty->name, "close")) |
1044 | return; | 1026 | return; |
1045 | 1027 | ||
@@ -1047,7 +1029,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1047 | 1029 | ||
1048 | if (tty_hung_up_p(filp)) | 1030 | if (tty_hung_up_p(filp)) |
1049 | goto out; | 1031 | goto out; |
1050 | 1032 | ||
1051 | bp = port_Board(port); | 1033 | bp = port_Board(port); |
1052 | if ((tty->count == 1) && (port->count != 1)) { | 1034 | if ((tty->count == 1) && (port->count != 1)) { |
1053 | printk(KERN_INFO "rc%d: rc_close: bad port count;" | 1035 | printk(KERN_INFO "rc%d: rc_close: bad port count;" |
@@ -1065,7 +1047,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1065 | goto out; | 1047 | goto out; |
1066 | port->flags |= ASYNC_CLOSING; | 1048 | port->flags |= ASYNC_CLOSING; |
1067 | /* | 1049 | /* |
1068 | * Now we wait for the transmit buffer to clear; and we notify | 1050 | * Now we wait for the transmit buffer to clear; and we notify |
1069 | * the line discipline to only process XON/XOFF characters. | 1051 | * the line discipline to only process XON/XOFF characters. |
1070 | */ | 1052 | */ |
1071 | tty->closing = 1; | 1053 | tty->closing = 1; |
@@ -1088,8 +1070,8 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1088 | * has completely drained; this is especially | 1070 | * has completely drained; this is especially |
1089 | * important if there is a transmit FIFO! | 1071 | * important if there is a transmit FIFO! |
1090 | */ | 1072 | */ |
1091 | timeout = jiffies+HZ; | 1073 | timeout = jiffies + HZ; |
1092 | while(port->IER & IER_TXEMPTY) { | 1074 | while (port->IER & IER_TXEMPTY) { |
1093 | msleep_interruptible(jiffies_to_msecs(port->timeout)); | 1075 | msleep_interruptible(jiffies_to_msecs(port->timeout)); |
1094 | if (time_after(jiffies, timeout)) | 1076 | if (time_after(jiffies, timeout)) |
1095 | break; | 1077 | break; |
@@ -1102,9 +1084,8 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1102 | tty->closing = 0; | 1084 | tty->closing = 0; |
1103 | port->tty = NULL; | 1085 | port->tty = NULL; |
1104 | if (port->blocked_open) { | 1086 | if (port->blocked_open) { |
1105 | if (port->close_delay) { | 1087 | if (port->close_delay) |
1106 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); | 1088 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); |
1107 | } | ||
1108 | wake_up_interruptible(&port->open_wait); | 1089 | wake_up_interruptible(&port->open_wait); |
1109 | } | 1090 | } |
1110 | port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1091 | port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
@@ -1114,17 +1095,17 @@ out: | |||
1114 | spin_unlock_irqrestore(&riscom_lock, flags); | 1095 | spin_unlock_irqrestore(&riscom_lock, flags); |
1115 | } | 1096 | } |
1116 | 1097 | ||
1117 | static int rc_write(struct tty_struct * tty, | 1098 | static int rc_write(struct tty_struct *tty, |
1118 | const unsigned char *buf, int count) | 1099 | const unsigned char *buf, int count) |
1119 | { | 1100 | { |
1120 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1101 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1121 | struct riscom_board *bp; | 1102 | struct riscom_board *bp; |
1122 | int c, total = 0; | 1103 | int c, total = 0; |
1123 | unsigned long flags; | 1104 | unsigned long flags; |
1124 | 1105 | ||
1125 | if (rc_paranoia_check(port, tty->name, "rc_write")) | 1106 | if (rc_paranoia_check(port, tty->name, "rc_write")) |
1126 | return 0; | 1107 | return 0; |
1127 | 1108 | ||
1128 | bp = port_Board(port); | 1109 | bp = port_Board(port); |
1129 | 1110 | ||
1130 | if (!tty || !port->xmit_buf) | 1111 | if (!tty || !port->xmit_buf) |
@@ -1161,7 +1142,7 @@ static int rc_write(struct tty_struct * tty, | |||
1161 | return total; | 1142 | return total; |
1162 | } | 1143 | } |
1163 | 1144 | ||
1164 | static int rc_put_char(struct tty_struct * tty, unsigned char ch) | 1145 | static int rc_put_char(struct tty_struct *tty, unsigned char ch) |
1165 | { | 1146 | { |
1166 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1147 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1167 | unsigned long flags; | 1148 | unsigned long flags; |
@@ -1174,7 +1155,7 @@ static int rc_put_char(struct tty_struct * tty, unsigned char ch) | |||
1174 | return 0; | 1155 | return 0; |
1175 | 1156 | ||
1176 | spin_lock_irqsave(&riscom_lock, flags); | 1157 | spin_lock_irqsave(&riscom_lock, flags); |
1177 | 1158 | ||
1178 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) | 1159 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) |
1179 | goto out; | 1160 | goto out; |
1180 | 1161 | ||
@@ -1188,14 +1169,14 @@ out: | |||
1188 | return ret; | 1169 | return ret; |
1189 | } | 1170 | } |
1190 | 1171 | ||
1191 | static void rc_flush_chars(struct tty_struct * tty) | 1172 | static void rc_flush_chars(struct tty_struct *tty) |
1192 | { | 1173 | { |
1193 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1174 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1194 | unsigned long flags; | 1175 | unsigned long flags; |
1195 | 1176 | ||
1196 | if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) | 1177 | if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) |
1197 | return; | 1178 | return; |
1198 | 1179 | ||
1199 | if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || | 1180 | if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || |
1200 | !port->xmit_buf) | 1181 | !port->xmit_buf) |
1201 | return; | 1182 | return; |
@@ -1209,11 +1190,11 @@ static void rc_flush_chars(struct tty_struct * tty) | |||
1209 | spin_unlock_irqrestore(&riscom_lock, flags); | 1190 | spin_unlock_irqrestore(&riscom_lock, flags); |
1210 | } | 1191 | } |
1211 | 1192 | ||
1212 | static int rc_write_room(struct tty_struct * tty) | 1193 | static int rc_write_room(struct tty_struct *tty) |
1213 | { | 1194 | { |
1214 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1195 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1215 | int ret; | 1196 | int ret; |
1216 | 1197 | ||
1217 | if (rc_paranoia_check(port, tty->name, "rc_write_room")) | 1198 | if (rc_paranoia_check(port, tty->name, "rc_write_room")) |
1218 | return 0; | 1199 | return 0; |
1219 | 1200 | ||
@@ -1226,17 +1207,17 @@ static int rc_write_room(struct tty_struct * tty) | |||
1226 | static int rc_chars_in_buffer(struct tty_struct *tty) | 1207 | static int rc_chars_in_buffer(struct tty_struct *tty) |
1227 | { | 1208 | { |
1228 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1209 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1229 | 1210 | ||
1230 | if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer")) | 1211 | if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer")) |
1231 | return 0; | 1212 | return 0; |
1232 | 1213 | ||
1233 | return port->xmit_cnt; | 1214 | return port->xmit_cnt; |
1234 | } | 1215 | } |
1235 | 1216 | ||
1236 | static int rc_tiocmget(struct tty_struct *tty, struct file *file) | 1217 | static int rc_tiocmget(struct tty_struct *tty, struct file *file) |
1237 | { | 1218 | { |
1238 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1219 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1239 | struct riscom_board * bp; | 1220 | struct riscom_board *bp; |
1240 | unsigned char status; | 1221 | unsigned char status; |
1241 | unsigned int result; | 1222 | unsigned int result; |
1242 | unsigned long flags; | 1223 | unsigned long flags; |
@@ -1295,11 +1276,11 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file, | |||
1295 | return 0; | 1276 | return 0; |
1296 | } | 1277 | } |
1297 | 1278 | ||
1298 | static inline void rc_send_break(struct riscom_port * port, unsigned long length) | 1279 | static void rc_send_break(struct riscom_port *port, unsigned long length) |
1299 | { | 1280 | { |
1300 | struct riscom_board *bp = port_Board(port); | 1281 | struct riscom_board *bp = port_Board(port); |
1301 | unsigned long flags; | 1282 | unsigned long flags; |
1302 | 1283 | ||
1303 | spin_lock_irqsave(&riscom_lock, flags); | 1284 | spin_lock_irqsave(&riscom_lock, flags); |
1304 | 1285 | ||
1305 | port->break_length = RISCOM_TPS / HZ * length; | 1286 | port->break_length = RISCOM_TPS / HZ * length; |
@@ -1315,17 +1296,17 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length | |||
1315 | spin_unlock_irqrestore(&riscom_lock, flags); | 1296 | spin_unlock_irqrestore(&riscom_lock, flags); |
1316 | } | 1297 | } |
1317 | 1298 | ||
1318 | static inline int rc_set_serial_info(struct riscom_port * port, | 1299 | static int rc_set_serial_info(struct riscom_port *port, |
1319 | struct serial_struct __user * newinfo) | 1300 | struct serial_struct __user *newinfo) |
1320 | { | 1301 | { |
1321 | struct serial_struct tmp; | 1302 | struct serial_struct tmp; |
1322 | struct riscom_board *bp = port_Board(port); | 1303 | struct riscom_board *bp = port_Board(port); |
1323 | int change_speed; | 1304 | int change_speed; |
1324 | 1305 | ||
1325 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) | 1306 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) |
1326 | return -EFAULT; | 1307 | return -EFAULT; |
1327 | 1308 | ||
1328 | #if 0 | 1309 | #if 0 |
1329 | if ((tmp.irq != bp->irq) || | 1310 | if ((tmp.irq != bp->irq) || |
1330 | (tmp.port != bp->base) || | 1311 | (tmp.port != bp->base) || |
1331 | (tmp.type != PORT_CIRRUS) || | 1312 | (tmp.type != PORT_CIRRUS) || |
@@ -1334,16 +1315,16 @@ static inline int rc_set_serial_info(struct riscom_port * port, | |||
1334 | (tmp.xmit_fifo_size != CD180_NFIFO) || | 1315 | (tmp.xmit_fifo_size != CD180_NFIFO) || |
1335 | (tmp.flags & ~RISCOM_LEGAL_FLAGS)) | 1316 | (tmp.flags & ~RISCOM_LEGAL_FLAGS)) |
1336 | return -EINVAL; | 1317 | return -EINVAL; |
1337 | #endif | 1318 | #endif |
1338 | 1319 | ||
1339 | change_speed = ((port->flags & ASYNC_SPD_MASK) != | 1320 | change_speed = ((port->flags & ASYNC_SPD_MASK) != |
1340 | (tmp.flags & ASYNC_SPD_MASK)); | 1321 | (tmp.flags & ASYNC_SPD_MASK)); |
1341 | 1322 | ||
1342 | if (!capable(CAP_SYS_ADMIN)) { | 1323 | if (!capable(CAP_SYS_ADMIN)) { |
1343 | if ((tmp.close_delay != port->close_delay) || | 1324 | if ((tmp.close_delay != port->close_delay) || |
1344 | (tmp.closing_wait != port->closing_wait) || | 1325 | (tmp.closing_wait != port->closing_wait) || |
1345 | ((tmp.flags & ~ASYNC_USR_MASK) != | 1326 | ((tmp.flags & ~ASYNC_USR_MASK) != |
1346 | (port->flags & ~ASYNC_USR_MASK))) | 1327 | (port->flags & ~ASYNC_USR_MASK))) |
1347 | return -EPERM; | 1328 | return -EPERM; |
1348 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | | 1329 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | |
1349 | (tmp.flags & ASYNC_USR_MASK)); | 1330 | (tmp.flags & ASYNC_USR_MASK)); |
@@ -1363,12 +1344,12 @@ static inline int rc_set_serial_info(struct riscom_port * port, | |||
1363 | return 0; | 1344 | return 0; |
1364 | } | 1345 | } |
1365 | 1346 | ||
1366 | static inline int rc_get_serial_info(struct riscom_port * port, | 1347 | static int rc_get_serial_info(struct riscom_port *port, |
1367 | struct serial_struct __user *retinfo) | 1348 | struct serial_struct __user *retinfo) |
1368 | { | 1349 | { |
1369 | struct serial_struct tmp; | 1350 | struct serial_struct tmp; |
1370 | struct riscom_board *bp = port_Board(port); | 1351 | struct riscom_board *bp = port_Board(port); |
1371 | 1352 | ||
1372 | memset(&tmp, 0, sizeof(tmp)); | 1353 | memset(&tmp, 0, sizeof(tmp)); |
1373 | tmp.type = PORT_CIRRUS; | 1354 | tmp.type = PORT_CIRRUS; |
1374 | tmp.line = port - rc_port; | 1355 | tmp.line = port - rc_port; |
@@ -1382,19 +1363,18 @@ static inline int rc_get_serial_info(struct riscom_port * port, | |||
1382 | return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 1363 | return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
1383 | } | 1364 | } |
1384 | 1365 | ||
1385 | static int rc_ioctl(struct tty_struct * tty, struct file * filp, | 1366 | static int rc_ioctl(struct tty_struct *tty, struct file *filp, |
1386 | unsigned int cmd, unsigned long arg) | 1367 | unsigned int cmd, unsigned long arg) |
1387 | |||
1388 | { | 1368 | { |
1389 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1369 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1390 | void __user *argp = (void __user *)arg; | 1370 | void __user *argp = (void __user *)arg; |
1391 | int retval = 0; | 1371 | int retval = 0; |
1392 | 1372 | ||
1393 | if (rc_paranoia_check(port, tty->name, "rc_ioctl")) | 1373 | if (rc_paranoia_check(port, tty->name, "rc_ioctl")) |
1394 | return -ENODEV; | 1374 | return -ENODEV; |
1395 | 1375 | ||
1396 | switch (cmd) { | 1376 | switch (cmd) { |
1397 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 1377 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
1398 | retval = tty_check_change(tty); | 1378 | retval = tty_check_change(tty); |
1399 | if (retval) | 1379 | if (retval) |
1400 | return retval; | 1380 | return retval; |
@@ -1402,42 +1382,40 @@ static int rc_ioctl(struct tty_struct * tty, struct file * filp, | |||
1402 | if (!arg) | 1382 | if (!arg) |
1403 | rc_send_break(port, HZ/4); /* 1/4 second */ | 1383 | rc_send_break(port, HZ/4); /* 1/4 second */ |
1404 | break; | 1384 | break; |
1405 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | 1385 | case TCSBRKP: /* support for POSIX tcsendbreak() */ |
1406 | retval = tty_check_change(tty); | 1386 | retval = tty_check_change(tty); |
1407 | if (retval) | 1387 | if (retval) |
1408 | return retval; | 1388 | return retval; |
1409 | tty_wait_until_sent(tty, 0); | 1389 | tty_wait_until_sent(tty, 0); |
1410 | rc_send_break(port, arg ? arg*(HZ/10) : HZ/4); | 1390 | rc_send_break(port, arg ? arg*(HZ/10) : HZ/4); |
1411 | break; | 1391 | break; |
1412 | case TIOCGSERIAL: | 1392 | case TIOCGSERIAL: |
1413 | lock_kernel(); | 1393 | lock_kernel(); |
1414 | retval = rc_get_serial_info(port, argp); | 1394 | retval = rc_get_serial_info(port, argp); |
1415 | unlock_kernel(); | 1395 | unlock_kernel(); |
1416 | break; | 1396 | break; |
1417 | case TIOCSSERIAL: | 1397 | case TIOCSSERIAL: |
1418 | lock_kernel(); | 1398 | lock_kernel(); |
1419 | retval = rc_set_serial_info(port, argp); | 1399 | retval = rc_set_serial_info(port, argp); |
1420 | unlock_kernel(); | 1400 | unlock_kernel(); |
1421 | break; | 1401 | break; |
1422 | default: | 1402 | default: |
1423 | retval = -ENOIOCTLCMD; | 1403 | retval = -ENOIOCTLCMD; |
1424 | } | 1404 | } |
1425 | return retval; | 1405 | return retval; |
1426 | } | 1406 | } |
1427 | 1407 | ||
1428 | static void rc_throttle(struct tty_struct * tty) | 1408 | static void rc_throttle(struct tty_struct *tty) |
1429 | { | 1409 | { |
1430 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1410 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1431 | struct riscom_board *bp; | 1411 | struct riscom_board *bp; |
1432 | unsigned long flags; | 1412 | unsigned long flags; |
1433 | 1413 | ||
1434 | if (rc_paranoia_check(port, tty->name, "rc_throttle")) | 1414 | if (rc_paranoia_check(port, tty->name, "rc_throttle")) |
1435 | return; | 1415 | return; |
1436 | |||
1437 | bp = port_Board(port); | 1416 | bp = port_Board(port); |
1438 | 1417 | ||
1439 | spin_lock_irqsave(&riscom_lock, flags); | 1418 | spin_lock_irqsave(&riscom_lock, flags); |
1440 | |||
1441 | port->MSVR &= ~MSVR_RTS; | 1419 | port->MSVR &= ~MSVR_RTS; |
1442 | rc_out(bp, CD180_CAR, port_No(port)); | 1420 | rc_out(bp, CD180_CAR, port_No(port)); |
1443 | if (I_IXOFF(tty)) { | 1421 | if (I_IXOFF(tty)) { |
@@ -1446,23 +1424,20 @@ static void rc_throttle(struct tty_struct * tty) | |||
1446 | rc_wait_CCR(bp); | 1424 | rc_wait_CCR(bp); |
1447 | } | 1425 | } |
1448 | rc_out(bp, CD180_MSVR, port->MSVR); | 1426 | rc_out(bp, CD180_MSVR, port->MSVR); |
1449 | |||
1450 | spin_unlock_irqrestore(&riscom_lock, flags); | 1427 | spin_unlock_irqrestore(&riscom_lock, flags); |
1451 | } | 1428 | } |
1452 | 1429 | ||
1453 | static void rc_unthrottle(struct tty_struct * tty) | 1430 | static void rc_unthrottle(struct tty_struct *tty) |
1454 | { | 1431 | { |
1455 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1432 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1456 | struct riscom_board *bp; | 1433 | struct riscom_board *bp; |
1457 | unsigned long flags; | 1434 | unsigned long flags; |
1458 | 1435 | ||
1459 | if (rc_paranoia_check(port, tty->name, "rc_unthrottle")) | 1436 | if (rc_paranoia_check(port, tty->name, "rc_unthrottle")) |
1460 | return; | 1437 | return; |
1461 | |||
1462 | bp = port_Board(port); | 1438 | bp = port_Board(port); |
1463 | |||
1464 | spin_lock_irqsave(&riscom_lock, flags); | ||
1465 | 1439 | ||
1440 | spin_lock_irqsave(&riscom_lock, flags); | ||
1466 | port->MSVR |= MSVR_RTS; | 1441 | port->MSVR |= MSVR_RTS; |
1467 | rc_out(bp, CD180_CAR, port_No(port)); | 1442 | rc_out(bp, CD180_CAR, port_No(port)); |
1468 | if (I_IXOFF(tty)) { | 1443 | if (I_IXOFF(tty)) { |
@@ -1471,62 +1446,58 @@ static void rc_unthrottle(struct tty_struct * tty) | |||
1471 | rc_wait_CCR(bp); | 1446 | rc_wait_CCR(bp); |
1472 | } | 1447 | } |
1473 | rc_out(bp, CD180_MSVR, port->MSVR); | 1448 | rc_out(bp, CD180_MSVR, port->MSVR); |
1474 | |||
1475 | spin_unlock_irqrestore(&riscom_lock, flags); | 1449 | spin_unlock_irqrestore(&riscom_lock, flags); |
1476 | } | 1450 | } |
1477 | 1451 | ||
1478 | static void rc_stop(struct tty_struct * tty) | 1452 | static void rc_stop(struct tty_struct *tty) |
1479 | { | 1453 | { |
1480 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1454 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1481 | struct riscom_board *bp; | 1455 | struct riscom_board *bp; |
1482 | unsigned long flags; | 1456 | unsigned long flags; |
1483 | 1457 | ||
1484 | if (rc_paranoia_check(port, tty->name, "rc_stop")) | 1458 | if (rc_paranoia_check(port, tty->name, "rc_stop")) |
1485 | return; | 1459 | return; |
1486 | 1460 | ||
1487 | bp = port_Board(port); | 1461 | bp = port_Board(port); |
1488 | |||
1489 | spin_lock_irqsave(&riscom_lock, flags); | ||
1490 | 1462 | ||
1463 | spin_lock_irqsave(&riscom_lock, flags); | ||
1491 | port->IER &= ~IER_TXRDY; | 1464 | port->IER &= ~IER_TXRDY; |
1492 | rc_out(bp, CD180_CAR, port_No(port)); | 1465 | rc_out(bp, CD180_CAR, port_No(port)); |
1493 | rc_out(bp, CD180_IER, port->IER); | 1466 | rc_out(bp, CD180_IER, port->IER); |
1494 | |||
1495 | spin_unlock_irqrestore(&riscom_lock, flags); | 1467 | spin_unlock_irqrestore(&riscom_lock, flags); |
1496 | } | 1468 | } |
1497 | 1469 | ||
1498 | static void rc_start(struct tty_struct * tty) | 1470 | static void rc_start(struct tty_struct *tty) |
1499 | { | 1471 | { |
1500 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1472 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1501 | struct riscom_board *bp; | 1473 | struct riscom_board *bp; |
1502 | unsigned long flags; | 1474 | unsigned long flags; |
1503 | 1475 | ||
1504 | if (rc_paranoia_check(port, tty->name, "rc_start")) | 1476 | if (rc_paranoia_check(port, tty->name, "rc_start")) |
1505 | return; | 1477 | return; |
1506 | 1478 | ||
1507 | bp = port_Board(port); | 1479 | bp = port_Board(port); |
1508 | 1480 | ||
1509 | spin_lock_irqsave(&riscom_lock, flags); | 1481 | spin_lock_irqsave(&riscom_lock, flags); |
1510 | 1482 | ||
1511 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { | 1483 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { |
1512 | port->IER |= IER_TXRDY; | 1484 | port->IER |= IER_TXRDY; |
1513 | rc_out(bp, CD180_CAR, port_No(port)); | 1485 | rc_out(bp, CD180_CAR, port_No(port)); |
1514 | rc_out(bp, CD180_IER, port->IER); | 1486 | rc_out(bp, CD180_IER, port->IER); |
1515 | } | 1487 | } |
1516 | |||
1517 | spin_unlock_irqrestore(&riscom_lock, flags); | 1488 | spin_unlock_irqrestore(&riscom_lock, flags); |
1518 | } | 1489 | } |
1519 | 1490 | ||
1520 | static void rc_hangup(struct tty_struct * tty) | 1491 | static void rc_hangup(struct tty_struct *tty) |
1521 | { | 1492 | { |
1522 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1493 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1523 | struct riscom_board *bp; | 1494 | struct riscom_board *bp; |
1524 | 1495 | ||
1525 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) | 1496 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) |
1526 | return; | 1497 | return; |
1527 | 1498 | ||
1528 | bp = port_Board(port); | 1499 | bp = port_Board(port); |
1529 | 1500 | ||
1530 | rc_shutdown_port(bp, port); | 1501 | rc_shutdown_port(bp, port); |
1531 | port->count = 0; | 1502 | port->count = 0; |
1532 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | 1503 | port->flags &= ~ASYNC_NORMAL_ACTIVE; |
@@ -1534,17 +1505,14 @@ static void rc_hangup(struct tty_struct * tty) | |||
1534 | wake_up_interruptible(&port->open_wait); | 1505 | wake_up_interruptible(&port->open_wait); |
1535 | } | 1506 | } |
1536 | 1507 | ||
1537 | static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termios) | 1508 | static void rc_set_termios(struct tty_struct *tty, |
1509 | struct ktermios *old_termios) | ||
1538 | { | 1510 | { |
1539 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1511 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1540 | unsigned long flags; | 1512 | unsigned long flags; |
1541 | 1513 | ||
1542 | if (rc_paranoia_check(port, tty->name, "rc_set_termios")) | 1514 | if (rc_paranoia_check(port, tty->name, "rc_set_termios")) |
1543 | return; | 1515 | return; |
1544 | |||
1545 | if (tty->termios->c_cflag == old_termios->c_cflag && | ||
1546 | tty->termios->c_iflag == old_termios->c_iflag) | ||
1547 | return; | ||
1548 | 1516 | ||
1549 | spin_lock_irqsave(&riscom_lock, flags); | 1517 | spin_lock_irqsave(&riscom_lock, flags); |
1550 | rc_change_speed(port_Board(port), port); | 1518 | rc_change_speed(port_Board(port), port); |
@@ -1583,9 +1551,9 @@ static int __init rc_init_drivers(void) | |||
1583 | int i; | 1551 | int i; |
1584 | 1552 | ||
1585 | riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT); | 1553 | riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT); |
1586 | if (!riscom_driver) | 1554 | if (!riscom_driver) |
1587 | return -ENOMEM; | 1555 | return -ENOMEM; |
1588 | 1556 | ||
1589 | riscom_driver->owner = THIS_MODULE; | 1557 | riscom_driver->owner = THIS_MODULE; |
1590 | riscom_driver->name = "ttyL"; | 1558 | riscom_driver->name = "ttyL"; |
1591 | riscom_driver->major = RISCOM8_NORMAL_MAJOR; | 1559 | riscom_driver->major = RISCOM8_NORMAL_MAJOR; |
@@ -1598,23 +1566,21 @@ static int __init rc_init_drivers(void) | |||
1598 | riscom_driver->init_termios.c_ospeed = 9600; | 1566 | riscom_driver->init_termios.c_ospeed = 9600; |
1599 | riscom_driver->flags = TTY_DRIVER_REAL_RAW; | 1567 | riscom_driver->flags = TTY_DRIVER_REAL_RAW; |
1600 | tty_set_operations(riscom_driver, &riscom_ops); | 1568 | tty_set_operations(riscom_driver, &riscom_ops); |
1601 | if ((error = tty_register_driver(riscom_driver))) { | 1569 | error = tty_register_driver(riscom_driver); |
1570 | if (error != 0) { | ||
1602 | put_tty_driver(riscom_driver); | 1571 | put_tty_driver(riscom_driver); |
1603 | printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, " | 1572 | printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, " |
1604 | "error = %d\n", | 1573 | "error = %d\n", error); |
1605 | error); | ||
1606 | return 1; | 1574 | return 1; |
1607 | } | 1575 | } |
1608 | |||
1609 | memset(rc_port, 0, sizeof(rc_port)); | 1576 | memset(rc_port, 0, sizeof(rc_port)); |
1610 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { | 1577 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { |
1611 | rc_port[i].magic = RISCOM8_MAGIC; | 1578 | rc_port[i].magic = RISCOM8_MAGIC; |
1612 | rc_port[i].close_delay = 50 * HZ/100; | 1579 | rc_port[i].close_delay = 50 * HZ / 100; |
1613 | rc_port[i].closing_wait = 3000 * HZ/100; | 1580 | rc_port[i].closing_wait = 3000 * HZ / 100; |
1614 | init_waitqueue_head(&rc_port[i].open_wait); | 1581 | init_waitqueue_head(&rc_port[i].open_wait); |
1615 | init_waitqueue_head(&rc_port[i].close_wait); | 1582 | init_waitqueue_head(&rc_port[i].close_wait); |
1616 | } | 1583 | } |
1617 | |||
1618 | return 0; | 1584 | return 0; |
1619 | } | 1585 | } |
1620 | 1586 | ||
@@ -1627,13 +1593,13 @@ static void rc_release_drivers(void) | |||
1627 | #ifndef MODULE | 1593 | #ifndef MODULE |
1628 | /* | 1594 | /* |
1629 | * Called at boot time. | 1595 | * Called at boot time. |
1630 | * | 1596 | * |
1631 | * You can specify IO base for up to RC_NBOARD cards, | 1597 | * You can specify IO base for up to RC_NBOARD cards, |
1632 | * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt. | 1598 | * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt. |
1633 | * Note that there will be no probing at default | 1599 | * Note that there will be no probing at default |
1634 | * addresses in this case. | 1600 | * addresses in this case. |
1635 | * | 1601 | * |
1636 | */ | 1602 | */ |
1637 | static int __init riscom8_setup(char *str) | 1603 | static int __init riscom8_setup(char *str) |
1638 | { | 1604 | { |
1639 | int ints[RC_NBOARD]; | 1605 | int ints[RC_NBOARD]; |
@@ -1644,7 +1610,7 @@ static int __init riscom8_setup(char *str) | |||
1644 | for (i = 0; i < RC_NBOARD; i++) { | 1610 | for (i = 0; i < RC_NBOARD; i++) { |
1645 | if (i < ints[0]) | 1611 | if (i < ints[0]) |
1646 | rc_board[i].base = ints[i+1]; | 1612 | rc_board[i].base = ints[i+1]; |
1647 | else | 1613 | else |
1648 | rc_board[i].base = 0; | 1614 | rc_board[i].base = 0; |
1649 | } | 1615 | } |
1650 | return 1; | 1616 | return 1; |
@@ -1659,8 +1625,8 @@ static char banner[] __initdata = | |||
1659 | static char no_boards_msg[] __initdata = | 1625 | static char no_boards_msg[] __initdata = |
1660 | KERN_INFO "rc: No RISCom/8 boards detected.\n"; | 1626 | KERN_INFO "rc: No RISCom/8 boards detected.\n"; |
1661 | 1627 | ||
1662 | /* | 1628 | /* |
1663 | * This routine must be called by kernel at boot time | 1629 | * This routine must be called by kernel at boot time |
1664 | */ | 1630 | */ |
1665 | static int __init riscom8_init(void) | 1631 | static int __init riscom8_init(void) |
1666 | { | 1632 | { |
@@ -1669,13 +1635,12 @@ static int __init riscom8_init(void) | |||
1669 | 1635 | ||
1670 | printk(banner); | 1636 | printk(banner); |
1671 | 1637 | ||
1672 | if (rc_init_drivers()) | 1638 | if (rc_init_drivers()) |
1673 | return -EIO; | 1639 | return -EIO; |
1674 | 1640 | ||
1675 | for (i = 0; i < RC_NBOARD; i++) | 1641 | for (i = 0; i < RC_NBOARD; i++) |
1676 | if (rc_board[i].base && !rc_probe(&rc_board[i])) | 1642 | if (rc_board[i].base && !rc_probe(&rc_board[i])) |
1677 | found++; | 1643 | found++; |
1678 | |||
1679 | if (!found) { | 1644 | if (!found) { |
1680 | rc_release_drivers(); | 1645 | rc_release_drivers(); |
1681 | printk(no_boards_msg); | 1646 | printk(no_boards_msg); |
@@ -1702,13 +1667,13 @@ MODULE_LICENSE("GPL"); | |||
1702 | * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter. | 1667 | * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter. |
1703 | * | 1668 | * |
1704 | */ | 1669 | */ |
1705 | static int __init riscom8_init_module (void) | 1670 | static int __init riscom8_init_module(void) |
1706 | { | 1671 | { |
1707 | #ifdef MODULE | 1672 | #ifdef MODULE |
1708 | int i; | 1673 | int i; |
1709 | 1674 | ||
1710 | if (iobase || iobase1 || iobase2 || iobase3) { | 1675 | if (iobase || iobase1 || iobase2 || iobase3) { |
1711 | for(i = 0; i < RC_NBOARD; i++) | 1676 | for (i = 0; i < RC_NBOARD; i++) |
1712 | rc_board[i].base = 0; | 1677 | rc_board[i].base = 0; |
1713 | } | 1678 | } |
1714 | 1679 | ||
@@ -1724,18 +1689,17 @@ static int __init riscom8_init_module (void) | |||
1724 | 1689 | ||
1725 | return riscom8_init(); | 1690 | return riscom8_init(); |
1726 | } | 1691 | } |
1727 | 1692 | ||
1728 | static void __exit riscom8_exit_module (void) | 1693 | static void __exit riscom8_exit_module(void) |
1729 | { | 1694 | { |
1730 | int i; | 1695 | int i; |
1731 | 1696 | ||
1732 | rc_release_drivers(); | 1697 | rc_release_drivers(); |
1733 | for (i = 0; i < RC_NBOARD; i++) | 1698 | for (i = 0; i < RC_NBOARD; i++) |
1734 | if (rc_board[i].flags & RC_BOARD_PRESENT) | 1699 | if (rc_board[i].flags & RC_BOARD_PRESENT) |
1735 | rc_release_io_range(&rc_board[i]); | 1700 | rc_release_io_range(&rc_board[i]); |
1736 | 1701 | ||
1737 | } | 1702 | } |
1738 | 1703 | ||
1739 | module_init(riscom8_init_module); | 1704 | module_init(riscom8_init_module); |
1740 | module_exit(riscom8_exit_module); | 1705 | module_exit(riscom8_exit_module); |
1741 | |||