4,465
社区成员




static ssize_t globalfifo_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos)
{
int ret;
DECLARE_WAITQUEUE(wait,current);
down(&globalfifo_devp->sem);
add_wait_queue(&globalfifo_devp->w_wait,&wait);
if(globalfifo_devp->current_len==GLOBALFIFO_SIZE)
{
if(filp->f_flags & O_NONBLOCK)
{
ret=-EAGAIN;
goto out;
}
__set_current_state(TASK_INTERRUPTIBLE);
up(&globalfifo_devp->sem);
schedule();
if(signal_pending(current))
{
ret=-ERESTARTSYS;
goto out2;
}
down(&globalfifo_devp->sem);
}
if(count>GLOBALFIFO_SIZE-globalfifo_devp->current_len)
count=GLOBALFIFO_SIZE-globalfifo_devp->current_len;
if(copy_from_user(globalfifo_devp->mem+globalfifo_devp->current_len,buf,count))
{
ret=-EFAULT;
goto out;
}
else
{
globalfifo_devp->current_len +=count;
printk(KERN_INFO"written %d bytes ,curren_len:%d\n",count,globalfifo_devp->current_len);
wake_up_interruptible(&globalfifo_devp->r_wait);
ret=count;
}
out:up(&globalfifo_devp->sem);
out2:remove_wait_queue(&globalfifo_devp->w_wait,&wait);
set_current_state(TASK_RUNNING);
return ret;
}
static ssize_t globalfifo_read(struct file *filp,char __user *buf,size_t count,loff_t *ppos)
{
int ret;
DECLARE_WAITQUEUE(wait,current);
down(&globalfifo_devp->sem);
add_wait_queue(&globalfifo_devp->r_wait,&wait);
if(globalfifo_devp->current_len==0)
{
if(filp->f_flags & O_NONBLOCK)
{
ret = -EAGAIN;
goto out;
}
__set_current_state(TASK_INTERRUPTIBLE);
up(&globalfifo_devp->sem);
schedule();
if(signal_pending(current))
{
ret =-ERESTARTSYS;
goto out2;
}
down(&globalfifo_devp->sem);
}
if(count>globalfifo_devp->current_len)
count=globalfifo_devp->current_len;
if(copy_to_user(buf,globalfifo_devp->mem,count))
{
ret=-EFAULT;
goto out;
}
else
{
memcpy(globalfifo_devp->mem,globalfifo_devp->mem+count,globalfifo_devp->current_len-count);
globalfifo_devp->current_len-=count;
printk(KERN_INFO"read %d bytes,current_len:%d\n",count,globalfifo_devp->current_len);
wake_up_interruptible(&globalfifo_devp->w_wait);
ret=count;
}
out:up(&globalfifo_devp->sem);
out2:remove_wait_queue(&globalfifo_devp->w_wait,&wait);
return ret;
}