所有 USB 驱动必须创建的主要结构是 struct usb_driver. 这个结构必须被 USB 驱动填 充并且包含多个函数回调和变量, 来向 USB 核心代码描述 USB 驱动:

struct module *owner

指向这个驱动的模块拥有者的指针. USB 核心使用它正确地引用计数这个 USB 驱 动, 以便它不被在不合适的时刻卸载. 这个变量应当设置到 THIS_MODULE 宏.

const char *name

指向驱动名子的指针. 它必须在内核 USB 驱动中是唯一的并且通常被设置为和驱 动的模块名相同. 它出现在 sysfs 中在 /sys/bus/usb/drivers/ 之下, 当驱动在 内核中时.

const struct usb_device_id *id_table

指向 struct usb_device_id 表的指针, 包含这个驱动可接受的所有不同类型 USB 设备的列表. 如果这个变量没被设置, USB 驱动中的探测回调函数不会被调用. 如 果你需要你的驱动给系统中每个 USB 设备一直被调用, 创建一个只设置这个 driver_info 成员的入口项:

static struct usb_device_id usb_ids[] = {

{.driver_info = 42},

{}

};

int (*probe) (struct usb_interface *intf, const struct usb_device_id *id)

指向 USB 驱动中探测函数的指针. 这个函数(在"探测和去连接的细节"一节中描述) 被 USB 核心调用当它认为它有一个这个驱动可处理的 struct usb_interface. 一 个指向 USB 核心用来做决定的 struct usb_device_id 的指针也被传递到这个函 数. 如果这个 USB 驱动主张传递给它的 struct usb_interface, 它应当正确地初 始化设备并且返回 0. 如果驱动不想主张这个设备, 或者发生一个错误, 它应当返 回一个负错误值.

void (*disconnect) (struct usb_interface *intf)

指向 USB 驱动的去连接函数的指针. 这个函数(在"探测和去连接的细节"一节中描 述)被 USB 核心调用, 当 struct usb_interface 已被从系统中清除或者当驱动被 从 USB 核心卸载.

为创建一个值 struct usb_driver 结构, 只有 5 个成员需要被初始化:

static struct usb_driver skel_driver = {

.owner = THIS_MODULE,

.name = "skeleton",

.id_table = skel_table,

.probe = skel_probe,

.disconnect = skel_disconnect,

};

struct usb_driver 确实包含更多几个回调, 它们通常不经常用到, 并且不被要求使 USB 驱动正确工作:

int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf)

指向 USB 驱动的 ioctl 函数的指针. 如果它出现, 在用户空间程序对一个关联到 USB 设备的 usbfs 文件系统设备入口, 做一个 ioctl 调用时被调用. 实际上, 只 有 USB 集线器驱动使用这个 ioctl, 因为没有其他的真实需要对于任何其他 USB 驱动要使用.

int (*suspend) (struct usb_interface *intf, u32 state)

指向 USB 驱动中的悬挂函数的指针. 当设备要被 USB 核心悬挂时被调用. int (*resume) (struct usb_interface *intf)

指向 USB 驱动中的恢复函数的指针. 当设备正被 USB 核心恢复时被调用.

为注册 struct usb_driver 到 USB 核心, 一个调用 usb_register_driver 带一个指向 struct usb_driver 的指针. 传统上在 USB 驱动的模块初始化代码做这个:

static int   init usb_skel_init(void)

