编写Linux下usb设备驱动方法:disconnect函数中要完成的任务
一. 简介
前一篇文章学习了 usb设备驱动开发中,probe函数中要完成的工作,文章如下:
编写Linux下usb设备驱动方法:probe函数中要进行的工作-CSDN博客
本文继续学习 Linux嵌入式 usb设备驱动实现,主要简单学习一下 disconnect函数要进行的工作。
二. 编写Linux下usb设备驱动方法:disconnect函数中要完成的任务
在 USB 设备驱动中,disconnect
函数是 struct usb_driver
结构体中的一个关键回调函数,主要负责在 USB 设备与驱动断开连接时(如设备被物理拔出、驱动被卸载或系统重启时)执行资源清理操作,是保障内核稳定性的重要机制。
1. disconnect函数的核心作用
- 资源释放:释放
probe
函数中分配的所有资源(内存、URB、设备节点等),避免内存泄漏。
- 状态清理:重置设备相关的状态标志,确保驱动退出时系统状态一致。
- 通知处理:必要时通知用户空间程序设备已断开连接。
2. disconnect函数调用时机
disconnect
函数由内核在以下场景自动调用:
(1) USB设备被物理拔出时;
(2) 驱动模块被卸载时(rmmod),对已绑定的设备执行清理;
(3) 设备在枚举过程中失败,需要解除驱动绑定;
(4) 系统关闭或重启时;
3. disconnect函数中需要进行的工作
(1) 资源释放:释放所有在 probe函数中分配的资源
(2) 设备注销:从系统中注销设备节点和字符设备
(3) URB清理:停止和释放所有未完成的 usb请求块(URB传输块)
(4) 状态清理:清理设备状态,确保系统稳定性
(5) 引用计数管理:正确管理引用计数,防止内存泄漏
三. disconnect函数实现框架
disconnect函数示例如下:
//设备私有数据
struct my_usb_dev {struct usb_device *udev; //usb设备指针struct usb_interface * intf;//接口指针struct urb *read_urb; //URB传输块unsigned char * read_buf; //读缓冲区struct cdev cdev; //字符设备结构struct class *class;//... 其他需要释放的资源
};//disconnect函数
static void my_usb_disconnect(struct usb_interface *intf) {//获取probe函数中关联到接口的私有数据struct my_usb_dev* usb_dev = usb_get_intfdata(intf);if(!usb_dev) {return;}//1. 终止URB传输(避免设备已断开但URB仍在等待)usb_kill_urb(usb_dev->read_urb); //强制终止URBusb_free_urb(usb_dev->read_urb); //释放URB结构体//2. 释放内核内存缓冲区kfree(usb_dev->read_buf);//3. 注销字符设备(如果创建了/dev节点)cdev_del(&usb_dev->cdev);unregister_chrdev_region(MAJOR(usb_dev->dev_num, 0), 1);device_destroy(usb_dev->class, usb_dev->dev_num);//4. 释放USB设备引用(减少设备计数,允许内核释放设备结构体)usb_put_dev(usb_dev->udev);//5. 释放私有数据结构本身kfree(usb_dev);//6.清除接口关联的私有数据(避免野指针)usb_set_intfdata(intf, NULL);//输出调试信息dev_info(&intf->dev, "USB device disconnected and resources released\n");
}