193 if (dev->ecdev) { |
194 if (dev->ecdev) { |
194 ecdev_close(dev->ecdev); |
195 ecdev_close(dev->ecdev); |
195 ecdev_withdraw(dev->ecdev); |
196 ecdev_withdraw(dev->ecdev); |
196 } |
197 } |
197 if (!(dev->socket < 0)) { |
198 if (!(dev->socket < 0)) { |
|
199 rtdm_fd_put(dev->rtdm_fd); |
198 rtdm_close(dev->socket); |
200 rtdm_close(dev->socket); |
199 dev->socket = -1; |
201 dev->socket = -1; |
200 } |
202 } |
201 free_netdev(dev->netdev); |
203 free_netdev(dev->netdev); |
202 |
204 |
225 /* create rt-socket */ |
227 /* create rt-socket */ |
226 dev->socket = rtdm_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ETHERCAT)); |
228 dev->socket = rtdm_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ETHERCAT)); |
227 if (dev->socket < 0) { |
229 if (dev->socket < 0) { |
228 printk(" rtdm_socket() = %d!\n", dev->socket); |
230 printk(" rtdm_socket() = %d!\n", dev->socket); |
229 return dev->socket; |
231 return dev->socket; |
|
232 } |
|
233 |
|
234 /* HACK : |
|
235 When this is called, process is 'kernel', i.e. |
|
236 cobalt_ppd_get(0) == &cobalt_kernel_ppd |
|
237 |
|
238 This makes a problem later when recvmsg or sendmsg is indirectly called |
|
239 from application's cobalt thread through RTDM IOCTL. From such thread, |
|
240 RTDM can't resolv socket's 'ufd' that rtdm_socket just returned. |
|
241 |
|
242 To keep a usable file descriptor for that socket, even when calling |
|
243 from cobalt thread (i.e. if (cobalt_ppd_get(0) != &cobalt_kernel_ppd)) |
|
244 we resolve it here in advance */ |
|
245 dev->rtdm_fd = rtdm_fd_get(dev->socket,0); |
|
246 if (IS_ERR(dev->rtdm_fd)){ |
|
247 printk(" rtdm_fd_get() = %d!\n", ret); |
|
248 ret = PTR_ERR(dev->rtdm_fd); |
|
249 goto out_err; |
230 } |
250 } |
231 |
251 |
232 printk(KERN_ERR PFX "Binding socket to interface %i (%s).\n", |
252 printk(KERN_ERR PFX "Binding socket to interface %i (%s).\n", |
233 desc->ifindex, desc->name); |
253 desc->ifindex, desc->name); |
234 |
254 |
238 sa.sll_ifindex = desc->ifindex; |
258 sa.sll_ifindex = desc->ifindex; |
239 ret = rtdm_bind(dev->socket, (struct sockaddr *)&sa, |
259 ret = rtdm_bind(dev->socket, (struct sockaddr *)&sa, |
240 sizeof(struct sockaddr_ll)); |
260 sizeof(struct sockaddr_ll)); |
241 if (ret < 0) { |
261 if (ret < 0) { |
242 printk(" rtdm_bind() = %d!\n", ret); |
262 printk(" rtdm_bind() = %d!\n", ret); |
243 rtdm_close(dev->socket); |
263 goto out_err; |
244 dev->socket = -1; |
|
245 return ret; |
|
246 } |
264 } |
247 |
265 |
248 return 0; |
266 return 0; |
|
267 |
|
268 out_err: |
|
269 rtdm_fd_put(dev->rtdm_fd); |
|
270 rtdm_close(dev->socket); |
|
271 dev->socket = -1; |
|
272 return ret; |
|
273 |
249 } |
274 } |
250 |
275 |
251 /*****************************************************************************/ |
276 /*****************************************************************************/ |
252 |
277 |
253 /** Offer generic device to master. |
278 /** Offer generic device to master. |
349 // msg.msg_namelen = sizeof(dev->dest_addr); |
374 // msg.msg_namelen = sizeof(dev->dest_addr); |
350 msg.msg_iov = &iov; |
375 msg.msg_iov = &iov; |
351 msg.msg_iovlen = 1; |
376 msg.msg_iovlen = 1; |
352 |
377 |
353 if (rtdm_in_rt_context()) |
378 if (rtdm_in_rt_context()) |
354 ret = rtdm_sendmsg(dev->socket, &msg, 0); |
379 /* HACK : call fd ops directly as in rtdm's fd.c */ |
|
380 ret = dev->rtdm_fd->ops->sendmsg_rt(dev->rtdm_fd, &msg, 0); |
355 else |
381 else |
356 ret = nrt_rtdm_sendmsg(dev->socket, &msg); |
382 ret = nrt_rtdm_sendmsg(dev->socket, &msg); |
357 |
383 |
358 return ret == len ? NETDEV_TX_OK : NETDEV_TX_BUSY; |
384 return ret == len ? NETDEV_TX_OK : NETDEV_TX_BUSY; |
359 } |
385 } |
404 iov.iov_len = EC_GEN_RX_BUF_SIZE; |
430 iov.iov_len = EC_GEN_RX_BUF_SIZE; |
405 memset(&msg, 0, sizeof(msg)); |
431 memset(&msg, 0, sizeof(msg)); |
406 msg.msg_iov = &iov; |
432 msg.msg_iov = &iov; |
407 msg.msg_iovlen = 1; |
433 msg.msg_iovlen = 1; |
408 |
434 |
409 if (rtdm_in_rt_context()) |
435 if (rtdm_in_rt_context()){ |
410 ret = rtdm_recvmsg(dev->socket, &msg, MSG_DONTWAIT); |
436 /* HACK : call fd ops directly as in rtdm's fd.c */ |
411 else |
437 ret = dev->rtdm_fd->ops->recvmsg_rt(dev->rtdm_fd, &msg, MSG_DONTWAIT); |
|
438 }else |
412 ret = nrt_rtdm_recvmsg(dev->socket, &msg); |
439 ret = nrt_rtdm_recvmsg(dev->socket, &msg); |
413 |
440 |
414 if (ret > 0) { |
441 if (ret > 0) { |
415 ecdev_receive(dev->ecdev, dev->rx_buf, ret); |
442 ecdev_receive(dev->ecdev, dev->rx_buf, ret); |
416 } else if (ret < 0) { |
443 } else if (ret < 0) { |