8940704c75ae0e6815a19ad9432da3569100ea16
[linux-flexiantxendom0-3.2.10.git] / drivers / usb / serial / ftdi_sio.c
1 /*
2  * USB FTDI SIO driver
3  *
4  *      Copyright (C) 1999, 2000
5  *          Greg Kroah-Hartman (greg@kroah.com)
6  *          Bill Ryder (bryder@sgi.com)
7  *
8  *      This program is free software; you can redistribute it and/or modify
9  *      it under the terms of the GNU General Public License as published by
10  *      the Free Software Foundation; either version 2 of the License, or
11  *      (at your option) any later version.
12  *
13  * See Documentation/usb/usb-serial.txt for more information on using this driver
14  *
15  * See http://reality.sgi.com/bryder_wellington/ftdi_sio for upto date testing info
16  *     and extra documentation
17  *       
18  * (12/3/2000) Bill Ryder
19  *     Added support for 8U232AM device.
20  *     Moved PID and VIDs into header file only.
21  *     Turned on low-latency for the tty (device will do high baudrates)
22  *     Added shutdown routine to close files when device removed.
23  *     More debug and error message cleanups.
24  *     
25  *
26  * (11/13/2000) Bill Ryder
27  *     Added spinlock protected open code and close code.
28  *     Multiple opens work (sort of - see webpage mentioned above).
29  *     Cleaned up comments. Removed multiple PID/VID definitions.
30  *     Factorised cts/dtr code
31  *     Made use of __FUNCTION__ in dbg's
32  *      
33  * (11/01/2000) Adam J. Richter
34  *      usb_device_id table support
35  * 
36  * (10/05/2000) gkh
37  *      Fixed bug with urb->dev not being set properly, now that the usb
38  *      core needs it.
39  * 
40  * (09/11/2000) gkh
41  *      Removed DEBUG #ifdefs with call to usb_serial_debug_data
42  *
43  * (07/19/2000) gkh
44  *      Added module_init and module_exit functions to handle the fact that this
45  *      driver is a loadable module now.
46  *
47  * (04/04/2000) Bill Ryder 
48  *      Fixed bugs in TCGET/TCSET ioctls (by removing them - they are 
49  *        handled elsewhere in the tty io driver chain).
50  *
51  * (03/30/2000) Bill Ryder 
52  *      Implemented lots of ioctls
53  *      Fixed a race condition in write
54  *      Changed some dbg's to errs
55  *
56  * (03/26/2000) gkh
57  *      Split driver up into device specific pieces.
58  *
59  */
60
61 /* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */
62 /* Thanx to FTDI for so kindly providing details of the protocol required */
63 /*   to talk to the device */
64 /* Thanx to gkh and the rest of the usb dev group for all code I have assimilated :-) */
65
66
67 #include <linux/config.h>
68 #include <linux/kernel.h>
69 #include <linux/sched.h>
70 #include <linux/signal.h>
71 #include <linux/errno.h>
72 #include <linux/poll.h>
73 #include <linux/init.h>
74 #include <linux/slab.h>
75 #include <linux/fcntl.h>
76 #include <linux/tty.h>
77 #include <linux/tty_driver.h>
78 #include <linux/tty_flip.h>
79 #include <linux/module.h>
80 #include <linux/spinlock.h>
81
82 #ifdef CONFIG_USB_SERIAL_DEBUG
83         #define DEBUG
84 #else
85         #undef DEBUG
86 #endif
87 #include <linux/usb.h>
88
89 #include "usb-serial.h"
90
91 #include "ftdi_sio.h"
92
93
94 static __devinitdata struct usb_device_id id_table_sio [] = {
95         { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
96         { }                                             /* Terminating entry */
97 };
98
99 /* THe 8U232AM has the same API as the sio - but it can support MUCH 
100    higher baudrates (921600 at 48MHz/230400 at 12MHz 
101    so .. it's baudrate setting codes are different */
102
103    
104 static __devinitdata struct usb_device_id id_table_8U232AM [] = {
105         { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
106         { }                                             /* Terminating entry */
107 };
108
109
110 static __devinitdata struct usb_device_id id_table_combined [] = {
111         { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
112         { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
113         { }                                             /* Terminating entry */
114 };
115
116 MODULE_DEVICE_TABLE (usb, id_table_combined);
117
118
119 struct ftdi_private {
120         ftdi_type_t ftdi_type;
121         char last_status_byte; /* device sends this every 40ms when open */
122         
123         
124 };
125 /* function prototypes for a FTDI serial converter */
126 static int  ftdi_sio_startup            (struct usb_serial *serial);
127 static int  ftdi_8U232AM_startup        (struct usb_serial *serial);
128 static void ftdi_sio_shutdown           (struct usb_serial *serial);
129 static int  ftdi_sio_open               (struct usb_serial_port *port, struct file *filp);
130 static void ftdi_sio_close              (struct usb_serial_port *port, struct file *filp);
131 static int  ftdi_sio_write              (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
132 static void ftdi_sio_write_bulk_callback (struct urb *urb);
133 static void ftdi_sio_read_bulk_callback (struct urb *urb);
134 static void ftdi_sio_set_termios        (struct usb_serial_port *port, struct termios * old);
135 static int  ftdi_sio_ioctl              (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
136
137 /* Should rename most ftdi_sio's to ftdi_ now since there are two devices 
138    which share common code */ 
139
140 struct usb_serial_device_type ftdi_sio_device = {
141         name:                   "FTDI SIO",
142         id_table:               id_table_sio,
143         needs_interrupt_in:     MUST_HAVE_NOT,
144         needs_bulk_in:          MUST_HAVE,
145         needs_bulk_out:         MUST_HAVE,
146         num_interrupt_in:       0,
147         num_bulk_in:            1,
148         num_bulk_out:           1,
149         num_ports:              1,
150         open:                   ftdi_sio_open,
151         close:                  ftdi_sio_close,
152         write:                  ftdi_sio_write,
153         read_bulk_callback:     ftdi_sio_read_bulk_callback,
154         write_bulk_callback:    ftdi_sio_write_bulk_callback,
155         ioctl:                  ftdi_sio_ioctl,
156         set_termios:            ftdi_sio_set_termios,
157         startup:                ftdi_sio_startup,
158         shutdown:               ftdi_sio_shutdown,
159 };
160
161 struct usb_serial_device_type ftdi_8U232AM_device = {
162         name:                   "FTDI 8U232AM",
163         id_table:               id_table_8U232AM,
164         needs_interrupt_in:     DONT_CARE,
165         needs_bulk_in:          MUST_HAVE,
166         needs_bulk_out:         MUST_HAVE,
167         num_interrupt_in:       0,
168         num_bulk_in:            1,
169         num_bulk_out:           1,
170         num_ports:              1,
171         open:                   ftdi_sio_open,
172         close:                  ftdi_sio_close,
173         write:                  ftdi_sio_write,
174         read_bulk_callback:     ftdi_sio_read_bulk_callback,
175         write_bulk_callback:    ftdi_sio_write_bulk_callback,
176         ioctl:                  ftdi_sio_ioctl,
177         set_termios:            ftdi_sio_set_termios,
178         startup:                ftdi_8U232AM_startup,
179         shutdown:               ftdi_sio_shutdown,
180 };
181
182
183 /*
184  * ***************************************************************************
185  * FTDI SIO Serial Converter specific driver functions
186  * ***************************************************************************
187  */
188
189 #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
190
191 /* utility functions to set and unset dtr and rts */
192 #define HIGH 1
193 #define LOW 0
194 static int set_rts(struct usb_device *dev, 
195                    unsigned int pipe,
196                    int high_or_low)
197 {
198         static char buf[1];
199         unsigned ftdi_high_or_low = (high_or_low? FTDI_SIO_SET_RTS_HIGH : 
200                                 FTDI_SIO_SET_RTS_LOW);
201         return(usb_control_msg(dev, pipe,
202                                FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
203                                FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
204                                ftdi_high_or_low, 0, 
205                                buf, 0, WDR_TIMEOUT));
206 }
207 static int set_dtr(struct usb_device *dev, 
208                    unsigned int pipe,
209                    int high_or_low)
210 {
211         static char buf[1];
212         unsigned ftdi_high_or_low = (high_or_low? FTDI_SIO_SET_DTR_HIGH : 
213                                 FTDI_SIO_SET_DTR_LOW);
214         return(usb_control_msg(dev, pipe,
215                                FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
216                                FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
217                                ftdi_high_or_low, 0, 
218                                buf, 0, WDR_TIMEOUT));
219 }
220
221
222
223 static int ftdi_sio_startup (struct usb_serial *serial)
224 {
225         struct ftdi_private *priv;
226         
227         init_waitqueue_head(&serial->port[0].write_wait);
228         
229         priv = serial->port->private = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
230         if (!priv){
231                 err(__FUNCTION__"- kmalloc(%d) failed.", sizeof(struct ftdi_private));
232                 return -ENOMEM;
233         }
234
235         priv->ftdi_type = sio;
236         
237         return (0);
238 }
239
240
241 static int ftdi_8U232AM_startup (struct usb_serial *serial)
242 {
243         struct ftdi_private *priv;
244  
245         init_waitqueue_head(&serial->port[0].write_wait);
246
247         priv = serial->port->private = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
248         if (!priv){
249                 err(__FUNCTION__"- kmalloc(%d) failed.", sizeof(struct ftdi_private));
250                 return -ENOMEM;
251         }
252
253         priv->ftdi_type = F8U232AM;
254         
255         return (0);
256 }
257
258 static void ftdi_sio_shutdown (struct usb_serial *serial)
259 {
260         
261         dbg (__FUNCTION__);
262
263         /* Close ports if they are open */
264         while (serial->port[0].open_count > 0) {
265                 ftdi_sio_close (&serial->port[0], NULL);
266         }
267         if (serial->port->private){
268                 kfree(serial->port->private);
269                 serial->port->private = NULL;
270         }
271 }
272
273
274
275 static int  ftdi_sio_open (struct usb_serial_port *port, struct file *filp)
276 { /* ftdi_sio_open */
277         struct termios tmp_termios;
278         struct usb_serial *serial = port->serial;
279         unsigned long flags;    /* Used for spinlock */
280         int result;
281         char buf[1]; /* Needed for the usb_control_msg I think */
282
283         dbg(__FUNCTION__);
284
285         spin_lock_irqsave (&port->port_lock, flags);
286         
287         MOD_INC_USE_COUNT;
288         ++port->open_count;
289
290         if (!port->active){
291                 port->active = 1;
292
293                 spin_unlock_irqrestore (&port->port_lock, flags);
294
295                 /* do not allow a task to be queued to deliver received data */
296                 port->tty->low_latency = 1;
297
298                 /* No error checking for this (will get errors later anyway) */
299                 /* See ftdi_sio.h for description of what is reset */
300                 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
301                                 FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 
302                                 FTDI_SIO_RESET_SIO, 
303                                 0, buf, 0, WDR_TIMEOUT);
304
305                 /* Setup termios defaults. According to tty_io.c the 
306                    settings are driver specific */
307                 port->tty->termios->c_cflag =
308                         B9600 | CS8 | CREAD | HUPCL | CLOCAL;
309
310                 /* ftdi_sio_set_termios  will send usb control messages */
311                 ftdi_sio_set_termios(port, &tmp_termios);       
312
313                 /* Turn on RTS and DTR since we are not flow controlling by default */
314                 if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0),HIGH) < 0) {
315                         err(__FUNCTION__ " Error from DTR HIGH urb");
316                 }
317                 if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),HIGH) < 0){
318                         err(__FUNCTION__ " Error from RTS HIGH urb");
319                 }
320         
321                 /* Start reading from the device */
322                 FILL_BULK_URB(port->read_urb, serial->dev, 
323                               usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
324                               port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
325                               ftdi_sio_read_bulk_callback, port);
326                 result = usb_submit_urb(port->read_urb);
327                 if (result)
328                         err(__FUNCTION__ " - failed submitting read urb, error %d", result);
329         } else { /* the port was already active - so no initialisation is done */
330                 spin_unlock_irqrestore (&port->port_lock, flags);
331         }
332
333         return (0);
334 } /* ftdi_sio_open */
335
336
337 static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp)
338 { /* ftdi_sio_close */
339         struct usb_serial *serial = port->serial;
340         unsigned int c_cflag = port->tty->termios->c_cflag;
341         char buf[1];
342         unsigned long flags;
343
344         dbg( __FUNCTION__);
345
346         spin_lock_irqsave (&port->port_lock, flags);
347         --port->open_count;
348
349         if (port->open_count <= 0) {
350                 spin_unlock_irqrestore (&port->port_lock, flags);
351                 if (c_cflag & HUPCL){
352                         /* Disable flow control */
353                         if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
354                                             FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
355                                             FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
356                                             0, 0, 
357                                             buf, 0, WDR_TIMEOUT) < 0) {
358                                 err("error from flowcontrol urb");
359                         }           
360
361                         /* drop DTR */
362                         if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0), LOW) < 0){
363                                 err("Error from DTR LOW urb");
364                         }
365                         /* drop RTS */
366                         if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0) {
367                                 err("Error from RTS LOW urb");
368                         }       
369                 } /* Note change no line is hupcl is off */
370
371                 /* shutdown our bulk reads and writes */
372                 usb_unlink_urb (port->write_urb);
373                 usb_unlink_urb (port->read_urb);
374                 port->active = 0;
375                 port->open_count = 0;
376         } else {  
377                 spin_unlock_irqrestore (&port->port_lock, flags);
378
379                 /* Send a HUP if necessary */
380                 if (!(port->tty->termios->c_cflag & CLOCAL)){
381                         tty_hangup(port->tty);
382                 }
383                 
384         }
385
386         MOD_DEC_USE_COUNT;
387
388 } /* ftdi_sio_close */
389
390
391   
392 /* The ftdi_sio requires the first byte to have:
393  *  B0 1
394  *  B1 0
395  *  B2..7 length of message excluding byte 0
396  */
397 static int ftdi_sio_write (struct usb_serial_port *port, int from_user, 
398                            const unsigned char *buf, int count)
399 { /* ftdi_sio_write */
400         struct usb_serial *serial = port->serial;
401         struct ftdi_private *priv = (struct ftdi_private *)port->private;
402         int data_offset ;
403         int rc; 
404         int result;
405         DECLARE_WAITQUEUE(wait, current);
406         
407         dbg(__FUNCTION__ " port %d, %d bytes", port->number, count);
408
409         if (count == 0) {
410                 err("write request of 0 bytes");
411                 return 0;
412         }
413         
414         if (priv->ftdi_type == sio){
415                 data_offset = 1;
416         } else {
417                 data_offset = 0;
418         }
419         dbg("data_offset set to %d",data_offset);
420
421         /* only do something if we have a bulk out endpoint */
422         if (serial->num_bulk_out) {
423                 unsigned char *first_byte = port->write_urb->transfer_buffer;
424
425                 /* Was seeing a race here, got a read callback, then write callback before
426                    hitting interuptible_sleep_on  - so wrapping in a wait_queue */
427
428                 add_wait_queue(&port->write_wait, &wait);
429                 set_current_state (TASK_INTERRUPTIBLE);
430                 while (port->write_urb->status == -EINPROGRESS) {
431                         dbg(__FUNCTION__ " write in progress - retrying");
432                         if (signal_pending(current)) {
433                                 current->state = TASK_RUNNING;
434                                 remove_wait_queue(&port->write_wait, &wait);
435                                 rc = -ERESTARTSYS;
436                                 goto err;
437                         }
438                         schedule();
439                 }               
440                 remove_wait_queue(&port->write_wait, &wait);
441                 set_current_state(TASK_RUNNING);
442
443                 count += data_offset;
444                 count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
445                 if (count == 0) {
446                         return 0;
447                 }
448
449                 /* Copy in the data to send */
450                 if (from_user) {
451                         copy_from_user(port->write_urb->transfer_buffer + data_offset , 
452                                        buf, count - data_offset );
453                 }
454                 else {
455                         memcpy(port->write_urb->transfer_buffer + data_offset,
456                                buf, count - data_offset );
457                 }  
458
459                 first_byte = port->write_urb->transfer_buffer;
460                 if (data_offset > 0){
461                         /* Write the control byte at the front of the packet*/
462                         *first_byte = 1 | ((count-data_offset) << 2) ; 
463                 }
464
465                 dbg(__FUNCTION__ " Bytes: %d, First Byte: 0o%03o",count, first_byte[0]);
466                 usb_serial_debug_data (__FILE__, __FUNCTION__, count, first_byte);
467                 
468                 /* send the data out the bulk port */
469                 FILL_BULK_URB(port->write_urb, serial->dev, 
470                               usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
471                               port->write_urb->transfer_buffer, count,
472                               ftdi_sio_write_bulk_callback, port);
473                 
474                 result = usb_submit_urb(port->write_urb);
475                 if (result) {
476                         err(__FUNCTION__ " - failed submitting write urb, error %d", result);
477                         return 0;
478                 }
479
480                 dbg(__FUNCTION__ " write returning: %d", count - data_offset);
481                 return (count - data_offset);
482         }
483         
484         /* no bulk out, so return 0 bytes written */
485         return 0;
486  err: /* error exit */
487         return(rc);
488 } /* ftdi_sio_write */
489
490 static void ftdi_sio_write_bulk_callback (struct urb *urb)
491 {
492         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
493         struct usb_serial *serial;
494         struct tty_struct *tty = port->tty;
495
496         dbg("ftdi_sio_write_bulk_callback");
497
498         if (port_paranoia_check (port, "ftdi_sio_write_bulk_callback")) {
499                 return;
500         }
501
502         serial = port->serial;
503         if (serial_paranoia_check (serial, "ftdi_sio_write_bulk_callback")) {
504                 return;
505         }
506         
507         if (urb->status) {
508                 dbg("nonzero write bulk status received: %d", urb->status);
509                 return;
510         }
511
512         wake_up_interruptible(&port->write_wait);
513         if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
514                 (tty->ldisc.write_wakeup)(tty);
515
516         wake_up_interruptible(&tty->write_wait);
517         
518         return;
519 } /* ftdi_sio_write_bulk_callback */
520
521 static void ftdi_sio_read_bulk_callback (struct urb *urb)
522 { /* ftdi_sio_serial_buld_callback */
523         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
524         struct ftdi_private *priv = (struct ftdi_private *)port->private;
525         struct usb_serial *serial;
526         struct tty_struct *tty = port->tty ;
527         unsigned char *data = urb->transfer_buffer;
528
529         const int data_offset = 2;
530         int i;
531         int result;
532
533         dbg(__FUNCTION__);
534
535         if (port_paranoia_check (port, "ftdi_sio_read_bulk_callback")) {
536                 return;
537         }
538
539         serial = port->serial;
540         if (serial_paranoia_check (serial, "ftdi_sio_read_bulk_callback")) {
541                 return;
542         }
543
544         if (urb->status) {
545                 /* This will happen at close every time so it is a dbg not an err */
546                 dbg("nonzero read bulk status received: %d", urb->status);
547                 return;
548         }
549
550         if (urb->actual_length > 2) {
551                 usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
552         } else {
553                 dbg("Just status");
554         }
555
556         priv->last_status_byte = data[0]; /* this has modem control lines */
557
558         /* TO DO -- check for hung up line and handle appropriately: */
559         /*   send hangup  */
560         /* See acm.c - you do a tty_hangup  - eg tty_hangup(tty) */
561         /* if CD is dropped and the line is not CLOCAL then we should hangup */
562
563
564         if (urb->actual_length > data_offset) {
565                 for (i = data_offset ; i < urb->actual_length ; ++i) {
566                         tty_insert_flip_char(tty, data[i], 0);
567                 }
568                 tty_flip_buffer_push(tty);
569         }
570
571         /* Continue trying to always read  */
572         FILL_BULK_URB(urb, serial->dev, 
573                       usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
574                       urb->transfer_buffer, urb->transfer_buffer_length,
575                       ftdi_sio_read_bulk_callback, port);
576
577         result = usb_submit_urb(urb);
578         if (result)
579                 err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
580
581         return;
582 } /* ftdi_sio_serial_read_bulk_callback */
583
584
585 __u16 translate_baudrate_to_ftdi(unsigned int cflag, ftdi_type_t ftdi_type) 
586 { /* translate_baudrate_to_ftdi */
587         
588         __u16 urb_value = ftdi_sio_b9600;
589
590         if (ftdi_type == sio){
591                 switch(cflag & CBAUD){
592                 case B0: break; /* ignored by this */
593                 case B300: urb_value = ftdi_sio_b300; dbg("Set to 300"); break;
594                 case B600: urb_value = ftdi_sio_b600; dbg("Set to 600") ; break;
595                 case B1200: urb_value = ftdi_sio_b1200; dbg("Set to 1200") ; break;
596                 case B2400: urb_value = ftdi_sio_b2400; dbg("Set to 2400") ; break;
597                 case B4800: urb_value = ftdi_sio_b4800; dbg("Set to 4800") ; break;
598                 case B9600: urb_value = ftdi_sio_b9600; dbg("Set to 9600") ; break;
599                 case B19200: urb_value = ftdi_sio_b19200; dbg("Set to 19200") ; break;
600                 case B38400: urb_value = ftdi_sio_b38400; dbg("Set to 38400") ; break;
601                 case B57600: urb_value = ftdi_sio_b57600; dbg("Set to 57600") ; break;
602                 case B115200: urb_value = ftdi_sio_b115200; dbg("Set to 115200") ; break;
603                 default: dbg(__FUNCTION__ " FTDI_SIO does not support the baudrate (%d) requested",
604                              (cflag & CBAUD)); 
605                    break;
606                 }
607         } else { /* it is 8U232AM */
608                 switch(cflag & CBAUD){
609                 case B0: break; /* ignored by this */
610                 case B300: urb_value = ftdi_8U232AM_48MHz_b300; dbg("Set to 300"); break;
611                 case B600: urb_value = ftdi_8U232AM_48MHz_b600; dbg("Set to 600") ; break;
612                 case B1200: urb_value = ftdi_8U232AM_48MHz_b1200; dbg("Set to 1200") ; break;
613                 case B2400: urb_value = ftdi_8U232AM_48MHz_b2400; dbg("Set to 2400") ; break;
614                 case B4800: urb_value = ftdi_8U232AM_48MHz_b4800; dbg("Set to 4800") ; break;
615                 case B9600: urb_value = ftdi_8U232AM_48MHz_b9600; dbg("Set to 9600") ; break;
616                 case B19200: urb_value = ftdi_8U232AM_48MHz_b19200; dbg("Set to 19200") ; break;
617                 case B38400: urb_value = ftdi_8U232AM_48MHz_b38400; dbg("Set to 38400") ; break;
618                 case B57600: urb_value = ftdi_8U232AM_48MHz_b57600; dbg("Set to 57600") ; break;
619                 case B115200: urb_value = ftdi_8U232AM_48MHz_b115200; dbg("Set to 115200") ; break;
620                 case B230400: urb_value = ftdi_8U232AM_48MHz_b230400; dbg("Set to 230400") ; break;
621                 case B460800: urb_value = ftdi_8U232AM_48MHz_b460800; dbg("Set to 460800") ; break;
622                 case B921600: urb_value = ftdi_8U232AM_48MHz_b921600; dbg("Set to 921600") ; break;
623                 default: dbg(__FUNCTION__ " The baudrate (%d) requested is not implemented",
624                              (cflag & CBAUD)); 
625                    break;
626                 }
627         }
628         return(urb_value);
629 }
630
631 /* As I understand this - old_termios contains the original termios settings */
632 /*  and tty->termios contains the new setting to be used */
633 /* */
634 /*   WARNING: set_termios calls this with old_termios in kernel space */
635
636 static void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios *old_termios)
637 { /* ftdi_sio_set_termios */
638         struct usb_serial *serial = port->serial;
639         unsigned int cflag = port->tty->termios->c_cflag;
640         struct ftdi_private *priv = (struct ftdi_private *)port->private;       
641         __u16 urb_value; /* will hold the new flags */
642         char buf[1]; /* Perhaps I should dynamically alloc this? */
643         
644         
645         dbg(__FUNCTION__);
646
647
648         /* FIXME -For this cut I don't care if the line is really changing or 
649            not  - so just do the change regardless  - should be able to 
650            compare old_termios and tty->termios */
651         /* NOTE These routines can get interrupted by 
652            ftdi_sio_read_bulk_callback  - need to examine what this 
653            means - don't see any problems yet */
654         
655         /* Set number of data bits, parity, stop bits */
656         
657         urb_value = 0;
658         urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 :
659                       FTDI_SIO_SET_DATA_STOP_BITS_1);
660         urb_value |= (cflag & PARENB ? 
661                       (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : 
662                        FTDI_SIO_SET_DATA_PARITY_EVEN) :
663                       FTDI_SIO_SET_DATA_PARITY_NONE);
664         if (cflag & CSIZE) {
665                 switch (cflag & CSIZE) {
666                 case CS5: urb_value |= 5; dbg("Setting CS5"); break;
667                 case CS6: urb_value |= 6; dbg("Setting CS6"); break;
668                 case CS7: urb_value |= 7; dbg("Setting CS7"); break;
669                 case CS8: urb_value |= 8; dbg("Setting CS8"); break;
670                 default:
671                         err("CSIZE was set but not CS5-CS8");
672                 }
673         }
674         if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
675                             FTDI_SIO_SET_DATA_REQUEST, 
676                             FTDI_SIO_SET_DATA_REQUEST_TYPE,
677                             urb_value , 0,
678                             buf, 0, 100) < 0) {
679                 err(__FUNCTION__ " FAILED to set databits/stopbits/parity");
680         }          
681
682         /* Now do the baudrate */
683         urb_value = translate_baudrate_to_ftdi((cflag & CBAUD), priv->ftdi_type);
684         
685         if ((cflag & CBAUD) == B0 ) {
686                 /* Disable flow control */
687                 if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
688                                     FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
689                                     FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
690                                     0, 0, 
691                                     buf, 0, WDR_TIMEOUT) < 0) {
692                         err(__FUNCTION__ " error from disable flowcontrol urb");
693                 }           
694                 /* Drop RTS and DTR */
695                 if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0){
696                         err(__FUNCTION__ " Error from DTR LOW urb");
697                 }
698                 if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0){
699                         err(__FUNCTION__ " Error from RTS LOW urb");
700                 }       
701                 
702         } else {
703                 /* set the baudrate determined before */
704                 if (usb_control_msg(serial->dev, 
705                                     usb_sndctrlpipe(serial->dev, 0),
706                                     FTDI_SIO_SET_BAUDRATE_REQUEST, 
707                                     FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
708                                     urb_value, 0, 
709                                     buf, 0, 100) < 0) {
710                         err(__FUNCTION__ " urb failed to set baurdrate");
711                 }
712         }
713         /* Set flow control */
714         /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
715         if (cflag & CRTSCTS) {
716                 dbg(__FUNCTION__ " Setting to CRTSCTS flow control");
717                 if (usb_control_msg(serial->dev, 
718                                     usb_sndctrlpipe(serial->dev, 0),
719                                     FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
720                                     FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
721                                     0 , FTDI_SIO_RTS_CTS_HS,
722                                     buf, 0, WDR_TIMEOUT) < 0) {
723                         err("urb failed to set to rts/cts flow control");
724                 }               
725                 
726         } else { 
727                 /* CHECKME Assuming XON/XOFF handled by tty stack - not by device */
728                 dbg(__FUNCTION__ " Turning off hardware flow control");
729                 if (usb_control_msg(serial->dev, 
730                                     usb_sndctrlpipe(serial->dev, 0),
731                                     FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
732                                     FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
733                                     0, 0, 
734                                     buf, 0, WDR_TIMEOUT) < 0) {
735                         err("urb failed to clear flow control");
736                 }                               
737                 
738         }
739         return;
740 } /* ftdi_sio_set_termios */
741
742 static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
743 {
744         struct usb_serial *serial = port->serial;
745         struct ftdi_private *priv = (struct ftdi_private *)port->private;
746         __u16 urb_value=0; /* Will hold the new flags */
747         char buf[1];
748         int  ret, mask;
749         
750         dbg(__FUNCTION__ " cmd 0x%04x", cmd);
751
752         /* Based on code from acm.c and others */
753         switch (cmd) {
754
755         case TIOCMGET:
756                 dbg(__FUNCTION__ " TIOCMGET");
757                 /* The MODEM_STATUS_REQUEST works for the sio but not the 232 */
758                 if (priv->ftdi_type == sio){
759                         /* TO DECIDE - use the 40ms status packets or not? */
760                         /*   PRO: No need to send urb */
761                         /*   CON: Could be 40ms out of date */
762
763                         /* Request the status from the device */
764                         if ((ret = usb_control_msg(serial->dev, 
765                                                    usb_rcvctrlpipe(serial->dev, 0),
766                                                    FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
767                                                    FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
768                                                    0, 0, 
769                                                    buf, 1, WDR_TIMEOUT)) < 0 ) {
770                                 err(__FUNCTION__ " Could not get modem status of device - err: %d",
771                                     ret);
772                                 return(ret);
773                         }
774                 } else {
775                         /* This gets updated every 40ms - so just copy it in */
776                         buf[0] = priv->last_status_byte;
777                 }
778
779                 return put_user((buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
780                                 (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) |
781                                 (buf[0]  & FTDI_SIO_RI_MASK  ? TIOCM_RI  : 0) |
782                                 (buf[0]  & FTDI_SIO_RLSD_MASK ? TIOCM_CD  : 0),
783                                 (unsigned long *) arg);
784                 break;
785
786         case TIOCMSET: /* Turns on and off the lines as specified by the mask */
787                 dbg(__FUNCTION__ " TIOCMSET");
788                 if ((ret = get_user(mask, (unsigned long *) arg))) return ret;
789                 urb_value = ((mask & TIOCM_DTR) ? HIGH : LOW);
790                 if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0),urb_value) < 0){
791                         err("Error from DTR set urb (TIOCMSET)");
792                 }
793                 urb_value = ((mask & TIOCM_RTS) ? HIGH : LOW);
794                 if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),urb_value) < 0){
795                         err("Error from RTS set urb (TIOCMSET)");
796                 }       
797                 break;
798                                         
799         case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */
800                 dbg(__FUNCTION__ " TIOCMBIS");
801                 if ((ret = get_user(mask, (unsigned long *) arg))) return ret;
802                 if (mask & TIOCM_DTR){
803                         if ((ret = set_dtr(serial->dev, 
804                                            usb_sndctrlpipe(serial->dev, 0),
805                                            HIGH)) < 0) {
806                                 err("Urb to set DTR failed");
807                                 return(ret);
808                         }
809                 }
810                 if (mask & TIOCM_RTS) {
811                         if ((ret = set_rts(serial->dev, 
812                                            usb_sndctrlpipe(serial->dev, 0),
813                                            HIGH)) < 0){
814                                 err("Urb to set RTS failed");
815                                 return(ret);
816                         }
817                 }
818                                         break;
819
820         case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */
821                 dbg(__FUNCTION__ " TIOCMBIC");
822                 if ((ret = get_user(mask, (unsigned long *) arg))) return ret;
823                 if (mask & TIOCM_DTR){
824                         if ((ret = set_dtr(serial->dev, 
825                                            usb_sndctrlpipe(serial->dev, 0),
826                                            LOW)) < 0){
827                                 err("Urb to unset DTR failed");
828                                 return(ret);
829                         }
830                 }       
831                 if (mask & TIOCM_RTS) {
832                         if ((ret = set_rts(serial->dev, 
833                                            usb_sndctrlpipe(serial->dev, 0),
834                                            LOW)) < 0){
835                                 err("Urb to unset RTS failed");
836                                 return(ret);
837                         }
838                 }
839                 break;
840
841                 /*
842                  * I had originally implemented TCSET{A,S}{,F,W} and
843                  * TCGET{A,S} here separately, however when testing I
844                  * found that the higher layers actually do the termios
845                  * conversions themselves and pass the call onto
846                  * ftdi_sio_set_termios. 
847                  *
848                  */
849
850         default:
851           /* This is not an error - turns out the higher layers will do 
852            *  some ioctls itself (see comment above)
853            */
854                 dbg(__FUNCTION__ " arg not supported - it was 0x%04x",cmd);
855                 return(-ENOIOCTLCMD);
856                 break;
857         }
858         return 0;
859 } /* ftdi_sio_ioctl */
860
861
862 static int __init ftdi_sio_init (void)
863 {
864         dbg(__FUNCTION__);
865         usb_serial_register (&ftdi_sio_device);
866         usb_serial_register (&ftdi_8U232AM_device);
867         return 0;
868 }
869
870
871 static void __exit ftdi_sio_exit (void)
872 {
873         dbg(__FUNCTION__);
874         usb_serial_deregister (&ftdi_sio_device);
875         usb_serial_deregister (&ftdi_8U232AM_device);
876 }
877
878
879 module_init(ftdi_sio_init);
880 module_exit(ftdi_sio_exit);
881
882 MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>");
883 MODULE_DESCRIPTION("USB FTDI RS232 converters driver");