1187 |
1187 |
1188 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1188 if (copy_to_user((void __user *) arg, &data, sizeof(data))) |
1189 return -EFAULT; |
1189 return -EFAULT; |
1190 |
1190 |
1191 return 0; |
1191 return 0; |
|
1192 } |
|
1193 |
|
1194 /*****************************************************************************/ |
|
1195 |
|
1196 /** Read a file from a slave via FoE. |
|
1197 */ |
|
1198 int ec_cdev_ioctl_slave_foe_read( |
|
1199 ec_master_t *master, /**< EtherCAT master. */ |
|
1200 unsigned long arg /**< ioctl() argument. */ |
|
1201 ) |
|
1202 { |
|
1203 ec_ioctl_slave_foe_t data; |
|
1204 ec_master_foe_request_t request; |
|
1205 int retval; |
|
1206 |
|
1207 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
|
1208 return -EFAULT; |
|
1209 } |
|
1210 |
|
1211 ec_foe_request_init(&request.req, data.file_name); |
|
1212 ec_foe_request_read(&request.req); |
|
1213 ec_foe_request_alloc(&request.req, 10000); // FIXME |
|
1214 |
|
1215 if (down_interruptible(&master->master_sem)) |
|
1216 return -EINTR; |
|
1217 |
|
1218 if (!(request.slave = ec_master_find_slave( |
|
1219 master, 0, data.slave_position))) { |
|
1220 up(&master->master_sem); |
|
1221 ec_foe_request_clear(&request.req); |
|
1222 EC_ERR("Slave %u does not exist!\n", data.slave_position); |
|
1223 return -EINVAL; |
|
1224 } |
|
1225 |
|
1226 // schedule request. |
|
1227 list_add_tail(&request.list, &master->foe_requests); |
|
1228 |
|
1229 up(&master->master_sem); |
|
1230 |
|
1231 // wait for processing through FSM |
|
1232 if (wait_event_interruptible(master->foe_queue, |
|
1233 request.req.state != EC_REQUEST_QUEUED)) { |
|
1234 // interrupted by signal |
|
1235 down(&master->master_sem); |
|
1236 if (request.req.state == EC_REQUEST_QUEUED) { |
|
1237 list_del(&request.list); |
|
1238 up(&master->master_sem); |
|
1239 ec_foe_request_clear(&request.req); |
|
1240 return -EINTR; |
|
1241 } |
|
1242 // request already processing: interrupt not possible. |
|
1243 up(&master->master_sem); |
|
1244 } |
|
1245 |
|
1246 // wait until master FSM has finished processing |
|
1247 wait_event(master->foe_queue, request.req.state != EC_REQUEST_BUSY); |
|
1248 |
|
1249 data.abort_code = request.req.abort_code; |
|
1250 |
|
1251 if (master->debug_level) { |
|
1252 EC_DBG("%d bytes read via FoE (abort_code = 0x%x).\n", |
|
1253 request.req.data_size, request.req.abort_code); |
|
1254 } |
|
1255 |
|
1256 if (request.req.state != EC_REQUEST_SUCCESS) { |
|
1257 data.data_size = 0; |
|
1258 retval = -EIO; |
|
1259 } else { |
|
1260 if (request.req.data_size > data.buffer_size) { |
|
1261 EC_ERR("Buffer too small.\n"); |
|
1262 ec_foe_request_clear(&request.req); |
|
1263 return -EOVERFLOW; |
|
1264 } |
|
1265 data.data_size = request.req.data_size; |
|
1266 if (copy_to_user((void __user *) data.buffer, |
|
1267 request.req.buffer, data.data_size)) { |
|
1268 ec_foe_request_clear(&request.req); |
|
1269 return -EFAULT; |
|
1270 } |
|
1271 retval = 0; |
|
1272 } |
|
1273 |
|
1274 if (__copy_to_user((void __user *) arg, &data, sizeof(data))) { |
|
1275 retval = -EFAULT; |
|
1276 } |
|
1277 |
|
1278 ec_foe_request_clear(&request.req); |
|
1279 return retval; |
|
1280 } |
|
1281 |
|
1282 /*****************************************************************************/ |
|
1283 |
|
1284 /** Write a file to a slave via FoE |
|
1285 */ |
|
1286 int ec_cdev_ioctl_slave_foe_write( |
|
1287 ec_master_t *master, /**< EtherCAT master. */ |
|
1288 unsigned long arg /**< ioctl() argument. */ |
|
1289 ) |
|
1290 { |
|
1291 ec_ioctl_slave_foe_t data; |
|
1292 ec_master_foe_request_t request; |
|
1293 int retval; |
|
1294 |
|
1295 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { |
|
1296 return -EFAULT; |
|
1297 } |
|
1298 |
|
1299 INIT_LIST_HEAD(&request.list); |
|
1300 |
|
1301 ec_foe_request_init(&request.req, data.file_name); |
|
1302 |
|
1303 if (ec_foe_request_alloc(&request.req, data.buffer_size)) { |
|
1304 ec_foe_request_clear(&request.req); |
|
1305 return -ENOMEM; |
|
1306 } |
|
1307 if (copy_from_user(request.req.buffer, |
|
1308 (void __user *) data.buffer, data.buffer_size)) { |
|
1309 ec_foe_request_clear(&request.req); |
|
1310 return -EFAULT; |
|
1311 } |
|
1312 request.req.data_size = data.buffer_size; |
|
1313 ec_foe_request_write(&request.req); |
|
1314 |
|
1315 if (down_interruptible(&master->master_sem)) |
|
1316 return -EINTR; |
|
1317 |
|
1318 if (!(request.slave = ec_master_find_slave( |
|
1319 master, 0, data.slave_position))) { |
|
1320 up(&master->master_sem); |
|
1321 EC_ERR("Slave %u does not exist!\n", data.slave_position); |
|
1322 ec_foe_request_clear(&request.req); |
|
1323 return -EINVAL; |
|
1324 } |
|
1325 |
|
1326 if (master->debug_level) { |
|
1327 EC_DBG("Scheduling FoE write request.\n"); |
|
1328 } |
|
1329 |
|
1330 // schedule FoE write request. |
|
1331 list_add_tail(&request.list, &master->foe_requests); |
|
1332 |
|
1333 up(&master->master_sem); |
|
1334 |
|
1335 // wait for processing through FSM |
|
1336 if (wait_event_interruptible(master->foe_queue, |
|
1337 request.req.state != EC_REQUEST_QUEUED)) { |
|
1338 // interrupted by signal |
|
1339 down(&master->master_sem); |
|
1340 if (request.req.state == EC_REQUEST_QUEUED) { |
|
1341 // abort request |
|
1342 list_del(&request.list); |
|
1343 up(&master->master_sem); |
|
1344 ec_foe_request_clear(&request.req); |
|
1345 return -EINTR; |
|
1346 } |
|
1347 up(&master->master_sem); |
|
1348 } |
|
1349 |
|
1350 // wait until master FSM has finished processing |
|
1351 wait_event(master->foe_queue, request.req.state != EC_REQUEST_BUSY); |
|
1352 |
|
1353 data.abort_code = request.req.abort_code; |
|
1354 |
|
1355 retval = request.req.state == EC_REQUEST_SUCCESS ? 0 : -EIO; |
|
1356 |
|
1357 if (__copy_to_user((void __user *) arg, &data, sizeof(data))) { |
|
1358 retval = -EFAULT; |
|
1359 } |
|
1360 |
|
1361 ec_foe_request_clear(&request.req); |
|
1362 |
|
1363 if (master->debug_level) { |
|
1364 printk ("Finished FoE writing.\n"); |
|
1365 } |
|
1366 |
|
1367 return retval; |
1192 } |
1368 } |
1193 |
1369 |
1194 /****************************************************************************** |
1370 /****************************************************************************** |
1195 * File operations |
1371 * File operations |
1196 *****************************************************************************/ |
1372 *****************************************************************************/ |
1274 return ec_cdev_ioctl_slave_sii_read(master, arg); |
1450 return ec_cdev_ioctl_slave_sii_read(master, arg); |
1275 case EC_IOCTL_SLAVE_SII_WRITE: |
1451 case EC_IOCTL_SLAVE_SII_WRITE: |
1276 if (!(filp->f_mode & FMODE_WRITE)) |
1452 if (!(filp->f_mode & FMODE_WRITE)) |
1277 return -EPERM; |
1453 return -EPERM; |
1278 return ec_cdev_ioctl_slave_sii_write(master, arg); |
1454 return ec_cdev_ioctl_slave_sii_write(master, arg); |
|
1455 case EC_IOCTL_SLAVE_FOE_READ: |
|
1456 return ec_cdev_ioctl_slave_foe_read(master, arg); |
|
1457 case EC_IOCTL_SLAVE_FOE_WRITE: |
|
1458 if (!(filp->f_mode & FMODE_WRITE)) |
|
1459 return -EPERM; |
|
1460 return ec_cdev_ioctl_slave_foe_write(master, arg); |
1279 case EC_IOCTL_CONFIG: |
1461 case EC_IOCTL_CONFIG: |
1280 return ec_cdev_ioctl_config(master, arg); |
1462 return ec_cdev_ioctl_config(master, arg); |
1281 case EC_IOCTL_CONFIG_PDO: |
1463 case EC_IOCTL_CONFIG_PDO: |
1282 return ec_cdev_ioctl_config_pdo(master, arg); |
1464 return ec_cdev_ioctl_config_pdo(master, arg); |
1283 case EC_IOCTL_CONFIG_PDO_ENTRY: |
1465 case EC_IOCTL_CONFIG_PDO_ENTRY: |