125 // process MAC parameters |
125 // process MAC parameters |
126 for (i = 0; i < master_count; i++) { |
126 for (i = 0; i < master_count; i++) { |
127 ret = ec_mac_parse(macs[i][0], main_devices[i], 0); |
127 ret = ec_mac_parse(macs[i][0], main_devices[i], 0); |
128 if (ret) |
128 if (ret) |
129 goto out_class; |
129 goto out_class; |
130 |
130 |
131 if (i < backup_count) { |
131 if (i < backup_count) { |
132 ret = ec_mac_parse(macs[i][1], backup_devices[i], 1); |
132 ret = ec_mac_parse(macs[i][1], backup_devices[i], 1); |
133 if (ret) |
133 if (ret) |
134 goto out_class; |
134 goto out_class; |
135 } |
135 } |
136 } |
136 } |
137 |
137 |
138 // initialize static master variables |
138 // initialize static master variables |
139 ec_master_init_static(); |
139 ec_master_init_static(); |
140 |
140 |
141 if (master_count) { |
141 if (master_count) { |
142 if (!(masters = kmalloc(sizeof(ec_master_t) * master_count, |
142 if (!(masters = kmalloc(sizeof(ec_master_t) * master_count, |
143 GFP_KERNEL))) { |
143 GFP_KERNEL))) { |
144 EC_ERR("Failed to allocate memory" |
144 EC_ERR("Failed to allocate memory" |
145 " for EtherCAT masters.\n"); |
145 " for EtherCAT masters.\n"); |
146 ret = -ENOMEM; |
146 ret = -ENOMEM; |
147 goto out_class; |
147 goto out_class; |
148 } |
148 } |
149 } |
149 } |
150 |
150 |
151 for (i = 0; i < master_count; i++) { |
151 for (i = 0; i < master_count; i++) { |
152 ret = ec_master_init(&masters[i], i, macs[i][0], macs[i][1], |
152 ret = ec_master_init(&masters[i], i, macs[i][0], macs[i][1], |
153 device_number, class, debug_level); |
153 device_number, class, debug_level); |
154 if (ret) |
154 if (ret) |
155 goto out_free_masters; |
155 goto out_free_masters; |
156 } |
156 } |
157 |
157 |
158 EC_INFO("%u master%s waiting for devices.\n", |
158 EC_INFO("%u master%s waiting for devices.\n", |
159 master_count, (master_count == 1 ? "" : "s")); |
159 master_count, (master_count == 1 ? "" : "s")); |
160 return ret; |
160 return ret; |
161 |
161 |
162 out_free_masters: |
162 out_free_masters: |
186 ec_master_clear(&masters[i]); |
186 ec_master_clear(&masters[i]); |
187 } |
187 } |
188 |
188 |
189 if (master_count) |
189 if (master_count) |
190 kfree(masters); |
190 kfree(masters); |
191 |
191 |
192 class_destroy(class); |
192 class_destroy(class); |
193 |
193 |
194 if (master_count) |
194 if (master_count) |
195 unregister_chrdev_region(device_number, master_count); |
195 unregister_chrdev_region(device_number, master_count); |
196 |
196 |
197 EC_INFO("Master module cleaned up.\n"); |
197 EC_INFO("Master module cleaned up.\n"); |
198 } |
198 } |
199 |
199 |
200 /*****************************************************************************/ |
200 /*****************************************************************************/ |
201 |
201 |
217 const uint8_t *mac1, /**< First MAC address. */ |
217 const uint8_t *mac1, /**< First MAC address. */ |
218 const uint8_t *mac2 /**< Second MAC address. */ |
218 const uint8_t *mac2 /**< Second MAC address. */ |
219 ) |
219 ) |
220 { |
220 { |
221 unsigned int i; |
221 unsigned int i; |
222 |
222 |
223 for (i = 0; i < ETH_ALEN; i++) |
223 for (i = 0; i < ETH_ALEN; i++) |
224 if (mac1[i] != mac2[i]) |
224 if (mac1[i] != mac2[i]) |
225 return 0; |
225 return 0; |
226 |
226 |
227 return 1; |
227 return 1; |
228 } |
228 } |
229 |
229 |
230 /*****************************************************************************/ |
230 /*****************************************************************************/ |
231 |
231 |
232 /** Print a MAC address to a buffer. |
232 /** Print a MAC address to a buffer. |
233 * |
233 * |
234 * \return number of bytes written. |
234 * \return number of bytes written. |
238 char *buffer /**< target buffer */ |
238 char *buffer /**< target buffer */ |
239 ) |
239 ) |
240 { |
240 { |
241 off_t off = 0; |
241 off_t off = 0; |
242 unsigned int i; |
242 unsigned int i; |
243 |
243 |
244 for (i = 0; i < ETH_ALEN; i++) { |
244 for (i = 0; i < ETH_ALEN; i++) { |
245 off += sprintf(buffer + off, "%02X", mac[i]); |
245 off += sprintf(buffer + off, "%02X", mac[i]); |
246 if (i < ETH_ALEN - 1) off += sprintf(buffer + off, ":"); |
246 if (i < ETH_ALEN - 1) off += sprintf(buffer + off, ":"); |
247 } |
247 } |
248 |
248 |
471 down(&master->device_sem); |
471 down(&master->device_sem); |
472 if (master->main_device.dev) { // master already has a device |
472 if (master->main_device.dev) { // master already has a device |
473 up(&master->device_sem); |
473 up(&master->device_sem); |
474 continue; |
474 continue; |
475 } |
475 } |
476 |
476 |
477 if (ec_mac_equal(master->main_mac, net_dev->dev_addr) |
477 if (ec_mac_equal(master->main_mac, net_dev->dev_addr) |
478 || ec_mac_is_broadcast(master->main_mac)) { |
478 || ec_mac_is_broadcast(master->main_mac)) { |
479 ec_mac_print(net_dev->dev_addr, str); |
479 ec_mac_print(net_dev->dev_addr, str); |
480 EC_INFO("Accepting device %s for master %u.\n", |
480 EC_INFO("Accepting device %s for master %u.\n", |
481 str, master->index); |
481 str, master->index); |
482 |
482 |
483 ec_device_attach(&master->main_device, net_dev, poll, module); |
483 ec_device_attach(&master->main_device, net_dev, poll, module); |
484 up(&master->device_sem); |
484 up(&master->device_sem); |
485 |
485 |
486 snprintf(net_dev->name, IFNAMSIZ, "ec%u", master->index); |
486 snprintf(net_dev->name, IFNAMSIZ, "ec%u", master->index); |
487 |
487 |
488 return &master->main_device; // offer accepted |
488 return &master->main_device; // offer accepted |
489 } |
489 } |
490 else { |
490 else { |
540 |
540 |
541 if (down_interruptible(&master->device_sem)) { |
541 if (down_interruptible(&master->device_sem)) { |
542 errptr = ERR_PTR(-EINTR); |
542 errptr = ERR_PTR(-EINTR); |
543 goto out_release; |
543 goto out_release; |
544 } |
544 } |
545 |
545 |
546 if (master->phase != EC_IDLE) { |
546 if (master->phase != EC_IDLE) { |
547 up(&master->device_sem); |
547 up(&master->device_sem); |
548 EC_MASTER_ERR(master, "Master still waiting for devices!\n"); |
548 EC_MASTER_ERR(master, "Master still waiting for devices!\n"); |
549 errptr = ERR_PTR(-ENODEV); |
549 errptr = ERR_PTR(-ENODEV); |
550 goto out_release; |
550 goto out_release; |