460 ec_pollfunc_t poll, /**< device poll function */ |
475 ec_pollfunc_t poll, /**< device poll function */ |
461 struct module *module /**< pointer to the module */ |
476 struct module *module /**< pointer to the module */ |
462 ) |
477 ) |
463 { |
478 { |
464 ec_master_t *master; |
479 ec_master_t *master; |
465 char str[20]; |
480 char str[EC_MAX_MAC_STRING_SIZE]; |
466 unsigned int i; |
481 unsigned int i, dev_idx; |
467 |
482 |
468 for (i = 0; i < master_count; i++) { |
483 for (i = 0; i < master_count; i++) { |
469 master = &masters[i]; |
484 master = &masters[i]; |
470 |
485 ec_mac_print(net_dev->dev_addr, str); |
471 ec_mutex_lock(&master->device_mutex); |
486 |
472 if (master->main_device.dev) { // master already has a device |
487 if (down_interruptible(&master->device_sem)) { |
473 ec_mutex_unlock(&master->device_mutex); |
488 EC_MASTER_WARN(master, "%s() interrupted!\n", __func__); |
474 continue; |
489 return NULL; |
475 } |
490 } |
476 |
491 |
477 if (ec_mac_equal(master->main_mac, net_dev->dev_addr) |
492 for (dev_idx = EC_DEVICE_MAIN; |
478 || ec_mac_is_broadcast(master->main_mac)) { |
493 dev_idx < ec_master_num_devices(master); dev_idx++) { |
479 ec_mac_print(net_dev->dev_addr, str); |
494 if (!master->devices[dev_idx].dev |
480 EC_INFO("Accepting device %s for master %u.\n", |
495 && (ec_mac_equal(master->macs[dev_idx], net_dev->dev_addr) |
481 str, master->index); |
496 || ec_mac_is_broadcast(master->macs[dev_idx]))) { |
482 |
497 |
483 ec_device_attach(&master->main_device, net_dev, poll, module); |
498 EC_INFO("Accepting %s as %s device for master %u.\n", |
484 ec_mutex_unlock(&master->device_mutex); |
499 str, ec_device_names[dev_idx != 0], master->index); |
485 |
500 |
486 snprintf(net_dev->name, IFNAMSIZ, "ec%u", master->index); |
501 ec_device_attach(&master->devices[dev_idx], |
487 |
502 net_dev, poll, module); |
488 return &master->main_device; // offer accepted |
503 up(&master->device_sem); |
489 } |
504 |
490 else { |
505 snprintf(net_dev->name, IFNAMSIZ, "ec%c%u", |
491 ec_mutex_unlock(&master->device_mutex); |
506 ec_device_names[dev_idx != 0][0], master->index); |
492 |
507 |
493 if (master->debug_level) { |
508 return &master->devices[dev_idx]; // offer accepted |
494 ec_mac_print(net_dev->dev_addr, str); |
|
495 EC_MASTER_DBG(master, 0, "Master declined device %s.\n", |
|
496 str); |
|
497 } |
509 } |
498 } |
510 } |
|
511 |
|
512 up(&master->device_sem); |
|
513 |
|
514 EC_MASTER_DBG(master, 1, "Master declined device %s.\n", str); |
499 } |
515 } |
500 |
516 |
501 return NULL; // offer declined |
517 return NULL; // offer declined |
502 } |
518 } |
503 |
519 |
504 /****************************************************************************** |
520 /****************************************************************************** |
505 * Realtime interface |
521 * Application interface |
506 *****************************************************************************/ |
522 *****************************************************************************/ |
507 |
523 |
508 /** Request a master. |
524 /** Request a master. |
509 * |
525 * |
510 * Same as ecrt_request_master(), but with ERR_PTR() return value. |
526 * Same as ecrt_request_master(), but with ERR_PTR() return value. |
|
527 * |
|
528 * \return Requested master. |
511 */ |
529 */ |
512 ec_master_t *ecrt_request_master_err( |
530 ec_master_t *ecrt_request_master_err( |
513 unsigned int master_index /**< Master index. */ |
531 unsigned int master_index /**< Master index. */ |
514 ) |
532 ) |
515 { |
533 { |
516 ec_master_t *master, *errptr = NULL; |
534 ec_master_t *master, *errptr = NULL; |
|
535 unsigned int dev_idx = EC_DEVICE_MAIN; |
517 |
536 |
518 EC_INFO("Requesting master %u...\n", master_index); |
537 EC_INFO("Requesting master %u...\n", master_index); |
519 |
538 |
520 if (master_index >= master_count) { |
539 if (master_index >= master_count) { |
521 EC_ERR("Invalid master index %u.\n", master_index); |
540 EC_ERR("Invalid master index %u.\n", master_index); |
522 errptr = ERR_PTR(-EINVAL); |
541 errptr = ERR_PTR(-EINVAL); |
523 goto out_return; |
542 goto out_return; |
524 } |
543 } |
525 master = &masters[master_index]; |
544 master = &masters[master_index]; |
526 |
545 |
527 if (ec_mutex_lock_interruptible(&master_mutex)) { |
546 if (down_interruptible(&master_sem)) { |
528 errptr = ERR_PTR(-EINTR); |
547 errptr = ERR_PTR(-EINTR); |
529 goto out_return; |
548 goto out_return; |
530 } |
549 } |
531 |
550 |
532 if (master->reserved) { |
551 if (master->reserved) { |
533 ec_mutex_unlock(&master_mutex); |
552 up(&master_sem); |
534 EC_MASTER_ERR(master, "Master already in use!\n"); |
553 EC_MASTER_ERR(master, "Master already in use!\n"); |
535 errptr = ERR_PTR(-EBUSY); |
554 errptr = ERR_PTR(-EBUSY); |
536 goto out_return; |
555 goto out_return; |
537 } |
556 } |
538 master->reserved = 1; |
557 master->reserved = 1; |
539 ec_mutex_unlock(&master_mutex); |
558 up(&master_sem); |
540 |
559 |
541 if (ec_mutex_lock_interruptible(&master->device_mutex)) { |
560 if (down_interruptible(&master->device_sem)) { |
542 errptr = ERR_PTR(-EINTR); |
561 errptr = ERR_PTR(-EINTR); |
543 goto out_release; |
562 goto out_release; |
544 } |
563 } |
545 |
564 |
546 if (master->phase != EC_IDLE) { |
565 if (master->phase != EC_IDLE) { |
547 ec_mutex_unlock(&master->device_mutex); |
566 up(&master->device_sem); |
548 EC_MASTER_ERR(master, "Master still waiting for devices!\n"); |
567 EC_MASTER_ERR(master, "Master still waiting for devices!\n"); |
549 errptr = ERR_PTR(-ENODEV); |
568 errptr = ERR_PTR(-ENODEV); |
550 goto out_release; |
569 goto out_release; |
551 } |
570 } |
552 |
571 |
553 if (!try_module_get(master->main_device.module)) { |
572 for (; dev_idx < ec_master_num_devices(master); dev_idx++) { |
554 ec_mutex_unlock(&master->device_mutex); |
573 ec_device_t *device = &master->devices[dev_idx]; |
555 EC_ERR("Device module is unloading!\n"); |
574 if (!try_module_get(device->module)) { |
556 errptr = ERR_PTR(-ENODEV); |
575 up(&master->device_sem); |
557 goto out_release; |
576 EC_MASTER_ERR(master, "Device module is unloading!\n"); |
558 } |
577 errptr = ERR_PTR(-ENODEV); |
559 |
578 goto out_module_put; |
560 ec_mutex_unlock(&master->device_mutex); |
579 } |
|
580 } |
|
581 |
|
582 up(&master->device_sem); |
561 |
583 |
562 if (ec_master_enter_operation_phase(master)) { |
584 if (ec_master_enter_operation_phase(master)) { |
563 EC_MASTER_ERR(master, "Failed to enter OPERATION phase!\n"); |
585 EC_MASTER_ERR(master, "Failed to enter OPERATION phase!\n"); |
564 errptr = ERR_PTR(-EIO); |
586 errptr = ERR_PTR(-EIO); |
565 goto out_module_put; |
587 goto out_module_put; |
586 |
611 |
587 /*****************************************************************************/ |
612 /*****************************************************************************/ |
588 |
613 |
589 void ecrt_release_master(ec_master_t *master) |
614 void ecrt_release_master(ec_master_t *master) |
590 { |
615 { |
|
616 unsigned int dev_idx; |
|
617 |
591 EC_MASTER_INFO(master, "Releasing master...\n"); |
618 EC_MASTER_INFO(master, "Releasing master...\n"); |
592 |
619 |
593 if (!master->reserved) { |
620 if (!master->reserved) { |
594 EC_MASTER_WARN(master, "%s(): Master was was not requested!\n", |
621 EC_MASTER_WARN(master, "%s(): Master was was not requested!\n", |
595 __func__); |
622 __func__); |
596 return; |
623 return; |
597 } |
624 } |
598 |
625 |
599 ec_master_leave_operation_phase(master); |
626 ec_master_leave_operation_phase(master); |
600 |
627 |
601 module_put(master->main_device.module); |
628 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master); |
|
629 dev_idx++) { |
|
630 module_put(master->devices[dev_idx].module); |
|
631 } |
|
632 |
602 master->reserved = 0; |
633 master->reserved = 0; |
603 |
634 |
604 EC_MASTER_INFO(master, "Released.\n"); |
635 EC_MASTER_INFO(master, "Released.\n"); |
605 } |
636 } |
606 |
637 |
607 /*****************************************************************************/ |
638 /*****************************************************************************/ |
608 |
639 |
609 unsigned int ecrt_version_magic(void) |
640 unsigned int ecrt_version_magic(void) |
610 { |
641 { |
611 return ECRT_VERSION_MAGIC; |
642 return ECRT_VERSION_MAGIC; |
612 } |
|
613 |
|
614 /*****************************************************************************/ |
|
615 |
|
616 /** Return pointer to running master |
|
617 */ |
|
618 ec_master_t *ecrt_attach_master(unsigned int master_index) |
|
619 { |
|
620 ec_master_t *master = NULL; |
|
621 |
|
622 EC_INFO("Requesting master %u...\n", master_index); |
|
623 |
|
624 if (master_index >= master_count) { |
|
625 EC_ERR("Invalid master index %u.\n", master_index); |
|
626 return master; |
|
627 } |
|
628 |
|
629 master = &masters[master_index]; |
|
630 if (master->reserved) { |
|
631 // ok master is attached |
|
632 EC_INFO("attaching Master %u!\n", master_index); |
|
633 } else { |
|
634 EC_ERR("No Master %u in use!\n", master_index); |
|
635 master = NULL; |
|
636 } |
|
637 return master; |
|
638 } |
643 } |
639 |
644 |
640 /*****************************************************************************/ |
645 /*****************************************************************************/ |
641 |
646 |
642 /** Global request state type translation table. |
647 /** Global request state type translation table. |