/* * Copyright (c) 2014 Novatek * * NVT USB Host Test */ #include #include #include #include #include #include #include #include #include #include //#include <../host/xhci.h> //#include /* * Version Information */ #define DRIVER_VERSION "v1.0" #define DRIVER_AUTHOR "Klins Chen " #define DRIVER_DESC "Novatek USB test program" #define DRIVER_LICENSE "GPL" MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE(DRIVER_LICENSE); struct usb_nvttst { char name[128]; struct usb_interface *inf; struct usb_device *usbdev; struct task_struct *ctl_thread; struct urb *urb1,*urb2,*urb3; struct completion done1,done2; struct completion close; //Cx Resource struct task_struct *cx_thread; struct urb *cx_urb_in,*cx_urb_out; struct completion cx_done_in,cx_done_out; struct completion cx_close; //BULK Resource struct task_struct *bulk_thread; struct urb *bulk_urb_in,*bulk_urb_out; struct completion bulk_done_in,bulk_done_out; struct completion bulk_close; //Interrupt Resource struct task_struct *intr_thread; struct urb *intr_urb_in,*intr_urb_out; struct completion intr_done_in,intr_done_out; struct completion intr_close; //ISO Resource struct task_struct *isoin_thread; struct task_struct *isoout_thread; struct urb *iso_urb_in,*iso_urb_in2,*iso_urb_out; struct completion iso_done_in,iso_done_in2,iso_done_out; struct completion isoin_close,isoout_close; // ISO UVC struct task_struct *isouvc1_thread; struct urb *iso_urb_uvc11,*iso_urb_uvc12; struct completion iso_done_uvc11,iso_done_uvc12; struct completion isoin_close_uvc1; struct task_struct *isouvc2_thread; struct urb *iso_urb_uvc21,*iso_urb_uvc22; struct completion iso_done_uvc21,iso_done_uvc22; struct completion isoin_close_uvc2; int status; int msgoff; }; #ifdef CONFIG_PM extern int usb_suspend(struct device *dev, pm_message_t msg); extern int usb_resume(struct device *dev, pm_message_t msg); extern int usb_suspend_both(struct usb_device *udev, pm_message_t msg); #endif #if 0 void usb_nvttst_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); if((urb == nvttst->urb1)||(urb == nvttst->urb3)) complete(&nvttst->done1); else if (urb == nvttst->urb2) complete(&nvttst->done2); } #endif #if 1 static void usb_nvttst_cxin_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->cx_done_in); } static void usb_nvttst_cxout_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->cx_done_out); } static void usb_nvttst_bulkin_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->bulk_done_in); } static void usb_nvttst_bulkout_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->bulk_done_out); } static void usb_nvttst_intrin_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->intr_done_in); } static void usb_nvttst_introut_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->intr_done_out); } static void usb_nvttst_isoin_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->iso_done_in); } #if 0 static void usb_nvttst_isoin_blocking_completion2(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->iso_done_in2); } static void usb_nvttst_isouvc11_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->iso_done_uvc11); } static void usb_nvttst_isouvc12_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->iso_done_uvc12); } static void usb_nvttst_isouvc21_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->iso_done_uvc21); } static void usb_nvttst_isouvc22_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->iso_done_uvc22); } #endif static void usb_nvttst_isoout_blocking_completion(struct urb *urb) { struct usb_nvttst *nvttst = urb->context; nvttst->status = urb->status; if(nvttst->status) printk("[%s]: err sts = %d\n",__func__,nvttst->status); complete(&nvttst->iso_done_out); } #endif #if 1 #if 0 static int usb_nvttst_issue_urb_blocking(struct urb *urb, struct usb_nvttst *nvttst) { int ret; if((urb == nvttst->urb1)||(urb == nvttst->urb3)) init_completion(&nvttst->done1); else if(urb == nvttst->urb2) init_completion(&nvttst->done2); urb->actual_length = 0; ret = usb_submit_urb(urb, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } if((urb == nvttst->urb1)||(urb == nvttst->urb3)) { if (!wait_for_completion_timeout(&nvttst->done1, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } } else if(urb == nvttst->urb2) { if (!wait_for_completion_timeout(&nvttst->done2, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } } return 0; } static int usb_nvttst_issue_urb_nonblocking(struct urb *urb, struct usb_nvttst *nvttst) { int ret; if(urb == nvttst->urb1) init_completion(&nvttst->done1); else if(urb == nvttst->urb2) init_completion(&nvttst->done2); urb->actual_length = 0; ret = usb_submit_urb(urb, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } return 0; } static int usb_nvttst_nonblocking_waitdone(struct urb *urb, struct usb_nvttst *nvttst) { if(urb == nvttst->urb1) { if (!wait_for_completion_timeout(&nvttst->done1, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } } else if(urb == nvttst->urb2) { if (!wait_for_completion_timeout(&nvttst->done2, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } } return 0; } #endif static void usb_nvttst_setup_CxIN(struct usb_nvttst *nvttst, struct usb_ctrlrequest *req, void *buf, size_t length) { req->bRequestType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE; req->bRequest = 0x00; req->wValue = 0x0000; req->wIndex = 0x0000; req->wLength = length; usb_fill_control_urb(nvttst->cx_urb_in, nvttst->usbdev, usb_rcvctrlpipe(nvttst->usbdev, 0), (unsigned char *) req, (void *)buf, length, usb_nvttst_cxin_blocking_completion, nvttst); } static void usb_nvttst_setup_CxOUT(struct usb_nvttst *nvttst, struct usb_ctrlrequest *req, void *buf, size_t length) { req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; req->bRequest = 0x00; req->wValue = 0x0000; req->wIndex = 0x0000; req->wLength = length; usb_fill_control_urb(nvttst->cx_urb_out, nvttst->usbdev, usb_sndctrlpipe(nvttst->usbdev, 0), (unsigned char *) req, (void *)buf, length, usb_nvttst_cxout_blocking_completion, nvttst); } static void usb_nvttst_setup_BulkIN(struct usb_nvttst *nvttst, void *buf, size_t length,int epn) { usb_fill_bulk_urb(nvttst->bulk_urb_in, nvttst->usbdev, usb_rcvbulkpipe(nvttst->usbdev, epn), (void *)buf, length, usb_nvttst_bulkin_blocking_completion, nvttst); } static void usb_nvttst_setup_BulkOUT(struct usb_nvttst *nvttst, void *buf, size_t length,int epn) { usb_fill_bulk_urb(nvttst->bulk_urb_out, nvttst->usbdev, usb_sndbulkpipe(nvttst->usbdev, epn), (void *)buf, length, usb_nvttst_bulkout_blocking_completion, nvttst); } static void usb_nvttst_setup_IntrIN(struct usb_nvttst *nvttst, void *buf, size_t length) { usb_fill_int_urb(nvttst->intr_urb_in, nvttst->usbdev, usb_rcvintpipe(nvttst->usbdev, 3), (void *)buf, length, usb_nvttst_intrin_blocking_completion, nvttst, 1); } static void usb_nvttst_setup_IntrOUT(struct usb_nvttst *nvttst, void *buf, size_t length) { usb_fill_int_urb(nvttst->intr_urb_out, nvttst->usbdev, usb_sndintpipe(nvttst->usbdev, 4), (void *)buf, length, usb_nvttst_introut_blocking_completion, nvttst, 1); } static void usb_nvttst_setup_IsoIN(struct usb_nvttst *nvttst, void *buf, size_t length, size_t pktno, size_t ofs, int epn) { int i; nvttst->iso_urb_in->dev = nvttst->usbdev; nvttst->iso_urb_in->pipe= usb_rcvisocpipe(nvttst->usbdev, epn); nvttst->iso_urb_in->context = nvttst; nvttst->iso_urb_in->interval= 1; nvttst->iso_urb_in->transfer_flags = URB_ISO_ASAP; nvttst->iso_urb_in->transfer_buffer= buf; nvttst->iso_urb_in->complete = usb_nvttst_isoin_blocking_completion; nvttst->iso_urb_in->number_of_packets = pktno; nvttst->iso_urb_in->transfer_buffer_length= pktno*length; nvttst->iso_urb_in->actual_length= 0; for(i=0;iiso_urb_in->iso_frame_desc[i].offset = (length*i)+ofs; nvttst->iso_urb_in->iso_frame_desc[i].length = length; nvttst->iso_urb_in->iso_frame_desc[i].actual_length = 0; } } #if 0 static void usb_nvttst_setup_IsoIN2(struct usb_nvttst *nvttst, void *buf, size_t length, size_t pktno, size_t ofs, int epn) { int i; nvttst->iso_urb_in2->dev = nvttst->usbdev; nvttst->iso_urb_in2->pipe= usb_rcvisocpipe(nvttst->usbdev, epn); nvttst->iso_urb_in2->context = nvttst; nvttst->iso_urb_in2->interval= 1; nvttst->iso_urb_in2->transfer_flags = URB_ISO_ASAP; nvttst->iso_urb_in2->transfer_buffer= buf; nvttst->iso_urb_in2->complete = usb_nvttst_isoin_blocking_completion2; nvttst->iso_urb_in2->number_of_packets = pktno; nvttst->iso_urb_in2->transfer_buffer_length= pktno*length; nvttst->iso_urb_in2->actual_length= 0; for(i=0;iiso_urb_in2->iso_frame_desc[i].offset = (length*i)+ofs; nvttst->iso_urb_in2->iso_frame_desc[i].length = length; nvttst->iso_urb_in2->iso_frame_desc[i].actual_length = 0; } } static void usb_nvttst_setup_uvc11(struct usb_nvttst *nvttst, void *buf, size_t length, size_t pktno, size_t ofs, int epn) { int i; nvttst->iso_urb_uvc11->dev = nvttst->usbdev; nvttst->iso_urb_uvc11->pipe= usb_rcvisocpipe(nvttst->usbdev, epn); nvttst->iso_urb_uvc11->context = nvttst; nvttst->iso_urb_uvc11->interval= 1; nvttst->iso_urb_uvc11->transfer_flags = URB_ISO_ASAP; nvttst->iso_urb_uvc11->transfer_buffer= buf; nvttst->iso_urb_uvc11->complete = usb_nvttst_isouvc11_blocking_completion; nvttst->iso_urb_uvc11->number_of_packets = pktno; nvttst->iso_urb_uvc11->transfer_buffer_length= pktno*length; nvttst->iso_urb_uvc11->actual_length= 0; for(i=0;iiso_urb_uvc11->iso_frame_desc[i].offset = (length*i)+ofs; nvttst->iso_urb_uvc11->iso_frame_desc[i].length = length; nvttst->iso_urb_uvc11->iso_frame_desc[i].actual_length = 0; } } static void usb_nvttst_setup_uvc12(struct usb_nvttst *nvttst, void *buf, size_t length, size_t pktno, size_t ofs, int epn) { int i; nvttst->iso_urb_uvc12->dev = nvttst->usbdev; nvttst->iso_urb_uvc12->pipe= usb_rcvisocpipe(nvttst->usbdev, epn); nvttst->iso_urb_uvc12->context = nvttst; nvttst->iso_urb_uvc12->interval= 1; nvttst->iso_urb_uvc12->transfer_flags = URB_ISO_ASAP; nvttst->iso_urb_uvc12->transfer_buffer= buf; nvttst->iso_urb_uvc12->complete = usb_nvttst_isouvc12_blocking_completion; nvttst->iso_urb_uvc12->number_of_packets = pktno; nvttst->iso_urb_uvc12->transfer_buffer_length= pktno*length; nvttst->iso_urb_uvc12->actual_length= 0; for(i=0;iiso_urb_uvc12->iso_frame_desc[i].offset = (length*i)+ofs; nvttst->iso_urb_uvc12->iso_frame_desc[i].length = length; nvttst->iso_urb_uvc12->iso_frame_desc[i].actual_length = 0; } } static void usb_nvttst_setup_uvc21(struct usb_nvttst *nvttst, void *buf, size_t length, size_t pktno, size_t ofs, int epn) { int i; nvttst->iso_urb_uvc21->dev = nvttst->usbdev; nvttst->iso_urb_uvc21->pipe= usb_rcvisocpipe(nvttst->usbdev, epn); nvttst->iso_urb_uvc21->context = nvttst; nvttst->iso_urb_uvc21->interval= 1; nvttst->iso_urb_uvc21->transfer_flags = URB_ISO_ASAP; nvttst->iso_urb_uvc21->transfer_buffer= buf; nvttst->iso_urb_uvc21->complete = usb_nvttst_isouvc21_blocking_completion; nvttst->iso_urb_uvc21->number_of_packets = pktno; nvttst->iso_urb_uvc21->transfer_buffer_length= pktno*length; nvttst->iso_urb_uvc21->actual_length= 0; for(i=0;iiso_urb_uvc21->iso_frame_desc[i].offset = (length*i)+ofs; nvttst->iso_urb_uvc21->iso_frame_desc[i].length = length; nvttst->iso_urb_uvc21->iso_frame_desc[i].actual_length = 0; } } static void usb_nvttst_setup_uvc22(struct usb_nvttst *nvttst, void *buf, size_t length, size_t pktno, size_t ofs, int epn) { int i; nvttst->iso_urb_uvc22->dev = nvttst->usbdev; nvttst->iso_urb_uvc22->pipe= usb_rcvisocpipe(nvttst->usbdev, epn); nvttst->iso_urb_uvc22->context = nvttst; nvttst->iso_urb_uvc22->interval= 1; nvttst->iso_urb_uvc22->transfer_flags = URB_ISO_ASAP; nvttst->iso_urb_uvc22->transfer_buffer= buf; nvttst->iso_urb_uvc22->complete = usb_nvttst_isouvc22_blocking_completion; nvttst->iso_urb_uvc22->number_of_packets = pktno; nvttst->iso_urb_uvc22->transfer_buffer_length= pktno*length; nvttst->iso_urb_uvc22->actual_length= 0; for(i=0;iiso_urb_uvc22->iso_frame_desc[i].offset = (length*i)+ofs; nvttst->iso_urb_uvc22->iso_frame_desc[i].length = length; nvttst->iso_urb_uvc22->iso_frame_desc[i].actual_length = 0; } } #endif static void usb_nvttst_setup_IsoOUT(struct usb_nvttst *nvttst, void *buf, size_t length, size_t pktno, size_t ofs, int epn) { int i; nvttst->iso_urb_out->dev = nvttst->usbdev; nvttst->iso_urb_out->pipe= usb_sndisocpipe(nvttst->usbdev, epn); nvttst->iso_urb_out->context = nvttst; nvttst->iso_urb_out->interval= 1; nvttst->iso_urb_out->transfer_flags = URB_ISO_ASAP; nvttst->iso_urb_out->transfer_buffer= buf; nvttst->iso_urb_out->complete = usb_nvttst_isoout_blocking_completion; nvttst->iso_urb_out->number_of_packets = pktno; nvttst->iso_urb_out->transfer_buffer_length= length*pktno; for(i=0;iiso_urb_out->iso_frame_desc[i].offset = (length*i)+ofs; nvttst->iso_urb_out->iso_frame_desc[i].length = length; nvttst->iso_urb_out->iso_frame_desc[i].actual_length = 0; } } #endif #if 1 static int usb_nvttst_cxin_issue_urb_blocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->cx_done_in); nvttst->cx_urb_in->actual_length = 0; ret = usb_submit_urb(nvttst->cx_urb_in, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } if (!wait_for_completion_timeout(&nvttst->cx_done_in, msecs_to_jiffies(8000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } static int usb_nvttst_cxout_issue_urb_blocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->cx_done_out); nvttst->cx_urb_out->actual_length = 0; ret = usb_submit_urb(nvttst->cx_urb_out, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } if (!wait_for_completion_timeout(&nvttst->cx_done_out, msecs_to_jiffies(8000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } static int usb_nvttst_bulkin_issue_urb_blocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->bulk_done_in); nvttst->bulk_urb_in->actual_length = 0; ret = usb_submit_urb(nvttst->bulk_urb_in, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } if (!wait_for_completion_timeout(&nvttst->bulk_done_in, msecs_to_jiffies(8000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } static int usb_nvttst_bulkout_issue_urb_blocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->bulk_done_out); nvttst->bulk_urb_out->actual_length = 0; ret = usb_submit_urb(nvttst->bulk_urb_out, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } if (!wait_for_completion_timeout(&nvttst->bulk_done_out, msecs_to_jiffies(8000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } static int usb_nvttst_intrin_issue_urb_blocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->intr_done_in); nvttst->intr_urb_in->actual_length = 0; ret = usb_submit_urb(nvttst->intr_urb_in, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } if (!wait_for_completion_timeout(&nvttst->intr_done_in, msecs_to_jiffies(8000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } static int usb_nvttst_introut_issue_urb_blocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->intr_done_out); nvttst->intr_urb_out->actual_length = 0; ret = usb_submit_urb(nvttst->intr_urb_out, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } if (!wait_for_completion_timeout(&nvttst->intr_done_out, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } /* static int usb_nvttst_isoin_issue_urb_blocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->iso_done_in); nvttst->iso_urb_in->actual_length = 0; ret = usb_submit_urb(nvttst->iso_urb_in, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } if (!wait_for_completion_timeout(&nvttst->iso_done_in, msecs_to_jiffies(2000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } */ static int usb_nvttst_isoin_issue_urb_nonblocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->iso_done_in); nvttst->iso_urb_in->actual_length = 0; ret = usb_submit_urb(nvttst->iso_urb_in, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } //if (!wait_for_completion_timeout(&nvttst->iso_done_in, msecs_to_jiffies(2000))) { // printk("[%s]: timeout",__func__); // return -ETIMEDOUT; //} return 0; } static int usb_nvttst_isoin_issue_urb_waitdone(struct usb_nvttst *nvttst) { if (!wait_for_completion_timeout(&nvttst->iso_done_in, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } #if 0 static int usb_nvttst_isoin2_issue_urb_nonblocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->iso_done_in2); nvttst->iso_urb_in2->actual_length = 0; ret = usb_submit_urb(nvttst->iso_urb_in2, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } //if (!wait_for_completion_timeout(&nvttst->iso_done_in, msecs_to_jiffies(2000))) { // printk("[%s]: timeout",__func__); // return -ETIMEDOUT; //} return 0; } static int usb_nvttst_isoin2_issue_urb_waitdone(struct usb_nvttst *nvttst) { if (!wait_for_completion_timeout(&nvttst->iso_done_in2, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } #endif static int usb_nvttst_isoout_issue_urb_blocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->iso_done_out); nvttst->iso_urb_out->actual_length = 0; ret = usb_submit_urb(nvttst->iso_urb_out, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } if (!wait_for_completion_timeout(&nvttst->iso_done_out, msecs_to_jiffies(2000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } #if 0 static int usb_nvttst_isouvc11_issue_urb_nonblocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->iso_done_uvc11); nvttst->iso_urb_uvc11->actual_length = 0; ret = usb_submit_urb(nvttst->iso_urb_uvc11, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } //if (!wait_for_completion_timeout(&nvttst->iso_done_in, msecs_to_jiffies(2000))) { // printk("[%s]: timeout",__func__); // return -ETIMEDOUT; //} return 0; } static int usb_nvttst_isouvc12_issue_urb_nonblocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->iso_done_uvc12); nvttst->iso_urb_uvc12->actual_length = 0; ret = usb_submit_urb(nvttst->iso_urb_uvc12, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } //if (!wait_for_completion_timeout(&nvttst->iso_done_in, msecs_to_jiffies(2000))) { // printk("[%s]: timeout",__func__); // return -ETIMEDOUT; //} return 0; } static int usb_nvttst_isouvc11_issue_urb_waitdone(struct usb_nvttst *nvttst) { if (!wait_for_completion_timeout(&nvttst->iso_done_uvc11, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } static int usb_nvttst_isouvc12_issue_urb_waitdone(struct usb_nvttst *nvttst) { if (!wait_for_completion_timeout(&nvttst->iso_done_uvc12, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } static int usb_nvttst_isouvc21_issue_urb_nonblocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->iso_done_uvc21); nvttst->iso_urb_uvc21->actual_length = 0; ret = usb_submit_urb(nvttst->iso_urb_uvc21, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } //if (!wait_for_completion_timeout(&nvttst->iso_done_in, msecs_to_jiffies(2000))) { // printk("[%s]: timeout",__func__); // return -ETIMEDOUT; //} return 0; } static int usb_nvttst_isouvc22_issue_urb_nonblocking(struct usb_nvttst *nvttst) { int ret; init_completion(&nvttst->iso_done_uvc22); nvttst->iso_urb_uvc22->actual_length = 0; ret = usb_submit_urb(nvttst->iso_urb_uvc22, GFP_KERNEL); if( ret ) { printk("[%s]: usb_submit_urb failed %d\n",__func__,ret); return ret; } //if (!wait_for_completion_timeout(&nvttst->iso_done_in, msecs_to_jiffies(2000))) { // printk("[%s]: timeout",__func__); // return -ETIMEDOUT; //} return 0; } static int usb_nvttst_isouvc21_issue_urb_waitdone(struct usb_nvttst *nvttst) { if (!wait_for_completion_timeout(&nvttst->iso_done_uvc21, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } static int usb_nvttst_isouvc22_issue_urb_waitdone(struct usb_nvttst *nvttst) { if (!wait_for_completion_timeout(&nvttst->iso_done_uvc22, msecs_to_jiffies(5000))) { printk("[%s]: timeout",__func__); return -ETIMEDOUT; } return 0; } #endif #endif #if 1 void usb_nvttst_fill_cbw(u8 *cbwbuf, u32 len, bool OUT) { static u32 Tag = 0x88888888; cbwbuf[0] = 0x55; cbwbuf[1] = 0x53; cbwbuf[2] = 0x42; cbwbuf[3] = 0x43; cbwbuf[4] =(Tag>>0)&0xFF;cbwbuf[5]=(Tag>>8)&0xFF;cbwbuf[6]=(Tag>>16)&0xFF;cbwbuf[7]=(Tag>>24)&0xFF; cbwbuf[8] =(len>>0)&0xFF;cbwbuf[9]=(len>>8)&0xFF;cbwbuf[10]=(len>>16)&0xFF;cbwbuf[11]=(len>>24)&0xFF; if(OUT) cbwbuf[12]=0x00;//OUT else cbwbuf[12]=0x80; Tag++; } #endif #if 0 static int usb_nvttst_control_thread(void * __nvttst) { struct usb_nvttst *nvttst = (struct usb_nvttst *)__nvttst; struct usb_ctrlrequest ctrlreq1,ctrlreq2; u8 *txfbuf,inCnter=0; u8 *rxfbuf,outCnter=0; u8 *cbwbuf,*cswbuf; size_t i,len1=1,len2=1,bulksize=0; int ret,Cnt=0; bool bulk=0,intrr=0,isoin=0,isoout=0; struct usb_host_interface *intf = nvttst->inf->cur_altsetting; // Check if bulk/interrupt/isochronous test if(intf->desc.bNumEndpoints == 2) { if(((intf->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) &&((intf->endpoint[0].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x81) &&((intf->endpoint[1].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) &&((intf->endpoint[1].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x02)) { printk("Bulk desc matched. Start bulk testing...\n"); bulk= 1; } else if(((intf->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) &&((intf->endpoint[0].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x81) &&((intf->endpoint[1].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) &&((intf->endpoint[1].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x02)) { printk("Interrupt desc matched. Start Interrupt testing...\n"); intrr= 1; } } else if(intf->desc.bNumEndpoints == 1) { if(((intf->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[0].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x81)) { printk("ISOIN desc matched. Start ISOIN testing...\n"); isoin= 1; } else if(((intf->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[0].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x01)) { printk("ISOOUT desc matched. Start ISOOUT testing...\n"); isoout= 1; } } bulk=1; if((bulk==0)&&(intrr==0)&&(isoin==0)&&(isoout==0)) { printk("Non of matched testing item desc. close thread\n"); goto fail1; } if(isoin) { //FWSTART for ISOIN ctrlreq1.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; ctrlreq1.bRequest = 0x00; ctrlreq1.wValue = 0x0001; ctrlreq1.wIndex = 0x0000; ctrlreq1.wLength = 0; usb_fill_control_urb(nvttst->urb1, nvttst->usbdev, usb_sndctrlpipe(nvttst->usbdev, 0), (unsigned char *) &ctrlreq1, NULL, 0, usb_nvttst_blocking_completion, nvttst); usb_nvttst_issue_urb_blocking(nvttst->urb1, nvttst); msleep(100); } while(1) { if(isoout) { txfbuf = kmalloc(512*8, GFP_KERNEL); if(!txfbuf) { printk("[%s]: rx no mem\n",__func__); goto fail1; } for(i=0;i<512*8;i++) { txfbuf[i] = inCnter++; if(inCnter == 0xFF) inCnter = 0x00; } usb_nvttst_setup_IsoOUT(nvttst->urb3, nvttst, txfbuf, 512); ret = usb_nvttst_issue_urb_blocking(nvttst->urb3, nvttst); kfree(txfbuf); if(ret) goto fail1; printk("isoout %d\n",++Cnt); } if(isoin) { txfbuf = kmalloc(1536*8, GFP_KERNEL); if(!txfbuf) { printk("[%s]: rx no mem\n",__func__); goto fail1; } usb_nvttst_setup_IsoIN(nvttst->urb3, nvttst, txfbuf, 1536); ret = usb_nvttst_issue_urb_blocking(nvttst->urb3, nvttst); for(i=0;i<1536*8;i++) { if(txfbuf[i] != inCnter++) printk("ISOIN Data Err!\r\n"); if(inCnter == 0xFF) inCnter = 0x00; } kfree(txfbuf); if(ret) goto fail1; printk("isoin %d\n",++Cnt); } if(bulk) { get_random_bytes ( &len1, sizeof (len1) ); len1 &= 0x3FFF;//Max 16384 in linux if(len1 == 0) len1++; txfbuf = kmalloc(len1, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail1; } get_random_bytes ( &len2, sizeof (len2) ); len2 &= 0x3FFF; if(len2 == 0) len2++; rxfbuf = kmalloc(len2, GFP_KERNEL); if(!rxfbuf) { printk("[%s]: rx no mem\n",__func__); goto fail2; } for(i=0;iurb1, nvttst, &ctrlreq1, (void *)txfbuf, len1); usb_nvttst_setup_CxOUT(nvttst->urb2, nvttst, &ctrlreq2, (void *)rxfbuf, len2); /* Send Control IN/OUT jobs by non-blocking operation */ ret = usb_nvttst_issue_urb_nonblocking(nvttst->urb1, nvttst); if(ret) goto fail3; ret = usb_nvttst_issue_urb_nonblocking(nvttst->urb2, nvttst); if(ret) goto fail3; ret = usb_nvttst_nonblocking_waitdone(nvttst->urb1, nvttst); if(ret) goto fail3; ret = usb_nvttst_nonblocking_waitdone(nvttst->urb2, nvttst); if(ret) goto fail3; /* Compare CxIN Data */ if((nvttst->urb1->status)==0) { for(i=0;iurb1,nvttst, cbwbuf, 31); ret = usb_nvttst_issue_urb_blocking(nvttst->urb1, nvttst); kfree(cbwbuf); if(ret) goto fail1; txfbuf = kmalloc(len1, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail1; } for(i=0;iurb1,nvttst, txfbuf, len1); ret = usb_nvttst_issue_urb_blocking(nvttst->urb1, nvttst); //kfree(txfbuf); if(ret) goto fail2; cswbuf = kmalloc(13, GFP_KERNEL); if(!cswbuf) { printk("[%s]: csw no mem\n",__func__); goto fail2; } usb_nvttst_setup_BulkIN(nvttst->urb1,nvttst, cswbuf, 13); ret = usb_nvttst_issue_urb_blocking(nvttst->urb1, nvttst); kfree(cswbuf); if(ret) goto fail2; #endif #if 1 /******************************** * BULK IN ********************************/ cbwbuf = kzalloc(31, GFP_KERNEL); if(!cbwbuf) { printk("[%s]: cbw no mem\n",__func__); goto fail2; } usb_nvttst_fill_cbw(cbwbuf, len1, 0); usb_nvttst_setup_BulkOUT(nvttst->urb1,nvttst, cbwbuf, 31); ret = usb_nvttst_issue_urb_blocking(nvttst->urb1, nvttst); kfree(cbwbuf); if(ret) goto fail2; rxfbuf = kmalloc(len1, GFP_KERNEL); if(!rxfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail2; } usb_nvttst_setup_BulkIN(nvttst->urb1,nvttst, rxfbuf, len1); ret = usb_nvttst_issue_urb_blocking(nvttst->urb1, nvttst); //kfree(txfbuf); if(ret) goto fail3; cswbuf = kmalloc(13, GFP_KERNEL); if(!cswbuf) { printk("[%s]: csw no mem\n",__func__); goto fail3; } usb_nvttst_setup_BulkIN(nvttst->urb1,nvttst, cswbuf, 13); ret = usb_nvttst_issue_urb_blocking(nvttst->urb1, nvttst); kfree(cswbuf); if(ret) goto fail3; if(memcmp(txfbuf, rxfbuf, len1)) { printk("BULK DATA COMPARE ERROR!\n"); goto fail3; } kfree(rxfbuf); kfree(txfbuf); #endif //if((++Cnt % 500) == 0) printk("CX/BULK Pass Count = %d (%d)\n",++Cnt,len1); if (kthread_should_stop() || (nvttst->status)) goto fail1; } if(intrr) { #if 1 /******************************** * Interrupt OUT/IN ********************************/ if(len1 > (size_t)(intf->endpoint[0].desc.wMaxPacketSize & 0x7ff)) len1=1; txfbuf = kmalloc(len1, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail1; } for(i=0;iurb1,nvttst, txfbuf, len1); ret = usb_nvttst_issue_urb_blocking(nvttst->urb1, nvttst); if(ret) goto fail2; rxfbuf = kmalloc(len1, GFP_KERNEL); if(!rxfbuf) { printk("[%s]: rx no mem\n",__func__); goto fail1; } usb_nvttst_setup_IntrIN(nvttst->urb1,nvttst, rxfbuf, len1); ret = usb_nvttst_issue_urb_blocking(nvttst->urb1, nvttst); if(ret) goto fail3; if(memcmp(txfbuf, rxfbuf, len1)) { printk("Interrupt DATA COMPARE ERROR!\n"); goto fail3; } kfree(txfbuf); kfree(rxfbuf); #endif printk("Interrupt Pass Count = %d(%d)\n",++Cnt,len1); len1++; } } fail3: kfree(rxfbuf); fail2: kfree(txfbuf); fail1: complete(&nvttst->close); printk("[%s]: thread closed.\n",__func__); return 0; } #endif #if 1 static int usb_nvttst_CxRW_thread(void * __nvttst) { struct usb_nvttst *nvttst = (struct usb_nvttst *)__nvttst; struct usb_ctrlrequest *ctrlreq1,*ctrlreq2; u8 *txfbuf; u8 *rxfbuf; size_t i,len1=0,txofs=0; int ret,Cnt=0; //struct usb_host_interface *intf = nvttst->inf->cur_altsetting; int MaxOfs = 4096,MaxTestSize = 16384;//16384 nvttst->cx_urb_in = NULL; nvttst->cx_urb_out = NULL; txfbuf = NULL; rxfbuf = NULL; #if 0 #ifdef CONFIG_PM printk("TEST Suspend Resume\n"); //{ // u32 *pREG; // pREG = (u32 *)0xF1700058; // *pREG |= 0x100; // msleep(100); //} while(1) { u32 *pREG; u32 temp; pREG = (u32 *)0xF1700420; while(((*pREG >>5) &0xF) != 0x0) ; msleep(5000); printk("Suspend\n"); temp = *pREG; temp &= ~(0xF<<5); *pREG = temp + (0x3<<5); while(((*pREG >>5) &0xF) != 0x3) ; msleep(5000); printk("Resume\n"); temp = *pREG; temp &= ~(0xF<<5); *pREG = temp + (0xF<<5); if (kthread_should_stop()) goto fail1; } #endif #endif nvttst->cx_urb_in = usb_alloc_urb(0, GFP_KERNEL); if (!nvttst->cx_urb_in) goto fail1; nvttst->cx_urb_out = usb_alloc_urb(0, GFP_KERNEL); if (!nvttst->cx_urb_out) goto fail1; txfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail2; } for(i=0;imsgoff) printk("CX= %d (%d)(%d)\n",++Cnt,len1,txofs); if (kthread_should_stop() || (nvttst->status)) goto fail3; } fail3: fail2: kfree(ctrlreq1); kfree(ctrlreq2); if(txfbuf) kfree(txfbuf); if(rxfbuf) kfree(rxfbuf); fail1: if(nvttst->cx_urb_in) usb_free_urb(nvttst->cx_urb_in); if(nvttst->cx_urb_out) usb_free_urb(nvttst->cx_urb_out); while(!kthread_should_stop()) { msleep(50); } complete(&nvttst->cx_close); printk("[%s]: thread closed.\n",__func__); return 0; } static int usb_nvttst_BULKRW_thread(void * __nvttst) { struct usb_nvttst *nvttst = (struct usb_nvttst *)__nvttst; u8 *txfbuf; u8 *rxfbuf; u8 *cbwbuf,*cswbuf; size_t ofs1,bulksize=0; int ret,Cnt=0; struct usb_host_interface *intf = nvttst->inf->cur_altsetting; int MaxOfs = 4096, MaxTestSize = 256*1024;//256 int epi=1,epo=2; nvttst->bulk_urb_in = NULL; nvttst->bulk_urb_out = NULL; txfbuf = NULL; rxfbuf = NULL; cbwbuf = NULL; cswbuf = NULL; // Check if bulk/interrupt/isochronous test if(((intf->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) &&((intf->endpoint[0].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x81) &&((intf->endpoint[1].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) ) { printk("Bulk desc matched. Start bulk EP1/2 testing...\n"); epo = (intf->endpoint[1].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)); } else { printk("Bulk desc NOT matched. Close test!\n"); goto fail1; } nvttst->bulk_urb_in = usb_alloc_urb(0, GFP_KERNEL); if (!nvttst->bulk_urb_in) goto fail1; nvttst->bulk_urb_out = usb_alloc_urb(0, GFP_KERNEL); if (!nvttst->bulk_urb_out) goto fail1; txfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail2; } get_random_bytes ( txfbuf, MaxTestSize+MaxOfs ); //{ // int i; // for(i=0;imsgoff) printk("BULK Pass Count = %d (%d)(%d)\n",++Cnt,bulksize,ofs1); if (kthread_should_stop() || (nvttst->status)) goto fail3; } fail3: fail2: if(txfbuf) kfree(txfbuf); if(rxfbuf) kfree(rxfbuf); if(cbwbuf) kfree(cbwbuf); if(cswbuf) kfree(cswbuf); fail1: if(nvttst->bulk_urb_in) usb_free_urb(nvttst->bulk_urb_in); if(nvttst->bulk_urb_out) usb_free_urb(nvttst->bulk_urb_out); while(!kthread_should_stop()) { msleep(50); } complete(&nvttst->bulk_close); printk("[%s]: thread closed.\n",__func__); return 0; } static int usb_nvttst_INTRRW_thread(void * __nvttst) { struct usb_nvttst *nvttst = (struct usb_nvttst *)__nvttst; u8 *txfbuf; u8 *rxfbuf; size_t ofs2=0,ofs1=0,testsize=1; int ret,Cnt=0; struct usb_host_interface *intf = nvttst->inf->cur_altsetting; int MaxOfs = 4096,MaxTestSize = 0; nvttst->intr_urb_in = NULL; nvttst->intr_urb_out = NULL; txfbuf = NULL; rxfbuf = NULL; // Check if bulk/interrupt/isochronous test if(((intf->endpoint[2].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) &&((intf->endpoint[2].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x83) &&((intf->endpoint[3].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) &&((intf->endpoint[3].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x04)) { printk("INTR desc matched. Start INTR EP3/4 testing...\n"); } else { printk("INTR desc NOT matched. Close test!\n"); goto fail1; } MaxTestSize = (intf->endpoint[2].desc.wMaxPacketSize & 0x7FF)*16; nvttst->intr_urb_in = usb_alloc_urb(0, GFP_KERNEL); if (!nvttst->intr_urb_in) goto fail1; nvttst->intr_urb_out = usb_alloc_urb(0, GFP_KERNEL); if (!nvttst->intr_urb_out) goto fail1; txfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail2; } get_random_bytes ( txfbuf, MaxTestSize+MaxOfs ); rxfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL); if(!rxfbuf) { printk("[%s]: rx no mem\n",__func__); goto fail2; } while(1) { get_random_bytes(&ofs1, sizeof(ofs1)); ofs1 &= 0xFFF; get_random_bytes(&ofs2, sizeof(ofs2)); ofs2 &= 0xFFF; //msleep(17); usb_nvttst_setup_IntrOUT(nvttst, txfbuf+ofs2, testsize); ret = usb_nvttst_introut_issue_urb_blocking(nvttst); if(ret) goto fail2; usb_nvttst_setup_IntrIN(nvttst, rxfbuf+ofs1, testsize); ret = usb_nvttst_intrin_issue_urb_blocking(nvttst); if(ret) goto fail2; if(memcmp(txfbuf+ofs2, rxfbuf+ofs1, testsize)) { printk("INTR DATA COMPARE ERROR! (%d)(%d)(%d)\n",testsize,ofs1,ofs2); goto fail3; } //rintk(" INTR= %d (%d)(%d)(%d)\n",++Cnt,testsize,ofs1,ofs2); printk("INTR= %d (%d)(%d)(%d)\n",++Cnt,testsize,ofs1,ofs2); testsize++; if(testsize > MaxTestSize) testsize=1; if (kthread_should_stop() || (nvttst->status)) goto fail3; } fail3: fail2: if(txfbuf) kfree(txfbuf); if(rxfbuf) kfree(rxfbuf); fail1: if(nvttst->intr_urb_in) usb_free_urb(nvttst->intr_urb_in); if(nvttst->intr_urb_out) usb_free_urb(nvttst->intr_urb_out); while(!kthread_should_stop()) { msleep(50); } complete(&nvttst->intr_close); printk("[%s]: thread closed.\n",__func__); return 0; } static int usb_nvttst_ISOIN_thread(void * __nvttst) #if 1 { struct usb_nvttst *nvttst = (struct usb_nvttst *)__nvttst; u8 *txfbuf; u8 *rxfbuf,*rxfbuf2; size_t i,ofs2=0,ofs1=0; int ret,Cnt=0; struct usb_host_interface *intf = nvttst->inf->cur_altsetting; int MaxOfs = 4096, pktno=256,MaxTestSize = 256*2048; int MaxPktSz,HBW,epn=5; nvttst->iso_urb_in = NULL; txfbuf = NULL; rxfbuf = NULL; rxfbuf2 = NULL; if(nvttst->usbdev->descriptor.bcdUSB == 0x0110) { if(((intf->endpoint[3].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[3].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x85)) { printk("ISOIN desc matched. Start ISOIN EP5 testing...\n"); } else { printk("ISOIN desc NOT matched. Close test!\n"); goto fail1; } MaxPktSz = intf->endpoint[3].desc.wMaxPacketSize & 0x07FF; HBW = ((intf->endpoint[3].desc.wMaxPacketSize >> 11) & 0x3)+1; } else { if(((intf->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[0].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x81)) { printk("ISOIN desc matched. Start ISOIN EP1 testing...\n"); epn = 1; } else if(((intf->endpoint[4].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[4].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x85)) { printk("ISOIN desc matched. Start ISOIN EP5 testing...\n"); epn = 5; } else { printk("ISOIN x desc NOT matched. Close test! 0x%02X\n",intf->endpoint[4].desc.bEndpointAddress); goto fail1; } MaxPktSz = intf->endpoint[epn-1].desc.wMaxPacketSize & 0x07FF; HBW = ((intf->endpoint[epn-1].desc.wMaxPacketSize >> 11) & 0x3)+1; } MaxPktSz = MaxPktSz * HBW; nvttst->iso_urb_in = usb_alloc_urb(pktno, GFP_KERNEL); if (!nvttst->iso_urb_in) goto fail1; txfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail2; } for(i=0;iiso_urb_in->iso_frame_desc[i-1].actual_length == MaxPktSz) && (nvttst->iso_urb_in->iso_frame_desc[i].actual_length == 0) && (nvttst->iso_urb_in->iso_frame_desc[i+1].actual_length == MaxPktSz)) { printk("!!!!!!!!!!!!!!!!!!!!!!!!!%d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",i); } } */ for(i=0;iiso_urb_in->iso_frame_desc[i].actual_length > 0) { ofs1 = *(rxfbuf+nvttst->iso_urb_in->iso_frame_desc[i].offset); break; } } for(i=0;iiso_urb_in->iso_frame_desc[i].actual_length > 0) { if(memcmp(txfbuf+ofs1, rxfbuf+nvttst->iso_urb_in->iso_frame_desc[i].offset, nvttst->iso_urb_in->iso_frame_desc[i].actual_length)) { printk("ISOIN DATA COMPARE ERROR! (%d)(%d) (%d)(%d)(%d)\n",i,ofs1,nvttst->iso_urb_in->iso_frame_desc[i].actual_length,nvttst->iso_urb_in->iso_frame_desc[i-1].actual_length,nvttst->iso_urb_in->iso_frame_desc[i-2].actual_length); goto fail3; break; } ofs1 = (ofs1+nvttst->iso_urb_in->iso_frame_desc[i].actual_length)%255; } } //printk(" ISOIN= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in->actual_length,ofs1); printk("ISOIN= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in->actual_length,ofs1); if (kthread_should_stop() || (nvttst->status)) goto fail3; } fail3: fail2: if(txfbuf) kfree(txfbuf); if(rxfbuf) kfree(rxfbuf); fail1: if(nvttst->iso_urb_in) usb_free_urb(nvttst->iso_urb_in); while(!kthread_should_stop()) { msleep(50); } complete(&nvttst->isoin_close); printk("[%s]: thread closed.\n",__func__); return 0; } #else { struct usb_nvttst *nvttst = (struct usb_nvttst *)__nvttst; u8 *txfbuf; u8 *rxfbuf,*rxfbuf2; size_t i,ofs1=0; int ret,Cnt=0; struct usb_host_interface *intf = nvttst->inf->cur_altsetting; int MaxOfs = 4096, pktno=1000,MaxTestSize = 1000*1024; int MaxPktSz,HBW,epn=5; nvttst->iso_urb_in = NULL; nvttst->iso_urb_in2 = NULL; txfbuf = NULL; rxfbuf = NULL; rxfbuf2 = NULL; if(nvttst->usbdev->descriptor.bcdUSB == 0x0110) { if(((intf->endpoint[3].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[3].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x85)) { printk("ISOIN desc matched. Start ISOIN EP5 testing...\n"); epn=5; } else { printk("ISOIN desc NOT matched. Close test!\n"); goto fail1; } MaxPktSz = intf->endpoint[3].desc.wMaxPacketSize & 0x07FF; HBW = ((intf->endpoint[3].desc.wMaxPacketSize >> 11) & 0x3)+1; } else { if(((intf->endpoint[4].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[4].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x85)) { printk("ISOIN desc matched. Start ISOIN EP5 testing...\n"); epn=5; MaxPktSz = intf->endpoint[4].desc.wMaxPacketSize & 0x07FF; HBW = ((intf->endpoint[4].desc.wMaxPacketSize >> 11) & 0x3)+1; } else if(((intf->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[0].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x81)) { printk("ISOIN desc matched. Start ISOIN EP1 testing...\n"); epn=1; MaxPktSz = intf->endpoint[0].desc.wMaxPacketSize & 0x07FF; HBW = ((intf->endpoint[0].desc.wMaxPacketSize >> 11) & 0x3)+1; } else { printk("ISOIN desc NOT matched. Close test!\n"); goto fail1; } } MaxPktSz = MaxPktSz * HBW; nvttst->iso_urb_in = usb_alloc_urb(pktno, GFP_KERNEL); if (!nvttst->iso_urb_in) goto fail1; nvttst->iso_urb_in2 = usb_alloc_urb(pktno, GFP_KERNEL); if (!nvttst->iso_urb_in2) goto fail1; txfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail2; } for(i=0;iiso_urb_in->iso_frame_desc[i-1].actual_length == MaxPktSz) && (nvttst->iso_urb_in->iso_frame_desc[i].actual_length == 0) && (nvttst->iso_urb_in->iso_frame_desc[i+1].actual_length == MaxPktSz)) { printk("!!!!!!!!!!!!!!!!!!!!!!!!!%d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",i); } }*/ for(i=0;iiso_urb_in->iso_frame_desc[i].actual_length > 0) { if(memcmp(txfbuf+ofs1, rxfbuf+nvttst->iso_urb_in->iso_frame_desc[i].offset, nvttst->iso_urb_in->iso_frame_desc[i].actual_length)) { printk("ISOIN DATA COMPARE ERROR! (%d)(%d) (%d)(%d)(%d)\n",i,ofs1,nvttst->iso_urb_in->iso_frame_desc[i].actual_length,nvttst->iso_urb_in->iso_frame_desc[i-1].actual_length,nvttst->iso_urb_in->iso_frame_desc[i-2].actual_length); //goto fail3; break; } ofs1 = (ofs1+nvttst->iso_urb_in->iso_frame_desc[i].actual_length)%255; } } printk("ISOIN1= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in->actual_length,ofs1); memset(rxfbuf, 0xAA, MaxTestSize); usb_nvttst_setup_IsoIN(nvttst, rxfbuf, MaxPktSz, pktno,0,epn); ret = usb_nvttst_isoin_issue_urb_nonblocking(nvttst); if(ret) goto fail3; usb_nvttst_isoin2_issue_urb_waitdone(nvttst); // comapre 2 for(i=0;iiso_urb_in2->iso_frame_desc[i].actual_length > 0) { if(memcmp(txfbuf+ofs1, rxfbuf2+nvttst->iso_urb_in2->iso_frame_desc[i].offset, nvttst->iso_urb_in2->iso_frame_desc[i].actual_length)) { printk("ISOIN DATA COMPARE ERROR! (%d)(%d) (%d)(%d)(%d)\n",i,ofs1,nvttst->iso_urb_in2->iso_frame_desc[i].actual_length,nvttst->iso_urb_in2->iso_frame_desc[i-1].actual_length,nvttst->iso_urb_in2->iso_frame_desc[i-2].actual_length); //goto fail3; break; } ofs1 = (ofs1+nvttst->iso_urb_in2->iso_frame_desc[i].actual_length)%255; } } printk("ISOIN2= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in2->actual_length,ofs1); //printk(" ISOIN= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in->actual_length,ofs1); //printk("ISOIN= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in->actual_length,ofs1); if (kthread_should_stop() || (nvttst->status)) goto fail3; } fail3: fail2: if(txfbuf) kfree(txfbuf); if(rxfbuf) kfree(rxfbuf); fail1: if(nvttst->iso_urb_in) usb_free_urb(nvttst->iso_urb_in); if(nvttst->iso_urb_in2) usb_free_urb(nvttst->iso_urb_in2); while(!kthread_should_stop()) { msleep(50); } complete(&nvttst->isoin_close); printk("[%s]: thread closed.\n",__func__); return 0; } #endif static int usb_nvttst_ISOOUT_thread(void * __nvttst) { struct usb_nvttst *nvttst = (struct usb_nvttst *)__nvttst; u8 *txfbuf; size_t i,ofs1=0; int ret,Cnt=0; struct usb_host_interface *intf = nvttst->inf->cur_altsetting; int pktno=512,MaxTestSize = (512*1024)+512; int MaxPktSz,HBW,epn=6; nvttst->iso_urb_out = NULL; txfbuf = NULL; if(nvttst->usbdev->descriptor.bcdUSB == 0x0110) { // Check if bulk/interrupt/isochronous test if(((intf->endpoint[3].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[3].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x06)) { printk("ISOOUT desc matched. Start ISOOUT EP6 testing...\n"); } else { printk("ISOOUT desc NOT matched. Close test!\n"); goto fail1; } MaxPktSz = intf->endpoint[3].desc.wMaxPacketSize & 0x07FF; HBW = ((intf->endpoint[3].desc.wMaxPacketSize >> 11) & 0x3)+1; } else { // Check if bulk/interrupt/isochronous test if(((intf->endpoint[5].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[5].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x06)) { printk("ISOOUT desc matched. Start ISOOUT EP6 testing...\n"); epn = 6; } else if(((intf->endpoint[1].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[1].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x02)) { printk("ISOOUT desc matched. Start ISOOUT EP2 testing...\n"); epn = 2; } else { printk("ISOOUT desc NOT matched. Close test!\n"); goto fail1; } MaxPktSz = intf->endpoint[epn-1].desc.wMaxPacketSize & 0x07FF; HBW = ((intf->endpoint[epn-1].desc.wMaxPacketSize >> 11) & 0x3)+1; } MaxPktSz = MaxPktSz * HBW; nvttst->iso_urb_out = usb_alloc_urb(pktno, GFP_KERNEL); if (!nvttst->iso_urb_out) goto fail1; txfbuf = kmalloc(MaxTestSize, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail2; } for(i=0;iiso_urb_out->actual_length,ofs1); printk("ISOOUT= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_out->actual_length,ofs1); if (kthread_should_stop() || (nvttst->status)) goto fail3; } fail3: fail2: if(txfbuf) kfree(txfbuf); fail1: if(nvttst->iso_urb_out) usb_free_urb(nvttst->iso_urb_out); while(!kthread_should_stop()) { msleep(50); } complete(&nvttst->isoout_close); printk("[%s]: thread closed.\n",__func__); return 0; } #if 0 static int usb_nvttst_ISOIN_UVC1_thread(void * __nvttst) { struct usb_nvttst *nvttst = (struct usb_nvttst *)__nvttst; u8 *txfbuf; u8 *rxfbuf,*rxfbuf2; size_t i,ofs1=0; int ret; struct usb_host_interface *intf = nvttst->inf->cur_altsetting; int MaxOfs = 4096, pktno=1000,MaxTestSize = 1000*1024; int MaxPktSz,HBW; u8 UvcHeader[12]; u32 CounterValue,FrmDataSz=0,PTS=0,tPTS=0,targetSz=1; u8 FID=255,state=1; unsigned long timeout = 0; nvttst->iso_urb_uvc11 = NULL; nvttst->iso_urb_uvc12 = NULL; txfbuf = NULL; rxfbuf = NULL; rxfbuf2 = NULL; { if(((intf->endpoint[2].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[2].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x87)) { printk("ISOIN UVC desc matched. Start ISOIN UVC EP7 testing...\n"); } else { printk("ISOIN desc NOT matched. Close test!\n"); goto fail1; } MaxPktSz = intf->endpoint[2].desc.wMaxPacketSize & 0x07FF; HBW = ((intf->endpoint[2].desc.wMaxPacketSize >> 11) & 0x3)+1; } nvttst->msgoff = 1; MaxPktSz = MaxPktSz * HBW; nvttst->iso_urb_uvc11= usb_alloc_urb(pktno, GFP_KERNEL); if (!nvttst->iso_urb_uvc11) goto fail1; nvttst->iso_urb_uvc12 = usb_alloc_urb(pktno, GFP_KERNEL); if (!nvttst->iso_urb_uvc12) goto fail1; txfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail2; } for(i=0;iiso_urb_uvc11->iso_frame_desc[i].actual_length > 0) { memcpy(UvcHeader, rxfbuf+nvttst->iso_urb_uvc11->iso_frame_desc[i].offset,(rxfbuf+nvttst->iso_urb_uvc11->iso_frame_desc[i].offset)[0]); /* Data Compare */ if(memcmp(txfbuf+ofs1, rxfbuf+nvttst->iso_urb_uvc11->iso_frame_desc[i].offset+UvcHeader[0], nvttst->iso_urb_uvc11->iso_frame_desc[i].actual_length-UvcHeader[0])) { printk("ISOIN DATA COMPARE ERROR! (%d)(%d) (%d)(%d)(%d)\n",i,ofs1,nvttst->iso_urb_uvc11->iso_frame_desc[i].actual_length,nvttst->iso_urb_uvc11->iso_frame_desc[i-1].actual_length,nvttst->iso_urb_uvc11->iso_frame_desc[i-2].actual_length); goto fail3; break; } ofs1 = (ofs1+nvttst->iso_urb_uvc11->iso_frame_desc[i].actual_length-UvcHeader[0])%255; FrmDataSz += nvttst->iso_urb_uvc11->iso_frame_desc[i].actual_length-UvcHeader[0]; /* Header Compare */ if(UvcHeader[0] == 12) { CounterValue = UvcHeader[6]+(UvcHeader[7]<<8)+(UvcHeader[8]<<16)+(UvcHeader[9]<<24); tPTS = UvcHeader[2]+(UvcHeader[3]<<8)+(UvcHeader[4]<<16)+(UvcHeader[5]<<24); if((UvcHeader[1]&0x1) != FID) { FID = (UvcHeader[1]&0x1); PTS = tPTS; if(state==0) { printk("START ERR!\n"); while(1); } state=0; } if(UvcHeader[1]&0x2) { //printk("UVC1(%u)= %d\n",(CounterValue/1000000*33),FrmDataSz); if(FrmDataSz != targetSz) { printk("SzErr = %d %d\n",FrmDataSz,targetSz); } FrmDataSz=0; targetSz++; if(state==1) { printk("STOP ERR!\n"); while(1); } state=1; } if((UvcHeader[1] & 0x8C) != 0x8C) { printk("Header Err! 0x%02X\n",UvcHeader[1]); while(1); } if(tPTS != PTS) { printk("PTS ERR! 0x%08X 0x%08X\n",PTS,tPTS); while(1); } } else if (UvcHeader[0] == 2) { CounterValue = 0; if((UvcHeader[1]&0x1) != FID) { FID = (UvcHeader[1]&0x1); if(state==0) { printk("START ERR!\n"); while(1); } state=0; } if(UvcHeader[1]&0x2) { //printk("UVC1(%u)= %d\n",(CounterValue/1000000*33),FrmDataSz); if(FrmDataSz != targetSz) { printk("SzErr = %d %d\n",FrmDataSz,targetSz); } FrmDataSz=0; targetSz++; if(state==1) { printk("STOP ERR!\n"); while(1); } state=1; } //if((UvcHeader[1] & 0x8C) != 0x8C) { // printk("Header Err! 0x%02X\n",UvcHeader[1]); // while(1); //} } else { printk("header size error!\r\n"); goto fail3; } } } if (time_after(jiffies, timeout)) { timeout = jiffies + msecs_to_jiffies(500); printk("UVC1(%ums)= %d\n",(CounterValue/1000000*33),targetSz-1); } //memset(rxfbuf, 0xAA, MaxTestSize); usb_nvttst_setup_uvc11(nvttst, rxfbuf, MaxPktSz, pktno,0,7); ret = usb_nvttst_isouvc11_issue_urb_nonblocking(nvttst); if(ret) goto fail3; usb_nvttst_isouvc12_issue_urb_waitdone(nvttst); // comapre 2 for(i=0;iiso_urb_uvc12->iso_frame_desc[i].actual_length > 0) { memcpy(UvcHeader, rxfbuf2+nvttst->iso_urb_uvc12->iso_frame_desc[i].offset,(rxfbuf2+nvttst->iso_urb_uvc12->iso_frame_desc[i].offset)[0]); if(memcmp(txfbuf+ofs1, rxfbuf2+nvttst->iso_urb_uvc12->iso_frame_desc[i].offset+UvcHeader[0], nvttst->iso_urb_uvc12->iso_frame_desc[i].actual_length-UvcHeader[0])) { printk("ISOIN DATA COMPARE ERROR! (%d)(%d) (%d)(%d)(%d)\n",i,ofs1,nvttst->iso_urb_uvc12->iso_frame_desc[i].actual_length,nvttst->iso_urb_uvc12->iso_frame_desc[i-1].actual_length,nvttst->iso_urb_uvc12->iso_frame_desc[i-2].actual_length); goto fail3; break; } ofs1 = (ofs1+nvttst->iso_urb_uvc12->iso_frame_desc[i].actual_length-UvcHeader[0])%255; FrmDataSz += nvttst->iso_urb_uvc12->iso_frame_desc[i].actual_length-UvcHeader[0]; /* Header Compare */ if(UvcHeader[0] == 12) { CounterValue = UvcHeader[6]+(UvcHeader[7]<<8)+(UvcHeader[8]<<16)+(UvcHeader[9]<<24); tPTS = UvcHeader[2]+(UvcHeader[3]<<8)+(UvcHeader[4]<<16)+(UvcHeader[5]<<24); if((UvcHeader[1]&0x1) != FID) { FID = (UvcHeader[1]&0x1); PTS = tPTS; if(state==0) { printk("START ERR!\n"); while(1); } state=0; } if(UvcHeader[1]&0x2) { //printk("UVC1(%u)= %d\n",(CounterValue/1000000*33),FrmDataSz); if(FrmDataSz != targetSz) { printk("SzErr = %d %d\n",FrmDataSz,targetSz); } FrmDataSz=0; targetSz++; if(state==1) { printk("STOP ERR!\n"); while(1); } state=1; } if((UvcHeader[1] & 0x8C) != 0x8C) { printk("Header Err! 0x%02X\n",UvcHeader[1]); while(1); } if(tPTS != PTS) { printk("PTS ERR! 0x%08X 0x%08X\n",PTS,tPTS); while(1); } } else if (UvcHeader[0] == 2) { CounterValue = 0; if((UvcHeader[1]&0x1) != FID) { FID = (UvcHeader[1]&0x1); if(state==0) { printk("START ERR!\n"); while(1); } state=0; } if(UvcHeader[1]&0x2) { //printk("UVC1(%u)= %d\n",(CounterValue/1000000*33),FrmDataSz); if(FrmDataSz != targetSz) { printk("SzErr = %d %d\n",FrmDataSz,targetSz); } FrmDataSz=0; targetSz++; if(state==1) { printk("STOP ERR!\n"); while(1); } state=1; } //if((UvcHeader[1] & 0x8C) != 0x8C) { // printk("Header Err! 0x%02X\n",UvcHeader[1]); // while(1); //} } else { printk("header size error!\r\n"); goto fail3; } } } //printk("UVC1(%u)= %d (%d)(%d)\n",(CounterValue/1000000*33),++Cnt,nvttst->iso_urb_uvc12->actual_length,ofs1); if (time_after(jiffies, timeout)) { timeout = jiffies + msecs_to_jiffies(500); printk("UVC1(%ums)= %d\n",(CounterValue/1000000*33),targetSz-1); } //printk(" ISOIN= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in->actual_length,ofs1); //printk("ISOIN= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in->actual_length,ofs1); if (kthread_should_stop() || (nvttst->status)) goto fail3; } fail3: fail2: if(txfbuf) kfree(txfbuf); if(rxfbuf) kfree(rxfbuf); fail1: if(nvttst->iso_urb_uvc11) usb_free_urb(nvttst->iso_urb_uvc11); if(nvttst->iso_urb_uvc12) usb_free_urb(nvttst->iso_urb_uvc12); while(!kthread_should_stop()) { msleep(50); } complete(&nvttst->isoin_close_uvc1); printk("[%s]: thread closed.\n",__func__); return 0; } static int usb_nvttst_ISOIN_UVC2_thread(void * __nvttst) { struct usb_nvttst *nvttst = (struct usb_nvttst *)__nvttst; u8 *txfbuf; u8 *rxfbuf,*rxfbuf2; size_t i,ofs1=0; int ret; struct usb_host_interface *intf = nvttst->inf->cur_altsetting; int MaxOfs = 4096, pktno=1000,MaxTestSize = 1000*1024; int MaxPktSz,HBW; u8 UvcHeader[12]; u32 CounterValue,FrmDataSz=0,PTS=0,tPTS=0,targetSz=1; u8 FID=255,state=1; unsigned long timeout = 0; nvttst->iso_urb_uvc21 = NULL; nvttst->iso_urb_uvc22 = NULL; txfbuf = NULL; rxfbuf = NULL; rxfbuf2 = NULL; { if(((intf->endpoint[3].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) &&((intf->endpoint[3].desc.bEndpointAddress & (USB_ENDPOINT_DIR_MASK|USB_ENDPOINT_NUMBER_MASK)) == 0x88)) { printk("ISOIN UVC2 desc matched. Start ISOIN UVC EP8 testing...\n"); } else { printk("ISOIN desc NOT matched. Close test!\n"); goto fail1; } MaxPktSz = intf->endpoint[3].desc.wMaxPacketSize & 0x07FF; HBW = ((intf->endpoint[3].desc.wMaxPacketSize >> 11) & 0x3)+1; } nvttst->msgoff = 1; MaxPktSz = MaxPktSz * HBW; nvttst->iso_urb_uvc21= usb_alloc_urb(pktno, GFP_KERNEL); if (!nvttst->iso_urb_uvc21) goto fail1; nvttst->iso_urb_uvc22 = usb_alloc_urb(pktno, GFP_KERNEL); if (!nvttst->iso_urb_uvc22) goto fail1; txfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL); if(!txfbuf) { printk("[%s]: tx no mem\n",__func__); goto fail2; } for(i=0;iiso_urb_uvc21->iso_frame_desc[i].actual_length > 0) { memcpy(UvcHeader, rxfbuf+nvttst->iso_urb_uvc21->iso_frame_desc[i].offset,(rxfbuf+nvttst->iso_urb_uvc21->iso_frame_desc[i].offset)[0]); /* Data Compare */ if(memcmp(txfbuf+ofs1, rxfbuf+nvttst->iso_urb_uvc21->iso_frame_desc[i].offset+UvcHeader[0], nvttst->iso_urb_uvc21->iso_frame_desc[i].actual_length-UvcHeader[0])) { printk("ISOIN DATA COMPARE ERROR! (%d)(%d) (%d)(%d)(%d)\n",i,ofs1,nvttst->iso_urb_uvc21->iso_frame_desc[i].actual_length,nvttst->iso_urb_uvc21->iso_frame_desc[i-1].actual_length,nvttst->iso_urb_uvc21->iso_frame_desc[i-2].actual_length); goto fail3; break; } ofs1 = (ofs1+nvttst->iso_urb_uvc21->iso_frame_desc[i].actual_length-UvcHeader[0])%255; FrmDataSz += nvttst->iso_urb_uvc21->iso_frame_desc[i].actual_length-UvcHeader[0]; /* Header Compare */ if(UvcHeader[0] == 12) { CounterValue = UvcHeader[6]+(UvcHeader[7]<<8)+(UvcHeader[8]<<16)+(UvcHeader[9]<<24); tPTS = UvcHeader[2]+(UvcHeader[3]<<8)+(UvcHeader[4]<<16)+(UvcHeader[5]<<24); if((UvcHeader[1]&0x1) != FID) { FID = (UvcHeader[1]&0x1); PTS = tPTS; if(state==0) { printk("START ERR!\n"); while(1); } state=0; } if(UvcHeader[1]&0x2) { //printk("UVC1(%u)= %d\n",(CounterValue/1000000*33),FrmDataSz); if(FrmDataSz != targetSz) { printk("SzErr = %d %d\n",FrmDataSz,targetSz); } FrmDataSz=0; targetSz++; if(state==1) { printk("STOP ERR!\n"); while(1); } state=1; } if((UvcHeader[1] & 0x8C) != 0x8C) { printk("Header Err! 0x%02X\n",UvcHeader[1]); while(1); } if(tPTS != PTS) { printk("PTS ERR! 0x%08X 0x%08X\n",PTS,tPTS); while(1); } } else if (UvcHeader[0] == 2) { CounterValue = 0; if((UvcHeader[1]&0x1) != FID) { FID = (UvcHeader[1]&0x1); if(state==0) { printk("START ERR!\n"); while(1); } state=0; } if(UvcHeader[1]&0x2) { //printk("UVC1(%u)= %d\n",(CounterValue/1000000*33),FrmDataSz); if(FrmDataSz != targetSz) { printk("SzErr = %d %d\n",FrmDataSz,targetSz); } FrmDataSz=0; targetSz++; if(state==1) { printk("STOP ERR!\n"); while(1); } state=1; } //if((UvcHeader[1] & 0x8C) != 0x8C) { // printk("Header Err! 0x%02X\n",UvcHeader[1]); // while(1); //} } else { printk("header size error!\r\n"); goto fail3; } } } if (time_after(jiffies, timeout)) { timeout = jiffies + msecs_to_jiffies(500); printk("UVC2(%ums)= %d\n",(CounterValue/1000000*33),targetSz-1); } //memset(rxfbuf, 0xAA, MaxTestSize); usb_nvttst_setup_uvc21(nvttst, rxfbuf, MaxPktSz, pktno,0,8); ret = usb_nvttst_isouvc21_issue_urb_nonblocking(nvttst); if(ret) goto fail3; usb_nvttst_isouvc22_issue_urb_waitdone(nvttst); // comapre 2 for(i=0;iiso_urb_uvc22->iso_frame_desc[i].actual_length > 0) { memcpy(UvcHeader, rxfbuf2+nvttst->iso_urb_uvc22->iso_frame_desc[i].offset,(rxfbuf2+nvttst->iso_urb_uvc22->iso_frame_desc[i].offset)[0]); if(memcmp(txfbuf+ofs1, rxfbuf2+nvttst->iso_urb_uvc22->iso_frame_desc[i].offset+UvcHeader[0], nvttst->iso_urb_uvc22->iso_frame_desc[i].actual_length-UvcHeader[0])) { printk("ISOIN DATA COMPARE ERROR! (%d)(%d) (%d)(%d)(%d)\n",i,ofs1,nvttst->iso_urb_uvc22->iso_frame_desc[i].actual_length,nvttst->iso_urb_uvc22->iso_frame_desc[i-1].actual_length,nvttst->iso_urb_uvc22->iso_frame_desc[i-2].actual_length); goto fail3; break; } ofs1 = (ofs1+nvttst->iso_urb_uvc22->iso_frame_desc[i].actual_length-UvcHeader[0])%255; FrmDataSz += nvttst->iso_urb_uvc22->iso_frame_desc[i].actual_length-UvcHeader[0]; /* Header Compare */ if(UvcHeader[0] == 12) { CounterValue = UvcHeader[6]+(UvcHeader[7]<<8)+(UvcHeader[8]<<16)+(UvcHeader[9]<<24); tPTS = UvcHeader[2]+(UvcHeader[3]<<8)+(UvcHeader[4]<<16)+(UvcHeader[5]<<24); if((UvcHeader[1]&0x1) != FID) { FID = (UvcHeader[1]&0x1); PTS = tPTS; if(state==0) { printk("START ERR!\n"); while(1); } state=0; } if(UvcHeader[1]&0x2) { //printk("UVC1(%u)= %d\n",(CounterValue/1000000*33),FrmDataSz); if(FrmDataSz != targetSz) { printk("SzErr = %d %d\n",FrmDataSz,targetSz); } FrmDataSz=0; targetSz++; if(state==1) { printk("STOP ERR!\n"); while(1); } state=1; } if((UvcHeader[1] & 0x8C) != 0x8C) { printk("Header Err! 0x%02X\n",UvcHeader[1]); while(1); } if(tPTS != PTS) { printk("PTS ERR! 0x%08X 0x%08X\n",PTS,tPTS); while(1); } } else if (UvcHeader[0] == 2) { CounterValue = 0; if((UvcHeader[1]&0x1) != FID) { FID = (UvcHeader[1]&0x1); if(state==0) { printk("START ERR!\n"); while(1); } state=0; } if(UvcHeader[1]&0x2) { //printk("UVC1(%u)= %d\n",(CounterValue/1000000*33),FrmDataSz); if(FrmDataSz != targetSz) { printk("SzErr = %d %d\n",FrmDataSz,targetSz); } FrmDataSz=0; targetSz++; if(state==1) { printk("STOP ERR!\n"); while(1); } state=1; } //if((UvcHeader[1] & 0x8C) != 0x8C) { // printk("Header Err! 0x%02X\n",UvcHeader[1]); // while(1); //} } else { printk("header size error!\r\n"); goto fail3; } } } //printk("UVC1(%u)= %d (%d)(%d)\n",(CounterValue/1000000*33),++Cnt,nvttst->iso_urb_uvc12->actual_length,ofs1); if (time_after(jiffies, timeout)) { timeout = jiffies + msecs_to_jiffies(500); printk("UVC2(%ums)= %d\n",(CounterValue/1000000*33),targetSz-1); } //printk(" ISOIN= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in->actual_length,ofs1); //printk("ISOIN= %d (%d)(%d)\n",++Cnt,nvttst->iso_urb_in->actual_length,ofs1); if (kthread_should_stop() || (nvttst->status)) goto fail3; } fail3: fail2: if(txfbuf) kfree(txfbuf); if(rxfbuf) kfree(rxfbuf); fail1: if(nvttst->iso_urb_uvc21) usb_free_urb(nvttst->iso_urb_uvc21); if(nvttst->iso_urb_uvc22) usb_free_urb(nvttst->iso_urb_uvc22); while(!kthread_should_stop()) { msleep(50); } complete(&nvttst->isoin_close_uvc2); printk("[%s]: thread closed.\n",__func__); return 0; } #endif #endif static int usb_nvttst_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_nvttst *nvttst; struct task_struct *th; /* printk("match_flags 0x%X\n",id->match_flags); printk("idVendor 0x%X\n",id->idVendor); printk("idProduct 0x%X\n",id->idProduct); printk("bcdDevice_lo 0x%X\n",id->bcdDevice_lo); printk("bcdDevice_hi 0x%X\n",id->bcdDevice_hi); printk("bDeviceClass 0x%X\n",id->bDeviceClass); printk("bDeviceSubClass 0x%X\n",id->bDeviceSubClass); printk("bDeviceProtocol 0x%X\n",id->bDeviceProtocol); printk("bInterfaceClass 0x%X\n",id->bInterfaceClass); printk("bInterfaceSubClass 0x%X\n",id->bInterfaceSubClass); printk("bInterfaceProtocol 0x%X\n",id->bInterfaceProtocol); printk("bInterfaceNumber 0x%X\n",id->bInterfaceNumber); */ nvttst = kzalloc(sizeof(struct usb_nvttst), GFP_KERNEL); if(!nvttst) return -ENOMEM; if(dev->manufacturer) strlcpy(nvttst->name, dev->manufacturer, sizeof(nvttst->name)); if (dev->product) { if (dev->manufacturer) strlcat(nvttst->name, " ", sizeof(nvttst->name)); strlcat(nvttst->name, dev->product, sizeof(nvttst->name)); } if (!strlen(nvttst->name)) snprintf(nvttst->name, sizeof(nvttst->name), "Novatek. USB HOST TEST PROGRAM."); //nvttst->urb1 = usb_alloc_urb(0, GFP_KERNEL); //if (!nvttst->urb1) // goto fail1; //nvttst->urb2 = usb_alloc_urb(0, GFP_KERNEL); //if (!nvttst->urb2) // goto fail2; //nvttst->urb3 = usb_alloc_urb(8, GFP_KERNEL); //if (!nvttst->urb3) // goto fail3; nvttst->cx_thread = NULL; nvttst->bulk_thread = NULL; nvttst->intr_thread = NULL; nvttst->isoin_thread = NULL; nvttst->isoout_thread = NULL; nvttst->isouvc1_thread = NULL; nvttst->isouvc2_thread = NULL; nvttst->inf = intf; nvttst->usbdev = dev; init_completion(&nvttst->cx_close); init_completion(&nvttst->bulk_close); init_completion(&nvttst->intr_close); init_completion(&nvttst->isoin_close); init_completion(&nvttst->isoout_close); init_completion(&nvttst->isoin_close_uvc1); init_completion(&nvttst->isoin_close_uvc2); usb_set_intfdata(intf, nvttst); /* Start test program run */ #if 1 th = kthread_run(usb_nvttst_CxRW_thread, nvttst, "nvttst-Cx-thread"); if (IS_ERR(th)) { printk("+%s[%d]: thread open error\n",__func__,__LINE__); goto fail1; } nvttst->cx_thread = th; #endif #if 1 th = kthread_run(usb_nvttst_BULKRW_thread, nvttst, "nvttst-bulk-thread"); if (IS_ERR(th)) { printk("+%s[%d]: thread open error\n",__func__,__LINE__); goto fail1; } nvttst->bulk_thread = th; #endif #if 1 th = kthread_run(usb_nvttst_INTRRW_thread, nvttst, "nvttst-intr-thread"); if (IS_ERR(th)) { printk("+%s[%d]: thread open error\n",__func__,__LINE__); goto fail1; } nvttst->intr_thread = th; #endif #if 1 th = kthread_run(usb_nvttst_ISOIN_thread, nvttst, "nvttst-isoin-thread"); if (IS_ERR(th)) { printk("+%s[%d]: thread open error\n",__func__,__LINE__); goto fail1; } nvttst->isoin_thread = th; #endif #if 1 th = kthread_run(usb_nvttst_ISOOUT_thread, nvttst, "nvttst-isoout-thread"); if (IS_ERR(th)) { printk("+%s[%d]: thread open error\n",__func__,__LINE__); goto fail1; } nvttst->isoout_thread = th; #endif #if 0 th = kthread_run(usb_nvttst_ISOIN_UVC1_thread, nvttst, "nvttst-isouvc1-thread"); if (IS_ERR(th)) { printk("+%s[%d]: thread open error\n",__func__,__LINE__); goto fail1; } nvttst->isouvc1_thread = th; #endif #if 0 th = kthread_run(usb_nvttst_ISOIN_UVC2_thread, nvttst, "nvttst-isouvc2-thread"); if (IS_ERR(th)) { printk("+%s[%d]: thread open error\n",__func__,__LINE__); goto fail1; } nvttst->isouvc2_thread = th; #endif printk("+%s[%d]: Name = %s\n",__func__,__LINE__,nvttst->name); return 0; // Sample codes for usb usages //usb_stor_acquire_resources //usb_stor_release_resources //usb_start_wait_urb fail1: kfree(nvttst); return -ENOMEM; } static void usb_nvttst_disconnect(struct usb_interface *intf) { struct usb_nvttst *nvttst = usb_get_intfdata(intf); printk("+%s[%d] 1\n",__func__,__LINE__); if (nvttst->cx_thread) kthread_stop(nvttst->cx_thread); else complete(&nvttst->cx_close); if (nvttst->bulk_thread) kthread_stop(nvttst->bulk_thread); else complete(&nvttst->bulk_close); if (nvttst->intr_thread) kthread_stop(nvttst->intr_thread); else complete(&nvttst->intr_close); if (nvttst->isoin_thread) kthread_stop(nvttst->isoin_thread); else complete(&nvttst->isoin_close); if (nvttst->isoout_thread) kthread_stop(nvttst->isoout_thread); else complete(&nvttst->isoout_close); if (nvttst->isouvc1_thread) kthread_stop(nvttst->isouvc1_thread); else complete(&nvttst->isoin_close_uvc1); if (nvttst->isouvc2_thread) kthread_stop(nvttst->isouvc2_thread); else complete(&nvttst->isoin_close_uvc2); printk("+%s[%d] 2\n",__func__,__LINE__); if(!wait_for_completion_timeout(&nvttst->cx_close, msecs_to_jiffies(5000))) printk("[%s]:wait thread close timeout\n",__func__); if(!wait_for_completion_timeout(&nvttst->bulk_close, msecs_to_jiffies(5000))) printk("[%s]:wait thread close timeout\n",__func__); if(!wait_for_completion_timeout(&nvttst->intr_close, msecs_to_jiffies(5000))) printk("[%s]:wait thread close timeout\n",__func__); if(!wait_for_completion_timeout(&nvttst->isoin_close, msecs_to_jiffies(5000))) printk("[%s]:wait thread close timeout\n",__func__); if(!wait_for_completion_timeout(&nvttst->isoout_close, msecs_to_jiffies(5000))) printk("[%s]:wait thread close timeout\n",__func__); if(!wait_for_completion_timeout(&nvttst->isoin_close_uvc1, msecs_to_jiffies(5000))) printk("[%s]:wait thread close timeout\n",__func__); if(!wait_for_completion_timeout(&nvttst->isoin_close_uvc2, msecs_to_jiffies(5000))) printk("[%s]:wait thread close timeout\n",__func__); printk("+%s[%d] 3\n",__func__,__LINE__); //if(nvttst->urb1) // usb_free_urb(nvttst->urb1); //if(nvttst->urb2) // usb_free_urb(nvttst->urb2); //if(nvttst->urb3) // usb_free_urb(nvttst->urb3); kfree(nvttst); printk("+%s[%d] 4\n",__func__,__LINE__); } static struct usb_device_id usb_nvttst_id_table [] = { { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT | USB_DEVICE_ID_MATCH_DEV_LO, .idVendor = 0x2310, .idProduct = 0x5678, .bcdDevice_lo= 2 }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, usb_nvttst_id_table); static struct usb_driver usb_nvttst_driver = { .name = "usbnvttst", .probe = usb_nvttst_probe, .disconnect = usb_nvttst_disconnect, .id_table = usb_nvttst_id_table, }; module_usb_driver(usb_nvttst_driver);