git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git]
/
drivers
/
char
/
specialix.c
diff --git
a/drivers/char/specialix.c
b/drivers/char/specialix.c
index
50e0b61
..
0b3044d
100644
(file)
--- a/
drivers/char/specialix.c
+++ b/
drivers/char/specialix.c
@@
-38,19
+38,19
@@
*
* Revision 1.0: April 1st 1997.
* Initial release for alpha testing.
*
* Revision 1.0: April 1st 1997.
* Initial release for alpha testing.
- * Revision 1.1: April 14th 1997.
- * Incorporated Richard Hudsons suggestions,
+ * Revision 1.1: April 14th 1997.
+ * Incorporated Richard Hudsons suggestions,
* removed some debugging printk's.
* Revision 1.2: April 15th 1997.
* Ported to 2.1.x kernels.
* removed some debugging printk's.
* Revision 1.2: April 15th 1997.
* Ported to 2.1.x kernels.
- * Revision 1.3: April 17th 1997
- * Backported to 2.0. (Compatibility macros).
+ * Revision 1.3: April 17th 1997
+ * Backported to 2.0. (Compatibility macros).
* Revision 1.4: April 18th 1997
* Revision 1.4: April 18th 1997
- * Fixed DTR/RTS bug that caused the card to indicate
- * "don't send data" to a modem after the password prompt.
+ * Fixed DTR/RTS bug that caused the card to indicate
+ * "don't send data" to a modem after the password prompt.
* Fixed bug for premature (fake) interrupts.
* Revision 1.5: April 19th 1997
* Fixed bug for premature (fake) interrupts.
* Revision 1.5: April 19th 1997
- * fixed a minor typo in the header file, cleanup a little.
+ * fixed a minor typo in the header file, cleanup a little.
* performance warnings are now MAXed at once per minute.
* Revision 1.6: May 23 1997
* Changed the specialix=... format to include interrupt.
* performance warnings are now MAXed at once per minute.
* Revision 1.6: May 23 1997
* Changed the specialix=... format to include interrupt.
@@
-60,10
+60,10
@@
* port to linux-2.1.43 kernel.
* Revision 1.9: Oct 9 1998
* Added stuff for the IO8+/PCI version.
* port to linux-2.1.43 kernel.
* Revision 1.9: Oct 9 1998
* Added stuff for the IO8+/PCI version.
- * Revision 1.10: Oct 22 1999 / Jan 21 2000.
- * Added stuff for setserial.
+ * Revision 1.10: Oct 22 1999 / Jan 21 2000.
+ * Added stuff for setserial.
* Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
* Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
- *
+ *
*/
#define VERSION "1.11"
*/
#define VERSION "1.11"
@@
-75,7
+75,6
@@
* Documentation/specialix.txt
*/
* Documentation/specialix.txt
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <asm/io.h>
#include <linux/module.h>
#include <asm/io.h>
@@
-85,12
+84,12
@@
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/tty.h>
+#include <linux/tty_flip.h>
#include <linux/mm.h>
#include <linux/serial.h>
#include <linux/fcntl.h>
#include <linux/major.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/serial.h>
#include <linux/fcntl.h>
#include <linux/major.h>
#include <linux/delay.h>
-#include <linux/version.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/uaccess.h>
@@
-154,7
+153,7
@@
static int sx_poll = HZ;
-/*
+/*
* The following defines are mostly for testing purposes. But if you need
* some nice reporting in your syslog, you can define them also.
*/
* The following defines are mostly for testing purposes. But if you need
* some nice reporting in your syslog, you can define them also.
*/
@@
-183,13
+182,6
@@
static int sx_poll = HZ;
#define RS_EVENT_WRITE_WAKEUP 0
static struct tty_driver *specialix_driver;
#define RS_EVENT_WRITE_WAKEUP 0
static struct tty_driver *specialix_driver;
-static unsigned char * tmp_buf;
-static DECLARE_MUTEX(tmp_buf_sem);
-
-static unsigned long baud_table[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 0,
-};
static struct specialix_board sx_board[SX_NBOARD] = {
{ 0, SX_IOBASE1, 9, },
static struct specialix_board sx_board[SX_NBOARD] = {
{ 0, SX_IOBASE1, 9, },
@@
-203,7
+195,7
@@
static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
#ifdef SPECIALIX_TIMER
static struct timer_list missed_irq_timer;
#ifdef SPECIALIX_TIMER
static struct timer_list missed_irq_timer;
-static irqreturn_t sx_interrupt(int irq, void * dev_id
, struct pt_regs * regs
);
+static irqreturn_t sx_interrupt(int irq, void * dev_id);
#endif
#endif
@@
-216,7
+208,7
@@
static inline int sx_paranoia_check(struct specialix_port const * port,
KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
static const char *badinfo =
KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
static const char *badinfo =
KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
-
+
if (!port) {
printk(badinfo, name, routine);
return 1;
if (!port) {
printk(badinfo, name, routine);
return 1;
@@
-231,9
+223,9
@@
static inline int sx_paranoia_check(struct specialix_port const * port,
/*
/*
- *
+ *
* Service functions for specialix IO8+ driver.
* Service functions for specialix IO8+ driver.
- *
+ *
*/
/* Get board number from pointer */
*/
/* Get board number from pointer */
@@
-246,7
+238,7
@@
static inline int board_No (struct specialix_board * bp)
/* Get port number from pointer */
static inline int port_No (struct specialix_port const * port)
{
/* Get port number from pointer */
static inline int port_No (struct specialix_port const * port)
{
- return SX_PORT(port - sx_port);
+ return SX_PORT(port - sx_port);
}
}
@@
-309,7
+301,7
@@
static inline void sx_wait_CCR(struct specialix_board * bp)
return;
udelay (1);
}
return;
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));
}
@@
-329,7
+321,7
@@
static inline void sx_wait_CCR_off(struct specialix_board * bp)
return;
udelay (1);
}
return;
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));
}
@@
-338,34
+330,28
@@
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_
check
_io_range(struct specialix_board * bp)
+static inline int sx_
request
_io_range(struct specialix_board * bp)
{
{
- return check_region (bp->base, SX_IO_SPACE);
-}
-
-
-static inline void sx_request_io_range(struct specialix_board * bp)
-{
- request_region(bp->base,
- bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE,
- "specialix IO8+" );
+ return request_region(bp->base,
+ bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
+ "specialix IO8+") == NULL;
}
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?SX_PCI_IO_SPACE:SX_IO_SPACE);
}
bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
}
-
+
/* Must be called with enabled interrupts */
/* Must be called with enabled interrupts */
-/* Ugly. Very ugly. Don't use this for anything else than initialization
+/* Ugly. Very ugly. Don't use this for anything else than initialization
code */
static inline void sx_long_delay(unsigned long delay)
{
unsigned long i;
code */
static inline void sx_long_delay(unsigned long delay)
{
unsigned long i;
-
+
for (i = jiffies + delay; time_after(i, jiffies); ) ;
}
for (i = jiffies + delay; time_after(i, jiffies); ) ;
}
@@
-378,7
+364,7
@@
static int sx_set_irq ( struct specialix_board *bp)
int i;
unsigned long flags;
int i;
unsigned long flags;
- if (bp->flags & SX_BOARD_IS_PCI)
+ if (bp->flags & SX_BOARD_IS_PCI)
return 1;
switch (bp->irq) {
/* In the same order as in the docs... */
return 1;
switch (bp->irq) {
/* In the same order as in the docs... */
@@
-420,7
+406,7
@@
static int sx_init_CD186x(struct specialix_board * bp)
sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
/* Set RegAckEn */
sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
/* Set RegAckEn */
sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
-
+
/* Setting up prescaler. We need 4 ticks per 1 ms */
scaler = SX_OSCFREQ/SPECIALIX_TPS;
/* Setting up prescaler. We need 4 ticks per 1 ms */
scaler = SX_OSCFREQ/SPECIALIX_TPS;
@@
-448,7
+434,7
@@
static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
spin_lock_irqsave(&bp->lock, flags);
for (i=0, t=0;i<8;i++) {
sx_out_off (bp, CD186x_CAR, i);
spin_lock_irqsave(&bp->lock, flags);
for (i=0, t=0;i<8;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;
}
spin_unlock_irqrestore(&bp->lock, flags);
t |= 1 << i;
}
spin_unlock_irqrestore(&bp->lock, flags);
@@
-472,8
+458,8
@@
void missed_irq (unsigned long data)
spin_unlock_irqrestore(&bp->lock, flags);
if (irq) {
printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
spin_unlock_irqrestore(&bp->lock, flags);
if (irq) {
printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
- sx_interrupt (((struct specialix_board *)data)->irq,
-
(void*)data, NULL
);
+ sx_interrupt (((struct specialix_board *)data)->irq,
+
(void*)data
);
}
missed_irq_timer.expires = jiffies + sx_poll;
add_timer (&missed_irq_timer);
}
missed_irq_timer.expires = jiffies + sx_poll;
add_timer (&missed_irq_timer);
@@
-495,7
+481,7
@@
static int sx_probe(struct specialix_board *bp)
func_enter();
func_enter();
- if (sx_
check
_io_range(bp)) {
+ if (sx_
request
_io_range(bp)) {
func_exit();
return 1;
}
func_exit();
return 1;
}
@@
-509,15
+495,16
@@
static int sx_probe(struct specialix_board *bp)
short_pause ();
val2 = sx_in_off(bp, CD186x_PPRL);
short_pause ();
val2 = sx_in_off(bp, CD186x_PPRL);
-
+
if ((val1 != 0x5a) || (val2 != 0xa5)) {
printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
board_No(bp), bp->base);
if ((val1 != 0x5a) || (val2 != 0xa5)) {
printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
board_No(bp), bp->base);
+ sx_release_io_range(bp);
func_exit();
return 1;
}
func_exit();
return 1;
}
- /* Check the DSR lines that Specialix uses as board
+ /* Check the DSR lines that Specialix uses as board
identification */
val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
identification */
val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
@@
-532,6
+519,7
@@
static int sx_probe(struct specialix_board *bp)
if (val1 != val2) {
printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
board_No(bp), val2, bp->base, val1);
if (val1 != val2) {
printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
board_No(bp), val2, bp->base, val1);
+ sx_release_io_range(bp);
func_exit();
return 1;
}
func_exit();
return 1;
}
@@
-546,7
+534,7
@@
static int sx_probe(struct specialix_board *bp)
sx_wait_CCR(bp);
sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
sx_wait_CCR(bp);
sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
- sx_long_delay(HZ/20);
+ sx_long_delay(HZ/20);
irqs = probe_irq_off(irqs);
dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
irqs = probe_irq_off(irqs);
dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
@@
-561,14
+549,15
@@
static int sx_probe(struct specialix_board *bp)
}
dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
}
dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
- val1, val2, val3);
-
+ val1, val2, val3);
+
}
}
-
+
#if 0
if (irqs <= 0) {
printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
board_No(bp), bp->base);
#if 0
if (irqs <= 0) {
printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
board_No(bp), bp->base);
+ sx_release_io_range(bp);
func_exit();
return 1;
}
func_exit();
return 1;
}
@@
-579,19
+568,20
@@
static int sx_probe(struct specialix_board *bp)
#endif
/* Reset CD186x again */
if (!sx_init_CD186x(bp)) {
#endif
/* Reset CD186x again */
if (!sx_init_CD186x(bp)) {
+ sx_release_io_range(bp);
func_exit();
func_exit();
- return
-EIO
;
+ return
1
;
}
sx_request_io_range(bp);
bp->flags |= SX_BOARD_PRESENT;
}
sx_request_io_range(bp);
bp->flags |= SX_BOARD_PRESENT;
-
+
/* Chip revcode pkgtype
GFRCR SRCR bit 7
CD180 rev B 0x81 0
CD180 rev C 0x82 0
CD1864 rev A 0x82 1
/* Chip revcode pkgtype
GFRCR SRCR bit 7
CD180 rev B 0x81 0
CD180 rev C 0x82 0
CD1864 rev A 0x82 1
- CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
+ CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
CD1865 rev B 0x84 1
-- Thanks to Gwen Wang, Cirrus Logic.
*/
CD1865 rev B 0x84 1
-- Thanks to Gwen Wang, Cirrus Logic.
*/
@@
-623,8
+613,8
@@
static int sx_probe(struct specialix_board *bp)
return 0;
}
return 0;
}
-/*
- *
+/*
+ *
* Interrupt processing routines.
* */
* Interrupt processing routines.
* */
@@
-657,7
+647,7
@@
static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
return port;
}
}
return port;
}
}
- printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
+ printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
board_No(bp), what, channel);
return NULL;
}
board_No(bp), what, channel);
return NULL;
}
@@
-668,7
+658,7
@@
static inline void sx_receive_exc(struct specialix_board * bp)
struct specialix_port *port;
struct tty_struct *tty;
unsigned char status;
struct specialix_port *port;
struct tty_struct *tty;
unsigned char status;
- unsigned char ch;
+ unsigned char ch
, flag
;
func_enter();
func_enter();
@@
-679,9
+669,7
@@
static inline void sx_receive_exc(struct specialix_board * bp)
return;
}
tty = port->tty;
return;
}
tty = port->tty;
- dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
- port, tty->flip.count, TTY_FLIPBUF_SIZE);
-
+
status = sx_in(bp, CD186x_RCSR);
dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
status = sx_in(bp, CD186x_RCSR);
dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
@@
-694,7
+682,7
@@
static inline void sx_receive_exc(struct specialix_board * bp)
/* This flip buffer check needs to be below the reading of the
status register to reset the chip's IRQ.... */
/* This flip buffer check needs to be below the reading of the
status register to reset the chip's IRQ.... */
- if (tty
->flip.count >= TTY_FLIPBUF_SIZE
) {
+ if (tty
_buffer_request_room(tty, 1) == 0
) {
dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
board_No(bp), port_No(port));
func_exit();
dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
board_No(bp), port_No(port));
func_exit();
@@
-707,34
+695,32
@@
static inline void sx_receive_exc(struct specialix_board * bp)
return;
}
if (status & RCSR_TOUT) {
return;
}
if (status & RCSR_TOUT) {
- printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
+ printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
board_No(bp), port_No(port));
func_exit();
return;
board_No(bp), port_No(port));
func_exit();
return;
-
+
} else if (status & RCSR_BREAK) {
dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
board_No(bp), port_No(port));
} else if (status & RCSR_BREAK) {
dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
board_No(bp), port_No(port));
-
*tty->flip.flag_buf_ptr++
= TTY_BREAK;
+
flag
= TTY_BREAK;
if (port->flags & ASYNC_SAK)
do_SAK(tty);
if (port->flags & ASYNC_SAK)
do_SAK(tty);
-
- } else if (status & RCSR_PE)
-
*tty->flip.flag_buf_ptr++
= TTY_PARITY;
-
- else if (status & RCSR_FE)
-
*tty->flip.flag_buf_ptr++
= TTY_FRAME;
-
+
+ } else if (status & RCSR_PE)
+
flag
= TTY_PARITY;
+
+ else if (status & RCSR_FE)
+
flag
= TTY_FRAME;
+
else if (status & RCSR_OE)
else if (status & RCSR_OE)
-
*tty->flip.flag_buf_ptr++
= TTY_OVERRUN;
-
+
flag
= TTY_OVERRUN;
+
else
else
- *tty->flip.flag_buf_ptr++ = 0;
-
- *tty->flip.char_buf_ptr++ = ch;
- tty->flip.count++;
- schedule_delayed_work(&tty->flip.work, 1);
+ flag = TTY_NORMAL;
+ if(tty_insert_flip_char(tty, ch, flag))
+ tty_flip_buffer_push(tty);
func_exit();
}
func_exit();
}
@@
-746,30
+732,23
@@
static inline void sx_receive(struct specialix_board * bp)
unsigned char count;
func_enter();
unsigned char count;
func_enter();
-
+
if (!(port = sx_get_port(bp, "Receive"))) {
dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
func_exit();
return;
}
tty = port->tty;
if (!(port = sx_get_port(bp, "Receive"))) {
dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
func_exit();
return;
}
tty = port->tty;
-
+
count = sx_in(bp, CD186x_RDCR);
dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
port->hits[count > 8 ? 9 : count]++;
count = sx_in(bp, CD186x_RDCR);
dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
port->hits[count > 8 ? 9 : count]++;
-
- while (count--) {
- if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
- printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
- board_No(bp), port_No(port));
- break;
- }
- *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR);
- *tty->flip.flag_buf_ptr++ = 0;
- tty->flip.count++;
- }
- schedule_delayed_work(&tty->flip.work, 1);
+ tty_buffer_request_room(tty, count);
+
+ while (count--)
+ tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
+ tty_flip_buffer_push(tty);
func_exit();
}
func_exit();
}
@@
-787,7
+766,7
@@
static inline void sx_transmit(struct specialix_board * bp)
}
dprintk (SX_DEBUG_TX, "port: %p\n", port);
tty = port->tty;
}
dprintk (SX_DEBUG_TX, "port: %p\n", port);
tty = port->tty;
-
+
if (port->IER & IER_TXEMPTY) {
/* FIFO drained */
sx_out(bp, CD186x_CAR, port_No(port));
if (port->IER & IER_TXEMPTY) {
/* FIFO drained */
sx_out(bp, CD186x_CAR, port_No(port));
@@
-796,7
+775,7
@@
static inline void sx_transmit(struct specialix_board * bp)
func_exit();
return;
}
func_exit();
return;
}
-
+
if ((port->xmit_cnt <= 0 && !port->break_length)
|| tty->stopped || tty->hw_stopped) {
sx_out(bp, CD186x_CAR, port_No(port));
if ((port->xmit_cnt <= 0 && !port->break_length)
|| tty->stopped || tty->hw_stopped) {
sx_out(bp, CD186x_CAR, port_No(port));
@@
-805,7
+784,7
@@
static inline void sx_transmit(struct specialix_board * bp)
func_exit();
return;
}
func_exit();
return;
}
-
+
if (port->break_length) {
if (port->break_length > 0) {
if (port->COR2 & COR2_ETC) {
if (port->break_length) {
if (port->break_length > 0) {
if (port->COR2 & COR2_ETC) {
@@
-831,7
+810,7
@@
static inline void sx_transmit(struct specialix_board * bp)
func_exit();
return;
}
func_exit();
return;
}
-
+
count = CD186x_NFIFO;
do {
sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
count = CD186x_NFIFO;
do {
sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
@@
-839,7
+818,7
@@
static inline void sx_transmit(struct specialix_board * bp)
if (--port->xmit_cnt <= 0)
break;
} while (--count > 0);
if (--port->xmit_cnt <= 0)
break;
} while (--count > 0);
-
+
if (port->xmit_cnt <= 0) {
sx_out(bp, CD186x_CAR, port_No(port));
port->IER &= ~IER_TXRDY;
if (port->xmit_cnt <= 0) {
sx_out(bp, CD186x_CAR, port_No(port));
port->IER &= ~IER_TXRDY;
@@
-862,9
+841,9
@@
static inline void sx_check_modem(struct specialix_board * bp)
dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
if (!(port = sx_get_port(bp, "Modem")))
return;
dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
if (!(port = sx_get_port(bp, "Modem")))
return;
-
+
tty = port->tty;
tty = port->tty;
-
+
mcr = sx_in(bp, CD186x_MCR);
printk ("mcr = %02x.\n", mcr);
mcr = sx_in(bp, CD186x_MCR);
printk ("mcr = %02x.\n", mcr);
@@
-879,7
+858,7
@@
static inline void sx_check_modem(struct specialix_board * bp)
schedule_work(&port->tqueue_hangup);
}
}
schedule_work(&port->tqueue_hangup);
}
}
-
+
#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
if (mcr & MCR_CTSCHG) {
if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
if (mcr & MCR_CTSCHG) {
if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
@@
-906,14
+885,14
@@
static inline void sx_check_modem(struct specialix_board * bp)
sx_out(bp, CD186x_IER, port->IER);
}
#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
sx_out(bp, CD186x_IER, port->IER);
}
#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
-
+
/* Clear change bits */
sx_out(bp, CD186x_MCR, 0);
}
/* The main interrupt processing routine */
/* Clear change bits */
sx_out(bp, CD186x_MCR, 0);
}
/* The main interrupt processing routine */
-static irqreturn_t sx_interrupt(int irq, void *dev_id
, struct pt_regs *regs
)
+static irqreturn_t sx_interrupt(int irq, void *dev_id)
{
unsigned char status;
unsigned char ack;
{
unsigned char status;
unsigned char ack;
@@
-928,7
+907,7
@@
static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_lock_irqsave(&bp->lock, flags);
dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
spin_lock_irqsave(&bp->lock, flags);
dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
- if (!
bp || !
(bp->flags & SX_BOARD_ACTIVE)) {
+ if (!(bp->flags & SX_BOARD_ACTIVE)) {
dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
spin_unlock_irqrestore(&bp->lock, flags);
func_exit();
dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
spin_unlock_irqrestore(&bp->lock, flags);
func_exit();
@@
-940,7
+919,7
@@
static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
(SRSR_RREQint |
SRSR_TREQint |
while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
(SRSR_RREQint |
SRSR_TREQint |
- SRSR_MREQint)))) {
+ SRSR_MREQint)))) {
if (status & SRSR_RREQint) {
ack = sx_in(bp, CD186x_RRAR);
if (status & SRSR_RREQint) {
ack = sx_in(bp, CD186x_RRAR);
@@
-951,7
+930,7
@@
static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
else
printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
board_No(bp), status, ack);
else
printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
board_No(bp), status, ack);
-
+
} else if (status & SRSR_TREQint) {
ack = sx_in(bp, CD186x_TRAR);
} else if (status & SRSR_TREQint) {
ack = sx_in(bp, CD186x_TRAR);
@@
-963,13
+942,13
@@
static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
} else if (status & SRSR_MREQint) {
ack = sx_in(bp, CD186x_MRAR);
} else if (status & SRSR_MREQint) {
ack = sx_in(bp, CD186x_MRAR);
- if (ack == (SX_ID | GIVR_IT_MODEM))
+ if (ack == (SX_ID | GIVR_IT_MODEM))
sx_check_modem(bp);
else
printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
board_No(bp), status, ack);
sx_check_modem(bp);
else
printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
board_No(bp), status, ack);
-
- }
+
+ }
sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
}
sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
}
@@
-1026,15
+1005,15
@@
static inline int sx_setup_board(struct specialix_board * bp)
{
int error;
{
int error;
- if (bp->flags & SX_BOARD_ACTIVE)
+ if (bp->flags & SX_BOARD_ACTIVE)
return 0;
if (bp->flags & SX_BOARD_IS_PCI)
return 0;
if (bp->flags & SX_BOARD_IS_PCI)
- error = request_irq(bp->irq, sx_interrupt,
SA_INTERRUPT | SA_SHIRQ
, "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,
SA_INTERRUPT
, "specialix IO8+", bp);
+ error = request_irq(bp->irq, sx_interrupt,
IRQF_DISABLED
, "specialix IO8+", bp);
- if (error)
+ if (error)
return error;
turn_ints_on (bp);
return error;
turn_ints_on (bp);
@@
-1055,7
+1034,7
@@
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",
bp->irq, board_No (bp));
free_irq(bp->irq, bp);
dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
bp->irq, board_No (bp));
free_irq(bp->irq, bp);
@@
-1068,7
+1047,7
@@
static inline void sx_shutdown_board(struct specialix_board *bp)
/*
/*
- * Setting up port characteristics.
+ * Setting up port characteristics.
* Must be called with disabled interrupts
*/
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
* Must be called with disabled interrupts
*/
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
@@
-1102,24
+1081,16
@@
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
spin_unlock_irqrestore(&bp->lock, flags);
dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
spin_unlock_irqrestore(&bp->lock, flags);
dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
- baud = C_BAUD(tty);
-
- if (baud & CBAUDEX) {
- baud &= ~CBAUDEX;
- if (baud < 1 || baud > 2)
- port->tty->termios->c_cflag &= ~CBAUDEX;
- else
- baud += 15;
- }
- if (baud == 15) {
+ baud = tty_get_baud_rate(tty);
+
+ if (baud == 38400) {
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- baud
++
;
+ baud
= 57600
;
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- baud
+= 2
;
+ baud
= 115200
;
}
}
-
-
- if (!baud_table[baud]) {
+
+ if (!baud) {
/* Drop DTR & exit */
dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
if (!SX_CRTSCTS (tty)) {
/* Drop DTR & exit */
dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
if (!SX_CRTSCTS (tty)) {
@@
-1127,7
+1098,7
@@
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_MSVR, port->MSVR );
spin_unlock_irqrestore(&bp->lock, flags);
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_MSVR, port->MSVR );
spin_unlock_irqrestore(&bp->lock, flags);
- }
+ }
else
dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
return;
else
dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
return;
@@
-1137,9
+1108,9
@@
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
port ->MSVR |= MSVR_DTR;
}
}
port ->MSVR |= MSVR_DTR;
}
}
-
+
/*
/*
- * Now we must calculate some speed depended things
+ * Now we must calculate some speed depended things
*/
/* Set baud rate for port */
*/
/* Set baud rate for port */
@@
-1149,10
+1120,10
@@
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
"This is an untested option, please be carefull.\n",
port_No (port), tmp);
else
"This is an untested option, please be carefull.\n",
port_No (port), tmp);
else
- tmp = (((SX_OSCFREQ + baud
_table[baud]/2) / baud_table[baud]
+
+ tmp = (((SX_OSCFREQ + baud
/2) / baud
+
CD186x_TPC/2) / CD186x_TPC);
CD186x_TPC/2) / CD186x_TPC);
- if ((tmp < 0x10) && time_before(again, jiffies)) {
+ if ((tmp < 0x10) && time_before(again, jiffies)) {
again = jiffies + HZ * 60;
/* Page 48 of version 2.0 of the CL-CD1865 databook */
if (tmp >= 12) {
again = jiffies + HZ * 60;
/* Page 48 of version 2.0 of the CL-CD1865 databook */
if (tmp >= 12) {
@@
-1164,27
+1135,25
@@
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
"Warning: overstressing Cirrus chip. "
"This might not work.\n"
printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
"Warning: overstressing Cirrus chip. "
"This might not work.\n"
- "Read specialix.txt for more info.\n",
+ "Read specialix.txt for more info.\n",
port_No (port), tmp);
}
}
spin_lock_irqsave(&bp->lock, flags);
port_No (port), tmp);
}
}
spin_lock_irqsave(&bp->lock, flags);
- sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
- sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
- sx_out(bp, CD186x_RBPRL, tmp & 0xff);
+ sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
+ sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
+ sx_out(bp, CD186x_RBPRL, tmp & 0xff);
sx_out(bp, CD186x_TBPRL, tmp & 0xff);
spin_unlock_irqrestore(&bp->lock, flags);
sx_out(bp, CD186x_TBPRL, tmp & 0xff);
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;
- } else
- baud = (baud_table[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 */
- tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
+ tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
SERIAL_XMIT_SIZE - 1 : tmp);
port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
SERIAL_XMIT_SIZE - 1 : tmp);
-
+
/* Receiver timeout will be transmission time for 1.5 chars */
tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
tmp = (tmp > 0xff) ? 0xff : tmp;
/* Receiver timeout will be transmission time for 1.5 chars */
tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
tmp = (tmp > 0xff) ? 0xff : tmp;
@@
-1205,29
+1174,29
@@
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
cor1 |= COR1_8BITS;
break;
}
cor1 |= COR1_8BITS;
break;
}
-
- if (C_CSTOPB(tty))
+
+ if (C_CSTOPB(tty))
cor1 |= COR1_2SB;
cor1 |= COR1_2SB;
-
+
cor1 |= COR1_IGNORE;
if (C_PARENB(tty)) {
cor1 |= COR1_NORMPAR;
cor1 |= COR1_IGNORE;
if (C_PARENB(tty)) {
cor1 |= COR1_NORMPAR;
- if (C_PARODD(tty))
+ if (C_PARODD(tty))
cor1 |= COR1_ODDP;
cor1 |= COR1_ODDP;
- if (I_INPCK(tty))
+ if (I_INPCK(tty))
cor1 &= ~COR1_IGNORE;
}
/* Set marking of some errors */
port->mark_mask = RCSR_OE | RCSR_TOUT;
cor1 &= ~COR1_IGNORE;
}
/* Set marking of some errors */
port->mark_mask = RCSR_OE | RCSR_TOUT;
- if (I_INPCK(tty))
+ if (I_INPCK(tty))
port->mark_mask |= RCSR_FE | RCSR_PE;
port->mark_mask |= RCSR_FE | RCSR_PE;
- if (I_BRKINT(tty) || I_PARMRK(tty))
+ if (I_BRKINT(tty) || I_PARMRK(tty))
port->mark_mask |= RCSR_BREAK;
port->mark_mask |= RCSR_BREAK;
- if (I_IGNPAR(tty))
+ if (I_IGNPAR(tty))
port->mark_mask &= ~(RCSR_FE | RCSR_PE);
if (I_IGNBRK(tty)) {
port->mark_mask &= ~RCSR_BREAK;
port->mark_mask &= ~(RCSR_FE | RCSR_PE);
if (I_IGNBRK(tty)) {
port->mark_mask &= ~RCSR_BREAK;
- if (I_IGNPAR(tty))
+ if (I_IGNPAR(tty))
/* Real raw mode. Ignore all */
port->mark_mask &= ~RCSR_OE;
}
/* Real raw mode. Ignore all */
port->mark_mask &= ~RCSR_OE;
}
@@
-1241,7
+1210,7
@@
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
spin_unlock_irqrestore(&bp->lock, flags);
#else
tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
spin_unlock_irqrestore(&bp->lock, flags);
#else
- port->COR2 |= COR2_CTSAE;
+ port->COR2 |= COR2_CTSAE;
#endif
}
/* Enable Software Flow Control. FIXME: I'm not sure about this */
#endif
}
/* Enable Software Flow Control. FIXME: I'm not sure about this */
@@
-1264,11
+1233,11
@@
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
mcor1 |= MCOR1_CDZD;
mcor2 |= MCOR2_CDOD;
}
mcor1 |= MCOR1_CDZD;
mcor2 |= MCOR2_CDOD;
}
-
- if (C_CREAD(tty))
+
+ if (C_CREAD(tty))
/* Enable receiver */
port->IER |= IER_RXD;
/* Enable receiver */
port->IER |= IER_RXD;
-
+
/* Set input FIFO size (1-8 bytes) */
cor3 |= sx_rxfifo;
/* Setting up CD186x channel registers */
/* Set input FIFO size (1-8 bytes) */
cor3 |= sx_rxfifo;
/* Setting up CD186x channel registers */
@@
-1311,11
+1280,11
@@
static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
func_exit();
return 0;
}
func_exit();
return 0;
}
-
+
if (!port->xmit_buf) {
/* We may sleep in get_zeroed_page() */
unsigned long tmp;
if (!port->xmit_buf) {
/* We may sleep in get_zeroed_page() */
unsigned long tmp;
-
+
if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
func_exit();
return -ENOMEM;
if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
func_exit();
return -ENOMEM;
@@
-1328,10
+1297,10
@@
static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
}
port->xmit_buf = (unsigned char *) tmp;
}
}
port->xmit_buf = (unsigned char *) tmp;
}
-
+
spin_lock_irqsave(&port->lock, flags);
spin_lock_irqsave(&port->lock, flags);
- if (port->tty)
+ if (port->tty)
clear_bit(TTY_IO_ERROR, &port->tty->flags);
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
clear_bit(TTY_IO_ERROR, &port->tty->flags);
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
@@
-1340,7
+1309,7
@@
static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->lock, flags);
-
+
func_exit();
return 0;
}
func_exit();
return 0;
}
@@
-1352,14
+1321,14
@@
static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
struct tty_struct *tty;
int i;
unsigned long flags;
struct tty_struct *tty;
int i;
unsigned long flags;
-
+
func_enter();
if (!(port->flags & ASYNC_INITIALIZED)) {
func_exit();
return;
}
func_enter();
if (!(port->flags & ASYNC_INITIALIZED)) {
func_exit();
return;
}
-
+
if (sx_debug & SX_DEBUG_FIFO) {
dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
board_No(bp), port_No(port), port->overrun);
if (sx_debug & SX_DEBUG_FIFO) {
dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
board_No(bp), port_No(port), port->overrun);
@@
-1394,13
+1363,13
@@
static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
if (tty)
set_bit(TTY_IO_ERROR, &tty->flags);
port->flags &= ~ASYNC_INITIALIZED;
if (tty)
set_bit(TTY_IO_ERROR, &tty->flags);
port->flags &= ~ASYNC_INITIALIZED;
-
- if (!bp->count)
+
+ if (!bp->count)
sx_shutdown_board(bp);
func_exit();
}
sx_shutdown_board(bp);
func_exit();
}
-
+
static int block_til_ready(struct tty_struct *tty, struct file * filp,
struct specialix_port *port)
{
static int block_til_ready(struct tty_struct *tty, struct file * filp,
struct specialix_port *port)
{
@@
-1427,7
+1396,7
@@
static int block_til_ready(struct tty_struct *tty, struct file * filp,
return -ERESTARTSYS;
}
}
return -ERESTARTSYS;
}
}
-
+
/*
* If non-blocking mode is set, or the port is not enabled,
* then make the check up front and then exit.
/*
* If non-blocking mode is set, or the port is not enabled,
* then make the check up front and then exit.
@@
-1477,7
+1446,7
@@
static int block_til_ready(struct tty_struct *tty, struct file * filp,
if (port->flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
if (port->flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
- retval = -ERESTARTSYS;
+ retval = -ERESTARTSYS;
break;
}
if (!(port->flags & ASYNC_CLOSING) &&
break;
}
if (!(port->flags & ASYNC_CLOSING) &&
@@
-1506,7
+1475,7
@@
static int block_til_ready(struct tty_struct *tty, struct file * filp,
port->flags |= ASYNC_NORMAL_ACTIVE;
func_exit();
return 0;
port->flags |= ASYNC_NORMAL_ACTIVE;
func_exit();
return 0;
-}
+}
static int sx_open(struct tty_struct * tty, struct file * filp)
static int sx_open(struct tty_struct * tty, struct file * filp)
@@
-1526,7
+1495,7
@@
static int sx_open(struct tty_struct * tty, struct file * filp)
func_exit();
return -ENODEV;
}
func_exit();
return -ENODEV;
}
-
+
bp = &sx_board[board];
port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
port->overrun = 0;
bp = &sx_board[board];
port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
port->overrun = 0;
@@
-1557,7
+1526,7
@@
static int sx_open(struct tty_struct * tty, struct file * filp)
func_enter();
return error;
}
func_enter();
return error;
}
-
+
if ((error = block_til_ready(tty, filp, port))) {
func_enter();
return error;
if ((error = block_til_ready(tty, filp, port))) {
func_enter();
return error;
@@
-1574,7
+1543,7
@@
static void sx_close(struct tty_struct * tty, struct file * filp)
struct specialix_board *bp;
unsigned long flags;
unsigned long timeout;
struct specialix_board *bp;
unsigned long flags;
unsigned long timeout;
-
+
func_enter();
if (!port || sx_paranoia_check(port, tty->name, "close")) {
func_exit();
func_enter();
if (!port || sx_paranoia_check(port, tty->name, "close")) {
func_exit();
@@
-1587,7
+1556,7
@@
static void sx_close(struct tty_struct * tty, struct file * filp)
func_exit();
return;
}
func_exit();
return;
}
-
+
bp = port_Board(port);
if ((tty->count == 1) && (port->count != 1)) {
printk(KERN_ERR "sx%d: sx_close: bad port count;"
bp = port_Board(port);
if ((tty->count == 1) && (port->count != 1)) {
printk(KERN_ERR "sx%d: sx_close: bad port count;"
@@
-1607,7
+1576,7
@@
static void sx_close(struct tty_struct * tty, struct file * filp)
}
port->flags |= ASYNC_CLOSING;
/*
}
port->flags |= ASYNC_CLOSING;
/*
- * Now we wait for the transmit buffer to clear; and we notify
+ * Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
@@
-1681,7
+1650,7
@@
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)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
const unsigned char *buf, int count)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@
-1694,10
+1663,10
@@
static int sx_write(struct tty_struct * tty,
func_exit();
return 0;
}
func_exit();
return 0;
}
-
+
bp = port_Board(port);
bp = port_Board(port);
- if (!
tty || !port->xmit_buf || !tmp
_buf) {
+ if (!
port->xmit
_buf) {
func_exit();
return 0;
}
func_exit();
return 0;
}
@@
-1747,7
+1716,7
@@
static void sx_put_char(struct tty_struct * tty, unsigned char ch)
return;
}
dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
return;
}
dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
- if (!
tty || !
port->xmit_buf) {
+ if (!port->xmit_buf) {
func_exit();
return;
}
func_exit();
return;
}
@@
-1824,7
+1793,7
@@
static int sx_chars_in_buffer(struct tty_struct *tty)
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
func_enter();
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
func_exit();
return 0;
if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
func_exit();
return 0;
@@
-1881,13
+1850,13
@@
static int sx_tiocmget(struct tty_struct *tty, struct file *file)
port_No(port), status, sx_in (bp, CD186x_CAR));
dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
if (SX_CRTSCTS(port->tty)) {
port_No(port), status, sx_in (bp, CD186x_CAR));
dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
if (SX_CRTSCTS(port->tty)) {
- result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
+ result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_RTS : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
| ((status & MSVR_CTS) ? TIOCM_CTS : 0);
} else {
| ((status & MSVR_DTR) ? TIOCM_RTS : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
| ((status & MSVR_CTS) ? TIOCM_CTS : 0);
} else {
- result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
+ result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_DTR : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_DTR : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
@@
-1955,7
+1924,7
@@
static inline void sx_send_break(struct specialix_port * port, unsigned long len
{
struct specialix_board *bp = port_Board(port);
unsigned long flags;
{
struct specialix_board *bp = port_Board(port);
unsigned long flags;
-
+
func_enter();
spin_lock_irqsave (&port->lock, flags);
func_enter();
spin_lock_irqsave (&port->lock, flags);
@@
-1996,8
+1965,8
@@
static inline int sx_set_serial_info(struct specialix_port * port,
func_enter();
return -EFAULT;
}
func_enter();
return -EFAULT;
}
-
-#if 0
+
+#if 0
if ((tmp.irq != bp->irq) ||
(tmp.port != bp->base) ||
(tmp.type != PORT_CIRRUS) ||
if ((tmp.irq != bp->irq) ||
(tmp.port != bp->base) ||
(tmp.type != PORT_CIRRUS) ||
@@
-2008,12
+1977,12
@@
static inline int sx_set_serial_info(struct specialix_port * port,
func_exit();
return -EINVAL;
}
func_exit();
return -EINVAL;
}
-#endif
+#endif
change_speed = ((port->flags & ASYNC_SPD_MASK) !=
(tmp.flags & ASYNC_SPD_MASK));
change_speed |= (tmp.custom_divisor != port->custom_divisor);
change_speed = ((port->flags & ASYNC_SPD_MASK) !=
(tmp.flags & ASYNC_SPD_MASK));
change_speed |= (tmp.custom_divisor != port->custom_divisor);
-
+
if (!capable(CAP_SYS_ADMIN)) {
if ((tmp.close_delay != port->close_delay) ||
(tmp.closing_wait != port->closing_wait) ||
if (!capable(CAP_SYS_ADMIN)) {
if ((tmp.close_delay != port->close_delay) ||
(tmp.closing_wait != port->closing_wait) ||
@@
-2045,7
+2014,7
@@
static inline int sx_get_serial_info(struct specialix_port * port,
{
struct serial_struct tmp;
struct specialix_board *bp = port_Board(port);
{
struct serial_struct tmp;
struct specialix_board *bp = port_Board(port);
-
+
func_enter();
/*
func_enter();
/*
@@
-2074,7
+2043,7
@@
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)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned int cmd, unsigned long arg)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@
-2087,7
+2056,7
@@
static int sx_ioctl(struct tty_struct * tty, struct file * filp,
func_exit();
return -ENODEV;
}
func_exit();
return -ENODEV;
}
-
+
switch (cmd) {
case TCSBRK: /* SVID version: non-zero arg --> no break */
retval = tty_check_change(tty);
switch (cmd) {
case TCSBRK: /* SVID version: non-zero arg --> no break */
retval = tty_check_change(tty);
@@
-2129,7
+2098,7
@@
static int sx_ioctl(struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL:
func_exit();
return sx_get_serial_info(port, argp);
case TIOCGSERIAL:
func_exit();
return sx_get_serial_info(port, argp);
- case TIOCSSERIAL:
+ case TIOCSSERIAL:
func_exit();
return sx_set_serial_info(port, argp);
default:
func_exit();
return sx_set_serial_info(port, argp);
default:
@@
-2153,16
+2122,16
@@
static void sx_throttle(struct tty_struct * tty)
func_exit();
return;
}
func_exit();
return;
}
-
+
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;
else {
/* Auch!!! I think the system shouldn't call this then. */
/* Or maybe we're supposed (allowed?) to do our side of hw
port->MSVR &= ~MSVR_DTR;
else {
/* Auch!!! I think the system shouldn't call this then. */
/* 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.... */
printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
port_No (port));
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",
port_No (port));
@@
-2193,14
+2162,14
@@
static void sx_unthrottle(struct tty_struct * tty)
unsigned long flags;
func_enter();
unsigned long flags;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
func_exit();
return;
}
if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
func_exit();
return;
}
-
+
bp = port_Board(port);
bp = port_Board(port);
-
+
spin_lock_irqsave(&port->lock, flags);
/* XXXX Use DTR INSTEAD???? */
if (SX_CRTSCTS(tty)) {
spin_lock_irqsave(&port->lock, flags);
/* XXXX Use DTR INSTEAD???? */
if (SX_CRTSCTS(tty)) {
@@
-2234,14
+2203,14
@@
static void sx_stop(struct tty_struct * tty)
unsigned long flags;
func_enter();
unsigned long flags;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_stop")) {
func_exit();
return;
}
bp = port_Board(port);
if (sx_paranoia_check(port, tty->name, "sx_stop")) {
func_exit();
return;
}
bp = port_Board(port);
-
+
spin_lock_irqsave(&port->lock, flags);
port->IER &= ~IER_TXRDY;
spin_lock_irqsave(&bp->lock, flags);
spin_lock_irqsave(&port->lock, flags);
port->IER &= ~IER_TXRDY;
spin_lock_irqsave(&bp->lock, flags);
@@
-2261,14
+2230,14
@@
static void sx_start(struct tty_struct * tty)
unsigned long flags;
func_enter();
unsigned long flags;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_start")) {
func_exit();
return;
}
if (sx_paranoia_check(port, tty->name, "sx_start")) {
func_exit();
return;
}
-
+
bp = port_Board(port);
bp = port_Board(port);
-
+
spin_lock_irqsave(&port->lock, flags);
if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
port->IER |= IER_TXRDY;
spin_lock_irqsave(&port->lock, flags);
if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
port->IER |= IER_TXRDY;
@@
-2290,13
+2259,14
@@
static void sx_start(struct tty_struct * tty)
*
* serial interrupt routine -> (workqueue) ->
* do_sx_hangup() -> tty->hangup() -> sx_hangup()
*
* serial interrupt routine -> (workqueue) ->
* do_sx_hangup() -> tty->hangup() -> sx_hangup()
- *
+ *
*/
*/
-static void do_sx_hangup(
void *private_
)
+static void do_sx_hangup(
struct work_struct *work
)
{
{
- struct specialix_port *port = (struct specialix_port *) private_;
+ struct specialix_port *port =
+ container_of(work, struct specialix_port, tqueue_hangup);
struct tty_struct *tty;
struct tty_struct *tty;
-
+
func_enter();
tty = port->tty;
func_enter();
tty = port->tty;
@@
-2319,9
+2289,9
@@
static void sx_hangup(struct tty_struct * tty)
func_exit();
return;
}
func_exit();
return;
}
-
+
bp = port_Board(port);
bp = port_Board(port);
-
+
sx_shutdown_port(bp, port);
spin_lock_irqsave(&port->lock, flags);
port->event = 0;
sx_shutdown_port(bp, port);
spin_lock_irqsave(&port->lock, flags);
port->event = 0;
@@
-2341,15
+2311,15
@@
static void sx_hangup(struct tty_struct * tty)
}
}
-static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
+static void sx_set_termios(struct tty_struct * tty, struct
k
termios * old_termios)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags;
struct specialix_board * bp;
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags;
struct specialix_board * bp;
-
+
if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
return;
if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
return;
-
+
if (tty->termios->c_cflag == old_termios->c_cflag &&
tty->termios->c_iflag == old_termios->c_iflag)
return;
if (tty->termios->c_cflag == old_termios->c_cflag &&
tty->termios->c_iflag == old_termios->c_iflag)
return;
@@
-2367,9
+2337,10
@@
static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios
}
}
-static void do_softint(
void *private_
)
+static void do_softint(
struct work_struct *work
)
{
{
- struct specialix_port *port = (struct specialix_port *) private_;
+ struct specialix_port *port =
+ container_of(work, struct specialix_port, tqueue);
struct tty_struct *tty;
func_enter();
struct tty_struct *tty;
func_enter();
@@
-2387,7
+2358,7
@@
static void do_softint(void *private_)
func_exit();
}
func_exit();
}
-static struct tty_operations sx_ops = {
+static
const
struct tty_operations sx_ops = {
.open = sx_open,
.close = sx_close,
.write = sx_write,
.open = sx_open,
.close = sx_close,
.write = sx_write,
@@
-2420,13
+2391,7
@@
static int sx_init_drivers(void)
func_exit();
return 1;
}
func_exit();
return 1;
}
-
- if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
- printk(KERN_ERR "sx: Couldn't get free page.\n");
- put_tty_driver(specialix_driver);
- func_exit();
- return 1;
- }
+
specialix_driver->owner = THIS_MODULE;
specialix_driver->name = "ttyW";
specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
specialix_driver->owner = THIS_MODULE;
specialix_driver->name = "ttyW";
specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
@@
-2435,12
+2400,13
@@
static int sx_init_drivers(void)
specialix_driver->init_termios = tty_std_termios;
specialix_driver->init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
specialix_driver->init_termios = tty_std_termios;
specialix_driver->init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ specialix_driver->init_termios.c_ispeed = 9600;
+ specialix_driver->init_termios.c_ospeed = 9600;
specialix_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(specialix_driver, &sx_ops);
if ((error = tty_register_driver(specialix_driver))) {
put_tty_driver(specialix_driver);
specialix_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(specialix_driver, &sx_ops);
if ((error = tty_register_driver(specialix_driver))) {
put_tty_driver(specialix_driver);
- free_page((unsigned long)tmp_buf);
printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
error);
func_exit();
printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
error);
func_exit();
@@
-2449,15
+2415,15
@@
static int sx_init_drivers(void)
memset(sx_port, 0, sizeof(sx_port));
for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
sx_port[i].magic = SPECIALIX_MAGIC;
memset(sx_port, 0, sizeof(sx_port));
for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
sx_port[i].magic = SPECIALIX_MAGIC;
- INIT_WORK(&sx_port[i].tqueue, do_softint
, &sx_port[i]
);
- INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup
, &sx_port[i]
);
+ INIT_WORK(&sx_port[i].tqueue, do_softint);
+ INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup);
sx_port[i].close_delay = 50 * HZ/100;
sx_port[i].closing_wait = 3000 * HZ/100;
init_waitqueue_head(&sx_port[i].open_wait);
init_waitqueue_head(&sx_port[i].close_wait);
spin_lock_init(&sx_port[i].lock);
}
sx_port[i].close_delay = 50 * HZ/100;
sx_port[i].closing_wait = 3000 * HZ/100;
init_waitqueue_head(&sx_port[i].open_wait);
init_waitqueue_head(&sx_port[i].close_wait);
spin_lock_init(&sx_port[i].lock);
}
-
+
func_exit();
return 0;
}
func_exit();
return 0;
}
@@
-2466,14
+2432,13
@@
static void sx_release_drivers(void)
{
func_enter();
{
func_enter();
- free_page((unsigned long)tmp_buf);
tty_unregister_driver(specialix_driver);
put_tty_driver(specialix_driver);
func_exit();
}
tty_unregister_driver(specialix_driver);
put_tty_driver(specialix_driver);
func_exit();
}
-/*
- * This routine must be called by kernel at boot time
+/*
+ * This routine must be called by kernel at boot time
*/
static int __init specialix_init(void)
{
*/
static int __init specialix_init(void)
{
@@
-2489,16
+2454,16
@@
static int __init specialix_init(void)
#else
printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
#endif
#else
printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
#endif
-
+
for (i = 0; i < SX_NBOARD; i++)
for (i = 0; i < SX_NBOARD; i++)
- s
x_board[i].lock = SPIN_LOCK_UNLOCKED
;
+ s
pin_lock_init(&sx_board[i].lock)
;
if (sx_init_drivers()) {
func_exit();
return -EIO;
}
if (sx_init_drivers()) {
func_exit();
return -EIO;
}
- for (i = 0; i < SX_NBOARD; i++)
+ for (i = 0; i < SX_NBOARD; i++)
if (sx_board[i].base && !sx_probe(&sx_board[i]))
found++;
if (sx_board[i].base && !sx_probe(&sx_board[i]))
found++;
@@
-2512,8
+2477,8
@@
static int __init specialix_init(void)
i++;
continue;
}
i++;
continue;
}
- pdev = pci_
find_device (PCI_VENDOR_ID_SPECIALIX,
- PCI_DEVICE_ID_SPECIALIX_IO8,
+ pdev = pci_
get_device (PCI_VENDOR_ID_SPECIALIX,
+ PCI_DEVICE_ID_SPECIALIX_IO8,
pdev);
if (!pdev) break;
pdev);
if (!pdev) break;
@@
-2528,6
+2493,9
@@
static int __init specialix_init(void)
if (!sx_probe(&sx_board[i]))
found ++;
}
if (!sx_probe(&sx_board[i]))
found ++;
}
+ /* May exit pci_get sequence early with lots of boards */
+ if (pdev != NULL)
+ pci_dev_put(pdev);
}
#endif
}
#endif
@@
-2557,10
+2525,10
@@
module_param(sx_poll, int, 0);
/*
* You can setup up to 4 boards.
* by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
/*
* You can setup up to 4 boards.
* by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
- * You should specify the IRQs too in that case "irq=....,...".
- *
+ * You should specify the IRQs too in that case "irq=....,...".
+ *
* More than 4 boards in one computer is not possible, as the card can
* More than 4 boards in one computer is not possible, as the card can
- * only use 4 different interrupts.
+ * only use 4 different interrupts.
*
*/
static int __init specialix_init_module(void)
*
*/
static int __init specialix_init_module(void)
@@
-2569,8
+2537,6
@@
static int __init specialix_init_module(void)
func_enter();
func_enter();
- init_MUTEX(&tmp_buf_sem); /* Init de the semaphore - pvdl */
-
if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
for(i = 0; i < SX_NBOARD; i++) {
sx_board[i].base = iobase[i];
if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
for(i = 0; i < SX_NBOARD; i++) {
sx_board[i].base = iobase[i];
@@
-2583,16
+2549,16
@@
static int __init specialix_init_module(void)
return specialix_init();
}
return specialix_init();
}
-
+
static void __exit specialix_exit_module(void)
{
int i;
static void __exit specialix_exit_module(void)
{
int i;
-
+
func_enter();
sx_release_drivers();
for (i = 0; i < SX_NBOARD; i++)
func_enter();
sx_release_drivers();
for (i = 0; i < SX_NBOARD; i++)
- if (sx_board[i].flags & SX_BOARD_PRESENT)
+ if (sx_board[i].flags & SX_BOARD_PRESENT)
sx_release_io_range(&sx_board[i]);
#ifdef SPECIALIX_TIMER
del_timer (&missed_irq_timer);
sx_release_io_range(&sx_board[i]);
#ifdef SPECIALIX_TIMER
del_timer (&missed_irq_timer);
@@
-2601,6
+2567,12
@@
static void __exit specialix_exit_module(void)
func_exit();
}
func_exit();
}
+static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
+ { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
+ { }
+};
+MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
+
module_init(specialix_init_module);
module_exit(specialix_exit_module);
module_init(specialix_init_module);
module_exit(specialix_exit_module);