{

int result;

/*
register this driver with the USB subsystem */ result =
usb_register(&skel_driver);

if
(result)

err("usb_register failed. Error number
%d", result); return result;

}


USB 驱动被卸载, struct usb_driver 需要从内核注销. 使用对 usb_deregister_driver 的调用做这个. 当这个调用发生,
任何当前绑定到这个驱动的 USB 接口被去连接, 并且去连接函数为它们而被调用.

static void  
exit usb_skel_exit(void)

{

/* deregister this driver with the USB subsystem */
usb_deregister(&skel_driver);

}

Linux 内核注册一个 USB 驱动的更多相关文章

  1. linux内核分析作业6:分析Linux内核创建一个新进程的过程

    task_struct结构: struct task_struct {   volatile long state;进程状态  void *stack; 堆栈  pid_t pid; 进程标识符  u ...

  2. 第六周分析Linux内核创建一个新进程的过程

    潘恒 原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 task_struct结构: ...

  3. 实验 六:分析linux内核创建一个新进程的过程

    实验六:分析Linux内核创建一个新进程的过程 作者:王朝宪  <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029 ...

  4. 20135202闫佳歆--week6 分析Linux内核创建一个新进程的过程——实验及总结

    week 6 实验:分析Linux内核创建一个新进程的过程 1.使用gdb跟踪创建新进程的过程 准备工作: rm menu -rf git clone https://github.com/mengn ...

  5. 《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

    20135311傅冬菁 分析Linux内核创建一个新进程的过程 一.学习内容 进程控制块——PCB  task_struct数据结构 PCB task_struct中包含: 进程状态.进程打开的文件. ...

  6. 作业六:分析Linux内核创建一个新进程的过程

    分析Linux内核创建一个新进程的过程 进程描述符PCB----task_struct数据结构 操作系统:1.进程管理 2.内存管理 3 文件系统 一.新进程如何创建和修改task_struct数据结 ...

  7. Linux内核分析-分析Linux内核创建一个新进程的过程

    作者:江军 ID:fuchen1994 实验题目:分析Linux内核创建一个新进程的过程 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/li ...

  8. 给Linux内核增加一个系统调用的方法(转)

    作者:chenjieb520 给Linux内核增加一个系统调用的方法    为了更加好地调试linux内核,笔者的实验均在mini6410的arm板上运行的.这样做的原因,第一是因为本人是学嵌入式的, ...

  9. Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程

    Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

随机推荐

  1. js写的滑动解锁

    css部分 *{ margin:; padding:; box-sizing: border-box; -webkit-touch-callout: none; -webkit-user-select ...

  2. Contacts源码分析(一、概述)

    代码版本: Contact code version: 4.4.2 一 打开Log开关:如if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG ...

  3. Android实战:手把手实现“捧腹网”APP(三)-----UI实现,逻辑实现

    Android实战:手把手实现"捧腹网"APP(一)-–捧腹网网页分析.数据获取 Android实战:手把手实现"捧腹网"APP(二)-–捧腹APP原型设计.实 ...

  4. [ITOO]动态建库 标签: 库数据库mysql 2016-07-17 21:23 241人阅读 评论(2) 收

    最近一直在做权限系统的动态建库,动态建库,说白了就是在你点击"注册"按钮的时候,根据你输入的信息,来创建一个企业所需要的数据库的过程,因为现阶段并没有提供购买等功能,所以暂时咱们是 ...

  5. Java练习 SDUT-3848_Shift Dot

    Shift Dot Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给出平面直角坐标系中的一点,并顺序给出n个向量,求该 ...

  6. OpenKruise - 云原生应用自动化引擎正式开源

    2019 年 6 月 24 日至 26 日, 由 Cloud Native Computing Foundation (CNCF) 主办的云原生技术大会 KubeCon + CloudNativeCo ...

  7. @topcoder - 2017TCOAlgorithmRound2A - D1L2@ DistanceZeroAndOne

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一个 n 个点的无向简单的连通图,编号从 0 到 n-1. 现给 ...

  8. Python基础:27执行环境

    一:可调用对象 可调用对象,是任何能通过函数操作符“()”来调用的对象.Python 有4 种可调用对象:函数,方法,类,以及一些类的实例. 1:函数 python 有 3 种不同类型的函数对象. a ...

  9. HZOJ 辣鸡(ljh)

    题解?noipT1还需要题解?正解就是$n^2$大暴力. 考试的时候打了$n^2$的暴力,也想到了正解的优化,然而觉得它太麻烦了,而且$n^2$怎么优化也过不了50000啊,而且即使不优化前面30分我 ...

  10. APICloud ajax请求api数据问题

    云编译开启全局加密的情况下,请务必使用api.ajax,避免使用JQ等框架的ajax,否则将引起请求失败.官网API说明链接 还要就是要注意用$.ajax请求数据时会出现的同源策略问题.