36 CANopen Sdo functions. |
36 CANopen Sdo functions. |
37 */ |
37 */ |
38 |
38 |
39 /*****************************************************************************/ |
39 /*****************************************************************************/ |
40 |
40 |
41 #include <linux/module.h> |
41 #include <linux/slab.h> |
42 |
42 |
43 #include "master.h" |
43 #include "master.h" |
44 |
44 |
45 #include "sdo.h" |
45 #include "sdo.h" |
46 |
46 |
47 /*****************************************************************************/ |
47 /*****************************************************************************/ |
48 |
48 |
49 ssize_t ec_show_sdo_attribute(struct kobject *, struct attribute *, char *); |
49 /** Constructor. |
50 void ec_sdo_clear(struct kobject *); |
|
51 |
|
52 /*****************************************************************************/ |
|
53 |
|
54 /** \cond */ |
|
55 |
|
56 EC_SYSFS_READ_ATTR(info); |
|
57 |
|
58 static struct attribute *sdo_def_attrs[] = { |
|
59 &attr_info, |
|
60 NULL, |
|
61 }; |
|
62 |
|
63 static struct sysfs_ops sdo_sysfs_ops = { |
|
64 .show = &ec_show_sdo_attribute, |
|
65 .store = NULL |
|
66 }; |
|
67 |
|
68 static struct kobj_type ktype_ec_sdo = { |
|
69 .release = ec_sdo_clear, |
|
70 .sysfs_ops = &sdo_sysfs_ops, |
|
71 .default_attrs = sdo_def_attrs |
|
72 }; |
|
73 |
|
74 /** \endcond */ |
|
75 |
|
76 /*****************************************************************************/ |
|
77 |
|
78 /** Sdo constructor. |
|
79 * |
|
80 * \todo Turn parameters. |
|
81 */ |
50 */ |
82 int ec_sdo_init( |
51 void ec_sdo_init( |
83 ec_sdo_t *sdo, /**< Sdo. */ |
52 ec_sdo_t *sdo, /**< Sdo. */ |
84 uint16_t index, /**< Sdo index. */ |
53 ec_slave_t *slave, /**< Parent slave. */ |
85 ec_slave_t *slave /**< Parent slave. */ |
54 uint16_t index /**< Sdo index. */ |
86 ) |
55 ) |
87 { |
56 { |
88 sdo->slave = slave; |
57 sdo->slave = slave; |
89 sdo->index = index; |
58 sdo->index = index; |
90 sdo->object_code = 0x00; |
59 sdo->object_code = 0x00; |
91 sdo->name = NULL; |
60 sdo->name = NULL; |
92 sdo->max_subindex = 0; |
61 sdo->max_subindex = 0; |
93 INIT_LIST_HEAD(&sdo->entries); |
62 INIT_LIST_HEAD(&sdo->entries); |
94 |
|
95 // Init kobject and add it to the hierarchy |
|
96 memset(&sdo->kobj, 0x00, sizeof(struct kobject)); |
|
97 kobject_init(&sdo->kobj); |
|
98 sdo->kobj.ktype = &ktype_ec_sdo; |
|
99 sdo->kobj.parent = &slave->sdo_kobj; |
|
100 if (kobject_set_name(&sdo->kobj, "%4X", sdo->index)) { |
|
101 EC_ERR("Failed to set kobj name.\n"); |
|
102 kobject_put(&sdo->kobj); |
|
103 return -1; |
|
104 } |
|
105 if (kobject_add(&sdo->kobj)) { |
|
106 EC_ERR("Failed to add Sdo kobject.\n"); |
|
107 kobject_put(&sdo->kobj); |
|
108 return -1; |
|
109 } |
|
110 |
|
111 return 0; |
|
112 } |
63 } |
113 |
64 |
114 /*****************************************************************************/ |
65 /*****************************************************************************/ |
115 |
66 |
116 /** Sdo destructor. |
67 /** Sdo destructor. |
117 * |
68 * |
118 * Clears and frees an Sdo object. |
69 * Clears and frees an Sdo object. |
119 */ |
70 */ |
120 void ec_sdo_destroy( |
71 void ec_sdo_clear( |
121 ec_sdo_t *sdo /**< Sdo. */ |
72 ec_sdo_t *sdo /**< Sdo. */ |
122 ) |
73 ) |
123 { |
74 { |
124 ec_sdo_entry_t *entry, *next; |
75 ec_sdo_entry_t *entry, *next; |
125 |
76 |
128 list_del(&entry->list); |
79 list_del(&entry->list); |
129 ec_sdo_entry_clear(entry); |
80 ec_sdo_entry_clear(entry); |
130 kfree(entry); |
81 kfree(entry); |
131 } |
82 } |
132 |
83 |
133 // destroy self |
84 if (sdo->name) |
134 kobject_del(&sdo->kobj); |
85 kfree(sdo->name); |
135 kobject_put(&sdo->kobj); |
|
136 } |
|
137 |
|
138 /*****************************************************************************/ |
|
139 |
|
140 /** Clear and free Sdo. |
|
141 * |
|
142 * This method is called by the kobject, |
|
143 * once there are no more references to it. |
|
144 */ |
|
145 void ec_sdo_clear( |
|
146 struct kobject *kobj /**< Sdo's kobject. */ |
|
147 ) |
|
148 { |
|
149 ec_sdo_t *sdo = container_of(kobj, ec_sdo_t, kobj); |
|
150 |
|
151 if (sdo->name) kfree(sdo->name); |
|
152 |
|
153 kfree(sdo); |
|
154 } |
86 } |
155 |
87 |
156 /*****************************************************************************/ |
88 /*****************************************************************************/ |
157 |
89 |
158 /** Get an Sdo entry from an Sdo via its subindex. |
90 /** Get an Sdo entry from an Sdo via its subindex. |
200 |
132 |
201 return NULL; |
133 return NULL; |
202 } |
134 } |
203 |
135 |
204 /*****************************************************************************/ |
136 /*****************************************************************************/ |
205 |
|
206 /** Print Sdo information to a buffer. |
|
207 * |
|
208 * /return size of bytes written to buffer. |
|
209 */ |
|
210 ssize_t ec_sdo_info( |
|
211 ec_sdo_t *sdo, /**< Sdo. */ |
|
212 char *buffer /**< Target buffer. */ |
|
213 ) |
|
214 { |
|
215 off_t off = 0; |
|
216 |
|
217 off += sprintf(buffer + off, "Index: 0x%04X\n", sdo->index); |
|
218 off += sprintf(buffer + off, "Name: %s\n", sdo->name ? sdo->name : ""); |
|
219 off += sprintf(buffer + off, "Max subindex: %u\n", sdo->max_subindex); |
|
220 |
|
221 return off; |
|
222 } |
|
223 |
|
224 /*****************************************************************************/ |
|
225 |
|
226 /** Show a Sysfs attribute of an Sdo. |
|
227 * |
|
228 * /return Number of bytes written to buffer. |
|
229 */ |
|
230 ssize_t ec_show_sdo_attribute( |
|
231 struct kobject *kobj, /**< kobject */ |
|
232 struct attribute *attr, /**< Requested attribute. */ |
|
233 char *buffer /**< Buffer to write the data in. */ |
|
234 ) |
|
235 { |
|
236 ec_sdo_t *sdo = container_of(kobj, ec_sdo_t, kobj); |
|
237 |
|
238 if (attr == &attr_info) { |
|
239 return ec_sdo_info(sdo, buffer); |
|
240 } |
|
241 |
|
242 return 0; |
|
243 } |
|
244 |
|
245 /*****************************************************************************/ |
|