Re-introduced ecdev_open() and ecdev_close(), to avoid a race condition regarding the link state.
authorFlorian Pose <fp@igh-essen.com>
Fri, 08 Dec 2006 11:39:56 +0000
changeset 497 04552130dd54
parent 496 b2aee2241952
child 498 fbf44b0d6b54
Re-introduced ecdev_open() and ecdev_close(), to avoid a race condition regarding the link state.
NEWS
devices/8139too-2.6.13-ethercat.c
devices/8139too-2.6.17-ethercat.c
devices/ecdev.h
master/module.c
--- a/NEWS	Fri Nov 24 11:09:36 2006 +0000
+++ b/NEWS	Fri Dec 08 11:39:56 2006 +0000
@@ -13,8 +13,8 @@
   ecrt_master_release().
 * Removed ecrt_master_prepare(). Its functionality was moved into
   ecrt_master_activate().
-* Removed ecdev_start() and ecdev_stop(). Their functionality was moved into
-  ecdev_register() and ecdev_unregister, respectively.
+* Renamed ecdev_start() and ecdev_stop() to ecdev_open() and ecdev_close().
+  These two functions now take a pointer to ec_device_t as their arguments.
 * The data_ptr parameter of ecrt_domain_register_pdo(),
   ecrt_domain_register_pdo_list() and ecrt_domain_register_pdo_range() may
   not be NULL any more.
--- a/devices/8139too-2.6.13-ethercat.c	Fri Nov 24 11:09:36 2006 +0000
+++ b/devices/8139too-2.6.13-ethercat.c	Fri Dec 08 11:39:56 2006 +0000
@@ -2907,12 +2907,24 @@
 			printk(KERN_ERR "Failed to register EtherCAT device!\n");
 			goto out_pci;
 		}
+
+		printk(KERN_INFO "Opening EtherCAT device...\n");
+		if (ecdev_open(rtl_ec_dev)) {
+			printk(KERN_ERR "Failed to open EtherCAT device!\n");
+			goto out_unregister;
+		}
+
+		printk(KERN_INFO "EtherCAT device ready.\n");
 	} else {
 		printk(KERN_WARNING "No EtherCAT device registered!\n");
 	}
 
 	return 0;
 
+    out_unregister:
+	printk(KERN_INFO "Unregistering EtherCAT device...\n");
+	ecdev_unregister(ec_device_master_index, rtl_ec_dev);
+	rtl_ec_dev = NULL;
     out_pci:
 	pci_unregister_driver(&rtl8139_pci_driver);
     out_return:
@@ -2929,7 +2941,9 @@
 	printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
 
 	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Unregistering device...\n");
+		printk(KERN_INFO "Closing EtherCAT device...\n");
+		ecdev_close(rtl_ec_dev);
+		printk(KERN_INFO "Unregistering EtherCAT device...\n");
 		ecdev_unregister(ec_device_master_index, rtl_ec_dev);
 		rtl_ec_dev = NULL;
 	}
--- a/devices/8139too-2.6.17-ethercat.c	Fri Nov 24 11:09:36 2006 +0000
+++ b/devices/8139too-2.6.17-ethercat.c	Fri Dec 08 11:39:56 2006 +0000
@@ -2905,12 +2905,24 @@
 			printk(KERN_ERR "Failed to register EtherCAT device!\n");
 			goto out_pci;
 		}
+
+		printk(KERN_INFO "Opening EtherCAT device...\n");
+		if (ecdev_open(rtl_ec_dev)) {
+			printk(KERN_ERR "Failed to open EtherCAT device!\n");
+			goto out_unregister;
+		}
+
+		printk(KERN_INFO "EtherCAT device ready.\n");
 	} else {
 		printk(KERN_WARNING "No EtherCAT device registered!\n");
 	}
 
 	return 0;
 
+    out_unregister:
+	printk(KERN_INFO "Unregistering EtherCAT device...\n");
+	ecdev_unregister(ec_device_master_index, rtl_ec_dev);
+	rtl_ec_dev = NULL;
     out_pci:
 	pci_unregister_driver(&rtl8139_pci_driver);
     out_return:
@@ -2927,7 +2939,9 @@
 	printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
 
 	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Unregistering device...\n");
+		printk(KERN_INFO "Closing EtherCAT device...\n");
+		ecdev_close(rtl_ec_dev);
+		printk(KERN_INFO "Unregistering EtherCAT device...\n");
 		ecdev_unregister(ec_device_master_index, rtl_ec_dev);
 		rtl_ec_dev = NULL;
 	}
--- a/devices/ecdev.h	Fri Nov 24 11:09:36 2006 +0000
+++ b/devices/ecdev.h	Fri Dec 08 11:39:56 2006 +0000
@@ -74,6 +74,8 @@
 /*****************************************************************************/
 // Device methods
 
+int ecdev_open(ec_device_t *device);
+int ecdev_close(ec_device_t *device);
 void ecdev_receive(ec_device_t *device, const void *data, size_t size);
 void ecdev_link_state(ec_device_t *device, uint8_t newstate);
 
--- a/master/module.c	Fri Nov 24 11:09:36 2006 +0000
+++ b/master/module.c	Fri Dec 08 11:39:56 2006 +0000
@@ -311,19 +311,9 @@
         goto out_free;
     }
 
-    if (ec_device_open(master->device)) {
-        EC_ERR("Failed to open device!\n");
-        goto out_clear;
-    }
-
     up(&master->device_sem);
-
-    ec_master_enter_idle_mode(master);
-
     return master->device;
 
- out_clear:
-    ec_device_clear(master->device);
  out_free:
     kfree(master->device);
     master->device = NULL;
@@ -352,11 +342,6 @@
 
     if (!(master = ec_find_master(master_index))) return;
 
-    ec_master_leave_idle_mode(master);
-
-    if (ec_device_close(master->device))
-        EC_WARN("Failed to close device!\n");
-
     down(&master->device_sem);
 
     if (!master->device || master->device != device) {
@@ -372,6 +357,41 @@
     up(&master->device_sem);
 }
 
+/*****************************************************************************/
+
+/**
+   Opens the network device and makes the master enter IDLE mode.
+   \return 0 on success, else < 0
+   \ingroup DeviceInterface
+*/
+
+int ecdev_open(ec_device_t *device /**< EtherCAT device */)
+{
+    if (ec_device_open(device)) {
+        EC_ERR("Failed to open device!\n");
+        return -1;
+    }
+
+    ec_master_enter_idle_mode(device->master);
+    return 0;
+}
+
+/*****************************************************************************/
+
+/**
+   Makes the master leave IDLE mode and closes the network device.
+   \return 0 on success, else < 0
+   \ingroup DeviceInterface
+*/
+
+void ecdev_close(ec_device_t *device /**< EtherCAT device */)
+{
+    ec_master_leave_idle_mode(device->master);
+
+    if (ec_device_close(device))
+        EC_WARN("Failed to close device!\n");
+}
+
 /******************************************************************************
  *  Realtime interface
  *****************************************************************************/
@@ -465,6 +485,8 @@
 
 EXPORT_SYMBOL(ecdev_register);
 EXPORT_SYMBOL(ecdev_unregister);
+EXPORT_SYMBOL(ecdev_open);
+EXPORT_SYMBOL(ecdev_close);
 EXPORT_SYMBOL(ecrt_request_master);
 EXPORT_SYMBOL(ecrt_release_master);