add ZTE EV_DO to a proper driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hello there,
i have an usb modem zte ev-do that i used with kernel from 2.6.29 up to 3.5.
since 3.5, i got the following message:

    [77496.664090] usb 5-2: udev 10, busnum 5, minor = 521
    [77496.664097] usb 5-2: New USB device found, idVendor=19d2, idProduct=ffff
    [77496.664102] usb 5-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    [77496.664107] usb 5-2: Product: ZTE CDMA Tech
    [77496.664112] usb 5-2: Manufacturer: ZTE, Incorporated
    [77496.664226] usb 5-2: usb_probe_device
    [77496.664232] usb 5-2: configuration #1 chosen from 1 choice
    [77496.667119] usb 5-2: adding 5-2:1.0 (config #1, interface 0)
    [77496.670161] usbserial_generic 5-2:1.0: usb_probe_interface
    [77496.670169] usbserial_generic 5-2:1.0: usb_probe_interface - got id
    [77496.670177] usbserial_generic 5-2:1.0: The "generic" usb-serial driver is only for testing and
     one-off prototypes.
    [77496.670182] usbserial_generic 5-2:1.0: Tell linux-usb@xxxxxxxxxxxxxxx to add your device to a 
    proper driver.
    [77496.670186] usbserial_generic 5-2:1.0: generic converter detected
    [77496.670276] usb 5-2: generic converter now attached to ttyUSB0

i would be nice to have a driver for this device in the kernel.
the device is shipped with sources to build its modules. if i understand
correctly thet are released under GPL, so i attached them below.
this is portion of Makefile i used:

    obj-m := ztemt.o
    ztemt-objs := usb-serial.o bus.o generic.o ezusb.o zte_ev.o

usb-serial.c, bus.c, generic.c and ezusb.c are from the kernel source.
the patch against 3.5 i used for generic.c is also attached below.

and since 3.5, i've also got the following message:

    [77694.270178] usb 5-2: uhci_result_common: failed with status 440000
    [77694.272174] usb 5-2: uhci_result_common: failed with status 440000

/////////////////////////////////////////////////
/*-- begin zte_ev.c --*/

#include <linux/version.h> 
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/usb.h>
#include <asm/uaccess.h>
#include <linux/usb/serial.h>
#include "zte_ev.h"

#define  MAX_SETUP_DATA_SIZE   32 

static int debug=0;
void zte_ev_usb_serial_init(struct usb_serial_port *port)
{
   	struct usb_serial *serial = port->serial;
	int result = 0,len;
	unsigned char *buf;

       if (port->number != 0)  return;  

       printk("zte ev enter---
"); 
	buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);


/*send 1st ctl cmd(CTL    21 22 01 00  00 00 00 00)*/
      len = 0;
      result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x22, 0x21,
				0x0001, 0x0000, NULL, len,
				HZ * USB_CTRL_GET_TIMEOUT);
      dbg("result = %d
",result);  

      /*send  2st cmd and recieve data*/
     /*
 16.0  CTL    a1 21 00 00  00 00 07 00                                                                                CLASS                   25.1.0(5)     
  16.0  DI     00 96 00 00  00 00 08    
      */
      len = 0x0007;
     result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
				0x21, 0xa1,
				0x0000, 0x0000, buf, len,
				HZ * USB_CTRL_GET_TIMEOUT);
     dbg("result = %d
",result);
     if (result == len)	  
          usb_serial_debug_data(debug,&port->dev, __FUNCTION__, len,buf);

   /*send 3 cmd*/
   /*
  16.0 CTL    21 20 00 00  00 00 07 00                                                                                CLASS                   30.1.0        
  16.0  DO     80 25 00 00  00 00 08                                                                                   .%.....                 30.2.0        
  */
  len = 0x0007;
   buf[0]=0x80;
   buf[1]=0x25;
   buf[2]=0x00;
   buf[3]=0x00;
   buf[4]=0x00;
   buf[5]=0x00;
   buf[6]=0x08;
     result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x20, 0x21,
				0x0000, 0x0000, buf, len,
				HZ * USB_CTRL_GET_TIMEOUT);
     dbg("result = %d
",result);
     if (result == len)	  
          usb_serial_debug_data(debug,&port->dev, __FUNCTION__, len,buf);


   

   /*send 4 cmd*/
   /*
    16.0 CTL    21 22 03 00  00 00 00 00   
  */

      len = 0;
      result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x22, 0x21,
				0x0003, 0x0000, NULL, len,
				HZ * USB_CTRL_GET_TIMEOUT);
      dbg("result = %d
",result);  
   

   /*send 5 cmd*/
   /*
 16.0  CTL    a1 21 00 00  00 00 07 00                                                                                CLASS                   33.1.0        
  16.0  DI     80 25 00 00  00 00 08   
  */
   len = 0x0007;
     result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
				0x21, 0xa1,
				0x0000, 0x0000, buf, len,
				HZ * USB_CTRL_GET_TIMEOUT);
     dbg("result = %d
",result);
     if (result == len)	  
          usb_serial_debug_data(debug,&port->dev, __FUNCTION__, len,buf);


  /*send 6 cmd*/
   /*
   16.0  CTL    21 20 00 00  00 00 07 00                                                                                CLASS                   34.1.0        
  16.0  DO     80 25 00 00  00 00 08 
  */
  len = 0x0007;
   buf[0]=0x80;
   buf[1]=0x25;
   buf[2]=0x00;
   buf[3]=0x00;
   buf[4]=0x00;
   buf[5]=0x00;
   buf[6]=0x08;
     result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x20, 0x21,
				0x0000, 0x0000, buf, len,
				HZ * USB_CTRL_GET_TIMEOUT);
     dbg("result = %d
",result);
     if (result == len)	  
          usb_serial_debug_data(debug,&port->dev, __FUNCTION__, len,buf);
	kfree(buf);
}


/*
      CTL    21 22 02 00  00 00 00 00                                                                                CLASS                  338.1.0         
  
 * 16.1  DI     a1 20 00 00  00 00 02 00  02 00                                                                         . ........             340.1.0        
  16.0  CTL    21 22 03 00  00 00 00 00                                                                                CLASS                  341.1.0        
 
  16.0  CTL    a1 21 00 00  00 00 07 00                                                                                CLASS                  346.1.0(3)     
  16.0  DI     00 08 07 00  00 00 08                                                                                   .......                346.2.0        

  16.0  CTL    21 20 00 00  00 00 07 00                                                                                CLASS                  349.1.0        
  16.0  DO     00 c2 01 00  00 00 08                                                                                   .......                349.2.0        

  16.0  CTL    21 22 03 00  00 00 00 00                                                                                CLASS                  350.1.0(2)     

  16.0  CTL    a1 21 00 00  00 00 07 00                                                                                CLASS                  352.1.0        
  16.0  DI     00 c2 01 00  00 00 08                                                                                   .......                352.2.0        

  *16.1  DI     a1 20 00 00  00 00 02 00  02 00                                                                         . ........             353.1.0        

  16.0  CTL    21 20 00 00  00 00 07 00                                                                                CLASS                  354.1.0        
  16.0  DO     00 c2 01 00  00 00 08                                                                                   .......                354.2.0        

  16.0  CTL    21 22 03 00  00 00 00 00    
*/

void zte_ev_usb_serial_exit(struct usb_serial_port *port)
{
   	struct usb_serial *serial = port->serial;
	int result = 0,len,actual_len;
	unsigned char *buf;

       if (port->number != 0)  return;

	buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);


      printk("zte ev exit---
");
   /*send 1st ctl cmd(CTL    21 22 02 00  00 00 00 00)*/
      len = 0;
      result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x22, 0x21,
				0x0002, 0x0000, NULL, len,
				HZ * USB_CTRL_GET_TIMEOUT);
      dbg("result = %d
",result);  

 /*send 2st ctl cmd(CTL    21 22 03 00  00 00 00 00 )*/
      len = 0;
      result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x22, 0x21,
				0x0003, 0x0000, NULL, len,
				HZ * USB_CTRL_GET_TIMEOUT);
      dbg("result = %d
",result);  


      /*send  3st cmd and recieve data*/
     /*
 16.0  CTL    a1 21 00 00  00 00 07 00                                                                                CLASS                   25.1.0(5)     
  16.0  DI     00 08 07 00  00 00 08   
      */
      len = 0x0007;
     result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
				0x21, 0xa1,
				0x0000, 0x0000, buf, len,
				HZ * USB_CTRL_GET_TIMEOUT);
     dbg("result = %d
",result);
     if (result == len)	  
          usb_serial_debug_data(debug,&port->dev, __FUNCTION__, len,buf);

   /*send 4 cmd*/
   /*
  16.0 CTL    21 20 00 00  00 00 07 00                                                                                CLASS                   30.1.0        
  16.0  DO     00 c2 01 00  00 00 08                                                                                 .%.....                 30.2.0        
  */
  len = 0x0007;
   buf[0]=0x00;
   buf[1]=0xc2;
   buf[2]=0x01;
   buf[3]=0x00;
   buf[4]=0x00;
   buf[5]=0x00;
   buf[6]=0x08;
     result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x20, 0x21,
				0x0000, 0x0000, buf, len,
				HZ * USB_CTRL_GET_TIMEOUT);
     dbg("result = %d
",result);
     if (result == len)	  
          usb_serial_debug_data(debug,&port->dev, __FUNCTION__, len,buf);


   

   /*send 5 cmd*/
   /*
    16.0 CTL    21 22 03 00  00 00 00 00    
  */

      len = 0;
      result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x22, 0x21,
				0x0003, 0x0000, NULL, len,
				HZ * USB_CTRL_GET_TIMEOUT);
      dbg("result = %d
",result);  
   

   /*send 6 cmd*/
   /*
 16.0  CTL     a1 21 00 00  00 00 07 00                                                                               CLASS                   33.1.0        
  16.0  DI     00 c2 01 00  00 00 08  
  */
   len = 0x0007;
     result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
				0x21, 0xa1,
				0x0000, 0x0000, buf, len,
				HZ * USB_CTRL_GET_TIMEOUT);
     dbg("result = %d
",result);
     if (result == len)	  
          usb_serial_debug_data(debug,&port->dev, __FUNCTION__, len,buf);


  /*send 7 cmd*/
   /*
   16.0  CTL    21 20 00 00  00 00 07 00                                                                                CLASS                  354.1.0        
  16.0  DO     00 c2 01 00  00 00 08                                                                                   .......                354.2.0        
  */
  len = 0x0007;
   buf[0]=0x00;
   buf[1]=0xc2;
   buf[2]=0x01;
   buf[3]=0x00;
   buf[4]=0x00;
   buf[5]=0x00;
   buf[6]=0x08;
     result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x20, 0x21,
				0x0000, 0x0000, buf, len,
				HZ * USB_CTRL_GET_TIMEOUT);
     dbg("result = %d
",result);
     if (result == len)	  
          usb_serial_debug_data(debug,&port->dev, __FUNCTION__, len,buf);

  /*send 8 cmd*/
   /*
    16.0 CTL    21 22 03 00  00 00 00 00    
  */

      len = 0;
      result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				0x22, 0x21,
				0x0003, 0x0000, NULL, len,
				HZ * USB_CTRL_GET_TIMEOUT);
      dbg("result = %d
",result);  

	kfree(buf);
}

/*-- end zte_ev.c --*/

/////////////////////////////////////////////////
/*-- begin zte_ev.h --*/
#ifndef  __ZTE_EVDO_TERMINAL__

#define  __ZTE_EVDO_TERMINAL__

#include   <linux/version.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#define  usb_endpoint_is_bulk_in(endpoint)   	((endpoint->bEndpointAddress & 0x80) &&((endpoint->bmAttributes & 3) == 0x02)) 

#define  usb_endpoint_is_bulk_out(endpoint) 		(((endpoint->bEndpointAddress & 0x80) == 0x00) && ((endpoint->bmAttributes & 3) == 0x02)) 

#define  usb_endpoint_is_int_in(endpoint) 		((endpoint->bEndpointAddress & 0x80) &&((endpoint->bmAttributes & 3) == 0x03)) 

#define  usb_endpoint_is_int_out(endpoint) 		(((endpoint->bEndpointAddress & 0x80) == 0x00) &&((endpoint->bmAttributes & 3) == 0x03))
#endif

/*some supplement for usb-serial.h*/
#define  CONFIG_ZTE_EV_MODEM
extern int  usb_serial_generic_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
extern void  usb_serial_generic_set_termios(struct tty_struct *tty, struct termios * old);

#define dbgg  dbg   //do {  printk(KERN_DEBUG "%s(%d): " format "
" , __FILE__ , __LINE__,## arg); } while (0)
#endif
/*-- end zte_ev.c --*/

/////////////////////////////////////////////////
/*-- begin generic.c.diff --*/
--- /usr/src/linux-3.5/drivers/usb/serial/generic.c	2012-07-25 22:15:29.059874571 +0300
+++ ./generic.c	2012-07-24 19:12:33.301992508 +0300
@@ -22,14 +22,20 @@
 #include <linux/usb/serial.h>
 #include <linux/uaccess.h>
 #include <linux/kfifo.h>
 #include <linux/serial.h>
-
+#include "zte_ev.h"
+ 
 static int debug;
 
+#ifdef  CONFIG_ZTE_EV_MODEM
+void zte_ev_usb_serial_init(struct usb_serial_port *port);
+void zte_ev_usb_serial_exit(struct usb_serial_port *port);
+#endif
+
 #ifdef CONFIG_USB_SERIAL_GENERIC
 
-static __u16 vendor  = 0x05f9;
+static __u16 vendor  = 0x19d2;
 static __u16 product = 0xffff;
 
 module_param(vendor, ushort, 0);
 MODULE_PARM_DESC(vendor, "User specified USB idVendor");
@@ -89,9 +95,11 @@
 int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	int result = 0;
 	unsigned long flags;
-
+#ifdef  CONFIG_ZTE_EV_MODEM
+       zte_ev_usb_serial_init(port);
+#endif
 	/* clear the throttle flags */
 	spin_lock_irqsave(&port->lock, flags);
 	port->throttled = 0;
 	port->throttle_req = 0;
@@ -129,8 +137,11 @@
 }
 
 void usb_serial_generic_close(struct usb_serial_port *port)
 {
+#ifdef  CONFIG_ZTE_EV_MODEM
+       zte_ev_usb_serial_exit(port);
+#endif	
 	generic_cleanup(port);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_close);

/*-- end generic.c.diff --*/

regards,
--
nirinA
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux