按下键盘上的每个键后,usb设备断开连接

时间:2017-11-04 07:50:35

标签: usb linux-device-driver embedded-linux keyboard-events

我是USB的初学者。我想学习usb驱动程序。我正在使用现有的usbkbd代码在键盘上测试代码。目前,我的目的只是在每个按键时调用完整的回调。我从system和depmod ed中删除了usbkbd,hid-generic。

在每个按键上,我可以在dmesg中看到设备断开连接,探测器被调用但没有回调。

INPUT:dmesg:

[ 5846.796941] usb 2-2: new low-speed USB device number 47 using xhci_hcd
[ 5846.935078] usb 2-2: New USB device found, idVendor=1a2c, idProduct=0002
[ 5846.935082] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 5846.935084] usb 2-2: Product: USB Keykoard
[ 5846.935086] usb 2-2: Manufacturer: USB
[ 5846.935290] usb 2-2: ep 0x81 - rounding interval to 64 microframes, ep desc says 80 microframes
[ 5846.935297] usb 2-2: ep 0x82 - rounding interval to 64 microframes, ep desc says 80 microframes
[ 5846.935718] usb_test: usb_kbd_probe : probe is called for kbd
[ 5846.935722] usb_test: usb_kbd_probe : bNumEndpoints = 1,bInterfaceNumber = 0
[ 5846.935725] usb_test: usb_kbd_probe : error = 0
[ 5846.935727] usb_test: usb_kbd_probe : usb_fill_int_urb, bInterval = 10
[ 5846.935803] usb_test: usb_kbd_probe : probe is called for kbd
[ 5846.935805] usb_test: usb_kbd_probe : bNumEndpoints = 1,bInterfaceNumber = 1
[ 5846.935807] usb_test: usb_kbd_probe : error = 0
[ 5846.935809] usb_test: usb_kbd_probe : usb_fill_int_urb, bInterval = 10
[ 5847.466506] usbcore: registered new interface driver usbhid
[ 5847.466510] usbhid: USB HID core driver

[ 6108.600030] usb 2-2: USB disconnect, device number 47

[ 6109.384486] usb 2-2: new low-speed USB device number 48 using xhci_hcd
[ 6109.578129] usb 2-2: New USB device found, idVendor=1a2c, idProduct=0002
[ 6109.578133] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 6109.578135] usb 2-2: Product: USB Keykoard
[ 6109.578137] usb 2-2: Manufacturer: USB
[ 6109.578284] usb 2-2: ep 0x81 - rounding interval to 64 microframes, ep desc says 80 microframes
[ 6109.578291] usb 2-2: ep 0x82 - rounding interval to 64 microframes, ep desc says 80 microframes
[ 6109.579300] usb_test: usb_kbd_probe : probe is called for kbd
[ 6109.579313] usb_test: usb_kbd_probe : bNumEndpoints = 1,bInterfaceNumber = 0
[ 6109.579321] usb_test: usb_kbd_probe : error = 0
[ 6109.579322] usb_test: usb_kbd_probe : usb_fill_int_urb, bInterval = 10
[ 6109.579453] usb_test: usb_kbd_probe : probe is called for kbd
[ 6109.579456] usb_test: usb_kbd_probe : bNumEndpoints = 1,bInterfaceNumber = 1
[ 6109.579460] usb_test: usb_kbd_probe : error = 0
[ 6109.579461] usb_test: usb_kbd_probe : usb_fill_int_urb, bInterval = 10

代码是:

#define DEBUG
#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>


MODULE_AUTHOR("XYZ");
MODULE_DESCRIPTION("");
MODULE_LICENSE("GPL");

struct usb_kbd {
     struct usb_device *usbdev;
     unsigned char old[8];
     struct urb *irq;
     unsigned char newleds;

     unsigned char *new;
     dma_addr_t new_dma;

     bool led_urb_submitted;
 };

 static void usb_kbd_irq(struct urb *urb)
 {
     struct usb_kbd *kbd = urb->context;
     int i;
     pr_debug("usb_kbd_irq : compete is called\n");
     switch (urb->status) {
         case 0:            /* success */
              break;
         case -ECONNRESET:  /* unlink */
         case -ENOENT:
         case -ESHUTDOWN:
         return;

         default:       /* error */
              goto resubmit;
    }

 resubmit:
    if (usb_submit_urb (urb, GFP_ATOMIC))
         hid_err(urb->dev, "can't resubmit intr, %s-%s/input0, status %d",
         kbd->usbdev->bus->bus_name,
         kbd->usbdev->devpath, i);
 }

static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
{
     if (!(kbd->irq = usb_alloc_urb(0, GFP_KERNEL)))
         return -1;
     if (!(kbd->new = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
         return -2;

    return 0;
}

static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
{
     usb_free_urb(kbd->irq);
     usb_free_coherent(dev, 8, kbd->new, kbd->new_dma);
}

static int usb_kbd_probe(struct usb_interface *iface,
             const struct usb_device_id *id)
{
    struct usb_device *dev = interface_to_usbdev(iface);
    struct usb_host_interface *interface;
    struct usb_endpoint_descriptor *endpoint;
    struct usb_kbd *kbd;
    int i, pipe, maxp;
    int error = -ENOMEM;

    pr_debug("usb_kbd_probe : probe is called for kbd\n");
    interface = iface->cur_altsetting;

    pr_debug("usb_kbd_probe : bNumEndpoints = %d,bInterfaceNumber = %d\n", 
    interface->desc.bNumEndpoints, 
    interface->desc.bInterfaceNumber);
    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));

    kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);

    error = usb_kbd_alloc_mem(dev, kbd);
    pr_debug("usb_kbd_probe : error = %d\n", error);
    if (error < 0) {
         pr_debug("usb_kbd_probe : falied to usb_kbd_alloc_mem\n");
         goto fail2;
    }

    kbd->usbdev = dev;

    pr_debug("usb_kbd_probe : usb_fill_int_urb, bInterval = %d\n",
        endpoint->bInterval);

    usb_fill_int_urb(kbd->irq, dev, pipe,
             kbd->new, (maxp > 8 ? 8 : maxp),
             usb_kbd_irq, kbd, endpoint->bInterval);

   //   kbd->irq->transfer_dma = kbd->new_dma;
   //   kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

    usb_set_intfdata(iface, kbd);
    return 0;
fail2:  
    usb_kbd_free_mem(dev, kbd);
    kfree(kbd);
    return error;
}

static void usb_kbd_disconnect(struct usb_interface *intf)
{
    struct usb_kbd *kbd = usb_get_intfdata (intf);

    usb_set_intfdata(intf, NULL);
    if (kbd) {
        usb_kill_urb(kbd->irq);
        usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
        kfree(kbd);
     }
}

static struct usb_device_id usb_kbd_id_table [] = {
    { USB_DEVICE(0x1a2c, 0x0002) },
    { USB_DEVICE(0x0000, 0x0538) },
    { }                     /* Terminating entry */
 };

 MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);

static struct usb_driver usb_kbd_driver = {
    .name =     "usbkbd_new",
    .probe =    usb_kbd_probe,
    .disconnect =   usb_kbd_disconnect,
    .id_table = usb_kbd_id_table,
};

module_usb_driver(usb_kbd_driver);

任何帮助都将不胜感激。

代码是否正确?

它应该如何工作?

每次按键时断开连接的原因...... ???

谢谢, Pritam

1 个答案:

答案 0 :(得分:0)

填写后需要提交urb。 因此,超时正在发生,设备正在与核心断开连接......

如果我被误解,请纠正我。