master/cdev.c
changeset 1388 3c886ec376f5
parent 1382 cb2188d111f3
child 1397 6f9294a445c1
equal deleted inserted replaced
1387:57020c731092 1388:3c886ec376f5
  1039     return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  1039     return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  1040 }
  1040 }
  1041 
  1041 
  1042 /*****************************************************************************/
  1042 /*****************************************************************************/
  1043 
  1043 
  1044 /** Read a slave's physical memory.
  1044 /** Read a slave's registers.
  1045  */
  1045  */
  1046 int ec_cdev_ioctl_slave_phy_read(
  1046 int ec_cdev_ioctl_slave_reg_read(
  1047         ec_master_t *master, /**< EtherCAT master. */
  1047         ec_master_t *master, /**< EtherCAT master. */
  1048         unsigned long arg /**< ioctl() argument. */
  1048         unsigned long arg /**< ioctl() argument. */
  1049         )
  1049         )
  1050 {
  1050 {
  1051     ec_ioctl_slave_phy_t data;
  1051     ec_ioctl_slave_reg_t data;
  1052     ec_slave_t *slave;
  1052     ec_slave_t *slave;
  1053     uint8_t *contents;
  1053     uint8_t *contents;
  1054     ec_phy_request_t request;
  1054     ec_reg_request_t request;
  1055 
  1055 
  1056     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  1056     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  1057         return -EFAULT;
  1057         return -EFAULT;
  1058     }
  1058     }
  1059 
  1059 
  1060     if (!data.length)
  1060     if (!data.length)
  1061         return 0;
  1061         return 0;
  1062 
  1062 
  1063     if (!(contents = kmalloc(data.length, GFP_KERNEL))) {
  1063     if (!(contents = kmalloc(data.length, GFP_KERNEL))) {
  1064         EC_ERR("Failed to allocate %u bytes for phy data.\n", data.length);
  1064         EC_ERR("Failed to allocate %u bytes for register data.\n", data.length);
  1065         return -ENOMEM;
  1065         return -ENOMEM;
  1066     }
  1066     }
  1067 
  1067 
  1068     if (down_interruptible(&master->master_sem))
  1068     if (down_interruptible(&master->master_sem))
  1069         return -EINTR;
  1069         return -EINTR;
  1073         up(&master->master_sem);
  1073         up(&master->master_sem);
  1074         EC_ERR("Slave %u does not exist!\n", data.slave_position);
  1074         EC_ERR("Slave %u does not exist!\n", data.slave_position);
  1075         return -EINVAL;
  1075         return -EINVAL;
  1076     }
  1076     }
  1077 
  1077 
  1078     // init phy request
  1078     // init register request
  1079     INIT_LIST_HEAD(&request.list);
  1079     INIT_LIST_HEAD(&request.list);
  1080     request.slave = slave;
  1080     request.slave = slave;
  1081     request.dir = EC_DIR_INPUT;
  1081     request.dir = EC_DIR_INPUT;
  1082     request.data = contents;
  1082     request.data = contents;
  1083     request.offset = data.offset;
  1083     request.offset = data.offset;
  1084     request.length = data.length;
  1084     request.length = data.length;
  1085     request.state = EC_INT_REQUEST_QUEUED;
  1085     request.state = EC_INT_REQUEST_QUEUED;
  1086 
  1086 
  1087     // schedule request.
  1087     // schedule request.
  1088     list_add_tail(&request.list, &master->phy_requests);
  1088     list_add_tail(&request.list, &master->reg_requests);
  1089 
  1089 
  1090     up(&master->master_sem);
  1090     up(&master->master_sem);
  1091 
  1091 
  1092     // wait for processing through FSM
  1092     // wait for processing through FSM
  1093     if (wait_event_interruptible(master->phy_queue,
  1093     if (wait_event_interruptible(master->reg_queue,
  1094                 request.state != EC_INT_REQUEST_QUEUED)) {
  1094                 request.state != EC_INT_REQUEST_QUEUED)) {
  1095         // interrupted by signal
  1095         // interrupted by signal
  1096         down(&master->master_sem);
  1096         down(&master->master_sem);
  1097         if (request.state == EC_INT_REQUEST_QUEUED) {
  1097         if (request.state == EC_INT_REQUEST_QUEUED) {
  1098             // abort request
  1098             // abort request
  1103         }
  1103         }
  1104         up(&master->master_sem);
  1104         up(&master->master_sem);
  1105     }
  1105     }
  1106 
  1106 
  1107     // wait until master FSM has finished processing
  1107     // wait until master FSM has finished processing
  1108     wait_event(master->phy_queue, request.state != EC_INT_REQUEST_BUSY);
  1108     wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY);
  1109 
  1109 
  1110     if (request.state == EC_INT_REQUEST_SUCCESS) {
  1110     if (request.state == EC_INT_REQUEST_SUCCESS) {
  1111         if (copy_to_user((void __user *) data.data, contents, data.length))
  1111         if (copy_to_user((void __user *) data.data, contents, data.length))
  1112             return -EFAULT;
  1112             return -EFAULT;
  1113     }
  1113     }
  1116     return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  1116     return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  1117 }
  1117 }
  1118 
  1118 
  1119 /*****************************************************************************/
  1119 /*****************************************************************************/
  1120 
  1120 
  1121 /** Write a slave's physical memory.
  1121 /** Write a slave's registers.
  1122  */
  1122  */
  1123 int ec_cdev_ioctl_slave_phy_write(
  1123 int ec_cdev_ioctl_slave_reg_write(
  1124         ec_master_t *master, /**< EtherCAT master. */
  1124         ec_master_t *master, /**< EtherCAT master. */
  1125         unsigned long arg /**< ioctl() argument. */
  1125         unsigned long arg /**< ioctl() argument. */
  1126         )
  1126         )
  1127 {
  1127 {
  1128     ec_ioctl_slave_phy_t data;
  1128     ec_ioctl_slave_reg_t data;
  1129     ec_slave_t *slave;
  1129     ec_slave_t *slave;
  1130     uint8_t *contents;
  1130     uint8_t *contents;
  1131     ec_phy_request_t request;
  1131     ec_reg_request_t request;
  1132 
  1132 
  1133     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  1133     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  1134         return -EFAULT;
  1134         return -EFAULT;
  1135     }
  1135     }
  1136 
  1136 
  1137     if (!data.length)
  1137     if (!data.length)
  1138         return 0;
  1138         return 0;
  1139 
  1139 
  1140     if (!(contents = kmalloc(data.length, GFP_KERNEL))) {
  1140     if (!(contents = kmalloc(data.length, GFP_KERNEL))) {
  1141         EC_ERR("Failed to allocate %u bytes for phy data.\n", data.length);
  1141         EC_ERR("Failed to allocate %u bytes for register data.\n", data.length);
  1142         return -ENOMEM;
  1142         return -ENOMEM;
  1143     }
  1143     }
  1144 
  1144 
  1145     if (copy_from_user(contents, (void __user *) data.data, data.length)) {
  1145     if (copy_from_user(contents, (void __user *) data.data, data.length)) {
  1146         kfree(contents);
  1146         kfree(contents);
  1156         EC_ERR("Slave %u does not exist!\n", data.slave_position);
  1156         EC_ERR("Slave %u does not exist!\n", data.slave_position);
  1157         kfree(contents);
  1157         kfree(contents);
  1158         return -EINVAL;
  1158         return -EINVAL;
  1159     }
  1159     }
  1160 
  1160 
  1161     // init phy request
  1161     // init register request
  1162     INIT_LIST_HEAD(&request.list);
  1162     INIT_LIST_HEAD(&request.list);
  1163     request.slave = slave;
  1163     request.slave = slave;
  1164     request.dir = EC_DIR_OUTPUT;
  1164     request.dir = EC_DIR_OUTPUT;
  1165     request.data = contents;
  1165     request.data = contents;
  1166     request.offset = data.offset;
  1166     request.offset = data.offset;
  1167     request.length = data.length;
  1167     request.length = data.length;
  1168     request.state = EC_INT_REQUEST_QUEUED;
  1168     request.state = EC_INT_REQUEST_QUEUED;
  1169 
  1169 
  1170     // schedule request.
  1170     // schedule request.
  1171     list_add_tail(&request.list, &master->phy_requests);
  1171     list_add_tail(&request.list, &master->reg_requests);
  1172 
  1172 
  1173     up(&master->master_sem);
  1173     up(&master->master_sem);
  1174 
  1174 
  1175     // wait for processing through FSM
  1175     // wait for processing through FSM
  1176     if (wait_event_interruptible(master->phy_queue,
  1176     if (wait_event_interruptible(master->reg_queue,
  1177                 request.state != EC_INT_REQUEST_QUEUED)) {
  1177                 request.state != EC_INT_REQUEST_QUEUED)) {
  1178         // interrupted by signal
  1178         // interrupted by signal
  1179         down(&master->master_sem);
  1179         down(&master->master_sem);
  1180         if (request.state == EC_INT_REQUEST_QUEUED) {
  1180         if (request.state == EC_INT_REQUEST_QUEUED) {
  1181             // abort request
  1181             // abort request
  1186         }
  1186         }
  1187         up(&master->master_sem);
  1187         up(&master->master_sem);
  1188     }
  1188     }
  1189 
  1189 
  1190     // wait until master FSM has finished processing
  1190     // wait until master FSM has finished processing
  1191     wait_event(master->phy_queue, request.state != EC_INT_REQUEST_BUSY);
  1191     wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY);
  1192 
  1192 
  1193     kfree(contents);
  1193     kfree(contents);
  1194 
  1194 
  1195     return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  1195     return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  1196 }
  1196 }
  2979             return ec_cdev_ioctl_slave_sii_read(master, arg);
  2979             return ec_cdev_ioctl_slave_sii_read(master, arg);
  2980         case EC_IOCTL_SLAVE_SII_WRITE:
  2980         case EC_IOCTL_SLAVE_SII_WRITE:
  2981             if (!(filp->f_mode & FMODE_WRITE))
  2981             if (!(filp->f_mode & FMODE_WRITE))
  2982                 return -EPERM;
  2982                 return -EPERM;
  2983             return ec_cdev_ioctl_slave_sii_write(master, arg);
  2983             return ec_cdev_ioctl_slave_sii_write(master, arg);
  2984         case EC_IOCTL_SLAVE_PHY_READ:
  2984         case EC_IOCTL_SLAVE_REG_READ:
  2985             return ec_cdev_ioctl_slave_phy_read(master, arg);
  2985             return ec_cdev_ioctl_slave_reg_read(master, arg);
  2986         case EC_IOCTL_SLAVE_PHY_WRITE:
  2986         case EC_IOCTL_SLAVE_REG_WRITE:
  2987             if (!(filp->f_mode & FMODE_WRITE))
  2987             if (!(filp->f_mode & FMODE_WRITE))
  2988                 return -EPERM;
  2988                 return -EPERM;
  2989             return ec_cdev_ioctl_slave_phy_write(master, arg);
  2989             return ec_cdev_ioctl_slave_reg_write(master, arg);
  2990         case EC_IOCTL_SLAVE_FOE_READ:
  2990         case EC_IOCTL_SLAVE_FOE_READ:
  2991             return ec_cdev_ioctl_slave_foe_read(master, arg);
  2991             return ec_cdev_ioctl_slave_foe_read(master, arg);
  2992         case EC_IOCTL_SLAVE_FOE_WRITE:
  2992         case EC_IOCTL_SLAVE_FOE_WRITE:
  2993             if (!(filp->f_mode & FMODE_WRITE))
  2993             if (!(filp->f_mode & FMODE_WRITE))
  2994                 return -EPERM;
  2994                 return -EPERM;