2342 } |
2342 } |
2343 } |
2343 } |
2344 |
2344 |
2345 /*****************************************************************************/ |
2345 /*****************************************************************************/ |
2346 |
2346 |
|
2347 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, |
|
2348 uint16_t idn, uint8_t *data, size_t data_size, uint16_t *error_code) |
|
2349 { |
|
2350 ec_master_soe_request_t request; |
|
2351 int retval; |
|
2352 |
|
2353 INIT_LIST_HEAD(&request.list); |
|
2354 ec_soe_request_init(&request.req); |
|
2355 ec_soe_request_set_idn(&request.req, idn); |
|
2356 |
|
2357 if (ec_soe_request_alloc(&request.req, data_size)) { |
|
2358 ec_soe_request_clear(&request.req); |
|
2359 return -ENOMEM; |
|
2360 } |
|
2361 |
|
2362 memcpy(request.req.data, data, data_size); |
|
2363 request.req.data_size = data_size; |
|
2364 ec_soe_request_write(&request.req); |
|
2365 |
|
2366 if (down_interruptible(&master->master_sem)) |
|
2367 return -EINTR; |
|
2368 |
|
2369 if (!(request.slave = ec_master_find_slave( |
|
2370 master, 0, slave_position))) { |
|
2371 up(&master->master_sem); |
|
2372 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
|
2373 slave_position); |
|
2374 ec_soe_request_clear(&request.req); |
|
2375 return -EINVAL; |
|
2376 } |
|
2377 |
|
2378 EC_SLAVE_DBG(request.slave, 1, "Scheduling SoE write request.\n"); |
|
2379 |
|
2380 // schedule SoE write request. |
|
2381 list_add_tail(&request.list, &request.slave->soe_requests); |
|
2382 |
|
2383 up(&master->master_sem); |
|
2384 |
|
2385 // wait for processing through FSM |
|
2386 if (wait_event_interruptible(request.slave->soe_queue, |
|
2387 request.req.state != EC_INT_REQUEST_QUEUED)) { |
|
2388 // interrupted by signal |
|
2389 down(&master->master_sem); |
|
2390 if (request.req.state == EC_INT_REQUEST_QUEUED) { |
|
2391 // abort request |
|
2392 list_del(&request.list); |
|
2393 up(&master->master_sem); |
|
2394 ec_soe_request_clear(&request.req); |
|
2395 return -EINTR; |
|
2396 } |
|
2397 up(&master->master_sem); |
|
2398 } |
|
2399 |
|
2400 // wait until master FSM has finished processing |
|
2401 wait_event(request.slave->soe_queue, |
|
2402 request.req.state != EC_INT_REQUEST_BUSY); |
|
2403 |
|
2404 if (error_code) { |
|
2405 *error_code = request.req.error_code; |
|
2406 } |
|
2407 retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
|
2408 ec_soe_request_clear(&request.req); |
|
2409 |
|
2410 return retval; |
|
2411 } |
|
2412 |
|
2413 /*****************************************************************************/ |
|
2414 |
|
2415 int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position, |
|
2416 uint16_t idn, uint8_t *target, size_t target_size, |
|
2417 size_t *result_size, uint16_t *error_code) |
|
2418 { |
|
2419 ec_master_soe_request_t request; |
|
2420 |
|
2421 INIT_LIST_HEAD(&request.list); |
|
2422 ec_soe_request_init(&request.req); |
|
2423 ec_soe_request_set_idn(&request.req, idn); |
|
2424 ec_soe_request_read(&request.req); |
|
2425 |
|
2426 if (down_interruptible(&master->master_sem)) |
|
2427 return -EINTR; |
|
2428 |
|
2429 if (!(request.slave = ec_master_find_slave(master, 0, slave_position))) { |
|
2430 up(&master->master_sem); |
|
2431 ec_soe_request_clear(&request.req); |
|
2432 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position); |
|
2433 return -EINVAL; |
|
2434 } |
|
2435 |
|
2436 // schedule request. |
|
2437 list_add_tail(&request.list, &request.slave->soe_requests); |
|
2438 |
|
2439 up(&master->master_sem); |
|
2440 |
|
2441 EC_SLAVE_DBG(request.slave, 1, "Scheduled SoE read request.\n"); |
|
2442 |
|
2443 // wait for processing through FSM |
|
2444 if (wait_event_interruptible(request.slave->soe_queue, |
|
2445 request.req.state != EC_INT_REQUEST_QUEUED)) { |
|
2446 // interrupted by signal |
|
2447 down(&master->master_sem); |
|
2448 if (request.req.state == EC_INT_REQUEST_QUEUED) { |
|
2449 list_del(&request.list); |
|
2450 up(&master->master_sem); |
|
2451 ec_soe_request_clear(&request.req); |
|
2452 return -EINTR; |
|
2453 } |
|
2454 // request already processing: interrupt not possible. |
|
2455 up(&master->master_sem); |
|
2456 } |
|
2457 |
|
2458 // wait until master FSM has finished processing |
|
2459 wait_event(request.slave->soe_queue, |
|
2460 request.req.state != EC_INT_REQUEST_BUSY); |
|
2461 |
|
2462 if (error_code) { |
|
2463 *error_code = request.req.error_code; |
|
2464 } |
|
2465 |
|
2466 EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via SoE.\n", |
|
2467 request.req.data_size); |
|
2468 |
|
2469 if (request.req.state != EC_INT_REQUEST_SUCCESS) { |
|
2470 if (result_size) { |
|
2471 *result_size = 0; |
|
2472 } |
|
2473 ec_soe_request_clear(&request.req); |
|
2474 return -EIO; |
|
2475 } else { |
|
2476 if (request.req.data_size > target_size) { |
|
2477 EC_MASTER_ERR(master, "Buffer too small.\n"); |
|
2478 ec_soe_request_clear(&request.req); |
|
2479 return -EOVERFLOW; |
|
2480 } |
|
2481 if (result_size) { |
|
2482 *result_size = request.req.data_size; |
|
2483 } |
|
2484 memcpy(target, request.req.data, request.req.data_size); |
|
2485 return 0; |
|
2486 } |
|
2487 } |
|
2488 |
|
2489 /*****************************************************************************/ |
|
2490 |
2347 /** \cond */ |
2491 /** \cond */ |
2348 |
2492 |
2349 EXPORT_SYMBOL(ecrt_master_create_domain); |
2493 EXPORT_SYMBOL(ecrt_master_create_domain); |
2350 EXPORT_SYMBOL(ecrt_master_activate); |
2494 EXPORT_SYMBOL(ecrt_master_activate); |
2351 EXPORT_SYMBOL(ecrt_master_deactivate); |
2495 EXPORT_SYMBOL(ecrt_master_deactivate); |