设为首页 加入收藏

TOP

Linux驱动开发:USB驱动之usb_skel分析(二)
2014-11-24 13:33:54 来源: 作者: 【 】 浏览:11
Tags:Linux 驱动 开发 USB usb_skel分析
ncrement our usage count for the device */


kref_get(&dev->kref);


/* now we can drop the lock */


mutex_unlock(&skel_open_lock);


/* prevent the device from being autosuspended */


retval = usb_autopm_get_interface(interface);


if (retval) {


kref_put(&dev->kref, skel_delete);


goto exit;


}


/* save our object in the file's private structure */


file->private_data = dev;


exit:


return retval;


}



static int skel_release(struct inode *inode, struct file *file)


{


struct usb_skel *dev;


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


if (dev == NULL)


return -ENODEV;


/* allow the device to be autosuspended */


mutex_lock(&dev->io_mutex);


if (dev->interface)


usb_autopm_put_interface(dev->interface);


mutex_unlock(&dev->io_mutex);


/* decrement the count on our device */


kref_put(&dev->kref, skel_delete);


return 0;


}



static ssize_t skel_read(struct file *file, char *buffer, size_t count, loff_t *ppos)


{


struct usb_skel *dev;


int retval;


int bytes_read;


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


mutex_lock(&dev->io_mutex);


if (!dev->interface) { /* disconnect() was called */


retval = -ENODEV;


goto exit;


}


/* 进行阻塞的批量读以从设备获取数据 */


retval = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr), dev->bulk_in_buffer, min(dev->bulk_in_size, count), &bytes_read, 10000);


/* 如果读成功,复制到用户空间 */


if (!retval) {


if (copy_to_user(buffer, dev->bulk_in_buffer, bytes_read))


retval = -EFAULT;


else


retval = bytes_read;


}


exit:


mutex_unlock(&dev->io_mutex);


return retval;


}



/*当urb被成功传输到USB设备之后,urb回调函数将被USB核心调用,在我们的例子中,我们初始化urb,使它指向skel_write_bulk_callback函数*/


static void skel_write_bulk_callback(struct urb *urb)


{


struct usb_skel *dev;


dev = (struct usb_skel *)urb->context;


/* sync/async unlink faults aren't errors */


if (urb->status && !(urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) {


err("%s - nonzero write bulk status received: %d",


__FUNCTION__, urb->status);


}


/ * free up our allocated buffer */


usb_buffer_free(urb->dev, urb->transfer_buffer_length,


urb->transfer_buffer, urb->transfer_dma);


up(&dev->limit_sem);


}



static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)


{


struct usb_skel *dev;


int retval = 0;


struct urb *urb = NULL;


char *buf = NULL;


size_t writesize = min(count, (size_t)MAX_TRANSFER);


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


/* verify that we actually have some data to write */


if (count == 0)


goto exit;


/* limit the number of URBs in flight to stop a user from using up all RAM */


if (down_interruptible(&dev->limit_sem)) {


retval = -ERESTARTSYS;


goto exit;


}



/* 创建一个urb,并且给它分配一个缓存*/
urb = usb_alloc_urb(0, GFP_KERNEL);


if (!urb) {


retval = -ENOMEM;


goto error;


}



/*当urb被成功分配后,还要创建一个DMA缓冲区来以高效的方式发送数据到设备,传递给驱动程序的数据要复制到这块缓冲中去*/


buf = usb_buffer_alloc(dev-

首页 上一页 1 2 3 4 5 下一页 尾页 2/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux驱动开发:Nand Flash时序图.. 下一篇Linux驱动开发:网络设备之虚拟网..

评论

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

·C语言中如何将结构体 (2025-12-24 22:20:09)
·纯C语言结构体成员变 (2025-12-24 22:20:06)
·C语言中,指针函数和 (2025-12-24 22:20:03)
·哈希表 - 菜鸟教程 (2025-12-24 20:18:55)
·MySQL存储引擎InnoDB (2025-12-24 20:18:53)