usb鼠标驱动(一)

news/2024/11/7 12:31:23/

Linux USB 鼠标驱动程序详解
注册一个usb driver,这个drvier不是usb设备driver,而是接口driver。

/* use a define to avoid include chaining to get THIS_MODULE & friends */
#define usb_register(driver) \usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)retval = driver_register(&new_driver->drvwrap.driver);if (retval)goto out;

这个probe参数1是一个接口数据结构,表示注册的时接口驱动不是设备驱动,设备驱动在在系统中已经注册好了,是一个通用设备驱动,用来读取设备的描述符,做一些解析。所以我们真正实现的时一个usb接口驱动。

static int usb_mouse_probe(struct usb_interface *intf,const struct usb_device_id *id)//表示一个接口
struct usb_interface {/* array of alternate settings for this interface,* stored in no particular order */struct usb_host_interface *altsetting;struct usb_host_interface *cur_altsetting;	/* the currently* active alternate setting */unsigned num_altsetting;	/* number of alternate settings *//* If there is an interface association descriptor then it will list* the associated interfaces */struct usb_interface_assoc_descriptor *intf_assoc;int minor;			/* minor number this interface is* bound to */enum usb_interface_condition condition;		/* state of binding */unsigned sysfs_files_created:1;	/* the sysfs attributes exist */unsigned ep_devs_created:1;	/* endpoint "devices" exist */unsigned unregistering:1;	/* unregistration is in progress */unsigned needs_remote_wakeup:1;	/* driver requires remote wakeup */unsigned needs_altsetting0:1;	/* switch to altsetting 0 is pending */unsigned needs_binding:1;	/* needs delayed unbind/rebind */unsigned resetting_device:1;	/* true: bandwidth alloc after reset */unsigned authorized:1;		/* used for interface authorization */struct device dev;		/* interface specific device info */struct device *usb_dev;struct work_struct reset_ws;	/* for resets in atomic context */
};
#define	to_usb_interface(d) container_of(d, struct usb_interface, dev)

usb设备结构体

struct usb_device {int		devnum;char		devpath[16];u32		route;enum usb_device_state	state;enum usb_device_speed	speed;unsigned int		rx_lanes;unsigned int		tx_lanes;struct usb_tt	*tt;int		ttport;unsigned int toggle[2];struct usb_device *parent;struct usb_bus *bus;struct usb_host_endpoint ep0;struct device dev;struct usb_device_descriptor descriptor;struct usb_host_bos *bos;struct usb_host_config *config;struct usb_host_config *actconfig;struct usb_host_endpoint *ep_in[16];struct usb_host_endpoint *ep_out[16];char **rawdescriptors;unsigned short bus_mA;u8 portnum;u8 level;unsigned can_submit:1;unsigned persist_enabled:1;unsigned have_langid:1;unsigned authorized:1;unsigned authenticated:1;unsigned wusb:1;unsigned lpm_capable:1;unsigned usb2_hw_lpm_capable:1;unsigned usb2_hw_lpm_besl_capable:1;unsigned usb2_hw_lpm_enabled:1;unsigned usb2_hw_lpm_allowed:1;unsigned usb3_lpm_u1_enabled:1;unsigned usb3_lpm_u2_enabled:1;int string_langid;/* static strings from the device */char *product;char *manufacturer;char *serial;struct list_head filelist;int maxchild;u32 quirks;atomic_t urbnum;unsigned long active_duration;#ifdef CONFIG_PMunsigned long connect_time;unsigned do_remote_wakeup:1;unsigned reset_resume:1;unsigned port_is_suspended:1;
#endifstruct wusb_dev *wusb_dev;int slot_id;enum usb_device_removable removable;struct usb2_lpm_parameters l1_params;struct usb3_lpm_parameters u1_params;struct usb3_lpm_parameters u2_params;unsigned lpm_disable_count;u16 hub_delay;
};
#define	to_usb_device(d) container_of(d, struct usb_device, dev)
int		devnum;  //usb总线上的一个地址
struct usb_device_descriptor descriptor; //设备描述符

配置描述符,可以有多个配置描述。

struct usb_host_config {struct usb_config_descriptor	desc;char *string;		/* iConfiguration string, if present *//* List of any Interface Association Descriptors in this* configuration. */struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS];/* the interfaces associated with this configuration,* stored in no particular order */struct usb_interface *interface[USB_MAXINTERFACES];/* Interface information available even when this is not the* active configuration */struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];unsigned char *extra;   /* Extra descriptors */int extralen;
};

