/*** * rt_packet_close */ int rt_packet_close(struct rtdm_dev_context *sockctx, rtdm_user_info_t *user_info) { struct rtsocket *sock = (struct rtsocket *)&sockctx->dev_private; struct rtpacket_type *pt = &sock->prot.packet.packet_type; struct rtskb *del; int ret = 0; rtdm_lockctx_t context; rtdm_lock_get_irqsave(&sock->param_lock, context); if ((pt->type != 0) && ((ret = rtdev_remove_pack(pt)) == 0)) pt->type = 0; rtdm_lock_put_irqrestore(&sock->param_lock, context); /* free packets in incoming queue */ while ((del = rtskb_dequeue(&sock->incoming)) != NULL) { rtdev_dereference(del->rtdev); kfree_rtskb(del); } if (ret == 0) ret = rt_socket_cleanup(sockctx); return ret; }
/*** * rt_socket_init - initialises a new socket structure */ int rt_socket_init(struct rtdm_dev_context *context) { struct rtsocket *sock = (struct rtsocket *)&context->dev_private; unsigned int pool_size; sock->priority = SOCK_DEF_PRIO; sock->callback_func = NULL; rtskb_queue_init(&sock->incoming); rtos_nanosecs_to_time(0, &sock->timeout); rtos_spin_lock_init(&sock->param_lock); rtos_event_sem_init(&sock->wakeup_event); if (test_bit(RTDM_CREATED_IN_NRT, &context->context_flags)) pool_size = rtskb_pool_init(&sock->skb_pool, socket_rtskbs); else pool_size = rtskb_pool_init_rt(&sock->skb_pool, socket_rtskbs); atomic_set(&sock->pool_size, pool_size); if (pool_size < socket_rtskbs) { /* fix statistics */ if (pool_size == 0) rtskb_pools--; rt_socket_cleanup(context); return -ENOMEM; } return 0; }
/*** * rt_packet_socket - initialize a packet socket */ int rt_packet_socket(struct rtdm_dev_context *sockctx, rtdm_user_info_t *user_info, int protocol) { struct rtsocket *sock = (struct rtsocket *)&sockctx->dev_private; int ret; if ((ret = rt_socket_init(sockctx)) != 0) return ret; sock->prot.packet.packet_type.type = protocol; sock->prot.packet.ifindex = 0; /* if protocol is non-zero, register the packet type */ if (protocol != 0) { sock->prot.packet.packet_type.name = "PACKET_SOCKET"; sock->prot.packet.packet_type.handler = rt_packet_rcv; sock->prot.packet.packet_type.err_handler = NULL; if ((ret = rtdev_add_pack(&sock->prot.packet.packet_type)) < 0) { rt_socket_cleanup(sockctx); return ret; } } sock->protocol = protocol; return 0; }
/*** * rt_socket_init - initialises a new socket structure */ int rt_socket_init(struct rtdm_dev_context *sockctx, unsigned short protocol) { struct rtsocket *sock = (struct rtsocket *)&sockctx->dev_private; unsigned int pool_size; sock->callback_func = NULL; rtskb_queue_init(&sock->incoming); sock->timeout = 0; rtdm_lock_init(&sock->param_lock); rtdm_sem_init(&sock->pending_sem, 0); pool_size = rt_bare_socket_init(sock, protocol, RTSKB_PRIO_VALUE(SOCK_DEF_PRIO, RTSKB_DEF_RT_CHANNEL), socket_rtskbs); sock->pool_size = pool_size; mutex_init(&sock->pool_nrt_lock); if (pool_size < socket_rtskbs) { /* fix statistics */ if (pool_size == 0) rtskb_pools--; rt_socket_cleanup(sockctx); return -ENOMEM; } return 0; }
/*** * rt_packet_close */ int rt_packet_close(struct rtdm_dev_context *context, int call_flags) { struct rtsocket *sock = (struct rtsocket *)&context->dev_private; struct rtpacket_type *pt = &sock->prot.packet.packet_type; struct rtskb *del; int ret = 0; unsigned long flags; rtos_spin_lock_irqsave(&sock->param_lock, flags); if ((pt->type != 0) && ((ret = rtdev_remove_pack(pt)) == 0)) pt->type = 0; rtos_spin_unlock_irqrestore(&sock->param_lock, flags); /* free packets in incoming queue */ while ((del = rtskb_dequeue(&sock->incoming)) != NULL) { rtdev_dereference(del->rtdev); kfree_rtskb(del); } if (ret == 0) ret = rt_socket_cleanup(context); return ret; }
/*** * rt_packet_socket - initialize a packet socket */ static int rt_packet_socket(struct rtdm_fd *fd, int protocol) { struct rtsocket *sock = rtdm_fd_to_private(fd); int ret; if ((ret = rt_socket_init(fd, protocol)) != 0) return ret; sock->prot.packet.packet_type.type = protocol; sock->prot.packet.ifindex = 0; sock->prot.packet.packet_type.trylock = rt_packet_trylock; sock->prot.packet.packet_type.unlock = rt_packet_unlock; /* if protocol is non-zero, register the packet type */ if (protocol != 0) { sock->prot.packet.packet_type.handler = rt_packet_rcv; sock->prot.packet.packet_type.err_handler = NULL; if ((ret = rtdev_add_pack(&sock->prot.packet.packet_type)) < 0) { rt_socket_cleanup(fd); return ret; } } return 0; }
/*** * rt_udp_close */ int rt_udp_close(struct rtdm_dev_context *context, int call_flags) { struct rtsocket *sock = (struct rtsocket *)&context->dev_private; struct rtskb *del; int port; unsigned long flags; rtos_spin_lock_irqsave(&udp_socket_base_lock, flags); sock->prot.inet.state = TCP_CLOSE; if (sock->prot.inet.reg_index >= 0) { port = sock->prot.inet.reg_index; clear_bit(port % 32, &port_bitmap[port / 32]); sock->prot.inet.reg_index = -1; } rtos_spin_unlock_irqrestore(&udp_socket_base_lock, flags); /* cleanup already collected fragments */ rt_ip_frag_invalidate_socket(sock); /* free packets in incoming queue */ while ((del = rtskb_dequeue(&sock->incoming)) != NULL) kfree_rtskb(del); return rt_socket_cleanup(context); }
/*** * rt_socket_init - initialises a new socket structure */ int __rt_socket_init(struct rtdm_fd *fd, unsigned short protocol, struct module *module) { struct rtsocket *sock = rtdm_fd_to_private(fd); unsigned int pool_size; sock->flags = 0; sock->callback_func = NULL; rtskb_queue_init(&sock->incoming); sock->timeout = 0; rtdm_lock_init(&sock->param_lock); rtdm_sem_init(&sock->pending_sem, 0); pool_size = __rt_bare_socket_init(fd, protocol, RTSKB_PRIO_VALUE(SOCK_DEF_PRIO, RTSKB_DEF_RT_CHANNEL), socket_rtskbs, module); sock->pool_size = pool_size; mutex_init(&sock->pool_nrt_lock); if (pool_size < socket_rtskbs) { /* fix statistics */ if (pool_size == 0) rtskb_pools--; rt_socket_cleanup(fd); return -ENOMEM; } return 0; }
/*** * rt_udp_close */ int rt_udp_close(struct rtdm_dev_context *sockctx, rtdm_user_info_t *user_info) { struct rtsocket *sock = (struct rtsocket *)&sockctx->dev_private; struct rtskb *del; int port; rtdm_lockctx_t context; rtdm_lock_get_irqsave(&udp_socket_base_lock, context); sock->prot.inet.state = TCP_CLOSE; if (sock->prot.inet.reg_index >= 0) { port = sock->prot.inet.reg_index; clear_bit(port % 32, &port_bitmap[port / 32]); free_ports++; sock->prot.inet.reg_index = -1; } rtdm_lock_put_irqrestore(&udp_socket_base_lock, context); /* cleanup already collected fragments */ rt_ip_frag_invalidate_socket(sock); /* free packets in incoming queue */ while ((del = rtskb_dequeue(&sock->incoming)) != NULL) kfree_rtskb(del); return rt_socket_cleanup(sockctx); }
/*** * rt_socket_init - initialises a new socket structure */ int rt_socket_init(struct rtdm_dev_context *context) { struct rtsocket *sock = (struct rtsocket *)&context->dev_private; unsigned int pool_size; sock->priority = RTSKB_PRIO_VALUE(SOCK_DEF_PRIO, RTSKB_DEF_RT_CHANNEL); sock->callback_func = NULL; rtskb_queue_init(&sock->incoming); sock->timeout = 0; rtos_spin_lock_init(&sock->param_lock); rtos_sem_init(&sock->pending_sem); if (test_bit(RTDM_CREATED_IN_NRT, &context->context_flags)) pool_size = rtskb_pool_init(&sock->skb_pool, socket_rtskbs); else pool_size = rtskb_pool_init_rt(&sock->skb_pool, socket_rtskbs); atomic_set(&sock->pool_size, pool_size); if (pool_size < socket_rtskbs) { /* fix statistics */ if (pool_size == 0) rtskb_pools--; rt_socket_cleanup(context); return -ENOMEM; } return 0; }
/*** * rt_udp_socket - create a new UDP-Socket * @s: socket */ int rt_udp_socket(struct rtdm_dev_context *context, rtdm_user_info_t *user_info) { struct rtsocket *sock = (struct rtsocket *)&context->dev_private; int ret; int i; int index; unsigned long flags; if ((ret = rt_socket_init(context)) != 0) return ret; sock->protocol = IPPROTO_UDP; sock->prot.inet.saddr = INADDR_ANY; sock->prot.inet.state = TCP_CLOSE; #ifdef CONFIG_RTNET_RTDM_SELECT sock->wakeup_select = NULL; #endif /* CONFIG_RTNET_RTDM_SELECT */ rtos_spin_lock_irqsave(&udp_socket_base_lock, flags); /* enforce maximum number of UDP sockets */ if (free_ports == 0) { rtos_spin_unlock_irqrestore(&udp_socket_base_lock, flags); rt_socket_cleanup(context); return -EAGAIN; } free_ports--; /* find free auto-port in bitmap */ for (i = 0; i < sizeof(port_bitmap)/4; i++) if (port_bitmap[i] != 0xFFFFFFFF) break; index = ffz(port_bitmap[i]); set_bit(index, &port_bitmap[i]); index += i*32; sock->prot.inet.reg_index = index; sock->prot.inet.sport = index + auto_port_start; /* register UDP socket */ port_registry[index].sport = sock->prot.inet.sport; port_registry[index].saddr = INADDR_ANY; port_registry[index].sock = sock; rtos_spin_unlock_irqrestore(&udp_socket_base_lock, flags); return 0; }
/*** * rt_packet_close */ static void rt_packet_close(struct rtdm_fd *fd) { struct rtsocket *sock = rtdm_fd_to_private(fd); struct rtpacket_type *pt = &sock->prot.packet.packet_type; struct rtskb *del; rtdm_lockctx_t context; rtdm_lock_get_irqsave(&sock->param_lock, context); if (pt->type != 0) { rtdev_remove_pack(pt); pt->type = 0; } rtdm_lock_put_irqrestore(&sock->param_lock, context); /* free packets in incoming queue */ while ((del = rtskb_dequeue(&sock->incoming)) != NULL) { kfree_rtskb(del); } rt_socket_cleanup(fd); }