391 /** Offers an EtherCAT device to a certain master. |
391 /** Offers an EtherCAT device to a certain master. |
392 * |
392 * |
393 * The master decides, if it wants to use the device for EtherCAT operation, |
393 * The master decides, if it wants to use the device for EtherCAT operation, |
394 * or not. It is important, that the offered net_device is not used by the |
394 * or not. It is important, that the offered net_device is not used by the |
395 * kernel IP stack. If the master, accepted the offer, the address of the |
395 * kernel IP stack. If the master, accepted the offer, the address of the |
396 * newly created EtherCAT device is written to the ecdev pointer, else the |
396 * newly created EtherCAT device is returned, else \a NULL is returned. |
397 * pointer is written to zero. |
397 * |
398 * |
398 * \return Pointer to device, if accepted, or NULL if declined. |
399 * \return 0 on success, else < 0 |
|
400 * \ingroup DeviceInterface |
399 * \ingroup DeviceInterface |
401 */ |
400 */ |
402 int ecdev_offer(struct net_device *net_dev, /**< net_device to offer */ |
401 ec_device_t *ecdev_offer( |
|
402 struct net_device *net_dev, /**< net_device to offer */ |
403 ec_pollfunc_t poll, /**< device poll function */ |
403 ec_pollfunc_t poll, /**< device poll function */ |
404 struct module *module, /**< pointer to the module */ |
404 struct module *module /**< pointer to the module */ |
405 ec_device_t **ecdev /**< pointer to store a device on success */ |
|
406 ) |
405 ) |
407 { |
406 { |
408 ec_master_t *master; |
407 ec_master_t *master; |
409 char str[20]; |
408 char str[20]; |
410 unsigned int i; |
409 unsigned int i; |
426 |
425 |
427 ec_device_attach(&master->main_device, net_dev, poll, module); |
426 ec_device_attach(&master->main_device, net_dev, poll, module); |
428 up(&master->device_sem); |
427 up(&master->device_sem); |
429 |
428 |
430 sprintf(net_dev->name, "ec%u", master->index); |
429 sprintf(net_dev->name, "ec%u", master->index); |
431 *ecdev = &master->main_device; // offer accepted |
430 return &master->main_device; // offer accepted |
432 return 0; // no error |
|
433 } |
431 } |
434 else { |
432 else { |
435 up(&master->device_sem); |
433 up(&master->device_sem); |
436 |
434 |
437 if (master->debug_level) { |
435 if (master->debug_level) { |
439 EC_DBG("Master %u declined device %s.\n", master->index, str); |
437 EC_DBG("Master %u declined device %s.\n", master->index, str); |
440 } |
438 } |
441 } |
439 } |
442 } |
440 } |
443 |
441 |
444 *ecdev = NULL; // offer declined |
442 return NULL; // offer declined |
445 return 0; // no error |
|
446 } |
|
447 |
|
448 /*****************************************************************************/ |
|
449 |
|
450 /** Withdraws an EtherCAT device from the master. |
|
451 * |
|
452 * The device is disconnected from the master and all device ressources |
|
453 * are freed. |
|
454 * |
|
455 * \attention Before calling this function, the ecdev_stop() function has |
|
456 * to be called, to be sure that the master does not use the device |
|
457 * any more. |
|
458 * \ingroup DeviceInterface |
|
459 */ |
|
460 void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */) |
|
461 { |
|
462 ec_master_t *master = device->master; |
|
463 char str[20]; |
|
464 |
|
465 ec_mac_print(device->dev->dev_addr, str); |
|
466 EC_INFO("Master %u releasing main device %s.\n", master->index, str); |
|
467 |
|
468 down(&master->device_sem); |
|
469 ec_device_detach(device); |
|
470 up(&master->device_sem); |
|
471 } |
|
472 |
|
473 /*****************************************************************************/ |
|
474 |
|
475 /** Opens the network device and makes the master enter IDLE mode. |
|
476 * |
|
477 * \return 0 on success, else < 0 |
|
478 * \ingroup DeviceInterface |
|
479 */ |
|
480 int ecdev_open(ec_device_t *device /**< EtherCAT device */) |
|
481 { |
|
482 if (ec_device_open(device)) { |
|
483 EC_ERR("Failed to open device!\n"); |
|
484 return -1; |
|
485 } |
|
486 |
|
487 if (ec_master_enter_idle_mode(device->master)) { |
|
488 EC_ERR("Failed to enter idle mode!\n"); |
|
489 return -1; |
|
490 } |
|
491 |
|
492 return 0; |
|
493 } |
|
494 |
|
495 /*****************************************************************************/ |
|
496 |
|
497 /** Makes the master leave IDLE mode and closes the network device. |
|
498 * |
|
499 * \return 0 on success, else < 0 |
|
500 * \ingroup DeviceInterface |
|
501 */ |
|
502 void ecdev_close(ec_device_t *device /**< EtherCAT device */) |
|
503 { |
|
504 ec_master_leave_idle_mode(device->master); |
|
505 |
|
506 if (ec_device_close(device)) |
|
507 EC_WARN("Failed to close device!\n"); |
|
508 } |
443 } |
509 |
444 |
510 /****************************************************************************** |
445 /****************************************************************************** |
511 * Realtime interface |
446 * Realtime interface |
512 *****************************************************************************/ |
447 *****************************************************************************/ |
596 |
531 |
597 module_init(ec_init_module); |
532 module_init(ec_init_module); |
598 module_exit(ec_cleanup_module); |
533 module_exit(ec_cleanup_module); |
599 |
534 |
600 EXPORT_SYMBOL(ecdev_offer); |
535 EXPORT_SYMBOL(ecdev_offer); |
601 EXPORT_SYMBOL(ecdev_withdraw); |
|
602 EXPORT_SYMBOL(ecdev_open); |
|
603 EXPORT_SYMBOL(ecdev_close); |
|
604 |
536 |
605 EXPORT_SYMBOL(ecrt_request_master); |
537 EXPORT_SYMBOL(ecrt_request_master); |
606 EXPORT_SYMBOL(ecrt_release_master); |
538 EXPORT_SYMBOL(ecrt_release_master); |
607 EXPORT_SYMBOL(ecrt_version_magic); |
539 EXPORT_SYMBOL(ecrt_version_magic); |
608 |
540 |