184 ) |
184 ) |
185 { |
185 { |
186 ec_ioctl_master_t data; |
186 ec_ioctl_master_t data; |
187 unsigned int i; |
187 unsigned int i; |
188 |
188 |
189 if (down_interruptible(&master->master_sem)) |
189 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
190 return -EINTR; |
190 return -EINTR; |
191 data.slave_count = master->slave_count; |
191 data.slave_count = master->slave_count; |
192 data.config_count = ec_master_config_count(master); |
192 data.config_count = ec_master_config_count(master); |
193 data.domain_count = ec_master_domain_count(master); |
193 data.domain_count = ec_master_domain_count(master); |
194 #ifdef EC_EOE |
194 #ifdef EC_EOE |
195 data.eoe_handler_count = ec_master_eoe_handler_count(master); |
195 data.eoe_handler_count = ec_master_eoe_handler_count(master); |
196 #endif |
196 #endif |
197 data.phase = (uint8_t) master->phase; |
197 data.phase = (uint8_t) master->phase; |
198 data.active = (uint8_t) master->active; |
198 data.active = (uint8_t) master->active; |
199 data.scan_busy = master->scan_busy; |
199 data.scan_busy = master->scan_busy; |
200 up(&master->master_sem); |
200 ec_mutex_unlock(&master->master_mutex); |
201 |
201 |
202 if (down_interruptible(&master->device_sem)) |
202 if (ec_mutex_lock_interruptible(&master->device_mutex)) |
203 return -EINTR; |
203 return -EINTR; |
204 |
204 |
205 if (master->main_device.dev) { |
205 if (master->main_device.dev) { |
206 memcpy(data.devices[0].address, |
206 memcpy(data.devices[0].address, |
207 master->main_device.dev->dev_addr, ETH_ALEN); |
207 master->main_device.dev->dev_addr, ETH_ALEN); |
269 |
269 |
270 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
270 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
271 return -EFAULT; |
271 return -EFAULT; |
272 } |
272 } |
273 |
273 |
274 if (down_interruptible(&master->master_sem)) |
274 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
275 return -EINTR; |
275 return -EINTR; |
276 |
276 |
277 if (!(slave = ec_master_find_slave_const( |
277 if (!(slave = ec_master_find_slave_const( |
278 master, 0, data.position))) { |
278 master, 0, data.position))) { |
279 up(&master->master_sem); |
279 ec_mutex_unlock(&master->master_mutex); |
280 EC_MASTER_ERR(master, "Slave %u does not exist!\n", data.position); |
280 EC_MASTER_ERR(master, "Slave %u does not exist!\n", data.position); |
281 return -EINVAL; |
281 return -EINVAL; |
282 } |
282 } |
283 |
283 |
284 data.vendor_id = slave->sii.vendor_id; |
284 data.vendor_id = slave->sii.vendor_id; |
328 ec_cdev_strcpy(data.group, slave->sii.group); |
328 ec_cdev_strcpy(data.group, slave->sii.group); |
329 ec_cdev_strcpy(data.image, slave->sii.image); |
329 ec_cdev_strcpy(data.image, slave->sii.image); |
330 ec_cdev_strcpy(data.order, slave->sii.order); |
330 ec_cdev_strcpy(data.order, slave->sii.order); |
331 ec_cdev_strcpy(data.name, slave->sii.name); |
331 ec_cdev_strcpy(data.name, slave->sii.name); |
332 |
332 |
333 up(&master->master_sem); |
333 ec_mutex_unlock(&master->master_mutex); |
334 |
334 |
335 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
335 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
336 return -EFAULT; |
336 return -EFAULT; |
337 |
337 |
338 return 0; |
338 return 0; |
353 |
353 |
354 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
354 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
355 return -EFAULT; |
355 return -EFAULT; |
356 } |
356 } |
357 |
357 |
358 if (down_interruptible(&master->master_sem)) |
358 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
359 return -EINTR; |
359 return -EINTR; |
360 |
360 |
361 if (!(slave = ec_master_find_slave_const( |
361 if (!(slave = ec_master_find_slave_const( |
362 master, 0, data.slave_position))) { |
362 master, 0, data.slave_position))) { |
363 up(&master->master_sem); |
363 ec_mutex_unlock(&master->master_mutex); |
364 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
364 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
365 data.slave_position); |
365 data.slave_position); |
366 return -EINVAL; |
366 return -EINVAL; |
367 } |
367 } |
368 |
368 |
369 if (data.sync_index >= slave->sii.sync_count) { |
369 if (data.sync_index >= slave->sii.sync_count) { |
370 up(&master->master_sem); |
370 ec_mutex_unlock(&master->master_mutex); |
371 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n", |
371 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n", |
372 data.sync_index); |
372 data.sync_index); |
373 return -EINVAL; |
373 return -EINVAL; |
374 } |
374 } |
375 |
375 |
405 |
405 |
406 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
406 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
407 return -EFAULT; |
407 return -EFAULT; |
408 } |
408 } |
409 |
409 |
410 if (down_interruptible(&master->master_sem)) |
410 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
411 return -EINTR; |
411 return -EINTR; |
412 |
412 |
413 if (!(slave = ec_master_find_slave_const( |
413 if (!(slave = ec_master_find_slave_const( |
414 master, 0, data.slave_position))) { |
414 master, 0, data.slave_position))) { |
415 up(&master->master_sem); |
415 ec_mutex_unlock(&master->master_mutex); |
416 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
416 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
417 data.slave_position); |
417 data.slave_position); |
418 return -EINVAL; |
418 return -EINVAL; |
419 } |
419 } |
420 |
420 |
421 if (data.sync_index >= slave->sii.sync_count) { |
421 if (data.sync_index >= slave->sii.sync_count) { |
422 up(&master->master_sem); |
422 ec_mutex_unlock(&master->master_mutex); |
423 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n", |
423 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n", |
424 data.sync_index); |
424 data.sync_index); |
425 return -EINVAL; |
425 return -EINVAL; |
426 } |
426 } |
427 |
427 |
428 sync = &slave->sii.syncs[data.sync_index]; |
428 sync = &slave->sii.syncs[data.sync_index]; |
429 if (!(pdo = ec_pdo_list_find_pdo_by_pos_const( |
429 if (!(pdo = ec_pdo_list_find_pdo_by_pos_const( |
430 &sync->pdos, data.pdo_pos))) { |
430 &sync->pdos, data.pdo_pos))) { |
431 up(&master->master_sem); |
431 ec_mutex_unlock(&master->master_mutex); |
432 EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with " |
432 EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with " |
433 "position %u!\n", data.sync_index, data.pdo_pos); |
433 "position %u!\n", data.sync_index, data.pdo_pos); |
434 return -EINVAL; |
434 return -EINVAL; |
435 } |
435 } |
436 |
436 |
437 data.index = pdo->index; |
437 data.index = pdo->index; |
438 data.entry_count = ec_pdo_entry_count(pdo); |
438 data.entry_count = ec_pdo_entry_count(pdo); |
439 ec_cdev_strcpy(data.name, pdo->name); |
439 ec_cdev_strcpy(data.name, pdo->name); |
440 |
440 |
441 up(&master->master_sem); |
441 ec_mutex_unlock(&master->master_mutex); |
442 |
442 |
443 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
443 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
444 return -EFAULT; |
444 return -EFAULT; |
445 |
445 |
446 return 0; |
446 return 0; |
463 |
463 |
464 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
464 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
465 return -EFAULT; |
465 return -EFAULT; |
466 } |
466 } |
467 |
467 |
468 if (down_interruptible(&master->master_sem)) |
468 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
469 return -EINTR; |
469 return -EINTR; |
470 |
470 |
471 if (!(slave = ec_master_find_slave_const( |
471 if (!(slave = ec_master_find_slave_const( |
472 master, 0, data.slave_position))) { |
472 master, 0, data.slave_position))) { |
473 up(&master->master_sem); |
473 ec_mutex_unlock(&master->master_mutex); |
474 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
474 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
475 data.slave_position); |
475 data.slave_position); |
476 return -EINVAL; |
476 return -EINVAL; |
477 } |
477 } |
478 |
478 |
479 if (data.sync_index >= slave->sii.sync_count) { |
479 if (data.sync_index >= slave->sii.sync_count) { |
480 up(&master->master_sem); |
480 ec_mutex_unlock(&master->master_mutex); |
481 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n", |
481 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n", |
482 data.sync_index); |
482 data.sync_index); |
483 return -EINVAL; |
483 return -EINVAL; |
484 } |
484 } |
485 |
485 |
486 sync = &slave->sii.syncs[data.sync_index]; |
486 sync = &slave->sii.syncs[data.sync_index]; |
487 if (!(pdo = ec_pdo_list_find_pdo_by_pos_const( |
487 if (!(pdo = ec_pdo_list_find_pdo_by_pos_const( |
488 &sync->pdos, data.pdo_pos))) { |
488 &sync->pdos, data.pdo_pos))) { |
489 up(&master->master_sem); |
489 ec_mutex_unlock(&master->master_mutex); |
490 EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with " |
490 EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with " |
491 "position %u!\n", data.sync_index, data.pdo_pos); |
491 "position %u!\n", data.sync_index, data.pdo_pos); |
492 return -EINVAL; |
492 return -EINVAL; |
493 } |
493 } |
494 |
494 |
495 if (!(entry = ec_pdo_find_entry_by_pos_const( |
495 if (!(entry = ec_pdo_find_entry_by_pos_const( |
496 pdo, data.entry_pos))) { |
496 pdo, data.entry_pos))) { |
497 up(&master->master_sem); |
497 ec_mutex_unlock(&master->master_mutex); |
498 EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with " |
498 EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with " |
499 "position %u!\n", data.pdo_pos, data.entry_pos); |
499 "position %u!\n", data.pdo_pos, data.entry_pos); |
500 return -EINVAL; |
500 return -EINVAL; |
501 } |
501 } |
502 |
502 |
503 data.index = entry->index; |
503 data.index = entry->index; |
504 data.subindex = entry->subindex; |
504 data.subindex = entry->subindex; |
505 data.bit_length = entry->bit_length; |
505 data.bit_length = entry->bit_length; |
506 ec_cdev_strcpy(data.name, entry->name); |
506 ec_cdev_strcpy(data.name, entry->name); |
507 |
507 |
508 up(&master->master_sem); |
508 ec_mutex_unlock(&master->master_mutex); |
509 |
509 |
510 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
510 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
511 return -EFAULT; |
511 return -EFAULT; |
512 |
512 |
513 return 0; |
513 return 0; |
527 |
527 |
528 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
528 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
529 return -EFAULT; |
529 return -EFAULT; |
530 } |
530 } |
531 |
531 |
532 if (down_interruptible(&master->master_sem)) |
532 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
533 return -EINTR; |
533 return -EINTR; |
534 |
534 |
535 if (!(domain = ec_master_find_domain_const(master, data.index))) { |
535 if (!(domain = ec_master_find_domain_const(master, data.index))) { |
536 up(&master->master_sem); |
536 ec_mutex_unlock(&master->master_mutex); |
537 EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index); |
537 EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index); |
538 return -EINVAL; |
538 return -EINVAL; |
539 } |
539 } |
540 |
540 |
541 data.data_size = domain->data_size; |
541 data.data_size = domain->data_size; |
543 data.logical_base_address = domain->logical_base_address; |
543 data.logical_base_address = domain->logical_base_address; |
544 data.working_counter = domain->working_counter; |
544 data.working_counter = domain->working_counter; |
545 data.expected_working_counter = domain->expected_working_counter; |
545 data.expected_working_counter = domain->expected_working_counter; |
546 data.fmmu_count = ec_domain_fmmu_count(domain); |
546 data.fmmu_count = ec_domain_fmmu_count(domain); |
547 |
547 |
548 up(&master->master_sem); |
548 ec_mutex_unlock(&master->master_mutex); |
549 |
549 |
550 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
550 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
551 return -EFAULT; |
551 return -EFAULT; |
552 |
552 |
553 return 0; |
553 return 0; |
568 |
568 |
569 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
569 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
570 return -EFAULT; |
570 return -EFAULT; |
571 } |
571 } |
572 |
572 |
573 if (down_interruptible(&master->master_sem)) |
573 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
574 return -EINTR; |
574 return -EINTR; |
575 |
575 |
576 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) { |
576 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) { |
577 up(&master->master_sem); |
577 ec_mutex_unlock(&master->master_mutex); |
578 EC_MASTER_ERR(master, "Domain %u does not exist!\n", |
578 EC_MASTER_ERR(master, "Domain %u does not exist!\n", |
579 data.domain_index); |
579 data.domain_index); |
580 return -EINVAL; |
580 return -EINVAL; |
581 } |
581 } |
582 |
582 |
583 if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) { |
583 if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) { |
584 up(&master->master_sem); |
584 ec_mutex_unlock(&master->master_mutex); |
585 EC_MASTER_ERR(master, "Domain %u has less than %u" |
585 EC_MASTER_ERR(master, "Domain %u has less than %u" |
586 " fmmu configurations.\n", |
586 " fmmu configurations.\n", |
587 data.domain_index, data.fmmu_index + 1); |
587 data.domain_index, data.fmmu_index + 1); |
588 return -EINVAL; |
588 return -EINVAL; |
589 } |
589 } |
618 |
618 |
619 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
619 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
620 return -EFAULT; |
620 return -EFAULT; |
621 } |
621 } |
622 |
622 |
623 if (down_interruptible(&master->master_sem)) |
623 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
624 return -EINTR; |
624 return -EINTR; |
625 |
625 |
626 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) { |
626 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) { |
627 up(&master->master_sem); |
627 ec_mutex_unlock(&master->master_mutex); |
628 EC_MASTER_ERR(master, "Domain %u does not exist!\n", |
628 EC_MASTER_ERR(master, "Domain %u does not exist!\n", |
629 data.domain_index); |
629 data.domain_index); |
630 return -EINVAL; |
630 return -EINVAL; |
631 } |
631 } |
632 |
632 |
633 if (domain->data_size != data.data_size) { |
633 if (domain->data_size != data.data_size) { |
634 up(&master->master_sem); |
634 ec_mutex_unlock(&master->master_mutex); |
635 EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n", |
635 EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n", |
636 data.data_size, domain->data_size); |
636 data.data_size, domain->data_size); |
637 return -EFAULT; |
637 return -EFAULT; |
638 } |
638 } |
639 |
639 |
640 if (copy_to_user((void __user *) data.target, domain->data, |
640 if (copy_to_user((void __user *) data.target, domain->data, |
641 domain->data_size)) { |
641 domain->data_size)) { |
642 up(&master->master_sem); |
642 ec_mutex_unlock(&master->master_mutex); |
643 return -EFAULT; |
643 return -EFAULT; |
644 } |
644 } |
645 |
645 |
646 up(&master->master_sem); |
646 ec_mutex_unlock(&master->master_mutex); |
647 return 0; |
647 return 0; |
648 } |
648 } |
649 |
649 |
650 /*****************************************************************************/ |
650 /*****************************************************************************/ |
651 |
651 |
686 |
686 |
687 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
687 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
688 return -EFAULT; |
688 return -EFAULT; |
689 } |
689 } |
690 |
690 |
691 if (down_interruptible(&master->master_sem)) |
691 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
692 return -EINTR; |
692 return -EINTR; |
693 |
693 |
694 if (!(slave = ec_master_find_slave( |
694 if (!(slave = ec_master_find_slave( |
695 master, 0, data.slave_position))) { |
695 master, 0, data.slave_position))) { |
696 up(&master->master_sem); |
696 ec_mutex_unlock(&master->master_mutex); |
697 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
697 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
698 data.slave_position); |
698 data.slave_position); |
699 return -EINVAL; |
699 return -EINVAL; |
700 } |
700 } |
701 |
701 |
702 ec_slave_request_state(slave, data.al_state); |
702 ec_slave_request_state(slave, data.al_state); |
703 |
703 |
704 up(&master->master_sem); |
704 ec_mutex_unlock(&master->master_mutex); |
705 return 0; |
705 return 0; |
706 } |
706 } |
707 |
707 |
708 /*****************************************************************************/ |
708 /*****************************************************************************/ |
709 |
709 |
720 |
720 |
721 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
721 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
722 return -EFAULT; |
722 return -EFAULT; |
723 } |
723 } |
724 |
724 |
725 if (down_interruptible(&master->master_sem)) |
725 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
726 return -EINTR; |
726 return -EINTR; |
727 |
727 |
728 if (!(slave = ec_master_find_slave_const( |
728 if (!(slave = ec_master_find_slave_const( |
729 master, 0, data.slave_position))) { |
729 master, 0, data.slave_position))) { |
730 up(&master->master_sem); |
730 ec_mutex_unlock(&master->master_mutex); |
731 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
731 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
732 data.slave_position); |
732 data.slave_position); |
733 return -EINVAL; |
733 return -EINVAL; |
734 } |
734 } |
735 |
735 |
736 if (!(sdo = ec_slave_get_sdo_by_pos_const( |
736 if (!(sdo = ec_slave_get_sdo_by_pos_const( |
737 slave, data.sdo_position))) { |
737 slave, data.sdo_position))) { |
738 up(&master->master_sem); |
738 ec_mutex_unlock(&master->master_mutex); |
739 EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position); |
739 EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position); |
740 return -EINVAL; |
740 return -EINVAL; |
741 } |
741 } |
742 |
742 |
743 data.sdo_index = sdo->index; |
743 data.sdo_index = sdo->index; |
744 data.max_subindex = sdo->max_subindex; |
744 data.max_subindex = sdo->max_subindex; |
745 ec_cdev_strcpy(data.name, sdo->name); |
745 ec_cdev_strcpy(data.name, sdo->name); |
746 |
746 |
747 up(&master->master_sem); |
747 ec_mutex_unlock(&master->master_mutex); |
748 |
748 |
749 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
749 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
750 return -EFAULT; |
750 return -EFAULT; |
751 |
751 |
752 return 0; |
752 return 0; |
768 |
768 |
769 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
769 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
770 return -EFAULT; |
770 return -EFAULT; |
771 } |
771 } |
772 |
772 |
773 if (down_interruptible(&master->master_sem)) |
773 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
774 return -EINTR; |
774 return -EINTR; |
775 |
775 |
776 if (!(slave = ec_master_find_slave_const( |
776 if (!(slave = ec_master_find_slave_const( |
777 master, 0, data.slave_position))) { |
777 master, 0, data.slave_position))) { |
778 up(&master->master_sem); |
778 ec_mutex_unlock(&master->master_mutex); |
779 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
779 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
780 data.slave_position); |
780 data.slave_position); |
781 return -EINVAL; |
781 return -EINVAL; |
782 } |
782 } |
783 |
783 |
784 if (data.sdo_spec <= 0) { |
784 if (data.sdo_spec <= 0) { |
785 if (!(sdo = ec_slave_get_sdo_by_pos_const( |
785 if (!(sdo = ec_slave_get_sdo_by_pos_const( |
786 slave, -data.sdo_spec))) { |
786 slave, -data.sdo_spec))) { |
787 up(&master->master_sem); |
787 ec_mutex_unlock(&master->master_mutex); |
788 EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec); |
788 EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec); |
789 return -EINVAL; |
789 return -EINVAL; |
790 } |
790 } |
791 } else { |
791 } else { |
792 if (!(sdo = ec_slave_get_sdo_const( |
792 if (!(sdo = ec_slave_get_sdo_const( |
793 slave, data.sdo_spec))) { |
793 slave, data.sdo_spec))) { |
794 up(&master->master_sem); |
794 ec_mutex_unlock(&master->master_mutex); |
795 EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n", |
795 EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n", |
796 data.sdo_spec); |
796 data.sdo_spec); |
797 return -EINVAL; |
797 return -EINVAL; |
798 } |
798 } |
799 } |
799 } |
800 |
800 |
801 if (!(entry = ec_sdo_get_entry_const( |
801 if (!(entry = ec_sdo_get_entry_const( |
802 sdo, data.sdo_entry_subindex))) { |
802 sdo, data.sdo_entry_subindex))) { |
803 up(&master->master_sem); |
803 ec_mutex_unlock(&master->master_mutex); |
804 EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n", |
804 EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n", |
805 sdo->index, data.sdo_entry_subindex); |
805 sdo->index, data.sdo_entry_subindex); |
806 return -EINVAL; |
806 return -EINVAL; |
807 } |
807 } |
808 |
808 |
820 entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP]; |
820 entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP]; |
821 data.write_access[EC_SDO_ENTRY_ACCESS_OP] = |
821 data.write_access[EC_SDO_ENTRY_ACCESS_OP] = |
822 entry->write_access[EC_SDO_ENTRY_ACCESS_OP]; |
822 entry->write_access[EC_SDO_ENTRY_ACCESS_OP]; |
823 ec_cdev_strcpy(data.description, entry->description); |
823 ec_cdev_strcpy(data.description, entry->description); |
824 |
824 |
825 up(&master->master_sem); |
825 ec_mutex_unlock(&master->master_mutex); |
826 |
826 |
827 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
827 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
828 return -EFAULT; |
828 return -EFAULT; |
829 |
829 |
830 return 0; |
830 return 0; |
855 ec_sdo_request_init(&request->req); |
855 ec_sdo_request_init(&request->req); |
856 ec_sdo_request_address(&request->req, |
856 ec_sdo_request_address(&request->req, |
857 data.sdo_index, data.sdo_entry_subindex); |
857 data.sdo_index, data.sdo_entry_subindex); |
858 ecrt_sdo_request_read(&request->req); |
858 ecrt_sdo_request_read(&request->req); |
859 |
859 |
860 if (down_interruptible(&master->master_sem)) { |
860 if (ec_mutex_lock_interruptible(&master->master_mutex)) { |
861 kref_put(&request->refcount,ec_master_sdo_request_release); |
861 kref_put(&request->refcount,ec_master_sdo_request_release); |
862 return -EINTR; |
862 return -EINTR; |
863 } |
863 } |
864 if (!(request->slave = ec_master_find_slave( |
864 if (!(request->slave = ec_master_find_slave( |
865 master, 0, data.slave_position))) { |
865 master, 0, data.slave_position))) { |
866 up(&master->master_sem); |
866 ec_mutex_unlock(&master->master_mutex); |
867 kref_put(&request->refcount,ec_master_sdo_request_release); |
867 kref_put(&request->refcount,ec_master_sdo_request_release); |
868 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
868 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
869 data.slave_position); |
869 data.slave_position); |
870 return -EINVAL; |
870 return -EINVAL; |
871 } |
871 } |
874 |
874 |
875 // schedule request. |
875 // schedule request. |
876 kref_get(&request->refcount); |
876 kref_get(&request->refcount); |
877 list_add_tail(&request->list, &request->slave->slave_sdo_requests); |
877 list_add_tail(&request->list, &request->slave->slave_sdo_requests); |
878 |
878 |
879 up(&master->master_sem); |
879 ec_mutex_unlock(&master->master_mutex); |
880 |
880 |
881 // wait for processing through FSM |
881 // wait for processing through FSM |
882 if (wait_event_interruptible(request->slave->sdo_queue, |
882 if (wait_event_interruptible(request->slave->sdo_queue, |
883 ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
883 ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
884 // interrupted by signal |
884 // interrupted by signal |
962 return -EFAULT; |
962 return -EFAULT; |
963 } |
963 } |
964 request->req.data_size = data.data_size; |
964 request->req.data_size = data.data_size; |
965 ecrt_sdo_request_write(&request->req); |
965 ecrt_sdo_request_write(&request->req); |
966 |
966 |
967 if (down_interruptible(&master->master_sem)) { |
967 if (ec_mutex_lock_interruptible(&master->master_mutex)) { |
968 kref_put(&request->refcount,ec_master_sdo_request_release); |
968 kref_put(&request->refcount,ec_master_sdo_request_release); |
969 return -EINTR; |
969 return -EINTR; |
970 } |
970 } |
971 if (!(request->slave = ec_master_find_slave( |
971 if (!(request->slave = ec_master_find_slave( |
972 master, 0, data.slave_position))) { |
972 master, 0, data.slave_position))) { |
973 up(&master->master_sem); |
973 ec_mutex_unlock(&master->master_mutex); |
974 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
974 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
975 data.slave_position); |
975 data.slave_position); |
976 kref_put(&request->refcount,ec_master_sdo_request_release); |
976 kref_put(&request->refcount,ec_master_sdo_request_release); |
977 return -EINVAL; |
977 return -EINVAL; |
978 } |
978 } |
981 |
981 |
982 // schedule request. |
982 // schedule request. |
983 kref_get(&request->refcount); |
983 kref_get(&request->refcount); |
984 list_add_tail(&request->list, &request->slave->slave_sdo_requests); |
984 list_add_tail(&request->list, &request->slave->slave_sdo_requests); |
985 |
985 |
986 up(&master->master_sem); |
986 ec_mutex_unlock(&master->master_mutex); |
987 |
987 |
988 // wait for processing through FSM |
988 // wait for processing through FSM |
989 if (wait_event_interruptible(request->slave->sdo_queue, |
989 if (wait_event_interruptible(request->slave->sdo_queue, |
990 ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
990 ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
991 // interrupted by signal |
991 // interrupted by signal |
1028 |
1028 |
1029 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1029 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1030 return -EFAULT; |
1030 return -EFAULT; |
1031 } |
1031 } |
1032 |
1032 |
1033 if (down_interruptible(&master->master_sem)) |
1033 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1034 return -EINTR; |
1034 return -EINTR; |
1035 |
1035 |
1036 if (!(slave = ec_master_find_slave_const( |
1036 if (!(slave = ec_master_find_slave_const( |
1037 master, 0, data.slave_position))) { |
1037 master, 0, data.slave_position))) { |
1038 up(&master->master_sem); |
1038 ec_mutex_unlock(&master->master_mutex); |
1039 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1039 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1040 data.slave_position); |
1040 data.slave_position); |
1041 return -EINVAL; |
1041 return -EINVAL; |
1042 } |
1042 } |
1043 |
1043 |
1044 if (!data.nwords |
1044 if (!data.nwords |
1045 || data.offset + data.nwords > slave->sii_nwords) { |
1045 || data.offset + data.nwords > slave->sii_nwords) { |
1046 up(&master->master_sem); |
1046 ec_mutex_unlock(&master->master_mutex); |
1047 EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII" |
1047 EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII" |
1048 " size %zu!\n", data.offset, data.nwords, slave->sii_nwords); |
1048 " size %zu!\n", data.offset, data.nwords, slave->sii_nwords); |
1049 return -EINVAL; |
1049 return -EINVAL; |
1050 } |
1050 } |
1051 |
1051 |
1092 (void __user *) data.words, byte_size)) { |
1092 (void __user *) data.words, byte_size)) { |
1093 kfree(words); |
1093 kfree(words); |
1094 return -EFAULT; |
1094 return -EFAULT; |
1095 } |
1095 } |
1096 |
1096 |
1097 if (down_interruptible(&master->master_sem)) |
1097 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1098 return -EINTR; |
1098 return -EINTR; |
1099 |
1099 |
1100 if (!(slave = ec_master_find_slave( |
1100 if (!(slave = ec_master_find_slave( |
1101 master, 0, data.slave_position))) { |
1101 master, 0, data.slave_position))) { |
1102 up(&master->master_sem); |
1102 ec_mutex_unlock(&master->master_mutex); |
1103 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1103 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1104 data.slave_position); |
1104 data.slave_position); |
1105 kfree(words); |
1105 kfree(words); |
1106 return -EINVAL; |
1106 return -EINVAL; |
1107 } |
1107 } |
1115 request.state = EC_INT_REQUEST_QUEUED; |
1115 request.state = EC_INT_REQUEST_QUEUED; |
1116 |
1116 |
1117 // schedule SII write request. |
1117 // schedule SII write request. |
1118 list_add_tail(&request.list, &master->sii_requests); |
1118 list_add_tail(&request.list, &master->sii_requests); |
1119 |
1119 |
1120 up(&master->master_sem); |
1120 ec_mutex_unlock(&master->master_mutex); |
1121 |
1121 |
1122 // wait for processing through FSM |
1122 // wait for processing through FSM |
1123 if (wait_event_interruptible(master->sii_queue, |
1123 if (wait_event_interruptible(master->sii_queue, |
1124 request.state != EC_INT_REQUEST_QUEUED)) { |
1124 request.state != EC_INT_REQUEST_QUEUED)) { |
1125 // interrupted by signal |
1125 // interrupted by signal |
1126 down(&master->master_sem); |
1126 ec_mutex_lock(&master->master_mutex); |
1127 if (request.state == EC_INT_REQUEST_QUEUED) { |
1127 if (request.state == EC_INT_REQUEST_QUEUED) { |
1128 // abort request |
1128 // abort request |
1129 list_del(&request.list); |
1129 list_del(&request.list); |
1130 up(&master->master_sem); |
1130 ec_mutex_unlock(&master->master_mutex); |
1131 kfree(words); |
1131 kfree(words); |
1132 return -EINTR; |
1132 return -EINTR; |
1133 } |
1133 } |
1134 up(&master->master_sem); |
1134 ec_mutex_unlock(&master->master_mutex); |
1135 } |
1135 } |
1136 |
1136 |
1137 // wait until master FSM has finished processing |
1137 // wait until master FSM has finished processing |
1138 wait_event(master->sii_queue, request.state != EC_INT_REQUEST_BUSY); |
1138 wait_event(master->sii_queue, request.state != EC_INT_REQUEST_BUSY); |
1139 |
1139 |
1167 EC_MASTER_ERR(master, "Failed to allocate %u bytes" |
1167 EC_MASTER_ERR(master, "Failed to allocate %u bytes" |
1168 " for register data.\n", data.length); |
1168 " for register data.\n", data.length); |
1169 return -ENOMEM; |
1169 return -ENOMEM; |
1170 } |
1170 } |
1171 |
1171 |
1172 if (down_interruptible(&master->master_sem)) |
1172 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1173 return -EINTR; |
1173 return -EINTR; |
1174 |
1174 |
1175 if (!(slave = ec_master_find_slave( |
1175 if (!(slave = ec_master_find_slave( |
1176 master, 0, data.slave_position))) { |
1176 master, 0, data.slave_position))) { |
1177 up(&master->master_sem); |
1177 ec_mutex_unlock(&master->master_mutex); |
1178 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1178 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1179 data.slave_position); |
1179 data.slave_position); |
1180 return -EINVAL; |
1180 return -EINVAL; |
1181 } |
1181 } |
1182 |
1182 |
1190 request.state = EC_INT_REQUEST_QUEUED; |
1190 request.state = EC_INT_REQUEST_QUEUED; |
1191 |
1191 |
1192 // schedule request. |
1192 // schedule request. |
1193 list_add_tail(&request.list, &master->reg_requests); |
1193 list_add_tail(&request.list, &master->reg_requests); |
1194 |
1194 |
1195 up(&master->master_sem); |
1195 ec_mutex_unlock(&master->master_mutex); |
1196 |
1196 |
1197 // wait for processing through FSM |
1197 // wait for processing through FSM |
1198 if (wait_event_interruptible(master->reg_queue, |
1198 if (wait_event_interruptible(master->reg_queue, |
1199 request.state != EC_INT_REQUEST_QUEUED)) { |
1199 request.state != EC_INT_REQUEST_QUEUED)) { |
1200 // interrupted by signal |
1200 // interrupted by signal |
1201 down(&master->master_sem); |
1201 ec_mutex_lock(&master->master_mutex); |
1202 if (request.state == EC_INT_REQUEST_QUEUED) { |
1202 if (request.state == EC_INT_REQUEST_QUEUED) { |
1203 // abort request |
1203 // abort request |
1204 list_del(&request.list); |
1204 list_del(&request.list); |
1205 up(&master->master_sem); |
1205 ec_mutex_unlock(&master->master_mutex); |
1206 kfree(contents); |
1206 kfree(contents); |
1207 return -EINTR; |
1207 return -EINTR; |
1208 } |
1208 } |
1209 up(&master->master_sem); |
1209 ec_mutex_unlock(&master->master_mutex); |
1210 } |
1210 } |
1211 |
1211 |
1212 // wait until master FSM has finished processing |
1212 // wait until master FSM has finished processing |
1213 wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY); |
1213 wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY); |
1214 |
1214 |
1251 if (copy_from_user(contents, (void __user *) data.data, data.length)) { |
1251 if (copy_from_user(contents, (void __user *) data.data, data.length)) { |
1252 kfree(contents); |
1252 kfree(contents); |
1253 return -EFAULT; |
1253 return -EFAULT; |
1254 } |
1254 } |
1255 |
1255 |
1256 if (down_interruptible(&master->master_sem)) |
1256 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1257 return -EINTR; |
1257 return -EINTR; |
1258 |
1258 |
1259 if (!(slave = ec_master_find_slave( |
1259 if (!(slave = ec_master_find_slave( |
1260 master, 0, data.slave_position))) { |
1260 master, 0, data.slave_position))) { |
1261 up(&master->master_sem); |
1261 ec_mutex_unlock(&master->master_mutex); |
1262 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1262 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1263 data.slave_position); |
1263 data.slave_position); |
1264 kfree(contents); |
1264 kfree(contents); |
1265 return -EINVAL; |
1265 return -EINVAL; |
1266 } |
1266 } |
1275 request.state = EC_INT_REQUEST_QUEUED; |
1275 request.state = EC_INT_REQUEST_QUEUED; |
1276 |
1276 |
1277 // schedule request. |
1277 // schedule request. |
1278 list_add_tail(&request.list, &master->reg_requests); |
1278 list_add_tail(&request.list, &master->reg_requests); |
1279 |
1279 |
1280 up(&master->master_sem); |
1280 ec_mutex_unlock(&master->master_mutex); |
1281 |
1281 |
1282 // wait for processing through FSM |
1282 // wait for processing through FSM |
1283 if (wait_event_interruptible(master->reg_queue, |
1283 if (wait_event_interruptible(master->reg_queue, |
1284 request.state != EC_INT_REQUEST_QUEUED)) { |
1284 request.state != EC_INT_REQUEST_QUEUED)) { |
1285 // interrupted by signal |
1285 // interrupted by signal |
1286 down(&master->master_sem); |
1286 ec_mutex_lock(&master->master_mutex); |
1287 if (request.state == EC_INT_REQUEST_QUEUED) { |
1287 if (request.state == EC_INT_REQUEST_QUEUED) { |
1288 // abort request |
1288 // abort request |
1289 list_del(&request.list); |
1289 list_del(&request.list); |
1290 up(&master->master_sem); |
1290 ec_mutex_unlock(&master->master_mutex); |
1291 kfree(contents); |
1291 kfree(contents); |
1292 return -EINTR; |
1292 return -EINTR; |
1293 } |
1293 } |
1294 up(&master->master_sem); |
1294 ec_mutex_unlock(&master->master_mutex); |
1295 } |
1295 } |
1296 |
1296 |
1297 // wait until master FSM has finished processing |
1297 // wait until master FSM has finished processing |
1298 wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY); |
1298 wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY); |
1299 |
1299 |
1317 |
1317 |
1318 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1318 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1319 return -EFAULT; |
1319 return -EFAULT; |
1320 } |
1320 } |
1321 |
1321 |
1322 if (down_interruptible(&master->master_sem)) |
1322 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1323 return -EINTR; |
1323 return -EINTR; |
1324 |
1324 |
1325 if (!(sc = ec_master_get_config_const( |
1325 if (!(sc = ec_master_get_config_const( |
1326 master, data.config_index))) { |
1326 master, data.config_index))) { |
1327 up(&master->master_sem); |
1327 ec_mutex_unlock(&master->master_mutex); |
1328 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1328 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1329 data.config_index); |
1329 data.config_index); |
1330 return -EINVAL; |
1330 return -EINVAL; |
1331 } |
1331 } |
1332 |
1332 |
1379 EC_MASTER_ERR(master, "Invalid sync manager index %u!\n", |
1379 EC_MASTER_ERR(master, "Invalid sync manager index %u!\n", |
1380 data.sync_index); |
1380 data.sync_index); |
1381 return -EINVAL; |
1381 return -EINVAL; |
1382 } |
1382 } |
1383 |
1383 |
1384 if (down_interruptible(&master->master_sem)) |
1384 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1385 return -EINTR; |
1385 return -EINTR; |
1386 |
1386 |
1387 if (!(sc = ec_master_get_config_const( |
1387 if (!(sc = ec_master_get_config_const( |
1388 master, data.config_index))) { |
1388 master, data.config_index))) { |
1389 up(&master->master_sem); |
1389 ec_mutex_unlock(&master->master_mutex); |
1390 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1390 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1391 data.config_index); |
1391 data.config_index); |
1392 return -EINVAL; |
1392 return -EINVAL; |
1393 } |
1393 } |
1394 |
1394 |
1395 if (!(pdo = ec_pdo_list_find_pdo_by_pos_const( |
1395 if (!(pdo = ec_pdo_list_find_pdo_by_pos_const( |
1396 &sc->sync_configs[data.sync_index].pdos, |
1396 &sc->sync_configs[data.sync_index].pdos, |
1397 data.pdo_pos))) { |
1397 data.pdo_pos))) { |
1398 up(&master->master_sem); |
1398 ec_mutex_unlock(&master->master_mutex); |
1399 EC_MASTER_ERR(master, "Invalid PDO position!\n"); |
1399 EC_MASTER_ERR(master, "Invalid PDO position!\n"); |
1400 return -EINVAL; |
1400 return -EINVAL; |
1401 } |
1401 } |
1402 |
1402 |
1403 data.index = pdo->index; |
1403 data.index = pdo->index; |
1404 data.entry_count = ec_pdo_entry_count(pdo); |
1404 data.entry_count = ec_pdo_entry_count(pdo); |
1405 ec_cdev_strcpy(data.name, pdo->name); |
1405 ec_cdev_strcpy(data.name, pdo->name); |
1406 |
1406 |
1407 up(&master->master_sem); |
1407 ec_mutex_unlock(&master->master_mutex); |
1408 |
1408 |
1409 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1409 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1410 return -EFAULT; |
1410 return -EFAULT; |
1411 |
1411 |
1412 return 0; |
1412 return 0; |
1434 EC_MASTER_ERR(master, "Invalid sync manager index %u!\n", |
1434 EC_MASTER_ERR(master, "Invalid sync manager index %u!\n", |
1435 data.sync_index); |
1435 data.sync_index); |
1436 return -EINVAL; |
1436 return -EINVAL; |
1437 } |
1437 } |
1438 |
1438 |
1439 if (down_interruptible(&master->master_sem)) |
1439 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1440 return -EINTR; |
1440 return -EINTR; |
1441 |
1441 |
1442 if (!(sc = ec_master_get_config_const( |
1442 if (!(sc = ec_master_get_config_const( |
1443 master, data.config_index))) { |
1443 master, data.config_index))) { |
1444 up(&master->master_sem); |
1444 ec_mutex_unlock(&master->master_mutex); |
1445 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1445 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1446 data.config_index); |
1446 data.config_index); |
1447 return -EINVAL; |
1447 return -EINVAL; |
1448 } |
1448 } |
1449 |
1449 |
1450 if (!(pdo = ec_pdo_list_find_pdo_by_pos_const( |
1450 if (!(pdo = ec_pdo_list_find_pdo_by_pos_const( |
1451 &sc->sync_configs[data.sync_index].pdos, |
1451 &sc->sync_configs[data.sync_index].pdos, |
1452 data.pdo_pos))) { |
1452 data.pdo_pos))) { |
1453 up(&master->master_sem); |
1453 ec_mutex_unlock(&master->master_mutex); |
1454 EC_MASTER_ERR(master, "Invalid PDO position!\n"); |
1454 EC_MASTER_ERR(master, "Invalid PDO position!\n"); |
1455 return -EINVAL; |
1455 return -EINVAL; |
1456 } |
1456 } |
1457 |
1457 |
1458 if (!(entry = ec_pdo_find_entry_by_pos_const( |
1458 if (!(entry = ec_pdo_find_entry_by_pos_const( |
1459 pdo, data.entry_pos))) { |
1459 pdo, data.entry_pos))) { |
1460 up(&master->master_sem); |
1460 ec_mutex_unlock(&master->master_mutex); |
1461 EC_MASTER_ERR(master, "Entry not found!\n"); |
1461 EC_MASTER_ERR(master, "Entry not found!\n"); |
1462 return -EINVAL; |
1462 return -EINVAL; |
1463 } |
1463 } |
1464 |
1464 |
1465 data.index = entry->index; |
1465 data.index = entry->index; |
1466 data.subindex = entry->subindex; |
1466 data.subindex = entry->subindex; |
1467 data.bit_length = entry->bit_length; |
1467 data.bit_length = entry->bit_length; |
1468 ec_cdev_strcpy(data.name, entry->name); |
1468 ec_cdev_strcpy(data.name, entry->name); |
1469 |
1469 |
1470 up(&master->master_sem); |
1470 ec_mutex_unlock(&master->master_mutex); |
1471 |
1471 |
1472 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1472 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1473 return -EFAULT; |
1473 return -EFAULT; |
1474 |
1474 |
1475 return 0; |
1475 return 0; |
1490 |
1490 |
1491 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1491 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1492 return -EFAULT; |
1492 return -EFAULT; |
1493 } |
1493 } |
1494 |
1494 |
1495 if (down_interruptible(&master->master_sem)) |
1495 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1496 return -EINTR; |
1496 return -EINTR; |
1497 |
1497 |
1498 if (!(sc = ec_master_get_config_const( |
1498 if (!(sc = ec_master_get_config_const( |
1499 master, data.config_index))) { |
1499 master, data.config_index))) { |
1500 up(&master->master_sem); |
1500 ec_mutex_unlock(&master->master_mutex); |
1501 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1501 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1502 data.config_index); |
1502 data.config_index); |
1503 return -EINVAL; |
1503 return -EINVAL; |
1504 } |
1504 } |
1505 |
1505 |
1506 if (!(req = ec_slave_config_get_sdo_by_pos_const( |
1506 if (!(req = ec_slave_config_get_sdo_by_pos_const( |
1507 sc, data.sdo_pos))) { |
1507 sc, data.sdo_pos))) { |
1508 up(&master->master_sem); |
1508 ec_mutex_unlock(&master->master_mutex); |
1509 EC_MASTER_ERR(master, "Invalid SDO position!\n"); |
1509 EC_MASTER_ERR(master, "Invalid SDO position!\n"); |
1510 return -EINVAL; |
1510 return -EINVAL; |
1511 } |
1511 } |
1512 |
1512 |
1513 data.index = req->index; |
1513 data.index = req->index; |
1514 data.subindex = req->subindex; |
1514 data.subindex = req->subindex; |
1515 data.size = req->data_size; |
1515 data.size = req->data_size; |
1516 memcpy(&data.data, req->data, |
1516 memcpy(&data.data, req->data, |
1517 min((u32) data.size, (u32) EC_MAX_SDO_DATA_SIZE)); |
1517 min((u32) data.size, (u32) EC_MAX_SDO_DATA_SIZE)); |
1518 |
1518 |
1519 up(&master->master_sem); |
1519 ec_mutex_unlock(&master->master_mutex); |
1520 |
1520 |
1521 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1521 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1522 return -EFAULT; |
1522 return -EFAULT; |
1523 |
1523 |
1524 return 0; |
1524 return 0; |
1539 |
1539 |
1540 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1540 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1541 return -EFAULT; |
1541 return -EFAULT; |
1542 } |
1542 } |
1543 |
1543 |
1544 if (down_interruptible(&master->master_sem)) |
1544 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1545 return -EINTR; |
1545 return -EINTR; |
1546 |
1546 |
1547 if (!(sc = ec_master_get_config_const( |
1547 if (!(sc = ec_master_get_config_const( |
1548 master, data.config_index))) { |
1548 master, data.config_index))) { |
1549 up(&master->master_sem); |
1549 ec_mutex_unlock(&master->master_mutex); |
1550 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1550 EC_MASTER_ERR(master, "Slave config %u does not exist!\n", |
1551 data.config_index); |
1551 data.config_index); |
1552 return -EINVAL; |
1552 return -EINVAL; |
1553 } |
1553 } |
1554 |
1554 |
1555 if (!(req = ec_slave_config_get_idn_by_pos_const( |
1555 if (!(req = ec_slave_config_get_idn_by_pos_const( |
1556 sc, data.idn_pos))) { |
1556 sc, data.idn_pos))) { |
1557 up(&master->master_sem); |
1557 ec_mutex_unlock(&master->master_mutex); |
1558 EC_MASTER_ERR(master, "Invalid IDN position!\n"); |
1558 EC_MASTER_ERR(master, "Invalid IDN position!\n"); |
1559 return -EINVAL; |
1559 return -EINVAL; |
1560 } |
1560 } |
1561 |
1561 |
1562 data.drive_no = req->drive_no; |
1562 data.drive_no = req->drive_no; |
1564 data.state = req->state; |
1564 data.state = req->state; |
1565 data.size = req->data_size; |
1565 data.size = req->data_size; |
1566 memcpy(&data.data, req->data, |
1566 memcpy(&data.data, req->data, |
1567 min((u32) data.size, (u32) EC_MAX_IDN_DATA_SIZE)); |
1567 min((u32) data.size, (u32) EC_MAX_IDN_DATA_SIZE)); |
1568 |
1568 |
1569 up(&master->master_sem); |
1569 ec_mutex_unlock(&master->master_mutex); |
1570 |
1570 |
1571 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1571 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1572 return -EFAULT; |
1572 return -EFAULT; |
1573 |
1573 |
1574 return 0; |
1574 return 0; |
1590 |
1590 |
1591 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1591 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
1592 return -EFAULT; |
1592 return -EFAULT; |
1593 } |
1593 } |
1594 |
1594 |
1595 if (down_interruptible(&master->master_sem)) |
1595 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1596 return -EINTR; |
1596 return -EINTR; |
1597 |
1597 |
1598 if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) { |
1598 if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) { |
1599 up(&master->master_sem); |
1599 ec_mutex_unlock(&master->master_mutex); |
1600 EC_MASTER_ERR(master, "EoE handler %u does not exist!\n", |
1600 EC_MASTER_ERR(master, "EoE handler %u does not exist!\n", |
1601 data.eoe_index); |
1601 data.eoe_index); |
1602 return -EINVAL; |
1602 return -EINVAL; |
1603 } |
1603 } |
1604 |
1604 |
1734 |
1734 |
1735 /* Get the sum of the domains' process data sizes. */ |
1735 /* Get the sum of the domains' process data sizes. */ |
1736 |
1736 |
1737 priv->process_data_size = 0; |
1737 priv->process_data_size = 0; |
1738 |
1738 |
1739 if (down_interruptible(&master->master_sem)) |
1739 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1740 return -EINTR; |
1740 return -EINTR; |
1741 |
1741 |
1742 list_for_each_entry(domain, &master->domains, list) { |
1742 list_for_each_entry(domain, &master->domains, list) { |
1743 priv->process_data_size += ecrt_domain_size(domain); |
1743 priv->process_data_size += ecrt_domain_size(domain); |
1744 } |
1744 } |
1745 |
1745 |
1746 up(&master->master_sem); |
1746 ec_mutex_unlock(&master->master_mutex); |
1747 |
1747 |
1748 if (priv->process_data_size) { |
1748 if (priv->process_data_size) { |
1749 priv->process_data = vmalloc(priv->process_data_size); |
1749 priv->process_data = vmalloc(priv->process_data_size); |
1750 if (!priv->process_data) { |
1750 if (!priv->process_data) { |
1751 priv->process_data_size = 0; |
1751 priv->process_data_size = 0; |
2159 return -EPERM; |
2159 return -EPERM; |
2160 |
2160 |
2161 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2161 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2162 return -EFAULT; |
2162 return -EFAULT; |
2163 |
2163 |
2164 if (down_interruptible(&master->master_sem)) |
2164 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2165 return -EINTR; |
2165 return -EINTR; |
2166 |
2166 |
2167 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2167 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2168 up(&master->master_sem); |
2168 ec_mutex_unlock(&master->master_mutex); |
2169 return -ENOENT; |
2169 return -ENOENT; |
2170 } |
2170 } |
2171 |
2171 |
2172 up(&master->master_sem); // FIXME |
2172 ec_mutex_unlock(&master->master_mutex); // FIXME |
2173 |
2173 |
2174 return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index); |
2174 return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index); |
2175 } |
2175 } |
2176 |
2176 |
2177 /*****************************************************************************/ |
2177 /*****************************************************************************/ |
2191 return -EPERM; |
2191 return -EPERM; |
2192 |
2192 |
2193 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2193 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2194 return -EFAULT; |
2194 return -EFAULT; |
2195 |
2195 |
2196 if (down_interruptible(&master->master_sem)) |
2196 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2197 return -EINTR; |
2197 return -EINTR; |
2198 |
2198 |
2199 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2199 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2200 up(&master->master_sem); |
2200 ec_mutex_unlock(&master->master_mutex); |
2201 return -ENOENT; |
2201 return -ENOENT; |
2202 } |
2202 } |
2203 |
2203 |
2204 up(&master->master_sem); // FIXME |
2204 ec_mutex_unlock(&master->master_mutex); // FIXME |
2205 |
2205 |
2206 ecrt_slave_config_pdo_assign_clear(sc, data.sync_index); |
2206 ecrt_slave_config_pdo_assign_clear(sc, data.sync_index); |
2207 return 0; |
2207 return 0; |
2208 } |
2208 } |
2209 |
2209 |
2224 return -EPERM; |
2224 return -EPERM; |
2225 |
2225 |
2226 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2226 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2227 return -EFAULT; |
2227 return -EFAULT; |
2228 |
2228 |
2229 if (down_interruptible(&master->master_sem)) |
2229 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2230 return -EINTR; |
2230 return -EINTR; |
2231 |
2231 |
2232 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2232 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2233 up(&master->master_sem); |
2233 ec_mutex_unlock(&master->master_mutex); |
2234 return -ENOENT; |
2234 return -ENOENT; |
2235 } |
2235 } |
2236 |
2236 |
2237 up(&master->master_sem); // FIXME |
2237 ec_mutex_unlock(&master->master_mutex); // FIXME |
2238 |
2238 |
2239 return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index, |
2239 return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index, |
2240 data.entry_index, data.entry_subindex, data.entry_bit_length); |
2240 data.entry_index, data.entry_subindex, data.entry_bit_length); |
2241 } |
2241 } |
2242 |
2242 |
2257 return -EPERM; |
2257 return -EPERM; |
2258 |
2258 |
2259 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2259 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2260 return -EFAULT; |
2260 return -EFAULT; |
2261 |
2261 |
2262 if (down_interruptible(&master->master_sem)) |
2262 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2263 return -EINTR; |
2263 return -EINTR; |
2264 |
2264 |
2265 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2265 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2266 up(&master->master_sem); |
2266 ec_mutex_unlock(&master->master_mutex); |
2267 return -ENOENT; |
2267 return -ENOENT; |
2268 } |
2268 } |
2269 |
2269 |
2270 up(&master->master_sem); // FIXME |
2270 ec_mutex_unlock(&master->master_mutex); // FIXME |
2271 |
2271 |
2272 ecrt_slave_config_pdo_mapping_clear(sc, data.index); |
2272 ecrt_slave_config_pdo_mapping_clear(sc, data.index); |
2273 return 0; |
2273 return 0; |
2274 } |
2274 } |
2275 |
2275 |
2292 return -EPERM; |
2292 return -EPERM; |
2293 |
2293 |
2294 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2294 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2295 return -EFAULT; |
2295 return -EFAULT; |
2296 |
2296 |
2297 if (down_interruptible(&master->master_sem)) |
2297 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2298 return -EINTR; |
2298 return -EINTR; |
2299 |
2299 |
2300 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2300 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2301 up(&master->master_sem); |
2301 ec_mutex_unlock(&master->master_mutex); |
2302 return -ENOENT; |
2302 return -ENOENT; |
2303 } |
2303 } |
2304 |
2304 |
2305 if (!(domain = ec_master_find_domain(master, data.domain_index))) { |
2305 if (!(domain = ec_master_find_domain(master, data.domain_index))) { |
2306 up(&master->master_sem); |
2306 ec_mutex_unlock(&master->master_mutex); |
2307 return -ENOENT; |
2307 return -ENOENT; |
2308 } |
2308 } |
2309 |
2309 |
2310 up(&master->master_sem); // FIXME |
2310 ec_mutex_unlock(&master->master_mutex); // FIXME |
2311 |
2311 |
2312 ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index, |
2312 ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index, |
2313 data.entry_subindex, domain, &data.bit_position); |
2313 data.entry_subindex, domain, &data.bit_position); |
2314 |
2314 |
2315 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
2315 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
2335 return -EPERM; |
2335 return -EPERM; |
2336 |
2336 |
2337 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2337 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2338 return -EFAULT; |
2338 return -EFAULT; |
2339 |
2339 |
2340 if (down_interruptible(&master->master_sem)) |
2340 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2341 return -EINTR; |
2341 return -EINTR; |
2342 |
2342 |
2343 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2343 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2344 up(&master->master_sem); |
2344 ec_mutex_unlock(&master->master_mutex); |
2345 return -ENOENT; |
2345 return -ENOENT; |
2346 } |
2346 } |
2347 |
2347 |
2348 ecrt_slave_config_dc(sc, data.dc_assign_activate, |
2348 ecrt_slave_config_dc(sc, data.dc_assign_activate, |
2349 data.dc_sync[0].cycle_time, |
2349 data.dc_sync[0].cycle_time, |
2350 data.dc_sync[0].shift_time, |
2350 data.dc_sync[0].shift_time, |
2351 data.dc_sync[1].cycle_time, |
2351 data.dc_sync[1].cycle_time, |
2352 data.dc_sync[1].shift_time); |
2352 data.dc_sync[1].shift_time); |
2353 |
2353 |
2354 up(&master->master_sem); |
2354 ec_mutex_unlock(&master->master_mutex); |
2355 |
2355 |
2356 return 0; |
2356 return 0; |
2357 } |
2357 } |
2358 |
2358 |
2359 /*****************************************************************************/ |
2359 /*****************************************************************************/ |
2387 if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) { |
2387 if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) { |
2388 kfree(sdo_data); |
2388 kfree(sdo_data); |
2389 return -EFAULT; |
2389 return -EFAULT; |
2390 } |
2390 } |
2391 |
2391 |
2392 if (down_interruptible(&master->master_sem)) { |
2392 if (ec_mutex_lock_interruptible(&master->master_mutex)) { |
2393 kfree(sdo_data); |
2393 kfree(sdo_data); |
2394 return -EINTR; |
2394 return -EINTR; |
2395 } |
2395 } |
2396 |
2396 |
2397 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2397 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2398 up(&master->master_sem); |
2398 ec_mutex_unlock(&master->master_mutex); |
2399 kfree(sdo_data); |
2399 kfree(sdo_data); |
2400 return -ENOENT; |
2400 return -ENOENT; |
2401 } |
2401 } |
2402 |
2402 |
2403 up(&master->master_sem); // FIXME |
2403 ec_mutex_unlock(&master->master_mutex); // FIXME |
2404 |
2404 |
2405 if (data.complete_access) { |
2405 if (data.complete_access) { |
2406 ret = ecrt_slave_config_complete_sdo(sc, |
2406 ret = ecrt_slave_config_complete_sdo(sc, |
2407 data.index, sdo_data, data.size); |
2407 data.index, sdo_data, data.size); |
2408 } else { |
2408 } else { |
2434 return -EFAULT; |
2434 return -EFAULT; |
2435 } |
2435 } |
2436 |
2436 |
2437 data.request_index = 0; |
2437 data.request_index = 0; |
2438 |
2438 |
2439 if (down_interruptible(&master->master_sem)) |
2439 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2440 return -EINTR; |
2440 return -EINTR; |
2441 |
2441 |
2442 sc = ec_master_get_config(master, data.config_index); |
2442 sc = ec_master_get_config(master, data.config_index); |
2443 if (!sc) { |
2443 if (!sc) { |
2444 up(&master->master_sem); |
2444 ec_mutex_unlock(&master->master_mutex); |
2445 return -ENOENT; |
2445 return -ENOENT; |
2446 } |
2446 } |
2447 |
2447 |
2448 list_for_each_entry(req, &sc->sdo_requests, list) { |
2448 list_for_each_entry(req, &sc->sdo_requests, list) { |
2449 data.request_index++; |
2449 data.request_index++; |
2450 } |
2450 } |
2451 |
2451 |
2452 up(&master->master_sem); |
2452 ec_mutex_unlock(&master->master_mutex); |
2453 |
2453 |
2454 req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index, |
2454 req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index, |
2455 data.sdo_subindex, data.size); |
2455 data.sdo_subindex, data.size); |
2456 if (IS_ERR(req)) |
2456 if (IS_ERR(req)) |
2457 return PTR_ERR(req); |
2457 return PTR_ERR(req); |
2483 return -EFAULT; |
2483 return -EFAULT; |
2484 } |
2484 } |
2485 |
2485 |
2486 data.voe_index = 0; |
2486 data.voe_index = 0; |
2487 |
2487 |
2488 if (down_interruptible(&master->master_sem)) |
2488 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2489 return -EINTR; |
2489 return -EINTR; |
2490 |
2490 |
2491 sc = ec_master_get_config(master, data.config_index); |
2491 sc = ec_master_get_config(master, data.config_index); |
2492 if (!sc) { |
2492 if (!sc) { |
2493 up(&master->master_sem); |
2493 ec_mutex_unlock(&master->master_mutex); |
2494 return -ENOENT; |
2494 return -ENOENT; |
2495 } |
2495 } |
2496 |
2496 |
2497 list_for_each_entry(voe, &sc->voe_handlers, list) { |
2497 list_for_each_entry(voe, &sc->voe_handlers, list) { |
2498 data.voe_index++; |
2498 data.voe_index++; |
2499 } |
2499 } |
2500 |
2500 |
2501 up(&master->master_sem); |
2501 ec_mutex_unlock(&master->master_mutex); |
2502 |
2502 |
2503 voe = ecrt_slave_config_create_voe_handler_err(sc, data.size); |
2503 voe = ecrt_slave_config_create_voe_handler_err(sc, data.size); |
2504 if (IS_ERR(voe)) |
2504 if (IS_ERR(voe)) |
2505 return PTR_ERR(voe); |
2505 return PTR_ERR(voe); |
2506 |
2506 |
2529 |
2529 |
2530 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
2530 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
2531 return -EFAULT; |
2531 return -EFAULT; |
2532 } |
2532 } |
2533 |
2533 |
2534 if (down_interruptible(&master->master_sem)) |
2534 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2535 return -EINTR; |
2535 return -EINTR; |
2536 |
2536 |
2537 if (!(sc = ec_master_get_config_const(master, data.config_index))) { |
2537 if (!(sc = ec_master_get_config_const(master, data.config_index))) { |
2538 up(&master->master_sem); |
2538 ec_mutex_unlock(&master->master_mutex); |
2539 return -ENOENT; |
2539 return -ENOENT; |
2540 } |
2540 } |
2541 |
2541 |
2542 ecrt_slave_config_state(sc, &state); |
2542 ecrt_slave_config_state(sc, &state); |
2543 |
2543 |
2544 up(&master->master_sem); |
2544 ec_mutex_unlock(&master->master_mutex); |
2545 |
2545 |
2546 if (copy_to_user((void __user *) data.state, &state, sizeof(state))) |
2546 if (copy_to_user((void __user *) data.state, &state, sizeof(state))) |
2547 return -EFAULT; |
2547 return -EFAULT; |
2548 |
2548 |
2549 return 0; |
2549 return 0; |
2580 if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) { |
2580 if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) { |
2581 kfree(data); |
2581 kfree(data); |
2582 return -EFAULT; |
2582 return -EFAULT; |
2583 } |
2583 } |
2584 |
2584 |
2585 if (down_interruptible(&master->master_sem)) { |
2585 if (ec_mutex_lock_interruptible(&master->master_mutex)) { |
2586 kfree(data); |
2586 kfree(data); |
2587 return -EINTR; |
2587 return -EINTR; |
2588 } |
2588 } |
2589 |
2589 |
2590 if (!(sc = ec_master_get_config(master, ioctl.config_index))) { |
2590 if (!(sc = ec_master_get_config(master, ioctl.config_index))) { |
2591 up(&master->master_sem); |
2591 ec_mutex_unlock(&master->master_mutex); |
2592 kfree(data); |
2592 kfree(data); |
2593 return -ENOENT; |
2593 return -ENOENT; |
2594 } |
2594 } |
2595 |
2595 |
2596 up(&master->master_sem); // FIXME |
2596 ec_mutex_unlock(&master->master_mutex); // FIXME |
2597 |
2597 |
2598 ret = ecrt_slave_config_idn( |
2598 ret = ecrt_slave_config_idn( |
2599 sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size); |
2599 sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size); |
2600 kfree(data); |
2600 kfree(data); |
2601 return ret; |
2601 return ret; |
2615 const ec_domain_t *domain; |
2615 const ec_domain_t *domain; |
2616 |
2616 |
2617 if (unlikely(!priv->requested)) |
2617 if (unlikely(!priv->requested)) |
2618 return -EPERM; |
2618 return -EPERM; |
2619 |
2619 |
2620 if (down_interruptible(&master->master_sem)) { |
2620 if (ec_mutex_lock_interruptible(&master->master_mutex)) { |
2621 return -EINTR; |
2621 return -EINTR; |
2622 } |
2622 } |
2623 |
2623 |
2624 list_for_each_entry(domain, &master->domains, list) { |
2624 list_for_each_entry(domain, &master->domains, list) { |
2625 if (domain->index == arg) { |
2625 if (domain->index == arg) { |
2626 up(&master->master_sem); |
2626 ec_mutex_unlock(&master->master_mutex); |
2627 return offset; |
2627 return offset; |
2628 } |
2628 } |
2629 offset += ecrt_domain_size(domain); |
2629 offset += ecrt_domain_size(domain); |
2630 } |
2630 } |
2631 |
2631 |
2632 up(&master->master_sem); |
2632 ec_mutex_unlock(&master->master_mutex); |
2633 return -ENOENT; |
2633 return -ENOENT; |
2634 } |
2634 } |
2635 |
2635 |
2636 /*****************************************************************************/ |
2636 /*****************************************************************************/ |
2637 |
2637 |
2646 ec_domain_t *domain; |
2646 ec_domain_t *domain; |
2647 |
2647 |
2648 if (unlikely(!priv->requested)) |
2648 if (unlikely(!priv->requested)) |
2649 return -EPERM; |
2649 return -EPERM; |
2650 |
2650 |
2651 if (down_interruptible(&master->master_sem)) |
2651 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2652 return -EINTR; |
2652 return -EINTR; |
2653 |
2653 |
2654 if (!(domain = ec_master_find_domain(master, arg))) { |
2654 if (!(domain = ec_master_find_domain(master, arg))) { |
2655 up(&master->master_sem); |
2655 ec_mutex_unlock(&master->master_mutex); |
2656 return -ENOENT; |
2656 return -ENOENT; |
2657 } |
2657 } |
2658 |
2658 |
2659 ecrt_domain_process(domain); |
2659 ecrt_domain_process(domain); |
2660 up(&master->master_sem); |
2660 ec_mutex_unlock(&master->master_mutex); |
2661 return 0; |
2661 return 0; |
2662 } |
2662 } |
2663 |
2663 |
2664 /*****************************************************************************/ |
2664 /*****************************************************************************/ |
2665 |
2665 |
2674 ec_domain_t *domain; |
2674 ec_domain_t *domain; |
2675 |
2675 |
2676 if (unlikely(!priv->requested)) |
2676 if (unlikely(!priv->requested)) |
2677 return -EPERM; |
2677 return -EPERM; |
2678 |
2678 |
2679 if (down_interruptible(&master->master_sem)) |
2679 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2680 return -EINTR; |
2680 return -EINTR; |
2681 |
2681 |
2682 if (!(domain = ec_master_find_domain(master, arg))) { |
2682 if (!(domain = ec_master_find_domain(master, arg))) { |
2683 up(&master->master_sem); |
2683 ec_mutex_unlock(&master->master_mutex); |
2684 return -ENOENT; |
2684 return -ENOENT; |
2685 } |
2685 } |
2686 |
2686 |
2687 ecrt_domain_queue(domain); |
2687 ecrt_domain_queue(domain); |
2688 up(&master->master_sem); |
2688 ec_mutex_unlock(&master->master_mutex); |
2689 return 0; |
2689 return 0; |
2690 } |
2690 } |
2691 |
2691 |
2692 /*****************************************************************************/ |
2692 /*****************************************************************************/ |
2693 |
2693 |
2708 |
2708 |
2709 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
2709 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
2710 return -EFAULT; |
2710 return -EFAULT; |
2711 } |
2711 } |
2712 |
2712 |
2713 if (down_interruptible(&master->master_sem)) |
2713 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2714 return -EINTR; |
2714 return -EINTR; |
2715 |
2715 |
2716 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) { |
2716 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) { |
2717 up(&master->master_sem); |
2717 ec_mutex_unlock(&master->master_mutex); |
2718 return -ENOENT; |
2718 return -ENOENT; |
2719 } |
2719 } |
2720 |
2720 |
2721 ecrt_domain_state(domain, &state); |
2721 ecrt_domain_state(domain, &state); |
2722 |
2722 |
2723 up(&master->master_sem); |
2723 ec_mutex_unlock(&master->master_mutex); |
2724 |
2724 |
2725 if (copy_to_user((void __user *) data.state, &state, sizeof(state))) |
2725 if (copy_to_user((void __user *) data.state, &state, sizeof(state))) |
2726 return -EFAULT; |
2726 return -EFAULT; |
2727 |
2727 |
2728 return 0; |
2728 return 0; |
2746 return -EPERM; |
2746 return -EPERM; |
2747 |
2747 |
2748 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2748 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2749 return -EFAULT; |
2749 return -EFAULT; |
2750 |
2750 |
2751 if (down_interruptible(&master->master_sem)) |
2751 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2752 return -EINTR; |
2752 return -EINTR; |
2753 |
2753 |
2754 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2754 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2755 up(&master->master_sem); |
2755 ec_mutex_unlock(&master->master_mutex); |
2756 return -ENOENT; |
2756 return -ENOENT; |
2757 } |
2757 } |
2758 |
2758 |
2759 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2759 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2760 up(&master->master_sem); |
2760 ec_mutex_unlock(&master->master_mutex); |
2761 return -ENOENT; |
2761 return -ENOENT; |
2762 } |
2762 } |
2763 |
2763 |
2764 up(&master->master_sem); |
2764 ec_mutex_unlock(&master->master_mutex); |
2765 |
2765 |
2766 ecrt_sdo_request_timeout(req, data.timeout); |
2766 ecrt_sdo_request_timeout(req, data.timeout); |
2767 return 0; |
2767 return 0; |
2768 } |
2768 } |
2769 |
2769 |
2785 return -EPERM; |
2785 return -EPERM; |
2786 |
2786 |
2787 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2787 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2788 return -EFAULT; |
2788 return -EFAULT; |
2789 |
2789 |
2790 if (down_interruptible(&master->master_sem)) |
2790 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2791 return -EINTR; |
2791 return -EINTR; |
2792 |
2792 |
2793 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2793 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2794 up(&master->master_sem); |
2794 ec_mutex_unlock(&master->master_mutex); |
2795 return -ENOENT; |
2795 return -ENOENT; |
2796 } |
2796 } |
2797 |
2797 |
2798 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2798 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2799 up(&master->master_sem); |
2799 ec_mutex_unlock(&master->master_mutex); |
2800 return -ENOENT; |
2800 return -ENOENT; |
2801 } |
2801 } |
2802 |
2802 |
2803 data.state = ecrt_sdo_request_state(req); |
2803 data.state = ecrt_sdo_request_state(req); |
2804 if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT) |
2804 if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT) |
2805 data.size = ecrt_sdo_request_data_size(req); |
2805 data.size = ecrt_sdo_request_data_size(req); |
2806 else |
2806 else |
2807 data.size = 0; |
2807 data.size = 0; |
2808 |
2808 |
2809 up(&master->master_sem); |
2809 ec_mutex_unlock(&master->master_mutex); |
2810 |
2810 |
2811 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
2811 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
2812 return -EFAULT; |
2812 return -EFAULT; |
2813 |
2813 |
2814 return 0; |
2814 return 0; |
2832 return -EPERM; |
2832 return -EPERM; |
2833 |
2833 |
2834 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2834 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2835 return -EFAULT; |
2835 return -EFAULT; |
2836 |
2836 |
2837 if (down_interruptible(&master->master_sem)) |
2837 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2838 return -EINTR; |
2838 return -EINTR; |
2839 |
2839 |
2840 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2840 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2841 up(&master->master_sem); |
2841 ec_mutex_unlock(&master->master_mutex); |
2842 return -ENOENT; |
2842 return -ENOENT; |
2843 } |
2843 } |
2844 |
2844 |
2845 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2845 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2846 up(&master->master_sem); |
2846 ec_mutex_unlock(&master->master_mutex); |
2847 return -ENOENT; |
2847 return -ENOENT; |
2848 } |
2848 } |
2849 |
2849 |
2850 up(&master->master_sem); |
2850 ec_mutex_unlock(&master->master_mutex); |
2851 |
2851 |
2852 ecrt_sdo_request_read(req); |
2852 ecrt_sdo_request_read(req); |
2853 return 0; |
2853 return 0; |
2854 } |
2854 } |
2855 |
2855 |
2877 if (!data.size) { |
2877 if (!data.size) { |
2878 EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n"); |
2878 EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n"); |
2879 return -EINVAL; |
2879 return -EINVAL; |
2880 } |
2880 } |
2881 |
2881 |
2882 if (down_interruptible(&master->master_sem)) |
2882 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2883 return -EINTR; |
2883 return -EINTR; |
2884 |
2884 |
2885 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2885 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2886 up(&master->master_sem); |
2886 ec_mutex_unlock(&master->master_mutex); |
2887 return -ENOENT; |
2887 return -ENOENT; |
2888 } |
2888 } |
2889 |
2889 |
2890 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2890 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2891 up(&master->master_sem); |
2891 ec_mutex_unlock(&master->master_mutex); |
2892 return -ENOENT; |
2892 return -ENOENT; |
2893 } |
2893 } |
2894 |
2894 |
2895 up(&master->master_sem); |
2895 ec_mutex_unlock(&master->master_mutex); |
2896 |
2896 |
2897 ret = ec_sdo_request_alloc(req, data.size); |
2897 ret = ec_sdo_request_alloc(req, data.size); |
2898 if (ret) |
2898 if (ret) |
2899 return ret; |
2899 return ret; |
2900 |
2900 |
2924 return -EPERM; |
2924 return -EPERM; |
2925 |
2925 |
2926 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2926 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
2927 return -EFAULT; |
2927 return -EFAULT; |
2928 |
2928 |
2929 if (down_interruptible(&master->master_sem)) |
2929 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2930 return -EINTR; |
2930 return -EINTR; |
2931 |
2931 |
2932 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2932 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2933 up(&master->master_sem); |
2933 ec_mutex_unlock(&master->master_mutex); |
2934 return -ENOENT; |
2934 return -ENOENT; |
2935 } |
2935 } |
2936 |
2936 |
2937 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2937 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) { |
2938 up(&master->master_sem); |
2938 ec_mutex_unlock(&master->master_mutex); |
2939 return -ENOENT; |
2939 return -ENOENT; |
2940 } |
2940 } |
2941 |
2941 |
2942 up(&master->master_sem); |
2942 ec_mutex_unlock(&master->master_mutex); |
2943 |
2943 |
2944 if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req), |
2944 if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req), |
2945 ecrt_sdo_request_data_size(req))) |
2945 ecrt_sdo_request_data_size(req))) |
2946 return -EFAULT; |
2946 return -EFAULT; |
2947 |
2947 |
2974 return -EFAULT; |
2974 return -EFAULT; |
2975 |
2975 |
2976 if (get_user(vendor_type, data.vendor_type)) |
2976 if (get_user(vendor_type, data.vendor_type)) |
2977 return -EFAULT; |
2977 return -EFAULT; |
2978 |
2978 |
2979 if (down_interruptible(&master->master_sem)) |
2979 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
2980 return -EINTR; |
2980 return -EINTR; |
2981 |
2981 |
2982 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2982 if (!(sc = ec_master_get_config(master, data.config_index))) { |
2983 up(&master->master_sem); |
2983 ec_mutex_unlock(&master->master_mutex); |
2984 return -ENOENT; |
2984 return -ENOENT; |
2985 } |
2985 } |
2986 |
2986 |
2987 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
2987 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
2988 up(&master->master_sem); |
2988 ec_mutex_unlock(&master->master_mutex); |
2989 return -ENOENT; |
2989 return -ENOENT; |
2990 } |
2990 } |
2991 |
2991 |
2992 up(&master->master_sem); |
2992 ec_mutex_unlock(&master->master_mutex); |
2993 |
2993 |
2994 ecrt_voe_handler_send_header(voe, vendor_id, vendor_type); |
2994 ecrt_voe_handler_send_header(voe, vendor_id, vendor_type); |
2995 return 0; |
2995 return 0; |
2996 } |
2996 } |
2997 |
2997 |
3015 return -EPERM; |
3015 return -EPERM; |
3016 |
3016 |
3017 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3017 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3018 return -EFAULT; |
3018 return -EFAULT; |
3019 |
3019 |
3020 if (down_interruptible(&master->master_sem)) |
3020 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
3021 return -EINTR; |
3021 return -EINTR; |
3022 |
3022 |
3023 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3023 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3024 up(&master->master_sem); |
3024 ec_mutex_unlock(&master->master_mutex); |
3025 return -ENOENT; |
3025 return -ENOENT; |
3026 } |
3026 } |
3027 |
3027 |
3028 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3028 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3029 up(&master->master_sem); |
3029 ec_mutex_unlock(&master->master_mutex); |
3030 return -ENOENT; |
3030 return -ENOENT; |
3031 } |
3031 } |
3032 |
3032 |
3033 ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type); |
3033 ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type); |
3034 |
3034 |
3035 up(&master->master_sem); |
3035 ec_mutex_unlock(&master->master_mutex); |
3036 |
3036 |
3037 if (likely(data.vendor_id)) |
3037 if (likely(data.vendor_id)) |
3038 if (put_user(vendor_id, data.vendor_id)) |
3038 if (put_user(vendor_id, data.vendor_id)) |
3039 return -EFAULT; |
3039 return -EFAULT; |
3040 |
3040 |
3063 return -EPERM; |
3063 return -EPERM; |
3064 |
3064 |
3065 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3065 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3066 return -EFAULT; |
3066 return -EFAULT; |
3067 |
3067 |
3068 if (down_interruptible(&master->master_sem)) |
3068 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
3069 return -EINTR; |
3069 return -EINTR; |
3070 |
3070 |
3071 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3071 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3072 up(&master->master_sem); |
3072 ec_mutex_unlock(&master->master_mutex); |
3073 return -ENOENT; |
3073 return -ENOENT; |
3074 } |
3074 } |
3075 |
3075 |
3076 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3076 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3077 up(&master->master_sem); |
3077 ec_mutex_unlock(&master->master_mutex); |
3078 return -ENOENT; |
3078 return -ENOENT; |
3079 } |
3079 } |
3080 |
3080 |
3081 up(&master->master_sem); |
3081 ec_mutex_unlock(&master->master_mutex); |
3082 |
3082 |
3083 ecrt_voe_handler_read(voe); |
3083 ecrt_voe_handler_read(voe); |
3084 return 0; |
3084 return 0; |
3085 } |
3085 } |
3086 |
3086 |
3102 return -EPERM; |
3102 return -EPERM; |
3103 |
3103 |
3104 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3104 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3105 return -EFAULT; |
3105 return -EFAULT; |
3106 |
3106 |
3107 if (down_interruptible(&master->master_sem)) |
3107 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
3108 return -EINTR; |
3108 return -EINTR; |
3109 |
3109 |
3110 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3110 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3111 up(&master->master_sem); |
3111 ec_mutex_unlock(&master->master_mutex); |
3112 return -ENOENT; |
3112 return -ENOENT; |
3113 } |
3113 } |
3114 |
3114 |
3115 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3115 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3116 up(&master->master_sem); |
3116 ec_mutex_unlock(&master->master_mutex); |
3117 return -ENOENT; |
3117 return -ENOENT; |
3118 } |
3118 } |
3119 |
3119 |
3120 up(&master->master_sem); |
3120 ec_mutex_unlock(&master->master_mutex); |
3121 |
3121 |
3122 ecrt_voe_handler_read_nosync(voe); |
3122 ecrt_voe_handler_read_nosync(voe); |
3123 return 0; |
3123 return 0; |
3124 } |
3124 } |
3125 |
3125 |
3141 return -EPERM; |
3141 return -EPERM; |
3142 |
3142 |
3143 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3143 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3144 return -EFAULT; |
3144 return -EFAULT; |
3145 |
3145 |
3146 if (down_interruptible(&master->master_sem)) |
3146 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
3147 return -EINTR; |
3147 return -EINTR; |
3148 |
3148 |
3149 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3149 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3150 up(&master->master_sem); |
3150 ec_mutex_unlock(&master->master_mutex); |
3151 return -ENOENT; |
3151 return -ENOENT; |
3152 } |
3152 } |
3153 |
3153 |
3154 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3154 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3155 up(&master->master_sem); |
3155 ec_mutex_unlock(&master->master_mutex); |
3156 return -ENOENT; |
3156 return -ENOENT; |
3157 } |
3157 } |
3158 |
3158 |
3159 up(&master->master_sem); |
3159 ec_mutex_unlock(&master->master_mutex); |
3160 |
3160 |
3161 if (data.size) { |
3161 if (data.size) { |
3162 if (data.size > ec_voe_handler_mem_size(voe)) |
3162 if (data.size > ec_voe_handler_mem_size(voe)) |
3163 return -EOVERFLOW; |
3163 return -EOVERFLOW; |
3164 |
3164 |
3189 return -EPERM; |
3189 return -EPERM; |
3190 |
3190 |
3191 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3191 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3192 return -EFAULT; |
3192 return -EFAULT; |
3193 |
3193 |
3194 if (down_interruptible(&master->master_sem)) |
3194 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
3195 return -EINTR; |
3195 return -EINTR; |
3196 |
3196 |
3197 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3197 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3198 up(&master->master_sem); |
3198 ec_mutex_unlock(&master->master_mutex); |
3199 return -ENOENT; |
3199 return -ENOENT; |
3200 } |
3200 } |
3201 |
3201 |
3202 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3202 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3203 up(&master->master_sem); |
3203 ec_mutex_unlock(&master->master_mutex); |
3204 return -ENOENT; |
3204 return -ENOENT; |
3205 } |
3205 } |
3206 |
3206 |
3207 up(&master->master_sem); |
3207 ec_mutex_unlock(&master->master_mutex); |
3208 |
3208 |
3209 data.state = ecrt_voe_handler_execute(voe); |
3209 data.state = ecrt_voe_handler_execute(voe); |
3210 if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT) |
3210 if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT) |
3211 data.size = ecrt_voe_handler_data_size(voe); |
3211 data.size = ecrt_voe_handler_data_size(voe); |
3212 else |
3212 else |
3236 return -EPERM; |
3236 return -EPERM; |
3237 |
3237 |
3238 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3238 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) |
3239 return -EFAULT; |
3239 return -EFAULT; |
3240 |
3240 |
3241 if (down_interruptible(&master->master_sem)) |
3241 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
3242 return -EINTR; |
3242 return -EINTR; |
3243 |
3243 |
3244 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3244 if (!(sc = ec_master_get_config(master, data.config_index))) { |
3245 up(&master->master_sem); |
3245 ec_mutex_unlock(&master->master_mutex); |
3246 return -ENOENT; |
3246 return -ENOENT; |
3247 } |
3247 } |
3248 |
3248 |
3249 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3249 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) { |
3250 up(&master->master_sem); |
3250 ec_mutex_unlock(&master->master_mutex); |
3251 return -ENOENT; |
3251 return -ENOENT; |
3252 } |
3252 } |
3253 |
3253 |
3254 up(&master->master_sem); |
3254 ec_mutex_unlock(&master->master_mutex); |
3255 |
3255 |
3256 if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe), |
3256 if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe), |
3257 ecrt_voe_handler_data_size(voe))) |
3257 ecrt_voe_handler_data_size(voe))) |
3258 return -EFAULT; |
3258 return -EFAULT; |
3259 |
3259 |
3279 |
3279 |
3280 ec_foe_request_init(&request.req, data.file_name); |
3280 ec_foe_request_init(&request.req, data.file_name); |
3281 ec_foe_request_read(&request.req); |
3281 ec_foe_request_read(&request.req); |
3282 ec_foe_request_alloc(&request.req, 10000); // FIXME |
3282 ec_foe_request_alloc(&request.req, 10000); // FIXME |
3283 |
3283 |
3284 if (down_interruptible(&master->master_sem)) |
3284 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
3285 return -EINTR; |
3285 return -EINTR; |
3286 |
3286 |
3287 if (!(request.slave = ec_master_find_slave( |
3287 if (!(request.slave = ec_master_find_slave( |
3288 master, 0, data.slave_position))) { |
3288 master, 0, data.slave_position))) { |
3289 up(&master->master_sem); |
3289 ec_mutex_unlock(&master->master_mutex); |
3290 ec_foe_request_clear(&request.req); |
3290 ec_foe_request_clear(&request.req); |
3291 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
3291 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
3292 data.slave_position); |
3292 data.slave_position); |
3293 return -EINVAL; |
3293 return -EINVAL; |
3294 } |
3294 } |
3295 |
3295 |
3296 // schedule request. |
3296 // schedule request. |
3297 list_add_tail(&request.list, &request.slave->foe_requests); |
3297 list_add_tail(&request.list, &request.slave->foe_requests); |
3298 |
3298 |
3299 up(&master->master_sem); |
3299 ec_mutex_unlock(&master->master_mutex); |
3300 |
3300 |
3301 EC_SLAVE_DBG(request.slave, 1, "Scheduled FoE read request.\n"); |
3301 EC_SLAVE_DBG(request.slave, 1, "Scheduled FoE read request.\n"); |
3302 |
3302 |
3303 // wait for processing through FSM |
3303 // wait for processing through FSM |
3304 if (wait_event_interruptible(request.slave->foe_queue, |
3304 if (wait_event_interruptible(request.slave->foe_queue, |
3305 request.req.state != EC_INT_REQUEST_QUEUED)) { |
3305 request.req.state != EC_INT_REQUEST_QUEUED)) { |
3306 // interrupted by signal |
3306 // interrupted by signal |
3307 down(&master->master_sem); |
3307 ec_mutex_lock(&master->master_mutex); |
3308 if (request.req.state == EC_INT_REQUEST_QUEUED) { |
3308 if (request.req.state == EC_INT_REQUEST_QUEUED) { |
3309 list_del(&request.list); |
3309 list_del(&request.list); |
3310 up(&master->master_sem); |
3310 ec_mutex_unlock(&master->master_mutex); |
3311 ec_foe_request_clear(&request.req); |
3311 ec_foe_request_clear(&request.req); |
3312 return -EINTR; |
3312 return -EINTR; |
3313 } |
3313 } |
3314 // request already processing: interrupt not possible. |
3314 // request already processing: interrupt not possible. |
3315 up(&master->master_sem); |
3315 ec_mutex_unlock(&master->master_mutex); |
3316 } |
3316 } |
3317 |
3317 |
3318 // wait until master FSM has finished processing |
3318 // wait until master FSM has finished processing |
3319 wait_event(request.slave->foe_queue, |
3319 wait_event(request.slave->foe_queue, |
3320 request.req.state != EC_INT_REQUEST_BUSY); |
3320 request.req.state != EC_INT_REQUEST_BUSY); |
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 (down_interruptible(&master->master_sem)) |
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 up(&master->master_sem); |
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 ec_foe_request_clear(&request.req); |
3399 return -EINVAL; |
3399 return -EINVAL; |
3400 } |
3400 } |
3402 EC_SLAVE_DBG(request.slave, 1, "Scheduling FoE write request.\n"); |
3402 EC_SLAVE_DBG(request.slave, 1, "Scheduling FoE write request.\n"); |
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 |
3406 |
3407 up(&master->master_sem); |
3407 ec_mutex_unlock(&master->master_mutex); |
3408 |
3408 |
3409 // wait for processing through FSM |
3409 // wait for processing through FSM |
3410 if (wait_event_interruptible(request.slave->foe_queue, |
3410 if (wait_event_interruptible(request.slave->foe_queue, |
3411 request.req.state != EC_INT_REQUEST_QUEUED)) { |
3411 request.req.state != EC_INT_REQUEST_QUEUED)) { |
3412 // interrupted by signal |
3412 // interrupted by signal |
3413 down(&master->master_sem); |
3413 ec_mutex_lock(&master->master_mutex); |
3414 if (request.req.state == EC_INT_REQUEST_QUEUED) { |
3414 if (request.req.state == EC_INT_REQUEST_QUEUED) { |
3415 // abort request |
3415 // abort request |
3416 list_del(&request.list); |
3416 list_del(&request.list); |
3417 up(&master->master_sem); |
3417 ec_mutex_unlock(&master->master_mutex); |
3418 ec_foe_request_clear(&request.req); |
3418 ec_foe_request_clear(&request.req); |
3419 return -EINTR; |
3419 return -EINTR; |
3420 } |
3420 } |
3421 up(&master->master_sem); |
3421 ec_mutex_unlock(&master->master_mutex); |
3422 } |
3422 } |
3423 |
3423 |
3424 // wait until master FSM has finished processing |
3424 // wait until master FSM has finished processing |
3425 wait_event(request.slave->foe_queue, |
3425 wait_event(request.slave->foe_queue, |
3426 request.req.state != EC_INT_REQUEST_BUSY); |
3426 request.req.state != EC_INT_REQUEST_BUSY); |