Advertisement
Guest User

Untitled

a guest
Oct 25th, 2015
379
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 33.54 KB | None | 0 0
  1. // 2013.7
  2. //********************************************
  3. //**  Copyright  (C)  WCH  2002-2013    ******
  4. //**  Web:  http://www.winchiphead.com  ******
  5. //********************************************
  6. //**  Driver for USB to serial adaptor CH34X**
  7. //**  GCC                                   **
  8. //********************************************
  9.  
  10. // Support linux kernel version 2.6.25 and later
  11. //
  12.  
  13. #include <linux/version.h>
  14. #ifndef KERNEL_VERSION
  15. #define KERNEL_VERSION(ver, rel, seq)   ((ver << 16) | (rel << 8) | (seq))
  16. #endif
  17.  
  18. #include <linux/kernel.h>
  19. #include <linux/errno.h>
  20. #include <linux/init.h>
  21. #include <linux/slab.h>
  22. #include <linux/tty.h>
  23. #include <linux/tty_driver.h>
  24. #include <linux/tty_flip.h>
  25. #include <linux/serial.h>
  26. #include <linux/module.h>
  27. #include <linux/moduleparam.h>
  28. #include <linux/spinlock.h>
  29. #include <asm/uaccess.h>
  30. //#include <linux/uaccess.h>
  31. #include <linux/usb.h>
  32. #include <linux/usb/serial.h>
  33.  
  34. #define DRIVER_DESC     "WCH CH34x USB to serial adaptor driver"
  35. #define DRIVER_AUTHOR   "<tech@wch.cn>"
  36.  
  37. #define CH34x_VENDOR_ID     0x1A86
  38. #define CH340_PRODUCT_ID    0x7523
  39. #define CH341_PRODUCT_ID    0x5523
  40.  
  41. #define CH34x_CLOSING_WAIT  (30 * HZ)
  42.  
  43. #define CH34x_BUF_SIZE      1024
  44. #define CH34x_TMP_BUF_SIZE  1024
  45.  
  46. //Vendor define
  47. #define VENDOR_WRITE_TYPE       0x40
  48. #define VENDOR_READ_TYPE        0xC0
  49.  
  50. #define VENDOR_READ             0x95
  51. #define VENDOR_WRITE            0x9A
  52. #define VENDOR_SERIAL_INIT      0xA1
  53. #define VENDOR_MODEM_OUT        0xA4
  54. #define VENDOR_VERSION          0x5F
  55.  
  56. //For CMD 0xA4
  57. #define UART_CTS        0x01
  58. #define UART_DSR        0x02
  59. #define UART_RING       0x04
  60. #define UART_DCD        0x08
  61. #define CONTROL_OUT     0x10
  62. #define CONTROL_DTR     0x20
  63. #define CONTROL_RTS     0x40
  64.  
  65. //Uart state
  66. #define UART_STATE          0x00
  67. #define UART_OVERRUN_ERROR  0x01
  68. #define UART_BREAK_ERROR    //no define
  69. #define UART_PARITY_ERROR   0x02
  70. #define UART_FRAME_ERROR    0x06
  71. #define UART_RECV_ERROR     0x02
  72. #define UART_STATE_TRANSIENT_MASK   0x07
  73.  
  74. //Port state
  75. #define PORTA_STATE     0x01
  76. #define PORTB_STATE     0x02
  77. #define PORTC_STATE     0x03
  78.  
  79. //CH34x Baud Rate
  80. #define CH34x_BAUDRATE_FACTOR   1532620800
  81. #define CH34x_BAUDRATE_DIVMAX   3
  82.  
  83. #define DEBUG_CH34x
  84. #undef  DEBUG_CH34x
  85.  
  86. #ifdef DEBUG_CH34x
  87. #define dbg_ch34x( format, arg... )     \
  88.     printk( KERN_DEBUG "%d: " format "\n", __LINE__, ##arg )
  89. #else
  90. #define dbg_ch34x( format, arg... )     \
  91. do{                                 \
  92.     if(0)                           \
  93.         printk(KERN_DEBUG "%d: " format "\n", __LINE__, ##arg); \
  94. } while (0)
  95. #endif
  96.  
  97. #ifdef DEBUG_CH34x
  98. #define err_ch34x( format, arg... )     \
  99.     printk(KERN_ERR KBUILD_MODNAME ": " format "\n", ##arg)
  100. #else
  101. #define err_ch34x( format, arg... )   \
  102. do{                             \
  103.     if(0)                       \
  104.     printk( KERN_ERR KBUILD_MODNAME ": " format "\n", ##arg)\
  105. }while(0)                      
  106. #endif
  107.  
  108. // For debug
  109. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,1))
  110. static int debug = 1;
  111. #endif
  112.  
  113. struct ch34x_buf {
  114.     unsigned int buf_size;
  115.     char *buf_buf;
  116.     char *buf_get;
  117.     char *buf_put;
  118. };
  119.  
  120. struct ch34x_private {
  121.     spinlock_t  lock;   //access lock
  122.     struct ch34x_buf    *buf;
  123.     int write_urb_in_use;
  124.     unsigned baud_rate;
  125.     wait_queue_head_t   delta_msr_wait;
  126.     u8  line_control;
  127.     u8  line_status;
  128.     u8  termios_initialized;
  129. };
  130.  
  131. static struct usb_device_id id_table [] = {
  132.     { USB_DEVICE(CH34x_VENDOR_ID, CH340_PRODUCT_ID) },
  133.     { USB_DEVICE(CH34x_VENDOR_ID, CH341_PRODUCT_ID) },
  134.     { } //End
  135. };
  136. MODULE_DEVICE_TABLE( usb, id_table );
  137.  
  138. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,2))
  139. static struct usb_driver ch34x_driver = {
  140.     .name          = "ch34x",
  141.     .probe         = usb_serial_probe,
  142.     .disconnect    = usb_serial_disconnect,
  143.     .id_table      = id_table,
  144.     .suspend       = usb_serial_suspend,
  145.     .resume        = usb_serial_resume,
  146.     .no_dynamic_id = 1,
  147.     .supports_autosuspend = 1,
  148. };
  149. #endif
  150.  
  151. // ch34x_buf_alloc
  152. // Allocate a circular buffer and all associated memory
  153. static struct ch34x_buf *ch34x_buf_alloc( unsigned int size )
  154. {
  155.     struct ch34x_buf *pb;
  156.  
  157.     if( size == 0 )
  158.         return NULL;
  159.  
  160.     pb = kmalloc( sizeof(struct ch34x_buf), GFP_KERNEL );
  161.     if( pb == NULL )
  162.         return NULL;
  163.  
  164.     pb->buf_buf = kmalloc( size, GFP_KERNEL );
  165.     if( pb->buf_buf == NULL ) {
  166.         kfree(pb);
  167.         return NULL;
  168.     }
  169.  
  170.     pb->buf_size = size;
  171.     pb->buf_get = pb->buf_put = pb->buf_buf;
  172.  
  173.     return pb;
  174. }
  175.  
  176. // ch34x_buf_free
  177. // Free the buffer and all associated memory
  178. static void ch34x_buf_free( struct ch34x_buf *pb )
  179. {
  180.     if( pb ) {
  181.         kfree( pb->buf_buf );
  182.         kfree( pb );
  183.     }
  184. }
  185.  
  186. // ch34x_buf_clear
  187. // Clear out all data in the circular buffer
  188. static void ch34x_buf_clear( struct ch34x_buf *pb )
  189. {
  190.     if( pb != NULL )
  191.         pb->buf_get = pb->buf_put;
  192.     // equivalent to a get of all data available
  193. }
  194.  
  195. // ch34x_buf_data_avail
  196. // Return the number of bytes of data available in he circular buffer
  197. static unsigned int ch34x_buf_data_avail( struct ch34x_buf *pb )
  198. {
  199.     if( pb == NULL )
  200.         return 0;
  201.  
  202.     return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size );
  203. }
  204.  
  205. // ch34x_buf_space_avail
  206. // Return the number of bytes of space available in the circular
  207. static unsigned int ch34x_buf_space_avail( struct ch34x_buf *pb )
  208. {
  209.     if( pb == NULL )
  210.         return 0;
  211.  
  212.     return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size );
  213. }
  214.  
  215. // ch34x_buf_put
  216. // Copy data from a user buffer and put it into the circular buffer.
  217. // Restrict to the amount of space available
  218. // Return the number of bytes copied
  219. static unsigned int ch34x_buf_put( struct ch34x_buf *pb,
  220.         const char *buf, unsigned int count )
  221. {
  222.     unsigned int len;
  223.  
  224.     if( pb == NULL )
  225.         return 0;
  226.  
  227.     len = ch34x_buf_space_avail(pb);
  228.     if( count > len )
  229.         count = len;
  230.     else if( count == 0 )
  231.         return 0;
  232.  
  233.     len = pb->buf_buf + pb->buf_size - pb->buf_put;
  234.     if( count > len ) {
  235.         memcpy( pb->buf_put, buf, len );
  236.         memcpy( pb->buf_buf, buf+len, count - len );
  237.         pb->buf_put = pb->buf_buf + count - len;
  238.     }
  239.     else {
  240.         memcpy( pb->buf_put, buf, count );
  241.         if( count < len )
  242.             pb->buf_put += count;
  243.         else if( count == len )
  244.             pb->buf_put = pb->buf_buf;
  245.     }
  246.  
  247.     return count;
  248. }
  249.  
  250. static unsigned int ch34x_buf_get( struct ch34x_buf *pb,
  251.         char *buf, unsigned int count )
  252. {
  253.     unsigned int len;
  254.  
  255.     if( pb == NULL )
  256.         return 0;
  257.  
  258.     len = ch34x_buf_data_avail(pb);
  259.     if( count > len )
  260.         count = len;
  261.     else if( count == 0 )
  262.         return 0;
  263.  
  264.     len = pb->buf_buf + pb->buf_size - pb->buf_get;
  265.     if( count > len ) {
  266.         memcpy( buf, pb->buf_get, len );
  267.         memcpy( buf+len, pb->buf_buf, count - len );
  268.         pb->buf_get = pb->buf_buf + count - len;
  269.     }
  270.     else {
  271.         memcpy( buf, pb->buf_get, count );
  272.         if( count < len )
  273.             pb->buf_get += count;
  274.         else if( count == len )
  275.             pb->buf_get = pb->buf_buf;
  276.     }
  277.  
  278.     return count;
  279. }
  280.  
  281. static int ch34x_vendor_read( __u8 request,
  282.         __u16 value,
  283.         __u16 index,
  284.         struct usb_serial *serial,
  285.         unsigned char *buf,
  286.         __u16 len )
  287. {
  288.     int retval;
  289.  
  290.     retval = usb_control_msg( serial->dev, usb_rcvctrlpipe(serial->dev, 0),
  291.             request, VENDOR_READ_TYPE, value, index, buf, len, 1000 );
  292.     dbg_ch34x("0x%x:0x%x:0x%x:0x%x %d - %d",
  293.             VENDOR_READ_TYPE, request, value, index, retval, len );
  294.  
  295.     return retval;
  296. }
  297.  
  298. static int ch34x_vendor_write( __u8 request,
  299.         __u16 value,
  300.         __u16 index,
  301.         struct usb_serial *serial,
  302.         unsigned char *buf,
  303.         __u16 len )
  304. {
  305.     int retval;
  306.  
  307.     retval = usb_control_msg( serial->dev,
  308.             usb_sndctrlpipe(serial->dev, 0),
  309.             request,
  310.             VENDOR_WRITE_TYPE,
  311.             value, index, buf, len, 1000 );
  312.  
  313.     return retval;
  314. }
  315.  
  316. static int set_control_lines( struct usb_serial *serial,
  317.         u8 value )
  318. {
  319.     int retval;
  320.  
  321.     retval = ch34x_vendor_write( VENDOR_MODEM_OUT, (unsigned short)value,
  322.             0x0000, serial, NULL, 0x00 );
  323.     dbg_ch34x("%s - value=%d, retval=%d", __func__, value, retval );
  324.  
  325.     return retval;
  326. }
  327.  
  328. static int ch34x_get_baud_rate( unsigned int baud_rate,
  329.         unsigned char *a, unsigned char *b )
  330. {
  331.     unsigned long factor = 0;
  332.     short divisor = 0;
  333.  
  334.     if( !baud_rate )
  335.         return -EINVAL;
  336.  
  337.     factor = (CH34x_BAUDRATE_FACTOR / baud_rate);
  338.     divisor = CH34x_BAUDRATE_DIVMAX;
  339.  
  340.     while( (factor > 0xfff0) && divisor ) {
  341.         factor >>= 3;
  342.         divisor --;
  343.     }
  344.  
  345.     if( factor > 0xfff0 )
  346.         return -EINVAL;
  347.  
  348.     factor = 0x10000 - factor;
  349.     *a = (factor & 0xff00) >> 8;
  350.     *b = divisor;
  351.  
  352.     return 0;
  353. }
  354.  
  355. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  356. static void ch34x_set_termios( struct tty_struct *tty,
  357.         struct usb_serial_port *port, struct ktermios *old_termios )
  358. {
  359. #else
  360. static void ch34x_set_termios( struct usb_serial_port *port,
  361.         struct ktermios *old_termios )
  362. {
  363.     struct tty_struct *tty = port->tty;
  364. #endif
  365.     struct usb_serial *serial = port->serial;  
  366.     struct ch34x_private *priv = usb_get_serial_port_data(port);
  367. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,1)) //sure
  368.     struct ktermios *termios = &tty->termios;
  369. #else
  370.     struct ktermios *termios = tty->termios;
  371. #endif
  372.     unsigned int baud_rate;
  373.     unsigned int cflag;
  374.     unsigned long flags;
  375.     u8 control;
  376.  
  377.     unsigned char divisor = 0;
  378.     unsigned char reg_count = 0;
  379.     unsigned char factor = 0;
  380.     unsigned char reg_value = 0;
  381.     unsigned short value = 0;
  382.     unsigned short index = 0;
  383.  
  384.     dbg_ch34x("%s - port:%d", __func__, port->number);
  385.    
  386.     spin_lock_irqsave( &priv->lock, flags );
  387.     if( !priv->termios_initialized ) {
  388.         *(termios) = tty_std_termios;
  389.         termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
  390.         termios->c_ispeed = 9600;
  391.         termios->c_ospeed = 9600;
  392.         priv->termios_initialized = 1;
  393.     }
  394.     spin_unlock_irqrestore( &priv->lock, flags );
  395.  
  396.     /*
  397.      * The ch34x is reported to lose bytes if you change serial setting
  398.      * even to the same vaules as before. Thus we actually need to filter
  399.      * in this specific case.
  400.      */
  401.     if( !tty_termios_hw_change(termios, old_termios) )
  402.         return;
  403.  
  404.     cflag = termios->c_cflag;
  405.     dbg_ch34x("%s (%d) cflag=0x%x\n", __func__, port->number, cflag );
  406.  
  407.     // Get the byte size
  408.     switch( cflag & CSIZE )
  409.     {
  410.         case CS5:
  411.             reg_value |= 0x00;
  412.             break;
  413.         case CS6:
  414.             reg_value |= 0x01;
  415.             break;
  416.         case CS7:
  417.             reg_value |= 0x02;
  418.             break;
  419.         case CS8:
  420.             reg_value |= 0x03;
  421.             break;
  422.         default:
  423.             reg_value |= 0x03;
  424.             break;
  425.     }
  426.     dbg_ch34x("%s - data bits = %d", __func__, reg_value + 0x05 );
  427.  
  428.     // Figure out the stop bits
  429.     if( cflag & CSTOPB ) {
  430.         reg_value |= 0x04;
  431.         dbg_ch34x("%s - stop bits = 2", __func__);
  432.     }
  433.     else
  434.         dbg_ch34x("%s - stop bits = 1", __func__);
  435.  
  436.     // Determine the parity
  437.     if( cflag & PARENB )
  438.         if( cflag & PARODD ) {
  439.             reg_value |= (0x08 | 0x00);
  440.             dbg_ch34x("%s - parity = odd", __func__);
  441.         }
  442.         else {
  443.             reg_value |= (0x08 | 0x10);
  444.             dbg_ch34x("%s - parity = even", __func__);
  445.         }
  446.     else
  447.         dbg_ch34x("%s - parity = none", __func__);
  448.  
  449.     // Determine the baud rate
  450.     baud_rate = tty_get_baud_rate( tty );
  451.     dbg_ch34x("%s = baud_rate = %d", __func__, baud_rate); 
  452.     ch34x_get_baud_rate( baud_rate, &factor, &divisor );   
  453.     dbg_ch34x("----->>>> baud_rate = %d, factor:0x%x, divisor:0x%x",
  454.                 baud_rate, factor, divisor );  
  455.  
  456.     //enable SFR_UART RX and TX
  457.     reg_value |= 0xc0;
  458.     //enable SFR_UART Control register and timer
  459.     reg_count |= 0x9c;
  460.  
  461.     value |= reg_count;
  462.     value |= (unsigned short)reg_value << 8;
  463.     index |= 0x80 | divisor;
  464.     index |= (unsigned short)factor << 8;
  465.     ch34x_vendor_write( VENDOR_SERIAL_INIT, value, index, serial, NULL, 0 );
  466.  
  467.     // change control lines if we are switching to or from B0
  468.     spin_lock_irqsave( &priv->lock, flags );
  469.     control = priv->line_control;
  470.     if( (cflag & CBAUD) == B0 )
  471.         priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
  472.     else
  473.         priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
  474.  
  475.     if( control != priv->line_control ) {
  476.         control = priv->line_control;
  477.         spin_unlock_irqrestore( &priv->lock, flags );
  478.         set_control_lines( serial, control );
  479.     }
  480.     else
  481.         spin_unlock_irqrestore( &priv->lock, flags );
  482.  
  483.     if( cflag & CRTSCTS )
  484.         ch34x_vendor_write( VENDOR_WRITE, 0x2727, 0x0101, serial, NULL, 0);
  485.  
  486.     // FIXME: Need to read back resulting baud rate
  487.     if( baud_rate )
  488.         tty_encode_baud_rate(tty, baud_rate, baud_rate);
  489.  
  490. }
  491.  
  492. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,3))
  493. static int ch34x_tiocmget( struct tty_struct *tty )
  494. {
  495.     struct usb_serial_port *port = tty->driver_data;
  496. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  497. static int ch34x_tiocmget( struct tty_struct *tty,
  498.         struct file *filp )
  499. {
  500.     struct usb_serial_port *port = tty->driver_data;
  501. #else
  502. static int ch34x_tiocmget( struct usb_serial_port *port,
  503.         struct file *filp )
  504. {
  505. #endif
  506.     struct ch34x_private *priv = usb_get_serial_port_data(port);
  507.     unsigned long flags;
  508.     unsigned int mcr;
  509.     /*unsigned int msr;*/
  510.     unsigned int retval;
  511.  
  512.     dbg_ch34x("%s - port:%d", __func__, port->number);
  513.  
  514.     if( !usb_get_intfdata( port->serial->interface) )
  515.         return -ENODEV;
  516.  
  517.     spin_lock_irqsave( &priv->lock, flags );
  518.     mcr = priv->line_control;
  519.     spin_unlock_irqrestore( &priv->lock, flags );
  520.  
  521.     retval = ((mcr & CONTROL_DTR) ? TIOCM_DTR : 0) |
  522.              ((mcr & CONTROL_RTS) ? TIOCM_RTS : 0) |
  523.              ((mcr & UART_CTS) ? TIOCM_CTS : 0) |
  524.              ((mcr & UART_DSR) ? TIOCM_DSR : 0) |
  525.              ((mcr & UART_RING) ? TIOCM_RI : 0) |
  526.              ((mcr & UART_DCD) ? TIOCM_CD : 0);
  527.  
  528.     dbg_ch34x("%s - retval=0x%x", __func__, retval);
  529.  
  530.     return retval;
  531. }
  532.  
  533. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) && \
  534.         LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) )
  535. static void ch34x_close( struct tty_struct *tty,
  536.         struct usb_serial_port *port, struct file *filp )
  537. {
  538. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) )
  539. static void ch34x_close( struct usb_serial_port *port )
  540. {
  541.     struct tty_struct *tty = port->port.tty;
  542. #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
  543. static void ch34x_close( struct usb_serial_port *port,
  544.         struct file *filp )
  545. {
  546.     struct tty_struct *tty = port->tty;
  547. #endif
  548.     struct ch34x_private *priv = usb_get_serial_port_data(port);
  549.     unsigned long flags;
  550.     unsigned int c_cflag;
  551.     int bps;
  552.     long timeout;
  553.     wait_queue_t wait;
  554.  
  555.     dbg_ch34x("%s - port:%d", __func__, port->number);
  556.    
  557.     // wait for data do drain from the buffer
  558.     spin_lock_irqsave( &priv->lock, flags );
  559.     timeout = CH34x_CLOSING_WAIT;
  560.     init_waitqueue_entry( &wait, current );
  561.     add_wait_queue( &tty->write_wait, &wait );
  562.     for(;;) {
  563.         set_current_state( TASK_INTERRUPTIBLE );
  564.         if( ch34x_buf_data_avail(priv->buf) == 0 || timeout == 0 ||
  565.                 signal_pending(current) || port->serial->disconnected )
  566.             break;
  567.         spin_unlock_irqrestore( &priv->lock, flags );
  568.         timeout = schedule_timeout( timeout );
  569.         spin_lock_irqsave( &priv->lock, flags );
  570.     }
  571.     set_current_state( TASK_RUNNING );
  572.     remove_wait_queue( &tty->write_wait, &wait );
  573.     // clear out any remaining data in the buffer
  574.     ch34x_buf_clear( priv->buf );
  575.     spin_unlock_irqrestore( &priv->lock, flags );
  576.  
  577.     bps = tty_get_baud_rate( tty );
  578.     if( bps > 1200 )
  579.         timeout = max( (HZ * 2560) / bps, HZ / 10 );
  580.     else
  581.         timeout = 2 * HZ;
  582.     schedule_timeout_interruptible(timeout);
  583.  
  584.     // shutdown our urbs
  585.     usb_kill_urb(port->interrupt_in_urb);
  586.     usb_kill_urb(port->read_urb);
  587.     usb_kill_urb(port->write_urb);
  588.     /*usb_serial_generic_close(port, filp);*/
  589.  
  590.     if( tty ) {
  591. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,1)) //sure
  592.         c_cflag = tty->termios.c_cflag;
  593. #else
  594.         c_cflag = tty->termios->c_cflag;
  595. #endif
  596.         if( c_cflag & HUPCL ) {
  597.             // drop DTR and RTS
  598.             spin_lock_irqsave( &priv->lock, flags );
  599.             priv->line_control = 0;
  600.             spin_unlock_irqrestore( &priv->lock, flags );
  601.             set_control_lines( port->serial, 0 );
  602.         }
  603.     }
  604. }
  605.  
  606. // kernel version
  607. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) \
  608.         && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  609. static int ch34x_open( struct tty_struct *tty,
  610.         struct usb_serial_port *port, struct file *filp )
  611. {
  612. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))
  613. static int ch34x_open( struct tty_struct *tty,
  614.         struct usb_serial_port *port )
  615. {
  616. #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
  617. static int ch34x_open( struct usb_serial_port *port,
  618.         struct file *filp )
  619. {
  620.     struct tty_struct *tty = port->tty;
  621. #endif
  622.     struct ktermios tmp_termios;
  623.     struct usb_serial *serial = port->serial;
  624.     int retval;
  625.  
  626.     dbg_ch34x("%s - port:%d", __func__, port->number );
  627.  
  628.     usb_clear_halt( serial->dev, port->write_urb->pipe );
  629.     usb_clear_halt( serial->dev, port->read_urb->pipe );
  630.  
  631.     if( tty ) {
  632. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  633.         ch34x_set_termios( tty, port, &tmp_termios );
  634. #else
  635.         ch34x_set_termios( port, &tmp_termios );
  636. #endif
  637.     }
  638.  
  639.     dbg_ch34x("%s - submit read urb", __func__);
  640.     port->read_urb->dev = serial->dev;
  641.     retval = usb_submit_urb( port->read_urb, GFP_KERNEL );
  642.     if(retval) {
  643.         dev_err( &port->dev, "%s - failed submit read urb,error %d\n",
  644.                 __func__, retval );
  645. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) && \
  646.         LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) )
  647.         ch34x_close(tty, port, NULL);
  648. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))
  649.         ch34x_close(port);
  650. #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
  651.         ch34x_close(port, filp);
  652. #endif
  653.         goto err_out;
  654.     }
  655.  
  656.     dbg_ch34x("%s - submit interrupt urb", __func__ );
  657.     port->interrupt_in_urb->dev = serial->dev;
  658.     retval = usb_submit_urb( port->interrupt_in_urb, GFP_KERNEL );
  659.     if(retval) {
  660.         dev_err( &port->dev, "%s - failed submit interrupt urb,error %d\n",
  661.                 __func__, retval );
  662. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) && \
  663.         LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) )
  664.         ch34x_close(tty, port, NULL);
  665. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))
  666.         ch34x_close(port);
  667. #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
  668.         ch34x_close(port, filp);
  669. #endif
  670.         goto err_out;
  671.     }
  672.  
  673. err_out:
  674.     return retval;
  675. }
  676.  
  677. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,3))
  678. static int ch34x_tiocmset( struct tty_struct *tty,
  679.         unsigned int set, unsigned int clear )
  680. {
  681.     struct usb_serial_port *port = tty->driver_data;
  682. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  683. static int ch34x_tiocmset( struct tty_struct *tty,
  684.         struct file *filp, unsigned int set, unsigned int clear )
  685. {
  686.     struct usb_serial_port *port = tty->driver_data;
  687. #else
  688. static int ch34x_tiocmset( struct usb_serial_port *port,
  689.         struct file *filp, unsigned int set, unsigned int clear )
  690. {
  691. #endif
  692.     struct ch34x_private *priv = usb_get_serial_port_data(port);
  693.     unsigned long flags;
  694.     /*unsigned int mcr = priv->line_control;*/
  695.     u8 control;
  696.  
  697.     dbg_ch34x("%s - port:%d", __func__, port->number);
  698.  
  699.     if( !usb_get_intfdata(port->serial->interface) )
  700.         return -ENODEV;
  701.  
  702.     spin_lock_irqsave( &priv->lock, flags );
  703.     if( set & TIOCM_RTS )
  704.         priv->line_control |= CONTROL_RTS;
  705.     if( set & TIOCM_DTR )
  706.         priv->line_control |= CONTROL_DTR;
  707.     if( clear & TIOCM_RTS )
  708.         priv->line_control &= ~CONTROL_RTS;
  709.     if( clear & TIOCM_DTR )
  710.         priv->line_control &= ~CONTROL_DTR;
  711.     control = priv->line_control;
  712.     spin_unlock_irqrestore( &priv->lock, flags );
  713.  
  714.     return set_control_lines( port->serial, control );
  715. }
  716.  
  717. static int wait_modem_info( struct usb_serial_port *port,
  718.         unsigned int arg )
  719. {
  720.     struct ch34x_private *priv = usb_get_serial_port_data(port);
  721.     unsigned long flags;
  722.     unsigned int prevstatus;
  723.     unsigned int status;
  724.     unsigned int changed;
  725.  
  726.     dbg_ch34x("%s -port:%d", __func__, port->number);
  727.  
  728.     spin_lock_irqsave( &priv->lock, flags );
  729.     prevstatus = priv->line_status;
  730.     spin_unlock_irqrestore( &priv->lock, flags );
  731.  
  732.     while(1) {
  733.         interruptible_sleep_on( &priv->delta_msr_wait );
  734.         // see if a signal did it
  735.         if( signal_pending(current) )
  736.             return -ERESTARTSYS;
  737.  
  738.         spin_lock_irqsave( &priv->lock, flags );
  739.         status = priv->line_status;
  740.         spin_unlock_irqrestore( &priv->lock, flags );
  741.  
  742.         changed = prevstatus ^ status;
  743.  
  744.         if( ((arg & TIOCM_RNG) && (changed & UART_RING)) ||
  745.             ((arg & TIOCM_DSR) && (changed & UART_DSR))  ||
  746.             ((arg & TIOCM_CD)  && (changed & UART_DCD))  ||
  747.             ((arg & TIOCM_CTS) && (changed & UART_CTS)) )
  748.             return 0;
  749.  
  750.         prevstatus = status;
  751.     }
  752.  
  753.     // Not reatched
  754.     return 0;
  755. }
  756.  
  757. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,3))
  758. static int ch34x_ioctl( struct tty_struct *tty,
  759.         unsigned int cmd, unsigned long arg )
  760. {
  761.     struct usb_serial_port *port = tty->driver_data;
  762. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  763. static int ch34x_ioctl( struct tty_struct *tty,
  764.         struct file *filp, unsigned int cmd, unsigned long arg )
  765. {
  766.     struct usb_serial_port *port = tty->driver_data;
  767. #else
  768. static int ch34x_ioctl( struct usb_serial_port *port,
  769.         struct file *filp, unsigned int cmd, unsigned long arg )
  770. {
  771.     //struct usb_serial_port *port = tty->driver_data;
  772. #endif
  773.     dbg_ch34x("%s - port:%d, cmd=0x%04x", __func__, port->number, cmd);
  774.  
  775.     switch(cmd)
  776.     {
  777.         // Note here
  778.         case TIOCMIWAIT:
  779.             dbg_ch34x("%s - port:%d TIOCMIWAIT", __func__, port->number);
  780.             return wait_modem_info(port, arg);
  781.         default:
  782.             dbg_ch34x("%s not supported=0x%04x", __func__, cmd);
  783.             break;
  784.     }
  785.  
  786.     return -ENOIOCTLCMD;
  787. }
  788.  
  789. static void ch34x_send( struct usb_serial_port *port )
  790. {
  791.     int count;
  792.     int retval;
  793.     struct ch34x_private *priv = usb_get_serial_port_data( port );
  794.     unsigned long flags;
  795.  
  796.     dbg_ch34x("%s - port:%d", __func__, port->number );
  797.  
  798.     spin_lock_irqsave( &priv->lock, flags );
  799.     if( priv->write_urb_in_use ) {
  800.         spin_unlock_irqrestore( &priv->lock, flags );
  801.         return;
  802.     }
  803.  
  804.     count = ch34x_buf_get( priv->buf, port->write_urb->transfer_buffer,
  805.             port->bulk_out_size );
  806.     if( count == 0 ) {
  807.         spin_unlock_irqrestore( &priv->lock, flags );
  808.         return;
  809.     }
  810.  
  811.     priv->write_urb_in_use = 1;
  812.     spin_unlock_irqrestore( &priv->lock, flags );
  813.  
  814. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,1))
  815.     usb_serial_debug_data( &port->dev, __func__, count,
  816.             port->write_urb->transfer_buffer );
  817. #else
  818.     usb_serial_debug_data( debug, &port->dev, __func__, count,
  819.             port->write_urb->transfer_buffer );
  820. #endif
  821.  
  822.     port->write_urb->transfer_buffer_length = count;
  823.     port->write_urb->dev = port->serial->dev;
  824.     retval = usb_submit_urb( port->write_urb, GFP_ATOMIC );
  825.     if( retval ) {
  826.         dev_err( &port->dev, "%s - failed submitting write urb,error %d\n"
  827.                 , __func__, retval );
  828.         priv->write_urb_in_use = 0;
  829.         // reschedule ch34x_send
  830.     }
  831.  
  832.     usb_serial_port_softint( port );
  833. }
  834.  
  835. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  836. static int ch34x_write( struct tty_struct *tty,
  837.         struct usb_serial_port *port, const unsigned char *buf, int count )
  838. #else
  839. static int ch34x_write( struct usb_serial_port *port,
  840.         const unsigned char *buf, int count )
  841. #endif
  842. {
  843.     struct ch34x_private *priv = usb_get_serial_port_data(port);
  844.     unsigned long flags;
  845.  
  846.     dbg_ch34x("%s - port:%d, %d bytes", __func__, port->number, count);
  847.  
  848.     if( !count )
  849.         return count;
  850.  
  851.     spin_lock_irqsave( &priv->lock, flags );
  852.     count = ch34x_buf_put( priv->buf, buf, count );
  853.     spin_unlock_irqrestore( &priv->lock, flags );
  854.  
  855.     ch34x_send(port);
  856.  
  857.     return count;
  858. }
  859.  
  860. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  861. static int ch34x_write_room( struct tty_struct *tty )
  862. {
  863.     struct usb_serial_port *port = tty->driver_data;
  864. #else
  865. static int ch34x_write_room( struct usb_serial_port *port )
  866. {
  867. #endif
  868.     struct ch34x_private *priv = usb_get_serial_port_data( port );
  869.     int room = 0;
  870.     unsigned long flags;
  871.  
  872.     dbg_ch34x("%s - port:%d", __func__, port->number );
  873.  
  874.     spin_lock_irqsave( &priv->lock, flags );
  875.     room = ch34x_buf_space_avail( priv->buf );
  876.     spin_unlock_irqrestore( &priv->lock, flags );
  877.  
  878.     dbg_ch34x("%s - room:%d", __func__, room );
  879.     return room;
  880. }
  881.  
  882. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  883. static int ch34x_chars_in_buffer( struct tty_struct *tty )
  884. {
  885.     struct usb_serial_port *port = tty->driver_data;
  886. #else
  887. static int ch34x_chars_in_buffer( struct usb_serial_port *port )
  888. {
  889. #endif
  890.     struct ch34x_private *priv = usb_get_serial_port_data(port);
  891.     int chars = 0;
  892.     unsigned long flags;
  893.  
  894.     dbg_ch34x("%s - port:%d", __func__, port->number );
  895.  
  896.     spin_lock_irqsave( &priv->lock, flags );
  897.     chars = ch34x_buf_data_avail( priv->buf );
  898.     spin_unlock_irqrestore( &priv->lock, flags );
  899.  
  900.     dbg_ch34x("%s - chars:%d", __func__, chars );
  901.  
  902.     return chars;
  903. }
  904.  
  905. static int ch34x_attach( struct usb_serial *serial )
  906. {
  907.     struct ch34x_private *priv;
  908.     int i;
  909.     char buf[8];
  910.  
  911.     dbg_ch34x("%s", __func__);
  912.  
  913.     for( i = 0; i < serial->num_ports; ++i ) {
  914.         priv = kzalloc( sizeof(struct ch34x_private), GFP_KERNEL );
  915.         if( !priv )
  916.             goto cleanup;
  917.         spin_lock_init( &priv->lock );
  918.         priv->buf = ch34x_buf_alloc( CH34x_BUF_SIZE );
  919.         if( priv->buf == NULL ) {
  920.             kfree( priv );
  921.             goto cleanup;
  922.         }
  923.         init_waitqueue_head( &priv->delta_msr_wait );
  924.         usb_set_serial_port_data( serial->port[i], priv );
  925.     }
  926.  
  927.     ch34x_vendor_read( VENDOR_VERSION, 0x0000, 0x0000,
  928.             serial, buf, 0x02 );
  929.     ch34x_vendor_write( VENDOR_SERIAL_INIT, 0x0000, 0x0000,
  930.             serial, NULL, 0x00 );
  931.     ch34x_vendor_write( VENDOR_WRITE, 0x1312, 0xD982,
  932.             serial, NULL, 0x00 );
  933.     ch34x_vendor_write( VENDOR_WRITE, 0x0F2C, 0x0004,
  934.             serial, NULL, 0x00 );
  935.     ch34x_vendor_read( VENDOR_READ, 0x2518, 0x0000,
  936.             serial, buf, 0x02 );
  937.     ch34x_vendor_write( VENDOR_WRITE, 0x2727, 0x0000,
  938.             serial, NULL, 0x00 );
  939.     ch34x_vendor_write( VENDOR_MODEM_OUT, 0x009F, 0x0000,
  940.             serial, NULL, 0x00 );
  941.  
  942.     return 0;
  943.  
  944. cleanup:
  945.     for( --i; i >= 0; --i ) {
  946.         priv = usb_get_serial_port_data( serial->port[i] );
  947.         ch34x_buf_free( priv->buf );
  948.         kfree( priv );
  949.         usb_set_serial_port_data( serial->port[i], NULL );
  950.     }
  951.  
  952.     return -ENOMEM;
  953. }
  954.  
  955. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32))
  956. static void ch34x_shutdown( struct usb_serial *serial )
  957. {
  958.     struct ch34x_private *priv;
  959.     int i;
  960.  
  961.     dbg_ch34x("%s", __func__);
  962.  
  963.     for( i = 0; i < serial->num_ports; ++i ) {
  964.         priv = usb_get_serial_port_data( serial->port[i] );
  965.         if( priv ) {
  966.             ch34x_buf_free( priv->buf );
  967.             kfree( priv );
  968.             usb_set_serial_port_data( serial->port[i], NULL );
  969.         }
  970.     }
  971. }
  972. #endif
  973.  
  974. static void ch34x_update_line_status( struct usb_serial_port *port,
  975.         unsigned char *data, unsigned int actual_length )
  976. {
  977.     struct ch34x_private *priv = usb_get_serial_port_data( port );
  978.     unsigned long flags;
  979.     u8 length = UART_STATE + 0x04;
  980.  
  981.     if( actual_length < length )
  982.         return;
  983.  
  984.     // Save off the uart status for others to look at
  985.     spin_lock_irqsave( &priv->lock, flags );
  986.     priv->line_status = data[UART_STATE];
  987.     priv->line_control = data[PORTB_STATE];
  988.     spin_unlock_irqrestore( &priv->lock, flags );
  989.     wake_up_interruptible( &priv->delta_msr_wait );
  990. }
  991.  
  992. static void ch34x_read_int_callback( struct urb *urb )
  993. {
  994.     struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
  995.     unsigned char *data = urb->transfer_buffer;
  996.     unsigned int actual_length = urb->actual_length;
  997.     int status = urb->status;
  998.     int retval;
  999.  
  1000.     dbg_ch34x("%s port:%d", __func__, port->number );
  1001.  
  1002.     switch( status ) {
  1003.         case 0: //success
  1004.             break;
  1005.         case -ECONNRESET:
  1006.         case -ENOENT:
  1007.         case -ESHUTDOWN: //this urb is terminated, clean up
  1008.             dbg_ch34x("%s - urb shutting down with status:%d", __func__, status );
  1009.             return;
  1010.         default:
  1011.             dbg_ch34x("%s - nonzero urb status received:%d", __func__, status );
  1012.             goto exit;
  1013.     }
  1014.  
  1015. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,1))
  1016.     usb_serial_debug_data( &port->dev, __func__,
  1017.             urb->actual_length, urb->transfer_buffer );
  1018. #else
  1019.     usb_serial_debug_data( debug, &port->dev,
  1020.             __func__, urb->actual_length, urb->transfer_buffer );
  1021. #endif
  1022.  
  1023.     ch34x_update_line_status( port, data, actual_length );
  1024.  
  1025. exit:
  1026.     retval = usb_submit_urb( urb, GFP_ATOMIC );
  1027.     if( retval )
  1028.         dev_err( &urb->dev->dev, "%s - usb_submit_urb failed with result %d\n",
  1029.                 __func__, retval );
  1030. }
  1031.  
  1032. static void ch34x_read_bulk_callback( struct urb *urb )
  1033. {
  1034.     struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
  1035.     struct ch34x_private *priv = usb_get_serial_port_data( port );
  1036.     struct tty_struct *tty;
  1037.     unsigned char *data = urb->transfer_buffer;
  1038.     unsigned long flags;
  1039.     int i;
  1040.     int retval;
  1041.     int status = urb->status;
  1042.     u8 line_status;
  1043.     char tty_flag;
  1044.  
  1045.     dbg_ch34x("%s - port:%d", __func__, port->number );
  1046.     if( status ) {
  1047.         dbg_ch34x("%s - urb status=%d", __func__, status );
  1048.         if( status == -EPROTO ) {
  1049.             // CH34x mysteriously fails with -EPROTO reschedule the read
  1050.             dbg_ch34x("%s - caught -EPROTO, resubmitting the urb", __func__);
  1051.             urb->dev = port->serial->dev;
  1052.             retval = usb_submit_urb( urb, GFP_ATOMIC );
  1053.             if( retval ) {
  1054.                 dev_err( &urb->dev->dev,
  1055.                         "%s - failed resubmitting read urb, error %d\n",
  1056.                         __func__, retval );
  1057.                 return;
  1058.             }
  1059.         }
  1060.  
  1061.         dbg_ch34x("%s - unable to handle the error, exiting.", __func__);
  1062.         return;
  1063.     }
  1064.  
  1065. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,1))
  1066.     usb_serial_debug_data( &port->dev, __func__,
  1067.             urb->actual_length, data );
  1068. #else
  1069.     usb_serial_debug_data( debug, &port->dev,
  1070.             __func__, urb->actual_length, data );
  1071. #endif
  1072.  
  1073.     // get tty_flag from status
  1074.     tty_flag = TTY_NORMAL;
  1075.  
  1076.     spin_lock_irqsave( &priv->lock, flags );
  1077.     line_status = priv->line_status;
  1078.     priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
  1079.     spin_unlock_irqrestore( &priv->lock, flags );
  1080.     wake_up_interruptible( &priv->delta_msr_wait );
  1081.  
  1082.     // break takes precedence over parity,
  1083.     // which takes precedence over framing errors
  1084.     if( line_status & UART_PARITY_ERROR )
  1085.         tty_flag = TTY_PARITY;
  1086.     else if( line_status & UART_OVERRUN_ERROR )
  1087.         tty_flag = TTY_OVERRUN;
  1088.     else if( line_status & UART_FRAME_ERROR )
  1089.         tty_flag = TTY_FRAME;
  1090.     dbg_ch34x("%s - tty_flag=%d", __func__, tty_flag);
  1091.  
  1092. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
  1093.     tty = port->port.tty;
  1094. #else
  1095.     tty = port->tty;
  1096. #endif
  1097.     if( tty && urb->actual_length ) {
  1098. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,1))
  1099.         tty_buffer_request_room( tty->port, urb->actual_length + 1);
  1100. #else
  1101.         tty_buffer_request_room( tty, urb->actual_length + 1 );
  1102. #endif
  1103.         // overrun is special, not associated with a char
  1104.         if( line_status & UART_OVERRUN_ERROR )
  1105. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,1))
  1106.             tty_insert_flip_char( tty->port, 0, TTY_OVERRUN );
  1107. #else
  1108.             tty_insert_flip_char( tty, 0, TTY_OVERRUN );
  1109. #endif
  1110.         for( i = 0; i < urb->actual_length; ++i )
  1111. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,1))
  1112.             tty_insert_flip_char( tty->port, data[i], tty_flag );
  1113. #else
  1114.             tty_insert_flip_char( tty, data[i], tty_flag );
  1115. #endif
  1116.  
  1117. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,1))
  1118.         tty_flip_buffer_push( tty->port );
  1119. #else
  1120.         tty_flip_buffer_push( tty );
  1121. #endif
  1122.     }
  1123.  
  1124.     //Schedule the next read _if_ we are still open
  1125. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
  1126.     if( port->open_count )
  1127. #endif
  1128.     {
  1129.         urb->dev = port->serial->dev;
  1130.         retval = usb_submit_urb( urb, GFP_ATOMIC );
  1131.         if( retval )
  1132.             dev_err( &urb->dev->dev,
  1133.                     "%s - fialed resubmitting read urb, error %d\n",
  1134.                     __func__, retval );
  1135.     }
  1136.  
  1137.     return;
  1138. }
  1139.  
  1140. static void ch34x_write_bulk_callback( struct urb *urb )
  1141. {
  1142.     struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
  1143.     struct ch34x_private *priv = usb_get_serial_port_data(port);
  1144.     int retval;
  1145.     int status = urb->status;
  1146.  
  1147.     dbg_ch34x("%s - port:%d", __func__, port->number );
  1148.  
  1149.     switch( status ) {
  1150.         case 0: //success
  1151.             break;
  1152.         case -ECONNRESET:
  1153.         case -ENOENT:
  1154.         case -ESHUTDOWN:
  1155.             // this urb is terminated, clean up
  1156.             dbg_ch34x("%s - urb shutting down with status:%d", __func__, status);
  1157.             priv->write_urb_in_use = 0;
  1158.             return;
  1159.         default:
  1160.             // error in the urb, so we have to resubmit it
  1161.             dbg_ch34x("%s - Overflow in write", __func__);
  1162.             dbg_ch34x("%s - nonzero write bulk status received:%d", __func__, status);
  1163.             port->write_urb->transfer_buffer_length = 1;
  1164.             port->write_urb->dev = port->serial->dev;
  1165.             retval = usb_submit_urb(port->write_urb, GFP_ATOMIC);
  1166.             if( retval )
  1167.                 dev_err( &urb->dev->dev,
  1168.                         "%s - failed resubmitting write urv, error:%d\n",
  1169.                         __func__, retval );
  1170.             else
  1171.                 return;
  1172.     }
  1173.  
  1174.     priv->write_urb_in_use = 0;
  1175.  
  1176.     // send any buffered data
  1177.     ch34x_send(port);
  1178. }
  1179.  
  1180. static struct usb_serial_driver ch34x_device = {
  1181.     .driver = {
  1182.         .owner  = THIS_MODULE,
  1183.         .name   = "ch34x",
  1184.     },
  1185.     .id_table   = id_table,
  1186. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,1))
  1187.     .usb_driver = &ch34x_driver,
  1188. #endif
  1189.     .num_ports      = 1,
  1190.     .open           = ch34x_open,
  1191.     .close          = ch34x_close,
  1192.     .write          = ch34x_write,
  1193.     .ioctl          = ch34x_ioctl,
  1194.     .set_termios    = ch34x_set_termios,
  1195.     .tiocmget       = ch34x_tiocmget,
  1196.     .tiocmset       = ch34x_tiocmset,
  1197.     .read_bulk_callback  = ch34x_read_bulk_callback,
  1198.     .read_int_callback   = ch34x_read_int_callback,
  1199.     .write_bulk_callback = ch34x_write_bulk_callback,
  1200.     .write_room     = ch34x_write_room,
  1201.     .chars_in_buffer = ch34x_chars_in_buffer,
  1202.     .attach         = ch34x_attach,
  1203. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) )
  1204.     .shutdown       = ch34x_shutdown,
  1205. #endif
  1206. };
  1207.  
  1208. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,5))
  1209. static struct usb_serial_driver *const serial_driver [] = {
  1210.     &ch34x_device, NULL
  1211. };
  1212. #endif
  1213.  
  1214.  
  1215. static int __init ch34x_init(void)
  1216. {
  1217. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,5))
  1218.     int retval = 0;
  1219.  
  1220.     retval = usb_serial_register( &ch34x_device );
  1221.     if( retval ) {
  1222.         goto err_usb_serial_register;
  1223.     }
  1224.     retval = usb_register( &ch34x_driver );
  1225.     if( retval ) {
  1226.         goto err_usb_register;
  1227.     }
  1228. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32))
  1229.     info( DRIVER_DESC );
  1230. #endif
  1231.     return 0;
  1232.  
  1233. err_usb_register:
  1234.     usb_deregister( &ch34x_driver );
  1235. err_usb_serial_register:
  1236.     usb_serial_deregister( &ch34x_device );
  1237.     return retval;
  1238. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,1))
  1239.     return usb_serial_register_drivers( serial_driver,
  1240.             KBUILD_MODNAME, id_table );
  1241. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,5) && \
  1242.         LINUX_VERSION_CODE < KERNEL_VERSION(3,5,1))
  1243.     return usb_serial_register_drivers(&ch34x_driver, serial_driver);
  1244. #endif
  1245. }
  1246.  
  1247. static void __exit ch34x_exit(void)
  1248. {
  1249. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,5))
  1250.     usb_deregister( &ch34x_driver );
  1251.     usb_serial_deregister( &ch34x_device );
  1252. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,1))
  1253.     usb_serial_deregister_drivers( serial_driver );
  1254. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,5) && \
  1255.         LINUX_VERSION_CODE < KERNEL_VERSION(3,5,1))
  1256.     usb_serial_deregister_drivers(&ch34x_driver, serial_driver);
  1257. #endif
  1258. }
  1259.  
  1260. module_init( ch34x_init );
  1261. module_exit( ch34x_exit );
  1262.  
  1263.  
  1264. MODULE_DESCRIPTION(DRIVER_DESC);
  1265. MODULE_AUTHOR(DRIVER_AUTHOR);
  1266. MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement