⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbmouse.c

📁 linux字符终端下的usb鼠标驱动
💻 C
字号:
//You know, usb device driver is according to the interface.
#include <linux/kernel.h>
#include <asm/ppc_asm.h>
#include <linux/slab.h>		//kmalloc,kfree
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/init.h>

#define DEBUG

#ifdef DEBUG
#define ent_line(n) printk(KERN_INFO "I have entered the line %d!\n",(n))
#endif

#define MOU_INTF_CL 3	//mouse interface class
#define MOU_INTF_SC 1	//interface sub class
#define MOU_INTF_PR 2	//interface protocal

static void * usb_mouse_probe(struct usb_device *udev,unsigned int ifnum,
			const struct usb_device_id *id);
static void usb_mouse_disconnect(struct usb_device *udev,void *ptr);
static void usb_mouse_irq(struct urb *urb);

struct usb_mouse{
	signed char mouse_data[8];
	char name[128];
	struct usb_device * usbdev;
	struct urb mouse_urb;
	int open;
};

MODULE_AUTHOR("Haijian CAO");
MODULE_DESCRIPTION("USB HID Boot Protocol mouse driver");
MODULE_LICENSE("GPL");
//MODULE_VERSION("V1.0");

static struct usb_device_id usb_mouse_id_table[]={
	{USB_INTERFACE_INFO(MOU_INTF_CL,MOU_INTF_SC,MOU_INTF_PR)},
	{}
};
MODULE_DEVICE_TABLE(usb,usb_mouse_id_table);	//Export the id_table

static struct usb_driver usb_mouse_driver={
	name:		"chj_usb_mouse",
	probe:		usb_mouse_probe,
	disconnect:	usb_mouse_disconnect,
	id_table:	usb_mouse_id_table,
};
/*************************************************************************
Probe function.
Return a struct usb_mouse pointer or a NULL that indicate error.
*************************************************************************/
static void * usb_mouse_probe(struct usb_device *udev,unsigned int ifnum,
			const struct usb_device_id *id)
{
	struct usb_interface *iface;
	struct usb_interface_descriptor * iface_desc;
	struct usb_endpoint_descriptor *enp_desc;
	struct usb_mouse * mouse;
	int pipe,maxp;
	char * buf;
	#ifdef DEBUG
	printk(KERN_INFO "I have entered the probe function!\n");
	//return NULL;
	#endif
	
	iface =&udev->actconfig->interface[ifnum];
ent_line(1);
	iface_desc=&iface->altsetting[iface->act_altsetting];	//get the active 
							//interface description.
ent_line(2);
	if(iface_desc->bNumEndpoints!=1) return NULL;	//There is only one enp.
	
ent_line(3);
	enp_desc=iface_desc->endpoint;			//get the endpoint
//Now make sure that the type of the endpoint is appropriate
ent_line(4);
	if(!(enp_desc->bEndpointAddress&
		USB_ENDPOINT_DIR_MASK)) return NULL; //Is an IN endpoint
ent_line(5);
	if((enp_desc->bmAttributes&USB_ENDPOINT_XFERTYPE_MASK)!=
		USB_ENDPOINT_XFER_INT) return NULL; //Is an Interrupt endpoint
ent_line(6);
//I don't know why not involving the idVendor 0x056a mouse
	if(udev->descriptor.idVendor==0x056a) return NULL;
ent_line(7);
//Create a proper pipe(in,interrupt,low)	
	pipe=usb_rcvintpipe(udev,enp_desc->bEndpointAddress);
ent_line(8);
//Get the value of the max_packet
	maxp=usb_maxpacket(udev,pipe,usb_pipeout(pipe));
ent_line(9);
	
	usb_set_idle(udev,iface_desc->bInterfaceNumber,0,0);
ent_line(10);
//Now fill the struct usb_mouse
	if(!(mouse=kmalloc(sizeof(struct usb_mouse),GFP_KERNEL))) return NULL;
ent_line(11);
	memset(mouse,0,sizeof(struct usb_mouse));	//initial a usb_mouse struct
ent_line(12);
	
	if(!(buf=kmalloc(63,GFP_KERNEL)))
	{
		kfree(mouse);
		return NULL;
	}
	
	if(udev->descriptor.iManufacturer&&usb_string(udev,
		udev->descriptor.iManufacturer,buf,63)>0)
		 	strcat(mouse->name,buf);
	if(udev->descriptor.iProduct&&usb_string(udev,
		udev->descriptor.iProduct,buf,63)>0)
		 	sprintf(mouse->name,"%s %s",mouse->name,buf);	//fill the mouse->name
	kfree(buf);
	
ent_line(16);
	FILL_INT_URB(&mouse->mouse_urb,udev,pipe,mouse->mouse_data,maxp,
		usb_mouse_irq,mouse,enp_desc->bInterval); //fill the mouse->mouse_urb

ent_line(25);
	printk(KERN_INFO "Device: %s\nThe ifnum is: %d\n",mouse->name,ifnum);
	
ent_line(26);
	if (usb_submit_urb(&mouse->mouse_urb)) return NULL;	//submit the urb to the uhci
	
ent_line(27);
	return mouse;
}
/*************************************************************************
disconnect function.
This function are called when the usb device are removing from the bus.
*************************************************************************/
static void usb_mouse_disconnect(struct usb_device *udev,void *ptr)
{
	struct usb_mouse *mouse=ptr;
	usb_unlink_urb(&mouse->mouse_urb);
	kfree(mouse);
}
/*************************************************************************
The completion routine.
Called when the urb completes a transfer.
*************************************************************************/
static void usb_mouse_irq(struct urb *urb)
{
	struct usb_mouse* cont=urb->context;
	signed char *data=cont->mouse_data;
	int i;
	if (urb->status) return; 	//some error
	printk("Mouse Event!\nData=[");
	for (i=0;i<=7;i++)
	{
		printk("%3d,",data[i]);
	}
	printk("]!\n");
}

static int __init usb_mouse_init(void)
{
	usb_register(&usb_mouse_driver);
	info("V1.0 : USB HID Boot Protocol mouse driver");
	return 0;
}
static void __exit usb_mouse_exit(void)
{
	usb_deregister(&usb_mouse_driver);
	info("Driver Removed!");
}
module_init(usb_mouse_init);
module_exit(usb_mouse_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -