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