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 |
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; |