4 * Copyright (C) 1999, 2000
5 * Greg Kroah-Hartman (greg@kroah.com)
6 * Bill Ryder (bryder@sgi.com)
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.
13 * See Documentation/usb/usb-serial.txt for more information on using this driver
15 * See http://reality.sgi.com/bryder_wellington/ftdi_sio for upto date testing info
16 * and extra documentation
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.
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
33 * (11/01/2000) Adam J. Richter
34 * usb_device_id table support
37 * Fixed bug with urb->dev not being set properly, now that the usb
41 * Removed DEBUG #ifdefs with call to usb_serial_debug_data
44 * Added module_init and module_exit functions to handle the fact that this
45 * driver is a loadable module now.
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).
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
57 * Split driver up into device specific pieces.
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 :-) */
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/malloc.h>
75 #include <linux/fcntl.h>
76 #include <linux/tty_driver.h>
77 #include <linux/tty_flip.h>
78 #include <linux/tty.h>
79 #include <linux/module.h>
80 #include <linux/spinlock.h>
82 #ifdef CONFIG_USB_SERIAL_DEBUG
87 #include <linux/usb.h>
89 #include "usb-serial.h"
94 static __devinitdata
struct usb_device_id id_table_sio
[] = {
95 { idVendor
: FTDI_VID
, idProduct
: FTDI_SIO_PID
},
96 { } /* Terminating entry */
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 */
104 static __devinitdata
struct usb_device_id id_table_8U232AM
[] = {
105 { idVendor
: FTDI_VID
, idProduct
: FTDI_8U232AM_PID
},
106 { } /* Terminating entry */
110 static __devinitdata
struct usb_device_id id_table_combined
[] = {
111 { idVendor
: FTDI_VID
, idProduct
: FTDI_SIO_PID
},
112 { idVendor
: FTDI_VID
, idProduct
: FTDI_8U232AM_PID
},
113 { } /* Terminating entry */
116 MODULE_DEVICE_TABLE (usb
, id_table_combined
);
119 struct ftdi_private
{
120 ftdi_type_t ftdi_type
;
121 char last_status_byte
; /* device sends this every 40ms when open */
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
);
137 /* Should rename most ftdi_sio's to ftdi_ now since there are two devices
138 which share common code */
140 struct usb_serial_device_type ftdi_sio_device
= {
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
,
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
,
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
,
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
,
184 * ***************************************************************************
185 * FTDI SIO Serial Converter specific driver functions
186 * ***************************************************************************
189 #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
191 /* utility functions to set and unset dtr and rts */
194 static int set_rts(struct usb_device
*dev
,
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
,
205 buf
, 0, WDR_TIMEOUT
));
207 static int set_dtr(struct usb_device
*dev
,
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
,
218 buf
, 0, WDR_TIMEOUT
));
223 static int ftdi_sio_startup (struct usb_serial
*serial
)
225 struct ftdi_private
*priv
;
227 init_waitqueue_head(&serial
->port
[0].write_wait
);
229 priv
= serial
->port
->private = kmalloc(sizeof(struct ftdi_private
), GFP_KERNEL
);
231 err(__FUNCTION__
"- kmalloc(%d) failed.", sizeof(struct ftdi_private
));
235 priv
->ftdi_type
= sio
;
241 static int ftdi_8U232AM_startup (struct usb_serial
*serial
)
243 struct ftdi_private
*priv
;
245 init_waitqueue_head(&serial
->port
[0].write_wait
);
247 priv
= serial
->port
->private = kmalloc(sizeof(struct ftdi_private
), GFP_KERNEL
);
249 err(__FUNCTION__
"- kmalloc(%d) failed.", sizeof(struct ftdi_private
));
253 priv
->ftdi_type
= F8U232AM
;
258 static void ftdi_sio_shutdown (struct usb_serial
*serial
)
263 /* Close ports if they are open */
264 while (serial
->port
[0].open_count
> 0) {
265 ftdi_sio_close (&serial
->port
[0], NULL
);
267 if (serial
->port
->private){
268 kfree(serial
->port
->private);
269 serial
->port
->private = NULL
;
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 */
281 char buf
[1]; /* Needed for the usb_control_msg I think */
285 spin_lock_irqsave (&port
->port_lock
, flags
);
293 spin_unlock_irqrestore (&port
->port_lock
, flags
);
295 /* do not allow a task to be queued to deliver received data */
296 port
->tty
->low_latency
= 1;
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
,
303 0, buf
, 0, WDR_TIMEOUT
);
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
;
310 /* ftdi_sio_set_termios will send usb control messages */
311 ftdi_sio_set_termios(port
, &tmp_termios
);
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");
317 if (set_rts(serial
->dev
, usb_sndctrlpipe(serial
->dev
, 0),HIGH
) < 0){
318 err(__FUNCTION__
" Error from RTS HIGH urb");
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
);
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
);
334 } /* ftdi_sio_open */
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
;
346 spin_lock_irqsave (&port
->port_lock
, flags
);
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
,
357 buf
, 0, WDR_TIMEOUT
) < 0) {
358 err("error from flowcontrol urb");
362 if (set_dtr(serial
->dev
, usb_sndctrlpipe(serial
->dev
, 0), LOW
) < 0){
363 err("Error from DTR LOW urb");
366 if (set_rts(serial
->dev
, usb_sndctrlpipe(serial
->dev
, 0),LOW
) < 0) {
367 err("Error from RTS LOW urb");
369 } /* Note change no line is hupcl is off */
371 /* shutdown our bulk reads and writes */
372 usb_unlink_urb (port
->write_urb
);
373 usb_unlink_urb (port
->read_urb
);
375 port
->open_count
= 0;
377 spin_unlock_irqrestore (&port
->port_lock
, flags
);
379 /* Send a HUP if necessary */
380 if (!(port
->tty
->termios
->c_cflag
& CLOCAL
)){
381 tty_hangup(port
->tty
);
388 } /* ftdi_sio_close */
392 /* The ftdi_sio requires the first byte to have:
395 * B2..7 length of message excluding byte 0
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;
405 DECLARE_WAITQUEUE(wait
, current
);
407 dbg(__FUNCTION__
" port %d, %d bytes", port
->number
, count
);
410 err("write request of 0 bytes");
414 if (priv
->ftdi_type
== sio
){
419 dbg("data_offset set to %d",data_offset
);
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
;
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 */
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
);
440 remove_wait_queue(&port
->write_wait
, &wait
);
441 set_current_state(TASK_RUNNING
);
443 count
+= data_offset
;
444 count
= (count
> port
->bulk_out_size
) ? port
->bulk_out_size
: count
;
449 /* Copy in the data to send */
451 copy_from_user(port
->write_urb
->transfer_buffer
+ data_offset
,
452 buf
, count
- data_offset
);
455 memcpy(port
->write_urb
->transfer_buffer
+ data_offset
,
456 buf
, count
- data_offset
);
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) ;
465 dbg(__FUNCTION__
" Bytes: %d, First Byte: 0o%03o",count
, first_byte
[0]);
466 usb_serial_debug_data (__FILE__
, __FUNCTION__
, count
, first_byte
);
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
);
474 result
= usb_submit_urb(port
->write_urb
);
476 err(__FUNCTION__
" - failed submitting write urb, error %d", result
);
480 dbg(__FUNCTION__
" write returning: %d", count
- data_offset
);
481 return (count
- data_offset
);
484 /* no bulk out, so return 0 bytes written */
486 err
: /* error exit */
488 } /* ftdi_sio_write */
490 static void ftdi_sio_write_bulk_callback (struct urb
*urb
)
492 struct usb_serial_port
*port
= (struct usb_serial_port
*)urb
->context
;
493 struct usb_serial
*serial
;
494 struct tty_struct
*tty
= port
->tty
;
496 dbg("ftdi_sio_write_bulk_callback");
498 if (port_paranoia_check (port
, "ftdi_sio_write_bulk_callback")) {
502 serial
= port
->serial
;
503 if (serial_paranoia_check (serial
, "ftdi_sio_write_bulk_callback")) {
508 dbg("nonzero write bulk status received: %d", urb
->status
);
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
);
516 wake_up_interruptible(&tty
->write_wait
);
519 } /* ftdi_sio_write_bulk_callback */
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
;
529 const int data_offset
= 2;
535 if (port_paranoia_check (port
, "ftdi_sio_read_bulk_callback")) {
539 serial
= port
->serial
;
540 if (serial_paranoia_check (serial
, "ftdi_sio_read_bulk_callback")) {
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
);
550 if (urb
->actual_length
> 2) {
551 usb_serial_debug_data (__FILE__
, __FUNCTION__
, urb
->actual_length
, data
);
556 priv
->last_status_byte
= data
[0]; /* this has modem control lines */
558 /* TO DO -- check for hung up line and handle appropriately: */
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 */
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);
568 tty_flip_buffer_push(tty
);
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
);
577 result
= usb_submit_urb(urb
);
579 err(__FUNCTION__
" - failed resubmitting read urb, error %d", result
);
582 } /* ftdi_sio_serial_read_bulk_callback */
585 __u16
translate_baudrate_to_ftdi(unsigned int cflag
, ftdi_type_t ftdi_type
)
586 { /* translate_baudrate_to_ftdi */
588 __u16 urb_value
= ftdi_sio_b9600
;
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",
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",
631 /* As I understand this - old_termios contains the original termios settings */
632 /* and tty->termios contains the new setting to be used */
634 /* WARNING: set_termios calls this with old_termios in kernel space */
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? */
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 */
655 /* Set number of data bits, parity, stop bits */
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
);
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;
671 err("CSIZE was set but not CS5-CS8");
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
,
679 err(__FUNCTION__
" FAILED to set databits/stopbits/parity");
682 /* Now do the baudrate */
683 urb_value
= translate_baudrate_to_ftdi((cflag
& CBAUD
), priv
->ftdi_type
);
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
,
691 buf
, 0, WDR_TIMEOUT
) < 0) {
692 err(__FUNCTION__
" error from disable flowcontrol urb");
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");
698 if (set_rts(serial
->dev
, usb_sndctrlpipe(serial
->dev
, 0),LOW
) < 0){
699 err(__FUNCTION__
" Error from RTS LOW urb");
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
,
710 err(__FUNCTION__
" urb failed to set baurdrate");
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");
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
,
734 buf
, 0, WDR_TIMEOUT
) < 0) {
735 err("urb failed to clear flow control");
740 } /* ftdi_sio_set_termios */
742 static int ftdi_sio_ioctl (struct usb_serial_port
*port
, struct file
* file
, unsigned int cmd
, unsigned long arg
)
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 */
750 dbg(__FUNCTION__
" cmd 0x%04x", cmd
);
752 /* Based on code from acm.c and others */
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 */
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
,
769 buf
, 1, WDR_TIMEOUT
)) < 0 ) {
770 err(__FUNCTION__
" Could not get modem status of device - err: %d",
775 /* This gets updated every 40ms - so just copy it in */
776 buf
[0] = priv
->last_status_byte
;
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
);
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)");
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)");
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),
806 err("Urb to set DTR failed");
810 if (mask
& TIOCM_RTS
) {
811 if ((ret
= set_rts(serial
->dev
,
812 usb_sndctrlpipe(serial
->dev
, 0),
814 err("Urb to set RTS failed");
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),
827 err("Urb to unset DTR failed");
831 if (mask
& TIOCM_RTS
) {
832 if ((ret
= set_rts(serial
->dev
,
833 usb_sndctrlpipe(serial
->dev
, 0),
835 err("Urb to unset RTS failed");
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.
851 /* This is not an error - turns out the higher layers will do
852 * some ioctls itself (see comment above)
854 dbg(__FUNCTION__
" arg not supported - it was 0x%04x",cmd
);
855 return(-ENOIOCTLCMD
);
859 } /* ftdi_sio_ioctl */
862 static int __init
ftdi_sio_init (void)
865 usb_serial_register (&ftdi_sio_device
);
866 usb_serial_register (&ftdi_8U232AM_device
);
871 static void __exit
ftdi_sio_exit (void)
874 usb_serial_deregister (&ftdi_sio_device
);
875 usb_serial_deregister (&ftdi_8U232AM_device
);
879 module_init(ftdi_sio_init
);
880 module_exit(ftdi_sio_exit
);
882 MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>");
883 MODULE_DESCRIPTION("USB FTDI RS232 converters driver");