diff options
author | Alan Cox <alan@redhat.com> | 2008-07-22 06:17:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-22 16:03:27 -0400 |
commit | a72492bd8a8d4326fd78b2142bf7cae779d5d4c2 (patch) | |
tree | 522392a8efbbbeee4f35f6c74e552c1dab4566c0 /drivers/char/specialix.c | |
parent | 01e1abb2c27e43339b8829a2e3b1c6f53806b77a (diff) |
specialix: Tidy up coding style
Preparation for doing some real work on the driver. Do this first so we can
easily identify if the cleanups accidentally broke something
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/specialix.c')
-rw-r--r-- | drivers/char/specialix.c | 663 |
1 files changed, 361 insertions, 302 deletions
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 037dc47e4cb1..c390c6cc030e 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -77,7 +77,7 @@ | |||
77 | 77 | ||
78 | #include <linux/module.h> | 78 | #include <linux/module.h> |
79 | 79 | ||
80 | #include <asm/io.h> | 80 | #include <linux/io.h> |
81 | #include <linux/kernel.h> | 81 | #include <linux/kernel.h> |
82 | #include <linux/sched.h> | 82 | #include <linux/sched.h> |
83 | #include <linux/ioport.h> | 83 | #include <linux/ioport.h> |
@@ -92,7 +92,7 @@ | |||
92 | #include <linux/delay.h> | 92 | #include <linux/delay.h> |
93 | #include <linux/pci.h> | 93 | #include <linux/pci.h> |
94 | #include <linux/init.h> | 94 | #include <linux/init.h> |
95 | #include <asm/uaccess.h> | 95 | #include <linux/uaccess.h> |
96 | 96 | ||
97 | #include "specialix_io8.h" | 97 | #include "specialix_io8.h" |
98 | #include "cd1865.h" | 98 | #include "cd1865.h" |
@@ -112,7 +112,7 @@ static int sx_debug; | |||
112 | static int sx_rxfifo = SPECIALIX_RXFIFO; | 112 | static int sx_rxfifo = SPECIALIX_RXFIFO; |
113 | 113 | ||
114 | #ifdef DEBUG | 114 | #ifdef DEBUG |
115 | #define dprintk(f, str...) if (sx_debug & f) printk (str) | 115 | #define dprintk(f, str...) if (sx_debug & f) printk(str) |
116 | #else | 116 | #else |
117 | #define dprintk(f, str...) /* nothing */ | 117 | #define dprintk(f, str...) /* nothing */ |
118 | #endif | 118 | #endif |
@@ -131,8 +131,8 @@ static int sx_rxfifo = SPECIALIX_RXFIFO; | |||
131 | #define SX_DEBUG_FIFO 0x0800 | 131 | #define SX_DEBUG_FIFO 0x0800 |
132 | 132 | ||
133 | 133 | ||
134 | #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__func__) | 134 | #define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__) |
135 | #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __func__) | 135 | #define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__) |
136 | 136 | ||
137 | #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1) | 137 | #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1) |
138 | 138 | ||
@@ -169,8 +169,8 @@ static int sx_poll = HZ; | |||
169 | #endif | 169 | #endif |
170 | 170 | ||
171 | 171 | ||
172 | /* Used to be outb (0xff, 0x80); */ | 172 | /* Used to be outb(0xff, 0x80); */ |
173 | #define short_pause() udelay (1) | 173 | #define short_pause() udelay(1) |
174 | 174 | ||
175 | 175 | ||
176 | #define SPECIALIX_LEGAL_FLAGS \ | 176 | #define SPECIALIX_LEGAL_FLAGS \ |
@@ -192,19 +192,19 @@ static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; | |||
192 | 192 | ||
193 | #ifdef SPECIALIX_TIMER | 193 | #ifdef SPECIALIX_TIMER |
194 | static struct timer_list missed_irq_timer; | 194 | static struct timer_list missed_irq_timer; |
195 | static irqreturn_t sx_interrupt(int irq, void * dev_id); | 195 | static irqreturn_t sx_interrupt(int irq, void *dev_id); |
196 | #endif | 196 | #endif |
197 | 197 | ||
198 | 198 | ||
199 | 199 | ||
200 | static inline int sx_paranoia_check(struct specialix_port const * port, | 200 | static inline int sx_paranoia_check(struct specialix_port const *port, |
201 | char *name, const char *routine) | 201 | char *name, const char *routine) |
202 | { | 202 | { |
203 | #ifdef SPECIALIX_PARANOIA_CHECK | 203 | #ifdef SPECIALIX_PARANOIA_CHECK |
204 | static const char *badmagic = | 204 | static const char *badmagic = KERN_ERR |
205 | KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n"; | 205 | "sx: Warning: bad specialix port magic number for device %s in %s\n"; |
206 | static const char *badinfo = | 206 | static const char *badinfo = KERN_ERR |
207 | KERN_ERR "sx: Warning: null specialix port for device %s in %s\n"; | 207 | "sx: Warning: null specialix port for device %s in %s\n"; |
208 | 208 | ||
209 | if (!port) { | 209 | if (!port) { |
210 | printk(badinfo, name, routine); | 210 | printk(badinfo, name, routine); |
@@ -226,66 +226,69 @@ static inline int sx_paranoia_check(struct specialix_port const * port, | |||
226 | */ | 226 | */ |
227 | 227 | ||
228 | /* Get board number from pointer */ | 228 | /* Get board number from pointer */ |
229 | static inline int board_No (struct specialix_board * bp) | 229 | static inline int board_No(struct specialix_board *bp) |
230 | { | 230 | { |
231 | return bp - sx_board; | 231 | return bp - sx_board; |
232 | } | 232 | } |
233 | 233 | ||
234 | 234 | ||
235 | /* Get port number from pointer */ | 235 | /* Get port number from pointer */ |
236 | static inline int port_No (struct specialix_port const * port) | 236 | static inline int port_No(struct specialix_port const *port) |
237 | { | 237 | { |
238 | return SX_PORT(port - sx_port); | 238 | return SX_PORT(port - sx_port); |
239 | } | 239 | } |
240 | 240 | ||
241 | 241 | ||
242 | /* Get pointer to board from pointer to port */ | 242 | /* Get pointer to board from pointer to port */ |
243 | static inline struct specialix_board * port_Board(struct specialix_port const * port) | 243 | static inline struct specialix_board *port_Board( |
244 | struct specialix_port const *port) | ||
244 | { | 245 | { |
245 | return &sx_board[SX_BOARD(port - sx_port)]; | 246 | return &sx_board[SX_BOARD(port - sx_port)]; |
246 | } | 247 | } |
247 | 248 | ||
248 | 249 | ||
249 | /* Input Byte from CL CD186x register */ | 250 | /* Input Byte from CL CD186x register */ |
250 | static inline unsigned char sx_in(struct specialix_board * bp, unsigned short reg) | 251 | static inline unsigned char sx_in(struct specialix_board *bp, |
252 | unsigned short reg) | ||
251 | { | 253 | { |
252 | bp->reg = reg | 0x80; | 254 | bp->reg = reg | 0x80; |
253 | outb (reg | 0x80, bp->base + SX_ADDR_REG); | 255 | outb(reg | 0x80, bp->base + SX_ADDR_REG); |
254 | return inb (bp->base + SX_DATA_REG); | 256 | return inb(bp->base + SX_DATA_REG); |
255 | } | 257 | } |
256 | 258 | ||
257 | 259 | ||
258 | /* Output Byte to CL CD186x register */ | 260 | /* Output Byte to CL CD186x register */ |
259 | static inline void sx_out(struct specialix_board * bp, unsigned short reg, | 261 | static inline void sx_out(struct specialix_board *bp, unsigned short reg, |
260 | unsigned char val) | 262 | unsigned char val) |
261 | { | 263 | { |
262 | bp->reg = reg | 0x80; | 264 | bp->reg = reg | 0x80; |
263 | outb (reg | 0x80, bp->base + SX_ADDR_REG); | 265 | outb(reg | 0x80, bp->base + SX_ADDR_REG); |
264 | outb (val, bp->base + SX_DATA_REG); | 266 | outb(val, bp->base + SX_DATA_REG); |
265 | } | 267 | } |
266 | 268 | ||
267 | 269 | ||
268 | /* Input Byte from CL CD186x register */ | 270 | /* Input Byte from CL CD186x register */ |
269 | static inline unsigned char sx_in_off(struct specialix_board * bp, unsigned short reg) | 271 | static inline unsigned char sx_in_off(struct specialix_board *bp, |
272 | unsigned short reg) | ||
270 | { | 273 | { |
271 | bp->reg = reg; | 274 | bp->reg = reg; |
272 | outb (reg, bp->base + SX_ADDR_REG); | 275 | outb(reg, bp->base + SX_ADDR_REG); |
273 | return inb (bp->base + SX_DATA_REG); | 276 | return inb(bp->base + SX_DATA_REG); |
274 | } | 277 | } |
275 | 278 | ||
276 | 279 | ||
277 | /* Output Byte to CL CD186x register */ | 280 | /* Output Byte to CL CD186x register */ |
278 | static inline void sx_out_off(struct specialix_board * bp, unsigned short reg, | 281 | static inline void sx_out_off(struct specialix_board *bp, |
279 | unsigned char val) | 282 | unsigned short reg, unsigned char val) |
280 | { | 283 | { |
281 | bp->reg = reg; | 284 | bp->reg = reg; |
282 | outb (reg, bp->base + SX_ADDR_REG); | 285 | outb(reg, bp->base + SX_ADDR_REG); |
283 | outb (val, bp->base + SX_DATA_REG); | 286 | outb(val, bp->base + SX_DATA_REG); |
284 | } | 287 | } |
285 | 288 | ||
286 | 289 | ||
287 | /* Wait for Channel Command Register ready */ | 290 | /* Wait for Channel Command Register ready */ |
288 | static inline void sx_wait_CCR(struct specialix_board * bp) | 291 | static inline void sx_wait_CCR(struct specialix_board *bp) |
289 | { | 292 | { |
290 | unsigned long delay, flags; | 293 | unsigned long delay, flags; |
291 | unsigned char ccr; | 294 | unsigned char ccr; |
@@ -296,7 +299,7 @@ static inline void sx_wait_CCR(struct specialix_board * bp) | |||
296 | spin_unlock_irqrestore(&bp->lock, flags); | 299 | spin_unlock_irqrestore(&bp->lock, flags); |
297 | if (!ccr) | 300 | if (!ccr) |
298 | return; | 301 | return; |
299 | udelay (1); | 302 | udelay(1); |
300 | } | 303 | } |
301 | 304 | ||
302 | printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); | 305 | printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); |
@@ -304,7 +307,7 @@ static inline void sx_wait_CCR(struct specialix_board * bp) | |||
304 | 307 | ||
305 | 308 | ||
306 | /* Wait for Channel Command Register ready */ | 309 | /* Wait for Channel Command Register ready */ |
307 | static inline void sx_wait_CCR_off(struct specialix_board * bp) | 310 | static inline void sx_wait_CCR_off(struct specialix_board *bp) |
308 | { | 311 | { |
309 | unsigned long delay; | 312 | unsigned long delay; |
310 | unsigned char crr; | 313 | unsigned char crr; |
@@ -316,7 +319,7 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp) | |||
316 | spin_unlock_irqrestore(&bp->lock, flags); | 319 | spin_unlock_irqrestore(&bp->lock, flags); |
317 | if (!crr) | 320 | if (!crr) |
318 | return; | 321 | return; |
319 | udelay (1); | 322 | udelay(1); |
320 | } | 323 | } |
321 | 324 | ||
322 | printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); | 325 | printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); |
@@ -327,7 +330,7 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp) | |||
327 | * specialix IO8+ IO range functions. | 330 | * specialix IO8+ IO range functions. |
328 | */ | 331 | */ |
329 | 332 | ||
330 | static inline int sx_request_io_range(struct specialix_board * bp) | 333 | static inline int sx_request_io_range(struct specialix_board *bp) |
331 | { | 334 | { |
332 | return request_region(bp->base, | 335 | return request_region(bp->base, |
333 | bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE, | 336 | bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE, |
@@ -335,15 +338,15 @@ static inline int sx_request_io_range(struct specialix_board * bp) | |||
335 | } | 338 | } |
336 | 339 | ||
337 | 340 | ||
338 | static inline void sx_release_io_range(struct specialix_board * bp) | 341 | static inline void sx_release_io_range(struct specialix_board *bp) |
339 | { | 342 | { |
340 | release_region(bp->base, | 343 | release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ? |
341 | bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE); | 344 | SX_PCI_IO_SPACE : SX_IO_SPACE); |
342 | } | 345 | } |
343 | 346 | ||
344 | 347 | ||
345 | /* Set the IRQ using the RTS lines that run to the PAL on the board.... */ | 348 | /* Set the IRQ using the RTS lines that run to the PAL on the board.... */ |
346 | static int sx_set_irq ( struct specialix_board *bp) | 349 | static int sx_set_irq(struct specialix_board *bp) |
347 | { | 350 | { |
348 | int virq; | 351 | int virq; |
349 | int i; | 352 | int i; |
@@ -353,15 +356,24 @@ static int sx_set_irq ( struct specialix_board *bp) | |||
353 | return 1; | 356 | return 1; |
354 | switch (bp->irq) { | 357 | switch (bp->irq) { |
355 | /* In the same order as in the docs... */ | 358 | /* In the same order as in the docs... */ |
356 | case 15: virq = 0;break; | 359 | case 15: |
357 | case 12: virq = 1;break; | 360 | virq = 0; |
358 | case 11: virq = 2;break; | 361 | break; |
359 | case 9: virq = 3;break; | 362 | case 12: |
360 | default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq); | 363 | virq = 1; |
361 | return 0; | 364 | break; |
365 | case 11: | ||
366 | virq = 2; | ||
367 | break; | ||
368 | case 9: | ||
369 | virq = 3; | ||
370 | break; | ||
371 | default:printk(KERN_ERR | ||
372 | "Speclialix: cannot set irq to %d.\n", bp->irq); | ||
373 | return 0; | ||
362 | } | 374 | } |
363 | spin_lock_irqsave(&bp->lock, flags); | 375 | spin_lock_irqsave(&bp->lock, flags); |
364 | for (i=0;i<2;i++) { | 376 | for (i = 0; i < 2; i++) { |
365 | sx_out(bp, CD186x_CAR, i); | 377 | sx_out(bp, CD186x_CAR, i); |
366 | sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0); | 378 | sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0); |
367 | } | 379 | } |
@@ -371,7 +383,7 @@ static int sx_set_irq ( struct specialix_board *bp) | |||
371 | 383 | ||
372 | 384 | ||
373 | /* Reset and setup CD186x chip */ | 385 | /* Reset and setup CD186x chip */ |
374 | static int sx_init_CD186x(struct specialix_board * bp) | 386 | static int sx_init_CD186x(struct specialix_board *bp) |
375 | { | 387 | { |
376 | unsigned long flags; | 388 | unsigned long flags; |
377 | int scaler; | 389 | int scaler; |
@@ -390,7 +402,7 @@ static int sx_init_CD186x(struct specialix_board * bp) | |||
390 | sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */ | 402 | sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */ |
391 | sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */ | 403 | sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */ |
392 | /* Set RegAckEn */ | 404 | /* Set RegAckEn */ |
393 | sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN); | 405 | sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN); |
394 | 406 | ||
395 | /* Setting up prescaler. We need 4 ticks per 1 ms */ | 407 | /* Setting up prescaler. We need 4 ticks per 1 ms */ |
396 | scaler = SX_OSCFREQ/SPECIALIX_TPS; | 408 | scaler = SX_OSCFREQ/SPECIALIX_TPS; |
@@ -399,9 +411,9 @@ static int sx_init_CD186x(struct specialix_board * bp) | |||
399 | sx_out_off(bp, CD186x_PPRL, scaler & 0xff); | 411 | sx_out_off(bp, CD186x_PPRL, scaler & 0xff); |
400 | spin_unlock_irqrestore(&bp->lock, flags); | 412 | spin_unlock_irqrestore(&bp->lock, flags); |
401 | 413 | ||
402 | if (!sx_set_irq (bp)) { | 414 | if (!sx_set_irq(bp)) { |
403 | /* Figure out how to pass this along... */ | 415 | /* Figure out how to pass this along... */ |
404 | printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq); | 416 | printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq); |
405 | rv = 0; | 417 | rv = 0; |
406 | } | 418 | } |
407 | 419 | ||
@@ -410,16 +422,16 @@ static int sx_init_CD186x(struct specialix_board * bp) | |||
410 | } | 422 | } |
411 | 423 | ||
412 | 424 | ||
413 | static int read_cross_byte (struct specialix_board *bp, int reg, int bit) | 425 | static int read_cross_byte(struct specialix_board *bp, int reg, int bit) |
414 | { | 426 | { |
415 | int i; | 427 | int i; |
416 | int t; | 428 | int t; |
417 | unsigned long flags; | 429 | unsigned long flags; |
418 | 430 | ||
419 | spin_lock_irqsave(&bp->lock, flags); | 431 | spin_lock_irqsave(&bp->lock, flags); |
420 | for (i=0, t=0;i<8;i++) { | 432 | for (i = 0, t = 0; i < 8; i++) { |
421 | sx_out_off (bp, CD186x_CAR, i); | 433 | sx_out_off(bp, CD186x_CAR, i); |
422 | if (sx_in_off (bp, reg) & bit) | 434 | if (sx_in_off(bp, reg) & bit) |
423 | t |= 1 << i; | 435 | t |= 1 << i; |
424 | } | 436 | } |
425 | spin_unlock_irqrestore(&bp->lock, flags); | 437 | spin_unlock_irqrestore(&bp->lock, flags); |
@@ -429,21 +441,20 @@ static int read_cross_byte (struct specialix_board *bp, int reg, int bit) | |||
429 | 441 | ||
430 | 442 | ||
431 | #ifdef SPECIALIX_TIMER | 443 | #ifdef SPECIALIX_TIMER |
432 | void missed_irq (unsigned long data) | 444 | void missed_irq(unsigned long data) |
433 | { | 445 | { |
434 | unsigned char irq; | 446 | unsigned char irq; |
435 | unsigned long flags; | 447 | unsigned long flags; |
436 | struct specialix_board *bp = (struct specialix_board *)data; | 448 | struct specialix_board *bp = (struct specialix_board *)data; |
437 | 449 | ||
438 | spin_lock_irqsave(&bp->lock, flags); | 450 | spin_lock_irqsave(&bp->lock, flags); |
439 | irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) & | 451 | irq = sx_in((struct specialix_board *)data, CD186x_SRSR) & |
440 | (SRSR_RREQint | | 452 | (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint); |
441 | SRSR_TREQint | | ||
442 | SRSR_MREQint); | ||
443 | spin_unlock_irqrestore(&bp->lock, flags); | 453 | spin_unlock_irqrestore(&bp->lock, flags); |
444 | if (irq) { | 454 | if (irq) { |
445 | printk (KERN_INFO "Missed interrupt... Calling int from timer. \n"); | 455 | printk(KERN_INFO |
446 | sx_interrupt (-1, bp); | 456 | "Missed interrupt... Calling int from timer. \n"); |
457 | sx_interrupt(-1, bp); | ||
447 | } | 458 | } |
448 | mod_timer(&missed_irq_timer, jiffies + sx_poll); | 459 | mod_timer(&missed_irq_timer, jiffies + sx_poll); |
449 | } | 460 | } |
@@ -471,17 +482,18 @@ static int sx_probe(struct specialix_board *bp) | |||
471 | 482 | ||
472 | /* Are the I/O ports here ? */ | 483 | /* Are the I/O ports here ? */ |
473 | sx_out_off(bp, CD186x_PPRL, 0x5a); | 484 | sx_out_off(bp, CD186x_PPRL, 0x5a); |
474 | short_pause (); | 485 | short_pause(); |
475 | val1 = sx_in_off(bp, CD186x_PPRL); | 486 | val1 = sx_in_off(bp, CD186x_PPRL); |
476 | 487 | ||
477 | sx_out_off(bp, CD186x_PPRL, 0xa5); | 488 | sx_out_off(bp, CD186x_PPRL, 0xa5); |
478 | short_pause (); | 489 | short_pause(); |
479 | val2 = sx_in_off(bp, CD186x_PPRL); | 490 | val2 = sx_in_off(bp, CD186x_PPRL); |
480 | 491 | ||
481 | 492 | ||
482 | if ((val1 != 0x5a) || (val2 != 0xa5)) { | 493 | if ((val1 != 0x5a) || (val2 != 0xa5)) { |
483 | printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n", | 494 | printk(KERN_INFO |
484 | board_No(bp), bp->base); | 495 | "sx%d: specialix IO8+ Board at 0x%03x not found.\n", |
496 | board_No(bp), bp->base); | ||
485 | sx_release_io_range(bp); | 497 | sx_release_io_range(bp); |
486 | func_exit(); | 498 | func_exit(); |
487 | return 1; | 499 | return 1; |
@@ -489,10 +501,11 @@ static int sx_probe(struct specialix_board *bp) | |||
489 | 501 | ||
490 | /* Check the DSR lines that Specialix uses as board | 502 | /* Check the DSR lines that Specialix uses as board |
491 | identification */ | 503 | identification */ |
492 | val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR); | 504 | val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR); |
493 | val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS); | 505 | val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS); |
494 | dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n", | 506 | dprintk(SX_DEBUG_INIT, |
495 | board_No(bp), val1, val2); | 507 | "sx%d: DSR lines are: %02x, rts lines are: %02x\n", |
508 | board_No(bp), val1, val2); | ||
496 | 509 | ||
497 | /* They managed to switch the bit order between the docs and | 510 | /* They managed to switch the bit order between the docs and |
498 | the IO8+ card. The new PCI card now conforms to old docs. | 511 | the IO8+ card. The new PCI card now conforms to old docs. |
@@ -500,7 +513,8 @@ static int sx_probe(struct specialix_board *bp) | |||
500 | old card. */ | 513 | old card. */ |
501 | val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2; | 514 | val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2; |
502 | if (val1 != val2) { | 515 | if (val1 != val2) { |
503 | printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n", | 516 | printk(KERN_INFO |
517 | "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n", | ||
504 | board_No(bp), val2, bp->base, val1); | 518 | board_No(bp), val2, bp->base, val1); |
505 | sx_release_io_range(bp); | 519 | sx_release_io_range(bp); |
506 | func_exit(); | 520 | func_exit(); |
@@ -512,40 +526,43 @@ static int sx_probe(struct specialix_board *bp) | |||
512 | /* It's time to find IRQ for this board */ | 526 | /* It's time to find IRQ for this board */ |
513 | for (retries = 0; retries < 5 && irqs <= 0; retries++) { | 527 | for (retries = 0; retries < 5 && irqs <= 0; retries++) { |
514 | irqs = probe_irq_on(); | 528 | irqs = probe_irq_on(); |
515 | sx_init_CD186x(bp); /* Reset CD186x chip */ | 529 | sx_init_CD186x(bp); /* Reset CD186x chip */ |
516 | sx_out(bp, CD186x_CAR, 2); /* Select port 2 */ | 530 | sx_out(bp, CD186x_CAR, 2); /* Select port 2 */ |
517 | sx_wait_CCR(bp); | 531 | sx_wait_CCR(bp); |
518 | sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */ | 532 | sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */ |
519 | sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */ | 533 | sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */ |
520 | msleep(50); | 534 | msleep(50); |
521 | irqs = probe_irq_off(irqs); | 535 | irqs = probe_irq_off(irqs); |
522 | 536 | ||
523 | dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR)); | 537 | dprintk(SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR)); |
524 | dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR)); | 538 | dprintk(SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR)); |
525 | dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR)); | 539 | dprintk(SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR)); |
526 | dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR)); | 540 | dprintk(SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR)); |
527 | dprintk (SX_DEBUG_INIT, "\n"); | 541 | dprintk(SX_DEBUG_INIT, "\n"); |
528 | 542 | ||
529 | /* Reset CD186x again */ | 543 | /* Reset CD186x again */ |
530 | if (!sx_init_CD186x(bp)) { | 544 | if (!sx_init_CD186x(bp)) { |
531 | /* Hmmm. This is dead code anyway. */ | 545 | /* Hmmm. This is dead code anyway. */ |
532 | } | 546 | } |
533 | 547 | ||
534 | dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n", | 548 | dprintk(SX_DEBUG_INIT |
535 | val1, val2, val3); | 549 | "val1 = %02x, val2 = %02x, val3 = %02x.\n", |
550 | val1, val2, val3); | ||
536 | 551 | ||
537 | } | 552 | } |
538 | 553 | ||
539 | #if 0 | 554 | #if 0 |
540 | if (irqs <= 0) { | 555 | if (irqs <= 0) { |
541 | printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n", | 556 | printk(KERN_ERR |
542 | board_No(bp), bp->base); | 557 | "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n", |
558 | board_No(bp), bp->base); | ||
543 | sx_release_io_range(bp); | 559 | sx_release_io_range(bp); |
544 | func_exit(); | 560 | func_exit(); |
545 | return 1; | 561 | return 1; |
546 | } | 562 | } |
547 | #endif | 563 | #endif |
548 | printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs); | 564 | printk(KERN_INFO "Started with irq=%d, but now have irq=%d.\n", |
565 | bp->irq, irqs); | ||
549 | if (irqs > 0) | 566 | if (irqs > 0) |
550 | bp->irq = irqs; | 567 | bp->irq = irqs; |
551 | #endif | 568 | #endif |
@@ -560,7 +577,7 @@ static int sx_probe(struct specialix_board *bp) | |||
560 | bp->flags |= SX_BOARD_PRESENT; | 577 | bp->flags |= SX_BOARD_PRESENT; |
561 | 578 | ||
562 | /* Chip revcode pkgtype | 579 | /* Chip revcode pkgtype |
563 | GFRCR SRCR bit 7 | 580 | GFRCR SRCR bit 7 |
564 | CD180 rev B 0x81 0 | 581 | CD180 rev B 0x81 0 |
565 | CD180 rev C 0x82 0 | 582 | CD180 rev C 0x82 0 |
566 | CD1864 rev A 0x82 1 | 583 | CD1864 rev A 0x82 1 |
@@ -570,24 +587,37 @@ static int sx_probe(struct specialix_board *bp) | |||
570 | */ | 587 | */ |
571 | 588 | ||
572 | switch (sx_in_off(bp, CD186x_GFRCR)) { | 589 | switch (sx_in_off(bp, CD186x_GFRCR)) { |
573 | case 0x82:chip = 1864;rev='A';break; | 590 | case 0x82: |
574 | case 0x83:chip = 1865;rev='A';break; | 591 | chip = 1864; |
575 | case 0x84:chip = 1865;rev='B';break; | 592 | rev = 'A'; |
576 | case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */ | 593 | break; |
577 | default:chip=-1;rev='x'; | 594 | case 0x83: |
595 | chip = 1865; | ||
596 | rev = 'A'; | ||
597 | break; | ||
598 | case 0x84: | ||
599 | chip = 1865; | ||
600 | rev = 'B'; | ||
601 | break; | ||
602 | case 0x85: | ||
603 | chip = 1865; | ||
604 | rev = 'C'; | ||
605 | break; /* Does not exist at this time */ | ||
606 | default: | ||
607 | chip = -1; | ||
608 | rev = 'x'; | ||
578 | } | 609 | } |
579 | 610 | ||
580 | dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) ); | 611 | dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR)); |
581 | 612 | ||
582 | #ifdef SPECIALIX_TIMER | 613 | #ifdef SPECIALIX_TIMER |
583 | setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp); | 614 | setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp); |
584 | mod_timer(&missed_irq_timer, jiffies + sx_poll); | 615 | mod_timer(&missed_irq_timer, jiffies + sx_poll); |
585 | #endif | 616 | #endif |
586 | 617 | ||
587 | printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n", | 618 | printk(KERN_INFO |
588 | board_No(bp), | 619 | "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n", |
589 | bp->base, bp->irq, | 620 | board_No(bp), bp->base, bp->irq, chip, rev); |
590 | chip, rev); | ||
591 | 621 | ||
592 | func_exit(); | 622 | func_exit(); |
593 | return 0; | 623 | return 0; |
@@ -598,20 +628,22 @@ static int sx_probe(struct specialix_board *bp) | |||
598 | * Interrupt processing routines. | 628 | * Interrupt processing routines. |
599 | * */ | 629 | * */ |
600 | 630 | ||
601 | static inline struct specialix_port * sx_get_port(struct specialix_board * bp, | 631 | static inline struct specialix_port *sx_get_port(struct specialix_board *bp, |
602 | unsigned char const * what) | 632 | unsigned char const *what) |
603 | { | 633 | { |
604 | unsigned char channel; | 634 | unsigned char channel; |
605 | struct specialix_port * port = NULL; | 635 | struct specialix_port *port = NULL; |
606 | 636 | ||
607 | channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF; | 637 | channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF; |
608 | dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel); | 638 | dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel); |
609 | if (channel < CD186x_NCH) { | 639 | if (channel < CD186x_NCH) { |
610 | port = &sx_port[board_No(bp) * SX_NPORT + channel]; | 640 | port = &sx_port[board_No(bp) * SX_NPORT + channel]; |
611 | dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",board_No(bp) * SX_NPORT + channel, port, port->port.flags & ASYNC_INITIALIZED); | 641 | dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n", |
642 | board_No(bp) * SX_NPORT + channel, port, | ||
643 | port->port.flags & ASYNC_INITIALIZED); | ||
612 | 644 | ||
613 | if (port->port.flags & ASYNC_INITIALIZED) { | 645 | if (port->port.flags & ASYNC_INITIALIZED) { |
614 | dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port); | 646 | dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port); |
615 | func_exit(); | 647 | func_exit(); |
616 | return port; | 648 | return port; |
617 | } | 649 | } |
@@ -622,7 +654,7 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp, | |||
622 | } | 654 | } |
623 | 655 | ||
624 | 656 | ||
625 | static inline void sx_receive_exc(struct specialix_board * bp) | 657 | static inline void sx_receive_exc(struct specialix_board *bp) |
626 | { | 658 | { |
627 | struct specialix_port *port; | 659 | struct specialix_port *port; |
628 | struct tty_struct *tty; | 660 | struct tty_struct *tty; |
@@ -633,7 +665,7 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
633 | 665 | ||
634 | port = sx_get_port(bp, "Receive"); | 666 | port = sx_get_port(bp, "Receive"); |
635 | if (!port) { | 667 | if (!port) { |
636 | dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n"); | 668 | dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n"); |
637 | func_exit(); | 669 | func_exit(); |
638 | return; | 670 | return; |
639 | } | 671 | } |
@@ -641,19 +673,21 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
641 | 673 | ||
642 | status = sx_in(bp, CD186x_RCSR); | 674 | status = sx_in(bp, CD186x_RCSR); |
643 | 675 | ||
644 | dprintk (SX_DEBUG_RX, "status: 0x%x\n", status); | 676 | dprintk(SX_DEBUG_RX, "status: 0x%x\n", status); |
645 | if (status & RCSR_OE) { | 677 | if (status & RCSR_OE) { |
646 | port->overrun++; | 678 | port->overrun++; |
647 | dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n", | 679 | dprintk(SX_DEBUG_FIFO, |
648 | board_No(bp), port_No(port), port->overrun); | 680 | "sx%d: port %d: Overrun. Total %ld overruns.\n", |
681 | board_No(bp), port_No(port), port->overrun); | ||
649 | } | 682 | } |
650 | status &= port->mark_mask; | 683 | status &= port->mark_mask; |
651 | 684 | ||
652 | /* This flip buffer check needs to be below the reading of the | 685 | /* This flip buffer check needs to be below the reading of the |
653 | status register to reset the chip's IRQ.... */ | 686 | status register to reset the chip's IRQ.... */ |
654 | if (tty_buffer_request_room(tty, 1) == 0) { | 687 | if (tty_buffer_request_room(tty, 1) == 0) { |
655 | dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n", | 688 | dprintk(SX_DEBUG_FIFO, |
656 | board_No(bp), port_No(port)); | 689 | "sx%d: port %d: Working around flip buffer overflow.\n", |
690 | board_No(bp), port_No(port)); | ||
657 | func_exit(); | 691 | func_exit(); |
658 | return; | 692 | return; |
659 | } | 693 | } |
@@ -664,8 +698,9 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
664 | return; | 698 | return; |
665 | } | 699 | } |
666 | if (status & RCSR_TOUT) { | 700 | if (status & RCSR_TOUT) { |
667 | printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n", | 701 | printk(KERN_INFO |
668 | board_No(bp), port_No(port)); | 702 | "sx%d: port %d: Receiver timeout. Hardware problems ?\n", |
703 | board_No(bp), port_No(port)); | ||
669 | func_exit(); | 704 | func_exit(); |
670 | return; | 705 | return; |
671 | 706 | ||
@@ -688,13 +723,13 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
688 | else | 723 | else |
689 | flag = TTY_NORMAL; | 724 | flag = TTY_NORMAL; |
690 | 725 | ||
691 | if(tty_insert_flip_char(tty, ch, flag)) | 726 | if (tty_insert_flip_char(tty, ch, flag)) |
692 | tty_flip_buffer_push(tty); | 727 | tty_flip_buffer_push(tty); |
693 | func_exit(); | 728 | func_exit(); |
694 | } | 729 | } |
695 | 730 | ||
696 | 731 | ||
697 | static inline void sx_receive(struct specialix_board * bp) | 732 | static inline void sx_receive(struct specialix_board *bp) |
698 | { | 733 | { |
699 | struct specialix_port *port; | 734 | struct specialix_port *port; |
700 | struct tty_struct *tty; | 735 | struct tty_struct *tty; |
@@ -702,15 +737,16 @@ static inline void sx_receive(struct specialix_board * bp) | |||
702 | 737 | ||
703 | func_enter(); | 738 | func_enter(); |
704 | 739 | ||
705 | if (!(port = sx_get_port(bp, "Receive"))) { | 740 | port = sx_get_port(bp, "Receive"); |
706 | dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n"); | 741 | if (port == NULL) { |
742 | dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n"); | ||
707 | func_exit(); | 743 | func_exit(); |
708 | return; | 744 | return; |
709 | } | 745 | } |
710 | tty = port->port.tty; | 746 | tty = port->port.tty; |
711 | 747 | ||
712 | count = sx_in(bp, CD186x_RDCR); | 748 | count = sx_in(bp, CD186x_RDCR); |
713 | dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); | 749 | dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count); |
714 | port->hits[count > 8 ? 9 : count]++; | 750 | port->hits[count > 8 ? 9 : count]++; |
715 | 751 | ||
716 | tty_buffer_request_room(tty, count); | 752 | tty_buffer_request_room(tty, count); |
@@ -722,18 +758,19 @@ static inline void sx_receive(struct specialix_board * bp) | |||
722 | } | 758 | } |
723 | 759 | ||
724 | 760 | ||
725 | static inline void sx_transmit(struct specialix_board * bp) | 761 | static inline void sx_transmit(struct specialix_board *bp) |
726 | { | 762 | { |
727 | struct specialix_port *port; | 763 | struct specialix_port *port; |
728 | struct tty_struct *tty; | 764 | struct tty_struct *tty; |
729 | unsigned char count; | 765 | unsigned char count; |
730 | 766 | ||
731 | func_enter(); | 767 | func_enter(); |
732 | if (!(port = sx_get_port(bp, "Transmit"))) { | 768 | port = sx_get_port(bp, "Transmit"); |
769 | if (port == NULL) { | ||
733 | func_exit(); | 770 | func_exit(); |
734 | return; | 771 | return; |
735 | } | 772 | } |
736 | dprintk (SX_DEBUG_TX, "port: %p\n", port); | 773 | dprintk(SX_DEBUG_TX, "port: %p\n", port); |
737 | tty = port->port.tty; | 774 | tty = port->port.tty; |
738 | 775 | ||
739 | if (port->IER & IER_TXEMPTY) { | 776 | if (port->IER & IER_TXEMPTY) { |
@@ -765,7 +802,8 @@ static inline void sx_transmit(struct specialix_board * bp) | |||
765 | sx_out(bp, CD186x_TDR, CD186x_C_ESC); | 802 | sx_out(bp, CD186x_TDR, CD186x_C_ESC); |
766 | sx_out(bp, CD186x_TDR, CD186x_C_DELAY); | 803 | sx_out(bp, CD186x_TDR, CD186x_C_DELAY); |
767 | sx_out(bp, CD186x_TDR, count); | 804 | sx_out(bp, CD186x_TDR, count); |
768 | if (!(port->break_length -= count)) | 805 | port->break_length -= count; |
806 | if (port->break_length == 0) | ||
769 | port->break_length--; | 807 | port->break_length--; |
770 | } else { | 808 | } else { |
771 | sx_out(bp, CD186x_TDR, CD186x_C_ESC); | 809 | sx_out(bp, CD186x_TDR, CD186x_C_ESC); |
@@ -794,36 +832,37 @@ static inline void sx_transmit(struct specialix_board * bp) | |||
794 | sx_out(bp, CD186x_IER, port->IER); | 832 | sx_out(bp, CD186x_IER, port->IER); |
795 | } | 833 | } |
796 | if (port->xmit_cnt <= port->wakeup_chars) | 834 | if (port->xmit_cnt <= port->wakeup_chars) |
797 | tty_wakeup(tty); | 835 | tty_wakeup(tty); |
798 | 836 | ||
799 | func_exit(); | 837 | func_exit(); |
800 | } | 838 | } |
801 | 839 | ||
802 | 840 | ||
803 | static inline void sx_check_modem(struct specialix_board * bp) | 841 | static inline void sx_check_modem(struct specialix_board *bp) |
804 | { | 842 | { |
805 | struct specialix_port *port; | 843 | struct specialix_port *port; |
806 | struct tty_struct *tty; | 844 | struct tty_struct *tty; |
807 | unsigned char mcr; | 845 | unsigned char mcr; |
808 | int msvr_cd; | 846 | int msvr_cd; |
809 | 847 | ||
810 | dprintk (SX_DEBUG_SIGNALS, "Modem intr. "); | 848 | dprintk(SX_DEBUG_SIGNALS, "Modem intr. "); |
811 | if (!(port = sx_get_port(bp, "Modem"))) | 849 | port = sx_get_port(bp, "Modem"); |
850 | if (port == NULL) | ||
812 | return; | 851 | return; |
813 | 852 | ||
814 | tty = port->port.tty; | 853 | tty = port->port.tty; |
815 | 854 | ||
816 | mcr = sx_in(bp, CD186x_MCR); | 855 | mcr = sx_in(bp, CD186x_MCR); |
817 | printk ("mcr = %02x.\n", mcr); | 856 | printk("mcr = %02x.\n", mcr); /* FIXME */ |
818 | 857 | ||
819 | if ((mcr & MCR_CDCHG)) { | 858 | if ((mcr & MCR_CDCHG)) { |
820 | dprintk (SX_DEBUG_SIGNALS, "CD just changed... "); | 859 | dprintk(SX_DEBUG_SIGNALS, "CD just changed... "); |
821 | msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD; | 860 | msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD; |
822 | if (msvr_cd) { | 861 | if (msvr_cd) { |
823 | dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n"); | 862 | dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n"); |
824 | wake_up_interruptible(&port->port.open_wait); | 863 | wake_up_interruptible(&port->port.open_wait); |
825 | } else { | 864 | } else { |
826 | dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n"); | 865 | dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n"); |
827 | tty_hangup(tty); | 866 | tty_hangup(tty); |
828 | } | 867 | } |
829 | } | 868 | } |
@@ -874,9 +913,12 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) | |||
874 | 913 | ||
875 | spin_lock_irqsave(&bp->lock, flags); | 914 | spin_lock_irqsave(&bp->lock, flags); |
876 | 915 | ||
877 | dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); | 916 | dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, |
917 | port_No(sx_get_port(bp, "INT")), | ||
918 | SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); | ||
878 | if (!(bp->flags & SX_BOARD_ACTIVE)) { | 919 | if (!(bp->flags & SX_BOARD_ACTIVE)) { |
879 | dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq); | 920 | dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", |
921 | bp->irq); | ||
880 | spin_unlock_irqrestore(&bp->lock, flags); | 922 | spin_unlock_irqrestore(&bp->lock, flags); |
881 | func_exit(); | 923 | func_exit(); |
882 | return IRQ_NONE; | 924 | return IRQ_NONE; |
@@ -884,10 +926,11 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) | |||
884 | 926 | ||
885 | saved_reg = bp->reg; | 927 | saved_reg = bp->reg; |
886 | 928 | ||
887 | while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) & | 929 | while (++loop < 16) { |
888 | (SRSR_RREQint | | 930 | status = sx_in(bp, CD186x_SRSR) & |
889 | SRSR_TREQint | | 931 | (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint); |
890 | SRSR_MREQint)))) { | 932 | if (status == 0) |
933 | break; | ||
891 | if (status & SRSR_RREQint) { | 934 | if (status & SRSR_RREQint) { |
892 | ack = sx_in(bp, CD186x_RRAR); | 935 | ack = sx_in(bp, CD186x_RRAR); |
893 | 936 | ||
@@ -896,8 +939,9 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) | |||
896 | else if (ack == (SX_ID | GIVR_IT_REXC)) | 939 | else if (ack == (SX_ID | GIVR_IT_REXC)) |
897 | sx_receive_exc(bp); | 940 | sx_receive_exc(bp); |
898 | else | 941 | else |
899 | printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n", | 942 | printk(KERN_ERR |
900 | board_No(bp), status, ack); | 943 | "sx%d: status: 0x%x Bad receive ack 0x%02x.\n", |
944 | board_No(bp), status, ack); | ||
901 | 945 | ||
902 | } else if (status & SRSR_TREQint) { | 946 | } else if (status & SRSR_TREQint) { |
903 | ack = sx_in(bp, CD186x_TRAR); | 947 | ack = sx_in(bp, CD186x_TRAR); |
@@ -906,14 +950,16 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) | |||
906 | sx_transmit(bp); | 950 | sx_transmit(bp); |
907 | else | 951 | else |
908 | printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n", | 952 | printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n", |
909 | board_No(bp), status, ack, port_No (sx_get_port (bp, "Int"))); | 953 | board_No(bp), status, ack, |
954 | port_No(sx_get_port(bp, "Int"))); | ||
910 | } else if (status & SRSR_MREQint) { | 955 | } else if (status & SRSR_MREQint) { |
911 | ack = sx_in(bp, CD186x_MRAR); | 956 | ack = sx_in(bp, CD186x_MRAR); |
912 | 957 | ||
913 | if (ack == (SX_ID | GIVR_IT_MODEM)) | 958 | if (ack == (SX_ID | GIVR_IT_MODEM)) |
914 | sx_check_modem(bp); | 959 | sx_check_modem(bp); |
915 | else | 960 | else |
916 | printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n", | 961 | printk(KERN_ERR |
962 | "sx%d: status: 0x%x Bad modem ack 0x%02x.\n", | ||
917 | board_No(bp), status, ack); | 963 | board_No(bp), status, ack); |
918 | 964 | ||
919 | } | 965 | } |
@@ -921,7 +967,7 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) | |||
921 | sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */ | 967 | sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */ |
922 | } | 968 | } |
923 | bp->reg = saved_reg; | 969 | bp->reg = saved_reg; |
924 | outb (bp->reg, bp->base + SX_ADDR_REG); | 970 | outb(bp->reg, bp->base + SX_ADDR_REG); |
925 | spin_unlock_irqrestore(&bp->lock, flags); | 971 | spin_unlock_irqrestore(&bp->lock, flags); |
926 | func_exit(); | 972 | func_exit(); |
927 | return IRQ_HANDLED; | 973 | return IRQ_HANDLED; |
@@ -932,7 +978,7 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) | |||
932 | * Routines for open & close processing. | 978 | * Routines for open & close processing. |
933 | */ | 979 | */ |
934 | 980 | ||
935 | static void turn_ints_off (struct specialix_board *bp) | 981 | static void turn_ints_off(struct specialix_board *bp) |
936 | { | 982 | { |
937 | unsigned long flags; | 983 | unsigned long flags; |
938 | 984 | ||
@@ -945,13 +991,13 @@ static void turn_ints_off (struct specialix_board *bp) | |||
945 | } | 991 | } |
946 | 992 | ||
947 | spin_lock_irqsave(&bp->lock, flags); | 993 | spin_lock_irqsave(&bp->lock, flags); |
948 | (void) sx_in_off (bp, 0); /* Turn off interrupts. */ | 994 | (void) sx_in_off(bp, 0); /* Turn off interrupts. */ |
949 | spin_unlock_irqrestore(&bp->lock, flags); | 995 | spin_unlock_irqrestore(&bp->lock, flags); |
950 | 996 | ||
951 | func_exit(); | 997 | func_exit(); |
952 | } | 998 | } |
953 | 999 | ||
954 | static void turn_ints_on (struct specialix_board *bp) | 1000 | static void turn_ints_on(struct specialix_board *bp) |
955 | { | 1001 | { |
956 | unsigned long flags; | 1002 | unsigned long flags; |
957 | 1003 | ||
@@ -961,7 +1007,7 @@ static void turn_ints_on (struct specialix_board *bp) | |||
961 | /* play with the PCI chip. See comment above. */ | 1007 | /* play with the PCI chip. See comment above. */ |
962 | } | 1008 | } |
963 | spin_lock_irqsave(&bp->lock, flags); | 1009 | spin_lock_irqsave(&bp->lock, flags); |
964 | (void) sx_in (bp, 0); /* Turn ON interrupts. */ | 1010 | (void) sx_in(bp, 0); /* Turn ON interrupts. */ |
965 | spin_unlock_irqrestore(&bp->lock, flags); | 1011 | spin_unlock_irqrestore(&bp->lock, flags); |
966 | 1012 | ||
967 | func_exit(); | 1013 | func_exit(); |
@@ -969,7 +1015,7 @@ static void turn_ints_on (struct specialix_board *bp) | |||
969 | 1015 | ||
970 | 1016 | ||
971 | /* Called with disabled interrupts */ | 1017 | /* Called with disabled interrupts */ |
972 | static inline int sx_setup_board(struct specialix_board * bp) | 1018 | static inline int sx_setup_board(struct specialix_board *bp) |
973 | { | 1019 | { |
974 | int error; | 1020 | int error; |
975 | 1021 | ||
@@ -977,14 +1023,16 @@ static inline int sx_setup_board(struct specialix_board * bp) | |||
977 | return 0; | 1023 | return 0; |
978 | 1024 | ||
979 | if (bp->flags & SX_BOARD_IS_PCI) | 1025 | if (bp->flags & SX_BOARD_IS_PCI) |
980 | error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp); | 1026 | error = request_irq(bp->irq, sx_interrupt, |
1027 | IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp); | ||
981 | else | 1028 | else |
982 | error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED, "specialix IO8+", bp); | 1029 | error = request_irq(bp->irq, sx_interrupt, |
1030 | IRQF_DISABLED, "specialix IO8+", bp); | ||
983 | 1031 | ||
984 | if (error) | 1032 | if (error) |
985 | return error; | 1033 | return error; |
986 | 1034 | ||
987 | turn_ints_on (bp); | 1035 | turn_ints_on(bp); |
988 | bp->flags |= SX_BOARD_ACTIVE; | 1036 | bp->flags |= SX_BOARD_ACTIVE; |
989 | 1037 | ||
990 | return 0; | 1038 | return 0; |
@@ -1003,13 +1051,10 @@ static inline void sx_shutdown_board(struct specialix_board *bp) | |||
1003 | 1051 | ||
1004 | bp->flags &= ~SX_BOARD_ACTIVE; | 1052 | bp->flags &= ~SX_BOARD_ACTIVE; |
1005 | 1053 | ||
1006 | dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n", | 1054 | dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n", |
1007 | bp->irq, board_No (bp)); | 1055 | bp->irq, board_No(bp)); |
1008 | free_irq(bp->irq, bp); | 1056 | free_irq(bp->irq, bp); |
1009 | 1057 | turn_ints_off(bp); | |
1010 | turn_ints_off (bp); | ||
1011 | |||
1012 | |||
1013 | func_exit(); | 1058 | func_exit(); |
1014 | } | 1059 | } |
1015 | 1060 | ||
@@ -1018,7 +1063,8 @@ static inline void sx_shutdown_board(struct specialix_board *bp) | |||
1018 | * Setting up port characteristics. | 1063 | * Setting up port characteristics. |
1019 | * Must be called with disabled interrupts | 1064 | * Must be called with disabled interrupts |
1020 | */ | 1065 | */ |
1021 | static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port) | 1066 | static void sx_change_speed(struct specialix_board *bp, |
1067 | struct specialix_port *port) | ||
1022 | { | 1068 | { |
1023 | struct tty_struct *tty; | 1069 | struct tty_struct *tty; |
1024 | unsigned long baud; | 1070 | unsigned long baud; |
@@ -1030,7 +1076,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1030 | 1076 | ||
1031 | func_enter(); | 1077 | func_enter(); |
1032 | 1078 | ||
1033 | if (!(tty = port->port.tty) || !tty->termios) { | 1079 | tty = port->port.tty; |
1080 | if (!tty || !tty->termios) { | ||
1034 | func_exit(); | 1081 | func_exit(); |
1035 | return; | 1082 | return; |
1036 | } | 1083 | } |
@@ -1048,7 +1095,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1048 | else | 1095 | else |
1049 | port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS); | 1096 | port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS); |
1050 | spin_unlock_irqrestore(&bp->lock, flags); | 1097 | spin_unlock_irqrestore(&bp->lock, flags); |
1051 | dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR); | 1098 | dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR); |
1052 | baud = tty_get_baud_rate(tty); | 1099 | baud = tty_get_baud_rate(tty); |
1053 | 1100 | ||
1054 | if (baud == 38400) { | 1101 | if (baud == 38400) { |
@@ -1060,21 +1107,19 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1060 | 1107 | ||
1061 | if (!baud) { | 1108 | if (!baud) { |
1062 | /* Drop DTR & exit */ | 1109 | /* Drop DTR & exit */ |
1063 | dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); | 1110 | dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); |
1064 | if (!SX_CRTSCTS (tty)) { | 1111 | if (!SX_CRTSCTS(tty)) { |
1065 | port -> MSVR &= ~ MSVR_DTR; | 1112 | port->MSVR &= ~MSVR_DTR; |
1066 | spin_lock_irqsave(&bp->lock, flags); | 1113 | spin_lock_irqsave(&bp->lock, flags); |
1067 | sx_out(bp, CD186x_MSVR, port->MSVR ); | 1114 | sx_out(bp, CD186x_MSVR, port->MSVR); |
1068 | spin_unlock_irqrestore(&bp->lock, flags); | 1115 | spin_unlock_irqrestore(&bp->lock, flags); |
1069 | } | 1116 | } else |
1070 | else | 1117 | dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n"); |
1071 | dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n"); | ||
1072 | return; | 1118 | return; |
1073 | } else { | 1119 | } else { |
1074 | /* Set DTR on */ | 1120 | /* Set DTR on */ |
1075 | if (!SX_CRTSCTS (tty)) { | 1121 | if (!SX_CRTSCTS(tty)) |
1076 | port ->MSVR |= MSVR_DTR; | 1122 | port->MSVR |= MSVR_DTR; |
1077 | } | ||
1078 | } | 1123 | } |
1079 | 1124 | ||
1080 | /* | 1125 | /* |
@@ -1083,28 +1128,27 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1083 | 1128 | ||
1084 | /* Set baud rate for port */ | 1129 | /* Set baud rate for port */ |
1085 | tmp = port->custom_divisor ; | 1130 | tmp = port->custom_divisor ; |
1086 | if ( tmp ) | 1131 | if (tmp) |
1087 | printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n" | 1132 | printk(KERN_INFO |
1088 | "This is an untested option, please be carefull.\n", | 1133 | "sx%d: Using custom baud rate divisor %ld. \n" |
1089 | port_No (port), tmp); | 1134 | "This is an untested option, please be careful.\n", |
1135 | port_No(port), tmp); | ||
1090 | else | 1136 | else |
1091 | tmp = (((SX_OSCFREQ + baud/2) / baud + | 1137 | tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) / |
1092 | CD186x_TPC/2) / CD186x_TPC); | 1138 | CD186x_TPC); |
1093 | 1139 | ||
1094 | if ((tmp < 0x10) && time_before(again, jiffies)) { | 1140 | if (tmp < 0x10 && time_before(again, jiffies)) { |
1095 | again = jiffies + HZ * 60; | 1141 | again = jiffies + HZ * 60; |
1096 | /* Page 48 of version 2.0 of the CL-CD1865 databook */ | 1142 | /* Page 48 of version 2.0 of the CL-CD1865 databook */ |
1097 | if (tmp >= 12) { | 1143 | if (tmp >= 12) { |
1098 | printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n" | 1144 | printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n" |
1099 | "Performance degradation is possible.\n" | 1145 | "Performance degradation is possible.\n" |
1100 | "Read specialix.txt for more info.\n", | 1146 | "Read specialix.txt for more info.\n", |
1101 | port_No (port), tmp); | 1147 | port_No(port), tmp); |
1102 | } else { | 1148 | } else { |
1103 | printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n" | 1149 | printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n" |
1104 | "Warning: overstressing Cirrus chip. " | 1150 | "Warning: overstressing Cirrus chip. This might not work.\n" |
1105 | "This might not work.\n" | 1151 | "Read specialix.txt for more info.\n", port_No(port), tmp); |
1106 | "Read specialix.txt for more info.\n", | ||
1107 | port_No (port), tmp); | ||
1108 | } | 1152 | } |
1109 | } | 1153 | } |
1110 | spin_lock_irqsave(&bp->lock, flags); | 1154 | spin_lock_irqsave(&bp->lock, flags); |
@@ -1114,7 +1158,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1114 | sx_out(bp, CD186x_TBPRL, tmp & 0xff); | 1158 | sx_out(bp, CD186x_TBPRL, tmp & 0xff); |
1115 | spin_unlock_irqrestore(&bp->lock, flags); | 1159 | spin_unlock_irqrestore(&bp->lock, flags); |
1116 | if (port->custom_divisor) | 1160 | if (port->custom_divisor) |
1117 | baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; | 1161 | baud = (SX_OSCFREQ + port->custom_divisor/2) / |
1162 | port->custom_divisor; | ||
1118 | baud = (baud + 5) / 10; /* Estimated CPS */ | 1163 | baud = (baud + 5) / 10; /* Estimated CPS */ |
1119 | 1164 | ||
1120 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ | 1165 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ |
@@ -1129,16 +1174,16 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1129 | sx_out(bp, CD186x_RTPR, tmp); | 1174 | sx_out(bp, CD186x_RTPR, tmp); |
1130 | spin_unlock_irqrestore(&bp->lock, flags); | 1175 | spin_unlock_irqrestore(&bp->lock, flags); |
1131 | switch (C_CSIZE(tty)) { | 1176 | switch (C_CSIZE(tty)) { |
1132 | case CS5: | 1177 | case CS5: |
1133 | cor1 |= COR1_5BITS; | 1178 | cor1 |= COR1_5BITS; |
1134 | break; | 1179 | break; |
1135 | case CS6: | 1180 | case CS6: |
1136 | cor1 |= COR1_6BITS; | 1181 | cor1 |= COR1_6BITS; |
1137 | break; | 1182 | break; |
1138 | case CS7: | 1183 | case CS7: |
1139 | cor1 |= COR1_7BITS; | 1184 | cor1 |= COR1_7BITS; |
1140 | break; | 1185 | break; |
1141 | case CS8: | 1186 | case CS8: |
1142 | cor1 |= COR1_8BITS; | 1187 | cor1 |= COR1_8BITS; |
1143 | break; | 1188 | break; |
1144 | } | 1189 | } |
@@ -1175,7 +1220,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1175 | mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; | 1220 | mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; |
1176 | mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; | 1221 | mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; |
1177 | spin_lock_irqsave(&bp->lock, flags); | 1222 | spin_lock_irqsave(&bp->lock, flags); |
1178 | tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR)); | 1223 | tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & |
1224 | (MSVR_CTS|MSVR_DSR)); | ||
1179 | spin_unlock_irqrestore(&bp->lock, flags); | 1225 | spin_unlock_irqrestore(&bp->lock, flags); |
1180 | #else | 1226 | #else |
1181 | port->COR2 |= COR2_CTSAE; | 1227 | port->COR2 |= COR2_CTSAE; |
@@ -1219,7 +1265,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1219 | spin_lock_irqsave(&bp->lock, flags); | 1265 | spin_lock_irqsave(&bp->lock, flags); |
1220 | sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); | 1266 | sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); |
1221 | /* Setting up modem option registers */ | 1267 | /* Setting up modem option registers */ |
1222 | dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2); | 1268 | dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", |
1269 | mcor1, mcor2); | ||
1223 | sx_out(bp, CD186x_MCOR1, mcor1); | 1270 | sx_out(bp, CD186x_MCOR1, mcor1); |
1224 | sx_out(bp, CD186x_MCOR2, mcor2); | 1271 | sx_out(bp, CD186x_MCOR2, mcor2); |
1225 | spin_unlock_irqrestore(&bp->lock, flags); | 1272 | spin_unlock_irqrestore(&bp->lock, flags); |
@@ -1238,7 +1285,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1238 | 1285 | ||
1239 | 1286 | ||
1240 | /* Must be called with interrupts enabled */ | 1287 | /* Must be called with interrupts enabled */ |
1241 | static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port) | 1288 | static int sx_setup_port(struct specialix_board *bp, |
1289 | struct specialix_port *port) | ||
1242 | { | 1290 | { |
1243 | unsigned long flags; | 1291 | unsigned long flags; |
1244 | 1292 | ||
@@ -1253,7 +1301,8 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port | |||
1253 | /* We may sleep in get_zeroed_page() */ | 1301 | /* We may sleep in get_zeroed_page() */ |
1254 | unsigned long tmp; | 1302 | unsigned long tmp; |
1255 | 1303 | ||
1256 | if (!(tmp = get_zeroed_page(GFP_KERNEL))) { | 1304 | tmp = get_zeroed_page(GFP_KERNEL); |
1305 | if (tmp == 0L) { | ||
1257 | func_exit(); | 1306 | func_exit(); |
1258 | return -ENOMEM; | 1307 | return -ENOMEM; |
1259 | } | 1308 | } |
@@ -1284,7 +1333,8 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port | |||
1284 | 1333 | ||
1285 | 1334 | ||
1286 | /* Must be called with interrupts disabled */ | 1335 | /* Must be called with interrupts disabled */ |
1287 | static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port) | 1336 | static void sx_shutdown_port(struct specialix_board *bp, |
1337 | struct specialix_port *port) | ||
1288 | { | 1338 | { |
1289 | struct tty_struct *tty; | 1339 | struct tty_struct *tty; |
1290 | int i; | 1340 | int i; |
@@ -1298,11 +1348,11 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port * | |||
1298 | } | 1348 | } |
1299 | 1349 | ||
1300 | if (sx_debug & SX_DEBUG_FIFO) { | 1350 | if (sx_debug & SX_DEBUG_FIFO) { |
1301 | dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ", | 1351 | dprintk(SX_DEBUG_FIFO, |
1302 | board_No(bp), port_No(port), port->overrun); | 1352 | "sx%d: port %d: %ld overruns, FIFO hits [ ", |
1303 | for (i = 0; i < 10; i++) { | 1353 | board_No(bp), port_No(port), port->overrun); |
1354 | for (i = 0; i < 10; i++) | ||
1304 | dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]); | 1355 | dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]); |
1305 | } | ||
1306 | dprintk(SX_DEBUG_FIFO, "].\n"); | 1356 | dprintk(SX_DEBUG_FIFO, "].\n"); |
1307 | } | 1357 | } |
1308 | 1358 | ||
@@ -1315,7 +1365,8 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port * | |||
1315 | spin_lock_irqsave(&bp->lock, flags); | 1365 | spin_lock_irqsave(&bp->lock, flags); |
1316 | sx_out(bp, CD186x_CAR, port_No(port)); | 1366 | sx_out(bp, CD186x_CAR, port_No(port)); |
1317 | 1367 | ||
1318 | if (!(tty = port->port.tty) || C_HUPCL(tty)) { | 1368 | tty = port->port.tty; |
1369 | if (tty == NULL || C_HUPCL(tty)) { | ||
1319 | /* Drop DTR */ | 1370 | /* Drop DTR */ |
1320 | sx_out(bp, CD186x_MSVDTR, 0); | 1371 | sx_out(bp, CD186x_MSVDTR, 0); |
1321 | } | 1372 | } |
@@ -1338,8 +1389,8 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port * | |||
1338 | } | 1389 | } |
1339 | 1390 | ||
1340 | 1391 | ||
1341 | static int block_til_ready(struct tty_struct *tty, struct file * filp, | 1392 | static int block_til_ready(struct tty_struct *tty, struct file *filp, |
1342 | struct specialix_port *port) | 1393 | struct specialix_port *port) |
1343 | { | 1394 | { |
1344 | DECLARE_WAITQUEUE(wait, current); | 1395 | DECLARE_WAITQUEUE(wait, current); |
1345 | struct specialix_board *bp = port_Board(port); | 1396 | struct specialix_board *bp = port_Board(port); |
@@ -1389,23 +1440,22 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1389 | retval = 0; | 1440 | retval = 0; |
1390 | add_wait_queue(&port->port.open_wait, &wait); | 1441 | add_wait_queue(&port->port.open_wait, &wait); |
1391 | spin_lock_irqsave(&port->lock, flags); | 1442 | spin_lock_irqsave(&port->lock, flags); |
1392 | if (!tty_hung_up_p(filp)) { | 1443 | if (!tty_hung_up_p(filp)) |
1393 | port->port.count--; | 1444 | port->port.count--; |
1394 | } | ||
1395 | spin_unlock_irqrestore(&port->lock, flags); | 1445 | spin_unlock_irqrestore(&port->lock, flags); |
1396 | port->port.blocked_open++; | 1446 | port->port.blocked_open++; |
1397 | while (1) { | 1447 | while (1) { |
1398 | spin_lock_irqsave(&bp->lock, flags); | 1448 | spin_lock_irqsave(&bp->lock, flags); |
1399 | sx_out(bp, CD186x_CAR, port_No(port)); | 1449 | sx_out(bp, CD186x_CAR, port_No(port)); |
1400 | CD = sx_in(bp, CD186x_MSVR) & MSVR_CD; | 1450 | CD = sx_in(bp, CD186x_MSVR) & MSVR_CD; |
1401 | if (SX_CRTSCTS (tty)) { | 1451 | if (SX_CRTSCTS(tty)) { |
1402 | /* Activate RTS */ | 1452 | /* Activate RTS */ |
1403 | port->MSVR |= MSVR_DTR; /* WTF? */ | 1453 | port->MSVR |= MSVR_DTR; /* WTF? */ |
1404 | sx_out (bp, CD186x_MSVR, port->MSVR); | 1454 | sx_out(bp, CD186x_MSVR, port->MSVR); |
1405 | } else { | 1455 | } else { |
1406 | /* Activate DTR */ | 1456 | /* Activate DTR */ |
1407 | port->MSVR |= MSVR_DTR; | 1457 | port->MSVR |= MSVR_DTR; |
1408 | sx_out (bp, CD186x_MSVR, port->MSVR); | 1458 | sx_out(bp, CD186x_MSVR, port->MSVR); |
1409 | } | 1459 | } |
1410 | spin_unlock_irqrestore(&bp->lock, flags); | 1460 | spin_unlock_irqrestore(&bp->lock, flags); |
1411 | set_current_state(TASK_INTERRUPTIBLE); | 1461 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -1430,9 +1480,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1430 | set_current_state(TASK_RUNNING); | 1480 | set_current_state(TASK_RUNNING); |
1431 | remove_wait_queue(&port->port.open_wait, &wait); | 1481 | remove_wait_queue(&port->port.open_wait, &wait); |
1432 | spin_lock_irqsave(&port->lock, flags); | 1482 | spin_lock_irqsave(&port->lock, flags); |
1433 | if (!tty_hung_up_p(filp)) { | 1483 | if (!tty_hung_up_p(filp)) |
1434 | port->port.count++; | 1484 | port->port.count++; |
1435 | } | ||
1436 | port->port.blocked_open--; | 1485 | port->port.blocked_open--; |
1437 | spin_unlock_irqrestore(&port->lock, flags); | 1486 | spin_unlock_irqrestore(&port->lock, flags); |
1438 | if (retval) { | 1487 | if (retval) { |
@@ -1446,12 +1495,12 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1446 | } | 1495 | } |
1447 | 1496 | ||
1448 | 1497 | ||
1449 | static int sx_open(struct tty_struct * tty, struct file * filp) | 1498 | static int sx_open(struct tty_struct *tty, struct file *filp) |
1450 | { | 1499 | { |
1451 | int board; | 1500 | int board; |
1452 | int error; | 1501 | int error; |
1453 | struct specialix_port * port; | 1502 | struct specialix_port *port; |
1454 | struct specialix_board * bp; | 1503 | struct specialix_board *bp; |
1455 | int i; | 1504 | int i; |
1456 | unsigned long flags; | 1505 | unsigned long flags; |
1457 | 1506 | ||
@@ -1468,17 +1517,19 @@ static int sx_open(struct tty_struct * tty, struct file * filp) | |||
1468 | port = sx_port + board * SX_NPORT + SX_PORT(tty->index); | 1517 | port = sx_port + board * SX_NPORT + SX_PORT(tty->index); |
1469 | port->overrun = 0; | 1518 | port->overrun = 0; |
1470 | for (i = 0; i < 10; i++) | 1519 | for (i = 0; i < 10; i++) |
1471 | port->hits[i]=0; | 1520 | port->hits[i] = 0; |
1472 | 1521 | ||
1473 | dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n", | 1522 | dprintk(SX_DEBUG_OPEN, |
1474 | board, bp, port, SX_PORT(tty->index)); | 1523 | "Board = %d, bp = %p, port = %p, portno = %d.\n", |
1524 | board, bp, port, SX_PORT(tty->index)); | ||
1475 | 1525 | ||
1476 | if (sx_paranoia_check(port, tty->name, "sx_open")) { | 1526 | if (sx_paranoia_check(port, tty->name, "sx_open")) { |
1477 | func_enter(); | 1527 | func_enter(); |
1478 | return -ENODEV; | 1528 | return -ENODEV; |
1479 | } | 1529 | } |
1480 | 1530 | ||
1481 | if ((error = sx_setup_board(bp))) { | 1531 | error = sx_setup_board(bp); |
1532 | if (error) { | ||
1482 | func_exit(); | 1533 | func_exit(); |
1483 | return error; | 1534 | return error; |
1484 | } | 1535 | } |
@@ -1490,12 +1541,14 @@ static int sx_open(struct tty_struct * tty, struct file * filp) | |||
1490 | port->port.tty = tty; | 1541 | port->port.tty = tty; |
1491 | spin_unlock_irqrestore(&bp->lock, flags); | 1542 | spin_unlock_irqrestore(&bp->lock, flags); |
1492 | 1543 | ||
1493 | if ((error = sx_setup_port(bp, port))) { | 1544 | error = sx_setup_port(bp, port); |
1545 | if (error) { | ||
1494 | func_enter(); | 1546 | func_enter(); |
1495 | return error; | 1547 | return error; |
1496 | } | 1548 | } |
1497 | 1549 | ||
1498 | if ((error = block_til_ready(tty, filp, port))) { | 1550 | error = block_til_ready(tty, filp, port); |
1551 | if (error) { | ||
1499 | func_enter(); | 1552 | func_enter(); |
1500 | return error; | 1553 | return error; |
1501 | } | 1554 | } |
@@ -1508,7 +1561,7 @@ static void sx_flush_buffer(struct tty_struct *tty) | |||
1508 | { | 1561 | { |
1509 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 1562 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1510 | unsigned long flags; | 1563 | unsigned long flags; |
1511 | struct specialix_board * bp; | 1564 | struct specialix_board *bp; |
1512 | 1565 | ||
1513 | func_enter(); | 1566 | func_enter(); |
1514 | 1567 | ||
@@ -1526,9 +1579,9 @@ static void sx_flush_buffer(struct tty_struct *tty) | |||
1526 | func_exit(); | 1579 | func_exit(); |
1527 | } | 1580 | } |
1528 | 1581 | ||
1529 | static void sx_close(struct tty_struct * tty, struct file * filp) | 1582 | static void sx_close(struct tty_struct *tty, struct file *filp) |
1530 | { | 1583 | { |
1531 | struct specialix_port *port = (struct specialix_port *) tty->driver_data; | 1584 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1532 | struct specialix_board *bp; | 1585 | struct specialix_board *bp; |
1533 | unsigned long flags; | 1586 | unsigned long flags; |
1534 | unsigned long timeout; | 1587 | unsigned long timeout; |
@@ -1570,17 +1623,16 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1570 | */ | 1623 | */ |
1571 | tty->closing = 1; | 1624 | tty->closing = 1; |
1572 | spin_unlock_irqrestore(&port->lock, flags); | 1625 | spin_unlock_irqrestore(&port->lock, flags); |
1573 | dprintk (SX_DEBUG_OPEN, "Closing\n"); | 1626 | dprintk(SX_DEBUG_OPEN, "Closing\n"); |
1574 | if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) { | 1627 | if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1575 | tty_wait_until_sent(tty, port->port.closing_wait); | 1628 | tty_wait_until_sent(tty, port->port.closing_wait); |
1576 | } | ||
1577 | /* | 1629 | /* |
1578 | * At this point we stop accepting input. To do this, we | 1630 | * At this point we stop accepting input. To do this, we |
1579 | * disable the receive line status interrupts, and tell the | 1631 | * disable the receive line status interrupts, and tell the |
1580 | * interrupt driver to stop checking the data ready bit in the | 1632 | * interrupt driver to stop checking the data ready bit in the |
1581 | * line status register. | 1633 | * line status register. |
1582 | */ | 1634 | */ |
1583 | dprintk (SX_DEBUG_OPEN, "Closed\n"); | 1635 | dprintk(SX_DEBUG_OPEN, "Closed\n"); |
1584 | port->IER &= ~IER_RXD; | 1636 | port->IER &= ~IER_RXD; |
1585 | if (port->port.flags & ASYNC_INITIALIZED) { | 1637 | if (port->port.flags & ASYNC_INITIALIZED) { |
1586 | port->IER &= ~IER_TXRDY; | 1638 | port->IER &= ~IER_TXRDY; |
@@ -1595,11 +1647,11 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1595 | * important if there is a transmit FIFO! | 1647 | * important if there is a transmit FIFO! |
1596 | */ | 1648 | */ |
1597 | timeout = jiffies+HZ; | 1649 | timeout = jiffies+HZ; |
1598 | while(port->IER & IER_TXEMPTY) { | 1650 | while (port->IER & IER_TXEMPTY) { |
1599 | set_current_state (TASK_INTERRUPTIBLE); | 1651 | set_current_state(TASK_INTERRUPTIBLE); |
1600 | msleep_interruptible(jiffies_to_msecs(port->timeout)); | 1652 | msleep_interruptible(jiffies_to_msecs(port->timeout)); |
1601 | if (time_after(jiffies, timeout)) { | 1653 | if (time_after(jiffies, timeout)) { |
1602 | printk (KERN_INFO "Timeout waiting for close\n"); | 1654 | printk(KERN_INFO "Timeout waiting for close\n"); |
1603 | break; | 1655 | break; |
1604 | } | 1656 | } |
1605 | } | 1657 | } |
@@ -1607,13 +1659,15 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1607 | } | 1659 | } |
1608 | 1660 | ||
1609 | if (--bp->count < 0) { | 1661 | if (--bp->count < 0) { |
1610 | printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n", | 1662 | printk(KERN_ERR |
1611 | board_No(bp), bp->count, tty->index); | 1663 | "sx%d: sx_shutdown_port: bad board count: %d port: %d\n", |
1664 | board_No(bp), bp->count, tty->index); | ||
1612 | bp->count = 0; | 1665 | bp->count = 0; |
1613 | } | 1666 | } |
1614 | if (--port->port.count < 0) { | 1667 | if (--port->port.count < 0) { |
1615 | printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n", | 1668 | printk(KERN_ERR |
1616 | board_No(bp), port_No(port), port->port.count); | 1669 | "sx%d: sx_close: bad port count for tty%d: %d\n", |
1670 | board_No(bp), port_No(port), port->port.count); | ||
1617 | port->port.count = 0; | 1671 | port->port.count = 0; |
1618 | } | 1672 | } |
1619 | 1673 | ||
@@ -1625,9 +1679,9 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1625 | port->port.tty = NULL; | 1679 | port->port.tty = NULL; |
1626 | spin_unlock_irqrestore(&port->lock, flags); | 1680 | spin_unlock_irqrestore(&port->lock, flags); |
1627 | if (port->port.blocked_open) { | 1681 | if (port->port.blocked_open) { |
1628 | if (port->port.close_delay) { | 1682 | if (port->port.close_delay) |
1629 | msleep_interruptible(jiffies_to_msecs(port->port.close_delay)); | 1683 | msleep_interruptible( |
1630 | } | 1684 | jiffies_to_msecs(port->port.close_delay)); |
1631 | wake_up_interruptible(&port->port.open_wait); | 1685 | wake_up_interruptible(&port->port.open_wait); |
1632 | } | 1686 | } |
1633 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1687 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
@@ -1637,8 +1691,8 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1637 | } | 1691 | } |
1638 | 1692 | ||
1639 | 1693 | ||
1640 | static int sx_write(struct tty_struct * tty, | 1694 | static int sx_write(struct tty_struct *tty, |
1641 | const unsigned char *buf, int count) | 1695 | const unsigned char *buf, int count) |
1642 | { | 1696 | { |
1643 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 1697 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1644 | struct specialix_board *bp; | 1698 | struct specialix_board *bp; |
@@ -1690,11 +1744,11 @@ static int sx_write(struct tty_struct * tty, | |||
1690 | } | 1744 | } |
1691 | 1745 | ||
1692 | 1746 | ||
1693 | static int sx_put_char(struct tty_struct * tty, unsigned char ch) | 1747 | static int sx_put_char(struct tty_struct *tty, unsigned char ch) |
1694 | { | 1748 | { |
1695 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 1749 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1696 | unsigned long flags; | 1750 | unsigned long flags; |
1697 | struct specialix_board * bp; | 1751 | struct specialix_board *bp; |
1698 | 1752 | ||
1699 | func_enter(); | 1753 | func_enter(); |
1700 | 1754 | ||
@@ -1702,7 +1756,7 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch) | |||
1702 | func_exit(); | 1756 | func_exit(); |
1703 | return 0; | 1757 | return 0; |
1704 | } | 1758 | } |
1705 | dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); | 1759 | dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); |
1706 | if (!port->xmit_buf) { | 1760 | if (!port->xmit_buf) { |
1707 | func_exit(); | 1761 | func_exit(); |
1708 | return 0; | 1762 | return 0; |
@@ -1710,14 +1764,15 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch) | |||
1710 | bp = port_Board(port); | 1764 | bp = port_Board(port); |
1711 | spin_lock_irqsave(&port->lock, flags); | 1765 | spin_lock_irqsave(&port->lock, flags); |
1712 | 1766 | ||
1713 | dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf); | 1767 | dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", |
1714 | if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) { | 1768 | port->xmit_cnt, port->xmit_buf); |
1769 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) { | ||
1715 | spin_unlock_irqrestore(&port->lock, flags); | 1770 | spin_unlock_irqrestore(&port->lock, flags); |
1716 | dprintk (SX_DEBUG_TX, "Exit size\n"); | 1771 | dprintk(SX_DEBUG_TX, "Exit size\n"); |
1717 | func_exit(); | 1772 | func_exit(); |
1718 | return 0; | 1773 | return 0; |
1719 | } | 1774 | } |
1720 | dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf); | 1775 | dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf); |
1721 | port->xmit_buf[port->xmit_head++] = ch; | 1776 | port->xmit_buf[port->xmit_head++] = ch; |
1722 | port->xmit_head &= SERIAL_XMIT_SIZE - 1; | 1777 | port->xmit_head &= SERIAL_XMIT_SIZE - 1; |
1723 | port->xmit_cnt++; | 1778 | port->xmit_cnt++; |
@@ -1728,11 +1783,11 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch) | |||
1728 | } | 1783 | } |
1729 | 1784 | ||
1730 | 1785 | ||
1731 | static void sx_flush_chars(struct tty_struct * tty) | 1786 | static void sx_flush_chars(struct tty_struct *tty) |
1732 | { | 1787 | { |
1733 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 1788 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1734 | unsigned long flags; | 1789 | unsigned long flags; |
1735 | struct specialix_board * bp = port_Board(port); | 1790 | struct specialix_board *bp = port_Board(port); |
1736 | 1791 | ||
1737 | func_enter(); | 1792 | func_enter(); |
1738 | 1793 | ||
@@ -1755,7 +1810,7 @@ static void sx_flush_chars(struct tty_struct * tty) | |||
1755 | } | 1810 | } |
1756 | 1811 | ||
1757 | 1812 | ||
1758 | static int sx_write_room(struct tty_struct * tty) | 1813 | static int sx_write_room(struct tty_struct *tty) |
1759 | { | 1814 | { |
1760 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 1815 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1761 | int ret; | 1816 | int ret; |
@@ -1790,12 +1845,10 @@ static int sx_chars_in_buffer(struct tty_struct *tty) | |||
1790 | return port->xmit_cnt; | 1845 | return port->xmit_cnt; |
1791 | } | 1846 | } |
1792 | 1847 | ||
1793 | |||
1794 | |||
1795 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) | 1848 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) |
1796 | { | 1849 | { |
1797 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 1850 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1798 | struct specialix_board * bp; | 1851 | struct specialix_board *bp; |
1799 | unsigned char status; | 1852 | unsigned char status; |
1800 | unsigned int result; | 1853 | unsigned int result; |
1801 | unsigned long flags; | 1854 | unsigned long flags; |
@@ -1808,25 +1861,25 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file) | |||
1808 | } | 1861 | } |
1809 | 1862 | ||
1810 | bp = port_Board(port); | 1863 | bp = port_Board(port); |
1811 | spin_lock_irqsave (&bp->lock, flags); | 1864 | spin_lock_irqsave(&bp->lock, flags); |
1812 | sx_out(bp, CD186x_CAR, port_No(port)); | 1865 | sx_out(bp, CD186x_CAR, port_No(port)); |
1813 | status = sx_in(bp, CD186x_MSVR); | 1866 | status = sx_in(bp, CD186x_MSVR); |
1814 | spin_unlock_irqrestore(&bp->lock, flags); | 1867 | spin_unlock_irqrestore(&bp->lock, flags); |
1815 | dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n", | 1868 | dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n", |
1816 | port_No(port), status, sx_in (bp, CD186x_CAR)); | 1869 | port_No(port), status, sx_in(bp, CD186x_CAR)); |
1817 | dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); | 1870 | dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); |
1818 | if (SX_CRTSCTS(port->port.tty)) { | 1871 | if (SX_CRTSCTS(port->port.tty)) { |
1819 | result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ | 1872 | result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ |
1820 | | ((status & MSVR_DTR) ? TIOCM_RTS : 0) | 1873 | | ((status & MSVR_DTR) ? TIOCM_RTS : 0) |
1821 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) | 1874 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) |
1822 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ | 1875 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ |
1823 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); | 1876 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); |
1824 | } else { | 1877 | } else { |
1825 | result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ | 1878 | result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ |
1826 | | ((status & MSVR_DTR) ? TIOCM_DTR : 0) | 1879 | | ((status & MSVR_DTR) ? TIOCM_DTR : 0) |
1827 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) | 1880 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) |
1828 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ | 1881 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ |
1829 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); | 1882 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); |
1830 | } | 1883 | } |
1831 | 1884 | ||
1832 | func_exit(); | 1885 | func_exit(); |
@@ -1886,14 +1939,15 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, | |||
1886 | } | 1939 | } |
1887 | 1940 | ||
1888 | 1941 | ||
1889 | static inline void sx_send_break(struct specialix_port * port, unsigned long length) | 1942 | static inline void sx_send_break(struct specialix_port *port, |
1943 | unsigned long length) | ||
1890 | { | 1944 | { |
1891 | struct specialix_board *bp = port_Board(port); | 1945 | struct specialix_board *bp = port_Board(port); |
1892 | unsigned long flags; | 1946 | unsigned long flags; |
1893 | 1947 | ||
1894 | func_enter(); | 1948 | func_enter(); |
1895 | 1949 | ||
1896 | spin_lock_irqsave (&port->lock, flags); | 1950 | spin_lock_irqsave(&port->lock, flags); |
1897 | port->break_length = SPECIALIX_TPS / HZ * length; | 1951 | port->break_length = SPECIALIX_TPS / HZ * length; |
1898 | port->COR2 |= COR2_ETC; | 1952 | port->COR2 |= COR2_ETC; |
1899 | port->IER |= IER_TXRDY; | 1953 | port->IER |= IER_TXRDY; |
@@ -1902,7 +1956,7 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len | |||
1902 | sx_out(bp, CD186x_COR2, port->COR2); | 1956 | sx_out(bp, CD186x_COR2, port->COR2); |
1903 | sx_out(bp, CD186x_IER, port->IER); | 1957 | sx_out(bp, CD186x_IER, port->IER); |
1904 | spin_unlock_irqrestore(&bp->lock, flags); | 1958 | spin_unlock_irqrestore(&bp->lock, flags); |
1905 | spin_unlock_irqrestore (&port->lock, flags); | 1959 | spin_unlock_irqrestore(&port->lock, flags); |
1906 | sx_wait_CCR(bp); | 1960 | sx_wait_CCR(bp); |
1907 | spin_lock_irqsave(&bp->lock, flags); | 1961 | spin_lock_irqsave(&bp->lock, flags); |
1908 | sx_out(bp, CD186x_CCR, CCR_CORCHG2); | 1962 | sx_out(bp, CD186x_CCR, CCR_CORCHG2); |
@@ -1913,8 +1967,8 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len | |||
1913 | } | 1967 | } |
1914 | 1968 | ||
1915 | 1969 | ||
1916 | static inline int sx_set_serial_info(struct specialix_port * port, | 1970 | static inline int sx_set_serial_info(struct specialix_port *port, |
1917 | struct serial_struct __user * newinfo) | 1971 | struct serial_struct __user *newinfo) |
1918 | { | 1972 | { |
1919 | struct serial_struct tmp; | 1973 | struct serial_struct tmp; |
1920 | struct specialix_board *bp = port_Board(port); | 1974 | struct specialix_board *bp = port_Board(port); |
@@ -1943,25 +1997,25 @@ static inline int sx_set_serial_info(struct specialix_port * port, | |||
1943 | return -EPERM; | 1997 | return -EPERM; |
1944 | } | 1998 | } |
1945 | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | | 1999 | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | |
1946 | (tmp.flags & ASYNC_USR_MASK)); | 2000 | (tmp.flags & ASYNC_USR_MASK)); |
1947 | port->custom_divisor = tmp.custom_divisor; | 2001 | port->custom_divisor = tmp.custom_divisor; |
1948 | } else { | 2002 | } else { |
1949 | port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | | 2003 | port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | |
1950 | (tmp.flags & ASYNC_FLAGS)); | 2004 | (tmp.flags & ASYNC_FLAGS)); |
1951 | port->port.close_delay = tmp.close_delay; | 2005 | port->port.close_delay = tmp.close_delay; |
1952 | port->port.closing_wait = tmp.closing_wait; | 2006 | port->port.closing_wait = tmp.closing_wait; |
1953 | port->custom_divisor = tmp.custom_divisor; | 2007 | port->custom_divisor = tmp.custom_divisor; |
1954 | } | 2008 | } |
1955 | if (change_speed) { | 2009 | if (change_speed) |
1956 | sx_change_speed(bp, port); | 2010 | sx_change_speed(bp, port); |
1957 | } | 2011 | |
1958 | func_exit(); | 2012 | func_exit(); |
1959 | unlock_kernel(); | 2013 | unlock_kernel(); |
1960 | return 0; | 2014 | return 0; |
1961 | } | 2015 | } |
1962 | 2016 | ||
1963 | 2017 | ||
1964 | static inline int sx_get_serial_info(struct specialix_port * port, | 2018 | static inline int sx_get_serial_info(struct specialix_port *port, |
1965 | struct serial_struct __user *retinfo) | 2019 | struct serial_struct __user *retinfo) |
1966 | { | 2020 | { |
1967 | struct serial_struct tmp; | 2021 | struct serial_struct tmp; |
@@ -1992,8 +2046,8 @@ static inline int sx_get_serial_info(struct specialix_port * port, | |||
1992 | } | 2046 | } |
1993 | 2047 | ||
1994 | 2048 | ||
1995 | static int sx_ioctl(struct tty_struct * tty, struct file * filp, | 2049 | static int sx_ioctl(struct tty_struct *tty, struct file *filp, |
1996 | unsigned int cmd, unsigned long arg) | 2050 | unsigned int cmd, unsigned long arg) |
1997 | { | 2051 | { |
1998 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2052 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1999 | int retval; | 2053 | int retval; |
@@ -2007,7 +2061,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, | |||
2007 | } | 2061 | } |
2008 | 2062 | ||
2009 | switch (cmd) { | 2063 | switch (cmd) { |
2010 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 2064 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
2011 | retval = tty_check_change(tty); | 2065 | retval = tty_check_change(tty); |
2012 | if (retval) { | 2066 | if (retval) { |
2013 | func_exit(); | 2067 | func_exit(); |
@@ -2017,7 +2071,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, | |||
2017 | if (!arg) | 2071 | if (!arg) |
2018 | sx_send_break(port, HZ/4); /* 1/4 second */ | 2072 | sx_send_break(port, HZ/4); /* 1/4 second */ |
2019 | return 0; | 2073 | return 0; |
2020 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | 2074 | case TCSBRKP: /* support for POSIX tcsendbreak() */ |
2021 | retval = tty_check_change(tty); | 2075 | retval = tty_check_change(tty); |
2022 | if (retval) { | 2076 | if (retval) { |
2023 | func_exit(); | 2077 | func_exit(); |
@@ -2027,13 +2081,13 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, | |||
2027 | sx_send_break(port, arg ? arg*(HZ/10) : HZ/4); | 2081 | sx_send_break(port, arg ? arg*(HZ/10) : HZ/4); |
2028 | func_exit(); | 2082 | func_exit(); |
2029 | return 0; | 2083 | return 0; |
2030 | case TIOCGSERIAL: | 2084 | case TIOCGSERIAL: |
2031 | func_exit(); | 2085 | func_exit(); |
2032 | return sx_get_serial_info(port, argp); | 2086 | return sx_get_serial_info(port, argp); |
2033 | case TIOCSSERIAL: | 2087 | case TIOCSSERIAL: |
2034 | func_exit(); | 2088 | func_exit(); |
2035 | return sx_set_serial_info(port, argp); | 2089 | return sx_set_serial_info(port, argp); |
2036 | default: | 2090 | default: |
2037 | func_exit(); | 2091 | func_exit(); |
2038 | return -ENOIOCTLCMD; | 2092 | return -ENOIOCTLCMD; |
2039 | } | 2093 | } |
@@ -2042,7 +2096,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, | |||
2042 | } | 2096 | } |
2043 | 2097 | ||
2044 | 2098 | ||
2045 | static void sx_throttle(struct tty_struct * tty) | 2099 | static void sx_throttle(struct tty_struct *tty) |
2046 | { | 2100 | { |
2047 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2101 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
2048 | struct specialix_board *bp; | 2102 | struct specialix_board *bp; |
@@ -2058,15 +2112,16 @@ static void sx_throttle(struct tty_struct * tty) | |||
2058 | bp = port_Board(port); | 2112 | bp = port_Board(port); |
2059 | 2113 | ||
2060 | /* Use DTR instead of RTS ! */ | 2114 | /* Use DTR instead of RTS ! */ |
2061 | if (SX_CRTSCTS (tty)) | 2115 | if (SX_CRTSCTS(tty)) |
2062 | port->MSVR &= ~MSVR_DTR; | 2116 | port->MSVR &= ~MSVR_DTR; |
2063 | else { | 2117 | else { |
2064 | /* Auch!!! I think the system shouldn't call this then. */ | 2118 | /* Auch!!! I think the system shouldn't call this then. */ |
2065 | /* Or maybe we're supposed (allowed?) to do our side of hw | 2119 | /* Or maybe we're supposed (allowed?) to do our side of hw |
2066 | handshake anyway, even when hardware handshake is off. | 2120 | handshake anyway, even when hardware handshake is off. |
2067 | When you see this in your logs, please report.... */ | 2121 | When you see this in your logs, please report.... */ |
2068 | printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n", | 2122 | printk(KERN_ERR |
2069 | port_No (port)); | 2123 | "sx%d: Need to throttle, but can't (hardware hs is off)\n", |
2124 | port_No(port)); | ||
2070 | } | 2125 | } |
2071 | spin_lock_irqsave(&bp->lock, flags); | 2126 | spin_lock_irqsave(&bp->lock, flags); |
2072 | sx_out(bp, CD186x_CAR, port_No(port)); | 2127 | sx_out(bp, CD186x_CAR, port_No(port)); |
@@ -2086,7 +2141,7 @@ static void sx_throttle(struct tty_struct * tty) | |||
2086 | } | 2141 | } |
2087 | 2142 | ||
2088 | 2143 | ||
2089 | static void sx_unthrottle(struct tty_struct * tty) | 2144 | static void sx_unthrottle(struct tty_struct *tty) |
2090 | { | 2145 | { |
2091 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2146 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
2092 | struct specialix_board *bp; | 2147 | struct specialix_board *bp; |
@@ -2103,9 +2158,9 @@ static void sx_unthrottle(struct tty_struct * tty) | |||
2103 | 2158 | ||
2104 | spin_lock_irqsave(&port->lock, flags); | 2159 | spin_lock_irqsave(&port->lock, flags); |
2105 | /* XXXX Use DTR INSTEAD???? */ | 2160 | /* XXXX Use DTR INSTEAD???? */ |
2106 | if (SX_CRTSCTS(tty)) { | 2161 | if (SX_CRTSCTS(tty)) |
2107 | port->MSVR |= MSVR_DTR; | 2162 | port->MSVR |= MSVR_DTR; |
2108 | } /* Else clause: see remark in "sx_throttle"... */ | 2163 | /* Else clause: see remark in "sx_throttle"... */ |
2109 | spin_lock_irqsave(&bp->lock, flags); | 2164 | spin_lock_irqsave(&bp->lock, flags); |
2110 | sx_out(bp, CD186x_CAR, port_No(port)); | 2165 | sx_out(bp, CD186x_CAR, port_No(port)); |
2111 | spin_unlock_irqrestore(&bp->lock, flags); | 2166 | spin_unlock_irqrestore(&bp->lock, flags); |
@@ -2127,7 +2182,7 @@ static void sx_unthrottle(struct tty_struct * tty) | |||
2127 | } | 2182 | } |
2128 | 2183 | ||
2129 | 2184 | ||
2130 | static void sx_stop(struct tty_struct * tty) | 2185 | static void sx_stop(struct tty_struct *tty) |
2131 | { | 2186 | { |
2132 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2187 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
2133 | struct specialix_board *bp; | 2188 | struct specialix_board *bp; |
@@ -2154,7 +2209,7 @@ static void sx_stop(struct tty_struct * tty) | |||
2154 | } | 2209 | } |
2155 | 2210 | ||
2156 | 2211 | ||
2157 | static void sx_start(struct tty_struct * tty) | 2212 | static void sx_start(struct tty_struct *tty) |
2158 | { | 2213 | { |
2159 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2214 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
2160 | struct specialix_board *bp; | 2215 | struct specialix_board *bp; |
@@ -2182,7 +2237,7 @@ static void sx_start(struct tty_struct * tty) | |||
2182 | func_exit(); | 2237 | func_exit(); |
2183 | } | 2238 | } |
2184 | 2239 | ||
2185 | static void sx_hangup(struct tty_struct * tty) | 2240 | static void sx_hangup(struct tty_struct *tty) |
2186 | { | 2241 | { |
2187 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2242 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
2188 | struct specialix_board *bp; | 2243 | struct specialix_board *bp; |
@@ -2201,8 +2256,9 @@ static void sx_hangup(struct tty_struct * tty) | |||
2201 | spin_lock_irqsave(&port->lock, flags); | 2256 | spin_lock_irqsave(&port->lock, flags); |
2202 | bp->count -= port->port.count; | 2257 | bp->count -= port->port.count; |
2203 | if (bp->count < 0) { | 2258 | if (bp->count < 0) { |
2204 | printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n", | 2259 | printk(KERN_ERR |
2205 | board_No(bp), bp->count, tty->index); | 2260 | "sx%d: sx_hangup: bad board count: %d port: %d\n", |
2261 | board_No(bp), bp->count, tty->index); | ||
2206 | bp->count = 0; | 2262 | bp->count = 0; |
2207 | } | 2263 | } |
2208 | port->port.count = 0; | 2264 | port->port.count = 0; |
@@ -2215,11 +2271,12 @@ static void sx_hangup(struct tty_struct * tty) | |||
2215 | } | 2271 | } |
2216 | 2272 | ||
2217 | 2273 | ||
2218 | static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termios) | 2274 | static void sx_set_termios(struct tty_struct *tty, |
2275 | struct ktermios *old_termios) | ||
2219 | { | 2276 | { |
2220 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2277 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
2221 | unsigned long flags; | 2278 | unsigned long flags; |
2222 | struct specialix_board * bp; | 2279 | struct specialix_board *bp; |
2223 | 2280 | ||
2224 | if (sx_paranoia_check(port, tty->name, "sx_set_termios")) | 2281 | if (sx_paranoia_check(port, tty->name, "sx_set_termios")) |
2225 | return; | 2282 | return; |
@@ -2283,10 +2340,12 @@ static int sx_init_drivers(void) | |||
2283 | specialix_driver->flags = TTY_DRIVER_REAL_RAW; | 2340 | specialix_driver->flags = TTY_DRIVER_REAL_RAW; |
2284 | tty_set_operations(specialix_driver, &sx_ops); | 2341 | tty_set_operations(specialix_driver, &sx_ops); |
2285 | 2342 | ||
2286 | if ((error = tty_register_driver(specialix_driver))) { | 2343 | error = tty_register_driver(specialix_driver); |
2344 | if (error) { | ||
2287 | put_tty_driver(specialix_driver); | 2345 | put_tty_driver(specialix_driver); |
2288 | printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n", | 2346 | printk(KERN_ERR |
2289 | error); | 2347 | "sx: Couldn't register specialix IO8+ driver, error = %d\n", |
2348 | error); | ||
2290 | func_exit(); | 2349 | func_exit(); |
2291 | return 1; | 2350 | return 1; |
2292 | } | 2351 | } |
@@ -2323,9 +2382,9 @@ static int __init specialix_init(void) | |||
2323 | printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n"); | 2382 | printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n"); |
2324 | printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n"); | 2383 | printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n"); |
2325 | #ifdef CONFIG_SPECIALIX_RTSCTS | 2384 | #ifdef CONFIG_SPECIALIX_RTSCTS |
2326 | printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n"); | 2385 | printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n"); |
2327 | #else | 2386 | #else |
2328 | printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); | 2387 | printk(KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); |
2329 | #endif | 2388 | #endif |
2330 | 2389 | ||
2331 | for (i = 0; i < SX_NBOARD; i++) | 2390 | for (i = 0; i < SX_NBOARD; i++) |
@@ -2344,27 +2403,27 @@ static int __init specialix_init(void) | |||
2344 | { | 2403 | { |
2345 | struct pci_dev *pdev = NULL; | 2404 | struct pci_dev *pdev = NULL; |
2346 | 2405 | ||
2347 | i=0; | 2406 | i = 0; |
2348 | while (i < SX_NBOARD) { | 2407 | while (i < SX_NBOARD) { |
2349 | if (sx_board[i].flags & SX_BOARD_PRESENT) { | 2408 | if (sx_board[i].flags & SX_BOARD_PRESENT) { |
2350 | i++; | 2409 | i++; |
2351 | continue; | 2410 | continue; |
2352 | } | 2411 | } |
2353 | pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, | 2412 | pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, |
2354 | PCI_DEVICE_ID_SPECIALIX_IO8, | 2413 | PCI_DEVICE_ID_SPECIALIX_IO8, pdev); |
2355 | pdev); | 2414 | if (!pdev) |
2356 | if (!pdev) break; | 2415 | break; |
2357 | 2416 | ||
2358 | if (pci_enable_device(pdev)) | 2417 | if (pci_enable_device(pdev)) |
2359 | continue; | 2418 | continue; |
2360 | 2419 | ||
2361 | sx_board[i].irq = pdev->irq; | 2420 | sx_board[i].irq = pdev->irq; |
2362 | 2421 | ||
2363 | sx_board[i].base = pci_resource_start (pdev, 2); | 2422 | sx_board[i].base = pci_resource_start(pdev, 2); |
2364 | 2423 | ||
2365 | sx_board[i].flags |= SX_BOARD_IS_PCI; | 2424 | sx_board[i].flags |= SX_BOARD_IS_PCI; |
2366 | if (!sx_probe(&sx_board[i])) | 2425 | if (!sx_probe(&sx_board[i])) |
2367 | found ++; | 2426 | found++; |
2368 | } | 2427 | } |
2369 | /* May exit pci_get sequence early with lots of boards */ | 2428 | /* May exit pci_get sequence early with lots of boards */ |
2370 | if (pdev != NULL) | 2429 | if (pdev != NULL) |
@@ -2411,10 +2470,10 @@ static int __init specialix_init_module(void) | |||
2411 | func_enter(); | 2470 | func_enter(); |
2412 | 2471 | ||
2413 | if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) { | 2472 | if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) { |
2414 | for(i = 0; i < SX_NBOARD; i++) { | 2473 | for (i = 0; i < SX_NBOARD; i++) { |
2415 | sx_board[i].base = iobase[i]; | 2474 | sx_board[i].base = iobase[i]; |
2416 | sx_board[i].irq = irq[i]; | 2475 | sx_board[i].irq = irq[i]; |
2417 | sx_board[i].count= 0; | 2476 | sx_board[i].count = 0; |
2418 | } | 2477 | } |
2419 | } | 2478 | } |
2420 | 2479 | ||