http://blog.csdn.net/geekcome/article/details/7194988

 

主机:Gentoo Linux 11.2

内核版本:Linux 3.0.6

原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7194988

以前在Ubuntu下USB转串口驱动已经编译进内核,而编译的Gentoo内核没有编译进去,这里将内核中PL2303驱动 copy出来单独编译出pl2303.ko然后将其复制进/var/lib/(内核版本)/drivers/usb/serial/目录下

然后使用命令

depmod

modprobe pl2303

然后将usb转串口接口插入usb,使用命令查看dmesg | tail查看如下

查看内核中驱动,看到usbserial.ko驱动,下面单独编译pl2303.ko

从内核中拷贝的pl2303.h

  1. /* 
  2.  * Prolific PL2303 USB to serial adaptor driver header file 
  3.  * 
  4.  *  This program is free software; you can redistribute it and/or modify 
  5.  *  it under the terms of the GNU General Public License as published by 
  6.  *  the Free Software Foundation; either version 2 of the License, or 
  7.  *  (at your option) any later version. 
  8.  * 
  9.  */  
  10.   
  11. #define BENQ_VENDOR_ID          0x04a5  
  12. #define BENQ_PRODUCT_ID_S81     0x4027  
  13.   
  14. #define PL2303_VENDOR_ID    0x067b  
  15. #define PL2303_PRODUCT_ID   0x2303  
  16. #define PL2303_PRODUCT_ID_RSAQ2     0x04bb  
  17. #define PL2303_PRODUCT_ID_DCU11     0x1234  
  18. #define PL2303_PRODUCT_ID_PHAROS    0xaaa0  
  19. #define PL2303_PRODUCT_ID_RSAQ3     0xaaa2  
  20. #define PL2303_PRODUCT_ID_ALDIGA    0x0611  
  21. #define PL2303_PRODUCT_ID_MMX       0x0612  
  22. #define PL2303_PRODUCT_ID_GPRS      0x0609  
  23. #define PL2303_PRODUCT_ID_HCR331    0x331a  
  24. #define PL2303_PRODUCT_ID_MOTOROLA  0x0307  
  25.   
  26. #define ATEN_VENDOR_ID      0x0557  
  27. #define ATEN_VENDOR_ID2     0x0547  
  28. #define ATEN_PRODUCT_ID     0x2008  
  29.   
  30. #define IODATA_VENDOR_ID    0x04bb  
  31. #define IODATA_PRODUCT_ID   0x0a03  
  32. #define IODATA_PRODUCT_ID_RSAQ5 0x0a0e  
  33.   
  34. #define ELCOM_VENDOR_ID     0x056e  
  35. #define ELCOM_PRODUCT_ID    0x5003  
  36. #define ELCOM_PRODUCT_ID_UCSGT  0x5004  
  37.   
  38. #define ITEGNO_VENDOR_ID    0x0eba  
  39. #define ITEGNO_PRODUCT_ID   0x1080  
  40. #define ITEGNO_PRODUCT_ID_2080  0x2080  
  41.   
  42. #define MA620_VENDOR_ID     0x0df7  
  43. #define MA620_PRODUCT_ID    0x0620  
  44.   
  45. #define RATOC_VENDOR_ID     0x0584  
  46. #define RATOC_PRODUCT_ID    0xb000  
  47.   
  48. #define TRIPP_VENDOR_ID     0x2478  
  49. #define TRIPP_PRODUCT_ID    0x2008  
  50.   
  51. #define RADIOSHACK_VENDOR_ID    0x1453  
  52. #define RADIOSHACK_PRODUCT_ID   0x4026  
  53.   
  54. #define DCU10_VENDOR_ID     0x0731  
  55. #define DCU10_PRODUCT_ID    0x0528  
  56.   
  57. #define SITECOM_VENDOR_ID   0x6189  
  58. #define SITECOM_PRODUCT_ID  0x2068  
  59.   
  60. /* Alcatel OT535/735 USB cable */  
  61. #define ALCATEL_VENDOR_ID   0x11f7  
  62. #define ALCATEL_PRODUCT_ID  0x02df  
  63.   
  64. /* Samsung I330 phone cradle */  
  65. #define SAMSUNG_VENDOR_ID   0x04e8  
  66. #define SAMSUNG_PRODUCT_ID  0x8001  
  67.   
  68. #define SIEMENS_VENDOR_ID   0x11f5  
  69. #define SIEMENS_PRODUCT_ID_SX1  0x0001  
  70. #define SIEMENS_PRODUCT_ID_X65  0x0003  
  71. #define SIEMENS_PRODUCT_ID_X75  0x0004  
  72. #define SIEMENS_PRODUCT_ID_EF81 0x0005  
  73.   
  74. #define SYNTECH_VENDOR_ID   0x0745  
  75. #define SYNTECH_PRODUCT_ID  0x0001  
  76.   
  77. /* Nokia CA-42 Cable */  
  78. #define NOKIA_CA42_VENDOR_ID    0x078b  
  79. #define NOKIA_CA42_PRODUCT_ID   0x1234  
  80.   
  81. /* CA-42 CLONE Cable www.ca-42.com chipset: Prolific Technology Inc */  
  82. #define CA_42_CA42_VENDOR_ID    0x10b5  
  83. #define CA_42_CA42_PRODUCT_ID   0xac70  
  84.   
  85. #define SAGEM_VENDOR_ID     0x079b  
  86. #define SAGEM_PRODUCT_ID    0x0027  
  87.   
  88. /* Leadtek GPS 9531 (ID 0413:2101) */  
  89. #define LEADTEK_VENDOR_ID   0x0413  
  90. #define LEADTEK_9531_PRODUCT_ID 0x2101  
  91.   
  92. /* USB GSM cable from Speed Dragon Multimedia, Ltd */  
  93. #define SPEEDDRAGON_VENDOR_ID   0x0e55  
  94. #define SPEEDDRAGON_PRODUCT_ID  0x110b  
  95.   
  96. /* DATAPILOT Universal-2 Phone Cable */  
  97. #define DATAPILOT_U2_VENDOR_ID  0x0731  
  98. #define DATAPILOT_U2_PRODUCT_ID 0x2003  
  99.   
  100. /* Belkin “F5U257” Serial Adapter */  
  101. #define BELKIN_VENDOR_ID    0x050d  
  102. #define BELKIN_PRODUCT_ID   0x0257  
  103.   
  104. /* Alcor Micro Corp. USB 2.0 TO RS-232 */  
  105. #define ALCOR_VENDOR_ID     0x058F  
  106. #define ALCOR_PRODUCT_ID    0x9720  
  107.   
  108. /* Willcom WS002IN Data Driver (by NetIndex Inc.) */  
  109. #define WS002IN_VENDOR_ID   0x11f6  
  110. #define WS002IN_PRODUCT_ID  0x2001  
  111.   
  112. /* Corega CG-USBRS232R Serial Adapter */  
  113. #define COREGA_VENDOR_ID    0x07aa  
  114. #define COREGA_PRODUCT_ID   0x002a  
  115.   
  116. /* Y.C. Cable U.S.A., Inc – USB to RS-232 */  
  117. #define YCCABLE_VENDOR_ID   0x05ad  
  118. #define YCCABLE_PRODUCT_ID  0x0fba  
  119.   
  120. /* “Superial” USB – Serial */  
  121. #define SUPERIAL_VENDOR_ID  0x5372  
  122. #define SUPERIAL_PRODUCT_ID 0x2303  
  123.   
  124. /* Hewlett-Packard LD220-HP POS Pole Display */  
  125. #define HP_VENDOR_ID        0x03f0  
  126. #define HP_LD220_PRODUCT_ID 0x3524  
  127.   
  128. /* Cressi Edy (diving computer) PC interface */  
  129. #define CRESSI_VENDOR_ID    0x04b8  
  130. #define CRESSI_EDY_PRODUCT_ID   0x0521  
  131.   
  132. /* Zeagle dive computer interface */  
  133. #define ZEAGLE_VENDOR_ID    0x04b8  
  134. #define ZEAGLE_N2ITION3_PRODUCT_ID  0x0522  
  135.   
  136. /* Sony, USB data cable for CMD-Jxx mobile phones */  
  137. #define SONY_VENDOR_ID      0x054c  
  138. #define SONY_QN3USB_PRODUCT_ID  0x0437  
  139.   
  140. /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */  
  141. #define SANWA_VENDOR_ID     0x11ad  
  142. #define SANWA_PRODUCT_ID    0x0001  
  143.   
  144. /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */  
  145. #define ADLINK_VENDOR_ID        0x0b63  
  146. #define ADLINK_ND6530_PRODUCT_ID    0x6530  
  147.   
  148. /* WinChipHead USB->RS 232 adapter */  
  149. #define WINCHIPHEAD_VENDOR_ID       0x4348  
  150. #define WINCHIPHEAD_USBSER_PRODUCT_ID   0x5523  

