- 论坛徽章:
- 0
|
我现在不确定是不是usb驱动引起的,具体症状就是突然系统死机,没有任何打印,但usb device通过LED灯显示出(单片机程序)运作正常。
以前驱动出现过这种情况,就是设备断线的时候,urb没有被取消,然后urb的callback调用有野指针,改过之后就好用了。
现在我通过主机发给usb device一些配置寄存器的命令,跑着跑着就死机不动了,可能搞kgdb来调试会有效,但是需要两台机器,一台烂机器跑虚拟机还跑不动。
可不可能是因为usb device硬件上的一些改变导致的死机?- struct usb_skel {
- char * devname;
- struct usb_device * udev; /* the usb device for this device */
- struct usb_interface * interface; /* the interface for this device */
- struct semaphore limit_sem; /* limiting the number of writes in progress */
- struct urb * rcv_urb_pool[DEFAULT_URBPOOL_SIZE]; /* urb pool */
- struct data_list rcv_data_list; /*recv data's buffer list*/
- __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
- __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
- int open_count; /* count the number of openers */
- int present; /* this is 1 as long as the device is connected */
- struct kref kref;
- struct mutex io_mutex; /* synchronize I/O with disconnect */
- wait_queue_head_t outq; /* read wait queue */
- unsigned int discard_count; /* count the number of packets dicarded */
- unsigned int fail_count; /* count the number of packets sent unsuccess */
- unsigned int sent_count; /* count the number of packets sent */
- unsigned int bufferqueue_maxlength;
- unsigned int recv_count; /* count the number of packets recieved*/
- };
复制代码 probe函数里将urb pool初始化,open函数里填充提交urb,并在urb回调函数中循环提交。- static void skel_read_bulk_callback(struct urb *urb,struct pt_regs * r)
- {
- struct usb_skel *dev;
- struct data_list_node *node;
- int retval;
-
- dev = (struct usb_skel *)urb->context;
- /* sync/async unlink faults aren't errors */
- if (urb->status)
- {
- dbg("%s - nonzero write bulk status received: %d",__FUNCTION__, urb->status);
- if(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN)
- {
- goto error;
- }
- else
- {
- goto out;
- }
- }
- /* if the read was successful, push the data to readqueue */
-
- if( urb->actual_length > 0)
- {
- spin_lock(&dev->rcv_data_list.listlock);
-
- if(dev->rcv_data_list.enqueue <= 0)
- {
- struct list_head * ptr;
- struct data_list_node * entry;
-
- ptr = dev->rcv_data_list.list.next;
- entry = list_entry(ptr,struct data_list_node,list);
- list_del(ptr);
- kmem_cache_free(buffer_cache,entry->bulk_in_buffer);
- kmem_cache_free(listnode_cache,entry);
- ++ dev->rcv_data_list.enqueue;
- -- dev->rcv_data_list.dequeue;
- ++ dev->discard_count;
- }
-
- node = kmem_cache_alloc(listnode_cache, GFP_ATOMIC);
- if(node == NULL)
- {
- err("Out of memory");
- spin_unlock(&dev->rcv_data_list.listlock);
- kmem_cache_free(buffer_cache,urb->transfer_buffer);
- goto error;
- }
- node->list.prev = NULL;
- node->list.next = NULL;
- node->bulk_in_buffer = urb->transfer_buffer;
- node->bulk_in_size = urb->actual_length;
-
- list_add_tail(&node->list,&dev->rcv_data_list.list);
- if(dev->rcv_data_list.dequeue <= 0)
- {
- wake_up_interruptible(&dev->outq); /*wake up read and poll*/
- }
- -- dev->rcv_data_list.enqueue;
- ++ dev->rcv_data_list.dequeue;
- ++ dev->recv_count;
- spin_unlock(&dev->rcv_data_list.listlock);
- urb->transfer_buffer = NULL;
-
- urb->transfer_buffer = kmem_cache_alloc(buffer_cache, GFP_ATOMIC);
-
- if(!urb->transfer_buffer)
- goto error;
- }
- out:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval) {
- err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
- kmem_cache_free(buffer_cache,urb->transfer_buffer);
- }
- error:
- return;
- }
复制代码 release函数或是其它判别出设备unpresent的地方,将urb kill掉。
disconnect函数中free urb
代码由usb-skeleton改来
我以为在disconnect调用之前release必被先调用 |
|