/*** * rtdev_alloc * @int sizeof_priv: * * allocate memory for a new rt-network-adapter */ struct rtnet_device *rtdev_alloc(int sizeof_priv) { struct rtnet_device *rtdev; int alloc_size; /* ensure 32-byte alignment of the private area */ alloc_size = sizeof (*rtdev) + sizeof_priv + 31; rtdev = (struct rtnet_device *)kmalloc(alloc_size, GFP_KERNEL); if (rtdev == NULL) { printk(KERN_ERR "RTnet: cannot allocate rtnet device\n"); return NULL; } memset(rtdev, 0, alloc_size); rtos_res_lock_init(&rtdev->xmit_lock); atomic_set(&rtdev->refcount, 0); /* scale global rtskb pool */ rtdev->add_rtskbs = rtskb_pool_extend(&global_pool, device_rtskbs); if (sizeof_priv) rtdev->priv = (void *)(((long)(rtdev + 1) + 31) & ~31); return rtdev; }
/*** * rt_socket_common_ioctl */ int rt_socket_common_ioctl(struct rtdm_dev_context *context, int call_flags, int request, void *arg) { struct rtsocket *sock = (struct rtsocket *)&context->dev_private; int ret = 0; struct rtnet_callback *callback = arg; unsigned int rtskbs; unsigned long flags; switch (request) { case RTNET_RTIOC_PRIORITY: sock->priority = *(unsigned int *)arg; break; case RTNET_RTIOC_TIMEOUT: rtos_spin_lock_irqsave(&sock->param_lock, flags); rtos_nanosecs_to_time(*(nanosecs_t *)arg, &sock->timeout); rtos_spin_unlock_irqrestore(&sock->param_lock, flags); break; case RTNET_RTIOC_CALLBACK: if (test_bit(RTDM_USER_MODE_CALL, &context->context_flags)) return -EACCES; rtos_spin_lock_irqsave(&sock->param_lock, flags); sock->callback_func = callback->func; sock->callback_arg = callback->arg; rtos_spin_unlock_irqrestore(&sock->param_lock, flags); break; case RTNET_RTIOC_NONBLOCK: if (*(unsigned int *)arg != 0) set_bit(RT_SOCK_NONBLOCK, &context->context_flags); else clear_bit(RT_SOCK_NONBLOCK, &context->context_flags); break; case RTNET_RTIOC_EXTPOOL: rtskbs = *(unsigned int *)arg; rtos_spin_lock_irqsave(&sock->param_lock, flags); if (test_bit(SKB_POOL_CLOSED, &context->context_flags)) { rtos_spin_unlock_irqrestore(&sock->param_lock, flags); return -EBADF; } atomic_add(rtskbs, &sock->pool_size); rtos_spin_unlock_irqrestore(&sock->param_lock, flags); if (test_bit(RTDM_CREATED_IN_NRT, &context->context_flags)) { if (!(call_flags & RTDM_NRT_CALL)) return -EACCES; ret = rtskb_pool_extend(&sock->skb_pool, rtskbs); } else ret = rtskb_pool_extend_rt(&sock->skb_pool, rtskbs); atomic_sub(rtskbs-ret, &sock->pool_size); break; case RTNET_RTIOC_SHRPOOL: rtskbs = *(unsigned int *)arg; rtos_spin_lock_irqsave(&sock->param_lock, flags); if (test_bit(SKB_POOL_CLOSED, &context->context_flags)) { rtos_spin_unlock_irqrestore(&sock->param_lock, flags); return -EBADF; } atomic_sub(rtskbs, &sock->pool_size); rtos_spin_unlock_irqrestore(&sock->param_lock, flags); if (test_bit(RTDM_CREATED_IN_NRT, &context->context_flags)) { if (!(call_flags & RTDM_NRT_CALL)) return -EACCES; ret = rtskb_pool_shrink(&sock->skb_pool, *(unsigned int *)arg); } else ret = rtskb_pool_shrink_rt(&sock->skb_pool, *(unsigned int *)arg); atomic_add(rtskbs-ret, &sock->pool_size); break; default: ret = -EOPNOTSUPP; break; } return ret; }
/*** * rt_socket_common_ioctl */ int rt_socket_common_ioctl(struct rtdm_dev_context *sockctx, rtdm_user_info_t *user_info, int request, void *arg) { struct rtsocket *sock = (struct rtsocket *)&sockctx->dev_private; int ret = 0; struct rtnet_callback *callback = arg; unsigned int rtskbs; rtdm_lockctx_t context; switch (request) { case RTNET_RTIOC_XMITPARAMS: sock->priority = *(unsigned int *)arg; break; case RTNET_RTIOC_TIMEOUT: sock->timeout = *(nanosecs_rel_t *)arg; break; case RTNET_RTIOC_CALLBACK: if (user_info) return -EACCES; rtdm_lock_get_irqsave(&sock->param_lock, context); sock->callback_func = callback->func; sock->callback_arg = callback->arg; rtdm_lock_put_irqrestore(&sock->param_lock, context); break; case RTNET_RTIOC_EXTPOOL: rtskbs = *(unsigned int *)arg; if (rtdm_in_rt_context()) return -ENOSYS; mutex_lock(&sock->pool_nrt_lock); if (test_bit(SKB_POOL_CLOSED, &sockctx->context_flags)) { mutex_unlock(&sock->pool_nrt_lock); return -EBADF; } ret = rtskb_pool_extend(&sock->skb_pool, rtskbs); sock->pool_size += ret; mutex_unlock(&sock->pool_nrt_lock); if (ret == 0 && rtskbs > 0) ret = -ENOMEM; break; case RTNET_RTIOC_SHRPOOL: rtskbs = *(unsigned int *)arg; if (rtdm_in_rt_context()) return -ENOSYS; mutex_lock(&sock->pool_nrt_lock); ret = rtskb_pool_shrink(&sock->skb_pool, rtskbs); sock->pool_size -= ret; mutex_unlock(&sock->pool_nrt_lock); if (ret == 0 && rtskbs > 0) ret = -EBUSY; break; default: ret = -EOPNOTSUPP; break; } return ret; }