50 /*****************************************************************************/ |
50 /*****************************************************************************/ |
51 |
51 |
52 int __init ec_init_module(void); |
52 int __init ec_init_module(void); |
53 void __exit ec_cleanup_module(void); |
53 void __exit ec_cleanup_module(void); |
54 |
54 |
55 /*****************************************************************************/ |
55 ssize_t ec_show_attribute(struct kobject *, struct attribute *, char *); |
|
56 |
|
57 /*****************************************************************************/ |
|
58 |
|
59 /** \cond */ |
|
60 |
|
61 EC_SYSFS_READ_ATTR(info); |
|
62 |
|
63 static struct attribute *ec_def_attrs[] = { |
|
64 &attr_info, |
|
65 NULL, |
|
66 }; |
|
67 |
|
68 static struct sysfs_ops ec_sysfs_ops = { |
|
69 .show = &ec_show_attribute, |
|
70 .store = NULL |
|
71 }; |
|
72 |
|
73 static struct kobj_type ktype_ec_module = { |
|
74 .release = NULL, // this is ok, because the module can not be unloaded |
|
75 // if the reference count is greater zero. |
|
76 .sysfs_ops = &ec_sysfs_ops, |
|
77 .default_attrs = ec_def_attrs |
|
78 }; |
|
79 |
|
80 /** \endcond */ |
|
81 |
|
82 /*****************************************************************************/ |
|
83 |
|
84 struct kobject ec_kobj; /**< kobject for master module */ |
56 |
85 |
57 static char *main; /**< main devices parameter */ |
86 static char *main; /**< main devices parameter */ |
58 static char *backup; /**< backup devices parameter */ |
87 static char *backup; /**< backup devices parameter */ |
59 |
88 |
60 static LIST_HEAD(main_ids); /**< list of main device IDs */ |
89 static LIST_HEAD(main_ids); /**< list of main device IDs */ |
95 ec_device_id_t *main_dev_id, *backup_dev_id; |
124 ec_device_id_t *main_dev_id, *backup_dev_id; |
96 unsigned int master_index = 0; |
125 unsigned int master_index = 0; |
97 |
126 |
98 EC_INFO("Master driver %s\n", EC_MASTER_VERSION); |
127 EC_INFO("Master driver %s\n", EC_MASTER_VERSION); |
99 |
128 |
|
129 // init kobject and add it to the hierarchy |
|
130 memset(&ec_kobj, 0x00, sizeof(struct kobject)); |
|
131 kobject_init(&ec_kobj); |
|
132 ec_kobj.ktype = &ktype_ec_module; |
|
133 |
|
134 if (kobject_set_name(&ec_kobj, "ethercat")) { |
|
135 EC_ERR("Failed to set module kobject name.\n"); |
|
136 goto out_put; |
|
137 } |
|
138 |
|
139 if (kobject_add(&ec_kobj)) { |
|
140 EC_ERR("Failed to add module kobject.\n"); |
|
141 goto out_put; |
|
142 } |
|
143 |
100 if (alloc_chrdev_region(&device_number, 0, 1, "EtherCAT")) { |
144 if (alloc_chrdev_region(&device_number, 0, 1, "EtherCAT")) { |
101 EC_ERR("Failed to obtain device number!\n"); |
145 EC_ERR("Failed to obtain device number!\n"); |
102 goto out_return; |
146 goto out_del; |
103 } |
147 } |
104 |
148 |
105 if (ec_device_id_process_params(main, backup, &main_ids, &backup_ids)) |
149 if (ec_device_id_process_params(main, backup, &main_ids, &backup_ids)) |
106 goto out_cdev; |
150 goto out_cdev; |
107 |
151 |
119 EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", |
163 EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", |
120 master_index); |
164 master_index); |
121 goto out_free_masters; |
165 goto out_free_masters; |
122 } |
166 } |
123 |
167 |
124 if (ec_master_init(master, master_index, |
168 if (ec_master_init(master, &ec_kobj, master_index, |
125 main_dev_id, backup_dev_id, 0)) |
169 main_dev_id, backup_dev_id, 0)) |
126 goto out_free_masters; |
170 goto out_free_masters; |
127 |
171 |
128 list_add_tail(&master->list, &masters); |
172 list_add_tail(&master->list, &masters); |
129 master_index++; |
173 master_index++; |
151 } |
195 } |
152 ec_device_id_clear_list(&main_ids); |
196 ec_device_id_clear_list(&main_ids); |
153 ec_device_id_clear_list(&backup_ids); |
197 ec_device_id_clear_list(&backup_ids); |
154 out_cdev: |
198 out_cdev: |
155 unregister_chrdev_region(device_number, 1); |
199 unregister_chrdev_region(device_number, 1); |
156 out_return: |
200 out_del: |
|
201 kobject_del(&ec_kobj); |
|
202 out_put: |
|
203 kobject_put(&ec_kobj); |
157 return -1; |
204 return -1; |
158 } |
205 } |
159 |
206 |
160 /*****************************************************************************/ |
207 /*****************************************************************************/ |
161 |
208 |
176 } |
223 } |
177 |
224 |
178 ec_device_id_clear_list(&main_ids); |
225 ec_device_id_clear_list(&main_ids); |
179 ec_device_id_clear_list(&backup_ids); |
226 ec_device_id_clear_list(&backup_ids); |
180 unregister_chrdev_region(device_number, 1); |
227 unregister_chrdev_region(device_number, 1); |
|
228 kobject_del(&ec_kobj); |
|
229 kobject_put(&ec_kobj); |
181 |
230 |
182 EC_INFO("Master module cleaned up.\n"); |
231 EC_INFO("Master module cleaned up.\n"); |
183 } |
232 } |
|
233 |
|
234 /*****************************************************************************/ |
|
235 |
|
236 /** |
|
237 Formats module information for SysFS read access. |
|
238 \return number of bytes written |
|
239 */ |
|
240 |
|
241 ssize_t ec_info(char *buffer /**< memory to store data */) |
|
242 { |
|
243 off_t off = 0; |
|
244 |
|
245 off += sprintf(buffer + off, "\nVersion: %s", ec_master_version_str); |
|
246 off += sprintf(buffer + off, "\n"); |
|
247 |
|
248 return off; |
|
249 } |
|
250 |
|
251 /*****************************************************************************/ |
|
252 |
|
253 /** |
|
254 Formats attribute data for SysFS read access. |
|
255 \return number of bytes to read |
|
256 */ |
|
257 |
|
258 ssize_t ec_show_attribute(struct kobject *kobj, /**< kobject */ |
|
259 struct attribute *attr, /**< attribute */ |
|
260 char *buffer /**< memory to store data */ |
|
261 ) |
|
262 { |
|
263 if (attr == &attr_info) |
|
264 return ec_info(buffer); |
|
265 |
|
266 return 0; |
|
267 } |
|
268 |
184 |
269 |
185 /*****************************************************************************/ |
270 /*****************************************************************************/ |
186 |
271 |
187 /** |
272 /** |
188 Gets a handle to a certain master. |
273 Gets a handle to a certain master. |