+ usbcan_usb_message_move_list(dev, m, &dev->tx_idle_list);
+
+}
+
+void usbcan_kthread_read_handler(struct ctu_usbcan_usb *dev, struct usbcan_message *m)
+{
+
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u8 *ptr;
+ int i, len, retval;
+ u16 flags = 0;
+ struct net_device_stats *stats = &m->dev->netdev->stats;
+
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
+ skb = alloc_can_skb(m->dev->netdev, &cf);
+#else
+ skb = netdev_alloc_skb(m->dev->netdev, sizeof(struct can_frame));
+ skb->protocol = htons(ETH_P_CAN);
+ cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+#endif
+
+ if (skb == NULL){
+ err("RX: error alloc skb\n");
+ return;
+ }
+
+
+ printk("RX: URB successfully received\n");
+
+ len=*(u8 *)(m->msg+1);
+ if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
+
+ flags = le16_to_cpu(*(u16 *)(m->msg+2));
+ cf->can_id = le32_to_cpu((*(u32 *)(m->msg+4)));
+
+ if (flags & MSG_RTR)
+ cf->can_id |= CAN_RTR_FLAG;
+
+ if (flags & MSG_EXT)
+ cf->can_id |= CAN_EFF_FLAG;
+
+ cf->can_dlc = len;
+
+ for(ptr=m->msg+8,i=0; i < len; ptr++,i++) {
+ cf->data[i]=*ptr;
+ }
+
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ /* Renewing RX urb */
+
+ usbcan_usb_message_move_list(dev, m, &dev->rx_pend_list);
+ retval = usb_submit_urb (m->u, GFP_KERNEL);
+ if (retval<0) {
+ err("URB error %d\n", retval);
+ }
+
+
+}
+
+
+static int usbcan_sleep_thread(struct ctu_usbcan_usb *dev)
+{
+ int rc = 0;
+
+ /* Wait until a signal arrives or we are woken up */
+ for (;;) {
+ try_to_freeze();
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ if (
+ kthread_should_stop() ||
+ test_bit(USBCAN_DATA_OK,&dev->flags)
+ )
+ break;
+ schedule();
+ }
+ __set_current_state(TASK_RUNNING);
+ return rc;
+}
+
+int usbcan_kthread(void *data)
+{
+
+ struct ctu_usbcan_usb *dev=(struct ctu_usbcan_usb *) data;
+
+ int i, retval;