diff --git a/TODO b/TODO index 6ecac12417144a8057016ad789988de406b7574e..1b6223bb647d6a4210039ac63d0e830f98645426 100644 --- a/TODO +++ b/TODO @@ -10,7 +10,6 @@ Version 1.4.0: * Update documentation. * Check for possible race condition in jiffy-based frame timeout calculation. -* Use down_interruptible() for cdev calls. Future issues: diff --git a/master/cdev.c b/master/cdev.c index bc06346db1494158ee24205d97ab9337df3514f9..dda8ab188de45623535173dd055cf6a127e9268a 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -127,14 +127,16 @@ int ec_cdev_ioctl_master( { ec_ioctl_master_t data; - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; data.slave_count = master->slave_count; data.config_count = ec_master_config_count(master); data.domain_count = ec_master_domain_count(master); data.phase = (uint8_t) master->phase; up(&master->master_sem); - down(&master->device_sem); + if (down_interruptible(&master->device_sem)) + return -EINTR; if (master->main_device.dev) { memcpy(data.devices[0].address, master->main_device.dev->dev_addr, ETH_ALEN); @@ -178,7 +180,8 @@ int ec_cdev_ioctl_slave( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(slave = ec_master_find_slave_const( master, 0, data.position))) { @@ -237,7 +240,8 @@ int ec_cdev_ioctl_slave_sync( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(slave = ec_master_find_slave_const( master, 0, data.slave_position))) { @@ -287,7 +291,8 @@ int ec_cdev_ioctl_slave_sync_pdo( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(slave = ec_master_find_slave_const( master, 0, data.slave_position))) { @@ -344,7 +349,8 @@ int ec_cdev_ioctl_slave_sync_pdo_entry( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(slave = ec_master_find_slave_const( master, 0, data.slave_position))) { @@ -408,7 +414,8 @@ int ec_cdev_ioctl_domain( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(domain = ec_master_find_domain_const(master, data.index))) { up(&master->master_sem); @@ -447,7 +454,8 @@ int ec_cdev_ioctl_domain_fmmu( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(domain = ec_master_find_domain_const(master, data.domain_index))) { up(&master->master_sem); @@ -493,7 +501,8 @@ int ec_cdev_ioctl_domain_data( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(domain = ec_master_find_domain_const(master, data.domain_index))) { up(&master->master_sem); @@ -547,7 +556,8 @@ int ec_cdev_ioctl_slave_state( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(slave = ec_master_find_slave( master, 0, data.slave_position))) { @@ -578,7 +588,8 @@ int ec_cdev_ioctl_slave_sdo( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(slave = ec_master_find_slave_const( master, 0, data.slave_position))) { @@ -625,7 +636,8 @@ int ec_cdev_ioctl_slave_sdo_entry( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(slave = ec_master_find_slave_const( master, 0, data.slave_position))) { @@ -695,7 +707,8 @@ int ec_cdev_ioctl_slave_sdo_upload( data.sdo_index, data.sdo_entry_subindex); ecrt_sdo_request_read(&request.req); - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(request.slave = ec_master_find_slave( master, 0, data.slave_position))) { @@ -796,7 +809,8 @@ int ec_cdev_ioctl_slave_sdo_download( ecrt_sdo_request_write(&request.req); - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(request.slave = ec_master_find_slave( master, 0, data.slave_position))) { @@ -858,7 +872,8 @@ int ec_cdev_ioctl_slave_sii_read( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(slave = ec_master_find_slave_const( master, 0, data.slave_position))) { @@ -921,7 +936,8 @@ int ec_cdev_ioctl_slave_sii_write( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(slave = ec_master_find_slave( master, 0, data.slave_position))) { @@ -984,7 +1000,8 @@ int ec_cdev_ioctl_config( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(sc = ec_master_get_config_const( master, data.config_index))) { @@ -1037,7 +1054,8 @@ int ec_cdev_ioctl_config_pdo( return -EINVAL; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(sc = ec_master_get_config_const( master, data.config_index))) { @@ -1091,7 +1109,8 @@ int ec_cdev_ioctl_config_pdo_entry( return -EINVAL; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(sc = ec_master_get_config_const( master, data.config_index))) { @@ -1146,7 +1165,8 @@ int ec_cdev_ioctl_config_sdo( return -EFAULT; } - down(&master->master_sem); + if (down_interruptible(&master->master_sem)) + return -EINTR; if (!(sc = ec_master_get_config_const( master, data.config_index))) { diff --git a/master/module.c b/master/module.c index f5d21ae2366a2606711294257562c0efdc22b7da..4651ff7387ea9b4b80338cb0bc5774781da9b728 100644 --- a/master/module.c +++ b/master/module.c @@ -473,7 +473,9 @@ ec_master_t *ecrt_request_master(unsigned int master_index) } master = &masters[master_index]; - down(&master_sem); + if (down_interruptible(&master_sem)) + goto out_return; + if (master->reserved) { up(&master_sem); EC_ERR("Master %u is already in use!\n", master_index); @@ -482,7 +484,8 @@ ec_master_t *ecrt_request_master(unsigned int master_index) master->reserved = 1; up(&master_sem); - down(&master->device_sem); + if (down_interruptible(&master->device_sem)) + goto out_release; if (master->phase != EC_IDLE) { up(&master->device_sem);