linux driver problem

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • cq410
    New Member
    • Feb 2012
    • 1

    #1

    linux driver problem

    Code:
    #include <linux/module.h>
    
    #include <linux/kernel.h>
    
    #include <linux/delay.h>
    
    #include <linux/ioport.h>
    
    #include <linux/sched.h>
    
    #include <linux/slab.h>
    
    #include <linux/smp_lock.h>
    
    #include <linux/errno.h>
    
    #include <linux/init.h>
    
    #include <linux/timer.h>
    
    #include <linux/list.h>
    
    #include <linux/interrupt.h>
    
    #include <linux/utsname.h>
    
    #include <linux/device.h>
    
    #include <linux/moduleparam.h>
    
    #include <linux/fs.h>
    
    #include <linux/poll.h>
    
    #include <linux/types.h>
    
    #include <linux/ctype.h>
    
    #include <linux/cdev.h>
    
    
    
    #include <asm/byteorder.h>
    
    #include <linux/io.h>
    
    #include <linux/irq.h>
    
    #include <asm/system.h>
    
    #include <linux/uaccess.h>
    
    #include <asm/unaligned.h>
    
    
    
    #include <linux/usb/ch9.h>
    
    #include <linux/usb/gadget.h>
    
    #include "zebra_mouse.h"
    
    #include "gadget_chips.h"
    
    
    
    
    
    #include "usbstring.c"
    
    #include "config.c"
    
    #include "epautoconf.c"
    
    
    
    
    
    /*...........................................................*/
    
    
    
    
    
    
    
    #define DRIVER_DESC		"Zebra USB"
    
    #define DRIVER_VERSION		"2009.07.10"
    
    
    
    /*...........................................................*/
    
    
    
    static const char shortname [] = "zebra_usb";
    
    static const char driver_desc [] = DRIVER_DESC;
    
    
    
    
    
    
    
    
    
    
    
    
    
    /*...........................................................*/
    
    
    
    static dev_t zebra_mouse_devno;
    
    int is_connect = 0;
    
    static struct class *usb_gadget_class;
    
    
    
    
    
    /*...........................................................*/
    
    
    
    struct zebra_mouse_dev {
    
    	spinlock_t		lock;		/* lock this structure */
    
    	/* lock buffer lists during read/write calls */
    
    	spinlock_t		lock_zebra_mouse_io;
    
    	struct usb_gadget	*gadget;
    
    	struct usb_request	*req;		/* for control responses */
    
    	u8			config;
    
    	s8			interface;
    
    	struct usb_ep		*in_ep;
    
    	const struct usb_endpoint_descriptor *in;//œøÈëµÄ¶ËµãÃèÊö·û	
    
    
    
    	/* wait until there is data to be read. */
    
    	wait_queue_head_t	rx_wait;
    
    	struct list_head	tx_reqs;	/* List of free TX structs£¿£¿£¿£¿£¿£¿ */
    
    	struct list_head	tx_reqs_active; /* List of Active TX xfers £¿£¿£¿£¿£¿£¿*/
    
    	/* Wait until there are write buffers available to use. */
    
    	wait_queue_head_t	tx_wait;
    
    	/* Wait until all write buffers have been sent. */
    
    	wait_queue_head_t	tx_flush_wait;
    
    	struct usb_request	*current_rx_req;
    
    	size_t			current_rx_bytes;
    
    	u8			*current_rx_buf;
    
    	u8			zebra_mouse_status;
    
    	u8			reset_zebra_mouse;
    
    	struct cdev		zebra_mouse_cdev;//×Ö·ûÉ豞
    
    	struct device		*pdev;//?????
    
    	u8			zebra_mouse_cdev_open;//?????
    
    	wait_queue_head_t	wait;
    
    };
    
    
    
    static struct zebra_mouse_dev zebra_mouse;
    
    /*...........................................................*/
    
    #define QLEN	qlen
    
    
    
    #ifdef CONFIG_USB_GADGET_DUALSPEED
    
    #define DEVSPEED	USB_SPEED_HIGH
    
    #else   /* full speed (low speed doesn't do bulk) */
    
    #define DEVSPEED        USB_SPEED_FULL
    
    #endif
    
    
    
    /*-------------------------------------------------------------------------*/
    
    
    
    
    
    
    
    
    
    /*....................É豞ÃèÊö·û....................*/
    
    
    
    #define STRING_MANUFACTURER		1
    
    #define STRING_PRODUCT			2
    
    #define STRING_SERIALNUM		3
    
    
    
    
    
    #define PRINTER_VENDOR_NUM	0x0408		 ///¶àµãŽ¥ÃþÆÁµÄIDºÅ
    
    #define PRINTER_PRODUCT_NUM	0x3001	  ///¶àµãŽ¥ÃþÆÁµÄIDºÅ
    
    
    
    static struct usb_device_descriptor device_desc = {
    
    	.bLength =		0x12,
    
    	.bDescriptorType =	0x01,
    
    	.bcdUSB =		cpu_to_le16(0x0200),
    
    	.bDeviceClass =		0x00,
    
    	.bDeviceSubClass =	0x00,
    
    	.bDeviceProtocol =	0x00,
    
         .bMaxPacketSize0 =  0x40,
    
       //kljii
    
    	.idVendor =		cpu_to_le16(PRINTER_VENDOR_NUM),
    
    	.idProduct =		cpu_to_le16(PRINTER_PRODUCT_NUM),
    
    	.iManufacturer =	STRING_MANUFACTURER,
    
    	.iProduct =		STRING_PRODUCT,
    
    	.iSerialNumber =	STRING_SERIALNUM,
    
    	.bNumConfigurations =	1
    
    };
    
    
    
    
    
    /*......................ÅäÖÃÃèÊö·û....................*/
    
    static struct usb_config_descriptor config_desc = {
    
    	.bLength =		0x09,//sizeof config_desc,
    
    	.bDescriptorType =	0x02,//USB_DT_CONFIG£¿£¿£¿£¿£¿£¿£¿£¿£¿£¿£¿£¿0x01????
    
    	/* compute wTotalLength on the fly */
    
    	.wTotalLength = cpu_to_le16(sizeof(config_desc)),
    
    	.bNumInterfaces =	0x01,
    
    	.bConfigurationValue =	0x01,//DEV_CONFIG_VALUE,
    
    	.iConfiguration =	0x00,
    
    	.bmAttributes =		0x80,//USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
    
    	.bMaxPower =		0x32,//???????????????????
    
    };
    
    
    
    
    
    /*..................œÓ¿ÚÃèÊö·û.......................*/
    
    
    
    
    
    static struct usb_interface_descriptor intf_desc = {
    
    	.bLength =		0x09,
    
    	.bDescriptorType =	0x04,//USB_DT_INTERFACE,
    
    	.bInterfaceNumber =	0x00,//DEV_CONFIG_VALUE,£¿£¿£¿£¿£¿£¿£¿£¿£¿£¿£¿£¿£¿£¿£¿
    
    	.bNumEndpoints =	0x01,
    
    	.bInterfaceClass =	0x03,//USB_CLASS_HID,
    
    	.bInterfaceSubClass =	0x00,	/* Printer Sub-Class */
    
    	.bInterfaceProtocol =	0x00,	/* Bi-Directional */
    
    	.iInterface =		0x00
    
    };
    
    
    
    /*................¶ËµãÃèÊö·û...................*/
    
    
    
    static struct usb_endpoint_descriptor fs_ep_in_desc = {
    
    	.bLength =		USB_DT_ENDPOINT_SIZE,//0x07
    
    	.bDescriptorType =	USB_DT_ENDPOINT,//0x05
    
    	.bEndpointAddress =	USB_DIR_IN,    //0x80
    
    	.bmAttributes =		USB_ENDPOINT_XFER_INT,//0x03
    
    	.wMaxPacketSize =	__constant_cpu_to_le16(2),//Êó±êΪ008
    
    	.bInterval =		32,	// frames -> 32 msͬ²œŽ«ËͱØÐëΪ1 £¬Öжώ«ËÍΪ1-255
    
    };
    
     /*....................HIDÃèÊö·û....................*/
    
    static struct usb_hid_descriptor hid_desc = {
    
    	.bLength	= 0x09,
    
    	.bDescriptorType	= 0x21,
    
    	.bcdHID	=	cpu_to_le16(0x0110),//?????????????????HID°æ±ŸºÅ  0x101
    
    	.bCountyCode = 0x21,
    
    	.bNumDescriptors = 0x01,
    
    	.bSubDescriptorType = 0x22,
    
    	.bDescriptorLength = cpu_to_le16(sizeof(report_desc))
    
    };
    
    
    
    
    
    
    
    
    
      
    
     /*................±š±íÃèÊö·û..................*/
    
    u8 report_desc[] = 
    
    {
    
    	0x05,0x01,
    
    	0x09,0x02,
    
    	0xa1,0x01,
    
    	0x09,0x01,
    
    	0xa1,0x00,
    
    	0x05,0x09,
    
    	0x19,0x01,
    
    	0x29,0x03,
    
    	0x15,0x00,
    
    	0x25,0x01,
    
    	0x95,0x03,
    
    	0x75,0x01,
    
    	0x81,0x02,
    
    	0x95,0x01,
    
    	0x75,0x05,
    
    	0x81,0x01,
    
    	0x05,0x01,
    
    	0x09,0x30,
    
    	0x09,0x31,
    
    	0x09,0x38,
    
    	0x15,0x81,
    
    	0x25,0x7f,
    
    	0x75,0x08,
    
    	0x95,0x03,
    
    	0x81,0x06,
    
    	0xc0,0xc0
    
    };
    
    	
    
    /*....................otgÃèÊö·û........................*/
    
    static struct usb_otg_descriptor otg_descriptor = {
    
    	.bLength =		sizeof otg_descriptor,
    
    	.bDescriptorType =	USB_DT_OTG,
    
    	.bmAttributes =		USB_OTG_SRP | USB_OTG_HNP,
    
    };
    
    
    
    static const struct usb_descriptor_header *otg_desc[] = {
    
    	(struct usb_descriptor_header *) &otg_descriptor,
    
    	NULL,
    
    };
    
    
    
    
    
    /*.....................×Ö·ûŽ®ÃèÊö·û.................*/
    
    #define STRING_MANUFACTURER_IDX		0
    
    #define STRING_PRODUCT_IDX		1
    
    
    
    static char manufacturer[50];
    
    
    
    static struct usb_string strings_dev[] = {
    
    	[STRING_MANUFACTURER_IDX].s = manufacturer,
    
    	[STRING_PRODUCT_IDX].s = DRIVER_DESC,
    
    	{  } /* end of list */
    
    };
    
    
    
    static struct usb_gadget_strings stringtab_dev = {
    
    	.language	= 0x0409,	/* en-us */
    
    	.strings	= strings_dev,
    
    };
    
    
    
    static struct usb_gadget_strings *dev_strings[] = {
    
    	&stringtab_dev,
    
    	NULL,
    
    };
    
    /*................ËùÓеÄÃèÊö·û¶ŒÒª¶šÒåÕâžöœá¹¹...................*/
    
    
    
    
    
    
    
    static const struct usb_descriptor_header *fs_zebra_mouse_function [11] = {
    
    	(struct usb_descriptor_header *) &config_desc, //add 
    
    	(struct usb_descriptor_header *) &intf_desc,
    
    	(struct usb_descriptor_header *) &hid_desc,
    
    	(struct usb_descriptor_header *) &fs_ep_in_desc,//////
    
    	NULL
    
    };
    
    
    
    
    
    
    
    /*...............ÈçºÎ¶šÒåÁËDUALSPEED.........................*/
    
    
    
    
    
    
    
    #ifdef	CONFIG_USB_GADGET_DUALSPEED
    
    
    
    /*
    
     * usb 2.0 devices need to expose both high speed and full speed
    
     * descriptors, unless they only run at full speed.
    
     */
    
    
    
    static struct usb_endpoint_descriptor hs_ep_in_desc = {
    
    	.bLength =		USB_DT_ENDPOINT_SIZE,
    
    	.bDescriptorType =	USB_DT_ENDPOINT,
    
    	.bmAttributes =		USB_ENDPOINT_XFER_INT,
    
    	.wMaxPacketSize =	__constant_cpu_to_le16(2),
    
    	.bInterval =		9,	// 2**(9-1) = 256 uframes -> 32 ms
    
    };
    
    
    
    static struct usb_qualifier_descriptor dev_qualifier = {
    
    	.bLength =		sizeof dev_qualifier,
    
    	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
    
    	.bcdUSB =		cpu_to_le16(0x0200),
    
    	.bDeviceClass =		USB_CLASS_PRINTER,
    
    	.bNumConfigurations =	1
    
    };
    
    
    
    static const struct usb_descriptor_header *hs_zebra_mouse_function [11] = {
    
    	(struct usb_descriptor_header *) &otg_desc,
    
    	(struct usb_descriptor_header *) &intf_desc,
    
    	(struct usb_descriptor_header *) &hs_ep_in_desc,
    
    	NULL
    
    };
    
    
    
    /* maxpacket and other transfer characteristics vary by speed. */
    
    #define ep_desc(g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs))
    
    
    
    #else
    
    
    
    /* if there's no high speed support, maxpacket doesn't change. */
    
    #define ep_desc(g, hs, fs) (((void)(g)), (fs))
    
    
    
    #endif	/* !CONFIG_USB_GADGET_DUALSPEED */
    
    
    
    
    
    
    
    
    
    
    
    /*-------------------------------------------------------------------------*/
    
    
    
    static struct usb_request * zebra_mouse_req_alloc(struct usb_ep *ep, unsigned len, gfp_t gfp_flags)
    
    {
    
    	struct usb_request	*req;
    
    
    
    	req = usb_ep_alloc_request(ep, gfp_flags);
    
    
    
    	if (req != NULL) {
    
    		req->length = len;
    
    		req->buf = kmalloc(len, gfp_flags);
    
    		if (req->buf == NULL) {
    
    			usb_ep_free_request(ep, req);
    
    			return NULL;
    
    		}
    
    	}
    
    
    
    	return req;
    
    }
    
    
    
    static void zebra_mouse_req_free(struct usb_ep *ep, struct usb_request *req)
    
    {
    
    	if (ep != NULL && req != NULL) {
    
    		kfree(req->buf);
    
    		usb_ep_free_request(ep, req);
    
    	}
    
    }
    
    
    
    static void tx_complete(struct usb_ep *ep, struct usb_request *req)
    
    {
    
    	struct zebra_mouse_dev	*dev = ep->driver_data;
    
    
    
    	switch (req->status) {
    
    	default:
    
    		printk("cichu");
    
    //VDBG(dev, "tx err %d\n", req->status);
    
    		/* FALLTHROUGH */
    
    	case -ECONNRESET:		/* unlink */
    
    	case -ESHUTDOWN:		/* disconnect etc */
    
    		break;
    
    	case 0:
    
    		break;
    
    	}
    
    
    
    	spin_lock(&dev->lock);
    
    	/* Take the request struct off the active list and put it on the
    
    	 * free list.
    
    	 */
    
    	list_del_init(&req->list);
    
    	list_add(&req->list, &dev->tx_reqs);
    
    	wake_up_interruptible(&dev->tx_wait);
    
    	if (likely(list_empty(&dev->tx_reqs_active)))
    
    		wake_up_interruptible(&dev->tx_flush_wait);
    
    
    
    	spin_unlock(&dev->lock);
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    /*...........................................................*/
    
    
    
    static int zebra_mouse_open(struct inode *inode, struct file *fd)
    
    {
    
    	struct zebra_mouse_dev	*dev;
    
    	unsigned long		flags;
    
    	int			ret = -EBUSY;
    
    
    
    	lock_kernel();
    
    	dev = container_of(inode->i_cdev, struct zebra_mouse_dev, zebra_mouse_cdev);
    
    
    
    	spin_lock_irqsave(&dev->lock, flags);
    
    
    
    	if (!dev->zebra_mouse_cdev_open) {
    
    		dev->zebra_mouse_cdev_open = 1;
    
    		fd->private_data = dev;
    
    		ret = 0;
    
    		/* Change the zebra_mouse status to show that it's on-line. */
    
    		dev->zebra_mouse_status |= ZEBRA_MOUSE_SELECTED;
    
    	}
    
    
    
    	spin_unlock_irqrestore(&dev->lock, flags);
    
    
    
    //BG(dev, "zebra_mouse_open returned %x\n", ret);
    
    	unlock_kernel();
    
    	return ret;
    
    }
    
    
    
    static int
    
    zebra_mouse_close(struct inode *inode, struct file *fd)
    
    {
    
    	struct zebra_mouse_dev	*dev = fd->private_data;
    
    	unsigned long		flags;
    
    
    
    	spin_lock_irqsave(&dev->lock, flags);
    
    	dev->zebra_mouse_cdev_open = 0;
    
    	fd->private_data = NULL;
    
    	/* Change zebra_mouse status to show that the zebra_mouse is off-line. */
    
    	dev->zebra_mouse_status &= ~ZEBRA_MOUSE_SELECTED;
    
    	spin_unlock_irqrestore(&dev->lock, flags);
    
    
    
    //BG(dev, "zebra_mouse_close\n");
    
    	printk( "zebra_mouse_close\n");
    
      	
    
    	return 0;
    
    }
    
    
    
    
    
    
    
    
    
    /*...........................................................*/
    
    
    
    static ssize_t zebra_mouse_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
    
    {
    
    	struct zebra_mouse_dev	*dev = fd->private_data;
    
    	unsigned long		flags;
    
    	size_t			size;	/* Amount of data in a TX request. */
    
    	size_t			bytes_copied = 0;
    
    	struct usb_request	*req;
    
    
    
    	if (!is_connect)
    
    	{
    
    		printk("USB is not connected!\n");
    
    		return -EINVAL;
    
    	} 
    
    	printk("zebra_mouse_write trying to send %d bytes\n", (int)len);
    
    
    
    	if (len == 0)
    
    		return -EINVAL;
    
    
    
    	spin_lock(&dev->lock_zebra_mouse_io);
    
    	spin_lock_irqsave(&dev->lock, flags);
    
    
    
    	/* Check if a zebra_mouse reset happens while we have interrupts on */
    
    	dev->reset_zebra_mouse = 0;
    
    
    
    
    
    	/* Check if there is any available write buffers */
    
    	if (likely(list_empty(&dev->tx_reqs))) {
    
    		/* Turn interrupts back on before sleeping. */
    
    		spin_unlock_irqrestore(&dev->lock, flags);
    
    
    
    		/*
    
    		 * If write buffers are available check if this is
    
    		 * a NON-Blocking call or not.
    
    		 */
    
    		if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) {
    
    			spin_unlock(&dev->lock_zebra_mouse_io);
    
    			return -EAGAIN;
    
    		}
    
    
    
    		/* Sleep until a write buffer is available */
    
    		wait_event_interruptible(dev->tx_wait,
    
    				(likely(!list_empty(&dev->tx_reqs))));
    
    		spin_lock_irqsave(&dev->lock, flags);
    
    	}
    
    
    
    	while (likely(!list_empty(&dev->tx_reqs)) && len) {
    
    
    
    		if (len > USB_BUFSIZE)
    
    			size = USB_BUFSIZE;
    
    		else
    
    			size = len;
    
    
    
    		req = container_of(dev->tx_reqs.next, struct usb_request,
    
    				list);
    
    		list_del_init(&req->list);
    
    
    
    		req->complete = tx_complete;
    
    		req->length = size;
    
    
    
    
    
    		/* Check if we need to send a zero length packet. */
    
    		if (len > size)
    
    			/* They will be more TX requests so no yet. */
    
    			req->zero = 0;
    
    		else
    
    			/* If the data amount is not a multple of the
    
    			 * maxpacket size then send a zero length packet.
    
    			 */
    
    			req->zero = ((len % dev->in_ep->maxpacket) == 0);
    
    
    
    		/* Don't leave irqs off while doing memory copies */
    
    		spin_unlock_irqrestore(&dev->lock, flags);
    
    
    
    		if (copy_from_user(req->buf, buf, size)) {
    
    			list_add(&req->list, &dev->tx_reqs);
    
    			spin_unlock(&dev->lock_zebra_mouse_io);
    
    			return bytes_copied;
    
    		}
    
    
    
    		bytes_copied += size;
    
    		len -= size;
    
    		buf += size;
    
    
    
    		spin_lock_irqsave(&dev->lock, flags);
    
    
    
    		/* We've disconnected or reset so free the req and buffer */
    
    		if (dev->reset_zebra_mouse) {
    
    			list_add(&req->list, &dev->tx_reqs);
    
    			spin_unlock_irqrestore(&dev->lock, flags);
    
    			spin_unlock(&dev->lock_zebra_mouse_io);
    
    			return -EAGAIN;
    
    		}
    
    
    
    		if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) {
    
    			list_add(&req->list, &dev->tx_reqs);
    
    			spin_unlock_irqrestore(&dev->lock, flags);
    
    			spin_unlock(&dev->lock_zebra_mouse_io);
    
    			return -EAGAIN;
    
    		}
    
    
    
    		list_add(&req->list, &dev->tx_reqs_active);
    
    
    
    	}
    
    
    
    
    
    	spin_unlock_irqrestore(&dev->lock, flags);
    
    	spin_unlock(&dev->lock_zebra_mouse_io);
    
    
    
    //BG(dev, "zebra_mouse_write sent %d bytes\n", (int)bytes_copied);
    
    
    
    	if (bytes_copied) {
    
    		return bytes_copied;
    
    	} else {
    
    		return -EAGAIN;
    
    	}
    
    	
    
    }
    
    
    
    /*...........................................................*/
    
    
    
    static int zebra_mouse_fsync(struct file *fd, struct dentry *dentry, int datasync)
    
    {
    
    	struct zebra_mouse_dev	*dev = fd->private_data;
    
    	unsigned long		flags;
    
    	int			tx_list_empty;
    
    	
    
    
    
    
    
    	spin_lock_irqsave(&dev->lock, flags);
    
    	tx_list_empty = (likely(list_empty(&dev->tx_reqs)));
    
    	spin_unlock_irqrestore(&dev->lock, flags);
    
    
    
    	if (!tx_list_empty) {
    
    		/* Sleep until all data has been sent */
    
    		printk("Sleep until all data has been sent!\n");
    
    		wait_event_interruptible(dev->tx_flush_wait,
    
    				(likely(list_empty(&dev->tx_reqs_active))));
    
    	}
    
    	
    
    
    
    	
    
    	return 0;
    
    }
    
    
    
    static unsigned int zebra_mouse_poll(struct file *fd, poll_table *wait)
    
    {
    
    	struct zebra_mouse_dev	*dev = fd->private_data;
    
    	unsigned long		flags;
    
    	int			status = 0;
    
    
    
    
    
    	spin_lock(&dev->lock_zebra_mouse_io);
    
    	spin_lock_irqsave(&dev->lock, flags);
    
    	
    
    	spin_unlock_irqrestore(&dev->lock, flags);
    
    	spin_unlock(&dev->lock_zebra_mouse_io);
    
    
    
    	poll_wait(fd, &dev->rx_wait, wait);
    
    	poll_wait(fd, &dev->tx_wait, wait);
    
    
    
    	spin_lock_irqsave(&dev->lock, flags);
    
    	if (likely(!list_empty(&dev->tx_reqs)))
    
    		status |= POLLOUT | POLLWRNORM;
    
    
    
    	spin_unlock_irqrestore(&dev->lock, flags);
    
    	
    
    	
    
    	return status;
    
    }
    
    
    
    
    
    /* used after endpoint configuration */
    
    static struct file_operations zebra_mouse_io_operations = {
    
    	.owner =	THIS_MODULE,
    
    	.open =		zebra_mouse_open,
    
    	//.read =		zebra_mouse_read,
    
    	.write =	zebra_mouse_write,
    
    	.fsync =	zebra_mouse_fsync,
    
    	.poll =		zebra_mouse_poll,
    
    	///.unlocked_ioctl = zebra_mouse_ioctl,
    
    	.release =	zebra_mouse_close
    
    };
    
    
    
    
    
    /*...........................................................*/
    
    static int set_zebra_mouse_interface(struct zebra_mouse_dev *dev)
    
    {
    
    	int			result = 0;
    
    	
    
    
    
    	dev->in = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc);
    
    	dev->in_ep->driver_data = dev;
    
    	
    
    	result = usb_ep_enable(dev->in_ep, dev->in);
    
    	if (result != 0) {
    
    //		DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result);
    
    		goto done;
    
    	}
    
    
    
    done:
    
    	/* on error, disable any endpoints  */
    
    	if (result != 0) {
    
    		(void) usb_ep_disable(dev->in_ep);		
    
    		dev->in = NULL;		
    
    	}
    
    	
    
    	
    
    	/* caller is responsible for cleanup on error */
    
    	return result;
    
    }
    
    /*...........................................................*/
    
    static void zebra_mouse_reset_interface(struct zebra_mouse_dev *dev)
    
    {
    
    	if (dev->interface < 0)
    
    		return;
    
    
    
    	
    
    //	DBG(dev, "%s\n", __func__);
    
    
    
    	if (dev->in)
    
    		usb_ep_disable(dev->in_ep);	
    
    
    
    	dev->interface = -1;
    
    	
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    /*...........................................................*/
    
    static int zebra_mouse_set_config(struct zebra_mouse_dev *dev, unsigned number)
    
    {
    
    	int			result = 0;
    
    	struct usb_gadget	*gadget = dev->gadget;
    
    	
    
    	if (gadget_is_sa1100(gadget) && dev->config) {
    
    		/* tx fifo is full, but we can't clear it...*/
    
    //		INFO(dev, "can't change configurations\n");
    
    		return -ESPIPE;
    
    	}
    
    
    
    	switch (number) {
    
    	case DEV_CONFIG_VALUE:
    
    		result = 0;
    
    		break;
    
    	default:
    
    		result = -EINVAL;
    
    		/* FALL THROUGH */
    
    	case 0:
    
    		break;
    
    	}
    
    
    
    	if (result) {
    
    		usb_gadget_vbus_draw(dev->gadget,
    
    				dev->gadget->is_otg ? 8 : 100);
    
    	} else {
    
    		char *speed;
    
    		unsigned power;
    
    
    
    		power = 2 * config_desc.bMaxPower;
    
    		usb_gadget_vbus_draw(dev->gadget, power);
    
    
    
    		switch (gadget->speed) {
    
    		case USB_SPEED_FULL:	speed = "full"; break;
    
    #ifdef CONFIG_USB_GADGET_DUALSPEED
    
    		case USB_SPEED_HIGH:	speed = "high"; break;
    
    #endif
    
    		default:		speed = "?"; break;
    
    		}
    
    
    
    		dev->config = number;
    
    //		INFO(dev, "%s speed config #%d: %d mA, %s\n",
    
    		//		speed, number, power, driver_desc);
    
    	}
    
    	
    
    	set_zebra_mouse_interface(dev);
    
    	
    
    	
    
    	return result;
    
    }
    
    
    
    /*...........................................................*/
    
    
    
    
    
    static int config_buf(enum usb_device_speed speed, u8 *buf, u8 type, unsigned index,
    
    		int is_otg)
    
    {
    
    	int					len;
    
    	const struct usb_descriptor_header	**function;
    
    #ifdef CONFIG_USB_GADGET_DUALSPEED
    
    	int					hs = (speed == USB_SPEED_HIGH);
    
    	
    
    	
    
    	if (type == USB_DT_OTHER_SPEED_CONFIG)
    
    		hs = !hs;
    
    
    
    	if (hs) {
    
    		function = hs_zebra_mouse_function;
    
    	} else {
    
    		function = fs_zebra_mouse_function;
    
    	}
    
    #else
    
    	function = fs_zebra_mouse_function;
    
    #endif
    
    
    
    	if (index >= device_desc.bNumConfigurations)
    
    		return -EINVAL;
    
    
    
    	/* for now, don't advertise srp-only devices */
    
    	if (!is_otg)
    
    		function++;
    
    
    
    //int usb_gadget_config_buf(const struct usb_config_descriptor *config,
    
    //	void *buf, unsigned buflen, const struct usb_descriptor_header **desc);
    
    
    
    	len = usb_gadget_config_buf(&config_desc, buf, USB_DESC_BUFSIZE,
    
    			function);
    
    	if (len < 0)
    
    		return len;
    
    	((struct usb_config_descriptor *) buf)->bDescriptorType = type;
    
    	
    
    	
    
    	return len;
    
    }
    
    
    
    /* Change our operational Interface. */
    
    static int
    
    set_interface(struct zebra_mouse_dev *dev, unsigned number)
    
    {
    
    	int			result = 0;
    
    	
    
    	
    
    	if (gadget_is_sa1100(dev->gadget) && dev->interface < 0) {
    
    		/* tx fifo is full, but we can't clear it...*/
    
    //		INFO(dev, "can't change interfaces\n");
    
    		return -ESPIPE;
    
    	}
    
    
    
    	/* Free the current interface */
    
    	switch (dev->interface) {
    
    	case ZEBRA_MOUSE_INTERFACE:
    
    		zebra_mouse_reset_interface(dev);
    
    		break;
    
    	}
    
    
    
    	switch (number) {
    
    	case ZEBRA_MOUSE_INTERFACE:
    
    		result = set_zebra_mouse_interface(dev);
    
    		if (result) {
    
    			zebra_mouse_reset_interface(dev);
    
    		} else {
    
    			dev->interface = ZEBRA_MOUSE_INTERFACE;
    
    		}
    
    		break;
    
    	default:
    
    		result = -EINVAL;
    
    		/* FALL THROUGH */
    
    	}
    
    
    
    	if (!result)
    
    	return result;
    
    //		INFO(dev, "Using interface %x\n", number);
    
    		
    
    
    
    	return result;
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    /*...........................................................*/
    
    
    
    static void zebra_mouse_setup_complete(struct usb_ep *ep, struct usb_request *req)
    
    {
    
    	
    
    	if (req->status || req->actual != req->length)
    
    		printk("do nothing");
    
    	//DBG((struct PRINTER_INTERFACE_dev *) ep->driver_data,
    
    				//"setup complete --> %d, %d/%d\n",
    
    				//req->status, req->actual, req->length);
    
    							
    
    }
    
    /*...........................................................*/
    
    static void zebra_mouse_soft_reset(struct zebra_mouse_dev *dev)
    
    {
    
    	struct usb_request	*req;
    
    	
    
    	
    
    //	INFO(dev, "Received zebra_mouse Reset Request\n");
    
    
    
    	if (usb_ep_disable(dev->in_ep))
    
    	printk("do nothing");
    
    		//DBG(dev, "Failed to disable USB in_ep\n");
    
    	
    
    	
    
    	dev->reset_zebra_mouse = 1;
    
    
    
    	while (likely(!(list_empty(&dev->tx_reqs_active)))) {
    
    		req = container_of(dev->tx_reqs_active.next,
    
    				struct usb_request, list);
    
    		list_del_init(&req->list);
    
    		list_add(&req->list, &dev->tx_reqs);
    
    	}
    
    
    
    	if (usb_ep_enable(dev->in_ep, dev->in))
    
    	printk("do nothing");
    
    		//DBG(dev, "Failed to enable USB in_ep\n");
    
    	
    
    	wake_up_interruptible(&dev->rx_wait);
    
    	wake_up_interruptible(&dev->tx_wait);
    
    	wake_up_interruptible(&dev->tx_flush_wait);
    
    	
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    /*...........................................................*/
    
    
    
    static int zebra_mouse_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
    
    {
    
    
    
    	struct zebra_mouse_dev	*dev = get_gadget_data(gadget);
    
    	struct usb_request	*req = dev->req;
    
    	int			value = -EOPNOTSUPP;
    
    	u16			wIndex = le16_to_cpu(ctrl->wIndex);
    
    	u16			wValue = le16_to_cpu(ctrl->wValue);
    
    	u16			wLength = le16_to_cpu(ctrl->wLength);
    
    	
    
    
    
    //	DBG(dev, "ctrl req%02x.%02x v%04x i%04x l%d\n",
    
    	//	ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength);
    
    //  printk("ctrl req%02x.%02x v%04x i%04x l%04x\n",
    
    //		ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength);
    
    		
    
    	req->complete = zebra_mouse_setup_complete;
    
    
    
    	switch (ctrl->bRequestType&USB_TYPE_MASK) {
    
    
    
    	case USB_TYPE_STANDARD:
    
    //		printk("USB_TYPE_STANDARD\n");
    
    		switch (ctrl->bRequest) {
    
    		case USB_REQ_GET_DESCRIPTOR:
    
    //			printk("USB_REQ_GET_DESCRIPTOR\n");
    
    			if (ctrl->bRequestType != USB_DIR_IN)
    
    				{
    
    					value = min(wLength, (u16) sizeof report_desc);
    
    //					printk("ctrl->bRequestType != USB_DIR_IN\n");
    
    					memcpy(req->buf, &report_desc, (u16)sizeof report_desc);
    
    					break;
    
    				}
    
    			switch (wValue >> 8) {
    
    	
    
    			case USB_DT_DEVICE:
    
    //				printk("USB_DT_DEVICE\n");
    
    				value = min(wLength, (u16) sizeof device_desc);
    
    //				printk("wLength %d,sizeof(device_desc) %d,value %d\n",wLength,(u16) sizeof device_desc,value);
    
    				memcpy(req->buf, &device_desc, value);
    
    				break;
    
    
    
    			case USB_DT_CONFIG:
    
    //				printk("USB_DT_CONFIG\n");
    
    //				printk("wValue is %d\n",wValue);
    
    				value = config_buf(gadget->speed, req->buf,
    
    						wValue >> 8,
    
    						wValue & 0xff,
    
    						gadget->is_otg);
    
    				if (value >= 0)
    
    					value = min(wLength, (u16) value);
    
    //				printk("value %d\n",value);
    
    				break;
    
    
    
    			case USB_DT_STRING:
    
    //				printk("USB_DT_STRING\n");
    
    				value = usb_gadget_get_string(&stringtab,
    
    						wValue & 0xff, req->buf);
    
    				if (value >= 0)
    
    					value = min(wLength, (u16) value);
    
    //				printk("value %d\n",value);
    
    				break;
    
    			}
    
    			break;
    
    		case USB_REQ_SET_CONFIGURATION:
    
    //			printk("USB_REQ_SET_CONFIGURATION\n");
    
    			if (ctrl->bRequestType != 0)
    
    				break;
    
    			if (gadget->a_hnp_support)
    
    	printk("do nothing");
    
    			//	DBG(dev, "HNP available\n");
    
    			else if (gadget->a_alt_hnp_support)	
    
    				printk("do nothing");
    
    			//	DBG(dev, "HNP needs a different root port\n");
    
    			value = zebra_mouse_set_config(dev, wValue);
    
    			break;
    
    		case USB_REQ_GET_CONFIGURATION:
    
    //			printk("USB_REQ_GET_CONFIGURATION\n");
    
    			if (ctrl->bRequestType != USB_DIR_IN)
    
    				break;
    
    			*(u8 *)req->buf = dev->config;
    
    			value = min(wLength, (u16) 1);
    
    			break;
    
    
    
    		case USB_REQ_SET_INTERFACE:
    
    //			printk("USB_REQ_SET_INTERFACE\n");
    
    			if (ctrl->bRequestType != USB_RECIP_INTERFACE ||
    
    					!dev->config)
    
    				break;
    
    
    
    			value = set_interface(dev, ZEBRA_MOUSE_INTERFACE);
    
    			break;
    
    		case USB_REQ_GET_INTERFACE:
    
    //			printk("USB_REQ_GET_INTERFACE\n");
    
    			if (ctrl->bRequestType !=
    
    					(USB_DIR_IN|USB_RECIP_INTERFACE)
    
    					|| !dev->config)
    
    				break;
    
    
    
    			*(u8 *)req->buf = dev->interface;
    
    			value = min(wLength, (u16) 1);
    
    			break;
    
    
    
    		default:
    
    //			printk("unknown ---------------\n");
    
    			goto unknown;
    
    		}
    
    		break;
    
    
    
    	case USB_TYPE_CLASS:
    
    //		printk("USB_TYPE_CLASS\n");
    
    		switch (ctrl->bRequest) {
    
    		case 0: /* Get the IEEE-1284 PNP String */
    
    			/* Only one zebra_mouse interface is supported. */
    
    //			printk("USB_TYPE_CLASS 0 ---------------\n");
    
    			if ((wIndex>>8) != ZEBRA_MOUSE_INTERFACE)
    
    				break;
    
    
    
    			value = (pnp_string[0]<<8)|pnp_string[1];
    
    			memcpy(req->buf, pnp_string, value);
    
    		//	DBG(dev, "1284 PNP String: %x %s\n", value,
    
    		//			&pnp_string[2]);
    
    			break;
    
    
    
    		case 1: /* Get Port Status */
    
    			/* Only one zebra_mouse interface is supported. */
    
    //			printk("USB_TYPE_CLASS 1 ---------------\n");				
    
    			if (wIndex != ZEBRA_MOUSE_INTERFACE)
    
    				break;
    
    
    
    			*(u8 *)req->buf = dev->zebra_mouse_status;
    
    			value = min(wLength, (u16) 1);
    
    			break;
    
    
    
    		case 2: /* Soft Reset */
    
    			/* Only one zebra_mouse interface is supported. */
    
    //			printk("USB_TYPE_CLASS 2 ---------------\n");
    
    			if (wIndex != ZEBRA_MOUSE_INTERFACE)
    
    				break;
    
    
    
    			zebra_mouse_soft_reset(dev);
    
    
    
    			value = 0;
    
    			break;
    
    
    
    		default:
    
    			goto unknown;
    
    		}
    
    		break;
    
    
    
    	default:
    
    unknown:
    
    			printk("do nothing");
    
    		//VDBG(dev,
    
    			//"unknown ctrl req%02x.%02x v%04x i%04x l%d\n",
    
    		//	ctrl->bRequestType, ctrl->bRequest,
    
    		//	wValue, wIndex, wLength);
    
    //		printk("unknown ctrl req%02x.%02x v%04x i%04x l%d\n",
    
    //			ctrl->bRequestType, ctrl->bRequest,
    
    //			wValue, wIndex, wLength);
    
    		break;
    
    	}
    
    
    
    	/* respond with data transfer before status phase? */
    
    	if (value >= 0) {
    
    		req->length = value;
    
    		req->zero = value < wLength;
    
    		value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
    
    		if (value < 0) {
    
    	//		DBG(dev, "ep_queue --> %d\n", value);
    
    			req->status = 0;
    
    			zebra_mouse_setup_complete(gadget->ep0, req);
    
    		}
    
    	}
    
    	
    
    	printk("zebra_mouse_setup end---------------\n");
    
    	is_connect = 1;
    
    	/* host either stalls (value < 0) or reports success */
    
    	return value;
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    /*...........................................................*/
    
    static void zebra_mouse_disconnect(struct usb_gadget *gadget)
    
    {
    
    	struct zebra_mouse_dev	*dev = get_gadget_data(gadget);
    
    	unsigned long		flags;
    
    	
    
    	printk("zebra_mouse_disconnect begin---------------\n");
    
    
    
    //	DBG(dev, "%s\n", __func__);
    
    
    
    	spin_lock_irqsave(&dev->lock, flags);
    
    
    
    	zebra_mouse_reset_interface(dev);
    
    
    
    	spin_unlock_irqrestore(&dev->lock, flags);
    
    	
    
    	is_connect = 0;
    
    //	printk("zebra_mouse_disconnect end---------------\n");
    
    }
    
    
    
    
    
    /*...........................................................*/
    
    
    
    static void zebra_mouse_unbind(struct usb_gadget *gadget)
    
    {
    
    	printk("zebra_mouse_unbind begin---------------\n");
    
    	
    
    	struct zebra_mouse_dev	*dev = get_gadget_data(gadget);
    
    	struct usb_request	*req;
    
    
    
    //	DBG(dev, "%s\n", __func__);
    
    
    
    	/* Remove sysfs files */
    
    	device_destroy(usb_gadget_class, zebra_mouse_devno);
    
    
    
    	/* Remove Character Device */
    
    	cdev_del(&dev->zebra_mouse_cdev);
    
    
    
    	/* we must already have been disconnected ... no i/o may be active */
    
    	WARN_ON(!list_empty(&dev->tx_reqs_active));
    
    
    
    	/* Free all memory for this driver. */
    
    	while (!list_empty(&dev->tx_reqs)) {
    
    		req = container_of(dev->tx_reqs.next, struct usb_request,
    
    				list);
    
    		list_del(&req->list);
    
    		zebra_mouse_req_free(dev->in_ep, req);
    
    	}
    
    
    
    	if (dev->req) {
    
    		zebra_mouse_req_free(gadget->ep0, dev->req);
    
    		dev->req = NULL;
    
    	}
    
    
    
    	set_gadget_data(gadget, NULL);
    
    	
    
    //	printk("zebra_mouse_unbind end---------------\n");
    
    }
    
    
    
    /*...........................................................*/
    
    
    
    
    
    static int __init zebra_mouse_bind(struct usb_gadget *gadget)
    
    {
    
    	printk("zebra_mouse_bind begin---------------\n");
    
    	
    
    	struct zebra_mouse_dev	*dev;
    
    	struct usb_ep		*in_ep;
    
    	int			status = -ENOMEM;
    
    	int			gcnum;
    
    	size_t			len;
    
    	u32			i;
    
    	struct usb_request	*req;
    
    
    
    	dev = &zebra_mouse;
    
    
    
    
    
    	/* Setup the sysfs files for the zebra_mouse gadget. */
    
    	dev->pdev = device_create(usb_gadget_class, NULL, zebra_mouse_devno, shortname);
    
    				  
    
    	if (IS_ERR(dev->pdev)) {
    
    	//E  R(dev, "Failed to create device: zebra_mouse\n");
    
    		goto fail;
    
    	}
    
    
    
    	/*
    
    	 * Register a character device as an interface to a user mode
    
    	 * program that handles the zebra_mouse specific functionality.
    
    	 */
    
    	cdev_init(&dev->zebra_mouse_cdev, &zebra_mouse_io_operations);
    
    	dev->zebra_mouse_cdev.owner = THIS_MODULE;
    
    	status = cdev_add(&dev->zebra_mouse_cdev, zebra_mouse_devno, 1);
    
    	if (status) {
    
    	//RROR(dev, "Failed to open char device\n");
    
    		goto fail;
    
    	}
    
    
    
    	if (gadget_is_sa1100(gadget)) {
    
    		/* hardware can't write zero length packets. */
    
    // RROR(dev, "SA1100 controller is unsupport by this driver\n");
    
    		goto fail;
    
    	}
    
    
    
    	gcnum = usb_gadget_controller_number(gadget);
    
    	if (gcnum >= 0) {
    
    		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
    
    	} else {
    
    		dev_warn(&gadget->dev, "controller '%s' not recognized\n",
    
    			gadget->name);
    
    		/* unrecognized, but safe unless bulk is REALLY quirky */
    
    		device_desc.bcdDevice =
    
    			cpu_to_le16(0xFFFF);
    
    	}
    
    	snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
    
    		init_utsname()->sysname, init_utsname()->release,
    
    		gadget->name);
    
    
    
    	device_desc.idVendor =
    
    		cpu_to_le16(PRINTER_VENDOR_NUM);
    
    	device_desc.idProduct =
    
    		cpu_to_le16(PRINTER_PRODUCT_NUM);
    
    
    
    	/* support optional vendor/distro customization */
    
    	if (idVendor) {
    
    		if (!idProduct) {
    
    			dev_err(&gadget->dev, "idVendor needs idProduct!\n");
    
    			return -ENODEV;
    
    		}
    
    		device_desc.idVendor = cpu_to_le16(idVendor);
    
    		device_desc.idProduct = cpu_to_le16(idProduct);
    
    		if (bcdDevice)
    
    			device_desc.bcdDevice = cpu_to_le16(bcdDevice);
    
    	}
    
    
    
    	if (iManufacturer)
    
    		strlcpy(manufacturer, iManufacturer, sizeof manufacturer);
    
    
    
    	if (iProduct)
    
    		strlcpy(product_desc, iProduct, sizeof product_desc);
    
    
    
    	if (iSerialNum)
    
    		strlcpy(serial_num, iSerialNum, sizeof serial_num);
    
    
    
    	if (iPNPstring)
    
    		strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2);
    
    
    
    	len = strlen(pnp_string);
    
    	pnp_string[0] = (len >> 8) & 0xFF;
    
    	pnp_string[1] = len & 0xFF;
    
    
    
    	/* all we really need is bulk IN/OUT */
    
    	usb_ep_autoconfig_reset(gadget);
    
    	in_ep = usb_ep_autoconfig(gadget, &fs_ep_in_desc);
    
    	if (!in_ep) {
    
    		dev_err(&gadget->dev, "can't autoconfigure on %s\n",
    
    			gadget->name);
    
    		return -ENODEV;
    
    	}
    
    	in_ep->driver_data = in_ep;	/* claim */
    
    
    
    #ifdef	CONFIG_USB_GADGET_DUALSPEED
    
    	/* assumes ep0 uses the same value for both speeds ... */
    
    	dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
    
    
    
    	/* and that all endpoints are dual-speed */
    
    	hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
    
    	hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
    
    #endif	/* DUALSPEED */
    
    
    
    	device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
    
    	usb_gadget_set_selfpowered(gadget);
    
    
    
    	//if (gadget->is_otg) {
    
    	//	otg_desc.bmAttributes |= USB_OTG_HNP,
    
    	//	config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
    
    	//}
    
    
    
    	spin_lock_init(&dev->lock);
    
    	spin_lock_init(&dev->lock_zebra_mouse_io);
    
    	INIT_LIST_HEAD(&dev->tx_reqs);
    
    	INIT_LIST_HEAD(&dev->tx_reqs_active);
    
    	init_waitqueue_head(&dev->tx_wait);
    
    	init_waitqueue_head(&dev->tx_flush_wait);
    
    
    
    	dev->config = 0;
    
    	dev->interface = -1;
    
    	dev->zebra_mouse_cdev_open = 0;
    
    	dev->zebra_mouse_status = ZEBRA_MOUSE_NOT_ERROR;
    
    	dev->current_rx_req = NULL;
    
    	dev->current_rx_bytes = 0;
    
    	dev->current_rx_buf = NULL;
    
    
    
    	dev->in_ep = in_ep;
    
    	
    
    	/* preallocate control message data and buffer */
    
    	dev->req = zebra_mouse_req_alloc(gadget->ep0, USB_DESC_BUFSIZE,
    
    			GFP_KERNEL);
    
    	if (!dev->req) {
    
    		status = -ENOMEM;
    
    		goto fail;
    
    	}
    
    
    
    	for (i = 0; i < QLEN; i++) {
    
    		req = zebra_mouse_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL);
    
    		if (!req) {
    
    			while (!list_empty(&dev->tx_reqs)) {
    
    				req = container_of(dev->tx_reqs.next,
    
    						struct usb_request, list);
    
    				list_del(&req->list);
    
    				zebra_mouse_req_free(dev->in_ep, req);
    
    			}
    
    			return -ENOMEM;
    
    		}
    
    		list_add(&req->list, &dev->tx_reqs);
    
    	}
    
    
    
    	dev->req->complete = zebra_mouse_setup_complete;
    
    
    
    	/* finish hookup to lower layer ... */
    
    	dev->gadget = gadget;
    
    	set_gadget_data(gadget, dev);
    
    	gadget->ep0->driver_data = dev;
    
    
    
    //	INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
    
    //	INFO(dev, "using %s, IN %s \n", gadget->name, in_ep->name);
    
    	
    
    	printk("zebra_mouse_bind end---------------\n");
    
    	
    
    	return 0;
    
    
    
    fail:
    
    	zebra_mouse_unbind(gadget);
    
    	return status;
    
    }
    
    
    
    
    
    
    
    /*...........................................................*/
    
    
    
    static struct usb_gadget_driver zebra_mouse_driver = {
    
    	.speed		= DEVSPEED,
    
    
    
    	.function	= (char *) driver_desc,
    
    	.bind		= zebra_mouse_bind,
    
    	.unbind		= zebra_mouse_unbind,
    
    
    
    	.setup		= zebra_mouse_setup,
    
    	.disconnect	= zebra_mouse_disconnect,
    
    
    
    	.driver		= {
    
    		.name		= (char *) shortname,
    
    		.owner		= THIS_MODULE,
    
    	},
    
    };
    
    
    
    
    
    
    
    
    
    /*...........................................................*/
    
    
    
    
    
    MODULE_DESCRIPTION(DRIVER_DESC);
    
    MODULE_AUTHOR("liven");
    
    MODULE_LICENSE("GPL");
    
    
    
    
    
    /*...........................................................*/
    
    
    
    static int __init init(void)
    
    {
    
    	int status;
    
    	printk("__init begin---------------\n");
    
    
    
    	usb_gadget_class = class_create(THIS_MODULE, shortname);
    
    	if (IS_ERR(usb_gadget_class)) {
    
    		status = PTR_ERR(usb_gadget_class);
    
    //ERROR(dev, "unable to create zebra_mouse class %d\n", status);
    
    		return status;
    
    	}
    
    
    
    	status = alloc_chrdev_region(&zebra_mouse_devno, 0, 1,
    
    			shortname);
    
    	if (status) {
    
    //ERROR(dev, "alloc_chrdev_region %d\n", status);
    
    		class_destroy(usb_gadget_class);
    
    		return status;
    
    	}
    
    
    
    	status = usb_gadget_register_driver(&zebra_mouse_driver);
    
    	if (status) {
    
    		class_destroy(usb_gadget_class);
    
    		unregister_chrdev_region(zebra_mouse_devno, 1);
    
    //		DBG(dev, "zebra_mouse_register_driver %x\n", status);
    
    	}
    
    
    
    	printk("__init end---------------\n");
    
    	return status;
    
    }
    
    
    
    module_init(init);
    
    
    
    
    
    /*...........................................................*/
    
    
    
    static void __exit cleanup(void)
    
    {
    
    	printk("cleanup begin---------------\n");
    
    	int status;
    
    
    
    	spin_lock(&zebra_mouse.lock_zebra_mouse_io);
    
    	class_destroy(usb_gadget_class);
    
    	unregister_chrdev_region(zebra_mouse_devno, 2);
    
    
    
    	status = usb_gadget_unregister_driver(&zebra_mouse_driver);
    
    	if (status)
    
    	//RROR(dev, "zebra_mouse_unregister_driver %x\n", status);
    
    
    
    	spin_unlock(&zebra_mouse.lock_zebra_mouse_io);
    
    	
    
    	printk("cleanup end---------------\n");
    
    }
    
    
    
    module_exit(cleanup);
    
    
    
    /*...........................................................*/







    when i "make modules" it shows



    drivers/usb/gadget/monihid.c:184:1 5: error: variable 'hid_desc' has initializer but incomplete type
    drivers/usb/gadget/monihid.c:185:2 : error: unknown field 'bLength' specified in initializer
    drivers/usb/gadget/monihid.c:185:2 : warning: excess elements in struct initializer
    drivers/usb/gadget/monihid.c:185:2 : warning: (near initialization for 'hid_desc')
    drivers/usb/gadget/monihid.c:186:2 : error: unknown field 'bDescriptorTyp e' specified in initializer
    drivers/usb/gadget/monihid.c:186:2 : warning: excess elements in struct initializer
    drivers/usb/gadget/monihid.c:186:2 : warning: (near initialization for 'hid_desc')
    drivers/usb/gadget/monihid.c:187:2 : error: unknown field 'bcdHID' specified in initializer
    drivers/usb/gadget/monihid.c:187:2 : warning: excess elements in struct initializer
    drivers/usb/gadget/monihid.c:187:2 : warning: (near initialization for 'hid_desc')
    drivers/usb/gadget/monihid.c:188:2 : error: unknown field 'bCountyCode' specified in initializer
    drivers/usb/gadget/monihid.c:188:2 : warning: excess elements in struct initializer
    drivers/usb/gadget/monihid.c:188:2 : warning: (near initialization for 'hid_desc')
    drivers/usb/gadget/monihid.c:189:2 : error: unknown field 'bNumDescriptor s' specified in initializer
    drivers/usb/gadget/monihid.c:189:2 : warning: excess elements in struct initializer
    drivers/usb/gadget/monihid.c:189:2 : warning: (near initialization for 'hid_desc')
    drivers/usb/gadget/monihid.c:190:2 : error: unknown field 'bSubDescriptor Type' specified in initializer
    drivers/usb/gadget/monihid.c:190:2 : warning: excess elements in struct initializer
    drivers/usb/gadget/monihid.c:190:2 : warning: (near initialization for 'hid_desc')
    drivers/usb/gadget/monihid.c:191:2 : error: unknown field 'bDescriptorLen gth' specified in initializer
    drivers/usb/gadget/monihid.c:191:2 3: error: 'report_desc' undeclared here (not in a function)
    drivers/usb/gadget/monihid.c:193:1 : warning: excess elements in struct initializer
    drivers/usb/gadget/monihid.c:193:1 : warning: (near initialization for 'hid_desc')
    drivers/usb/gadget/monihid.c: In function 'zebra_mouse_wr ite':
    drivers/usb/gadget/monihid.c:493:1 3: error: 'USB_BUFSIZE' undeclared (first use in this function)
    drivers/usb/gadget/monihid.c:493:1 3: note: each undeclared identifier is reported only once for each function it appears in
    drivers/usb/gadget/monihid.c: At top level:
    drivers/usb/gadget/monihid.c:623:2 : warning: initialization from incompatible pointer type
    drivers/usb/gadget/monihid.c: In function 'zebra_mouse_se t_config':
    drivers/usb/gadget/monihid.c:688:2 : error: implicit declaration of function 'gadget_is_sa11 00'
    drivers/usb/gadget/monihid.c:695:7 : error: 'DEV_CONFIG_VAL UE' undeclared (first use in this function)




    who can help me???
    Last edited by Rabbit; Feb 24 '12, 02:47 AM. Reason: Please use code tags when posting code.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    has initializer but incomplete type
    This normally means you have tried to use a class (or struct) when the compiler has only see a forward declaration of it (which only declares the name). The compiler needs to see a full declaration of the class before you use it.

    You will need to work out which header usb_hid_descrip tor is declared in and include it.

    Comment

    Working...