/* host-side wrapper for one interface setting’s parsed descriptors */
一个接口设置的解析描述符的主机端包装器

/* host-side wrapper for one interface setting's parsed descriptors */
struct usb_host_interface {struct usb_interface_descriptor	desc;int extralen;unsigned char *extra;   /* Extra descriptors *//* array of desc.bNumEndpoints endpoints associated with this* interface setting.  these will be in no particular order.*/struct usb_host_endpoint *endpoint;char *string;		/* iInterface string, if present */
};

端点结构体:表示一个端点
在这里插入图片描述

//鼠标驱动代码学习。

/**  Copyright (c) 1999-2001 Vojtech Pavlik**  USB HIDBP Mouse support*//** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA** Should you need to contact me, the author, you can do so either by* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic*/#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/hid.h>/* for apple IDs */
#ifdef CONFIG_USB_HID_MODULE
#include "../hid-ids.h"
#endif/** Version Information*/
#define DRIVER_VERSION "v1.6"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB HID Boot Protocol mouse driver"MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");struct usb_mouse {char name[128];char phys[64];struct usb_device *usbdev;struct input_dev *dev;struct urb *irq;signed char *data;dma_addr_t data_dma;
};static void usb_mouse_irq(struct urb *urb)
{struct usb_mouse *mouse = urb->context;signed char *data = mouse->data;struct input_dev *dev = mouse->dev;int status;switch (urb->status) {case 0:			/* success */break;case -ECONNRESET:	/* unlink */case -ENOENT:case -ESHUTDOWN:return;/* -EPIPE:  should clear the halt */default:		/* error */goto resubmit;}input_report_key(dev, BTN_LEFT,   data[0] & 0x01);input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);input_report_key(dev, BTN_SIDE,   data[0] & 0x08);input_report_key(dev, BTN_EXTRA,  data[0] & 0x10);input_report_rel(dev, REL_X,     data[1]);input_report_rel(dev, REL_Y,     data[2]);input_report_rel(dev, REL_WHEEL, data[3]);input_sync(dev);
resubmit:status = usb_submit_urb (urb, GFP_ATOMIC);if (status)dev_err(&mouse->usbdev->dev,"can't resubmit intr, %s-%s/input0, status %d\n",mouse->usbdev->bus->bus_name,mouse->usbdev->devpath, status);
}static int usb_mouse_open(struct input_dev *dev)
{struct usb_mouse *mouse = input_get_drvdata(dev);mouse->irq->dev = mouse->usbdev;if (usb_submit_urb(mouse->irq, GFP_KERNEL))return -EIO;return 0;
}static void usb_mouse_close(struct input_dev *dev)
{struct usb_mouse *mouse = input_get_drvdata(dev);usb_kill_urb(mouse->irq);
}static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
{struct usb_device *dev = interface_to_usbdev(intf);struct usb_host_interface *interface;struct usb_endpoint_descriptor *endpoint;struct usb_mouse *mouse;struct input_dev *input_dev;int pipe, maxp;int error = -ENOMEM;interface = intf->cur_altsetting;if (interface->desc.bNumEndpoints != 1)return -ENODEV;endpoint = &interface->endpoint[0].desc;if (!usb_endpoint_is_int_in(endpoint))return -ENODEV;pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);input_dev = input_allocate_device();if (!mouse || !input_dev)goto fail1;mouse->data = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &mouse->data_dma);if (!mouse->data)goto fail1;mouse->irq = usb_alloc_urb(0, GFP_KERNEL);if (!mouse->irq)goto fail2;mouse->usbdev = dev;mouse->dev = input_dev;if (dev->manufacturer)strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));if (dev->product) {if (dev->manufacturer)strlcat(mouse->name, " ", sizeof(mouse->name));strlcat(mouse->name, dev->product, sizeof(mouse->name));}if (!strlen(mouse->name))snprintf(mouse->name, sizeof(mouse->name),"USB HIDBP Mouse %04x:%04x",le16_to_cpu(dev->descriptor.idVendor),le16_to_cpu(dev->descriptor.idProduct));usb_make_path(dev, mouse->phys, sizeof(mouse->phys));strlcat(mouse->phys, "/input0", sizeof(mouse->phys));input_dev->name = mouse->name;input_dev->phys = mouse->phys;usb_to_input_id(dev, &input_dev->id);input_dev->dev.parent = &intf->dev;input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |BIT_MASK(BTN_EXTRA);input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);input_set_drvdata(input_dev, mouse);input_dev->open = usb_mouse_open;input_dev->close = usb_mouse_close;usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,(maxp > 8 ? 8 : maxp),usb_mouse_irq, mouse, endpoint->bInterval);mouse->irq->transfer_dma = mouse->data_dma;mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;error = input_register_device(mouse->dev);if (error)goto fail3;usb_set_intfdata(intf, mouse);return 0;fail3:	usb_free_urb(mouse->irq);
fail2:	usb_free_coherent(dev, 8, mouse->data, mouse->data_dma);
fail1:	input_free_device(input_dev);kfree(mouse);return error;
}static void usb_mouse_disconnect(struct usb_interface *intf)
{struct usb_mouse *mouse = usb_get_intfdata (intf);usb_set_intfdata(intf, NULL);if (mouse) {usb_kill_urb(mouse->irq);input_unregister_device(mouse->dev);usb_free_urb(mouse->irq);usb_free_coherent(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);kfree(mouse);}
}static const struct usb_device_id usb_mouse_id_table[] = {{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE) },{ }	/* Terminating entry */
};MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);static struct usb_driver usb_mouse_driver = {.name		= "usbmouse",.probe		= usb_mouse_probe,.disconnect	= usb_mouse_disconnect,.id_table	= usb_mouse_id_table,
};module_usb_driver(usb_mouse_driver);

