master/domain.c
changeset 993 8c32564252fd
parent 985 90bcaf9ce3d5
child 1009 6012e1414bec
equal deleted inserted replaced
992:50a44cbd30af 993:8c32564252fd
    46 
    46 
    47 #include "domain.h"
    47 #include "domain.h"
    48 
    48 
    49 /*****************************************************************************/
    49 /*****************************************************************************/
    50 
    50 
    51 void ec_domain_clear(struct kobject *);
       
    52 void ec_domain_clear_data(ec_domain_t *);
    51 void ec_domain_clear_data(ec_domain_t *);
    53 ssize_t ec_show_domain_attribute(struct kobject *, struct attribute *, char *);
       
    54 
       
    55 /*****************************************************************************/
       
    56 
       
    57 /** \cond */
       
    58 
       
    59 EC_SYSFS_READ_ATTR(image_size);
       
    60 
       
    61 static struct attribute *def_attrs[] = {
       
    62     &attr_image_size,
       
    63     NULL,
       
    64 };
       
    65 
       
    66 static struct sysfs_ops sysfs_ops = {
       
    67     .show = &ec_show_domain_attribute,
       
    68     .store = NULL
       
    69 };
       
    70 
       
    71 static struct kobj_type ktype_ec_domain = {
       
    72     .release = ec_domain_clear,
       
    73     .sysfs_ops = &sysfs_ops,
       
    74     .default_attrs = def_attrs
       
    75 };
       
    76 
       
    77 /** \endcond */
       
    78 
    52 
    79 /*****************************************************************************/
    53 /*****************************************************************************/
    80 
    54 
    81 /** Domain constructor.
    55 /** Domain constructor.
    82  *
    56  */
    83  * \return 0 in case of success, else < 0
    57 void ec_domain_init(
    84  */
       
    85 int ec_domain_init(
       
    86         ec_domain_t *domain, /**< EtherCAT domain. */
    58         ec_domain_t *domain, /**< EtherCAT domain. */
    87         ec_master_t *master, /**< Parent master. */
    59         ec_master_t *master, /**< Parent master. */
    88         unsigned int index /**< Index. */
    60         unsigned int index /**< Index. */
    89         )
    61         )
    90 {
    62 {
    98     INIT_LIST_HEAD(&domain->datagrams);
    70     INIT_LIST_HEAD(&domain->datagrams);
    99     domain->working_counter = 0xFFFF;
    71     domain->working_counter = 0xFFFF;
   100     domain->expected_working_counter = 0x0000;
    72     domain->expected_working_counter = 0x0000;
   101     domain->working_counter_changes = 0;
    73     domain->working_counter_changes = 0;
   102     domain->notify_jiffies = 0;
    74     domain->notify_jiffies = 0;
   103 
       
   104     // init kobject and add it to the hierarchy
       
   105     memset(&domain->kobj, 0x00, sizeof(struct kobject));
       
   106     kobject_init(&domain->kobj);
       
   107     domain->kobj.ktype = &ktype_ec_domain;
       
   108     domain->kobj.parent = &master->kobj;
       
   109     if (kobject_set_name(&domain->kobj, "domain%u", index)) {
       
   110         EC_ERR("Failed to set kobj name.\n");
       
   111         kobject_put(&domain->kobj);
       
   112         return -1;
       
   113     }
       
   114     if (kobject_add(&domain->kobj)) {
       
   115         EC_ERR("Failed to add domain kobject.\n");
       
   116         kobject_put(&domain->kobj);
       
   117         return -1;
       
   118     }
       
   119 
       
   120     return 0;
       
   121 }
    75 }
   122 
    76 
   123 /*****************************************************************************/
    77 /*****************************************************************************/
   124 
    78 
   125 /** Domain destructor.
    79 /** Domain destructor.
   126  *
    80  */
   127  * Clears and frees a domain object.
    81 void ec_domain_clear(ec_domain_t *domain /**< EtherCAT domain */)
   128  */
    82 {
   129 void ec_domain_destroy(ec_domain_t *domain /**< EtherCAT domain */)
    83     ec_datagram_t *datagram, *next;
   130 {
    84 
   131     ec_datagram_t *datagram;
    85     // dequeue and free datagrams
   132 
    86     list_for_each_entry_safe(datagram, next, &domain->datagrams, list) {
   133     // dequeue datagrams
       
   134     list_for_each_entry(datagram, &domain->datagrams, list) {
       
   135         if (!list_empty(&datagram->queue)) // datagram queued?
    87         if (!list_empty(&datagram->queue)) // datagram queued?
   136             list_del_init(&datagram->queue);
    88             list_del(&datagram->queue);
   137     }
       
   138 
       
   139     // destroy self
       
   140     kobject_del(&domain->kobj);
       
   141     kobject_put(&domain->kobj);
       
   142 }
       
   143 
       
   144 /*****************************************************************************/
       
   145 
       
   146 /** Clear and free domain.
       
   147  *
       
   148  * This method is called by the kobject, once there are no more references
       
   149  * to it.
       
   150  */
       
   151 void ec_domain_clear(struct kobject *kobj /**< kobject of the domain */)
       
   152 {
       
   153     ec_domain_t *domain;
       
   154     ec_datagram_t *datagram, *next;
       
   155 
       
   156     domain = container_of(kobj, ec_domain_t, kobj);
       
   157 
       
   158     list_for_each_entry_safe(datagram, next, &domain->datagrams, list) {
       
   159         ec_datagram_clear(datagram);
    89         ec_datagram_clear(datagram);
   160         kfree(datagram);
    90         kfree(datagram);
   161     }
    91     }
   162 
    92 
   163     ec_domain_clear_data(domain);
    93     ec_domain_clear_data(domain);
   164 
       
   165     kfree(domain);
       
   166 }
    94 }
   167 
    95 
   168 /*****************************************************************************/
    96 /*****************************************************************************/
   169 
    97 
   170 /** Frees internally allocated memory.
    98 /** Frees internally allocated memory.
   321         }
   249         }
   322 
   250 
   323         datagram_size += fmmu->data_size;
   251         datagram_size += fmmu->data_size;
   324     }
   252     }
   325 
   253 
   326     // allocate last datagram, if data are left
   254     // Allocate last datagram, if data are left (this is also the case if the
       
   255     // process data fit into a single datagram)
   327     if (datagram_size) {
   256     if (datagram_size) {
   328         if (ec_domain_add_datagram(domain,
   257         if (ec_domain_add_datagram(domain,
   329                     domain->logical_base_address + datagram_offset,
   258                     domain->logical_base_address + datagram_offset,
   330                     datagram_size, domain->data + datagram_offset,
   259                     datagram_size, domain->data + datagram_offset,
   331                     datagram_used))
   260                     datagram_used))
   346     return 0;
   275     return 0;
   347 }
   276 }
   348 
   277 
   349 /*****************************************************************************/
   278 /*****************************************************************************/
   350 
   279 
   351 /**
       
   352    Formats attribute data for SysFS reading.
       
   353    \return number of bytes to read
       
   354 */
       
   355 
       
   356 ssize_t ec_show_domain_attribute(struct kobject *kobj, /**< kobject */
       
   357                                  struct attribute *attr, /**< attribute */
       
   358                                  char *buffer /**< memory to store data in */
       
   359                                  )
       
   360 {
       
   361     ec_domain_t *domain = container_of(kobj, ec_domain_t, kobj);
       
   362 
       
   363     if (attr == &attr_image_size) {
       
   364         return sprintf(buffer, "%u\n", domain->data_size);
       
   365     }
       
   366 
       
   367     return 0;
       
   368 }
       
   369 
       
   370 /*****************************************************************************/
       
   371 
       
   372 unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
   280 unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
   373 {
   281 {
   374     const ec_fmmu_config_t *fmmu;
   282     const ec_fmmu_config_t *fmmu;
   375     unsigned int num = 0;
   283     unsigned int num = 0;
   376 
   284 
   475         if (domain->working_counter_changes == 1) {
   383         if (domain->working_counter_changes == 1) {
   476             EC_INFO("Domain %u: Working counter changed to %u/%u.\n",
   384             EC_INFO("Domain %u: Working counter changed to %u/%u.\n",
   477                     domain->index, domain->working_counter,
   385                     domain->index, domain->working_counter,
   478                     domain->expected_working_counter);
   386                     domain->expected_working_counter);
   479         } else {
   387         } else {
   480             EC_INFO("Domain %u: %u working counter changes. Currently %u/%u.\n",
   388             EC_INFO("Domain %u: %u working counter changes. "
   481                     domain->index, domain->working_counter_changes,
   389                     "Currently %u/%u.\n", domain->index,
   482                     domain->working_counter, domain->expected_working_counter);
   390                     domain->working_counter_changes, domain->working_counter,
       
   391                     domain->expected_working_counter);
   483         }
   392         }
   484         domain->working_counter_changes = 0;
   393         domain->working_counter_changes = 0;
   485     }
   394     }
   486 }
   395 }
   487 
   396