master/cdev.c
changeset 2029 5ef6507fc77a
parent 2028 55854f070c4a
child 2030 2bd8ad8bf41f
equal deleted inserted replaced
2028:55854f070c4a 2029:5ef6507fc77a
  3268         ec_master_t *master, /**< EtherCAT master. */
  3268         ec_master_t *master, /**< EtherCAT master. */
  3269         unsigned long arg /**< ioctl() argument. */
  3269         unsigned long arg /**< ioctl() argument. */
  3270         )
  3270         )
  3271 {
  3271 {
  3272     ec_ioctl_slave_foe_t data;
  3272     ec_ioctl_slave_foe_t data;
  3273     ec_master_foe_request_t request;
  3273     ec_master_foe_request_t* request;
  3274     int retval;
  3274     int retval;
  3275 
  3275 
  3276     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  3276     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  3277         return -EFAULT;
  3277         return -EFAULT;
  3278     }
  3278     }
  3279 
  3279 
  3280     ec_foe_request_init(&request.req, data.file_name);
  3280     request = kmalloc(sizeof(*request), GFP_KERNEL);
  3281     ec_foe_request_read(&request.req);
  3281     if (!request)
  3282     ec_foe_request_alloc(&request.req, 10000); // FIXME
  3282         return -ENOMEM;
  3283 
  3283     kref_init(&request->refcount);
  3284     if (ec_mutex_lock_interruptible(&master->master_mutex))
  3284 
  3285         return -EINTR;
  3285     ec_foe_request_init(&request->req, data.file_name);
  3286 
  3286     ec_foe_request_read(&request->req);
  3287     if (!(request.slave = ec_master_find_slave(
  3287     ec_foe_request_alloc(&request->req, 10000); // FIXME
       
  3288 
       
  3289     if (ec_mutex_lock_interruptible(&master->master_mutex))  {
       
  3290         kref_put(&request->refcount,ec_master_foe_request_release);
       
  3291         return -EINTR;
       
  3292     }
       
  3293     if (!(request->slave = ec_master_find_slave(
  3288                     master, 0, data.slave_position))) {
  3294                     master, 0, data.slave_position))) {
  3289         ec_mutex_unlock(&master->master_mutex);
  3295         ec_mutex_unlock(&master->master_mutex);
  3290         ec_foe_request_clear(&request.req);
  3296         kref_put(&request->refcount,ec_master_foe_request_release);
  3291         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3297         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3292                 data.slave_position);
  3298                 data.slave_position);
  3293         return -EINVAL;
  3299         return -EINVAL;
  3294     }
  3300     }
  3295 
  3301 
  3296     // schedule request.
  3302     // schedule request.
  3297     list_add_tail(&request.list, &request.slave->foe_requests);
  3303     list_add_tail(&request->list, &request->slave->foe_requests);
  3298 
  3304     kref_get(&request->refcount);
  3299     ec_mutex_unlock(&master->master_mutex);
  3305 
  3300 
  3306     ec_mutex_unlock(&master->master_mutex);
  3301     EC_SLAVE_DBG(request.slave, 1, "Scheduled FoE read request.\n");
  3307 
       
  3308     EC_SLAVE_DBG(request->slave, 1, "Scheduled FoE read request %p.\n",request);
  3302 
  3309 
  3303     // wait for processing through FSM
  3310     // wait for processing through FSM
  3304     if (wait_event_interruptible(request.slave->foe_queue,
  3311     if (wait_event_interruptible(request->slave->foe_queue,
  3305                 request.req.state != EC_INT_REQUEST_QUEUED)) {
  3312           ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) {
  3306         // interrupted by signal
  3313         // interrupted by signal
  3307         ec_mutex_lock(&master->master_mutex);
  3314         kref_put(&request->refcount,ec_master_foe_request_release);
  3308         if (request.req.state == EC_INT_REQUEST_QUEUED) {
  3315         return -EINTR;
  3309             list_del(&request.list);
  3316     }
  3310             ec_mutex_unlock(&master->master_mutex);
  3317 
  3311             ec_foe_request_clear(&request.req);
  3318     data.result = request->req.result;
  3312             return -EINTR;
  3319     data.error_code = request->req.error_code;
  3313         }
  3320 
  3314         // request already processing: interrupt not possible.
  3321     EC_SLAVE_DBG(request->slave, 1, "Read %zd bytes via FoE"
  3315         ec_mutex_unlock(&master->master_mutex);
  3322             " (result = 0x%x).\n", request->req.data_size, request->req.result);
  3316     }
  3323 
  3317 
  3324     if (request->req.state != EC_INT_REQUEST_SUCCESS) {
  3318     // wait until master FSM has finished processing
       
  3319     wait_event(request.slave->foe_queue,
       
  3320             request.req.state != EC_INT_REQUEST_BUSY);
       
  3321 
       
  3322     data.result = request.req.result;
       
  3323     data.error_code = request.req.error_code;
       
  3324 
       
  3325     EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via FoE"
       
  3326             " (result = 0x%x).\n", request.req.data_size, request.req.result);
       
  3327 
       
  3328     if (request.req.state != EC_INT_REQUEST_SUCCESS) {
       
  3329         data.data_size = 0;
  3325         data.data_size = 0;
  3330         retval = -EIO;
  3326         retval = -EIO;
  3331     } else {
  3327     } else {
  3332         if (request.req.data_size > data.buffer_size) {
  3328         if (request->req.data_size > data.buffer_size) {
  3333             EC_MASTER_ERR(master, "Buffer too small.\n");
  3329             EC_MASTER_ERR(master, "Buffer too small.\n");
  3334             ec_foe_request_clear(&request.req);
  3330             kref_put(&request->refcount,ec_master_foe_request_release);
  3335             return -EOVERFLOW;
  3331             return -EOVERFLOW;
  3336         }
  3332         }
  3337         data.data_size = request.req.data_size;
  3333         data.data_size = request->req.data_size;
  3338         if (copy_to_user((void __user *) data.buffer,
  3334         if (copy_to_user((void __user *) data.buffer,
  3339                     request.req.buffer, data.data_size)) {
  3335                     request->req.buffer, data.data_size)) {
  3340             ec_foe_request_clear(&request.req);
  3336             kref_put(&request->refcount,ec_master_foe_request_release);
  3341             return -EFAULT;
  3337             return -EFAULT;
  3342         }
  3338         }
  3343         retval = 0;
  3339         retval = 0;
  3344     }
  3340     }
  3345 
  3341 
  3346     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
  3342     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
  3347         retval = -EFAULT;
  3343         retval = -EFAULT;
  3348     }
  3344     }
  3349 
  3345 
  3350     EC_SLAVE_DBG(request.slave, 1, "Finished FoE read request.\n");
  3346     EC_SLAVE_DBG(request->slave, 1, "Finished FoE read request %p.\n",request);
  3351 
  3347     kref_put(&request->refcount,ec_master_foe_request_release);
  3352     ec_foe_request_clear(&request.req);
       
  3353 
  3348 
  3354     return retval;
  3349     return retval;
  3355 }
  3350 }
  3356 
  3351 
  3357 /*****************************************************************************/
  3352 /*****************************************************************************/
  3362         ec_master_t *master, /**< EtherCAT master. */
  3357         ec_master_t *master, /**< EtherCAT master. */
  3363         unsigned long arg /**< ioctl() argument. */
  3358         unsigned long arg /**< ioctl() argument. */
  3364         )
  3359         )
  3365 {
  3360 {
  3366     ec_ioctl_slave_foe_t data;
  3361     ec_ioctl_slave_foe_t data;
  3367     ec_master_foe_request_t request;
  3362     ec_master_foe_request_t* request;
  3368     int retval;
  3363     int retval;
  3369 
  3364 
  3370     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  3365     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  3371         return -EFAULT;
  3366         return -EFAULT;
  3372     }
  3367     }
  3373 
  3368 
  3374     INIT_LIST_HEAD(&request.list);
  3369     request = kmalloc(sizeof(*request), GFP_KERNEL);
  3375 
  3370     if (!request)
  3376     ec_foe_request_init(&request.req, data.file_name);
       
  3377 
       
  3378     if (ec_foe_request_alloc(&request.req, data.buffer_size)) {
       
  3379         ec_foe_request_clear(&request.req);
       
  3380         return -ENOMEM;
  3371         return -ENOMEM;
  3381     }
  3372     kref_init(&request->refcount);
  3382     if (copy_from_user(request.req.buffer,
  3373 
       
  3374     INIT_LIST_HEAD(&request->list);
       
  3375 
       
  3376     ec_foe_request_init(&request->req, data.file_name);
       
  3377 
       
  3378     if (ec_foe_request_alloc(&request->req, data.buffer_size)) {
       
  3379         kref_put(&request->refcount,ec_master_foe_request_release);
       
  3380         return -ENOMEM;
       
  3381     }
       
  3382     if (copy_from_user(request->req.buffer,
  3383                 (void __user *) data.buffer, data.buffer_size)) {
  3383                 (void __user *) data.buffer, data.buffer_size)) {
  3384         ec_foe_request_clear(&request.req);
  3384         kref_put(&request->refcount,ec_master_foe_request_release);
  3385         return -EFAULT;
  3385         return -EFAULT;
  3386     }
  3386     }
  3387     request.req.data_size = data.buffer_size;
  3387     request->req.data_size = data.buffer_size;
  3388     ec_foe_request_write(&request.req);
  3388     ec_foe_request_write(&request->req);
  3389 
  3389 
  3390     if (ec_mutex_lock_interruptible(&master->master_mutex))
  3390     if (ec_mutex_lock_interruptible(&master->master_mutex))
  3391         return -EINTR;
  3391         return -EINTR;
  3392 
  3392 
  3393     if (!(request.slave = ec_master_find_slave(
  3393     if (!(request->slave = ec_master_find_slave(
  3394                     master, 0, data.slave_position))) {
  3394                     master, 0, data.slave_position))) {
  3395         ec_mutex_unlock(&master->master_mutex);
  3395         ec_mutex_unlock(&master->master_mutex);
  3396         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3396         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3397                 data.slave_position);
  3397                 data.slave_position);
  3398         ec_foe_request_clear(&request.req);
  3398         kref_put(&request->refcount,ec_master_foe_request_release);
  3399         return -EINVAL;
  3399         return -EINVAL;
  3400     }
  3400     }
  3401 
  3401 
  3402     EC_SLAVE_DBG(request.slave, 1, "Scheduling FoE write request.\n");
  3402     EC_SLAVE_DBG(request->slave, 1, "Scheduling FoE write request %p.\n",request);
  3403 
  3403 
  3404     // schedule FoE write request.
  3404     // schedule FoE write request.
  3405     list_add_tail(&request.list, &request.slave->foe_requests);
  3405     list_add_tail(&request->list, &request->slave->foe_requests);
       
  3406     kref_get(&request->refcount);
  3406 
  3407 
  3407     ec_mutex_unlock(&master->master_mutex);
  3408     ec_mutex_unlock(&master->master_mutex);
  3408 
  3409 
  3409     // wait for processing through FSM
  3410     // wait for processing through FSM
  3410     if (wait_event_interruptible(request.slave->foe_queue,
  3411     if (wait_event_interruptible(request->slave->foe_queue,
  3411                 request.req.state != EC_INT_REQUEST_QUEUED)) {
  3412        ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) {
  3412         // interrupted by signal
  3413         // interrupted by signal
  3413         ec_mutex_lock(&master->master_mutex);
  3414         kref_put(&request->refcount,ec_master_foe_request_release);
  3414         if (request.req.state == EC_INT_REQUEST_QUEUED) {
  3415         return -EINTR;
  3415             // abort request
  3416     }
  3416             list_del(&request.list);
  3417 
  3417             ec_mutex_unlock(&master->master_mutex);
  3418     data.result = request->req.result;
  3418             ec_foe_request_clear(&request.req);
  3419     data.error_code = request->req.error_code;
  3419             return -EINTR;
  3420 
  3420         }
  3421     retval = request->req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  3421         ec_mutex_unlock(&master->master_mutex);
       
  3422     }
       
  3423 
       
  3424     // wait until master FSM has finished processing
       
  3425     wait_event(request.slave->foe_queue,
       
  3426             request.req.state != EC_INT_REQUEST_BUSY);
       
  3427 
       
  3428     data.result = request.req.result;
       
  3429     data.error_code = request.req.error_code;
       
  3430 
       
  3431     retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
       
  3432 
  3422 
  3433     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
  3423     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
  3434         retval = -EFAULT;
  3424         retval = -EFAULT;
  3435     }
  3425     }
  3436 
  3426 
  3437     ec_foe_request_clear(&request.req);
  3427     EC_SLAVE_DBG(request->slave, 1, "Finished FoE write request %p.\n",request);
  3438 
  3428     kref_put(&request->refcount,ec_master_foe_request_release);
  3439     EC_SLAVE_DBG(request.slave, 1, "Finished FoE write request.\n");
       
  3440 
  3429 
  3441     return retval;
  3430     return retval;
  3442 }
  3431 }
  3443 
  3432 
  3444 /*****************************************************************************/
  3433 /*****************************************************************************/