http://www.ppmy.cn/news/211201.html

相关文章

设计模式入门:策略模式

现有一套模拟鸭子游戏&#xff0c;可以一边游泳&#xff0c;一边呱呱叫。 每种鸭子都会呱呱叫和游泳&#xff0c;只是外观不同。因此&#xff0c;quack和swim放在父类中&#xff0c;display放在子类中实现。 增加新的功能&#xff1a;鸭子飞翔。 1 我们可能想到直接在父类中增…

条码软件如何制作GS1-128条形码

GS1是国际物品编码组织的英文名称&#xff0c;全称为GS1全球统一标识系统。GS1是整个一个系统&#xff0c;或者说架构&#xff0c;其架构内部所包含的条码&#xff0c;可以有很多种&#xff0c;比如内部的条码是Code 128的&#xff0c;叫做GS1-128&#xff0c;而内部是DataBar的…

亚马逊条码标签(SSCC/FBA)的制作打印

近日&#xff0c;亚马逊对所有商家提出统一要求&#xff0c;产品须按照亚马逊制定的新规范来打印条码标签。做亚马逊外贸的商户都清楚&#xff0c;货品进入亚马逊仓库都必须通过扫描入库&#xff0c;否则无法进行上市销售。 有很多客户最近联系我们请求提供技术指导&#xff0c…

条码标签软件快速生成序列号标签

在做条码标签的时候&#xff0c;各行各业应该都会制作一种可变数据标签——序列号标签。其实输入序列号很简单&#xff0c;如果数量不多&#xff0c;手工输入都是可以的&#xff0c;可是如果需要100个、1000个、甚至10000个序列号的时候&#xff0c;难道还手工输入吗&#xff1…

gt800打印测试软件,zebra GT800 高级桌面条码标签打印机

zebra GT800 高级桌面条码标签打印机 zebra GT800 热敏/热传印桌面标签打印机以极具竞争优势的价格实现了先进性能和可靠性&#xff0c;提供一系列功能&#xff0c;可满足各类中、低容量的打印应用。GT800 能容纳 300 米碳带&#xff0c;增加了灵活性和打印机正常运行时间&…

条码标签里的数据源如何使用

很多小伙伴在刚开始使用条码软件制作标签时&#xff0c;会对于数据源这个概念有些陌生&#xff0c;也不知道该在什么时候使用数据源。其实这个很好判断&#xff0c;基本宗旨就是如果一个元素是固定不变的&#xff0c;那么就不需要使用数据源&#xff0c;如果一个元素的内容是变…

使用普通打印机打印条码标签

条码标签不仅可以在专用的标签打印机上打印&#xff0c;也可以在普通打印机上打印&#xff0c;我们只需要设计好一个标签的内容&#xff0c;然后排版&#xff0c;最后选择普通打印机即可。下面小编用一个例子来演示操作步骤。 首先我们打开条码标签软件&#xff0c;新建一个条…

如何使用hiprint插件制作条码标签

hiprint中文网址&#xff1a;http://www.hinnn.com/ 模板设计地址&#xff1a;http://www.hinnn.com/design 使用比较方便&#xff0c;可以在线设计模板&#xff0c;并且预览。 在记录一下如何制作二维码&#xff0c;久了不用也容易忘记。 下面是制作出来的模板示例图&#xff…