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

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)