usbserial驱动流程解析_Part1_主要函数

本文分析了usbserial库的基础模板,详细介绍了主要函数定义,包括USB端和串口端的注册流程,重点讲解了如何替换和扩展tty_operation中的函数,并以probe为例展示了vendor特定操作的插入机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本系列解析usbseiral ko的源码,记录主要函数,调用流程,USB一端和串口一端的注册流程,本节简介主要函数以及替换规则。

首先,usbserial是USB转串口驱动的一个基础模板,其中有许多默认函数,他们的定义方式如下:

const struct bus_type usb_serial_bus_type = {
	.name =		"usb-serial",
	.match =	usb_serial_device_match,
	.probe =	usb_serial_device_probe,
	.remove =	usb_serial_device_remove,
	.drv_groups = 	usb_serial_drv_groups,
};
static struct usb_serial_driver usb_serial_generic_device = {
	.driver = {
		.owner =	THIS_MODULE,
		.name =		"generic",
	},
	.id_table =		generic_device_ids,
	.probe =		usb_serial_generic_probe,
	.calc_num_ports =	usb_serial_generic_calc_num_ports,
	.throttle =		usb_serial_generic_throttle,
	.unthrottle =		usb_serial_generic_unthrottle,
	.resume =		usb_serial_generic_resume,
};
static const struct tty_port_operations serial_port_ops = {
	.carrier_raised		= serial_port_carrier_raised,
	.dtr_rts		= serial_port_dtr_rts,
	.activate		= serial_port_activate,
	.shutdown		= serial_port_shutdown,
};
static const struct tty_operations serial_ops = {
	.open =			serial_open,
	.close =		serial_close,
	.write =		serial_write,
	.hangup =		serial_hangup,
	.write_room =		serial_write_room,
	.ioctl =		serial_ioctl,
	.set_termios =		serial_set_termios,
	.throttle =		serial_throttle,
	.unthrottle =		serial_unthrottle,
	.break_ctl =		serial_break,
	.chars_in_buffer =	serial_chars_in_buffer,
	.wait_until_sent =	serial_wait_until_sent,
	.tiocmget =		serial_tiocmget,
	.tiocmset =		serial_tiocmset,
	.get_icount =		serial_get_icount,
	.set_serial =		serial_set_serial,
	.get_serial =		serial_get_serial,
	.cleanup =		serial_cleanup,
	.install =		serial_install,
	.proc_show =		serial_proc_show,
};

其中,tty operation中有部分函数可以被替换掉,替换的过程如下:

static void usb_serial_operations_init(struct usb_serial_driver *device)
{
	set_to_generic_if_null(device, open);
	set_to_generic_if_null(device, write);
	set_to_generic_if_null(device, close);
	set_to_generic_if_null(device, write_room);
	set_to_generic_if_null(device, chars_in_buffer);
	if (device->tx_empty)
		set_to_generic_if_null(device, wait_until_sent);
	set_to_generic_if_null(device, read_bulk_callback);
	set_to_generic_if_null(device, write_bulk_callback);
	set_to_generic_if_null(device, process_read_urb);
	set_to_generic_if_null(device, prepare_write_buffer);
}

可见open、write、close、write_room、chars_in_buffer、read_bulk_callback、write_bulk_callback、process_read_urb、prepare_write_buffer函数可以被替换掉,不过有些函数采取的是插入的方式,目的是在generic的基础上,增加一些属vendor的其他操作,比如probe

以generic 的probe为例子,usbseiral设备在被probe的时候,一定会进行search_serial_device、create_serial等等操作,然后再简单的打印一些信息——如果有一些vendor specific的probe操作,可以单独添加——endpoint的查找在vendor的probe的后面,也是一定会进行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值