Linux设备驱动入门-USB设备驱动

Linux设备驱动入门-USB设备驱动

Linux设备驱动入门—-USB设备驱动

/****************************************
* USB主机与设备驱动
* 主机侧:由底到高:USB主机控制器硬件-->
* USB主机控制器驱动--> USB核心层 --> USB
* 设备驱动层
* 设备侧:UDC驱动程序、Gadget API和Gadget
* 驱动程序
* 逻辑组织:设备(1) <--> 配置(n)
* 配置(1) <--> 接口(n)
* 端点(0/n) <--> 接口(1) <--> 设置(n)
* USB主机控制驱动:控制插入其中的USB设备
* USB设备驱动:控制USB设备如何与主机通信
* 标准描述符:
* 设备描述符 usb_device_descriptor
* 配置描述符 usb_config_descriptor
* 接口描述符 usb_interface_descriptor
* 端点描述符 usb_endpoint_descriptor
* 字符串描述符 usb_string_descriptor
* 几个重要的数据结构:hc_driver usb_hcd
* ohci_hcd usb_driver urb(请求块)
* urb的典型生命周期:
* (1) 被一个USB设备驱动创建
* (2) 初始化,被安排给一个特定USB设备的特定端点
* (3) 被USB设备驱动提交给USB核心
* (4) 提交与USB核心指定的USB主机控制器驱动
* (5) 被USB主机控制器处理,进行一次到USB设备的传送
* (6) 当urb完成,USB主机控制器驱动通知USB设备驱动
*
* probe() 和 disconnect() 这两个函数比较重要
*
********************************************/

/*
* USB 设备驱动实例:USB串口驱动(部分)
*
*/
/* Driver structure we register with the USB core */
static struct usb_driver usb_serial_driver = {
.name = "usbserial",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.suspend = usb_serial_suspend,
.resume = usb_serial_resume,
.no_dynamic_id = 1,
}
/* USB串口设备驱动的模块加载函数 */
static int __init usb_serial_init(void)
{
int i;
int result;

/* 分配tty_driver */
usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS);
if(usb_serial_tty_driver)
{
return -ENOMEM;
}
/* 初始化全局变量 */
for(i = 0; i < SERIAL_TTY_MINORS; ++i)
serial_table[i] = NULL;

/* 注册总线 */
result = bus_register(&usb_serial_bus_type);
if(result)
{
printk(KERN_ERR "usb-serial: %s - registering bus driver failedn", __func__);
goto exit_bus;
}
/* 初始化tty_driver */
usb_serial_tty_driver->owner = THIS_MODULE;
usb_serial_tty_driver->driver_name = "usbserial";
usb_serial_tty_driver->name = "ttyUSB";
usb_serial_tty_driver->major = SERIAL_TTY_MAJOR;
usb_serial_tty_driver->minor_start = 0;
usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
usb_serial_tty_driver->init_termios = tty_std_termios;
usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD
| HUPCL | CLOCAL;
usb_serial_tty_driver->init_termios.c_ispeed = 9600;
usb_serial_tty_driver->init_termios.c_ospeed = 9600;

tty_set_operations(usb_serial_tty_driver, &serial_ops);
/* 注册tty_driver */
result = tty_register_driver(usb_serial_tty_driver);
if (result)
{
printk(KERN_ERR "usb-serial: %s - tty_register_driver failedn",
__func__);
goto exit_reg_driver;
}
/* 注册USB驱动 */
result = usb_register(&usb_serial_driver);
if (result < 0)
{
printk(KERN_ERR "usb-serial: %s - usb_register failedn",
__func__);
goto exit_tty;
}
/* register the generic driver, if we should */
result = usb_serial_generic_register(debug);
if (result < 0)
{
printk(KERN_ERR "usb-serial: %s - registering generic "
"driver failedn", __func__);
goto exit_generic;
}

printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "n");

return result;

exit_generic:
usb_deregister(&usb_serial_driver);

exit_tty:
tty_unregister_driver(usb_serial_tty_driver);

exit_reg_driver:
bus_unregister(&usb_serial_bus_type);

exit_bus:
printk(KERN_ERR "usb-serial: %s - returning with error %dn",
__func__, result);
put_tty_driver(usb_serial_tty_driver);
return result;
}

static void __exit usb_serial_exit(void)
{
usb_serial_console_exit();

usb_serial_generic_deregister();

usb_deregister(&usb_serial_driver); //注销usb_driver
tty_unregister_driver(usb_serial_tty_driver); // 注销tty_driver
put_tty_driver(usb_serial_tty_driver); // 减少引用计数

Linux设备驱动入门-USB设备驱动

相关文章:

你感兴趣的文章:

标签云: