patch-2.2.17 linux/drivers/char/sx.c
Next file: linux/drivers/char/synclink.c
Previous file: linux/drivers/char/rio/unixrup.h
Back to the patch index
Back to the overall index
- Lines: 307
- Date:
Mon Sep 4 18:39:18 2000
- Orig file:
v2.2.16/drivers/char/sx.c
- Orig date:
Mon Sep 4 18:37:32 2000
diff -u --recursive --new-file v2.2.16/drivers/char/sx.c linux/drivers/char/sx.c
@@ -33,7 +33,12 @@
*
* Revision history:
* $Log: sx.c,v $
- * Revision 1.32 2000/03/07 90:00:00 wolff,pvdl
+ * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff
+ * - Fixed module and port counting
+ * - Fixed signal handling
+ * - Fixed an Ooops
+ *
+ * Revision 1.32 2000/03/07 09:00:00 wolff,pvdl
* - Fixed some sx_dprintk typos
* - added detection for an invalid board/module configuration
*
@@ -195,8 +200,8 @@
* */
-#define RCS_ID "$Id: sx.c,v 1.32 2000/03/07 17:01:02 wolff, pvdl Exp $"
-#define RCS_REV "$Revision: 1.32 $"
+#define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $"
+#define RCS_REV "$Revision: 1.33 $"
#include <linux/module.h>
@@ -414,22 +419,9 @@
*/
static struct file_operations sx_fw_fops = {
- NULL, /* lseek */
- NULL, /* read */
- NULL, /* write */
- NULL, /* readdir */
- NULL, /* select */
- sx_fw_ioctl,
- NULL, /* mmap */
- sx_fw_open,
-#ifndef TWO_ZERO
- NULL, /* flush */
-#endif
- sx_fw_release,
- NULL, /* fsync */
- NULL, /* fasync */
- NULL, /* check_media_change */
- NULL, /* revalidate */
+ open: sx_fw_open,
+ release: sx_fw_release,
+ ioctl: sx_fw_ioctl
};
struct miscdevice sx_fw_device = {
@@ -781,6 +773,7 @@
if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS);
sx_write_channel_byte (port, hi_op, t);
sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts);
+
func_exit ();
}
@@ -896,6 +889,9 @@
func_enter2();
+ if (!port->gs.tty)
+ return 0;
+
/* What is this doing here? -- REW
Ha! figured it out. It is to allow you to get DTR active again
if you've dropped it with stty 0. Moved to set_baud, where it
@@ -1032,8 +1028,8 @@
if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail)
c = SERIAL_XMIT_SIZE - port->gs.xmit_tail;
- sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%d) \n",
- c, SERIAL_XMIT_SIZE- port->gs.xmit_tail);
+ sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%ld) \n",
+ c, (long)SERIAL_XMIT_SIZE- port->gs.xmit_tail);
/* If for one reason or another, we can't copy more data, we're done! */
if (c == 0) break;
@@ -1057,14 +1053,13 @@
sx_disable_tx_interrupts (port);
}
- if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+ if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) {
if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
port->gs.tty->ldisc.write_wakeup)
(port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
port->gs.wakeup_chars);
wake_up_interruptible(&port->gs.tty->write_wait);
- wake_up_interruptible(&port->gs.tty->poll_wait);
}
clear_bit (SX_PORT_TRANSMIT_LOCK, &port->locks);
@@ -1084,7 +1079,7 @@
struct tty_struct *tty;
int copied=0;
- /* func_enter2 (); */
+ func_enter2 ();
tty = port->gs.tty;
while (1) {
rx_op = sx_read_channel_byte (port, hi_rxopos);
@@ -1139,7 +1134,7 @@
/* tty_schedule_flip (tty); */
}
- /* func_exit (); */
+ func_exit ();
}
/* Inlined: it is called only once. Remove the inline if you add another
@@ -1309,6 +1304,8 @@
sx_interrupt (0, board, NULL);
+ init_timer(&board->timer);
+
board->timer.expires = jiffies + sx_poll;
add_timer (&board->timer);
func_exit ();
@@ -1404,7 +1401,7 @@
func_enter();
port->gs.flags &= ~ GS_ACTIVE;
- if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) {
+ if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) {
sx_setsignals (port, 0, 0);
sx_reconfigure_port(port);
}
@@ -1421,7 +1418,6 @@
* interface with the rest of the system *
* ********************************************************************** */
-
static int sx_fw_open(struct inode *inode, struct file *filp)
{
func_enter ();
@@ -1440,6 +1436,7 @@
}
+
static int sx_open (struct tty_struct * tty, struct file * filp)
{
struct sx_port *port;
@@ -1467,6 +1464,8 @@
tty->driver_data = port;
port->gs.tty = tty;
+ if (!port->gs.count)
+ MOD_INC_USE_COUNT;
port->gs.count++;
sx_dprintk (SX_DEBUG_OPEN, "starting port\n");
@@ -1478,19 +1477,13 @@
sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n");
if (retval) {
port->gs.count--;
+ if (port->gs.count) MOD_DEC_USE_COUNT;
return retval;
}
port->gs.flags |= GS_ACTIVE;
sx_setsignals (port, 1,1);
- sx_dprintk (SX_DEBUG_OPEN, "before inc_use_count (count=%d.\n",
- port->gs.count);
- if (port->gs.count == 1) {
- MOD_INC_USE_COUNT;
- }
- sx_dprintk (SX_DEBUG_OPEN, "after inc_use_count\n");
-
#if 0
if (sx_debug & SX_DEBUG_OPEN)
my_hd ((unsigned char *)port, sizeof (*port));
@@ -1502,8 +1495,8 @@
if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");
- MOD_DEC_USE_COUNT;
port->gs.count--;
+ if (!port->gs.count) MOD_DEC_USE_COUNT;
return -EIO;
}
@@ -1512,8 +1505,10 @@
retval, port->gs.count);
if (retval) {
- MOD_DEC_USE_COUNT;
- port->gs.count--;
+ /*
+ * Don't lower gs.count here because sx_close() will be called later
+ */
+
return retval;
}
/* tty->low_latency = 1; */
@@ -1545,7 +1540,24 @@
exit minicom. I expect an "oops". -- REW */
static void sx_hungup (void *ptr)
{
+ struct sx_port *port = ptr;
func_enter ();
+
+ /* Don't force the SX card to close. mgetty doesn't like it !!!!!! -- pvdl */
+ /* For some reson we added this code. Don't know why anymore ;-) -- pvdl */
+ /*
+ sx_setsignals (port, 0, 0);
+ sx_reconfigure_port(port);
+ sx_send_command (port, HS_CLOSE, 0, 0);
+
+ if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) {
+ if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) {
+ printk (KERN_ERR
+ "sx: sent the force_close command, but card didn't react\n");
+ } else
+ sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n");
+ }
+ */
MOD_DEC_USE_COUNT;
func_exit ();
}
@@ -1558,6 +1570,9 @@
int to = 5 * HZ;
func_enter ();
+
+ sx_setsignals (port, 0, 0);
+ sx_reconfigure_port(port);
sx_send_command (port, HS_CLOSE, 0, 0);
while (to-- && (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED)) {
@@ -1578,6 +1593,11 @@
sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n",
5 * HZ - to - 1, port->gs.count);
+ if(port->gs.count) {
+ sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count);
+ port->gs.count = 0;
+ }
+
MOD_DEC_USE_COUNT;
func_exit ();
}
@@ -2326,6 +2346,13 @@
#ifdef NEW_WRITE_LOCKING
port->gs.port_write_sem = MUTEX;
#endif
+ /*
+ * Initializing wait queue
+ */
+ /*
+ init_waitqueue_head(&port->gs.open_wait);
+ init_waitqueue_head(&port->gs.close_wait);
+ */
port++;
}
}
@@ -2367,7 +2394,7 @@
return 0;
}
-
+#ifdef MODULE
static void sx_release_drivers(void)
{
func_enter();
@@ -2375,6 +2402,7 @@
tty_unregister_driver(&sx_callout_driver);
func_exit();
}
+#endif
#ifdef TWO_ZERO
#define PDEV unsigned char pci_bus, unsigned pci_fun
@@ -2455,6 +2483,10 @@
while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
pdev))) {
+ /*
+ if (pci_enable_device(pdev))
+ continue;
+ */
#else
for (i=0;i< SX_NBOARDS;i++) {
if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX,
@@ -2490,10 +2522,14 @@
&tint);
else
pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
- &tint);
- board->hw_base = tint & PCI_BASE_ADDRESS_MEM_MASK;
+ &tint);
board->base2 =
board->base = (ulong) ioremap(board->hw_base, WINDOW_LEN (board));
+ if (!board->base) {
+ printk(KERN_ERR "ioremap failed\n");
+ /* XXX handle error */
+ }
+
/* Most of the stuff on the CF board is offset by
0x18000 .... */
if (IS_CF_BOARD (board)) board->base += 0x18000;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)