909 |
909 |
910 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
910 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
911 return -EFAULT; |
911 return -EFAULT; |
912 } |
912 } |
913 |
913 |
914 if (!data.nwords) |
914 if (!data.nwords) { |
915 return 0; |
915 return 0; |
|
916 } |
916 |
917 |
917 byte_size = sizeof(uint16_t) * data.nwords; |
918 byte_size = sizeof(uint16_t) * data.nwords; |
918 if (!(words = kmalloc(byte_size, GFP_KERNEL))) { |
919 if (!(words = kmalloc(byte_size, GFP_KERNEL))) { |
919 EC_MASTER_ERR(master, "Failed to allocate %u bytes" |
920 EC_MASTER_ERR(master, "Failed to allocate %u bytes" |
920 " for SII contents.\n", byte_size); |
921 " for SII contents.\n", byte_size); |
925 (void __user *) data.words, byte_size)) { |
926 (void __user *) data.words, byte_size)) { |
926 kfree(words); |
927 kfree(words); |
927 return -EFAULT; |
928 return -EFAULT; |
928 } |
929 } |
929 |
930 |
930 if (down_interruptible(&master->master_sem)) |
931 if (down_interruptible(&master->master_sem)) { |
|
932 kfree(words); |
931 return -EINTR; |
933 return -EINTR; |
|
934 } |
932 |
935 |
933 if (!(slave = ec_master_find_slave( |
936 if (!(slave = ec_master_find_slave( |
934 master, 0, data.slave_position))) { |
937 master, 0, data.slave_position))) { |
935 up(&master->master_sem); |
938 up(&master->master_sem); |
936 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
939 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
951 list_add_tail(&request.list, &master->sii_requests); |
954 list_add_tail(&request.list, &master->sii_requests); |
952 |
955 |
953 up(&master->master_sem); |
956 up(&master->master_sem); |
954 |
957 |
955 // wait for processing through FSM |
958 // wait for processing through FSM |
956 if (wait_event_interruptible(master->sii_queue, |
959 if (wait_event_interruptible(master->request_queue, |
957 request.state != EC_INT_REQUEST_QUEUED)) { |
960 request.state != EC_INT_REQUEST_QUEUED)) { |
958 // interrupted by signal |
961 // interrupted by signal |
959 down(&master->master_sem); |
962 down(&master->master_sem); |
960 if (request.state == EC_INT_REQUEST_QUEUED) { |
963 if (request.state == EC_INT_REQUEST_QUEUED) { |
961 // abort request |
964 // abort request |
1023 list_add_tail(&request.list, &slave->reg_requests); |
1026 list_add_tail(&request.list, &slave->reg_requests); |
1024 |
1027 |
1025 up(&master->master_sem); |
1028 up(&master->master_sem); |
1026 |
1029 |
1027 // wait for processing through FSM |
1030 // wait for processing through FSM |
1028 if (wait_event_interruptible(slave->reg_queue, |
1031 if (wait_event_interruptible(master->request_queue, |
1029 request.state != EC_INT_REQUEST_QUEUED)) { |
1032 request.state != EC_INT_REQUEST_QUEUED)) { |
1030 // interrupted by signal |
1033 // interrupted by signal |
1031 down(&master->master_sem); |
1034 down(&master->master_sem); |
1032 if (request.state == EC_INT_REQUEST_QUEUED) { |
1035 if (request.state == EC_INT_REQUEST_QUEUED) { |
1033 // abort request |
1036 // abort request |
1038 } |
1041 } |
1039 up(&master->master_sem); |
1042 up(&master->master_sem); |
1040 } |
1043 } |
1041 |
1044 |
1042 // wait until master FSM has finished processing |
1045 // wait until master FSM has finished processing |
1043 wait_event(slave->reg_queue, request.state != EC_INT_REQUEST_BUSY); |
1046 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY); |
1044 |
1047 |
1045 if (request.state == EC_INT_REQUEST_SUCCESS) { |
1048 if (request.state == EC_INT_REQUEST_SUCCESS) { |
1046 if (copy_to_user((void __user *) io.data, request.data, io.size)) { |
1049 if (copy_to_user((void __user *) io.data, request.data, io.size)) { |
1047 return -EFAULT; |
1050 return -EFAULT; |
1048 } |
1051 } |
1090 if (down_interruptible(&master->master_sem)) { |
1093 if (down_interruptible(&master->master_sem)) { |
1091 ec_reg_request_clear(&request); |
1094 ec_reg_request_clear(&request); |
1092 return -EINTR; |
1095 return -EINTR; |
1093 } |
1096 } |
1094 |
1097 |
1095 if (!(slave = ec_master_find_slave( |
1098 if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) { |
1096 master, 0, io.slave_position))) { |
|
1097 up(&master->master_sem); |
1099 up(&master->master_sem); |
1098 ec_reg_request_clear(&request); |
1100 ec_reg_request_clear(&request); |
1099 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1101 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1100 io.slave_position); |
1102 io.slave_position); |
1101 return -EINVAL; |
1103 return -EINVAL; |
1105 list_add_tail(&request.list, &slave->reg_requests); |
1107 list_add_tail(&request.list, &slave->reg_requests); |
1106 |
1108 |
1107 up(&master->master_sem); |
1109 up(&master->master_sem); |
1108 |
1110 |
1109 // wait for processing through FSM |
1111 // wait for processing through FSM |
1110 if (wait_event_interruptible(slave->reg_queue, |
1112 if (wait_event_interruptible(master->request_queue, |
1111 request.state != EC_INT_REQUEST_QUEUED)) { |
1113 request.state != EC_INT_REQUEST_QUEUED)) { |
1112 // interrupted by signal |
1114 // interrupted by signal |
1113 down(&master->master_sem); |
1115 down(&master->master_sem); |
1114 if (request.state == EC_INT_REQUEST_QUEUED) { |
1116 if (request.state == EC_INT_REQUEST_QUEUED) { |
1115 // abort request |
1117 // abort request |
1120 } |
1122 } |
1121 up(&master->master_sem); |
1123 up(&master->master_sem); |
1122 } |
1124 } |
1123 |
1125 |
1124 // wait until master FSM has finished processing |
1126 // wait until master FSM has finished processing |
1125 wait_event(slave->reg_queue, request.state != EC_INT_REQUEST_BUSY); |
1127 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY); |
1126 |
1128 |
1127 ec_reg_request_clear(&request); |
1129 ec_reg_request_clear(&request); |
1128 |
1130 |
1129 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
1131 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
1130 } |
1132 } |
3595 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
3597 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
3596 io.slave_position); |
3598 io.slave_position); |
3597 return -EINVAL; |
3599 return -EINVAL; |
3598 } |
3600 } |
3599 |
3601 |
|
3602 EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n"); |
|
3603 |
3600 // schedule request. |
3604 // schedule request. |
3601 list_add_tail(&request.list, &slave->foe_requests); |
3605 list_add_tail(&request.list, &slave->foe_requests); |
3602 |
3606 |
3603 up(&master->master_sem); |
3607 up(&master->master_sem); |
3604 |
3608 |
3605 EC_SLAVE_DBG(slave, 1, "Scheduled FoE read request.\n"); |
|
3606 |
|
3607 // wait for processing through FSM |
3609 // wait for processing through FSM |
3608 if (wait_event_interruptible(slave->foe_queue, |
3610 if (wait_event_interruptible(master->request_queue, |
3609 request.state != EC_INT_REQUEST_QUEUED)) { |
3611 request.state != EC_INT_REQUEST_QUEUED)) { |
3610 // interrupted by signal |
3612 // interrupted by signal |
3611 down(&master->master_sem); |
3613 down(&master->master_sem); |
3612 if (request.state == EC_INT_REQUEST_QUEUED) { |
3614 if (request.state == EC_INT_REQUEST_QUEUED) { |
3613 list_del(&request.list); |
3615 list_del(&request.list); |
3617 } |
3619 } |
3618 // request already processing: interrupt not possible. |
3620 // request already processing: interrupt not possible. |
3619 up(&master->master_sem); |
3621 up(&master->master_sem); |
3620 } |
3622 } |
3621 |
3623 |
3622 // FIXME slave may become invalid |
|
3623 |
|
3624 // wait until master FSM has finished processing |
3624 // wait until master FSM has finished processing |
3625 wait_event(slave->foe_queue, request.state != EC_INT_REQUEST_BUSY); |
3625 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY); |
3626 |
3626 |
3627 io.result = request.result; |
3627 io.result = request.result; |
3628 io.error_code = request.error_code; |
3628 io.error_code = request.error_code; |
3629 |
|
3630 EC_SLAVE_DBG(slave, 1, "Read %zd bytes via FoE (result = 0x%x).\n", |
|
3631 request.data_size, request.result); |
|
3632 |
3629 |
3633 if (request.state != EC_INT_REQUEST_SUCCESS) { |
3630 if (request.state != EC_INT_REQUEST_SUCCESS) { |
3634 io.data_size = 0; |
3631 io.data_size = 0; |
3635 ret = -EIO; |
3632 ret = -EIO; |
3636 } else { |
3633 } else { |
3650 |
3647 |
3651 if (__copy_to_user((void __user *) arg, &io, sizeof(io))) { |
3648 if (__copy_to_user((void __user *) arg, &io, sizeof(io))) { |
3652 ret = -EFAULT; |
3649 ret = -EFAULT; |
3653 } |
3650 } |
3654 |
3651 |
3655 EC_SLAVE_DBG(slave, 1, "Finished FoE read request.\n"); |
|
3656 |
|
3657 ec_foe_request_clear(&request); |
3652 ec_foe_request_clear(&request); |
3658 |
|
3659 return ret; |
3653 return ret; |
3660 } |
3654 } |
3661 |
3655 |
3662 /*****************************************************************************/ |
3656 /*****************************************************************************/ |
3663 |
3657 |
3713 list_add_tail(&request.list, &slave->foe_requests); |
3707 list_add_tail(&request.list, &slave->foe_requests); |
3714 |
3708 |
3715 up(&master->master_sem); |
3709 up(&master->master_sem); |
3716 |
3710 |
3717 // wait for processing through FSM |
3711 // wait for processing through FSM |
3718 if (wait_event_interruptible(slave->foe_queue, |
3712 if (wait_event_interruptible(master->request_queue, |
3719 request.state != EC_INT_REQUEST_QUEUED)) { |
3713 request.state != EC_INT_REQUEST_QUEUED)) { |
3720 // interrupted by signal |
3714 // interrupted by signal |
3721 down(&master->master_sem); |
3715 down(&master->master_sem); |
3722 if (request.state == EC_INT_REQUEST_QUEUED) { |
3716 if (request.state == EC_INT_REQUEST_QUEUED) { |
3723 // abort request |
3717 // abort request |
3727 return -EINTR; |
3721 return -EINTR; |
3728 } |
3722 } |
3729 up(&master->master_sem); |
3723 up(&master->master_sem); |
3730 } |
3724 } |
3731 |
3725 |
3732 // FIXME slave may become invalid |
|
3733 |
|
3734 // wait until master FSM has finished processing |
3726 // wait until master FSM has finished processing |
3735 wait_event(slave->foe_queue, request.state != EC_INT_REQUEST_BUSY); |
3727 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY); |
3736 |
3728 |
3737 io.result = request.result; |
3729 io.result = request.result; |
3738 io.error_code = request.error_code; |
3730 io.error_code = request.error_code; |
3739 |
3731 |
3740 ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
3732 ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
3742 if (__copy_to_user((void __user *) arg, &io, sizeof(io))) { |
3734 if (__copy_to_user((void __user *) arg, &io, sizeof(io))) { |
3743 ret = -EFAULT; |
3735 ret = -EFAULT; |
3744 } |
3736 } |
3745 |
3737 |
3746 ec_foe_request_clear(&request); |
3738 ec_foe_request_clear(&request); |
3747 |
|
3748 EC_SLAVE_DBG(slave, 1, "Finished FoE write request.\n"); |
|
3749 |
|
3750 return ret; |
3739 return ret; |
3751 } |
3740 } |
3752 |
3741 |
3753 /*****************************************************************************/ |
3742 /*****************************************************************************/ |
3754 |
3743 |