pl2303.c代码

 

  1. /* 
  2.  * Prolific PL2303 USB to serial adaptor driver 
  3.  * 
  4.  * Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com) 
  5.  * Copyright (C) 2003 IBM Corp. 
  6.  * 
  7.  * Original driver for 2.2.x by anonymous 
  8.  * 
  9.  *  This program is free software; you can redistribute it and/or 
  10.  *  modify it under the terms of the GNU General Public License version 
  11.  *  2 as published by the Free Software Foundation. 
  12.  * 
  13.  * See Documentation/usb/usb-serial.txt for more information on using this 
  14.  * driver 
  15.  * 
  16.  */  
  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 <linux/uaccess.h>  
  30. #include <linux/usb.h>  
  31. #include <linux/usb/serial.h>  
  32. #include “pl2303.h”  
  33.   
  34. /* 
  35.  * Version Information 
  36.  */  
  37. #define DRIVER_DESC “Prolific PL2303 USB to serial adaptor driver”  
  38.   
  39. static int debug;  
  40.   
  41. #define PL2303_CLOSING_WAIT (30*HZ)  
  42.   
  43. static const struct usb_device_id id_table[] = {  
  44.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },  
  45.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },  
  46.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) },  
  47.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },  
  48.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },  
  49.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },  
  50.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },  
  51.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },  
  52.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },  
  53.     { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) },  
  54.     { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },  
  55.     { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },  
  56.     { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },  
  57.     { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },  
  58.     { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },  
  59.     { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID_UCSGT) },  
  60.     { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },  
  61.     { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) },  
  62.     { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },  
  63.     { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },  
  64.     { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },  
  65.     { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) },  
  66.     { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) },  
  67.     { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) },  
  68.     { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) },  
  69.     { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) },  
  70.     { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) },  
  71.     { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },  
  72.     { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) },  
  73.     { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81) },  
  74.     { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_ID_S81) }, /* Benq/Siemens S81 */  
  75.     { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },  
  76.     { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) },  
  77.     { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) },  
  78.     { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) },  
  79.     { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) },  
  80.     { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },  
  81.     { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },  
  82.     { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },  
  83.     { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },  
  84.     { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },  
  85.     { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },  
  86.     { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },  
  87.     { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },  
  88.     { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },  
  89.     { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },  
  90.     { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },  
  91.     { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },  
  92.     { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },  
  93.     { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },  
  94.     { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) },  
  95.     { }                 /* Terminating entry */  
  96. };  
  97.   
  98. MODULE_DEVICE_TABLE(usb, id_table);  
  99.   
  100. static struct usb_driver pl2303_driver = {  
  101.     .name =     “pl2303”,  
  102.     .probe =    usb_serial_probe,  
  103.     .disconnect =   usb_serial_disconnect,  
  104.     .id_table = id_table,  
  105.     .suspend =      usb_serial_suspend,  
  106.     .resume =       usb_serial_resume,  
  107.     .no_dynamic_id =    1,  
  108.     .supports_autosuspend = 1,  
  109. };  
  110.   
  111. #define SET_LINE_REQUEST_TYPE       0x21  
  112. #define SET_LINE_REQUEST        0x20  
  113.   
  114. #define SET_CONTROL_REQUEST_TYPE    0x21  
  115. #define SET_CONTROL_REQUEST     0x22  
  116. #define CONTROL_DTR         0x01  
  117. #define CONTROL_RTS         0x02  
  118.   
  119. #define BREAK_REQUEST_TYPE      0x21  
  120. #define BREAK_REQUEST           0x23  
  121. #define BREAK_ON            0xffff  
  122. #define BREAK_OFF           0x0000  
  123.   
  124. #define GET_LINE_REQUEST_TYPE       0xa1  
  125. #define GET_LINE_REQUEST        0x21  
  126.   
  127. #define VENDOR_WRITE_REQUEST_TYPE   0x40  
  128. #define VENDOR_WRITE_REQUEST        0x01  
  129.   
  130. #define VENDOR_READ_REQUEST_TYPE    0xc0  
  131. #define VENDOR_READ_REQUEST     0x01  
  132.   
  133. #define UART_STATE          0x08  
  134. #define UART_STATE_TRANSIENT_MASK   0x74  
  135. #define UART_DCD            0x01  
  136. #define UART_DSR            0x02  
  137. #define UART_BREAK_ERROR        0x04  
  138. #define UART_RING           0x08  
  139. #define UART_FRAME_ERROR        0x10  
  140. #define UART_PARITY_ERROR       0x20  
  141. #define UART_OVERRUN_ERROR      0x40  
  142. #define UART_CTS            0x80  
  143.   
  144.   
  145. enum pl2303_type {  
  146.     type_0,     /* don\’t know the difference between type 0 and */  
  147.     type_1,     /* type 1, until someone from prolific tells us… */  
  148.     HX,     /* HX version of the pl2303 chip */  
  149. };  
  150.   
  151. struct pl2303_private {  
  152.     spinlock_t lock;  
  153.     wait_queue_head_t delta_msr_wait;  
  154.     u8 line_control;  
  155.     u8 line_status;  
  156.     enum pl2303_type type;  
  157. };  
  158.   
  159. static int pl2303_vendor_read(__u16 value, __u16 index,  
  160.         struct usb_serial *serial, unsigned char *buf)  
  161. {  
  162.     int res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),  
  163.             VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE,  
  164.             value, index, buf, 1, 100);  
  165.     dbg(“0x%x:0x%x:0x%x:0x%x  %d – %x”, VENDOR_READ_REQUEST_TYPE,  
  166.             VENDOR_READ_REQUEST, value, index, res, buf[0]);  
  167.     return res;  
  168. }  
  169.   
  170. static int pl2303_vendor_write(__u16 value, __u16 index,  
  171.         struct usb_serial *serial)  
  172. {  
  173.     int res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),  
  174.             VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE,  
  175.             value, index, NULL, 0, 100);  
  176.     dbg(“0x%x:0x%x:0x%x:0x%x  %d”, VENDOR_WRITE_REQUEST_TYPE,  
  177.             VENDOR_WRITE_REQUEST, value, index, res);  
  178.     return res;  
  179. }  
  180.   
  181. static int pl2303_startup(struct usb_serial *serial)  
  182. {  
  183.     struct pl2303_private *priv;  
  184.     enum pl2303_type type = type_0;  
  185.     unsigned char *buf;  
  186.     int i;  
  187.   
  188.     buf = kmalloc(10, GFP_KERNEL);  
  189.     if (buf == NULL)  
  190.         return -ENOMEM;  
  191.   
  192.     if (serial->dev->descriptor.bDeviceClass == 0x02)  
  193.         type = type_0;  
  194.     else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40)  
  195.         type = HX;  
  196.     else if (serial->dev->descriptor.bDeviceClass == 0x00)  
  197.         type = type_1;  
  198.     else if (serial->dev->descriptor.bDeviceClass == 0xFF)  
  199.         type = type_1;  
  200.     dbg(“device type: %d”, type);  
  201.   
  202.     for (i = 0; i < serial->num_ports; ++i) {  
  203.         priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL);  
  204.         if (!priv)  
  205.             goto cleanup;  
  206.         spin_lock_init(&priv->lock);  
  207.         init_waitqueue_head(&priv->delta_msr_wait);  
  208.         priv->type = type;  
  209.         usb_set_serial_port_data(serial->port[i], priv);  
  210.     }  
  211.   
  212.     pl2303_vendor_read(0x8484, 0, serial, buf);  
  213.     pl2303_vendor_write(0x0404, 0, serial);  
  214.     pl2303_vendor_read(0x8484, 0, serial, buf);  
  215.     pl2303_vendor_read(0x8383, 0, serial, buf);  
  216.     pl2303_vendor_read(0x8484, 0, serial, buf);  
  217.     pl2303_vendor_write(0x0404, 1, serial);  
  218.     pl2303_vendor_read(0x8484, 0, serial, buf);  
  219.     pl2303_vendor_read(0x8383, 0, serial, buf);  
  220.     pl2303_vendor_write(0, 1, serial);  
  221.     pl2303_vendor_write(1, 0, serial);  
  222.     if (type == HX)  
  223.         pl2303_vendor_write(2, 0x44, serial);  
  224.     else  
  225.         pl2303_vendor_write(2, 0x24, serial);  
  226.   
  227.     kfree(buf);  
  228.     return 0;  
  229.   
  230. cleanup:  
  231.     kfree(buf);  
  232.     for (–i; i >= 0; –i) {  
  233.         priv = usb_get_serial_port_data(serial->port[i]);  
  234.         kfree(priv);  
  235.         usb_set_serial_port_data(serial->port[i], NULL);  
  236.     }  
  237.     return -ENOMEM;  
  238. }  
  239.   
  240. static int set_control_lines(struct usb_device *dev, u8 value)  
  241. {  
  242.     int retval;  
  243.   
  244.     retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),  
  245.                  SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,  
  246.                  value, 0, NULL, 0, 100);  
  247.     dbg(“%s – value = %d, retval = %d”, __func__, value, retval);  
  248.     return retval;  
  249. }  
  250.   
  251. static void pl2303_set_termios(struct tty_struct *tty,  
  252.         struct usb_serial_port *port, struct ktermios *old_termios)  
  253. {  
  254.     struct usb_serial *serial = port->serial;  
  255.     struct pl2303_private *priv = usb_get_serial_port_data(port);  
  256.     unsigned long flags;  
  257.     unsigned int cflag;  
  258.     unsigned char *buf;  
  259.     int baud;  
  260.     int i;  
  261.     u8 control;  
  262.     const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600,  
  263.                              4800, 7200, 9600, 14400, 19200, 28800, 38400,  
  264.                              57600, 115200, 230400, 460800, 614400,  
  265.                              921600, 1228800, 2457600, 3000000, 6000000 };  
  266.     int baud_floor, baud_ceil;  
  267.     int k;  
  268.   
  269.     dbg(“%s –  port %d”, __func__, port->number);  
  270.   
  271.     /* The PL2303 is reported to lose bytes if you change 
  272.        serial settings even to the same values as before. Thus 
  273.        we actually need to filter in this specific case */  
  274.   
  275.     if (!tty_termios_hw_change(tty->termios, old_termios))  
  276.         return;  
  277.   
  278.     cflag = tty->termios->c_cflag;  
  279.   
  280.     buf = kzalloc(7, GFP_KERNEL);  
  281.     if (!buf) {  
  282.         dev_err(&port->dev, “%s – out of memory.\n”, __func__);  
  283.         /* Report back no change occurred */  
  284.         *tty->termios = *old_termios;  
  285.         return;  
  286.     }  
  287.   
  288.     i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),  
  289.                 GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,  
  290.                 0, 0, buf, 7, 100);  
  291.     dbg(“0xa1:0x21:0:0  %d – %x %x %x %x %x %x %x”, i,  
  292.         buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);  
  293.   
  294.     if (cflag & CSIZE) {  
  295.         switch (cflag & CSIZE) {  
  296.         case CS5:  
  297.             buf[6] = 5;  
  298.             break;  
  299.         case CS6:  
  300.             buf[6] = 6;  
  301.             break;  
  302.         case CS7:  
  303.             buf[6] = 7;  
  304.             break;  
  305.         default:  
  306.         case CS8:  
  307.             buf[6] = 8;  
  308.             break;  
  309.         }  
  310.         dbg(“%s – data bits = %d”, __func__, buf[6]);  
  311.     }  
  312.   
  313.     /* For reference buf[0]:buf[3] baud rate value */  
  314.     /* NOTE: Only the values defined in baud_sup are supported ! 
  315.      *       => if unsupported values are set, the PL2303 seems to use 
  316.      *          9600 baud (at least my PL2303X always does) 
  317.      */  
  318.     baud = tty_get_baud_rate(tty);  
  319.     dbg(“%s – baud requested = %d”, __func__, baud);  
  320.     if (baud) {  
  321.         /* Set baudrate to nearest supported value */  
  322.         for (k=0; k<ARRAY_SIZE(baud_sup); k++) {  
  323.             if (baud_sup[k] / baud) {  
  324.                 baud_ceil = baud_sup[k];  
  325.                 if (k==0) {  
  326.                     baud = baud_ceil;  
  327.                 } else {  
  328.                     baud_floor = baud_sup[k-1];  
  329.                     if ((baud_ceil % baud)  
  330.                         > (baud % baud_floor))  
  331.                         baud = baud_floor;  
  332.                     else  
  333.                         baud = baud_ceil;  
  334.                 }  
  335.                 break;  
  336.             }  
  337.         }  
  338.         if (baud > 1228800) {  
  339.             /* type_0, type_1 only support up to 1228800 baud */  
  340.             if (priv->type != HX)  
  341.                 baud = 1228800;  
  342.             else if (baud > 6000000)  
  343.                 baud = 6000000;  
  344.         }  
  345.         dbg(“%s – baud set = %d”, __func__, baud);  
  346.         if (baud <= 115200) {  
  347.             buf[0] = baud & 0xff;  
  348.             buf[1] = (baud >> 8) & 0xff;  
  349.             buf[2] = (baud >> 16) & 0xff;  
  350.             buf[3] = (baud >> 24) & 0xff;  
  351.         } else {  
  352.             /* apparently the formula for higher speeds is: 
  353.              * baudrate = 12M * 32 / (2^buf[1]) / buf[0] 
  354.              */  
  355.             unsigned tmp = 12*1000*1000*32 / baud;  
  356.             buf[3] = 0x80;  
  357.             buf[2] = 0;  
  358.             buf[1] = (tmp >= 256);  
  359.             while (tmp >= 256) {  
  360.                 tmp >>= 2;  
  361.                 buf[1] <<= 1;  
  362.             }  
  363.             if (tmp > 256) {  
  364.                 tmp %= 256;  
  365.             }  
  366.             buf[0] = tmp;  
  367.         }  
  368.     }  
  369.   
  370.     /* For reference buf[4]=0 is 1 stop bits */  
  371.     /* For reference buf[4]=1 is 1.5 stop bits */  
  372.     /* For reference buf[4]=2 is 2 stop bits */  
  373.     if (cflag & CSTOPB) {  
  374.         /* NOTE: Comply with “real” UARTs / RS232: 
  375.          *       use 1.5 instead of 2 stop bits with 5 data bits 
  376.          */  
  377.         if ((cflag & CSIZE) == CS5) {  
  378.             buf[4] = 1;  
  379.             dbg(“%s – stop bits = 1.5”, __func__);  
  380.         } else {  
  381.             buf[4] = 2;  
  382.             dbg(“%s – stop bits = 2”, __func__);  
  383.         }  
  384.     } else {  
  385.         buf[4] = 0;  
  386.         dbg(“%s – stop bits = 1”, __func__);  
  387.     }  
  388.   
  389.     if (cflag & PARENB) {  
  390.         /* For reference buf[5]=0 is none parity */  
  391.         /* For reference buf[5]=1 is odd parity */  
  392.         /* For reference buf[5]=2 is even parity */  
  393.         /* For reference buf[5]=3 is mark parity */  
  394.         /* For reference buf[5]=4 is space parity */  
  395.         if (cflag & PARODD) {  
  396.             if (cflag & CMSPAR) {  
  397.                 buf[5] = 3;  
  398.                 dbg(“%s – parity = mark”, __func__);  
  399.             } else {  
  400.                 buf[5] = 1;  
  401.                 dbg(“%s – parity = odd”, __func__);  
  402.             }  
  403.         } else {  
  404.             if (cflag & CMSPAR) {  
  405.                 buf[5] = 4;  
  406.                 dbg(“%s – parity = space”, __func__);  
  407.             } else {  
  408.                 buf[5] = 2;  
  409.                 dbg(“%s – parity = even”, __func__);  
  410.             }  
  411.         }  
  412.     } else {  
  413.         buf[5] = 0;  
  414.         dbg(“%s – parity = none”, __func__);  
  415.     }  
  416.   
  417.     i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),  
  418.                 SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE,  
  419.                 0, 0, buf, 7, 100);  
  420.     dbg(“0x21:0x20:0:0  %d”, i);  
  421.   
  422.     /* change control lines if we are switching to or from B0 */  
  423.     spin_lock_irqsave(&priv->lock, flags);  
  424.     control = priv->line_control;  
  425.     if ((cflag & CBAUD) == B0)  
  426.         priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);  
  427.     else  
  428.         priv->line_control |= (CONTROL_DTR | CONTROL_RTS);  
  429.     if (control != priv->line_control) {  
  430.         control = priv->line_control;  
  431.         spin_unlock_irqrestore(&priv->lock, flags);  
  432.         set_control_lines(serial->dev, control);  
  433.     } else {  
  434.         spin_unlock_irqrestore(&priv->lock, flags);  
  435.     }  
  436.   
  437.     buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;  
  438.   
  439.     i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),  
  440.                 GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,  
  441.                 0, 0, buf, 7, 100);  
  442.     dbg(“0xa1:0x21:0:0  %d – %x %x %x %x %x %x %x”, i,  
  443.          buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);  
  444.   
  445.     if (cflag & CRTSCTS) {  
  446.         if (priv->type == HX)  
  447.             pl2303_vendor_write(0x0, 0x61, serial);  
  448.         else  
  449.             pl2303_vendor_write(0x0, 0x41, serial);  
  450.     } else {  
  451.         pl2303_vendor_write(0x0, 0x0, serial);  
  452.     }  
  453.   
  454.     /* Save resulting baud rate */  
  455.     if (baud)  
  456.         tty_encode_baud_rate(tty, baud, baud);  
  457.   
  458.     kfree(buf);  
  459. }  
  460.   
  461. static void pl2303_dtr_rts(struct usb_serial_port *port, int on)  
  462. {  
  463.     struct pl2303_private *priv = usb_get_serial_port_data(port);  
  464.     unsigned long flags;  
  465.     u8 control;  
  466.   
  467.     spin_lock_irqsave(&priv->lock, flags);  
  468.     /* Change DTR and RTS */  
  469.     if (on)  
  470.         priv->line_control |= (CONTROL_DTR | CONTROL_RTS);  
  471.     else  
  472.         priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);  
  473.     control = priv->line_control;  
  474.     spin_unlock_irqrestore(&priv->lock, flags);  
  475.     set_control_lines(port->serial->dev, control);  
  476. }  
  477.   
  478. static void pl2303_close(struct usb_serial_port *port)  
  479. {  
  480.     dbg(“%s – port %d”, __func__, port->number);  
  481.   
  482.     usb_serial_generic_close(port);  
  483.     usb_kill_urb(port->interrupt_in_urb);  
  484. }  
  485.   
  486. static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)  
  487. {  
  488.     struct ktermios tmp_termios;  
  489.     struct usb_serial *serial = port->serial;  
  490.     struct pl2303_private *priv = usb_get_serial_port_data(port);  
  491.     int result;  
  492.   
  493.     dbg(“%s –  port %d”, __func__, port->number);  
  494.   
  495.     if (priv->type != HX) {  
  496.         usb_clear_halt(serial->dev, port->write_urb->pipe);  
  497.         usb_clear_halt(serial->dev, port->read_urb->pipe);  
  498.     } else {  
  499.         /* reset upstream data pipes */  
  500.         pl2303_vendor_write(8, 0, serial);  
  501.         pl2303_vendor_write(9, 0, serial);  
  502.     }  
  503.   
  504.     /* Setup termios */  
  505.     if (tty)  
  506.         pl2303_set_termios(tty, port, &tmp_termios);  
  507.   
  508.     dbg(“%s – submitting read urb”, __func__);  
  509.     result = usb_serial_generic_submit_read_urb(port, GFP_KERNEL);  
  510.     if (result) {  
  511.         pl2303_close(port);  
  512.         return -EPROTO;  
  513.     }  
  514.   
  515.     dbg(“%s – submitting interrupt urb”, __func__);  
  516.     result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  
  517.     if (result) {  
  518.         dev_err(&port->dev, “%s – failed submitting interrupt urb,”  
  519.             ” error %d\n”, __func__, result);  
  520.         pl2303_close(port);  
  521.         return -EPROTO;  
  522.     }  
  523.     port->port.drain_delay = 256;  
  524.     return 0;  
  525. }  
  526.   
  527. static int pl2303_tiocmset(struct tty_struct *tty,  
  528.                unsigned int set, unsigned int clear)  
  529. {  
  530.     struct usb_serial_port *port = tty->driver_data;  
  531.     struct pl2303_private *priv = usb_get_serial_port_data(port);  
  532.     unsigned long flags;  
  533.     u8 control;  
  534.   
  535.     if (!usb_get_intfdata(port->serial->interface))  
  536.         return -ENODEV;  
  537.   
  538.     spin_lock_irqsave(&priv->lock, flags);  
  539.     if (set & TIOCM_RTS)  
  540.         priv->line_control |= CONTROL_RTS;  
  541.     if (set & TIOCM_DTR)  
  542.         priv->line_control |= CONTROL_DTR;  
  543.     if (clear & TIOCM_RTS)  
  544.         priv->line_control &= ~CONTROL_RTS;  
  545.     if (clear & TIOCM_DTR)  
  546.         priv->line_control &= ~CONTROL_DTR;  
  547.     control = priv->line_control;  
  548.     spin_unlock_irqrestore(&priv->lock, flags);  
  549.   
  550.     return set_control_lines(port->serial->dev, control);  
  551. }  
  552.   
  553. static int pl2303_tiocmget(struct tty_struct *tty)  
  554. {  
  555.     struct usb_serial_port *port = tty->driver_data;  
  556.     struct pl2303_private *priv = usb_get_serial_port_data(port);  
  557.     unsigned long flags;  
  558.     unsigned int mcr;  
  559.     unsigned int status;  
  560.     unsigned int result;  
  561.   
  562.     dbg(“%s (%d)”, __func__, port->number);  
  563.   
  564.     if (!usb_get_intfdata(port->serial->interface))  
  565.         return -ENODEV;  
  566.   
  567.     spin_lock_irqsave(&priv->lock, flags);  
  568.     mcr = priv->line_control;  
  569.     status = priv->line_status;  
  570.     spin_unlock_irqrestore(&priv->lock, flags);  
  571.   
  572.     result = ((mcr & CONTROL_DTR)       ? TIOCM_DTR : 0)  
  573.           | ((mcr & CONTROL_RTS)    ? TIOCM_RTS : 0)  
  574.           | ((status & UART_CTS)    ? TIOCM_CTS : 0)  
  575.           | ((status & UART_DSR)    ? TIOCM_DSR : 0)  
  576.           | ((status & UART_RING)   ? TIOCM_RI  : 0)  
  577.           | ((status & UART_DCD)    ? TIOCM_CD  : 0);  
  578.   
  579.     dbg(“%s – result = %x”, __func__, result);  
  580.   
  581.     return result;  
  582. }  
  583.   
  584. static int pl2303_carrier_raised(struct usb_serial_port *port)  
  585. {  
  586.     struct pl2303_private *priv = usb_get_serial_port_data(port);  
  587.     if (priv->line_status & UART_DCD)  
  588.         return 1;  
  589.     return 0;  
  590. }  
  591.   
  592. static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)  
  593. {  
  594.     struct pl2303_private *priv = usb_get_serial_port_data(port);  
  595.     unsigned long flags;  
  596.     unsigned int prevstatus;  
  597.     unsigned int status;  
  598.     unsigned int changed;  
  599.   
  600.     spin_lock_irqsave(&priv->lock, flags);  
  601.     prevstatus = priv->line_status;  
  602.     spin_unlock_irqrestore(&priv->lock, flags);  
  603.   
  604.     while (1) {  
  605.         interruptible_sleep_on(&priv->delta_msr_wait);  
  606.         /* see if a signal did it */  
  607.         if (signal_pending(current))  
  608.             return -ERESTARTSYS;  
  609.   
  610.         spin_lock_irqsave(&priv->lock, flags);  
  611.         status = priv->line_status;  
  612.         spin_unlock_irqrestore(&priv->lock, flags);  
  613.   
  614.         changed = prevstatus ^ status;  
  615.   
  616.         if (((arg & TIOCM_RNG) && (changed & UART_RING)) ||  
  617.             ((arg & TIOCM_DSR) && (changed & UART_DSR)) ||  
  618.             ((arg & TIOCM_CD)  && (changed & UART_DCD)) ||  
  619.             ((arg & TIOCM_CTS) && (changed & UART_CTS))) {  
  620.             return 0;  
  621.         }  
  622.         prevstatus = status;  
  623.     }  
  624.     /* NOTREACHED */  
  625.     return 0;  
  626. }  
  627.   
  628. static int pl2303_ioctl(struct tty_struct *tty,  
  629.             unsigned int cmd, unsigned long arg)  
  630. {  
  631.     struct serial_struct ser;  
  632.     struct usb_serial_port *port = tty->driver_data;  
  633.     dbg(“%s (%d) cmd = 0x%04x”, __func__, port->number, cmd);  
  634.   
  635.     switch (cmd) {  
  636.     case TIOCGSERIAL:  
  637.         memset(&ser, 0, sizeof ser);  
  638.         ser.type = PORT_16654;  
  639.         ser.line = port->serial->minor;  
  640.         ser.port = port->number;  
  641.         ser.baud_base = 460800;  
  642.   
  643.         if (copy_to_user((void __user *)arg, &ser, sizeof ser))  
  644.             return -EFAULT;  
  645.   
  646.         return 0;  
  647.   
  648.     case TIOCMIWAIT:  
  649.         dbg(“%s (%d) TIOCMIWAIT”, __func__,  port->number);  
  650.         return wait_modem_info(port, arg);  
  651.     default:  
  652.         dbg(“%s not supported = 0x%04x”, __func__, cmd);  
  653.         break;  
  654.     }  
  655.     return -ENOIOCTLCMD;  
  656. }  
  657.   
  658. static void pl2303_break_ctl(struct tty_struct *tty, int break_state)  
  659. {  
  660.     struct usb_serial_port *port = tty->driver_data;  
  661.     struct usb_serial *serial = port->serial;  
  662.     u16 state;  
  663.     int result;  
  664.   
  665.     dbg(“%s – port %d”, __func__, port->number);  
  666.   
  667.     if (break_state == 0)  
  668.         state = BREAK_OFF;  
  669.     else  
  670.         state = BREAK_ON;  
  671.     dbg(“%s – turning break %s”, __func__,  
  672.             state == BREAK_OFF ? “off” : “on”);  
  673.   
  674.     result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),  
  675.                  BREAK_REQUEST, BREAK_REQUEST_TYPE, state,  
  676.                  0, NULL, 0, 100);  
  677.     if (result)  
  678.         dbg(“%s – error sending break = %d”, __func__, result);  
  679. }  
  680.   
  681. static void pl2303_release(struct usb_serial *serial)  
  682. {  
  683.     int i;  
  684.     struct pl2303_private *priv;  
  685.   
  686.     dbg(“%s”, __func__);  
  687.   
  688.     for (i = 0; i < serial->num_ports; ++i) {  
  689.         priv = usb_get_serial_port_data(serial->port[i]);  
  690.         kfree(priv);  
  691.     }  
  692. }  
  693.   
  694. static void pl2303_update_line_status(struct usb_serial_port *port,  
  695.                       unsigned char *data,  
  696.                       unsigned int actual_length)  
  697. {  
  698.   
  699.     struct pl2303_private *priv = usb_get_serial_port_data(port);  
  700.     struct tty_struct *tty;  
  701.     unsigned long flags;  
  702.     u8 status_idx = UART_STATE;  
  703.     u8 length = UART_STATE + 1;  
  704.     u8 prev_line_status;  
  705.     u16 idv, idp;  
  706.   
  707.     idv = le16_to_cpu(port->serial->dev->descriptor.idVendor);  
  708.     idp = le16_to_cpu(port->serial->dev->descriptor.idProduct);  
  709.   
  710.   
  711.     if (idv == SIEMENS_VENDOR_ID) {  
  712.         if (idp == SIEMENS_PRODUCT_ID_X65 ||  
  713.             idp == SIEMENS_PRODUCT_ID_SX1 ||  
  714.             idp == SIEMENS_PRODUCT_ID_X75) {  
  715.   
  716.             length = 1;  
  717.             status_idx = 0;  
  718.         }  
  719.     }  
  720.   
  721.     if (actual_length < length)  
  722.         return;  
  723.   
  724.     /* Save off the uart status for others to look at */  
  725.     spin_lock_irqsave(&priv->lock, flags);  
  726.     prev_line_status = priv->line_status;  
  727.     priv->line_status = data[status_idx];  
  728.     spin_unlock_irqrestore(&priv->lock, flags);  
  729.     if (priv->line_status & UART_BREAK_ERROR)  
  730.         usb_serial_handle_break(port);  
  731.     wake_up_interruptible(&priv->delta_msr_wait);  
  732.   
  733.     tty = tty_port_tty_get(&port->port);  
  734.     if (!tty)  
  735.         return;  
  736.     if ((priv->line_status ^ prev_line_status) & UART_DCD)  
  737.         usb_serial_handle_dcd_change(port, tty,  
  738.                 priv->line_status & UART_DCD);  
  739.     tty_kref_put(tty);  
  740. }  
  741.   
  742. static void pl2303_read_int_callback(struct urb *urb)  
  743. {  
  744.     struct usb_serial_port *port =  urb->context;  
  745.     unsigned char *data = urb->transfer_buffer;  
  746.     unsigned int actual_length = urb->actual_length;  
  747.     int status = urb->status;  
  748.     int retval;  
  749.   
  750.     dbg(“%s (%d)”, __func__, port->number);  
  751.   
  752.     switch (status) {  
  753.     case 0:  
  754.         /* success */  
  755.         break;  
  756.     case -ECONNRESET:  
  757.     case -ENOENT:  
  758.     case -ESHUTDOWN:  
  759.         /* this urb is terminated, clean up */  
  760.         dbg(“%s – urb shutting down with status: %d”, __func__,  
  761.             status);  
  762.         return;  
  763.     default:  
  764.         dbg(“%s – nonzero urb status received: %d”, __func__,  
  765.             status);  
  766.         goto exit;  
  767.     }  
  768.   
  769.     usb_serial_debug_data(debug, &port->dev, __func__,  
  770.                   urb->actual_length, urb->transfer_buffer);  
  771.   
  772.     pl2303_update_line_status(port, data, actual_length);  
  773.   
  774. exit:  
  775.     retval = usb_submit_urb(urb, GFP_ATOMIC);  
  776.     if (retval)  
  777.         dev_err(&urb->dev->dev,  
  778.             “%s – usb_submit_urb failed with result %d\n”,  
  779.             __func__, retval);  
  780. }  
  781.   
  782. static void pl2303_process_read_urb(struct urb *urb)  
  783. {  
  784.     struct usb_serial_port *port = urb->context;  
  785.     struct pl2303_private *priv = usb_get_serial_port_data(port);  
  786.     struct tty_struct *tty;  
  787.     unsigned char *data = urb->transfer_buffer;  
  788.     char tty_flag = TTY_NORMAL;  
  789.     unsigned long flags;  
  790.     u8 line_status;  
  791.     int i;  
  792.   
  793.     /* update line status */  
  794.     spin_lock_irqsave(&priv->lock, flags);  
  795.     line_status = priv->line_status;  
  796.     priv->line_status &= ~UART_STATE_TRANSIENT_MASK;  
  797.     spin_unlock_irqrestore(&priv->lock, flags);  
  798.     wake_up_interruptible(&priv->delta_msr_wait);  
  799.   
  800.     if (!urb->actual_length)  
  801.         return;  
  802.   
  803.     tty = tty_port_tty_get(&port->port);  
  804.     if (!tty)  
  805.         return;  
  806.   
  807.     /* break takes precedence over parity, */  
  808.     /* which takes precedence over framing errors */  
  809.     if (line_status & UART_BREAK_ERROR)  
  810.         tty_flag = TTY_BREAK;  
  811.     else if (line_status & UART_PARITY_ERROR)  
  812.         tty_flag = TTY_PARITY;  
  813.     else if (line_status & UART_FRAME_ERROR)  
  814.         tty_flag = TTY_FRAME;  
  815.     dbg(“%s – tty_flag = %d”, __func__, tty_flag);  
  816.   
  817.     /* overrun is special, not associated with a char */  
  818.     if (line_status & UART_OVERRUN_ERROR)  
  819.         tty_insert_flip_char(tty, 0, TTY_OVERRUN);  
  820.   
  821.     if (port->port.console && port->sysrq) {  
  822.         for (i = 0; i < urb->actual_length; ++i)  
  823.             if (!usb_serial_handle_sysrq_char(port, data[i]))  
  824.                 tty_insert_flip_char(tty, data[i], tty_flag);  
  825.     } else {  
  826.         tty_insert_flip_string_fixed_flag(tty, data, tty_flag,  
  827.                             urb->actual_length);  
  828.     }  
  829.   
  830.     tty_flip_buffer_push(tty);  
  831.     tty_kref_put(tty);  
  832. }  
  833.   
  834. /* All of the device info needed for the PL2303 SIO serial converter */  
  835. static struct usb_serial_driver pl2303_device = {  
  836.     .driver = {  
  837.         .owner =    THIS_MODULE,  
  838.         .name =     “pl2303”,  
  839.     },  
  840.     .id_table =     id_table,  
  841.     .usb_driver =       &pl2303_driver,  
  842.     .num_ports =        1,  
  843.     .bulk_in_size =     256,  
  844.     .bulk_out_size =    256,  
  845.     .open =         pl2303_open,  
  846.     .close =        pl2303_close,  
  847.     .dtr_rts =      pl2303_dtr_rts,  
  848.     .carrier_raised =   pl2303_carrier_raised,  
  849.     .ioctl =        pl2303_ioctl,  
  850.     .break_ctl =        pl2303_break_ctl,  
  851.     .set_termios =      pl2303_set_termios,  
  852.     .tiocmget =     pl2303_tiocmget,  
  853.     .tiocmset =     pl2303_tiocmset,  
  854.     .process_read_urb = pl2303_process_read_urb,  
  855.     .read_int_callback =    pl2303_read_int_callback,  
  856.     .attach =       pl2303_startup,  
  857.     .release =      pl2303_release,  
  858. };  
  859.   
  860. static int __init pl2303_init(void)  
  861. {  
  862.     int retval;  
  863.   
  864.     retval = usb_serial_register(&pl2303_device);  
  865.     if (retval)  
  866.         goto failed_usb_serial_register;  
  867.     retval = usb_register(&pl2303_driver);  
  868.     if (retval)  
  869.         goto failed_usb_register;  
  870.     printk(KERN_INFO KBUILD_MODNAME “: ” DRIVER_DESC “\n”);  
  871.     return 0;  
  872. failed_usb_register:  
  873.     usb_serial_deregister(&pl2303_device);  
  874. failed_usb_serial_register:  
  875.     return retval;  
  876. }  
  877.   
  878. static void __exit pl2303_exit(void)  
  879. {  
  880.     usb_deregister(&pl2303_driver);  
  881.     usb_serial_deregister(&pl2303_device);  
  882. }  
  883.   
  884. module_init(pl2303_init);  
  885. module_exit(pl2303_exit);  
  886.   
  887. MODULE_DESCRIPTION(DRIVER_DESC);  
  888. MODULE_LICENSE(“GPL”);  
  889.   
  890. module_param(debug, bool, S_IRUGO | S_IWUSR);  
  891. MODULE_PARM_DESC(debug, “Debug enabled or not”);  


Makefile文件:

    1. #KVER = /usr/src/linux  
    2. KVER = /lib/modules/`uname -r`/build  
    3. CURDIR = $(shell pwd)  
    4. # Kernel modules  
    5. obj-m := pl2303.o  
    6. build: kernel_modules  
    7. kernel_modules:  
    8.     $(MAKE) -C $(KVER) M=$(CURDIR) modules  
    9. clean:  
    10.     $(MAKE) -C $(KVER) M=$(CURDIR) clean 

版权声明:本文为alexyuyu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/alexyuyu/articles/3897904.html