Commit a72492bd authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

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: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 01e1abb2
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <asm/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/ioport.h> #include <linux/ioport.h>
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/uaccess.h> #include <linux/uaccess.h>
#include "specialix_io8.h" #include "specialix_io8.h"
#include "cd1865.h" #include "cd1865.h"
...@@ -112,7 +112,7 @@ static int sx_debug; ...@@ -112,7 +112,7 @@ static int sx_debug;
static int sx_rxfifo = SPECIALIX_RXFIFO; static int sx_rxfifo = SPECIALIX_RXFIFO;
#ifdef DEBUG #ifdef DEBUG
#define dprintk(f, str...) if (sx_debug & f) printk (str) #define dprintk(f, str...) if (sx_debug & f) printk(str)
#else #else
#define dprintk(f, str...) /* nothing */ #define dprintk(f, str...) /* nothing */
#endif #endif
...@@ -131,8 +131,8 @@ static int sx_rxfifo = SPECIALIX_RXFIFO; ...@@ -131,8 +131,8 @@ static int sx_rxfifo = SPECIALIX_RXFIFO;
#define SX_DEBUG_FIFO 0x0800 #define SX_DEBUG_FIFO 0x0800
#define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__func__) #define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__)
#define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __func__) #define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__)
#define jiffies_from_ms(a) ((((a) * HZ)/1000)+1) #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
...@@ -169,8 +169,8 @@ static int sx_poll = HZ; ...@@ -169,8 +169,8 @@ static int sx_poll = HZ;
#endif #endif
/* Used to be outb (0xff, 0x80); */ /* Used to be outb(0xff, 0x80); */
#define short_pause() udelay (1) #define short_pause() udelay(1)
#define SPECIALIX_LEGAL_FLAGS \ #define SPECIALIX_LEGAL_FLAGS \
...@@ -192,19 +192,19 @@ static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; ...@@ -192,19 +192,19 @@ static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
#ifdef SPECIALIX_TIMER #ifdef SPECIALIX_TIMER
static struct timer_list missed_irq_timer; static struct timer_list missed_irq_timer;
static irqreturn_t sx_interrupt(int irq, void * dev_id); static irqreturn_t sx_interrupt(int irq, void *dev_id);
#endif #endif
static inline int sx_paranoia_check(struct specialix_port const * port, static inline int sx_paranoia_check(struct specialix_port const *port,
char *name, const char *routine) char *name, const char *routine)
{ {
#ifdef SPECIALIX_PARANOIA_CHECK #ifdef SPECIALIX_PARANOIA_CHECK
static const char *badmagic = static const char *badmagic = KERN_ERR
KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n"; "sx: Warning: bad specialix port magic number for device %s in %s\n";
static const char *badinfo = static const char *badinfo = KERN_ERR
KERN_ERR "sx: Warning: null specialix port for device %s in %s\n"; "sx: Warning: null specialix port for device %s in %s\n";
if (!port) { if (!port) {
printk(badinfo, name, routine); printk(badinfo, name, routine);
...@@ -226,66 +226,69 @@ static inline int sx_paranoia_check(struct specialix_port const * port, ...@@ -226,66 +226,69 @@ static inline int sx_paranoia_check(struct specialix_port const * port,
*/ */
/* Get board number from pointer */ /* Get board number from pointer */
static inline int board_No (struct specialix_board * bp) static inline int board_No(struct specialix_board *bp)
{ {
return bp - sx_board; return bp - sx_board;
} }
/* Get port number from pointer */ /* Get port number from pointer */
static inline int port_No (struct specialix_port const * port) static inline int port_No(struct specialix_port const *port)
{ {
return SX_PORT(port - sx_port); return SX_PORT(port - sx_port);
} }
/* Get pointer to board from pointer to port */ /* Get pointer to board from pointer to port */
static inline struct specialix_board * port_Board(struct specialix_port const * port) static inline struct specialix_board *port_Board(
struct specialix_port const *port)
{ {
return &sx_board[SX_BOARD(port - sx_port)]; return &sx_board[SX_BOARD(port - sx_port)];
} }
/* Input Byte from CL CD186x register */ /* Input Byte from CL CD186x register */
static inline unsigned char sx_in(struct specialix_board * bp, unsigned short reg) static inline unsigned char sx_in(struct specialix_board *bp,
unsigned short reg)
{ {
bp->reg = reg | 0x80; bp->reg = reg | 0x80;
outb (reg | 0x80, bp->base + SX_ADDR_REG); outb(reg | 0x80, bp->base + SX_ADDR_REG);
return inb (bp->base + SX_DATA_REG); return inb(bp->base + SX_DATA_REG);
} }
/* Output Byte to CL CD186x register */ /* Output Byte to CL CD186x register */
static inline void sx_out(struct specialix_board * bp, unsigned short reg, static inline void sx_out(struct specialix_board *bp, unsigned short reg,
unsigned char val) unsigned char val)
{ {
bp->reg = reg | 0x80; bp->reg = reg | 0x80;
outb (reg | 0x80, bp->base + SX_ADDR_REG); outb(reg | 0x80, bp->base + SX_ADDR_REG);
outb (val, bp->base + SX_DATA_REG); outb(val, bp->base + SX_DATA_REG);
} }
/* Input Byte from CL CD186x register */ /* Input Byte from CL CD186x register */
static inline unsigned char sx_in_off(struct specialix_board * bp, unsigned short reg) static inline unsigned char sx_in_off(struct specialix_board *bp,
unsigned short reg)
{ {
bp->reg = reg; bp->reg = reg;
outb (reg, bp->base + SX_ADDR_REG); outb(reg, bp->base + SX_ADDR_REG);
return inb (bp->base + SX_DATA_REG); return inb(bp->base + SX_DATA_REG);
} }
/* Output Byte to CL CD186x register */ /* Output Byte to CL CD186x register */
static inline void sx_out_off(struct specialix_board * bp, unsigned short reg, static inline void sx_out_off(struct specialix_board *bp,
unsigned char val) unsigned short reg, unsigned char val)
{ {
bp->reg = reg; bp->reg = reg;
outb (reg, bp->base + SX_ADDR_REG); outb(reg, bp->base + SX_ADDR_REG);
outb (val, bp->base + SX_DATA_REG); outb(val, bp->base + SX_DATA_REG);
} }
/* Wait for Channel Command Register ready */ /* Wait for Channel Command Register ready */
static inline void sx_wait_CCR(struct specialix_board * bp) static inline void sx_wait_CCR(struct specialix_board *bp)
{ {
unsigned long delay, flags; unsigned long delay, flags;
unsigned char ccr; unsigned char ccr;
...@@ -296,7 +299,7 @@ static inline void sx_wait_CCR(struct specialix_board * bp) ...@@ -296,7 +299,7 @@ static inline void sx_wait_CCR(struct specialix_board * bp)
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
if (!ccr) if (!ccr)
return; return;
udelay (1); udelay(1);
} }
printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); 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,7 +307,7 @@ static inline void sx_wait_CCR(struct specialix_board * bp)
/* Wait for Channel Command Register ready */ /* Wait for Channel Command Register ready */
static inline void sx_wait_CCR_off(struct specialix_board * bp) static inline void sx_wait_CCR_off(struct specialix_board *bp)
{ {
unsigned long delay; unsigned long delay;
unsigned char crr; unsigned char crr;
...@@ -316,7 +319,7 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp) ...@@ -316,7 +319,7 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp)
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
if (!crr) if (!crr)
return; return;
udelay (1); udelay(1);
} }
printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); 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,7 +330,7 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp)
* specialix IO8+ IO range functions. * specialix IO8+ IO range functions.
*/ */
static inline int sx_request_io_range(struct specialix_board * bp) static inline int sx_request_io_range(struct specialix_board *bp)
{ {
return request_region(bp->base, return request_region(bp->base,
bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE, 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,15 +338,15 @@ static inline int sx_request_io_range(struct specialix_board * bp)
} }
static inline void sx_release_io_range(struct specialix_board * bp) static inline void sx_release_io_range(struct specialix_board *bp)
{ {
release_region(bp->base, release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ?
bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE); SX_PCI_IO_SPACE : SX_IO_SPACE);
} }
/* Set the IRQ using the RTS lines that run to the PAL on the board.... */ /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
static int sx_set_irq ( struct specialix_board *bp) static int sx_set_irq(struct specialix_board *bp)
{ {
int virq; int virq;
int i; int i;
...@@ -353,15 +356,24 @@ static int sx_set_irq ( struct specialix_board *bp) ...@@ -353,15 +356,24 @@ static int sx_set_irq ( struct specialix_board *bp)
return 1; return 1;
switch (bp->irq) { switch (bp->irq) {
/* In the same order as in the docs... */ /* In the same order as in the docs... */
case 15: virq = 0;break; case 15:
case 12: virq = 1;break; virq = 0;
case 11: virq = 2;break; break;
case 9: virq = 3;break; case 12:
default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq); virq = 1;
return 0; break;
case 11:
virq = 2;
break;
case 9:
virq = 3;
break;
default:printk(KERN_ERR
"Speclialix: cannot set irq to %d.\n", bp->irq);
return 0;
} }
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
for (i=0;i<2;i++) { for (i = 0; i < 2; i++) {
sx_out(bp, CD186x_CAR, i); sx_out(bp, CD186x_CAR, i);
sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0); sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
} }
...@@ -371,7 +383,7 @@ static int sx_set_irq ( struct specialix_board *bp) ...@@ -371,7 +383,7 @@ static int sx_set_irq ( struct specialix_board *bp)
/* Reset and setup CD186x chip */ /* Reset and setup CD186x chip */
static int sx_init_CD186x(struct specialix_board * bp) static int sx_init_CD186x(struct specialix_board *bp)
{ {
unsigned long flags; unsigned long flags;
int scaler; int scaler;
...@@ -390,7 +402,7 @@ static int sx_init_CD186x(struct specialix_board * bp) ...@@ -390,7 +402,7 @@ static int sx_init_CD186x(struct specialix_board * bp)
sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */ sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */ sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
/* Set RegAckEn */ /* Set RegAckEn */
sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN); sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN);
/* Setting up prescaler. We need 4 ticks per 1 ms */ /* Setting up prescaler. We need 4 ticks per 1 ms */
scaler = SX_OSCFREQ/SPECIALIX_TPS; scaler = SX_OSCFREQ/SPECIALIX_TPS;
...@@ -399,9 +411,9 @@ static int sx_init_CD186x(struct specialix_board * bp) ...@@ -399,9 +411,9 @@ static int sx_init_CD186x(struct specialix_board * bp)
sx_out_off(bp, CD186x_PPRL, scaler & 0xff); sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
if (!sx_set_irq (bp)) { if (!sx_set_irq(bp)) {
/* Figure out how to pass this along... */ /* Figure out how to pass this along... */
printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq); printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq);
rv = 0; rv = 0;
} }
...@@ -410,16 +422,16 @@ static int sx_init_CD186x(struct specialix_board * bp) ...@@ -410,16 +422,16 @@ static int sx_init_CD186x(struct specialix_board * bp)
} }
static int read_cross_byte (struct specialix_board *bp, int reg, int bit) static int read_cross_byte(struct specialix_board *bp, int reg, int bit)
{ {
int i; int i;
int t; int t;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
for (i=0, t=0;i<8;i++) { for (i = 0, t = 0; i < 8; i++) {
sx_out_off (bp, CD186x_CAR, i); sx_out_off(bp, CD186x_CAR, i);
if (sx_in_off (bp, reg) & bit) if (sx_in_off(bp, reg) & bit)
t |= 1 << i; t |= 1 << i;
} }
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
...@@ -429,21 +441,20 @@ static int read_cross_byte (struct specialix_board *bp, int reg, int bit) ...@@ -429,21 +441,20 @@ static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
#ifdef SPECIALIX_TIMER #ifdef SPECIALIX_TIMER
void missed_irq (unsigned long data) void missed_irq(unsigned long data)
{ {
unsigned char irq; unsigned char irq;
unsigned long flags; unsigned long flags;
struct specialix_board *bp = (struct specialix_board *)data; struct specialix_board *bp = (struct specialix_board *)data;
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) & irq = sx_in((struct specialix_board *)data, CD186x_SRSR) &
(SRSR_RREQint | (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
SRSR_TREQint |
SRSR_MREQint);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
if (irq) { if (irq) {
printk (KERN_INFO "Missed interrupt... Calling int from timer. \n"); printk(KERN_INFO
sx_interrupt (-1, bp); "Missed interrupt... Calling int from timer. \n");
sx_interrupt(-1, bp);
} }
mod_timer(&missed_irq_timer, jiffies + sx_poll); mod_timer(&missed_irq_timer, jiffies + sx_poll);
} }
...@@ -471,17 +482,18 @@ static int sx_probe(struct specialix_board *bp) ...@@ -471,17 +482,18 @@ static int sx_probe(struct specialix_board *bp)
/* Are the I/O ports here ? */ /* Are the I/O ports here ? */
sx_out_off(bp, CD186x_PPRL, 0x5a); sx_out_off(bp, CD186x_PPRL, 0x5a);
short_pause (); short_pause();
val1 = sx_in_off(bp, CD186x_PPRL); val1 = sx_in_off(bp, CD186x_PPRL);
sx_out_off(bp, CD186x_PPRL, 0xa5); sx_out_off(bp, CD186x_PPRL, 0xa5);
short_pause (); short_pause();
val2 = sx_in_off(bp, CD186x_PPRL); val2 = sx_in_off(bp, CD186x_PPRL);
if ((val1 != 0x5a) || (val2 != 0xa5)) { if ((val1 != 0x5a) || (val2 != 0xa5)) {
printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n", printk(KERN_INFO
board_No(bp), bp->base); "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
board_No(bp), bp->base);
sx_release_io_range(bp); sx_release_io_range(bp);
func_exit(); func_exit();
return 1; return 1;
...@@ -489,10 +501,11 @@ static int sx_probe(struct specialix_board *bp) ...@@ -489,10 +501,11 @@ static int sx_probe(struct specialix_board *bp)
/* Check the DSR lines that Specialix uses as board /* Check the DSR lines that Specialix uses as board
identification */ identification */
val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR); val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR);
val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS); val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS);
dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n", dprintk(SX_DEBUG_INIT,
board_No(bp), val1, val2); "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
board_No(bp), val1, val2);
/* They managed to switch the bit order between the docs and /* They managed to switch the bit order between the docs and
the IO8+ card. The new PCI card now conforms to old docs. 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,7 +513,8 @@ static int sx_probe(struct specialix_board *bp)
old card. */ old card. */
val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2; val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
if (val1 != val2) { if (val1 != val2) {
printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n", printk(KERN_INFO
"sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
board_No(bp), val2, bp->base, val1); board_No(bp), val2, bp->base, val1);
sx_release_io_range(bp); sx_release_io_range(bp);
func_exit(); func_exit();
...@@ -512,40 +526,43 @@ static int sx_probe(struct specialix_board *bp) ...@@ -512,40 +526,43 @@ static int sx_probe(struct specialix_board *bp)
/* It's time to find IRQ for this board */ /* It's time to find IRQ for this board */
for (retries = 0; retries < 5 && irqs <= 0; retries++) { for (retries = 0; retries < 5 && irqs <= 0; retries++) {
irqs = probe_irq_on(); irqs = probe_irq_on();
sx_init_CD186x(bp); /* Reset CD186x chip */ sx_init_CD186x(bp); /* Reset CD186x chip */
sx_out(bp, CD186x_CAR, 2); /* Select port 2 */ sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
sx_wait_CCR(bp); sx_wait_CCR(bp);
sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */ sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */ sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
msleep(50); msleep(50);
irqs = probe_irq_off(irqs); irqs = probe_irq_off(irqs);
dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR)); dprintk(SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR)); dprintk(SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR)); dprintk(SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR)); dprintk(SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
dprintk (SX_DEBUG_INIT, "\n"); dprintk(SX_DEBUG_INIT, "\n");
/* Reset CD186x again */ /* Reset CD186x again */
if (!sx_init_CD186x(bp)) { if (!sx_init_CD186x(bp)) {
/* Hmmm. This is dead code anyway. */ /* Hmmm. This is dead code anyway. */
} }
dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n", dprintk(SX_DEBUG_INIT
val1, val2, val3); "val1 = %02x, val2 = %02x, val3 = %02x.\n",
val1, val2, val3);
} }
#if 0 #if 0
if (irqs <= 0) { if (irqs <= 0) {
printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n", printk(KERN_ERR
board_No(bp), bp->base); "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
board_No(bp), bp->base);
sx_release_io_range(bp); sx_release_io_range(bp);
func_exit(); func_exit();
return 1; return 1;
} }
#endif #endif
printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs); printk(KERN_INFO "Started with irq=%d, but now have irq=%d.\n",
bp->irq, irqs);
if (irqs > 0) if (irqs > 0)
bp->irq = irqs; bp->irq = irqs;
#endif #endif
...@@ -560,7 +577,7 @@ static int sx_probe(struct specialix_board *bp) ...@@ -560,7 +577,7 @@ static int sx_probe(struct specialix_board *bp)
bp->flags |= SX_BOARD_PRESENT; bp->flags |= SX_BOARD_PRESENT;
/* Chip revcode pkgtype /* Chip revcode pkgtype
GFRCR SRCR bit 7 GFRCR SRCR bit 7
CD180 rev B 0x81 0 CD180 rev B 0x81 0
CD180 rev C 0x82 0 CD180 rev C 0x82 0
CD1864 rev A 0x82 1 CD1864 rev A 0x82 1
...@@ -570,24 +587,37 @@ static int sx_probe(struct specialix_board *bp) ...@@ -570,24 +587,37 @@ static int sx_probe(struct specialix_board *bp)
*/ */
switch (sx_in_off(bp, CD186x_GFRCR)) { switch (sx_in_off(bp, CD186x_GFRCR)) {
case 0x82:chip = 1864;rev='A';break; case 0x82:
case 0x83:chip = 1865;rev='A';break; chip = 1864;
case 0x84:chip = 1865;rev='B';break; rev = 'A';
case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */ break;
default:chip=-1;rev='x'; case 0x83:
chip = 1865;
rev = 'A';
break;
case 0x84:
chip = 1865;
rev = 'B';
break;
case 0x85:
chip = 1865;
rev = 'C';
break; /* Does not exist at this time */
default:
chip = -1;
rev = 'x';
} }
dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) ); dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR));
#ifdef SPECIALIX_TIMER #ifdef SPECIALIX_TIMER
setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp); setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp);
mod_timer(&missed_irq_timer, jiffies + sx_poll); mod_timer(&missed_irq_timer, jiffies + sx_poll);
#endif #endif
printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n", printk(KERN_INFO
board_No(bp), "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
bp->base, bp->irq, board_No(bp), bp->base, bp->irq, chip, rev);
chip, rev);
func_exit(); func_exit();
return 0; return 0;
...@@ -598,20 +628,22 @@ static int sx_probe(struct specialix_board *bp) ...@@ -598,20 +628,22 @@ static int sx_probe(struct specialix_board *bp)
* Interrupt processing routines. * Interrupt processing routines.
* */ * */
static inline struct specialix_port * sx_get_port(struct specialix_board * bp, static inline struct specialix_port *sx_get_port(struct specialix_board *bp,
unsigned char const * what) unsigned char const *what)
{ {
unsigned char channel; unsigned char channel;
struct specialix_port * port = NULL; struct specialix_port *port = NULL;
channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF; channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel); dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel);
if (channel < CD186x_NCH) { if (channel < CD186x_NCH) {
port = &sx_port[board_No(bp) * SX_NPORT + channel]; port = &sx_port[board_No(bp) * SX_NPORT + channel];
dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",board_No(bp) * SX_NPORT + channel, port, port->port.flags & ASYNC_INITIALIZED); dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",
board_No(bp) * SX_NPORT + channel, port,
port->port.flags & ASYNC_INITIALIZED);
if (port->port.flags & ASYNC_INITIALIZED) { if (port->port.flags & ASYNC_INITIALIZED) {
dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port); dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
func_exit(); func_exit();
return port; return port;
} }
...@@ -622,7 +654,7 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp, ...@@ -622,7 +654,7 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
} }
static inline void sx_receive_exc(struct specialix_board * bp) static inline void sx_receive_exc(struct specialix_board *bp)
{ {
struct specialix_port *port; struct specialix_port *port;
struct tty_struct *tty; struct tty_struct *tty;
...@@ -633,7 +665,7 @@ static inline void sx_receive_exc(struct specialix_board * bp) ...@@ -633,7 +665,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
port = sx_get_port(bp, "Receive"); port = sx_get_port(bp, "Receive");
if (!port) { if (!port) {
dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n"); dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
func_exit(); func_exit();
return; return;
} }
...@@ -641,19 +673,21 @@ static inline void sx_receive_exc(struct specialix_board * bp) ...@@ -641,19 +673,21 @@ static inline void sx_receive_exc(struct specialix_board * bp)
status = sx_in(bp, CD186x_RCSR); status = sx_in(bp, CD186x_RCSR);
dprintk (SX_DEBUG_RX, "status: 0x%x\n", status); dprintk(SX_DEBUG_RX, "status: 0x%x\n", status);
if (status & RCSR_OE) { if (status & RCSR_OE) {
port->overrun++; port->overrun++;
dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n", dprintk(SX_DEBUG_FIFO,
board_No(bp), port_No(port), port->overrun); "sx%d: port %d: Overrun. Total %ld overruns.\n",
board_No(bp), port_No(port), port->overrun);
} }
status &= port->mark_mask; status &= port->mark_mask;
/* This flip buffer check needs to be below the reading of the /* This flip buffer check needs to be below the reading of the
status register to reset the chip's IRQ.... */ status register to reset the chip's IRQ.... */
if (tty_buffer_request_room(tty, 1) == 0) { if (tty_buffer_request_room(tty, 1) == 0) {
dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n", dprintk(SX_DEBUG_FIFO,
board_No(bp), port_No(port)); "sx%d: port %d: Working around flip buffer overflow.\n",
board_No(bp), port_No(port));
func_exit(); func_exit();
return; return;
} }
...@@ -664,8 +698,9 @@ static inline void sx_receive_exc(struct specialix_board * bp) ...@@ -664,8 +698,9 @@ static inline void sx_receive_exc(struct specialix_board * bp)
return; return;
} }
if (status & RCSR_TOUT) { if (status & RCSR_TOUT) {
printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n", printk(KERN_INFO
board_No(bp), port_No(port)); "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
board_No(bp), port_No(port));
func_exit(); func_exit();
return; return;
...@@ -688,13 +723,13 @@ static inline void sx_receive_exc(struct specialix_board * bp) ...@@ -688,13 +723,13 @@ static inline void sx_receive_exc(struct specialix_board * bp)
else else
flag = TTY_NORMAL; flag = TTY_NORMAL;
if(tty_insert_flip_char(tty, ch, flag)) if (tty_insert_flip_char(tty, ch, flag))
tty_flip_buffer_push(tty); tty_flip_buffer_push(tty);
func_exit(); func_exit();
} }
static inline void sx_receive(struct specialix_board * bp) static inline void sx_receive(struct specialix_board *bp)
{ {
struct specialix_port *port; struct specialix_port *port;
struct tty_struct *tty; struct tty_struct *tty;
...@@ -702,15 +737,16 @@ static inline void sx_receive(struct specialix_board * bp) ...@@ -702,15 +737,16 @@ static inline void sx_receive(struct specialix_board * bp)
func_enter(); func_enter();
if (!(port = sx_get_port(bp, "Receive"))) { port = sx_get_port(bp, "Receive");
dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n"); if (port == NULL) {
dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
func_exit(); func_exit();
return; return;
} }
tty = port->port.tty; tty = port->port.tty;
count = sx_in(bp, CD186x_RDCR); count = sx_in(bp, CD186x_RDCR);
dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
port->hits[count > 8 ? 9 : count]++; port->hits[count > 8 ? 9 : count]++;
tty_buffer_request_room(tty, count); tty_buffer_request_room(tty, count);
...@@ -722,18 +758,19 @@ static inline void sx_receive(struct specialix_board * bp) ...@@ -722,18 +758,19 @@ static inline void sx_receive(struct specialix_board * bp)
} }
static inline void sx_transmit(struct specialix_board * bp) static inline void sx_transmit(struct specialix_board *bp)
{ {
struct specialix_port *port; struct specialix_port *port;
struct tty_struct *tty; struct tty_struct *tty;
unsigned char count; unsigned char count;
func_enter(); func_enter();
if (!(port = sx_get_port(bp, "Transmit"))) { port = sx_get_port(bp, "Transmit");
if (port == NULL) {
func_exit(); func_exit();
return; return;
} }
dprintk (SX_DEBUG_TX, "port: %p\n", port); dprintk(SX_DEBUG_TX, "port: %p\n", port);
tty = port->port.tty; tty = port->port.tty;
if (port->IER & IER_TXEMPTY) { if (port->IER & IER_TXEMPTY) {
...@@ -765,7 +802,8 @@ static inline void sx_transmit(struct specialix_board * bp) ...@@ -765,7 +802,8 @@ static inline void sx_transmit(struct specialix_board * bp)
sx_out(bp, CD186x_TDR, CD186x_C_ESC); sx_out(bp, CD186x_TDR, CD186x_C_ESC);
sx_out(bp, CD186x_TDR, CD186x_C_DELAY); sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
sx_out(bp, CD186x_TDR, count); sx_out(bp, CD186x_TDR, count);
if (!(port->break_length -= count)) port->break_length -= count;
if (port->break_length == 0)
port->break_length--; port->break_length--;
} else { } else {
sx_out(bp, CD186x_TDR, CD186x_C_ESC); sx_out(bp, CD186x_TDR, CD186x_C_ESC);
...@@ -794,36 +832,37 @@ static inline void sx_transmit(struct specialix_board * bp) ...@@ -794,36 +832,37 @@ static inline void sx_transmit(struct specialix_board * bp)
sx_out(bp, CD186x_IER, port->IER); sx_out(bp, CD186x_IER, port->IER);
} }
if (port->xmit_cnt <= port->wakeup_chars) if (port->xmit_cnt <= port->wakeup_chars)
tty_wakeup(tty); tty_wakeup(tty);
func_exit(); func_exit();
} }
static inline void sx_check_modem(struct specialix_board * bp) static inline void sx_check_modem(struct specialix_board *bp)
{ {
struct specialix_port *port; struct specialix_port *port;
struct tty_struct *tty; struct tty_struct *tty;
unsigned char mcr; unsigned char mcr;
int msvr_cd; int msvr_cd;
dprintk (SX_DEBUG_SIGNALS, "Modem intr. "); dprintk(SX_DEBUG_SIGNALS, "Modem intr. ");
if (!(port = sx_get_port(bp, "Modem"))) port = sx_get_port(bp, "Modem");
if (port == NULL)
return; return;
tty = port->port.tty; tty = port->port.tty;
mcr = sx_in(bp, CD186x_MCR); mcr = sx_in(bp, CD186x_MCR);
printk ("mcr = %02x.\n", mcr); printk("mcr = %02x.\n", mcr); /* FIXME */
if ((mcr & MCR_CDCHG)) { if ((mcr & MCR_CDCHG)) {
dprintk (SX_DEBUG_SIGNALS, "CD just changed... "); dprintk(SX_DEBUG_SIGNALS, "CD just changed... ");
msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD; msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
if (msvr_cd) { if (msvr_cd) {
dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n"); dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
wake_up_interruptible(&port->port.open_wait); wake_up_interruptible(&port->port.open_wait);
} else { } else {
dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n"); dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n");
tty_hangup(tty); tty_hangup(tty);
} }
} }
...@@ -874,9 +913,12 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) ...@@ -874,9 +913,12 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
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); 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);
if (!(bp->flags & SX_BOARD_ACTIVE)) { if (!(bp->flags & SX_BOARD_ACTIVE)) {
dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq); dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n",
bp->irq);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
func_exit(); func_exit();
return IRQ_NONE; return IRQ_NONE;
...@@ -884,10 +926,11 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) ...@@ -884,10 +926,11 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
saved_reg = bp->reg; saved_reg = bp->reg;
while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) & while (++loop < 16) {
(SRSR_RREQint | status = sx_in(bp, CD186x_SRSR) &
SRSR_TREQint | (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
SRSR_MREQint)))) { if (status == 0)
break;
if (status & SRSR_RREQint) { if (status & SRSR_RREQint) {
ack = sx_in(bp, CD186x_RRAR); ack = sx_in(bp, CD186x_RRAR);
...@@ -896,8 +939,9 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) ...@@ -896,8 +939,9 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
else if (ack == (SX_ID | GIVR_IT_REXC)) else if (ack == (SX_ID | GIVR_IT_REXC))
sx_receive_exc(bp); sx_receive_exc(bp);
else else
printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n", printk(KERN_ERR
board_No(bp), status, ack); "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
board_No(bp), status, ack);
} else if (status & SRSR_TREQint) { } else if (status & SRSR_TREQint) {
ack = sx_in(bp, CD186x_TRAR); ack = sx_in(bp, CD186x_TRAR);
...@@ -906,14 +950,16 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) ...@@ -906,14 +950,16 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
sx_transmit(bp); sx_transmit(bp);
else else
printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n", printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
board_No(bp), status, ack, port_No (sx_get_port (bp, "Int"))); board_No(bp), status, ack,
port_No(sx_get_port(bp, "Int")));
} else if (status & SRSR_MREQint) { } else if (status & SRSR_MREQint) {
ack = sx_in(bp, CD186x_MRAR); ack = sx_in(bp, CD186x_MRAR);
if (ack == (SX_ID | GIVR_IT_MODEM)) if (ack == (SX_ID | GIVR_IT_MODEM))
sx_check_modem(bp); sx_check_modem(bp);
else else
printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n", printk(KERN_ERR
"sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
board_No(bp), status, ack); board_No(bp), status, ack);
} }
...@@ -921,7 +967,7 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) ...@@ -921,7 +967,7 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */ sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
} }
bp->reg = saved_reg; bp->reg = saved_reg;
outb (bp->reg, bp->base + SX_ADDR_REG); outb(bp->reg, bp->base + SX_ADDR_REG);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
func_exit(); func_exit();
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -932,7 +978,7 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) ...@@ -932,7 +978,7 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
* Routines for open & close processing. * Routines for open & close processing.
*/ */
static void turn_ints_off (struct specialix_board *bp) static void turn_ints_off(struct specialix_board *bp)
{ {
unsigned long flags; unsigned long flags;
...@@ -945,13 +991,13 @@ static void turn_ints_off (struct specialix_board *bp) ...@@ -945,13 +991,13 @@ static void turn_ints_off (struct specialix_board *bp)
} }
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
(void) sx_in_off (bp, 0); /* Turn off interrupts. */ (void) sx_in_off(bp, 0); /* Turn off interrupts. */
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
func_exit(); func_exit();
} }
static void turn_ints_on (struct specialix_board *bp) static void turn_ints_on(struct specialix_board *bp)
{ {
unsigned long flags; unsigned long flags;
...@@ -961,7 +1007,7 @@ static void turn_ints_on (struct specialix_board *bp) ...@@ -961,7 +1007,7 @@ static void turn_ints_on (struct specialix_board *bp)
/* play with the PCI chip. See comment above. */ /* play with the PCI chip. See comment above. */
} }
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
(void) sx_in (bp, 0); /* Turn ON interrupts. */ (void) sx_in(bp, 0); /* Turn ON interrupts. */
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
func_exit(); func_exit();
...@@ -969,7 +1015,7 @@ static void turn_ints_on (struct specialix_board *bp) ...@@ -969,7 +1015,7 @@ static void turn_ints_on (struct specialix_board *bp)
/* Called with disabled interrupts */ /* Called with disabled interrupts */
static inline int sx_setup_board(struct specialix_board * bp) static inline int sx_setup_board(struct specialix_board *bp)
{ {
int error; int error;
...@@ -977,14 +1023,16 @@ static inline int sx_setup_board(struct specialix_board * bp) ...@@ -977,14 +1023,16 @@ static inline int sx_setup_board(struct specialix_board * bp)
return 0; return 0;
if (bp->flags & SX_BOARD_IS_PCI) if (bp->flags & SX_BOARD_IS_PCI)
error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp); error = request_irq(bp->irq, sx_interrupt,
IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
else else
error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED, "specialix IO8+", bp); error = request_irq(bp->irq, sx_interrupt,
IRQF_DISABLED, "specialix IO8+", bp);
if (error) if (error)
return error; return error;
turn_ints_on (bp); turn_ints_on(bp);
bp->flags |= SX_BOARD_ACTIVE; bp->flags |= SX_BOARD_ACTIVE;
return 0; return 0;
...@@ -1003,13 +1051,10 @@ static inline void sx_shutdown_board(struct specialix_board *bp) ...@@ -1003,13 +1051,10 @@ static inline void sx_shutdown_board(struct specialix_board *bp)
bp->flags &= ~SX_BOARD_ACTIVE; bp->flags &= ~SX_BOARD_ACTIVE;
dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n", dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
bp->irq, board_No (bp)); bp->irq, board_No(bp));
free_irq(bp->irq, bp); free_irq(bp->irq, bp);
turn_ints_off(bp);
turn_ints_off (bp);
func_exit(); func_exit();
} }
...@@ -1018,7 +1063,8 @@ static inline void sx_shutdown_board(struct specialix_board *bp) ...@@ -1018,7 +1063,8 @@ static inline void sx_shutdown_board(struct specialix_board *bp)
* Setting up port characteristics. * Setting up port characteristics.
* Must be called with disabled interrupts * Must be called with disabled interrupts
*/ */
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port) static void sx_change_speed(struct specialix_board *bp,
struct specialix_port *port)
{ {
struct tty_struct *tty; struct tty_struct *tty;
unsigned long baud; unsigned long baud;
...@@ -1030,7 +1076,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p ...@@ -1030,7 +1076,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
func_enter(); func_enter();
if (!(tty = port->port.tty) || !tty->termios) { tty = port->port.tty;
if (!tty || !tty->termios) {
func_exit(); func_exit();
return; return;
} }
...@@ -1048,7 +1095,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p ...@@ -1048,7 +1095,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
else else
port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS); port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR); dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
baud = tty_get_baud_rate(tty); baud = tty_get_baud_rate(tty);
if (baud == 38400) { if (baud == 38400) {
...@@ -1060,21 +1107,19 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p ...@@ -1060,21 +1107,19 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
if (!baud) { if (!baud) {
/* Drop DTR & exit */ /* Drop DTR & exit */
dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
if (!SX_CRTSCTS (tty)) { if (!SX_CRTSCTS(tty)) {
port -> MSVR &= ~ MSVR_DTR; port->MSVR &= ~MSVR_DTR;
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_MSVR, port->MSVR ); sx_out(bp, CD186x_MSVR, port->MSVR);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
} } else
else dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
return; return;
} else { } else {
/* Set DTR on */ /* Set DTR on */
if (!SX_CRTSCTS (tty)) { if (!SX_CRTSCTS(tty))
port ->MSVR |= MSVR_DTR; port->MSVR |= MSVR_DTR;
}
} }
/* /*
...@@ -1083,28 +1128,27 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p ...@@ -1083,28 +1128,27 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
/* Set baud rate for port */ /* Set baud rate for port */
tmp = port->custom_divisor ; tmp = port->custom_divisor ;
if ( tmp ) if (tmp)
printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n" printk(KERN_INFO
"This is an untested option, please be carefull.\n", "sx%d: Using custom baud rate divisor %ld. \n"
port_No (port), tmp); "This is an untested option, please be careful.\n",
port_No(port), tmp);
else else
tmp = (((SX_OSCFREQ + baud/2) / baud + tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) /
CD186x_TPC/2) / CD186x_TPC); CD186x_TPC);
if ((tmp < 0x10) && time_before(again, jiffies)) { if (tmp < 0x10 && time_before(again, jiffies)) {
again = jiffies + HZ * 60; again = jiffies + HZ * 60;
/* Page 48 of version 2.0 of the CL-CD1865 databook */ /* Page 48 of version 2.0 of the CL-CD1865 databook */
if (tmp >= 12) { if (tmp >= 12) {
printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n" printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
"Performance degradation is possible.\n" "Performance degradation is possible.\n"
"Read specialix.txt for more info.\n", "Read specialix.txt for more info.\n",
port_No (port), tmp); port_No(port), tmp);
} else { } else {
printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n" printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
"Warning: overstressing Cirrus chip. " "Warning: overstressing Cirrus chip. This might not work.\n"
"This might not work.\n" "Read specialix.txt for more info.\n", port_No(port), tmp);
"Read specialix.txt for more info.\n",
port_No (port), tmp);
} }
} }
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
...@@ -1114,7 +1158,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p ...@@ -1114,7 +1158,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
sx_out(bp, CD186x_TBPRL, tmp & 0xff); sx_out(bp, CD186x_TBPRL, tmp & 0xff);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
if (port->custom_divisor) if (port->custom_divisor)
baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; baud = (SX_OSCFREQ + port->custom_divisor/2) /
port->custom_divisor;
baud = (baud + 5) / 10; /* Estimated CPS */ baud = (baud + 5) / 10; /* Estimated CPS */
/* Two timer ticks seems enough to wakeup something like SLIP driver */ /* 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,16 +1174,16 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
sx_out(bp, CD186x_RTPR, tmp); sx_out(bp, CD186x_RTPR, tmp);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
switch (C_CSIZE(tty)) { switch (C_CSIZE(tty)) {
case CS5: case CS5:
cor1 |= COR1_5BITS; cor1 |= COR1_5BITS;
break; break;
case CS6: case CS6:
cor1 |= COR1_6BITS; cor1 |= COR1_6BITS;
break; break;
case CS7: case CS7:
cor1 |= COR1_7BITS; cor1 |= COR1_7BITS;
break; break;
case CS8: case CS8:
cor1 |= COR1_8BITS; cor1 |= COR1_8BITS;
break; break;
} }
...@@ -1175,7 +1220,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p ...@@ -1175,7 +1220,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR)); tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) &
(MSVR_CTS|MSVR_DSR));
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
#else #else
port->COR2 |= COR2_CTSAE; port->COR2 |= COR2_CTSAE;
...@@ -1219,7 +1265,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p ...@@ -1219,7 +1265,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
/* Setting up modem option registers */ /* Setting up modem option registers */
dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2); dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n",
mcor1, mcor2);
sx_out(bp, CD186x_MCOR1, mcor1); sx_out(bp, CD186x_MCOR1, mcor1);
sx_out(bp, CD186x_MCOR2, mcor2); sx_out(bp, CD186x_MCOR2, mcor2);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
...@@ -1238,7 +1285,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p ...@@ -1238,7 +1285,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
/* Must be called with interrupts enabled */ /* Must be called with interrupts enabled */
static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port) static int sx_setup_port(struct specialix_board *bp,
struct specialix_port *port)
{ {
unsigned long flags; unsigned long flags;
...@@ -1253,7 +1301,8 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port ...@@ -1253,7 +1301,8 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
/* We may sleep in get_zeroed_page() */ /* We may sleep in get_zeroed_page() */
unsigned long tmp; unsigned long tmp;
if (!(tmp = get_zeroed_page(GFP_KERNEL))) { tmp = get_zeroed_page(GFP_KERNEL);
if (tmp == 0L) {
func_exit(); func_exit();
return -ENOMEM; return -ENOMEM;
} }
...@@ -1284,7 +1333,8 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port ...@@ -1284,7 +1333,8 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
/* Must be called with interrupts disabled */ /* Must be called with interrupts disabled */
static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port) static void sx_shutdown_port(struct specialix_board *bp,
struct specialix_port *port)
{ {
struct tty_struct *tty; struct tty_struct *tty;
int i; int i;
...@@ -1298,11 +1348,11 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port * ...@@ -1298,11 +1348,11 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
} }
if (sx_debug & SX_DEBUG_FIFO) { if (sx_debug & SX_DEBUG_FIFO) {
dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ", dprintk(SX_DEBUG_FIFO,
board_No(bp), port_No(port), port->overrun); "sx%d: port %d: %ld overruns, FIFO hits [ ",
for (i = 0; i < 10; i++) { board_No(bp), port_No(port), port->overrun);
for (i = 0; i < 10; i++)
dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]); dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
}
dprintk(SX_DEBUG_FIFO, "].\n"); dprintk(SX_DEBUG_FIFO, "].\n");
} }
...@@ -1315,7 +1365,8 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port * ...@@ -1315,7 +1365,8 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port)); sx_out(bp, CD186x_CAR, port_No(port));
if (!(tty = port->port.tty) || C_HUPCL(tty)) { tty = port->port.tty;
if (tty == NULL || C_HUPCL(tty)) {
/* Drop DTR */ /* Drop DTR */
sx_out(bp, CD186x_MSVDTR, 0); sx_out(bp, CD186x_MSVDTR, 0);
} }
...@@ -1338,8 +1389,8 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port * ...@@ -1338,8 +1389,8 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
} }
static int block_til_ready(struct tty_struct *tty, struct file * filp, static int block_til_ready(struct tty_struct *tty, struct file *filp,
struct specialix_port *port) struct specialix_port *port)
{ {
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
struct specialix_board *bp = port_Board(port); struct specialix_board *bp = port_Board(port);
...@@ -1389,23 +1440,22 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, ...@@ -1389,23 +1440,22 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
retval = 0; retval = 0;
add_wait_queue(&port->port.open_wait, &wait); add_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
if (!tty_hung_up_p(filp)) { if (!tty_hung_up_p(filp))
port->port.count--; port->port.count--;
}
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
port->port.blocked_open++; port->port.blocked_open++;
while (1) { while (1) {
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port)); sx_out(bp, CD186x_CAR, port_No(port));
CD = sx_in(bp, CD186x_MSVR) & MSVR_CD; CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
if (SX_CRTSCTS (tty)) { if (SX_CRTSCTS(tty)) {
/* Activate RTS */ /* Activate RTS */
port->MSVR |= MSVR_DTR; /* WTF? */ port->MSVR |= MSVR_DTR; /* WTF? */
sx_out (bp, CD186x_MSVR, port->MSVR); sx_out(bp, CD186x_MSVR, port->MSVR);
} else { } else {
/* Activate DTR */ /* Activate DTR */
port->MSVR |= MSVR_DTR; port->MSVR |= MSVR_DTR;
sx_out (bp, CD186x_MSVR, port->MSVR); sx_out(bp, CD186x_MSVR, port->MSVR);
} }
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
...@@ -1430,9 +1480,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, ...@@ -1430,9 +1480,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&port->port.open_wait, &wait); remove_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
if (!tty_hung_up_p(filp)) { if (!tty_hung_up_p(filp))
port->port.count++; port->port.count++;
}
port->port.blocked_open--; port->port.blocked_open--;
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
if (retval) { if (retval) {
...@@ -1446,12 +1495,12 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, ...@@ -1446,12 +1495,12 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
} }
static int sx_open(struct tty_struct * tty, struct file * filp) static int sx_open(struct tty_struct *tty, struct file *filp)
{ {
int board; int board;
int error; int error;
struct specialix_port * port; struct specialix_port *port;
struct specialix_board * bp; struct specialix_board *bp;
int i; int i;
unsigned long flags; unsigned long flags;
...@@ -1468,17 +1517,19 @@ static int sx_open(struct tty_struct * tty, struct file * filp) ...@@ -1468,17 +1517,19 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
port = sx_port + board * SX_NPORT + SX_PORT(tty->index); port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
port->overrun = 0; port->overrun = 0;
for (i = 0; i < 10; i++) for (i = 0; i < 10; i++)
port->hits[i]=0; port->hits[i] = 0;
dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n", dprintk(SX_DEBUG_OPEN,
board, bp, port, SX_PORT(tty->index)); "Board = %d, bp = %p, port = %p, portno = %d.\n",
board, bp, port, SX_PORT(tty->index));
if (sx_paranoia_check(port, tty->name, "sx_open")) { if (sx_paranoia_check(port, tty->name, "sx_open")) {
func_enter(); func_enter();
return -ENODEV; return -ENODEV;
} }
if ((error = sx_setup_board(bp))) { error = sx_setup_board(bp);
if (error) {
func_exit(); func_exit();
return error; return error;
} }
...@@ -1490,12 +1541,14 @@ static int sx_open(struct tty_struct * tty, struct file * filp) ...@@ -1490,12 +1541,14 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
port->port.tty = tty; port->port.tty = tty;
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
if ((error = sx_setup_port(bp, port))) { error = sx_setup_port(bp, port);
if (error) {
func_enter(); func_enter();
return error; return error;
} }
if ((error = block_til_ready(tty, filp, port))) { error = block_til_ready(tty, filp, port);
if (error) {
func_enter(); func_enter();
return error; return error;
} }
...@@ -1508,7 +1561,7 @@ static void sx_flush_buffer(struct tty_struct *tty) ...@@ -1508,7 +1561,7 @@ static void sx_flush_buffer(struct tty_struct *tty)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags; unsigned long flags;
struct specialix_board * bp; struct specialix_board *bp;
func_enter(); func_enter();
...@@ -1526,9 +1579,9 @@ static void sx_flush_buffer(struct tty_struct *tty) ...@@ -1526,9 +1579,9 @@ static void sx_flush_buffer(struct tty_struct *tty)
func_exit(); func_exit();
} }
static void sx_close(struct tty_struct * tty, struct file * filp) static void sx_close(struct tty_struct *tty, struct file *filp)
{ {
struct specialix_port *port = (struct specialix_port *) tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp; struct specialix_board *bp;
unsigned long flags; unsigned long flags;
unsigned long timeout; unsigned long timeout;
...@@ -1570,17 +1623,16 @@ static void sx_close(struct tty_struct * tty, struct file * filp) ...@@ -1570,17 +1623,16 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
*/ */
tty->closing = 1; tty->closing = 1;
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
dprintk (SX_DEBUG_OPEN, "Closing\n"); dprintk(SX_DEBUG_OPEN, "Closing\n");
if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) { if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
tty_wait_until_sent(tty, port->port.closing_wait); tty_wait_until_sent(tty, port->port.closing_wait);
}
/* /*
* At this point we stop accepting input. To do this, we * At this point we stop accepting input. To do this, we
* disable the receive line status interrupts, and tell the * disable the receive line status interrupts, and tell the
* interrupt driver to stop checking the data ready bit in the * interrupt driver to stop checking the data ready bit in the
* line status register. * line status register.
*/ */
dprintk (SX_DEBUG_OPEN, "Closed\n"); dprintk(SX_DEBUG_OPEN, "Closed\n");
port->IER &= ~IER_RXD; port->IER &= ~IER_RXD;
if (port->port.flags & ASYNC_INITIALIZED) { if (port->port.flags & ASYNC_INITIALIZED) {
port->IER &= ~IER_TXRDY; port->IER &= ~IER_TXRDY;
...@@ -1595,11 +1647,11 @@ static void sx_close(struct tty_struct * tty, struct file * filp) ...@@ -1595,11 +1647,11 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
* important if there is a transmit FIFO! * important if there is a transmit FIFO!
*/ */
timeout = jiffies+HZ; timeout = jiffies+HZ;
while(port->IER & IER_TXEMPTY) { while (port->IER & IER_TXEMPTY) {
set_current_state (TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
msleep_interruptible(jiffies_to_msecs(port->timeout)); msleep_interruptible(jiffies_to_msecs(port->timeout));
if (time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
printk (KERN_INFO "Timeout waiting for close\n"); printk(KERN_INFO "Timeout waiting for close\n");
break; break;
} }
} }
...@@ -1607,13 +1659,15 @@ static void sx_close(struct tty_struct * tty, struct file * filp) ...@@ -1607,13 +1659,15 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
} }
if (--bp->count < 0) { if (--bp->count < 0) {
printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n", printk(KERN_ERR
board_No(bp), bp->count, tty->index); "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
board_No(bp), bp->count, tty->index);
bp->count = 0; bp->count = 0;
} }
if (--port->port.count < 0) { if (--port->port.count < 0) {
printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n", printk(KERN_ERR
board_No(bp), port_No(port), port->port.count); "sx%d: sx_close: bad port count for tty%d: %d\n",
board_No(bp), port_No(port), port->port.count);
port->port.count = 0; port->port.count = 0;
} }
...@@ -1625,9 +1679,9 @@ static void sx_close(struct tty_struct * tty, struct file * filp) ...@@ -1625,9 +1679,9 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
port->port.tty = NULL; port->port.tty = NULL;
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
if (port->port.blocked_open) { if (port->port.blocked_open) {
if (port->port.close_delay) { if (port->port.close_delay)
msleep_interruptible(jiffies_to_msecs(port->port.close_delay)); msleep_interruptible(
} jiffies_to_msecs(port->port.close_delay));
wake_up_interruptible(&port->port.open_wait); wake_up_interruptible(&port->port.open_wait);
} }
port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
...@@ -1637,8 +1691,8 @@ static void sx_close(struct tty_struct * tty, struct file * filp) ...@@ -1637,8 +1691,8 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
} }
static int sx_write(struct tty_struct * tty, static int sx_write(struct tty_struct *tty,
const unsigned char *buf, int count) const unsigned char *buf, int count)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp; struct specialix_board *bp;
...@@ -1690,11 +1744,11 @@ static int sx_write(struct tty_struct * tty, ...@@ -1690,11 +1744,11 @@ static int sx_write(struct tty_struct * tty,
} }
static int sx_put_char(struct tty_struct * tty, unsigned char ch) static int sx_put_char(struct tty_struct *tty, unsigned char ch)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags; unsigned long flags;
struct specialix_board * bp; struct specialix_board *bp;
func_enter(); func_enter();
...@@ -1702,7 +1756,7 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch) ...@@ -1702,7 +1756,7 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch)
func_exit(); func_exit();
return 0; return 0;
} }
dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
if (!port->xmit_buf) { if (!port->xmit_buf) {
func_exit(); func_exit();
return 0; return 0;
...@@ -1710,14 +1764,15 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch) ...@@ -1710,14 +1764,15 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch)
bp = port_Board(port); bp = port_Board(port);
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf); dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n",
if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) { port->xmit_cnt, port->xmit_buf);
if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) {
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
dprintk (SX_DEBUG_TX, "Exit size\n"); dprintk(SX_DEBUG_TX, "Exit size\n");
func_exit(); func_exit();
return 0; return 0;
} }
dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf); dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
port->xmit_buf[port->xmit_head++] = ch; port->xmit_buf[port->xmit_head++] = ch;
port->xmit_head &= SERIAL_XMIT_SIZE - 1; port->xmit_head &= SERIAL_XMIT_SIZE - 1;
port->xmit_cnt++; port->xmit_cnt++;
...@@ -1728,11 +1783,11 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch) ...@@ -1728,11 +1783,11 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch)
} }
static void sx_flush_chars(struct tty_struct * tty) static void sx_flush_chars(struct tty_struct *tty)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags; unsigned long flags;
struct specialix_board * bp = port_Board(port); struct specialix_board *bp = port_Board(port);
func_enter(); func_enter();
...@@ -1755,7 +1810,7 @@ static void sx_flush_chars(struct tty_struct * tty) ...@@ -1755,7 +1810,7 @@ static void sx_flush_chars(struct tty_struct * tty)
} }
static int sx_write_room(struct tty_struct * tty) static int sx_write_room(struct tty_struct *tty)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
int ret; int ret;
...@@ -1790,12 +1845,10 @@ static int sx_chars_in_buffer(struct tty_struct *tty) ...@@ -1790,12 +1845,10 @@ static int sx_chars_in_buffer(struct tty_struct *tty)
return port->xmit_cnt; return port->xmit_cnt;
} }
static int sx_tiocmget(struct tty_struct *tty, struct file *file) static int sx_tiocmget(struct tty_struct *tty, struct file *file)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board * bp; struct specialix_board *bp;
unsigned char status; unsigned char status;
unsigned int result; unsigned int result;
unsigned long flags; unsigned long flags;
...@@ -1808,25 +1861,25 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file) ...@@ -1808,25 +1861,25 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file)
} }
bp = port_Board(port); bp = port_Board(port);
spin_lock_irqsave (&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port)); sx_out(bp, CD186x_CAR, port_No(port));
status = sx_in(bp, CD186x_MSVR); status = sx_in(bp, CD186x_MSVR);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n", dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
port_No(port), status, sx_in (bp, CD186x_CAR)); port_No(port), status, sx_in(bp, CD186x_CAR));
dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
if (SX_CRTSCTS(port->port.tty)) { if (SX_CRTSCTS(port->port.tty)) {
result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_RTS : 0) | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0) | ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
| ((status & MSVR_CTS) ? TIOCM_CTS : 0); | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
} else { } else {
result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_DTR : 0) | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0) | ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
| ((status & MSVR_CTS) ? TIOCM_CTS : 0); | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
} }
func_exit(); func_exit();
...@@ -1886,14 +1939,15 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, ...@@ -1886,14 +1939,15 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
} }
static inline void sx_send_break(struct specialix_port * port, unsigned long length) static inline void sx_send_break(struct specialix_port *port,
unsigned long length)
{ {
struct specialix_board *bp = port_Board(port); struct specialix_board *bp = port_Board(port);
unsigned long flags; unsigned long flags;
func_enter(); func_enter();
spin_lock_irqsave (&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
port->break_length = SPECIALIX_TPS / HZ * length; port->break_length = SPECIALIX_TPS / HZ * length;
port->COR2 |= COR2_ETC; port->COR2 |= COR2_ETC;
port->IER |= IER_TXRDY; port->IER |= IER_TXRDY;
...@@ -1902,7 +1956,7 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len ...@@ -1902,7 +1956,7 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len
sx_out(bp, CD186x_COR2, port->COR2); sx_out(bp, CD186x_COR2, port->COR2);
sx_out(bp, CD186x_IER, port->IER); sx_out(bp, CD186x_IER, port->IER);
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
spin_unlock_irqrestore (&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
sx_wait_CCR(bp); sx_wait_CCR(bp);
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CCR, CCR_CORCHG2); 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,8 +1967,8 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len
} }
static inline int sx_set_serial_info(struct specialix_port * port, static inline int sx_set_serial_info(struct specialix_port *port,
struct serial_struct __user * newinfo) struct serial_struct __user *newinfo)
{ {
struct serial_struct tmp; struct serial_struct tmp;
struct specialix_board *bp = port_Board(port); struct specialix_board *bp = port_Board(port);
...@@ -1943,25 +1997,25 @@ static inline int sx_set_serial_info(struct specialix_port * port, ...@@ -1943,25 +1997,25 @@ static inline int sx_set_serial_info(struct specialix_port * port,
return -EPERM; return -EPERM;
} }
port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
(tmp.flags & ASYNC_USR_MASK)); (tmp.flags & ASYNC_USR_MASK));
port->custom_divisor = tmp.custom_divisor; port->custom_divisor = tmp.custom_divisor;
} else { } else {
port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
(tmp.flags & ASYNC_FLAGS)); (tmp.flags & ASYNC_FLAGS));
port->port.close_delay = tmp.close_delay; port->port.close_delay = tmp.close_delay;
port->port.closing_wait = tmp.closing_wait; port->port.closing_wait = tmp.closing_wait;
port->custom_divisor = tmp.custom_divisor; port->custom_divisor = tmp.custom_divisor;
} }
if (change_speed) { if (change_speed)
sx_change_speed(bp, port); sx_change_speed(bp, port);
}
func_exit(); func_exit();
unlock_kernel(); unlock_kernel();
return 0; return 0;
} }
static inline int sx_get_serial_info(struct specialix_port * port, static inline int sx_get_serial_info(struct specialix_port *port,
struct serial_struct __user *retinfo) struct serial_struct __user *retinfo)
{ {
struct serial_struct tmp; struct serial_struct tmp;
...@@ -1992,8 +2046,8 @@ static inline int sx_get_serial_info(struct specialix_port * port, ...@@ -1992,8 +2046,8 @@ static inline int sx_get_serial_info(struct specialix_port * port,
} }
static int sx_ioctl(struct tty_struct * tty, struct file * filp, static int sx_ioctl(struct tty_struct *tty, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
int retval; int retval;
...@@ -2007,7 +2061,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, ...@@ -2007,7 +2061,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
} }
switch (cmd) { switch (cmd) {
case TCSBRK: /* SVID version: non-zero arg --> no break */ case TCSBRK: /* SVID version: non-zero arg --> no break */
retval = tty_check_change(tty); retval = tty_check_change(tty);
if (retval) { if (retval) {
func_exit(); func_exit();
...@@ -2017,7 +2071,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, ...@@ -2017,7 +2071,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
if (!arg) if (!arg)
sx_send_break(port, HZ/4); /* 1/4 second */ sx_send_break(port, HZ/4); /* 1/4 second */
return 0; return 0;
case TCSBRKP: /* support for POSIX tcsendbreak() */ case TCSBRKP: /* support for POSIX tcsendbreak() */
retval = tty_check_change(tty); retval = tty_check_change(tty);
if (retval) { if (retval) {
func_exit(); func_exit();
...@@ -2027,13 +2081,13 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, ...@@ -2027,13 +2081,13 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
sx_send_break(port, arg ? arg*(HZ/10) : HZ/4); sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
func_exit(); func_exit();
return 0; return 0;
case TIOCGSERIAL: case TIOCGSERIAL:
func_exit(); func_exit();
return sx_get_serial_info(port, argp); return sx_get_serial_info(port, argp);
case TIOCSSERIAL: case TIOCSSERIAL:
func_exit(); func_exit();
return sx_set_serial_info(port, argp); return sx_set_serial_info(port, argp);
default: default:
func_exit(); func_exit();
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
...@@ -2042,7 +2096,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, ...@@ -2042,7 +2096,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
} }
static void sx_throttle(struct tty_struct * tty) static void sx_throttle(struct tty_struct *tty)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp; struct specialix_board *bp;
...@@ -2058,15 +2112,16 @@ static void sx_throttle(struct tty_struct * tty) ...@@ -2058,15 +2112,16 @@ static void sx_throttle(struct tty_struct * tty)
bp = port_Board(port); bp = port_Board(port);
/* Use DTR instead of RTS ! */ /* Use DTR instead of RTS ! */
if (SX_CRTSCTS (tty)) if (SX_CRTSCTS(tty))
port->MSVR &= ~MSVR_DTR; port->MSVR &= ~MSVR_DTR;
else { else {
/* Auch!!! I think the system shouldn't call this then. */ /* Auch!!! I think the system shouldn't call this then. */
/* Or maybe we're supposed (allowed?) to do our side of hw /* Or maybe we're supposed (allowed?) to do our side of hw
handshake anyway, even when hardware handshake is off. handshake anyway, even when hardware handshake is off.
When you see this in your logs, please report.... */ When you see this in your logs, please report.... */
printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n", printk(KERN_ERR
port_No (port)); "sx%d: Need to throttle, but can't (hardware hs is off)\n",
port_No(port));
} }
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port)); sx_out(bp, CD186x_CAR, port_No(port));
...@@ -2086,7 +2141,7 @@ static void sx_throttle(struct tty_struct * tty) ...@@ -2086,7 +2141,7 @@ static void sx_throttle(struct tty_struct * tty)
} }
static void sx_unthrottle(struct tty_struct * tty) static void sx_unthrottle(struct tty_struct *tty)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp; struct specialix_board *bp;
...@@ -2103,9 +2158,9 @@ static void sx_unthrottle(struct tty_struct * tty) ...@@ -2103,9 +2158,9 @@ static void sx_unthrottle(struct tty_struct * tty)
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
/* XXXX Use DTR INSTEAD???? */ /* XXXX Use DTR INSTEAD???? */
if (SX_CRTSCTS(tty)) { if (SX_CRTSCTS(tty))
port->MSVR |= MSVR_DTR; port->MSVR |= MSVR_DTR;
} /* Else clause: see remark in "sx_throttle"... */ /* Else clause: see remark in "sx_throttle"... */
spin_lock_irqsave(&bp->lock, flags); spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port)); sx_out(bp, CD186x_CAR, port_No(port));
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock_irqrestore(&bp->lock, flags);
...@@ -2127,7 +2182,7 @@ static void sx_unthrottle(struct tty_struct * tty) ...@@ -2127,7 +2182,7 @@ static void sx_unthrottle(struct tty_struct * tty)
} }
static void sx_stop(struct tty_struct * tty) static void sx_stop(struct tty_struct *tty)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp; struct specialix_board *bp;
...@@ -2154,7 +2209,7 @@ static void sx_stop(struct tty_struct * tty) ...@@ -2154,7 +2209,7 @@ static void sx_stop(struct tty_struct * tty)
} }
static void sx_start(struct tty_struct * tty) static void sx_start(struct tty_struct *tty)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp; struct specialix_board *bp;
...@@ -2182,7 +2237,7 @@ static void sx_start(struct tty_struct * tty) ...@@ -2182,7 +2237,7 @@ static void sx_start(struct tty_struct * tty)
func_exit(); func_exit();
} }
static void sx_hangup(struct tty_struct * tty) static void sx_hangup(struct tty_struct *tty)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp; struct specialix_board *bp;
...@@ -2201,8 +2256,9 @@ static void sx_hangup(struct tty_struct * tty) ...@@ -2201,8 +2256,9 @@ static void sx_hangup(struct tty_struct * tty)
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
bp->count -= port->port.count; bp->count -= port->port.count;
if (bp->count < 0) { if (bp->count < 0) {
printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n", printk(KERN_ERR
board_No(bp), bp->count, tty->index); "sx%d: sx_hangup: bad board count: %d port: %d\n",
board_No(bp), bp->count, tty->index);
bp->count = 0; bp->count = 0;
} }
port->port.count = 0; port->port.count = 0;
...@@ -2215,11 +2271,12 @@ static void sx_hangup(struct tty_struct * tty) ...@@ -2215,11 +2271,12 @@ static void sx_hangup(struct tty_struct * tty)
} }
static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termios) static void sx_set_termios(struct tty_struct *tty,
struct ktermios *old_termios)
{ {
struct specialix_port *port = (struct specialix_port *)tty->driver_data; struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags; unsigned long flags;
struct specialix_board * bp; struct specialix_board *bp;
if (sx_paranoia_check(port, tty->name, "sx_set_termios")) if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
return; return;
...@@ -2283,10 +2340,12 @@ static int sx_init_drivers(void) ...@@ -2283,10 +2340,12 @@ static int sx_init_drivers(void)
specialix_driver->flags = TTY_DRIVER_REAL_RAW; specialix_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(specialix_driver, &sx_ops); tty_set_operations(specialix_driver, &sx_ops);
if ((error = tty_register_driver(specialix_driver))) { error = tty_register_driver(specialix_driver);
if (error) {
put_tty_driver(specialix_driver); put_tty_driver(specialix_driver);
printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n", printk(KERN_ERR
error); "sx: Couldn't register specialix IO8+ driver, error = %d\n",
error);
func_exit(); func_exit();
return 1; return 1;
} }
...@@ -2323,9 +2382,9 @@ static int __init specialix_init(void) ...@@ -2323,9 +2382,9 @@ static int __init specialix_init(void)
printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n"); printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n"); printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
#ifdef CONFIG_SPECIALIX_RTSCTS #ifdef CONFIG_SPECIALIX_RTSCTS
printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n"); printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
#else #else
printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); printk(KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
#endif #endif
for (i = 0; i < SX_NBOARD; i++) for (i = 0; i < SX_NBOARD; i++)
...@@ -2344,27 +2403,27 @@ static int __init specialix_init(void) ...@@ -2344,27 +2403,27 @@ static int __init specialix_init(void)
{ {
struct pci_dev *pdev = NULL; struct pci_dev *pdev = NULL;
i=0; i = 0;
while (i < SX_NBOARD) { while (i < SX_NBOARD) {
if (sx_board[i].flags & SX_BOARD_PRESENT) { if (sx_board[i].flags & SX_BOARD_PRESENT) {
i++; i++;
continue; continue;
} }
pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX,
PCI_DEVICE_ID_SPECIALIX_IO8, PCI_DEVICE_ID_SPECIALIX_IO8, pdev);
pdev); if (!pdev)
if (!pdev) break; break;
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
continue; continue;
sx_board[i].irq = pdev->irq; sx_board[i].irq = pdev->irq;
sx_board[i].base = pci_resource_start (pdev, 2); sx_board[i].base = pci_resource_start(pdev, 2);
sx_board[i].flags |= SX_BOARD_IS_PCI; sx_board[i].flags |= SX_BOARD_IS_PCI;
if (!sx_probe(&sx_board[i])) if (!sx_probe(&sx_board[i]))
found ++; found++;
} }
/* May exit pci_get sequence early with lots of boards */ /* May exit pci_get sequence early with lots of boards */
if (pdev != NULL) if (pdev != NULL)
...@@ -2411,10 +2470,10 @@ static int __init specialix_init_module(void) ...@@ -2411,10 +2470,10 @@ static int __init specialix_init_module(void)
func_enter(); func_enter();
if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) { if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
for(i = 0; i < SX_NBOARD; i++) { for (i = 0; i < SX_NBOARD; i++) {
sx_board[i].base = iobase[i]; sx_board[i].base = iobase[i];
sx_board[i].irq = irq[i]; sx_board[i].irq = irq[i];
sx_board[i].count= 0; sx_board[i].count = 0;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment