master/ioctl.c
branchstable-1.5
changeset 2467 74ede087bc85
parent 2464 e6cc33cac6a2
child 2474 fb2fe8fae501
equal deleted inserted replaced
2466:a0b686241178 2467:74ede087bc85
   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
   966         }
   969         }
   967         up(&master->master_sem);
   970         up(&master->master_sem);
   968     }
   971     }
   969 
   972 
   970     // wait until master FSM has finished processing
   973     // wait until master FSM has finished processing
   971     wait_event(master->sii_queue, request.state != EC_INT_REQUEST_BUSY);
   974     wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
   972 
   975 
   973     kfree(words);
   976     kfree(words);
   974 
   977 
   975     return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
   978     return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
   976 }
   979 }
  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