编写Linux下usb设备驱动方法:disconnect函数中要完成的任务

发布于:2025-09-01 ⋅ 阅读:(18) ⋅ 点赞:(0)

一. 简介

前一篇文章学习了 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); //强制终止URB
    usb_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");
}


网站公告

今日签到

点亮在社区的每一天
去签到