linux添加usb,为linux添加自己的USB驱动

本来想为mini2440添加自己的USB驱动,然后通过手柄做一些控制,结果一开始就遇到自己写的驱动被抢占了,google了几天未果,在csdn发了一个求助帖(http://topic.csdn.net/u/20100926/15/b5c7fc3b-e4f9-4843-89d2-b88ea484b9f3.html?34584),deep_pro兄提供了一个方法,借助这个方法我打开了胜利之门。

1、驱动编写不用多说,不会的参照usb-skeleton.c。我的模块名是joystick,所以编译后的模块是joystick.ko。

2、安装模块。

insmod&dmesg发现自己驱动的probe没有被调用,下面被抢占的输出:

usb 5-1.4: new low speed USB device using uhci_hcd and address 6

usb 5-1.4: New USB device found, idVendor=0e8f, idProduct=0002

usb 5-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0

usb 5-1.4: Product: BETOP USB GAMEPAD

usb 5-1.4: Manufacturer: GreenAsia Inc.

input: GreenAsia Inc. BETOP USB GAMEPAD as /devices/pci0000:00/0000:00:1d.0/usb5/5-1/5-1.4/5-1.4:1.0/input/input12

generic-usb 0003:0E8F:0002.0004: input,hidraw1: USB HID v1.10 Joystick [GreenAsia Inc. BETOP USB GAMEPAD] on usb-0000:00:1d.0-1.4/input0

之后deep_pro提供了一个方法(http://hi.baidu.com/deep_pro/blog/item/415ec217bdead20c4b90a77d.html),找到抢占设备的模块是usbhid,如果禁用此模块的话插入别的usbhid设备也用不了了,比如鼠标和键盘,所以只能让该模块忽略掉特定的设备,于是就开始读内核源码。刚开始我钻到了死角,一直在内核源码树下drivers/hid目录下找,把所有关于GREENASIA和PANTHERLORD的#define都注释了,还是未能解决,后来step out and look back,整理一下思路,钻到drivers/hid/usbhid里面找(之前也进去过,只是没怎么研究),用过函数嵌套关系一层一层回溯,终于到了顶点,在usbhid/hid-core.c里面的usbhid_probe(这是usbhid模块的probe函数)发现,如果不为设备调用hid_add_device,那该设备就不被usbhid模块抢占,所以我在usbhid模块的probe函数开头加了一段过滤代码,问题就解决了。

修改后的代码:

staticstructusb_device_id ignored_list[] = {

{USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0002)},

{ },

};

staticintis_ignored_device(unsignedshortidVendor, unsignedshortidProduct)

{

intindex;

for(index = 0;ignored_list[index].idVendor;index++)

{

if((ignored_list[index].idVendor == idVendor) && (ignored_list[index].idProduct == idProduct))

return1;

}

return0;

}

staticintusbhid_probe(structusb_interface *intf,conststructusb_device_id *id)

{

structusb_host_interface *interface = intf->cur_altsetting;

structusb_device *dev = interface_to_usbdev(intf);

structusbhid_device *usbhid;

structhid_device *hid;

unsigned intn, has_in = 0;

size_tlen;

intret;

dbg_hid("HID probe called for ifnum %d/n",

intf->altsetting->desc.bInterfaceNumber);

//ignore the device should not be handled by usbhid module

if(is_ignored_device(dev->descriptor.idVendor, dev->descriptor.idProduct))

{

printk("*** Device ignored ***/n");

printk("VendorID = %04X, ProductID = %04X/n", dev->descriptor.idVendor, dev->descriptor.idProduct);

printk("%s/n", dev->manufacturer);

printk("%s/n", dev->product);

//printk("%s/n", );

printk("**********************/n");

return-ENODEV;

}

for(n = 0; n desc.bNumEndpoints; n++)

if(usb_endpoint_is_int_in(&interface->endpoint[n].desc))

has_in++;

if(!has_in) {

dev_err(&intf->dev, "couldn't find an input interrupt "

"endpoint/n");

return-ENODEV;

}

hid = hid_allocate_device();

if(IS_ERR(hid))

returnPTR_ERR(hid);

usb_set_intfdata(intf, hid);

hid->ll_driver = &usb_hid_driver;

hid->hid_output_raw_report = usbhid_output_raw_report;

hid->ff_init = hid_pidff_init;

#ifdef CONFIG_USB_HIDDEV

hid->hiddev_connect = hiddev_connect;

hid->hiddev_disconnect = hiddev_disconnect;

hid->hiddev_hid_event = hiddev_hid_event;

hid->hiddev_report_event = hiddev_report_event;

#endif

hid->dev.parent = &intf->dev;

hid->bus = BUS_USB;

hid->vendor = le16_to_cpu(dev->descriptor.idVendor);

hid->product = le16_to_cpu(dev->descriptor.idProduct);

hid->name[0] = 0;

if(intf->cur_altsetting->desc.bInterfaceProtocol ==

USB_INTERFACE_PROTOCOL_MOUSE)

hid->type = HID_TYPE_USBMOUSE;

if(dev->manufacturer)

strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));

if(dev->product) {

if(dev->manufacturer)

strlcat(hid->name, " ",sizeof(hid->name));

strlcat(hid->name, dev->product, sizeof(hid->name));

}

if(!strlen(hid->name))

snprintf(hid->name, sizeof(hid->name),"HID %04x:%04x",

le16_to_cpu(dev->descriptor.idVendor),

le16_to_cpu(dev->descriptor.idProduct));

usb_make_path(dev, hid->phys, sizeof(hid->phys));

strlcat(hid->phys, "/input",sizeof(hid->phys));

len = strlen(hid->phys);

if(len phys) - 1)

snprintf(hid->phys + len, sizeof(hid->phys) - len,

"%d", intf->altsetting[0].desc.bInterfaceNumber);

if(usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)

hid->uniq[0] = 0;

usbhid = kzalloc(sizeof(*usbhid), GFP_KERNEL);

if(usbhid == NULL) {

ret = -ENOMEM;

gotoerr;

}

hid->driver_data = usbhid;

usbhid->hid = hid;

ret = hid_add_device(hid);

if(ret) {

if(ret != -ENODEV)

dev_err(&intf->dev, "can't add hid device: %d/n", ret);

gotoerr_free;

}

return0;

err_free:

kfree(usbhid);

err:

hid_destroy_device(hid);

returnret;

}

ignored_list和is_ignored_device是我自己添加的。

重新编译usbhid模块和joystick模块,安装,插入手柄,输出如下:

usb 1-1: new low speed USB device using s3c2410-ohci and address 11

usb 1-1: New USB device found, idVendor=0e8f, idProduct=0002

usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0

usb 1-1: Product: BETOP USB GAMEPAD

usb 1-1: Manufacturer: GreenAsia Inc.

usb 1-1: configuration #1 chosen from 1 choice

*** Device ignored ***

VendorID = 0E8F, ProductID = 0002

GreenAsia Inc.

BETOP USB GAMEPAD

**********************

*************** Probe for joystick. ****************

bNumEndpoints: 1

direction: (81)Endpoint type: intterupt

MaxPacketSize: 8

嘿嘿,自己驱动的probe函数被调用了,接着就可以和设备通信了,至于怎么通信,还是看usb-skeleton.c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值