📄 usbmouse.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 + -