nt9856x/BSP/linux-kernel/drivers/usb/nvtusb/nvtusb.c
2023-03-28 15:07:53 +08:00

3445 lines
80 KiB
C
Executable File

/*
* Copyright (c) 2014 Novatek
*
* NVT USB Host Test
*/
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/random.h>
#include <linux/usb.h>
#include <linux/pm_runtime.h>
//#include <../host/xhci.h>
//#include <linux/usb/input.h>
/*
* Version Information
*/
#define DRIVER_VERSION "v1.0"
#define DRIVER_AUTHOR "Klins Chen <klins_chen@novatek.com.tw>"
#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;i<pktno;i++) {
nvttst->iso_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;i<pktno;i++) {
nvttst->iso_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;i<pktno;i++) {
nvttst->iso_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;i<pktno;i++) {
nvttst->iso_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;i<pktno;i++) {
nvttst->iso_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;i<pktno;i++) {
nvttst->iso_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;i<pktno;i++) {
nvttst->iso_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;i<len2;i++)
{
rxfbuf[i] = outCnter++;
}
/********************************
* Vendor Control IN/OUT
********************************/
usb_nvttst_setup_CxIN (nvttst->urb1, 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;i<len1;i++)
{
if(txfbuf[i] != inCnter++)
printk("Data Err tot=%d, idx=%d, should 0x%X, but 0x%X \n",len1,i,inCnter,txfbuf[i]);
}
}
kfree(txfbuf);
kfree(rxfbuf);
#if 1
/********************************
* BULK OUT
********************************/
cbwbuf = kzalloc(31, GFP_KERNEL);
if(!cbwbuf) {
printk("[%s]: cbw no mem\n",__func__);
goto fail1;
}
//get_random_bytes ( &len1, sizeof (len1) );
len1 = ++bulksize;
len1 &= 0x1FFFF;
if(len1 == 0)
len1++;
usb_nvttst_fill_cbw(cbwbuf, len1, 1);
usb_nvttst_setup_BulkOUT(nvttst->urb1,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;i<len1;i++)
{
get_random_bytes ( &txfbuf[i], sizeof (txfbuf[i]) );
}
usb_nvttst_setup_BulkOUT(nvttst->urb1,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;i<len1;i++)
{
txfbuf[i] = outCnter++;
}
usb_nvttst_setup_IntrOUT(nvttst->urb1,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;i<MaxTestSize+MaxOfs;i++)
{
txfbuf[i] = i&0xFF;
}
rxfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf) {
printk("[%s]: rx no mem\n",__func__);
goto fail2;
}
ctrlreq1 = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
ctrlreq2 = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
while(1) {
get_random_bytes ( &len1, sizeof (len1) );
len1 = len1 % MaxTestSize;//Max 16384 in linux
if(len1 == 0)
len1++;
//get_random_bytes ( &len2, sizeof (len2) );
//len2 = len2 % MaxTestSize;//Max 16384 in linux
//if(len2 == 0)
// len2++;
#if 0
msleep(200);
//small test size for iso
len1 = len1 % 257;
if(len1 == 0)
len1++;
len2 = len2 % 257;
if(len2 == 0)
len2++;
#endif
/********************************
* Vendor Control IN/OUT
********************************/
//msleep(len1&127);
usb_nvttst_setup_CxOUT(nvttst, ctrlreq2, (void *)txfbuf+txofs, len1);
ret = usb_nvttst_cxout_issue_urb_blocking(nvttst);
if(ret)
goto fail3;
msleep(11);
//msleep(len1&&127);
usb_nvttst_setup_CxIN (nvttst, ctrlreq1, (void *)rxfbuf, len1);
ret = usb_nvttst_cxin_issue_urb_blocking(nvttst);
if(ret)
goto fail3;
msleep(11);
if(memcmp(txfbuf+txofs, rxfbuf, len1)) {
printk("CX DATA COMPARE ERROR!\n");
printk("CX= %d (%d)(%d)\n",++Cnt,len1,txofs);
{
//for(i=0;i<len1;i++) {
// if(txfbuf[txofs+i] != rxfbuf[i]) {
// printk("CX DATA COMPARE ERROR!%d 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",i,txfbuf[txofs+i-1],rxfbuf[i-1],txfbuf[txofs+i],rxfbuf[i],txfbuf[txofs+i+1],rxfbuf[i+1]);
// }
//}
}
goto fail3;
}
txofs = (txofs + len1)&0xFF;
if(!nvttst->msgoff)
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;i<MaxTestSize+MaxOfs;i++)
// txfbuf[i]=i&0xFF;
//}
rxfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf) {
printk("[%s]: rx no mem\n",__func__);
goto fail2;
}
cbwbuf = kzalloc(31, GFP_KERNEL);
if(!cbwbuf) {
printk("[%s]: cbw no mem\n",__func__);
goto fail2;
}
cswbuf = kmalloc(13, GFP_KERNEL);
if(!cswbuf) {
printk("[%s]: csw no mem\n",__func__);
goto fail2;
}
bulksize = 0;
while(1) {
get_random_bytes ( &bulksize, sizeof (bulksize) );
//bulksize++;
bulksize &= (MaxTestSize-1);
if(bulksize == 0)
bulksize++;
get_random_bytes ( &ofs1, sizeof (ofs1) );
ofs1 &= (MaxOfs-1);
//ofs1=0;
msleep(15);
#if 0
msleep(200);
//small test size for iso
bulksize = bulksize % 33;
if(bulksize == 0)
bulksize++;
ofs1 = 0;
#endif
#if 1
/********************************
* BULK OUT
********************************/
usb_nvttst_fill_cbw(cbwbuf, bulksize, 1);
//printk("bksz=%d\r\n",bulksize);
usb_nvttst_setup_BulkOUT(nvttst, cbwbuf, 31,epo);
ret = usb_nvttst_bulkout_issue_urb_blocking(nvttst);
if(ret)
goto fail3;
usb_nvttst_setup_BulkOUT(nvttst, txfbuf+ofs1, bulksize,epo);
ret = usb_nvttst_bulkout_issue_urb_blocking(nvttst);
if(ret)
goto fail3;
usb_nvttst_setup_BulkIN(nvttst, cswbuf, 13,epi);
ret = usb_nvttst_bulkin_issue_urb_blocking(nvttst);
if(ret)
goto fail3;
#endif
#if 1
/********************************
* BULK IN
********************************/
usb_nvttst_fill_cbw(cbwbuf, bulksize, 0);
usb_nvttst_setup_BulkOUT(nvttst, cbwbuf, 31,epo);
ret = usb_nvttst_bulkout_issue_urb_blocking(nvttst);
if(ret)
goto fail3;
usb_nvttst_setup_BulkIN(nvttst, rxfbuf+ofs1, bulksize,epi);
ret = usb_nvttst_bulkin_issue_urb_blocking(nvttst);
if(ret)
goto fail3;
usb_nvttst_setup_BulkIN(nvttst, cswbuf, 13,epi);
ret = usb_nvttst_bulkin_issue_urb_blocking(nvttst);
if(ret)
goto fail3;
if(memcmp(txfbuf+ofs1, rxfbuf+ofs1, bulksize)) {
u8 *buf1,*buf2;
int i;
buf1 = txfbuf+ofs1;
buf2 = rxfbuf+ofs1;
for(i=0;i<bulksize;i++) {
if(buf1[i] != buf2[i]) {
break;
}
}
printk("BULK DATA COMPARE ERROR! %d\n",i);
goto fail3;
}
#endif
//printk(" BULK Pass Count = %d (%d)(%d)\n",++Cnt,bulksize,ofs1);
if(!nvttst->msgoff)
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;i<MaxTestSize+MaxOfs;i++)
{
txfbuf[i] = i%255;
}
rxfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf) {
printk("[%s]: rx no mem\n",__func__);
goto fail2;
}
rxfbuf2 = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf2) {
printk("[%s]: rx2 no mem\n",__func__);
goto fail2;
}
while(1) {
ofs2 = 0;
// This delay is very important for testing workaround
msleep(50);
memset(rxfbuf, 0xAA, MaxTestSize);
usb_nvttst_setup_IsoIN(nvttst, rxfbuf, MaxPktSz, pktno,ofs2,epn);
ret = usb_nvttst_isoin_issue_urb_nonblocking(nvttst);
if(ret)
goto fail3;
usb_nvttst_isoin_issue_urb_waitdone(nvttst);
/*
for(i=1;i<(pktno-1);i++)
{
if((nvttst->iso_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;i<pktno;i++)
{
if(nvttst->iso_urb_in->iso_frame_desc[i].actual_length > 0)
{
ofs1 = *(rxfbuf+nvttst->iso_urb_in->iso_frame_desc[i].offset);
break;
}
}
for(i=0;i<pktno;i++)
{
if(nvttst->iso_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;i<MaxTestSize+MaxOfs;i++)
{
txfbuf[i] = i%255;
}
rxfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf) {
printk("[%s]: rx no mem\n",__func__);
goto fail2;
}
rxfbuf2 = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf2) {
printk("[%s]: rx2 no mem\n",__func__);
goto fail2;
}
memset(rxfbuf, 0xAA, MaxTestSize);
usb_nvttst_setup_IsoIN(nvttst, rxfbuf, MaxPktSz, pktno,0,epn);
memset(rxfbuf2, 0xAA, MaxTestSize);
usb_nvttst_setup_IsoIN2(nvttst, rxfbuf2, MaxPktSz, pktno,0,epn);
ret = usb_nvttst_isoin_issue_urb_nonblocking(nvttst);
if(ret)
goto fail3;
while(1) {
// This delay is very important for testing workaround
//msleep(50);
memset(rxfbuf2, 0xAA, MaxTestSize);
usb_nvttst_setup_IsoIN2(nvttst, rxfbuf2, MaxPktSz, pktno,0,epn);
ret = usb_nvttst_isoin2_issue_urb_nonblocking(nvttst);
if(ret)
goto fail3;
usb_nvttst_isoin_issue_urb_waitdone(nvttst);
// comapre 1
/*for(i=1;i<(pktno-1);i++)
{
if((nvttst->iso_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;i<pktno;i++)
{
if(nvttst->iso_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;i<pktno;i++)
{
if(nvttst->iso_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;i<MaxTestSize;i++)
{
txfbuf[i] = i%255;
}
while(1) {
// This delay is making device having time to compare data.
msleep(50);
usb_nvttst_setup_IsoOUT(nvttst, txfbuf+ofs1, MaxPktSz, pktno,0,epn);
ret = usb_nvttst_isoout_issue_urb_blocking(nvttst);
if(ret)
goto fail3;
ofs1 = (ofs1 + (MaxPktSz*pktno))%255;
//printk(" ISOOUT= %d (%d)(%d)\n",++Cnt,nvttst->iso_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;i<MaxTestSize+MaxOfs;i++)
{
txfbuf[i] = i%255;
}
rxfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf) {
printk("[%s]: rx no mem\n",__func__);
goto fail2;
}
rxfbuf2 = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf2) {
printk("[%s]: rx2 no mem\n",__func__);
goto fail2;
}
memset(rxfbuf, 0xAA, MaxTestSize);
usb_nvttst_setup_uvc11(nvttst, rxfbuf, MaxPktSz, pktno,0,7);
memset(rxfbuf2, 0xAA, MaxTestSize);
usb_nvttst_setup_uvc12(nvttst, rxfbuf2, MaxPktSz, pktno,0,7);
ret = usb_nvttst_isouvc11_issue_urb_nonblocking(nvttst);
if(ret)
goto fail3;
timeout = jiffies + msecs_to_jiffies(2000);
while(1) {
//memset(rxfbuf2, 0xAA, MaxTestSize);
usb_nvttst_setup_uvc12(nvttst, rxfbuf2, MaxPktSz, pktno,0,7);
ret = usb_nvttst_isouvc12_issue_urb_nonblocking(nvttst);
if(ret)
goto fail3;
usb_nvttst_isouvc11_issue_urb_waitdone(nvttst);
// comapre 1
for(i=0;i<pktno;i++)
{
if(nvttst->iso_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;i<pktno;i++)
{
if(nvttst->iso_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;i<MaxTestSize+MaxOfs;i++)
{
txfbuf[i] = i%255;
}
rxfbuf = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf) {
printk("[%s]: rx no mem\n",__func__);
goto fail2;
}
rxfbuf2 = kmalloc(MaxTestSize+MaxOfs, GFP_KERNEL);
if(!rxfbuf2) {
printk("[%s]: rx2 no mem\n",__func__);
goto fail2;
}
memset(rxfbuf, 0xAA, MaxTestSize);
usb_nvttst_setup_uvc21(nvttst, rxfbuf, MaxPktSz, pktno,0,8);
memset(rxfbuf2, 0xAA, MaxTestSize);
usb_nvttst_setup_uvc22(nvttst, rxfbuf2, MaxPktSz, pktno,0,8);
ret = usb_nvttst_isouvc21_issue_urb_nonblocking(nvttst);
if(ret)
goto fail3;
timeout = jiffies + msecs_to_jiffies(2000);
while(1) {
//memset(rxfbuf2, 0xAA, MaxTestSize);
usb_nvttst_setup_uvc22(nvttst, rxfbuf2, MaxPktSz, pktno,0,8);
ret = usb_nvttst_isouvc22_issue_urb_nonblocking(nvttst);
if(ret)
goto fail3;
usb_nvttst_isouvc21_issue_urb_waitdone(nvttst);
// comapre 1
for(i=0;i<pktno;i++)
{
if(nvttst->iso_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;i<pktno;i++)
{
if(nvttst->iso_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);