461 * Realtime interface |
462 * Realtime interface |
462 *****************************************************************************/ |
463 *****************************************************************************/ |
463 |
464 |
464 ec_master_t *ecrt_request_master(unsigned int master_index) |
465 ec_master_t *ecrt_request_master(unsigned int master_index) |
465 { |
466 { |
466 ec_master_t *master; |
467 ec_master_t *master, *errptr = NULL; |
467 |
468 |
468 EC_INFO("Requesting master %u...\n", master_index); |
469 EC_INFO("Requesting master %u...\n", master_index); |
469 |
470 |
470 if (master_index >= master_count) { |
471 if (master_index >= master_count) { |
471 EC_ERR("Invalid master index %u.\n", master_index); |
472 EC_ERR("Invalid master index %u.\n", master_index); |
|
473 errptr = ERR_PTR(-EINVAL); |
472 goto out_return; |
474 goto out_return; |
473 } |
475 } |
474 master = &masters[master_index]; |
476 master = &masters[master_index]; |
475 |
477 |
476 if (down_interruptible(&master_sem)) |
478 if (down_interruptible(&master_sem)) { |
|
479 errptr = ERR_PTR(-EINTR); |
477 goto out_return; |
480 goto out_return; |
|
481 } |
478 |
482 |
479 if (master->reserved) { |
483 if (master->reserved) { |
480 up(&master_sem); |
484 up(&master_sem); |
481 EC_ERR("Master %u is already in use!\n", master_index); |
485 EC_ERR("Master %u is already in use!\n", master_index); |
|
486 errptr = ERR_PTR(-EBUSY); |
482 goto out_return; |
487 goto out_return; |
483 } |
488 } |
484 master->reserved = 1; |
489 master->reserved = 1; |
485 up(&master_sem); |
490 up(&master_sem); |
486 |
491 |
487 if (down_interruptible(&master->device_sem)) |
492 if (down_interruptible(&master->device_sem)) { |
|
493 errptr = ERR_PTR(-EINTR); |
488 goto out_release; |
494 goto out_release; |
|
495 } |
489 |
496 |
490 if (master->phase != EC_IDLE) { |
497 if (master->phase != EC_IDLE) { |
491 up(&master->device_sem); |
498 up(&master->device_sem); |
492 EC_ERR("Master %u still waiting for devices!\n", master_index); |
499 EC_ERR("Master %u still waiting for devices!\n", master_index); |
|
500 errptr = ERR_PTR(-ENODEV); |
493 goto out_release; |
501 goto out_release; |
494 } |
502 } |
495 |
503 |
496 if (!try_module_get(master->main_device.module)) { |
504 if (!try_module_get(master->main_device.module)) { |
497 up(&master->device_sem); |
505 up(&master->device_sem); |
498 EC_ERR("Device module is unloading!\n"); |
506 EC_ERR("Device module is unloading!\n"); |
|
507 errptr = ERR_PTR(-ENODEV); |
499 goto out_release; |
508 goto out_release; |
500 } |
509 } |
501 |
510 |
502 up(&master->device_sem); |
511 up(&master->device_sem); |
503 |
512 |
504 if (ec_master_enter_operation_phase(master)) { |
513 if (ec_master_enter_operation_phase(master)) { |
505 EC_ERR("Failed to enter OPERATION phase!\n"); |
514 EC_ERR("Failed to enter OPERATION phase!\n"); |
|
515 errptr = ERR_PTR(-EIO); |
506 goto out_module_put; |
516 goto out_module_put; |
507 } |
517 } |
508 |
518 |
509 EC_INFO("Successfully requested master %u.\n", master_index); |
519 EC_INFO("Successfully requested master %u.\n", master_index); |
510 return master; |
520 return master; |