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