ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / usb / serial / mct_u232.c
1 /*
2  * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver
3  *
4  *   Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch)
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  * This program is largely derived from the Belkin USB Serial Adapter Driver
12  * (see belkin_sa.[ch]). All of the information about the device was acquired
13  * by using SniffUSB on Windows98. For technical details see mct_u232.h.
14  *
15  * William G. Greathouse and Greg Kroah-Hartman provided great help on how to
16  * do the reverse engineering and how to write a USB serial device driver.
17  *
18  * TO BE DONE, TO BE CHECKED:
19  *   DTR/RTS signal handling may be incomplete or incorrect. I have mainly
20  *   implemented what I have seen with SniffUSB or found in belkin_sa.c.
21  *   For further TODOs check also belkin_sa.c.
22  *
23  * TEST STATUS:
24  *   Basic tests have been performed with minicom/zmodem transfers and
25  *   modem dialing under Linux 2.4.0-test10 (for me it works fine).
26  *
27  * 04-Nov-2003 Bill Marr <marr at flex dot com>
28  *   - Mimic Windows driver by sending 2 USB 'device request' messages
29  *     following normal 'baud rate change' message.  This allows data to be
30  *     transmitted to RS-232 devices which don't assert the 'CTS' signal.
31  *
32  * 10-Nov-2001 Wolfgang Grandegger
33  *   - Fixed an endianess problem with the baudrate selection for PowerPC.
34  *
35  * 06-Dec-2001 Martin Hamilton <martinh@gnu.org>
36  *      Added support for the Belkin F5U109 DB9 adaptor
37  *
38  * 30-May-2001 Greg Kroah-Hartman
39  *      switched from using spinlock to a semaphore, which fixes lots of problems.
40  *
41  * 04-May-2001 Stelian Pop
42  *   - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes
43  *     instead of the device reported 32 (using 32 bytes causes many data
44  *     loss, Windows driver uses 16 too).
45  *
46  * 02-May-2001 Stelian Pop
47  *   - Fixed the baud calculation for Sitecom U232-P25 model
48  *
49  * 08-Apr-2001 gb
50  *   - Identify version on module load.
51  *
52  * 06-Jan-2001 Cornel Ciocirlan 
53  *   - Added support for Sitecom U232-P25 model (Product Id 0x0230)
54  *   - Added support for D-Link DU-H3SP USB BAY (Product Id 0x0200)
55  *
56  * 29-Nov-2000 Greg Kroah-Hartman
57  *   - Added device id table to fit with 2.4.0-test11 structure.
58  *   - took out DEAL_WITH_TWO_INT_IN_ENDPOINTS #define as it's not needed
59  *     (lots of things will change if/when the usb-serial core changes to
60  *     handle these issues.
61  *
62  * 27-Nov-2000 Wolfgang Grandegger
63  *   A version for kernel 2.4.0-test10 released to the Linux community 
64  *   (via linux-usb-devel).
65  */
66
67 #include <linux/config.h>
68 #include <linux/kernel.h>
69 #include <linux/errno.h>
70 #include <linux/init.h>
71 #include <linux/slab.h>
72 #include <linux/tty.h>
73 #include <linux/tty_driver.h>
74 #include <linux/tty_flip.h>
75 #include <linux/module.h>
76 #include <linux/spinlock.h>
77 #include <asm/uaccess.h>
78 #include <linux/usb.h>
79
80 #ifdef CONFIG_USB_SERIAL_DEBUG
81         static int debug = 1;
82 #else
83         static int debug;
84 #endif
85
86 #include "usb-serial.h"
87 #include "mct_u232.h"
88
89
90 /*
91  * Version Information
92  */
93 #define DRIVER_VERSION "v1.2"
94 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
95 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
96
97 /*
98  * Some not properly written applications do not handle the return code of
99  * write() correctly. This can result in character losses. A work-a-round
100  * can be compiled in with the following definition. This work-a-round
101  * should _NOT_ be part of an 'official' kernel release, of course!
102  */
103 #undef FIX_WRITE_RETURN_CODE_PROBLEM
104 #ifdef FIX_WRITE_RETURN_CODE_PROBLEM
105 static int write_blocking; /* disabled by default */
106 #endif
107
108 /*
109  * Function prototypes
110  */
111 static int  mct_u232_startup             (struct usb_serial *serial);
112 static void mct_u232_shutdown            (struct usb_serial *serial);
113 static int  mct_u232_open                (struct usb_serial_port *port,
114                                           struct file *filp);
115 static void mct_u232_close               (struct usb_serial_port *port,
116                                           struct file *filp);
117 #ifdef FIX_WRITE_RETURN_CODE_PROBLEM
118 static int  mct_u232_write               (struct usb_serial_port *port,
119                                           int from_user,
120                                           const unsigned char *buf,
121                                           int count);
122 static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
123 #endif
124 static void mct_u232_read_int_callback   (struct urb *urb, struct pt_regs *regs);
125 static void mct_u232_set_termios         (struct usb_serial_port *port,
126                                           struct termios * old);
127 static int  mct_u232_ioctl               (struct usb_serial_port *port,
128                                           struct file * file,
129                                           unsigned int cmd,
130                                           unsigned long arg);
131 static void mct_u232_break_ctl           (struct usb_serial_port *port,
132                                           int break_state );
133 static int  mct_u232_tiocmget            (struct usb_serial_port *port,
134                                           struct file *file);
135 static int  mct_u232_tiocmset            (struct usb_serial_port *port,
136                                           struct file *file, unsigned int set,
137                                           unsigned int clear);
138 /*
139  * All of the device info needed for the MCT USB-RS232 converter.
140  */
141 static struct usb_device_id id_table_combined [] = {
142         { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
143         { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
144         { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
145         { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
146         { }             /* Terminating entry */
147 };
148
149 MODULE_DEVICE_TABLE (usb, id_table_combined);
150
151 static struct usb_driver mct_u232_driver = {
152         .owner =        THIS_MODULE,
153         .name =         "mct_u232",
154         .probe =        usb_serial_probe,
155         .disconnect =   usb_serial_disconnect,
156         .id_table =     id_table_combined,
157 };
158
159 static struct usb_serial_device_type mct_u232_device = {
160         .owner =             THIS_MODULE,
161         .name =              "Magic Control Technology USB-RS232",
162         .short_name =        "mct_u232",
163         .id_table =          id_table_combined,
164         .num_interrupt_in =  2,
165         .num_bulk_in =       0,
166         .num_bulk_out =      1,
167         .num_ports =         1,
168         .open =              mct_u232_open,
169         .close =             mct_u232_close,
170 #ifdef FIX_WRITE_RETURN_CODE_PROBLEM
171         .write =             mct_u232_write,
172         .write_bulk_callback = mct_u232_write_bulk_callback,
173 #endif
174         .read_int_callback = mct_u232_read_int_callback,
175         .ioctl =             mct_u232_ioctl,
176         .set_termios =       mct_u232_set_termios,
177         .break_ctl =         mct_u232_break_ctl,
178         .tiocmget =          mct_u232_tiocmget,
179         .tiocmset =          mct_u232_tiocmset,
180         .attach =            mct_u232_startup,
181         .shutdown =          mct_u232_shutdown,
182 };
183
184
185 struct mct_u232_private {
186         spinlock_t lock;
187         unsigned int         control_state; /* Modem Line Setting (TIOCM) */
188         unsigned char        last_lcr;      /* Line Control Register */
189         unsigned char        last_lsr;      /* Line Status Register */
190         unsigned char        last_msr;      /* Modem Status Register */
191 };
192
193 /*
194  * Handle vendor specific USB requests
195  */
196
197 #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
198
199 /*
200  * Later day 2.6.0-test kernels have new baud rates like B230400 which
201  * we do not know how to support. We ignore them for the moment.
202  * XXX Rate-limit the error message, it's user triggerable.
203  */
204 static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
205         if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID
206           || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) {
207                 switch (value) {
208                 case    B300: return 0x01;
209                 case    B600: return 0x02; /* this one not tested */
210                 case   B1200: return 0x03;
211                 case   B2400: return 0x04;
212                 case   B4800: return 0x06;
213                 case   B9600: return 0x08;
214                 case  B19200: return 0x09;
215                 case  B38400: return 0x0a;
216                 case  B57600: return 0x0b;
217                 case B115200: return 0x0c;
218                 default:
219                         err("MCT USB-RS232: unsupported baudrate request 0x%x,"
220                             " using default of B9600", value);
221                         return 0x08;
222                 }
223         } else {
224                 switch (value) {
225                 case    B300: value =     300;
226                 case    B600: value =     600;
227                 case   B1200: value =    1200;
228                 case   B2400: value =    2400;
229                 case   B4800: value =    4800;
230                 case   B9600: value =    9600;
231                 case  B19200: value =   19200;
232                 case  B38400: value =   38400;
233                 case  B57600: value =   57600;
234                 case B115200: value =  115200;
235                 default:
236                         err("MCT USB-RS232: unsupported baudrate request 0x%x,"
237                             " using default of B9600", value);
238                         value = 9600;
239                 }
240                 return 115200/value;
241         }
242 }
243
244 static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
245 {
246         unsigned int divisor;
247         int rc;
248         unsigned char zero_byte = 0;
249
250         divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value));
251
252         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
253                              MCT_U232_SET_BAUD_RATE_REQUEST,
254                              MCT_U232_SET_REQUEST_TYPE,
255                              0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
256                              WDR_TIMEOUT);
257         if (rc < 0)
258                 err("Set BAUD RATE %d failed (error = %d)", value, rc);
259         dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
260
261         /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
262            always sends two extra USB 'device request' messages after the
263            'baud rate change' message.  The actual functionality of the
264            request codes in these messages is not fully understood but these
265            particular codes are never seen in any operation besides a baud
266            rate change.  Both of these messages send a single byte of data
267            whose value is always zero.  The second of these two extra messages
268            is required in order for data to be properly written to an RS-232
269            device which does not assert the 'CTS' signal. */
270
271         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
272                              MCT_U232_SET_UNKNOWN1_REQUEST, 
273                              MCT_U232_SET_REQUEST_TYPE,
274                              0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE, 
275                              WDR_TIMEOUT);
276         if (rc < 0)
277                 err("Sending USB device request code %d failed (error = %d)", 
278                     MCT_U232_SET_UNKNOWN1_REQUEST, rc);
279
280         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
281                              MCT_U232_SET_UNKNOWN2_REQUEST, 
282                              MCT_U232_SET_REQUEST_TYPE,
283                              0, 0, &zero_byte, MCT_U232_SET_UNKNOWN2_SIZE, 
284                              WDR_TIMEOUT);
285         if (rc < 0)
286                 err("Sending USB device request code %d failed (error = %d)", 
287                     MCT_U232_SET_UNKNOWN2_REQUEST, rc);
288
289         return rc;
290 } /* mct_u232_set_baud_rate */
291
292 static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
293 {
294         int rc;
295         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
296                              MCT_U232_SET_LINE_CTRL_REQUEST,
297                              MCT_U232_SET_REQUEST_TYPE,
298                              0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
299                              WDR_TIMEOUT);
300         if (rc < 0)
301                 err("Set LINE CTRL 0x%x failed (error = %d)", lcr, rc);
302         dbg("set_line_ctrl: 0x%x", lcr);
303         return rc;
304 } /* mct_u232_set_line_ctrl */
305
306 static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
307                                    unsigned int control_state)
308 {
309         int rc;
310         unsigned char mcr = MCT_U232_MCR_NONE;
311
312         if (control_state & TIOCM_DTR)
313                 mcr |= MCT_U232_MCR_DTR;
314         if (control_state & TIOCM_RTS)
315                 mcr |= MCT_U232_MCR_RTS;
316
317         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
318                              MCT_U232_SET_MODEM_CTRL_REQUEST,
319                              MCT_U232_SET_REQUEST_TYPE,
320                              0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
321                              WDR_TIMEOUT);
322         if (rc < 0)
323                 err("Set MODEM CTRL 0x%x failed (error = %d)", mcr, rc);
324         dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
325
326         return rc;
327 } /* mct_u232_set_modem_ctrl */
328
329 static int mct_u232_get_modem_stat(struct usb_serial *serial, unsigned char *msr)
330 {
331         int rc;
332         rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
333                              MCT_U232_GET_MODEM_STAT_REQUEST,
334                              MCT_U232_GET_REQUEST_TYPE,
335                              0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
336                              WDR_TIMEOUT);
337         if (rc < 0) {
338                 err("Get MODEM STATus failed (error = %d)", rc);
339                 *msr = 0;
340         }
341         dbg("get_modem_stat: 0x%x", *msr);
342         return rc;
343 } /* mct_u232_get_modem_stat */
344
345 static void mct_u232_msr_to_state(unsigned int *control_state, unsigned char msr)
346 {
347         /* Translate Control Line states */
348         if (msr & MCT_U232_MSR_DSR)
349                 *control_state |=  TIOCM_DSR;
350         else
351                 *control_state &= ~TIOCM_DSR;
352         if (msr & MCT_U232_MSR_CTS)
353                 *control_state |=  TIOCM_CTS;
354         else
355                 *control_state &= ~TIOCM_CTS;
356         if (msr & MCT_U232_MSR_RI)
357                 *control_state |=  TIOCM_RI;
358         else
359                 *control_state &= ~TIOCM_RI;
360         if (msr & MCT_U232_MSR_CD)
361                 *control_state |=  TIOCM_CD;
362         else
363                 *control_state &= ~TIOCM_CD;
364         dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
365 } /* mct_u232_msr_to_state */
366
367 /*
368  * Driver's tty interface functions
369  */
370
371 static int mct_u232_startup (struct usb_serial *serial)
372 {
373         struct mct_u232_private *priv;
374         struct usb_serial_port *port, *rport;
375
376         /* allocate the private data structure */
377         priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
378         if (!priv)
379                 return -ENOMEM;
380         /* set initial values for control structures */
381         spin_lock_init(&priv->lock);
382         priv->control_state = 0;
383         priv->last_lsr = 0;
384         priv->last_msr = 0;
385         usb_set_serial_port_data(serial->port[0], priv);
386
387         init_waitqueue_head(&serial->port[0]->write_wait);
388
389         /* Puh, that's dirty */
390         port = serial->port[0];
391         rport = serial->port[1];
392         if (port->read_urb) {
393                 /* No unlinking, it wasn't submitted yet. */
394                 usb_free_urb(port->read_urb);
395         }
396         port->read_urb = rport->interrupt_in_urb;
397         rport->interrupt_in_urb = NULL;
398         port->read_urb->context = port;
399
400         return (0);
401 } /* mct_u232_startup */
402
403
404 static void mct_u232_shutdown (struct usb_serial *serial)
405 {
406         struct mct_u232_private *priv;
407         int i;
408         
409         dbg("%s", __FUNCTION__);
410
411         for (i=0; i < serial->num_ports; ++i) {
412                 /* My special items, the standard routines free my urbs */
413                 priv = usb_get_serial_port_data(serial->port[i]);
414                 if (priv)
415                         kfree(priv);
416         }
417 } /* mct_u232_shutdown */
418
419 static int  mct_u232_open (struct usb_serial_port *port, struct file *filp)
420 {
421         struct usb_serial *serial = port->serial;
422         struct mct_u232_private *priv = usb_get_serial_port_data(port);
423         int retval = 0;
424         unsigned int control_state;
425         unsigned long flags;
426         unsigned char last_lcr;
427         unsigned char last_msr;
428
429         dbg("%s port %d", __FUNCTION__, port->number);
430
431         /* Compensate for a hardware bug: although the Sitecom U232-P25
432          * device reports a maximum output packet size of 32 bytes,
433          * it seems to be able to accept only 16 bytes (and that's what
434          * SniffUSB says too...)
435          */
436         if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID)
437                 port->bulk_out_size = 16;
438
439         /* Do a defined restart: the normal serial device seems to 
440          * always turn on DTR and RTS here, so do the same. I'm not
441          * sure if this is really necessary. But it should not harm
442          * either.
443          */
444         spin_lock_irqsave(&priv->lock, flags);
445         if (port->tty->termios->c_cflag & CBAUD)
446                 priv->control_state = TIOCM_DTR | TIOCM_RTS;
447         else
448                 priv->control_state = 0;
449         
450         priv->last_lcr = (MCT_U232_DATA_BITS_8 | 
451                           MCT_U232_PARITY_NONE |
452                           MCT_U232_STOP_BITS_1);
453         control_state = priv->control_state;
454         last_lcr = priv->last_lcr;
455         spin_unlock_irqrestore(&priv->lock, flags);
456         mct_u232_set_modem_ctrl(serial, control_state);
457         mct_u232_set_line_ctrl(serial, last_lcr);
458
459         /* Read modem status and update control state */
460         mct_u232_get_modem_stat(serial, &last_msr);
461         spin_lock_irqsave(&priv->lock, flags);
462         priv->last_msr = last_msr;
463         mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
464         spin_unlock_irqrestore(&priv->lock, flags);
465
466         port->read_urb->dev = port->serial->dev;
467         retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
468         if (retval) {
469                 err("usb_submit_urb(read bulk) failed");
470                 goto exit;
471         }
472
473         port->interrupt_in_urb->dev = port->serial->dev;
474         retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
475         if (retval)
476                 err(" usb_submit_urb(read int) failed");
477
478 exit:
479         return 0;
480 } /* mct_u232_open */
481
482
483 static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
484 {
485         dbg("%s port %d", __FUNCTION__, port->number);
486
487         if (port->serial->dev) {
488                 /* shutdown our urbs */
489                 usb_unlink_urb (port->write_urb);
490                 usb_unlink_urb (port->read_urb);
491                 usb_unlink_urb (port->interrupt_in_urb);
492         }
493 } /* mct_u232_close */
494
495
496 #ifdef FIX_WRITE_RETURN_CODE_PROBLEM
497 /* The generic routines work fine otherwise */
498
499 static int mct_u232_write (struct usb_serial_port *port, int from_user,
500                            const unsigned char *buf, int count)
501 {
502         struct usb_serial *serial = port->serial;
503         int result, bytes_sent, size;
504
505         dbg("%s - port %d", __FUNCTION__, port->number);
506
507         if (count == 0) {
508                 dbg("%s - write request of 0 bytes", __FUNCTION__);
509                 return (0);
510         }
511
512         /* only do something if we have a bulk out endpoint */
513         if (!serial->num_bulk_out)
514                 return(0);
515         
516         /* another write is still pending? */
517         if (port->write_urb->status == -EINPROGRESS) {
518                 dbg("%s - already writing", __FUNCTION__);
519                 return (0);
520         }
521                 
522         bytes_sent = 0;
523         while (count > 0) {
524                 size = (count > port->bulk_out_size) ? port->bulk_out_size : count;
525                 
526                 usb_serial_debug_data (__FILE__, __FUNCTION__, size, buf);
527                 
528                 if (from_user) {
529                         if (copy_from_user(port->write_urb->transfer_buffer, buf, size)) {
530                                 return -EFAULT;
531                         }
532                 }
533                 else {
534                         memcpy (port->write_urb->transfer_buffer, buf, size);
535                 }
536                 
537                 /* set up our urb */
538                 usb_fill_bulk_urb(port->write_urb, serial->dev,
539                               usb_sndbulkpipe(serial->dev,
540                                               port->bulk_out_endpointAddress),
541                               port->write_urb->transfer_buffer, size,
542                               ((serial->type->write_bulk_callback) ?
543                                serial->type->write_bulk_callback :
544                                mct_u232_write_bulk_callback),
545                               port);
546                 
547                 /* send the data out the bulk port */
548                 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
549                 if (result) {
550                         err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
551                         return result;
552                 }
553
554                 bytes_sent += size;
555                 if (write_blocking)
556                         interruptible_sleep_on(&port->write_wait);
557                 else
558                         break;
559
560                 buf += size;
561                 count -= size;
562         }
563         
564         return bytes_sent;
565 } /* mct_u232_write */
566
567 static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
568 {
569         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
570         struct usb_serial *serial = port->serial;
571         struct tty_struct *tty = port->tty;
572
573         dbg("%s - port %d", __FUNCTION__, port->number);
574         
575         if (!serial) {
576                 dbg("%s - bad serial pointer, exiting", __FUNCTION__);
577                 return;
578         }
579
580         if (urb->status) {
581                 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__,
582                     urb->status);
583                 return;
584         }
585
586         if (write_blocking) {
587                 wake_up_interruptible(&port->write_wait);
588                 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
589                     tty->ldisc.write_wakeup)
590                         (tty->ldisc.write_wakeup)(tty);
591                 wake_up_interruptible(&tty->write_wait);
592                 
593         } else {
594                 /* from generic_write_bulk_callback */
595                 schedule_work(&port->work);
596         }
597
598         return;
599 } /* mct_u232_write_bulk_callback */
600 #endif
601
602 static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs)
603 {
604         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
605         struct mct_u232_private *priv = usb_get_serial_port_data(port);
606         struct usb_serial *serial = port->serial;
607         struct tty_struct *tty;
608         unsigned char *data = urb->transfer_buffer;
609         int status;
610         unsigned long flags;
611
612         dbg("%s - port %d", __FUNCTION__, port->number);
613
614         switch (urb->status) {
615         case 0:
616                 /* success */
617                 break;
618         case -ECONNRESET:
619         case -ENOENT:
620         case -ESHUTDOWN:
621                 /* this urb is terminated, clean up */
622                 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
623                 return;
624         default:
625                 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
626                 goto exit;
627         }
628
629         if (!serial) {
630                 dbg("%s - bad serial pointer, exiting", __FUNCTION__);
631                 return;
632         }
633         
634         usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
635
636         /*
637          * Work-a-round: handle the 'usual' bulk-in pipe here
638          */
639         if (urb->transfer_buffer_length > 2) {
640                 int i;
641                 tty = port->tty;
642                 if (urb->actual_length) {
643                         for (i = 0; i < urb->actual_length ; ++i) {
644                                 tty_insert_flip_char(tty, data[i], 0);
645                         }
646                         tty_flip_buffer_push(tty);
647                 }
648                 goto exit;
649         }
650         
651         /*
652          * The interrupt-in pipe signals exceptional conditions (modem line
653          * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
654          */
655         spin_lock_irqsave(&priv->lock, flags);
656         priv->last_msr = data[MCT_U232_MSR_INDEX];
657         
658         /* Record Control Line states */
659         mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
660
661 #if 0
662         /* Not yet handled. See belin_sa.c for further information */
663         /* Now to report any errors */
664         priv->last_lsr = data[MCT_U232_LSR_INDEX];
665         /*
666          * fill in the flip buffer here, but I do not know the relation
667          * to the current/next receive buffer or characters.  I need
668          * to look in to this before committing any code.
669          */
670         if (priv->last_lsr & MCT_U232_LSR_ERR) {
671                 tty = port->tty;
672                 /* Overrun Error */
673                 if (priv->last_lsr & MCT_U232_LSR_OE) {
674                 }
675                 /* Parity Error */
676                 if (priv->last_lsr & MCT_U232_LSR_PE) {
677                 }
678                 /* Framing Error */
679                 if (priv->last_lsr & MCT_U232_LSR_FE) {
680                 }
681                 /* Break Indicator */
682                 if (priv->last_lsr & MCT_U232_LSR_BI) {
683                 }
684         }
685 #endif
686         spin_unlock_irqrestore(&priv->lock, flags);
687 exit:
688         status = usb_submit_urb (urb, GFP_ATOMIC);
689         if (status)
690                 err ("%s - usb_submit_urb failed with result %d",
691                      __FUNCTION__, status);
692 } /* mct_u232_read_int_callback */
693
694 static void mct_u232_set_termios (struct usb_serial_port *port,
695                                   struct termios *old_termios)
696 {
697         struct usb_serial *serial = port->serial;
698         struct mct_u232_private *priv = usb_get_serial_port_data(port);
699         unsigned int iflag = port->tty->termios->c_iflag;
700         unsigned int cflag = port->tty->termios->c_cflag;
701         unsigned int old_cflag = old_termios->c_cflag;
702         unsigned long flags;
703         unsigned int control_state, new_state;
704         unsigned char last_lcr;
705
706         /* get a local copy of the current port settings */
707         spin_lock_irqsave(&priv->lock, flags);
708         control_state = priv->control_state;
709         spin_unlock_irqrestore(&priv->lock, flags);
710         last_lcr = 0;
711
712         /*
713          * Update baud rate.
714          * Do not attempt to cache old rates and skip settings,
715          * disconnects screw such tricks up completely.
716          * Premature optimization is the root of all evil.
717          */
718
719         /* reassert DTR and (maybe) RTS on transition from B0 */
720         if ((old_cflag & CBAUD) == B0) {
721                 dbg("%s: baud was B0", __FUNCTION__);
722                 control_state |= TIOCM_DTR;
723                 /* don't set RTS if using hardware flow control */
724                 if (!(old_cflag & CRTSCTS)) {
725                         control_state |= TIOCM_RTS;
726                 }
727                 mct_u232_set_modem_ctrl(serial, control_state);
728         }
729
730         mct_u232_set_baud_rate(serial, cflag & CBAUD);
731
732         if ((cflag & CBAUD) == B0 ) {
733                 dbg("%s: baud is B0", __FUNCTION__);
734                 /* Drop RTS and DTR */
735                 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
736                 mct_u232_set_modem_ctrl(serial, control_state);
737         }
738
739         /*
740          * Update line control register (LCR)
741          */
742
743         /* set the parity */
744         if (cflag & PARENB)
745                 last_lcr |= (cflag & PARODD) ?
746                         MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
747         else
748                 last_lcr |= MCT_U232_PARITY_NONE;
749
750         /* set the number of data bits */
751         switch (cflag & CSIZE) {
752         case CS5:
753                 last_lcr |= MCT_U232_DATA_BITS_5; break;
754         case CS6:
755                 last_lcr |= MCT_U232_DATA_BITS_6; break;
756         case CS7:
757                 last_lcr |= MCT_U232_DATA_BITS_7; break;
758         case CS8:
759                 last_lcr |= MCT_U232_DATA_BITS_8; break;
760         default:
761                 err("CSIZE was not CS5-CS8, using default of 8");
762                 last_lcr |= MCT_U232_DATA_BITS_8;
763                 break;
764         }
765
766         /* set the number of stop bits */
767         last_lcr |= (cflag & CSTOPB) ?
768                 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
769
770         mct_u232_set_line_ctrl(serial, last_lcr);
771
772         /*
773          * Set flow control: well, I do not really now how to handle DTR/RTS.
774          * Just do what we have seen with SniffUSB on Win98.
775          */
776         /* Drop DTR/RTS if no flow control otherwise assert */
777         new_state = control_state;
778         if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
779                 new_state |= TIOCM_DTR | TIOCM_RTS;
780         else
781                 new_state &= ~(TIOCM_DTR | TIOCM_RTS);
782         if (new_state != control_state) {
783                 mct_u232_set_modem_ctrl(serial, control_state);
784                 control_state = new_state;
785         }
786
787         /* save off the modified port settings */
788         spin_lock_irqsave(&priv->lock, flags);
789         priv->control_state = control_state;
790         priv->last_lcr = last_lcr;
791         spin_unlock_irqrestore(&priv->lock, flags);
792 } /* mct_u232_set_termios */
793
794 static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
795 {
796         struct usb_serial *serial = port->serial;
797         struct mct_u232_private *priv = usb_get_serial_port_data(port);
798         unsigned char lcr;
799         unsigned long flags;
800
801         dbg("%sstate=%d", __FUNCTION__, break_state);
802
803         spin_lock_irqsave(&priv->lock, flags);
804         lcr = priv->last_lcr;
805         spin_unlock_irqrestore(&priv->lock, flags);
806
807         if (break_state)
808                 lcr |= MCT_U232_SET_BREAK;
809
810         mct_u232_set_line_ctrl(serial, lcr);
811 } /* mct_u232_break_ctl */
812
813
814 static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file)
815 {
816         struct mct_u232_private *priv = usb_get_serial_port_data(port);
817         unsigned int control_state;
818         unsigned long flags;
819         
820         dbg("%s", __FUNCTION__);
821
822         spin_lock_irqsave(&priv->lock, flags);
823         control_state = priv->control_state;
824         spin_unlock_irqrestore(&priv->lock, flags);
825
826         return control_state;
827 }
828
829 static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file,
830                               unsigned int set, unsigned int clear)
831 {
832         struct usb_serial *serial = port->serial;
833         struct mct_u232_private *priv = usb_get_serial_port_data(port);
834         unsigned int control_state;
835         unsigned long flags;
836         
837         dbg("%s", __FUNCTION__);
838
839         spin_lock_irqsave(&priv->lock, flags);
840         control_state = priv->control_state;
841
842         if (set & TIOCM_RTS)
843                 control_state |= TIOCM_RTS;
844         if (set & TIOCM_DTR)
845                 control_state |= TIOCM_DTR;
846         if (clear & TIOCM_RTS)
847                 control_state &= ~TIOCM_RTS;
848         if (clear & TIOCM_DTR)
849                 control_state &= ~TIOCM_DTR;
850
851         priv->control_state = control_state;
852         spin_unlock_irqrestore(&priv->lock, flags);
853         return mct_u232_set_modem_ctrl(serial, control_state);
854 }
855
856 static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
857                            unsigned int cmd, unsigned long arg)
858 {
859         dbg("%scmd=0x%x", __FUNCTION__, cmd);
860
861         /* Based on code from acm.c and others */
862         switch (cmd) {
863         case TIOCMIWAIT:
864                 /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
865                 /* TODO */
866                 return( 0 );
867
868         case TIOCGICOUNT:
869                 /* return count of modemline transitions */
870                 /* TODO */
871                 return 0;
872
873         default:
874                 dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd);
875                 return(-ENOIOCTLCMD);
876                 break;
877         }
878         return 0;
879 } /* mct_u232_ioctl */
880
881
882 static int __init mct_u232_init (void)
883 {
884         int retval;
885         retval = usb_serial_register(&mct_u232_device);
886         if (retval)
887                 goto failed_usb_serial_register;
888         retval = usb_register(&mct_u232_driver);
889         if (retval)
890                 goto failed_usb_register;
891         info(DRIVER_DESC " " DRIVER_VERSION);
892         return 0;
893 failed_usb_register:
894         usb_serial_deregister(&mct_u232_device);
895 failed_usb_serial_register:
896         return retval;
897 }
898
899
900 static void __exit mct_u232_exit (void)
901 {
902         usb_deregister (&mct_u232_driver);
903         usb_serial_deregister (&mct_u232_device);
904 }
905
906
907 module_init (mct_u232_init);
908 module_exit(mct_u232_exit);
909
910 MODULE_AUTHOR( DRIVER_AUTHOR );
911 MODULE_DESCRIPTION( DRIVER_DESC );
912 MODULE_LICENSE("GPL");
913
914 #ifdef FIX_WRITE_RETURN_CODE_PROBLEM
915 MODULE_PARM(write_blocking, "i");
916 MODULE_PARM_DESC(write_blocking, 
917                  "The write function will block to write out all data");
918 #endif
919
920 MODULE_PARM(debug, "i");
921 MODULE_PARM_DESC(debug, "Debug enabled or not");
922