equal
deleted
inserted
replaced
36 */ |
36 */ |
37 |
37 |
38 /*****************************************************************************/ |
38 /*****************************************************************************/ |
39 |
39 |
40 #include <linux/module.h> |
40 #include <linux/module.h> |
41 #include <linux/kernel.h> |
|
42 #include <linux/init.h> |
|
43 #include <linux/fs.h> |
|
44 |
41 |
45 #include "globals.h" |
42 #include "globals.h" |
46 #include "master.h" |
43 #include "master.h" |
47 #include "device.h" |
44 #include "device.h" |
48 |
45 |
56 void __exit ec_cleanup_module(void); |
53 void __exit ec_cleanup_module(void); |
57 |
54 |
58 static int ec_mac_parse(uint8_t *, const char *, int); |
55 static int ec_mac_parse(uint8_t *, const char *, int); |
59 |
56 |
60 /*****************************************************************************/ |
57 /*****************************************************************************/ |
61 |
|
62 struct kobject kobj; /**< kobject for master module. */ |
|
63 |
58 |
64 static char *main_devices[MAX_MASTERS]; /**< Main devices parameter. */ |
59 static char *main_devices[MAX_MASTERS]; /**< Main devices parameter. */ |
65 static char *backup_devices[MAX_MASTERS]; /**< Backup devices parameter. */ |
60 static char *backup_devices[MAX_MASTERS]; /**< Backup devices parameter. */ |
66 |
61 |
67 static ec_master_t *masters; /**< Array of masters. */ |
62 static ec_master_t *masters; /**< Array of masters. */ |
104 |
99 |
105 EC_INFO("Master driver %s\n", EC_MASTER_VERSION); |
100 EC_INFO("Master driver %s\n", EC_MASTER_VERSION); |
106 |
101 |
107 init_MUTEX(&master_sem); |
102 init_MUTEX(&master_sem); |
108 |
103 |
109 // init kobject and add it to the hierarchy |
104 if (master_count) { |
110 memset(&kobj, 0x00, sizeof(struct kobject)); |
105 if (alloc_chrdev_region(&device_number, 0, master_count, "EtherCAT")) { |
111 kobject_init(&kobj); // no ktype |
106 EC_ERR("Failed to obtain device number(s)!\n"); |
112 |
107 ret = -EBUSY; |
113 if (kobject_set_name(&kobj, "ethercat")) { |
108 goto out_return; |
114 EC_ERR("Failed to set module kobject name.\n"); |
109 } |
115 ret = -ENOMEM; |
|
116 goto out_put; |
|
117 } |
|
118 |
|
119 if (kobject_add(&kobj)) { |
|
120 EC_ERR("Failed to add module kobject.\n"); |
|
121 ret = -EEXIST; |
|
122 goto out_put; |
|
123 } |
|
124 |
|
125 if (alloc_chrdev_region(&device_number, 0, master_count, "EtherCAT")) { |
|
126 EC_ERR("Failed to obtain device number(s)!\n"); |
|
127 ret = -EBUSY; |
|
128 goto out_del; |
|
129 } |
110 } |
130 |
111 |
131 // zero MAC addresses |
112 // zero MAC addresses |
132 memset(macs, 0x00, sizeof(uint8_t) * MAX_MASTERS * 2 * ETH_ALEN); |
113 memset(macs, 0x00, sizeof(uint8_t) * MAX_MASTERS * 2 * ETH_ALEN); |
133 |
114 |
152 goto out_cdev; |
133 goto out_cdev; |
153 } |
134 } |
154 } |
135 } |
155 |
136 |
156 for (i = 0; i < master_count; i++) { |
137 for (i = 0; i < master_count; i++) { |
157 if (ec_master_init(&masters[i], &kobj, i, macs[i][0], macs[i][1], |
138 if (ec_master_init(&masters[i], i, macs[i][0], macs[i][1], |
158 device_number)) { |
139 device_number)) { |
159 ret = -EIO; |
140 ret = -ENOMEM; |
160 goto out_free_masters; |
141 goto out_free_masters; |
161 } |
142 } |
162 } |
143 } |
163 |
144 |
164 EC_INFO("%u master%s waiting for devices.\n", |
145 EC_INFO("%u master%s waiting for devices.\n", |
165 master_count, (master_count == 1 ? "" : "s")); |
146 master_count, (master_count == 1 ? "" : "s")); |
166 return ret; |
147 return ret; |
167 |
148 |
168 out_free_masters: |
149 out_free_masters: |
169 for (i--; i >= 0; i--) ec_master_clear(&masters[i]); |
150 for (i--; i >= 0; i--) |
|
151 ec_master_clear(&masters[i]); |
170 kfree(masters); |
152 kfree(masters); |
171 out_cdev: |
153 out_cdev: |
172 unregister_chrdev_region(device_number, master_count); |
154 unregister_chrdev_region(device_number, master_count); |
173 out_del: |
155 out_return: |
174 kobject_del(&kobj); |
|
175 out_put: |
|
176 kobject_put(&kobj); |
|
177 return ret; |
156 return ret; |
178 } |
157 } |
179 |
158 |
180 /*****************************************************************************/ |
159 /*****************************************************************************/ |
181 |
160 |
188 unsigned int i; |
167 unsigned int i; |
189 |
168 |
190 for (i = 0; i < master_count; i++) { |
169 for (i = 0; i < master_count; i++) { |
191 ec_master_clear(&masters[i]); |
170 ec_master_clear(&masters[i]); |
192 } |
171 } |
193 if (master_count) |
172 if (master_count) { |
194 kfree(masters); |
173 kfree(masters); |
195 |
174 unregister_chrdev_region(device_number, master_count); |
196 unregister_chrdev_region(device_number, master_count); |
175 } |
197 |
176 |
198 kobject_del(&kobj); |
|
199 kobject_put(&kobj); |
|
200 |
|
201 EC_INFO("Master module cleaned up.\n"); |
177 EC_INFO("Master module cleaned up.\n"); |
202 } |
178 } |
203 |
179 |
204 /***************************************************************************** |
180 /***************************************************************************** |
205 * MAC address functions |
181 * MAC address functions |
592 |
568 |
593 void ecrt_release_master(ec_master_t *master) |
569 void ecrt_release_master(ec_master_t *master) |
594 { |
570 { |
595 EC_INFO("Releasing master %u...\n", master->index); |
571 EC_INFO("Releasing master %u...\n", master->index); |
596 |
572 |
597 if (master->mode != EC_MASTER_MODE_OPERATION) { |
573 if (!master->reserved) { |
598 EC_WARN("Master %u was was not requested!\n", master->index); |
574 EC_WARN("Master %u was was not requested!\n", master->index); |
599 return; |
575 return; |
600 } |
576 } |
601 |
577 |
602 ec_master_leave_operation_mode(master); |
578 ec_master_leave_operation_mode(master); |
623 |
599 |
624 EXPORT_SYMBOL(ecdev_offer); |
600 EXPORT_SYMBOL(ecdev_offer); |
625 EXPORT_SYMBOL(ecdev_withdraw); |
601 EXPORT_SYMBOL(ecdev_withdraw); |
626 EXPORT_SYMBOL(ecdev_open); |
602 EXPORT_SYMBOL(ecdev_open); |
627 EXPORT_SYMBOL(ecdev_close); |
603 EXPORT_SYMBOL(ecdev_close); |
|
604 |
628 EXPORT_SYMBOL(ecrt_request_master); |
605 EXPORT_SYMBOL(ecrt_request_master); |
629 EXPORT_SYMBOL(ecrt_release_master); |
606 EXPORT_SYMBOL(ecrt_release_master); |
630 EXPORT_SYMBOL(ecrt_version_magic); |
607 EXPORT_SYMBOL(ecrt_version_magic); |
631 |
608 |
632 /** \endcond */ |
609 /** \endcond */ |