1 /* 2 * mos7720.c 3 * Controls the Moschip 7720 usb to dual port serial convertor 4 * 5 * Copyright 2006 Moschip Semiconductor Tech. Ltd. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, version 2 of the License. 10 * 11 * Developed by: 12 * VijayaKumar.G.N. <vijaykumar@aspirecom.net> 13 * AjayKumar <ajay@aspirecom.net> 14 * Gurudeva.N. <gurudev@aspirecom.net> 15 * 16 * Cleaned up from the original by: 17 * Greg Kroah-Hartman <gregkh@suse.de> 18 * 19 * Originally based on drivers/usb/serial/io_edgeport.c which is: 20 * Copyright (C) 2000 Inside Out Networks, All rights reserved. 21 * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> 22 */ 23 #include <linux/kernel.h> 24 #include <linux/errno.h> 25 #include <linux/init.h> 26 #include <linux/slab.h> 27 #include <linux/tty.h> 28 #include <linux/tty_driver.h> 29 #include <linux/tty_flip.h> 30 #include <linux/module.h> 31 #include <linux/spinlock.h> 32 #include <linux/serial.h> 33 #include <linux/serial_reg.h> 34 #include <linux/usb.h> 35 #include <linux/usb/serial.h> 36 #include <asm/uaccess.h> 37 38 39 /* 40 * Version Information 41 */ 42 #define DRIVER_VERSION "1.0.0.4F" 43 #define DRIVER_AUTHOR "Aspire Communications pvt Ltd." 44 #define DRIVER_DESC "Moschip USB Serial Driver" 45 46 /* default urb timeout */ 47 #define MOS_WDR_TIMEOUT (HZ * 5) 48 49 #define MOS_PORT1 0x0200 50 #define MOS_PORT2 0x0300 51 #define MOS_VENREG 0x0000 52 #define MOS_MAX_PORT 0x02 53 #define MOS_WRITE 0x0E 54 #define MOS_READ 0x0D 55 56 /* Interrupt Rotinue Defines */ 57 #define SERIAL_IIR_RLS 0x06 58 #define SERIAL_IIR_RDA 0x04 59 #define SERIAL_IIR_CTI 0x0c 60 #define SERIAL_IIR_THR 0x02 61 #define SERIAL_IIR_MS 0x00 62 63 #define NUM_URBS 16 /* URB Count */ 64 #define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ 65 66 /* This structure holds all of the local port information */ 67 struct moschip_port 68 { 69 __u8 shadowLCR; /* last LCR value received */ 70 __u8 shadowMCR; /* last MCR value received */ 71 __u8 shadowMSR; /* last MSR value received */ 72 char open; 73 struct async_icount icount; 74 struct usb_serial_port *port; /* loop back to the owner */ 75 struct urb *write_urb_pool[NUM_URBS]; 76 }; 77 78 /* This structure holds all of the individual serial device information */ 79 struct moschip_serial 80 { 81 int interrupt_started; 82 }; 83 84 static int debug; 85 86 #define USB_VENDOR_ID_MOSCHIP 0x9710 87 #define MOSCHIP_DEVICE_ID_7720 0x7720 88 #define MOSCHIP_DEVICE_ID_7715 0x7715 89 90 static struct usb_device_id moschip_port_id_table [] = { 91 { USB_DEVICE(USB_VENDOR_ID_MOSCHIP,MOSCHIP_DEVICE_ID_7720) }, 92 { } /* terminating entry */ 93 }; 94 MODULE_DEVICE_TABLE(usb, moschip_port_id_table); 95 96 97 /* 98 * mos7720_interrupt_callback 99 * this is the callback function for when we have received data on the 100 * interrupt endpoint. 101 */ 102 static void mos7720_interrupt_callback(struct urb *urb) 103 { 104 int result; 105 int length; 106 __u32 *data; 107 unsigned int status; 108 __u8 sp1; 109 __u8 sp2; 110 __u8 st; 111 112 dbg("%s"," : Entering\n"); 113 114 if (!urb) { 115 dbg("%s","Invalid Pointer !!!!:\n"); 116 return; 117 } 118 119 switch (urb->status) { 120 case 0: 121 /* success */ 122 break; 123 case -ECONNRESET: 124 case -ENOENT: 125 case -ESHUTDOWN: 126 /* this urb is terminated, clean up */ 127 dbg("%s - urb shutting down with status: %d", __FUNCTION__, 128 urb->status); 129 return; 130 default: 131 dbg("%s - nonzero urb status received: %d", __FUNCTION__, 132 urb->status); 133 goto exit; 134 } 135 136 length = urb->actual_length; 137 data = urb->transfer_buffer; 138 139 /* Moschip get 4 bytes 140 * Byte 1 IIR Port 1 (port.number is 0) 141 * Byte 2 IIR Port 2 (port.number is 1) 142 * Byte 3 -------------- 143 * Byte 4 FIFO status for both */ 144 if (length && length > 4) { 145 dbg("Wrong data !!!"); 146 return; 147 } 148 149 status = *data; 150 151 sp1 = (status & 0xff000000)>>24; 152 sp2 = (status & 0x00ff0000)>>16; 153 st = status & 0x000000ff; 154 155 if ((sp1 & 0x01) || (sp2 & 0x01)) { 156 /* No Interrupt Pending in both the ports */ 157 dbg("No Interrupt !!!"); 158 } else { 159 switch (sp1 & 0x0f) { 160 case SERIAL_IIR_RLS: 161 dbg("Serial Port 1: Receiver status error or address " 162 "bit detected in 9-bit mode\n"); 163 break; 164 case SERIAL_IIR_CTI: 165 dbg("Serial Port 1: Receiver time out"); 166 break; 167 case SERIAL_IIR_MS: 168 dbg("Serial Port 1: Modem status change"); 169 break; 170 } 171 172 switch (sp2 & 0x0f) { 173 case SERIAL_IIR_RLS: 174 dbg("Serial Port 2: Receiver status error or address " 175 "bit detected in 9-bit mode"); 176 break; 177 case SERIAL_IIR_CTI: 178 dbg("Serial Port 2: Receiver time out"); 179 break; 180 case SERIAL_IIR_MS: 181 dbg("Serial Port 2: Modem status change"); 182 break; 183 } 184 } 185 186 exit: 187 result = usb_submit_urb(urb, GFP_ATOMIC); 188 if (result) 189 dev_err(&urb->dev->dev, 190 "%s - Error %d submitting control urb\n", 191 __FUNCTION__, result); 192 return; 193 } 194 195 /* 196 * mos7720_bulk_in_callback 197 * this is the callback function for when we have received data on the 198 * bulk in endpoint. 199 */ 200 static void mos7720_bulk_in_callback(struct urb *urb) 201 { 202 int status; 203 unsigned char *data ; 204 struct usb_serial_port *port; 205 struct moschip_port *mos7720_port; 206 struct tty_struct *tty; 207 208 if (urb->status) { 209 dbg("nonzero read bulk status received: %d",urb->status); 210 return; 211 } 212 213 mos7720_port = urb->context; 214 if (!mos7720_port) { 215 dbg("%s","NULL mos7720_port pointer \n"); 216 return ; 217 } 218 219 port = mos7720_port->port; 220 221 dbg("Entering...%s", __FUNCTION__); 222 223 data = urb->transfer_buffer; 224 225 tty = port->tty; 226 if (tty && urb->actual_length) { 227 tty_buffer_request_room(tty, urb->actual_length); 228 tty_insert_flip_string(tty, data, urb->actual_length); 229 tty_flip_buffer_push(tty); 230 } 231 232 if (!port->read_urb) { 233 dbg("URB KILLED !!!"); 234 return; 235 } 236 237 if (port->read_urb->status != -EINPROGRESS) { 238 port->read_urb->dev = port->serial->dev; 239 240 status = usb_submit_urb(port->read_urb, GFP_ATOMIC); 241 if (status) 242 dbg("usb_submit_urb(read bulk) failed, status = %d", 243 status); 244 } 245 } 246 247 /* 248 * mos7720_bulk_out_data_callback 249 * this is the callback function for when we have finished sending serial 250 * data on the bulk out endpoint. 251 */ 252 static void mos7720_bulk_out_data_callback(struct urb *urb) 253 { 254 struct moschip_port *mos7720_port; 255 struct tty_struct *tty; 256 257 if (urb->status) { 258 dbg("nonzero write bulk status received:%d", urb->status); 259 return; 260 } 261 262 mos7720_port = urb->context; 263 if (!mos7720_port) { 264 dbg("NULL mos7720_port pointer"); 265 return ; 266 } 267 268 dbg("Entering ........."); 269 270 tty = mos7720_port->port->tty; 271 272 if (tty && mos7720_port->open) 273 tty_wakeup(tty); 274 } 275 276 /* 277 * send_mos_cmd 278 * this function will be used for sending command to device 279 */ 280 static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value, 281 __u16 index, void *data) 282 { 283 int status; 284 unsigned int pipe; 285 u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); 286 __u8 requesttype; 287 __u16 size = 0x0000; 288 289 if (value < MOS_MAX_PORT) { 290 if (product == MOSCHIP_DEVICE_ID_7715) { 291 value = value*0x100+0x100; 292 } else { 293 value = value*0x100+0x200; 294 } 295 } else { 296 value = 0x0000; 297 if ((product == MOSCHIP_DEVICE_ID_7715) && 298 (index != 0x08)) { 299 dbg("serial->product== MOSCHIP_DEVICE_ID_7715"); 300 //index = 0x01 ; 301 } 302 } 303 304 if (request == MOS_WRITE) { 305 request = (__u8)MOS_WRITE; 306 requesttype = (__u8)0x40; 307 value = value + (__u16)*((unsigned char *)data); 308 data = NULL; 309 pipe = usb_sndctrlpipe(serial->dev, 0); 310 } else { 311 request = (__u8)MOS_READ; 312 requesttype = (__u8)0xC0; 313 size = 0x01; 314 pipe = usb_rcvctrlpipe(serial->dev,0); 315 } 316 317 status = usb_control_msg(serial->dev, pipe, request, requesttype, 318 value, index, data, size, MOS_WDR_TIMEOUT); 319 320 if (status < 0) 321 dbg("Command Write failed Value %x index %x\n",value,index); 322 323 return status; 324 } 325 326 static int mos7720_open(struct usb_serial_port *port, struct file * filp) 327 { 328 struct usb_serial *serial; 329 struct usb_serial_port *port0; 330 struct urb *urb; 331 struct moschip_serial *mos7720_serial; 332 struct moschip_port *mos7720_port; 333 int response; 334 int port_number; 335 char data; 336 int j; 337 338 serial = port->serial; 339 340 mos7720_port = usb_get_serial_port_data(port); 341 if (mos7720_port == NULL) 342 return -ENODEV; 343 344 port0 = serial->port[0]; 345 346 mos7720_serial = usb_get_serial_data(serial); 347 348 if (mos7720_serial == NULL || port0 == NULL) 349 return -ENODEV; 350 351 usb_clear_halt(serial->dev, port->write_urb->pipe); 352 usb_clear_halt(serial->dev, port->read_urb->pipe); 353 354 /* Initialising the write urb pool */ 355 for (j = 0; j < NUM_URBS; ++j) { 356 urb = usb_alloc_urb(0,GFP_ATOMIC); 357 mos7720_port->write_urb_pool[j] = urb; 358 359 if (urb == NULL) { 360 err("No more urbs???"); 361 continue; 362 } 363 364 urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, 365 GFP_KERNEL); 366 if (!urb->transfer_buffer) { 367 err("%s-out of memory for urb buffers.", __FUNCTION__); 368 continue; 369 } 370 } 371 372 /* Initialize MCS7720 -- Write Init values to corresponding Registers 373 * 374 * Register Index 375 * 1 : IER 376 * 2 : FCR 377 * 3 : LCR 378 * 4 : MCR 379 * 380 * 0x08 : SP1/2 Control Reg 381 */ 382 port_number = port->number - port->serial->minor; 383 send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data); 384 dbg("SS::%p LSR:%x\n",mos7720_port, data); 385 386 dbg("Check:Sending Command .........."); 387 388 data = 0x02; 389 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x01, &data); 390 data = 0x02; 391 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x02, &data); 392 393 data = 0x00; 394 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); 395 data = 0x00; 396 send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); 397 398 data = 0xCF; 399 send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); 400 data = 0x03; 401 mos7720_port->shadowLCR = data; 402 send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); 403 data = 0x0b; 404 mos7720_port->shadowMCR = data; 405 send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); 406 data = 0x0b; 407 send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); 408 409 data = 0x00; 410 send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); 411 data = 0x00; 412 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); 413 414 /* data = 0x00; 415 send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, port_number + 1, &data); 416 data = 0x03; 417 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data); 418 data = 0x00; 419 send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data); 420 */ 421 data = 0x00; 422 send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); 423 424 data = data | (port->number - port->serial->minor + 1); 425 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); 426 427 data = 0x83; 428 mos7720_port->shadowLCR = data; 429 send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); 430 data = 0x0c; 431 send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data); 432 data = 0x00; 433 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); 434 data = 0x03; 435 mos7720_port->shadowLCR = data; 436 send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); 437 data = 0x0c; 438 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); 439 data = 0x0c; 440 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); 441 442 //Matrix 443 444 /* force low_latency on so that our tty_push actually forces * 445 * the data through,otherwise it is scheduled, and with * 446 * high data rates (like with OHCI) data can get lost. */ 447 448 if (port->tty) 449 port->tty->low_latency = 1; 450 451 /* see if we've set up our endpoint info yet * 452 * (can't set it up in mos7720_startup as the * 453 * structures were not set up at that time.) */ 454 if (!mos7720_serial->interrupt_started) { 455 dbg("Interrupt buffer NULL !!!"); 456 457 /* not set up yet, so do it now */ 458 mos7720_serial->interrupt_started = 1; 459 460 dbg("To Submit URB !!!"); 461 462 /* set up our interrupt urb */ 463 usb_fill_int_urb(port0->interrupt_in_urb, serial->dev, 464 usb_rcvintpipe(serial->dev, 465 port->interrupt_in_endpointAddress), 466 port0->interrupt_in_buffer, 467 port0->interrupt_in_urb->transfer_buffer_length, 468 mos7720_interrupt_callback, mos7720_port, 469 port0->interrupt_in_urb->interval); 470 471 /* start interrupt read for this mos7720 this interrupt * 472 * will continue as long as the mos7720 is connected */ 473 dbg("Submit URB over !!!"); 474 response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL); 475 if (response) 476 dev_err(&port->dev, 477 "%s - Error %d submitting control urb", 478 __FUNCTION__, response); 479 } 480 481 /* set up our bulk in urb */ 482 usb_fill_bulk_urb(port->read_urb, serial->dev, 483 usb_rcvbulkpipe(serial->dev, 484 port->bulk_in_endpointAddress), 485 port->bulk_in_buffer, 486 port->read_urb->transfer_buffer_length, 487 mos7720_bulk_in_callback, mos7720_port); 488 response = usb_submit_urb(port->read_urb, GFP_KERNEL); 489 if (response) 490 dev_err(&port->dev, 491 "%s - Error %d submitting read urb", __FUNCTION__, response); 492 493 /* initialize our icount structure */ 494 memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount)); 495 496 /* initialize our port settings */ 497 mos7720_port->shadowMCR = UART_MCR_OUT2; /* Must set to enable ints! */ 498 499 /* send a open port command */ 500 mos7720_port->open = 1; 501 502 return 0; 503 } 504 505 /* 506 * mos7720_chars_in_buffer 507 * this function is called by the tty driver when it wants to know how many 508 * bytes of data we currently have outstanding in the port (data that has 509 * been written, but hasn't made it out the port yet) 510 * If successful, we return the number of bytes left to be written in the 511 * system, 512 * Otherwise we return a negative error number. 513 */ 514 static int mos7720_chars_in_buffer(struct usb_serial_port *port) 515 { 516 int i; 517 int chars = 0; 518 struct moschip_port *mos7720_port; 519 520 dbg("%s:entering ...........", __FUNCTION__); 521 522 mos7720_port = usb_get_serial_port_data(port); 523 if (mos7720_port == NULL) { 524 dbg("%s:leaving ...........", __FUNCTION__); 525 return -ENODEV; 526 } 527 528 for (i = 0; i < NUM_URBS; ++i) { 529 if (mos7720_port->write_urb_pool[i]->status == -EINPROGRESS) 530 chars += URB_TRANSFER_BUFFER_SIZE; 531 } 532 dbg("%s - returns %d", __FUNCTION__, chars); 533 return chars; 534 } 535 536 static void mos7720_close(struct usb_serial_port *port, struct file *filp) 537 { 538 struct usb_serial *serial; 539 struct moschip_port *mos7720_port; 540 char data; 541 int j; 542 543 dbg("mos7720_close:entering..."); 544 545 serial = port->serial; 546 547 mos7720_port = usb_get_serial_port_data(port); 548 if (mos7720_port == NULL) 549 return; 550 551 for (j = 0; j < NUM_URBS; ++j) 552 usb_kill_urb(mos7720_port->write_urb_pool[j]); 553 554 /* Freeing Write URBs */ 555 for (j = 0; j < NUM_URBS; ++j) { 556 if (mos7720_port->write_urb_pool[j]) { 557 kfree(mos7720_port->write_urb_pool[j]->transfer_buffer); 558 usb_free_urb(mos7720_port->write_urb_pool[j]); 559 } 560 } 561 562 /* While closing port, shutdown all bulk read, write * 563 * and interrupt read if they exists */ 564 if (serial->dev) { 565 dbg("Shutdown bulk write"); 566 usb_kill_urb(port->write_urb); 567 dbg("Shutdown bulk read"); 568 usb_kill_urb(port->read_urb); 569 } 570 571 data = 0x00; 572 send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, 573 0x04, &data); 574 575 data = 0x00; 576 send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, 577 0x01, &data); 578 579 mos7720_port->open = 0; 580 581 dbg("Leaving %s", __FUNCTION__); 582 } 583 584 static void mos7720_break(struct usb_serial_port *port, int break_state) 585 { 586 unsigned char data; 587 struct usb_serial *serial; 588 struct moschip_port *mos7720_port; 589 590 dbg("Entering %s", __FUNCTION__); 591 592 serial = port->serial; 593 594 mos7720_port = usb_get_serial_port_data(port); 595 if (mos7720_port == NULL) 596 return; 597 598 if (break_state == -1) 599 data = mos7720_port->shadowLCR | UART_LCR_SBC; 600 else 601 data = mos7720_port->shadowLCR & ~UART_LCR_SBC; 602 603 mos7720_port->shadowLCR = data; 604 send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, 605 0x03, &data); 606 607 return; 608 } 609 610 /* 611 * mos7720_write_room 612 * this function is called by the tty driver when it wants to know how many 613 * bytes of data we can accept for a specific port. 614 * If successful, we return the amount of room that we have for this port 615 * Otherwise we return a negative error number. 616 */ 617 static int mos7720_write_room(struct usb_serial_port *port) 618 { 619 struct moschip_port *mos7720_port; 620 int room = 0; 621 int i; 622 623 dbg("%s:entering ...........", __FUNCTION__); 624 625 mos7720_port = usb_get_serial_port_data(port); 626 if (mos7720_port == NULL) { 627 dbg("%s:leaving ...........", __FUNCTION__); 628 return -ENODEV; 629 } 630 631 for (i = 0; i < NUM_URBS; ++i) { 632 if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) 633 room += URB_TRANSFER_BUFFER_SIZE; 634 } 635 636 dbg("%s - returns %d", __FUNCTION__, room); 637 return room; 638 } 639 640 static int mos7720_write(struct usb_serial_port *port, 641 const unsigned char *data, int count) 642 { 643 int status; 644 int i; 645 int bytes_sent = 0; 646 int transfer_size; 647 648 struct moschip_port *mos7720_port; 649 struct usb_serial *serial; 650 struct urb *urb; 651 const unsigned char *current_position = data; 652 653 dbg("%s:entering ...........", __FUNCTION__); 654 655 serial = port->serial; 656 657 mos7720_port = usb_get_serial_port_data(port); 658 if (mos7720_port == NULL) { 659 dbg("mos7720_port is NULL"); 660 return -ENODEV; 661 } 662 663 /* try to find a free urb in the list */ 664 urb = NULL; 665 666 for (i = 0; i < NUM_URBS; ++i) { 667 if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) { 668 urb = mos7720_port->write_urb_pool[i]; 669 dbg("URB:%d",i); 670 break; 671 } 672 } 673 674 if (urb == NULL) { 675 dbg("%s - no more free urbs", __FUNCTION__); 676 goto exit; 677 } 678 679 if (urb->transfer_buffer == NULL) { 680 urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, 681 GFP_KERNEL); 682 if (urb->transfer_buffer == NULL) { 683 err("%s no more kernel memory...", __FUNCTION__); 684 goto exit; 685 } 686 } 687 transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE); 688 689 memcpy(urb->transfer_buffer, current_position, transfer_size); 690 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, 691 urb->transfer_buffer); 692 693 /* fill urb with data and submit */ 694 usb_fill_bulk_urb(urb, serial->dev, 695 usb_sndbulkpipe(serial->dev, 696 port->bulk_out_endpointAddress), 697 urb->transfer_buffer, transfer_size, 698 mos7720_bulk_out_data_callback, mos7720_port); 699 700 /* send it down the pipe */ 701 status = usb_submit_urb(urb,GFP_ATOMIC); 702 if (status) { 703 err("%s - usb_submit_urb(write bulk) failed with status = %d", 704 __FUNCTION__, status); 705 bytes_sent = status; 706 goto exit; 707 } 708 bytes_sent = transfer_size; 709 710 exit: 711 return bytes_sent; 712 } 713 714 static void mos7720_throttle(struct usb_serial_port *port) 715 { 716 struct moschip_port *mos7720_port; 717 struct tty_struct *tty; 718 int status; 719 720 dbg("%s- port %d\n", __FUNCTION__, port->number); 721 722 mos7720_port = usb_get_serial_port_data(port); 723 724 if (mos7720_port == NULL) 725 return; 726 727 if (!mos7720_port->open) { 728 dbg("port not opened"); 729 return; 730 } 731 732 dbg("%s: Entering ..........", __FUNCTION__); 733 734 tty = port->tty; 735 if (!tty) { 736 dbg("%s - no tty available", __FUNCTION__); 737 return; 738 } 739 740 /* if we are implementing XON/XOFF, send the stop character */ 741 if (I_IXOFF(tty)) { 742 unsigned char stop_char = STOP_CHAR(tty); 743 status = mos7720_write(port, &stop_char, 1); 744 if (status <= 0) 745 return; 746 } 747 748 /* if we are implementing RTS/CTS, toggle that line */ 749 if (tty->termios->c_cflag & CRTSCTS) { 750 mos7720_port->shadowMCR &= ~UART_MCR_RTS; 751 status = send_mos_cmd(port->serial, MOS_WRITE, 752 port->number - port->serial->minor, 753 UART_MCR, &mos7720_port->shadowMCR); 754 if (status != 0) 755 return; 756 } 757 } 758 759 static void mos7720_unthrottle(struct usb_serial_port *port) 760 { 761 struct tty_struct *tty; 762 int status; 763 struct moschip_port *mos7720_port = usb_get_serial_port_data(port); 764 765 if (mos7720_port == NULL) 766 return; 767 768 if (!mos7720_port->open) { 769 dbg("%s - port not opened", __FUNCTION__); 770 return; 771 } 772 773 dbg("%s: Entering ..........", __FUNCTION__); 774 775 tty = port->tty; 776 if (!tty) { 777 dbg("%s - no tty available", __FUNCTION__); 778 return; 779 } 780 781 /* if we are implementing XON/XOFF, send the start character */ 782 if (I_IXOFF(tty)) { 783 unsigned char start_char = START_CHAR(tty); 784 status = mos7720_write(port, &start_char, 1); 785 if (status <= 0) 786 return; 787 } 788 789 /* if we are implementing RTS/CTS, toggle that line */ 790 if (tty->termios->c_cflag & CRTSCTS) { 791 mos7720_port->shadowMCR |= UART_MCR_RTS; 792 status = send_mos_cmd(port->serial, MOS_WRITE, 793 port->number - port->serial->minor, 794 UART_MCR, &mos7720_port->shadowMCR); 795 if (status != 0) 796 return; 797 } 798 } 799 800 static int set_higher_rates(struct moschip_port *mos7720_port, 801 unsigned int baud) 802 { 803 unsigned char data; 804 struct usb_serial_port *port; 805 struct usb_serial *serial; 806 int port_number; 807 808 if (mos7720_port == NULL) 809 return -EINVAL; 810 811 port = mos7720_port->port; 812 serial = port->serial; 813 814 /*********************************************** 815 * Init Sequence for higher rates 816 ***********************************************/ 817 dbg("Sending Setting Commands .........."); 818 port_number = port->number - port->serial->minor; 819 820 data = 0x000; 821 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); 822 data = 0x000; 823 send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); 824 data = 0x0CF; 825 send_mos_cmd(serial, MOS_WRITE, port->number, 0x02, &data); 826 data = 0x00b; 827 mos7720_port->shadowMCR = data; 828 send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); 829 data = 0x00b; 830 send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); 831 832 data = 0x000; 833 send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); 834 data = 0x000; 835 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); 836 837 838 /*********************************************** 839 * Set for higher rates * 840 ***********************************************/ 841 842 data = baud * 0x10; 843 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1,&data); 844 845 data = 0x003; 846 send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); 847 data = 0x003; 848 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); 849 850 data = 0x02b; 851 mos7720_port->shadowMCR = data; 852 send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); 853 data = 0x02b; 854 send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); 855 856 /*********************************************** 857 * Set DLL/DLM 858 ***********************************************/ 859 860 data = mos7720_port->shadowLCR | UART_LCR_DLAB; 861 mos7720_port->shadowLCR = data; 862 send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); 863 864 data = 0x001; /* DLL */ 865 send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data); 866 data = 0x000; /* DLM */ 867 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); 868 869 data = mos7720_port->shadowLCR & ~UART_LCR_DLAB; 870 mos7720_port->shadowLCR = data; 871 send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); 872 873 return 0; 874 } 875 876 /* baud rate information */ 877 struct divisor_table_entry 878 { 879 __u32 baudrate; 880 __u16 divisor; 881 }; 882 883 /* Define table of divisors for moschip 7720 hardware * 884 * These assume a 3.6864MHz crystal, the standard /16, and * 885 * MCR.7 = 0. */ 886 static struct divisor_table_entry divisor_table[] = { 887 { 50, 2304}, 888 { 110, 1047}, /* 2094.545455 => 230450 => .0217 % over */ 889 { 134, 857}, /* 1713.011152 => 230398.5 => .00065% under */ 890 { 150, 768}, 891 { 300, 384}, 892 { 600, 192}, 893 { 1200, 96}, 894 { 1800, 64}, 895 { 2400, 48}, 896 { 4800, 24}, 897 { 7200, 16}, 898 { 9600, 12}, 899 { 19200, 6}, 900 { 38400, 3}, 901 { 57600, 2}, 902 { 115200, 1}, 903 }; 904 905 /***************************************************************************** 906 * calc_baud_rate_divisor 907 * this function calculates the proper baud rate divisor for the specified 908 * baud rate. 909 *****************************************************************************/ 910 static int calc_baud_rate_divisor(int baudrate, int *divisor) 911 { 912 int i; 913 __u16 custom; 914 __u16 round1; 915 __u16 round; 916 917 918 dbg("%s - %d", __FUNCTION__, baudrate); 919 920 for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { 921 if (divisor_table[i].baudrate == baudrate) { 922 *divisor = divisor_table[i].divisor; 923 return 0; 924 } 925 } 926 927 /* After trying for all the standard baud rates * 928 * Try calculating the divisor for this baud rate */ 929 if (baudrate > 75 && baudrate < 230400) { 930 /* get the divisor */ 931 custom = (__u16)(230400L / baudrate); 932 933 /* Check for round off */ 934 round1 = (__u16)(2304000L / baudrate); 935 round = (__u16)(round1 - (custom * 10)); 936 if (round > 4) 937 custom++; 938 *divisor = custom; 939 940 dbg("Baud %d = %d",baudrate, custom); 941 return 0; 942 } 943 944 dbg("Baud calculation Failed..."); 945 return -EINVAL; 946 } 947 948 /* 949 * send_cmd_write_baud_rate 950 * this function sends the proper command to change the baud rate of the 951 * specified port. 952 */ 953 static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, 954 int baudrate) 955 { 956 struct usb_serial_port *port; 957 struct usb_serial *serial; 958 int divisor; 959 int status; 960 unsigned char data; 961 unsigned char number; 962 963 if (mos7720_port == NULL) 964 return -1; 965 966 port = mos7720_port->port; 967 serial = port->serial; 968 969 dbg("%s: Entering ..........", __FUNCTION__); 970 971 number = port->number - port->serial->minor; 972 dbg("%s - port = %d, baud = %d", __FUNCTION__, port->number, baudrate); 973 974 /* Calculate the Divisor */ 975 status = calc_baud_rate_divisor(baudrate, &divisor); 976 if (status) { 977 err("%s - bad baud rate", __FUNCTION__); 978 return status; 979 } 980 981 /* Enable access to divisor latch */ 982 data = mos7720_port->shadowLCR | UART_LCR_DLAB; 983 mos7720_port->shadowLCR = data; 984 send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data); 985 986 /* Write the divisor */ 987 data = ((unsigned char)(divisor & 0xff)); 988 send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data); 989 990 data = ((unsigned char)((divisor & 0xff00) >> 8)); 991 send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data); 992 993 /* Disable access to divisor latch */ 994 data = mos7720_port->shadowLCR & ~UART_LCR_DLAB; 995 mos7720_port->shadowLCR = data; 996 send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data); 997 998 return status; 999 } 1000 1001 /* 1002 * change_port_settings 1003 * This routine is called to set the UART on the device to match 1004 * the specified new settings. 1005 */ 1006 static void change_port_settings(struct moschip_port *mos7720_port, 1007 struct ktermios *old_termios) 1008 { 1009 struct usb_serial_port *port; 1010 struct usb_serial *serial; 1011 struct tty_struct *tty; 1012 int baud; 1013 unsigned cflag; 1014 unsigned iflag; 1015 __u8 mask = 0xff; 1016 __u8 lData; 1017 __u8 lParity; 1018 __u8 lStop; 1019 int status; 1020 int port_number; 1021 char data; 1022 1023 if (mos7720_port == NULL) 1024 return ; 1025 1026 port = mos7720_port->port; 1027 serial = port->serial; 1028 port_number = port->number - port->serial->minor; 1029 1030 dbg("%s - port %d", __FUNCTION__, port->number); 1031 1032 if (!mos7720_port->open) { 1033 dbg("%s - port not opened", __FUNCTION__); 1034 return; 1035 } 1036 1037 tty = mos7720_port->port->tty; 1038 1039 if ((!tty) || (!tty->termios)) { 1040 dbg("%s - no tty structures", __FUNCTION__); 1041 return; 1042 } 1043 1044 dbg("%s: Entering ..........", __FUNCTION__); 1045 1046 lData = UART_LCR_WLEN8; 1047 lStop = 0x00; /* 1 stop bit */ 1048 lParity = 0x00; /* No parity */ 1049 1050 cflag = tty->termios->c_cflag; 1051 iflag = tty->termios->c_iflag; 1052 1053 /* Change the number of bits */ 1054 switch (cflag & CSIZE) { 1055 case CS5: 1056 lData = UART_LCR_WLEN5; 1057 mask = 0x1f; 1058 break; 1059 1060 case CS6: 1061 lData = UART_LCR_WLEN6; 1062 mask = 0x3f; 1063 break; 1064 1065 case CS7: 1066 lData = UART_LCR_WLEN7; 1067 mask = 0x7f; 1068 break; 1069 default: 1070 case CS8: 1071 lData = UART_LCR_WLEN8; 1072 break; 1073 } 1074 1075 /* Change the Parity bit */ 1076 if (cflag & PARENB) { 1077 if (cflag & PARODD) { 1078 lParity = UART_LCR_PARITY; 1079 dbg("%s - parity = odd", __FUNCTION__); 1080 } else { 1081 lParity = (UART_LCR_EPAR | UART_LCR_PARITY); 1082 dbg("%s - parity = even", __FUNCTION__); 1083 } 1084 1085 } else { 1086 dbg("%s - parity = none", __FUNCTION__); 1087 } 1088 1089 if (cflag & CMSPAR) 1090 lParity = lParity | 0x20; 1091 1092 /* Change the Stop bit */ 1093 if (cflag & CSTOPB) { 1094 lStop = UART_LCR_STOP; 1095 dbg("%s - stop bits = 2", __FUNCTION__); 1096 } else { 1097 lStop = 0x00; 1098 dbg("%s - stop bits = 1", __FUNCTION__); 1099 } 1100 1101 #define LCR_BITS_MASK 0x03 /* Mask for bits/char field */ 1102 #define LCR_STOP_MASK 0x04 /* Mask for stop bits field */ 1103 #define LCR_PAR_MASK 0x38 /* Mask for parity field */ 1104 1105 /* Update the LCR with the correct value */ 1106 mos7720_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); 1107 mos7720_port->shadowLCR |= (lData | lParity | lStop); 1108 1109 1110 /* Disable Interrupts */ 1111 data = 0x00; 1112 send_mos_cmd(serial,MOS_WRITE,port->number - port->serial->minor, UART_IER, &data); 1113 1114 data = 0x00; 1115 send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data); 1116 1117 data = 0xcf; 1118 send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data); 1119 1120 /* Send the updated LCR value to the mos7720 */ 1121 data = mos7720_port->shadowLCR; 1122 send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data); 1123 1124 data = 0x00b; 1125 mos7720_port->shadowMCR = data; 1126 send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); 1127 data = 0x00b; 1128 send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); 1129 1130 /* set up the MCR register and send it to the mos7720 */ 1131 mos7720_port->shadowMCR = UART_MCR_OUT2; 1132 if (cflag & CBAUD) 1133 mos7720_port->shadowMCR |= (UART_MCR_DTR | UART_MCR_RTS); 1134 1135 if (cflag & CRTSCTS) { 1136 mos7720_port->shadowMCR |= (UART_MCR_XONANY); 1137 1138 /* To set hardware flow control to the specified * 1139 * serial port, in SP1/2_CONTROL_REG */ 1140 if (port->number) { 1141 data = 0x001; 1142 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 1143 0x08, &data); 1144 } else { 1145 data = 0x002; 1146 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 1147 0x08, &data); 1148 } 1149 } else { 1150 mos7720_port->shadowMCR &= ~(UART_MCR_XONANY); 1151 } 1152 1153 data = mos7720_port->shadowMCR; 1154 send_mos_cmd(serial, MOS_WRITE, port_number, UART_MCR, &data); 1155 1156 /* Determine divisor based on baud rate */ 1157 baud = tty_get_baud_rate(tty); 1158 if (!baud) { 1159 /* pick a default, any default... */ 1160 dbg("Picked default baud..."); 1161 baud = 9600; 1162 } 1163 1164 if (baud >= 230400) { 1165 set_higher_rates(mos7720_port, baud); 1166 /* Enable Interrupts */ 1167 data = 0x0c; 1168 send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); 1169 return; 1170 } 1171 1172 dbg("%s - baud rate = %d", __FUNCTION__, baud); 1173 status = send_cmd_write_baud_rate(mos7720_port, baud); 1174 1175 /* Enable Interrupts */ 1176 data = 0x0c; 1177 send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); 1178 1179 if (port->read_urb->status != -EINPROGRESS) { 1180 port->read_urb->dev = serial->dev; 1181 1182 status = usb_submit_urb(port->read_urb, GFP_ATOMIC); 1183 if (status) 1184 dbg("usb_submit_urb(read bulk) failed, status = %d", 1185 status); 1186 } 1187 return; 1188 } 1189 1190 /* 1191 * mos7720_set_termios 1192 * this function is called by the tty driver when it wants to change the 1193 * termios structure. 1194 */ 1195 static void mos7720_set_termios(struct usb_serial_port *port, 1196 struct ktermios *old_termios) 1197 { 1198 int status; 1199 unsigned int cflag; 1200 struct usb_serial *serial; 1201 struct moschip_port *mos7720_port; 1202 struct tty_struct *tty; 1203 1204 serial = port->serial; 1205 1206 mos7720_port = usb_get_serial_port_data(port); 1207 1208 if (mos7720_port == NULL) 1209 return; 1210 1211 tty = port->tty; 1212 1213 if (!port->tty || !port->tty->termios) { 1214 dbg("%s - no tty or termios", __FUNCTION__); 1215 return; 1216 } 1217 1218 if (!mos7720_port->open) { 1219 dbg("%s - port not opened", __FUNCTION__); 1220 return; 1221 } 1222 1223 dbg("%s\n","setting termios - ASPIRE"); 1224 1225 cflag = tty->termios->c_cflag; 1226 1227 if (!cflag) { 1228 printk("%s %s\n",__FUNCTION__,"cflag is NULL"); 1229 return; 1230 } 1231 1232 /* check that they really want us to change something */ 1233 if (old_termios) { 1234 if ((cflag == old_termios->c_cflag) && 1235 (RELEVANT_IFLAG(tty->termios->c_iflag) == 1236 RELEVANT_IFLAG(old_termios->c_iflag))) { 1237 dbg("Nothing to change"); 1238 return; 1239 } 1240 } 1241 1242 dbg("%s - clfag %08x iflag %08x", __FUNCTION__, 1243 tty->termios->c_cflag, 1244 RELEVANT_IFLAG(tty->termios->c_iflag)); 1245 1246 if (old_termios) 1247 dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, 1248 old_termios->c_cflag, 1249 RELEVANT_IFLAG(old_termios->c_iflag)); 1250 1251 dbg("%s - port %d", __FUNCTION__, port->number); 1252 1253 /* change the port settings to the new ones specified */ 1254 change_port_settings(mos7720_port, old_termios); 1255 1256 if(!port->read_urb) { 1257 dbg("%s","URB KILLED !!!!!\n"); 1258 return; 1259 } 1260 1261 if(port->read_urb->status != -EINPROGRESS) { 1262 port->read_urb->dev = serial->dev; 1263 status = usb_submit_urb(port->read_urb, GFP_ATOMIC); 1264 if (status) 1265 dbg("usb_submit_urb(read bulk) failed, status = %d", 1266 status); 1267 } 1268 return; 1269 } 1270 1271 /* 1272 * get_lsr_info - get line status register info 1273 * 1274 * Purpose: Let user call ioctl() to get info when the UART physically 1275 * is emptied. On bus types like RS485, the transmitter must 1276 * release the bus after transmitting. This must be done when 1277 * the transmit shift register is empty, not be done when the 1278 * transmit holding register is empty. This functionality 1279 * allows an RS485 driver to be written in user space. 1280 */ 1281 static int get_lsr_info(struct moschip_port *mos7720_port, 1282 unsigned int __user *value) 1283 { 1284 int count; 1285 unsigned int result = 0; 1286 1287 count = mos7720_chars_in_buffer(mos7720_port->port); 1288 if (count == 0) { 1289 dbg("%s -- Empty", __FUNCTION__); 1290 result = TIOCSER_TEMT; 1291 } 1292 1293 if (copy_to_user(value, &result, sizeof(int))) 1294 return -EFAULT; 1295 return 0; 1296 } 1297 1298 /* 1299 * get_number_bytes_avail - get number of bytes available 1300 * 1301 * Purpose: Let user call ioctl to get the count of number of bytes available. 1302 */ 1303 static int get_number_bytes_avail(struct moschip_port *mos7720_port, 1304 unsigned int __user *value) 1305 { 1306 unsigned int result = 0; 1307 struct tty_struct *tty = mos7720_port->port->tty; 1308 1309 if (!tty) 1310 return -ENOIOCTLCMD; 1311 1312 result = tty->read_cnt; 1313 1314 dbg("%s(%d) = %d", __FUNCTION__, mos7720_port->port->number, result); 1315 if (copy_to_user(value, &result, sizeof(int))) 1316 return -EFAULT; 1317 1318 return -ENOIOCTLCMD; 1319 } 1320 1321 static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, 1322 unsigned int __user *value) 1323 { 1324 unsigned int mcr ; 1325 unsigned int arg; 1326 unsigned char data; 1327 1328 struct usb_serial_port *port; 1329 1330 if (mos7720_port == NULL) 1331 return -1; 1332 1333 port = (struct usb_serial_port*)mos7720_port->port; 1334 mcr = mos7720_port->shadowMCR; 1335 1336 if (copy_from_user(&arg, value, sizeof(int))) 1337 return -EFAULT; 1338 1339 switch (cmd) { 1340 case TIOCMBIS: 1341 if (arg & TIOCM_RTS) 1342 mcr |= UART_MCR_RTS; 1343 if (arg & TIOCM_DTR) 1344 mcr |= UART_MCR_RTS; 1345 if (arg & TIOCM_LOOP) 1346 mcr |= UART_MCR_LOOP; 1347 break; 1348 1349 case TIOCMBIC: 1350 if (arg & TIOCM_RTS) 1351 mcr &= ~UART_MCR_RTS; 1352 if (arg & TIOCM_DTR) 1353 mcr &= ~UART_MCR_RTS; 1354 if (arg & TIOCM_LOOP) 1355 mcr &= ~UART_MCR_LOOP; 1356 break; 1357 1358 case TIOCMSET: 1359 /* turn off the RTS and DTR and LOOPBACK 1360 * and then only turn on what was asked to */ 1361 mcr &= ~(UART_MCR_RTS | UART_MCR_DTR | UART_MCR_LOOP); 1362 mcr |= ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0); 1363 mcr |= ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0); 1364 mcr |= ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0); 1365 break; 1366 } 1367 1368 mos7720_port->shadowMCR = mcr; 1369 1370 data = mos7720_port->shadowMCR; 1371 send_mos_cmd(port->serial, MOS_WRITE, 1372 port->number - port->serial->minor, UART_MCR, &data); 1373 1374 return 0; 1375 } 1376 1377 static int get_modem_info(struct moschip_port *mos7720_port, 1378 unsigned int __user *value) 1379 { 1380 unsigned int result = 0; 1381 unsigned int msr = mos7720_port->shadowMSR; 1382 unsigned int mcr = mos7720_port->shadowMCR; 1383 1384 result = ((mcr & UART_MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ 1385 | ((mcr & UART_MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ 1386 | ((msr & UART_MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ 1387 | ((msr & UART_MSR_DCD) ? TIOCM_CAR: 0) /* 0x040 */ 1388 | ((msr & UART_MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ 1389 | ((msr & UART_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ 1390 1391 1392 dbg("%s -- %x", __FUNCTION__, result); 1393 1394 if (copy_to_user(value, &result, sizeof(int))) 1395 return -EFAULT; 1396 return 0; 1397 } 1398 1399 static int get_serial_info(struct moschip_port *mos7720_port, 1400 struct serial_struct __user *retinfo) 1401 { 1402 struct serial_struct tmp; 1403 1404 if (!retinfo) 1405 return -EFAULT; 1406 1407 memset(&tmp, 0, sizeof(tmp)); 1408 1409 tmp.type = PORT_16550A; 1410 tmp.line = mos7720_port->port->serial->minor; 1411 tmp.port = mos7720_port->port->number; 1412 tmp.irq = 0; 1413 tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; 1414 tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; 1415 tmp.baud_base = 9600; 1416 tmp.close_delay = 5*HZ; 1417 tmp.closing_wait = 30*HZ; 1418 1419 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 1420 return -EFAULT; 1421 return 0; 1422 } 1423 1424 static int mos7720_ioctl(struct usb_serial_port *port, struct file *file, 1425 unsigned int cmd, unsigned long arg) 1426 { 1427 struct moschip_port *mos7720_port; 1428 struct async_icount cnow; 1429 struct async_icount cprev; 1430 struct serial_icounter_struct icount; 1431 1432 mos7720_port = usb_get_serial_port_data(port); 1433 if (mos7720_port == NULL) 1434 return -ENODEV; 1435 1436 dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); 1437 1438 switch (cmd) { 1439 case TIOCINQ: 1440 /* return number of bytes available */ 1441 dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number); 1442 return get_number_bytes_avail(mos7720_port, 1443 (unsigned int __user *)arg); 1444 break; 1445 1446 case TIOCSERGETLSR: 1447 dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); 1448 return get_lsr_info(mos7720_port, (unsigned int __user *)arg); 1449 return 0; 1450 1451 case TIOCMBIS: 1452 case TIOCMBIC: 1453 case TIOCMSET: 1454 dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__, 1455 port->number); 1456 return set_modem_info(mos7720_port, cmd, 1457 (unsigned int __user *)arg); 1458 1459 case TIOCMGET: 1460 dbg("%s (%d) TIOCMGET", __FUNCTION__, port->number); 1461 return get_modem_info(mos7720_port, 1462 (unsigned int __user *)arg); 1463 1464 case TIOCGSERIAL: 1465 dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number); 1466 return get_serial_info(mos7720_port, 1467 (struct serial_struct __user *)arg); 1468 1469 case TIOCSSERIAL: 1470 dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number); 1471 break; 1472 1473 case TIOCMIWAIT: 1474 dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number); 1475 cprev = mos7720_port->icount; 1476 while (1) { 1477 if (signal_pending(current)) 1478 return -ERESTARTSYS; 1479 cnow = mos7720_port->icount; 1480 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 1481 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) 1482 return -EIO; /* no change => error */ 1483 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || 1484 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || 1485 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || 1486 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { 1487 return 0; 1488 } 1489 cprev = cnow; 1490 } 1491 /* NOTREACHED */ 1492 break; 1493 1494 case TIOCGICOUNT: 1495 cnow = mos7720_port->icount; 1496 icount.cts = cnow.cts; 1497 icount.dsr = cnow.dsr; 1498 icount.rng = cnow.rng; 1499 icount.dcd = cnow.dcd; 1500 icount.rx = cnow.rx; 1501 icount.tx = cnow.tx; 1502 icount.frame = cnow.frame; 1503 icount.overrun = cnow.overrun; 1504 icount.parity = cnow.parity; 1505 icount.brk = cnow.brk; 1506 icount.buf_overrun = cnow.buf_overrun; 1507 1508 dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, 1509 port->number, icount.rx, icount.tx ); 1510 if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) 1511 return -EFAULT; 1512 return 0; 1513 } 1514 1515 return -ENOIOCTLCMD; 1516 } 1517 1518 static int mos7720_startup(struct usb_serial *serial) 1519 { 1520 struct moschip_serial *mos7720_serial; 1521 struct moschip_port *mos7720_port; 1522 struct usb_device *dev; 1523 int i; 1524 char data; 1525 1526 dbg("%s: Entering ..........", __FUNCTION__); 1527 1528 if (!serial) { 1529 dbg("Invalid Handler"); 1530 return -ENODEV; 1531 } 1532 1533 dev = serial->dev; 1534 1535 /* create our private serial structure */ 1536 mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL); 1537 if (mos7720_serial == NULL) { 1538 err("%s - Out of memory", __FUNCTION__); 1539 return -ENOMEM; 1540 } 1541 1542 usb_set_serial_data(serial, mos7720_serial); 1543 1544 /* we set up the pointers to the endpoints in the mos7720_open * 1545 * function, as the structures aren't created yet. */ 1546 1547 /* set up port private structures */ 1548 for (i = 0; i < serial->num_ports; ++i) { 1549 mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); 1550 if (mos7720_port == NULL) { 1551 err("%s - Out of memory", __FUNCTION__); 1552 usb_set_serial_data(serial, NULL); 1553 kfree(mos7720_serial); 1554 return -ENOMEM; 1555 } 1556 1557 /* Initialize all port interrupt end point to port 0 int 1558 * endpoint. Our device has only one interrupt endpoint 1559 * comman to all ports */ 1560 serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress; 1561 1562 mos7720_port->port = serial->port[i]; 1563 usb_set_serial_port_data(serial->port[i], mos7720_port); 1564 1565 dbg("port number is %d", serial->port[i]->number); 1566 dbg("serial number is %d", serial->minor); 1567 } 1568 1569 1570 /* setting configuration feature to one */ 1571 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 1572 (__u8)0x03, 0x00,0x01,0x00, NULL, 0x00, 5*HZ); 1573 1574 send_mos_cmd(serial,MOS_READ,0x00, UART_LSR, &data); // LSR For Port 1 1575 dbg("LSR:%x",data); 1576 1577 send_mos_cmd(serial,MOS_READ,0x01, UART_LSR, &data); // LSR For Port 2 1578 dbg("LSR:%x",data); 1579 1580 return 0; 1581 } 1582 1583 static void mos7720_shutdown(struct usb_serial *serial) 1584 { 1585 int i; 1586 1587 /* free private structure allocated for serial port */ 1588 for (i=0; i < serial->num_ports; ++i) { 1589 kfree(usb_get_serial_port_data(serial->port[i])); 1590 usb_set_serial_port_data(serial->port[i], NULL); 1591 } 1592 1593 /* free private structure allocated for serial device */ 1594 kfree(usb_get_serial_data(serial)); 1595 usb_set_serial_data(serial, NULL); 1596 } 1597 1598 static struct usb_driver usb_driver = { 1599 .name = "moschip7720", 1600 .probe = usb_serial_probe, 1601 .disconnect = usb_serial_disconnect, 1602 .id_table = moschip_port_id_table, 1603 .no_dynamic_id = 1, 1604 }; 1605 1606 static struct usb_serial_driver moschip7720_2port_driver = { 1607 .driver = { 1608 .owner = THIS_MODULE, 1609 .name = "moschip7720", 1610 }, 1611 .description = "Moschip 2 port adapter", 1612 .usb_driver = &usb_driver, 1613 .id_table = moschip_port_id_table, 1614 .num_interrupt_in = 1, 1615 .num_bulk_in = 2, 1616 .num_bulk_out = 2, 1617 .num_ports = 2, 1618 .open = mos7720_open, 1619 .close = mos7720_close, 1620 .throttle = mos7720_throttle, 1621 .unthrottle = mos7720_unthrottle, 1622 .attach = mos7720_startup, 1623 .shutdown = mos7720_shutdown, 1624 .ioctl = mos7720_ioctl, 1625 .set_termios = mos7720_set_termios, 1626 .write = mos7720_write, 1627 .write_room = mos7720_write_room, 1628 .chars_in_buffer = mos7720_chars_in_buffer, 1629 .break_ctl = mos7720_break, 1630 .read_bulk_callback = mos7720_bulk_in_callback, 1631 }; 1632 1633 static int __init moschip7720_init(void) 1634 { 1635 int retval; 1636 1637 dbg("%s: Entering ..........", __FUNCTION__); 1638 1639 /* Register with the usb serial */ 1640 retval = usb_serial_register(&moschip7720_2port_driver); 1641 if (retval) 1642 goto failed_port_device_register; 1643 1644 info(DRIVER_DESC " " DRIVER_VERSION); 1645 1646 /* Register with the usb */ 1647 retval = usb_register(&usb_driver); 1648 if (retval) 1649 goto failed_usb_register; 1650 1651 return 0; 1652 1653 failed_usb_register: 1654 usb_serial_deregister(&moschip7720_2port_driver); 1655 1656 failed_port_device_register: 1657 return retval; 1658 } 1659 1660 static void __exit moschip7720_exit(void) 1661 { 1662 usb_deregister(&usb_driver); 1663 usb_serial_deregister(&moschip7720_2port_driver); 1664 } 1665 1666 module_init(moschip7720_init); 1667 module_exit(moschip7720_exit); 1668 1669 /* Module information */ 1670 MODULE_AUTHOR( DRIVER_AUTHOR ); 1671 MODULE_DESCRIPTION( DRIVER_DESC ); 1672 MODULE_LICENSE("GPL"); 1673 1674 module_param(debug, bool, S_IRUGO | S_IWUSR); 1675 MODULE_PARM_DESC(debug, "Debug enabled or not"); 1676