本文基于mstar801平台Linux内核2.6.35.11版本。
最近公司项目比较紧,好久没写东西了;暂补一篇。
USB键盘不能用问题:
一、报错
[ 523.084000] usb 1-1.2: new low speed USB device using ***-ehci-2 and address 6
[ 523.092000] First get dev desc failed
[ 523.824000] usb 1-1.2: device not accepting address 6, error -32
[ 523.852000] ====> hub_port_init 2
[ 523.924000] usb 1-1.2: new low speed USB device using ***-ehci-2 and address 7
[ 523.932000] First get dev desc failed
[ 524.664000] usb 1-1.2: device not accepting address 7, error -32
[ 524.692000] ====> hub_port_init 2
[ 524.764000] usb 1-1.2: new low speed USB device using ***-ehci-2 and address 8
[ 524.772000] First get dev desc failed
[ 525.172000] set_addr and port_reset failed!
[ 525.200000] ====> hub_port_init 2
二、分析
1、2.6.35.11/include/asm-generic/errno-base.h
#define EPIPE 32 /* Broken pipe */
2、2.6.35.11/drivers/usb/core/hub.c
static int hub_port_init_ehc (struct usb_hub *hub, struct usb_device *udev, int port1, int retry_counter);
3、2.6.35.11/drivers/usb/core/message.c
int usb_get_device_descriptor(struct usb_device *dev, unsigned int size);
int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size);
三、USB设备发现机制问题
1、2.6.35.11/drivers/usb/core/usb.c
static int __init usb_init(void);
2、2.6.35.11/drivers/usb/core/hub.c
int usb_hub_init(void);
static int hub_thread(void *__unused);
static void hub_events(void);
static void hub_port_connect_change(struct usb_hub *hub, int port1, u16 portstatus, u16 portchange);
////begin
udev = usb_alloc_dev(hdev, hdev->bus, port1);//2.6.35.11/drivers/usb/core/usb.c
//
usb_put_hcd(bus_to_hcd(bus));//2.6.35.11/drivers/usb/core/hcd.c
//
static int hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, int retry_counter);
////end
static int hub_port_init_ehc(struct usb_hub *hub, struct usb_device *udev, int port1, int retry_counter);
////begin
static int hub_set_address(struct usb_device *udev, int devnum); //问题出在这里!!!
static int hub_port_reset(struct usb_hub *hub, int port1, struct usb_device *udev, unsigned int delay);
////end
3、2.6.35.11/drivers/usb/core/message.c
int usb_get_device_descriptor(struct usb_device *dev, unsigned int size);
int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size);
int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout);
static int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, struct usb_ctrlrequest *cmd, void *data, int len, int timeout);
static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length);
4、2.6.35.11/drivers/usb/core/urb.c
int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
5、2.6.35.11/drivers/usb/core/hcd.c
int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags);
static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb);
static int rh_call_control (struct usb_hcd *hcd, struct urb *urb);
四、usb键鼠在驱动中位置
1、2.6.35.11/drivers/hid/usbhid/hid-core.c
static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id);
static int usbhid_parse(struct hid_device *hid);
static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
2、2.6.35.11/drivers/hid/hid-core.c
int hid_connect(struct hid_device *hdev, unsigned int connect_mask);
3、2.6.35.11/drivers/hid/hid-input.c
int hidinput_connect(struct hid_device *hid, unsigned int force);
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, struct hid_usage *usage);
五、问题
费劲周折,发现是USB键盘本身坏了。郁闷。。。
因为设备本身有问题;导致2.6.36.11/drivers/usb/core/hub.c中hub_set_address()函数无法将地址设置到键盘中。如此超时反复。