devices/rtdmnet.c
branchstable-1.5
changeset 2726 ca80d6dac4c8
parent 2722 5e5bec5ee9c1
child 2727 32c9a2dea9ed
equal deleted inserted replaced
2725:e008dc9d8c9f 2726:ca80d6dac4c8
    78 typedef struct {
    78 typedef struct {
    79     struct list_head list;
    79     struct list_head list;
    80     struct net_device *netdev;
    80     struct net_device *netdev;
    81     struct rtnet_device *used_netdev;
    81     struct rtnet_device *used_netdev;
    82     int socket;
    82     int socket;
       
    83     struct rtdm_fd *rtdm_fd;
    83     ec_device_t *ecdev;
    84     ec_device_t *ecdev;
    84     uint8_t *rx_buf;
    85     uint8_t *rx_buf;
    85     // struct sockaddr_ll dest_addr;
    86     // struct sockaddr_ll dest_addr;
    86 } ec_gen_device_t;
    87 } ec_gen_device_t;
    87 
    88 
   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) {