2274 return ret; |
2274 return ret; |
2275 } |
2275 } |
2276 |
2276 |
2277 /*****************************************************************************/ |
2277 /*****************************************************************************/ |
2278 |
2278 |
|
2279 /** Set the emergency ring buffer size. |
|
2280 */ |
|
2281 static int ec_ioctl_sc_emerg_size( |
|
2282 ec_master_t *master, /**< EtherCAT master. */ |
|
2283 void *arg, /**< ioctl() argument. */ |
|
2284 ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ |
|
2285 ) |
|
2286 { |
|
2287 ec_ioctl_sc_emerg_t io; |
|
2288 ec_slave_config_t *sc; |
|
2289 int ret; |
|
2290 |
|
2291 if (unlikely(!ctx->requested)) |
|
2292 return -EPERM; |
|
2293 |
|
2294 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) |
|
2295 return -EFAULT; |
|
2296 |
|
2297 if (down_interruptible(&master->master_sem)) { |
|
2298 return -EINTR; |
|
2299 } |
|
2300 |
|
2301 if (!(sc = ec_master_get_config(master, io.config_index))) { |
|
2302 up(&master->master_sem); |
|
2303 return -ENOENT; |
|
2304 } |
|
2305 |
|
2306 ret = ecrt_slave_config_emerg_size(sc, io.size); |
|
2307 |
|
2308 up(&master->master_sem); |
|
2309 |
|
2310 return ret; |
|
2311 } |
|
2312 |
|
2313 /*****************************************************************************/ |
|
2314 |
|
2315 /** Get an emergency message from the ring. |
|
2316 */ |
|
2317 static int ec_ioctl_sc_emerg_pop( |
|
2318 ec_master_t *master, /**< EtherCAT master. */ |
|
2319 void *arg, /**< ioctl() argument. */ |
|
2320 ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ |
|
2321 ) |
|
2322 { |
|
2323 ec_ioctl_sc_emerg_t io; |
|
2324 ec_slave_config_t *sc; |
|
2325 u8 msg[EC_COE_EMERGENCY_MSG_SIZE]; |
|
2326 int ret; |
|
2327 |
|
2328 if (unlikely(!ctx->requested)) |
|
2329 return -EPERM; |
|
2330 |
|
2331 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) |
|
2332 return -EFAULT; |
|
2333 |
|
2334 if (down_interruptible(&master->master_sem)) { |
|
2335 return -EINTR; |
|
2336 } |
|
2337 |
|
2338 if (!(sc = ec_master_get_config(master, io.config_index))) { |
|
2339 up(&master->master_sem); |
|
2340 return -ENOENT; |
|
2341 } |
|
2342 |
|
2343 ret = ecrt_slave_config_emerg_pop(sc, msg); |
|
2344 |
|
2345 up(&master->master_sem); |
|
2346 |
|
2347 if (ret < 0) { |
|
2348 return ret; |
|
2349 } |
|
2350 |
|
2351 if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) { |
|
2352 return -EFAULT; |
|
2353 } |
|
2354 |
|
2355 return ret; |
|
2356 } |
|
2357 |
|
2358 /*****************************************************************************/ |
|
2359 |
|
2360 /** Clear the emergency ring. |
|
2361 */ |
|
2362 static int ec_ioctl_sc_emerg_clear( |
|
2363 ec_master_t *master, /**< EtherCAT master. */ |
|
2364 void *arg, /**< ioctl() argument. */ |
|
2365 ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ |
|
2366 ) |
|
2367 { |
|
2368 ec_ioctl_sc_emerg_t io; |
|
2369 ec_slave_config_t *sc; |
|
2370 int ret; |
|
2371 |
|
2372 if (unlikely(!ctx->requested)) |
|
2373 return -EPERM; |
|
2374 |
|
2375 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) |
|
2376 return -EFAULT; |
|
2377 |
|
2378 if (down_interruptible(&master->master_sem)) { |
|
2379 return -EINTR; |
|
2380 } |
|
2381 |
|
2382 if (!(sc = ec_master_get_config(master, io.config_index))) { |
|
2383 up(&master->master_sem); |
|
2384 return -ENOENT; |
|
2385 } |
|
2386 |
|
2387 ret = ecrt_slave_config_emerg_clear(sc); |
|
2388 |
|
2389 up(&master->master_sem); |
|
2390 |
|
2391 return ret; |
|
2392 } |
|
2393 |
|
2394 /*****************************************************************************/ |
|
2395 |
|
2396 /** Get the number of emergency overruns. |
|
2397 */ |
|
2398 static int ec_ioctl_sc_emerg_overruns( |
|
2399 ec_master_t *master, /**< EtherCAT master. */ |
|
2400 void *arg, /**< ioctl() argument. */ |
|
2401 ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ |
|
2402 ) |
|
2403 { |
|
2404 ec_ioctl_sc_emerg_t io; |
|
2405 ec_slave_config_t *sc; |
|
2406 int ret; |
|
2407 |
|
2408 if (unlikely(!ctx->requested)) |
|
2409 return -EPERM; |
|
2410 |
|
2411 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) |
|
2412 return -EFAULT; |
|
2413 |
|
2414 if (down_interruptible(&master->master_sem)) { |
|
2415 return -EINTR; |
|
2416 } |
|
2417 |
|
2418 if (!(sc = ec_master_get_config(master, io.config_index))) { |
|
2419 up(&master->master_sem); |
|
2420 return -ENOENT; |
|
2421 } |
|
2422 |
|
2423 ret = ecrt_slave_config_emerg_overruns(sc); |
|
2424 |
|
2425 up(&master->master_sem); |
|
2426 |
|
2427 if (ret < 0) { |
|
2428 return ret; |
|
2429 } |
|
2430 |
|
2431 io.overruns = ret; |
|
2432 |
|
2433 if (copy_to_user((void __user *) arg, &io, sizeof(io))) { |
|
2434 return -EFAULT; |
|
2435 } |
|
2436 |
|
2437 return 0; |
|
2438 } |
|
2439 |
|
2440 /*****************************************************************************/ |
|
2441 |
2279 /** Create an SDO request. |
2442 /** Create an SDO request. |
2280 */ |
2443 */ |
2281 static int ec_ioctl_sc_create_sdo_request( |
2444 static int ec_ioctl_sc_create_sdo_request( |
2282 ec_master_t *master, /**< EtherCAT master. */ |
2445 ec_master_t *master, /**< EtherCAT master. */ |
2283 void *arg, /**< ioctl() argument. */ |
2446 void *arg, /**< ioctl() argument. */ |
3676 ret = -EPERM; |
3839 ret = -EPERM; |
3677 break; |
3840 break; |
3678 } |
3841 } |
3679 ret = ec_ioctl_sc_sdo(master, arg, ctx); |
3842 ret = ec_ioctl_sc_sdo(master, arg, ctx); |
3680 break; |
3843 break; |
|
3844 case EC_IOCTL_SC_EMERG_SIZE: |
|
3845 if (!ctx->writable) { |
|
3846 ret = -EPERM; |
|
3847 break; |
|
3848 } |
|
3849 ret = ec_ioctl_sc_emerg_size(master, arg, ctx); |
|
3850 break; |
|
3851 case EC_IOCTL_SC_EMERG_POP: |
|
3852 if (!ctx->writable) { |
|
3853 ret = -EPERM; |
|
3854 break; |
|
3855 } |
|
3856 ret = ec_ioctl_sc_emerg_pop(master, arg, ctx); |
|
3857 break; |
|
3858 case EC_IOCTL_SC_EMERG_CLEAR: |
|
3859 if (!ctx->writable) { |
|
3860 ret = -EPERM; |
|
3861 break; |
|
3862 } |
|
3863 ret = ec_ioctl_sc_emerg_clear(master, arg, ctx); |
|
3864 break; |
|
3865 case EC_IOCTL_SC_EMERG_OVERRUNS: |
|
3866 if (!ctx->writable) { |
|
3867 ret = -EPERM; |
|
3868 break; |
|
3869 } |
|
3870 ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx); |
|
3871 break; |
3681 case EC_IOCTL_SC_SDO_REQUEST: |
3872 case EC_IOCTL_SC_SDO_REQUEST: |
3682 if (!ctx->writable) { |
3873 if (!ctx->writable) { |
3683 ret = -EPERM; |
3874 ret = -EPERM; |
3684 break; |
3875 break; |
3685 } |
3876 } |