542 |
542 |
543 data.slave_config_alias = fmmu->sc->alias; |
543 data.slave_config_alias = fmmu->sc->alias; |
544 data.slave_config_position = fmmu->sc->position; |
544 data.slave_config_position = fmmu->sc->position; |
545 data.sync_index = fmmu->sync_index; |
545 data.sync_index = fmmu->sync_index; |
546 data.dir = fmmu->dir; |
546 data.dir = fmmu->dir; |
547 data.logical_address = fmmu->logical_start_address; |
547 data.logical_address = fmmu->domain->logical_base_address + fmmu->logical_domain_offset; |
548 data.data_size = fmmu->data_size; |
548 data.data_size = fmmu->data_size; |
549 |
549 |
550 up(&master->master_sem); |
550 up(&master->master_sem); |
551 |
551 |
552 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
552 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
862 EC_MASTER_ERR(master, "Failed to allocate %zu bytes" |
862 EC_MASTER_ERR(master, "Failed to allocate %zu bytes" |
863 " for SDO download.\n", data.data_size); |
863 " for SDO download.\n", data.data_size); |
864 return -ENOMEM; |
864 return -ENOMEM; |
865 } |
865 } |
866 |
866 |
867 if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) { |
867 if (copy_from_user(sdo_data, (const void __user *) data.data, data.data_size)) { |
868 kfree(sdo_data); |
868 kfree(sdo_data); |
869 return -EFAULT; |
869 return -EFAULT; |
870 } |
870 } |
871 |
871 |
872 if (data.complete_access) { |
872 if (data.complete_access) { |
1911 ec_master_t *master, /**< EtherCAT master. */ |
1911 ec_master_t *master, /**< EtherCAT master. */ |
1912 void *arg, /**< ioctl() argument. */ |
1912 void *arg, /**< ioctl() argument. */ |
1913 ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ |
1913 ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ |
1914 ) |
1914 ) |
1915 { |
1915 { |
|
1916 size_t sent_bytes; |
|
1917 |
1916 if (unlikely(!ctx->requested)) { |
1918 if (unlikely(!ctx->requested)) { |
1917 return -EPERM; |
1919 return -EPERM; |
1918 } |
1920 } |
1919 |
1921 |
1920 ecrt_master_send(master); |
1922 sent_bytes = ecrt_master_send(master); |
|
1923 |
|
1924 if (copy_to_user((void __user *) arg, &sent_bytes, sizeof(sent_bytes))) { |
|
1925 return -EFAULT; |
|
1926 } |
|
1927 |
1921 return 0; |
1928 return 0; |
1922 } |
1929 } |
1923 |
1930 |
1924 /*****************************************************************************/ |
1931 /*****************************************************************************/ |
1925 |
1932 |
2250 up(&master->master_sem); |
2257 up(&master->master_sem); |
2251 out_return: |
2258 out_return: |
2252 return ret; |
2259 return ret; |
2253 } |
2260 } |
2254 |
2261 |
|
2262 /*****************************************************************************/ |
|
2263 |
|
2264 /** Configure wether a slave allows overlapping PDOs. |
|
2265 */ |
|
2266 static ATTRIBUTES int ec_ioctl_sc_allow_overlapping_pdos( |
|
2267 ec_master_t *master, /**< EtherCAT master. */ |
|
2268 void *arg, /**< ioctl() argument. */ |
|
2269 ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ |
|
2270 ) |
|
2271 { |
|
2272 ec_ioctl_config_t data; |
|
2273 ec_slave_config_t *sc; |
|
2274 int ret = 0; |
|
2275 |
|
2276 if (unlikely(!ctx->requested)) { |
|
2277 ret = -EPERM; |
|
2278 goto out_return; |
|
2279 } |
|
2280 |
|
2281 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
|
2282 ret = -EFAULT; |
|
2283 goto out_return; |
|
2284 } |
|
2285 |
|
2286 if (down_interruptible(&master->master_sem)) { |
|
2287 ret = -EINTR; |
|
2288 goto out_return; |
|
2289 } |
|
2290 |
|
2291 if (!(sc = ec_master_get_config(master, data.config_index))) { |
|
2292 ret = -ENOENT; |
|
2293 goto out_up; |
|
2294 } |
|
2295 |
|
2296 ecrt_slave_config_overlapping_pdos(sc, |
|
2297 data.allow_overlapping_pdos); |
|
2298 |
|
2299 out_up: |
|
2300 up(&master->master_sem); |
|
2301 out_return: |
|
2302 return ret; |
|
2303 } |
2255 /*****************************************************************************/ |
2304 /*****************************************************************************/ |
2256 |
2305 |
2257 /** Add a PDO to the assignment. |
2306 /** Add a PDO to the assignment. |
2258 * |
2307 * |
2259 * \return Zero on success, otherwise a negative error code. |
2308 * \return Zero on success, otherwise a negative error code. |
4445 ret = -EPERM; |
4494 ret = -EPERM; |
4446 break; |
4495 break; |
4447 } |
4496 } |
4448 ret = ec_ioctl_sc_watchdog(master, arg, ctx); |
4497 ret = ec_ioctl_sc_watchdog(master, arg, ctx); |
4449 break; |
4498 break; |
|
4499 case EC_IOCTL_SC_OVERLAPPING_IO: |
|
4500 if (!ctx->writable) { |
|
4501 ret = -EPERM; |
|
4502 break; |
|
4503 } |
|
4504 ret = ec_ioctl_sc_allow_overlapping_pdos(master, arg, ctx); |
|
4505 break; |
4450 case EC_IOCTL_SC_ADD_PDO: |
4506 case EC_IOCTL_SC_ADD_PDO: |
4451 if (!ctx->writable) { |
4507 if (!ctx->writable) { |
4452 ret = -EPERM; |
4508 ret = -EPERM; |
4453 break; |
4509 break; |
4454 } |
4510 } |