Re-introduced ecdev_open() and ecdev_close(), to avoid a race condition regarding the link state.

This commit is contained in:
Florian Pose 2006-12-08 11:39:56 +00:00
parent b3de249e28
commit 3f8978f998
5 changed files with 71 additions and 19 deletions

4
NEWS
View File

@ -13,8 +13,8 @@ Changes in version 1.2.0:
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.

View File

@ -2907,12 +2907,24 @@ static int __init rtl8139_init_module (void)
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 @@ static void __exit rtl8139_cleanup_module (void)
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;
}

View File

@ -2905,12 +2905,24 @@ static int __init rtl8139_init_module (void)
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 @@ static void __exit rtl8139_cleanup_module (void)
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;
}

View File

@ -74,6 +74,8 @@ void ecdev_unregister(unsigned int master_index, ec_device_t *device);
/*****************************************************************************/
// 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);

View File

@ -311,19 +311,9 @@ ec_device_t *ecdev_register(unsigned int master_index, /**< master index */
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 @@ void ecdev_unregister(unsigned int master_index, /**< master index */
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 @@ void ecdev_unregister(unsigned int master_index, /**< master index */
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 @@ module_exit(ec_cleanup_module);
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);