设为首页 加入收藏

TOP

Linux 2.6.35 下usb框架程序源码(四)
2014-11-24 08:39:33 来源: 作者: 【 】 浏览:6
Tags:Linux 2.6.35 usb 框架 程序源码
ev->bulk_in_urb, GFP_KERNEL);
if (rv < 0) {
err("%s - failed submitting read urb, error %d",
__func__, rv);
dev->bulk_in_filled = 0;
rv = (rv == -ENOMEM) rv : -EIO;
spin_lock_irq(&dev->err_lock);
dev->ongoing_read = 0;
spin_unlock_irq(&dev->err_lock);
}


return rv;
}


static ssize_t skel_read(struct file *file, char *buffer, size_t count,
loff_t *ppos)
{
struct usb_skel *dev;
int rv;
bool ongoing_io;


dev = (struct usb_skel *)file->private_data;


/* if we cannot read at all, return EOF */
if (!dev->bulk_in_urb || !count)
return 0;


/* no concurrent readers */
rv = mutex_lock_interruptible(&dev->io_mutex);
if (rv < 0)
return rv;


if (!dev->interface) { /* disconnect() was called */
rv = -ENODEV;
goto exit;
}


/* if IO is under way, we must not touch things */
retry:
spin_lock_irq(&dev->err_lock);
ongoing_io = dev->ongoing_read;
spin_unlock_irq(&dev->err_lock);


if (ongoing_io) {
/* nonblocking IO shall not wait */
if (file->f_flags & O_NONBLOCK) {
rv = -EAGAIN;
goto exit;
}
/*
* IO may take forever
* hence wait in an interruptible state
*/
rv = wait_for_completion_interruptible(&dev->bulk_in_completion);
if (rv < 0)
goto exit;
/*
* by waiting we also semiprocessed the urb
* we must finish now
*/
dev->bulk_in_copied = 0;
dev->processed_urb = 1;
}


if (!dev->processed_urb) {
/*
* the URB hasn't been processed
* do it now
*/
wait_for_completion(&dev->bulk_in_completion);
dev->bulk_in_copied = 0;
dev->processed_urb = 1;
}


/* errors must be reported */
rv = dev->errors;
if (rv < 0) {
/* any error is reported once */
dev->errors = 0;
/* to preserve notifications about reset */
rv = (rv == -EPIPE) rv : -EIO;
/* no data to deliver */
dev->bulk_in_filled = 0;
/* report it */
goto exit;
}


/*
* if the buffer is filled we may satisfy the read
* else we need to start IO
*/


if (dev->bulk_in_filled) {
/* we had read data */
size_t available = dev->bulk_in_filled - dev->bulk_in_copied;
size_t chunk = min(available, count);


if (!available) {
/*
* all data has been used
* actual IO needs to be done
*/
rv = skel_do_read_io(dev, count);
if (rv < 0)
goto exit;
else
goto retry;
}
/*
* data is available
* chunk tells us how much shall be copied
*/


if (copy_to_user(buffer,
dev->bulk_in_buffer + dev->bulk_in_copied,
chunk))
rv = -EFAULT;
else
rv = chunk;


dev->bulk_in_copied += chunk;


/*
* if we are asked for more than we have,
* we start IO but don't wait
*/
if (available < count)
skel_do_read_io(dev, count - chunk);
} else {
/* no data in the buffer */
rv = skel_do_read_io(dev, count);
if (rv < 0)
goto exit;
else if (!(file->f_flags & O_NONBLOCK))
goto retry;
rv = -EAGAIN;
}
exit:
mutex_unlock(&dev->io_mutex);
return rv;
}


stat

首页 上一页 1 2 3 4 5 6 下一页 尾页 4/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Eclipse+CDT+Gcc编译选项控制 下一篇嵌入式Linux低成本智能终端方案

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·【C语言】动态内存管 (2025-12-27 06:23:20)
·C语言中的内存管理 - (2025-12-27 06:23:16)
·C语言指南:C语言内 (2025-12-27 06:23:14)
·Redis on AWS:Elast (2025-12-27 04:19:30)
·在 Spring Boot 项目 (2025-12-27 04:19:27)