master/cdev.c
branch1.4-foe
changeset 1707 11ec009e145d
parent 1687 5c40af734120
child 1708 fae3a1759126
equal deleted inserted replaced
1706:c55ebaa206f8 1707:11ec009e145d
  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: