2005-04-17 02:20:36 +04:00
/*
2014-10-04 15:19:59 +04:00
* USB Keyspan PDA / Xircom / Entrega Converter driver
2005-04-17 02:20:36 +04:00
*
* Copyright ( C ) 1999 - 2001 Greg Kroah - Hartman < greg @ kroah . com >
* Copyright ( C ) 1999 , 2000 Brian Warner < warner @ lothar . com >
* Copyright ( C ) 2000 Al Borchers < borchers @ steinerpoint . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
2008-07-22 14:13:42 +04:00
* See Documentation / usb / usb - serial . txt for more information on using this
* driver
2005-04-17 02:20:36 +04:00
*/
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/slab.h>
# include <linux/tty.h>
# include <linux/tty_driver.h>
# include <linux/tty_flip.h>
# include <linux/module.h>
# include <linux/spinlock.h>
# include <linux/workqueue.h>
2008-07-22 14:13:42 +04:00
# include <linux/uaccess.h>
2005-04-17 02:20:36 +04:00
# include <linux/usb.h>
2006-07-12 08:22:58 +04:00
# include <linux/usb/serial.h>
2012-09-18 11:00:41 +04:00
# include <linux/usb/ezusb.h>
2005-04-17 02:20:36 +04:00
/* make a simple define to handle if we are compiling keyspan_pda or xircom support */
2016-08-18 16:45:06 +03:00
# if IS_ENABLED(CONFIG_USB_SERIAL_KEYSPAN_PDA)
2005-04-17 02:20:36 +04:00
# define KEYSPAN
# else
# undef KEYSPAN
# endif
2016-08-18 16:45:06 +03:00
# if IS_ENABLED(CONFIG_USB_SERIAL_XIRCOM)
2005-04-17 02:20:36 +04:00
# define XIRCOM
# else
# undef XIRCOM
# endif
# define DRIVER_AUTHOR "Brian Warner <warner@lothar.com>"
# define DRIVER_DESC "USB Keyspan PDA Converter driver"
struct keyspan_pda_private {
int tx_room ;
int tx_throttled ;
struct work_struct wakeup_work ;
struct work_struct unthrottle_work ;
2006-11-22 17:57:56 +03:00
struct usb_serial * serial ;
struct usb_serial_port * port ;
2005-04-17 02:20:36 +04:00
} ;
# define KEYSPAN_VENDOR_ID 0x06cd
# define KEYSPAN_PDA_FAKE_ID 0x0103
# define KEYSPAN_PDA_ID 0x0104 /* no clue */
2014-10-04 15:19:59 +04:00
/* For Xircom PGSDB9 and older Entrega version of the same device */
2005-04-17 02:20:36 +04:00
# define XIRCOM_VENDOR_ID 0x085a
# define XIRCOM_FAKE_ID 0x8027
2015-03-16 18:19:55 +03:00
# define XIRCOM_FAKE_ID_2 0x8025 /* "PGMFHUB" serial */
2014-10-04 15:19:59 +04:00
# define ENTREGA_VENDOR_ID 0x1645
# define ENTREGA_FAKE_ID 0x8093
2005-04-17 02:20:36 +04:00
2010-01-10 17:34:24 +03:00
static const struct usb_device_id id_table_combined [ ] = {
2005-04-17 02:20:36 +04:00
# ifdef KEYSPAN
{ USB_DEVICE ( KEYSPAN_VENDOR_ID , KEYSPAN_PDA_FAKE_ID ) } ,
# endif
# ifdef XIRCOM
{ USB_DEVICE ( XIRCOM_VENDOR_ID , XIRCOM_FAKE_ID ) } ,
2015-03-16 18:19:55 +03:00
{ USB_DEVICE ( XIRCOM_VENDOR_ID , XIRCOM_FAKE_ID_2 ) } ,
2014-10-04 15:19:59 +04:00
{ USB_DEVICE ( ENTREGA_VENDOR_ID , ENTREGA_FAKE_ID ) } ,
2005-04-17 02:20:36 +04:00
# endif
{ USB_DEVICE ( KEYSPAN_VENDOR_ID , KEYSPAN_PDA_ID ) } ,
{ } /* Terminating entry */
} ;
2008-07-22 14:13:42 +04:00
MODULE_DEVICE_TABLE ( usb , id_table_combined ) ;
2005-04-17 02:20:36 +04:00
2010-01-10 17:34:24 +03:00
static const struct usb_device_id id_table_std [ ] = {
2005-04-17 02:20:36 +04:00
{ USB_DEVICE ( KEYSPAN_VENDOR_ID , KEYSPAN_PDA_ID ) } ,
{ } /* Terminating entry */
} ;
# ifdef KEYSPAN
2010-01-10 17:34:24 +03:00
static const struct usb_device_id id_table_fake [ ] = {
2005-04-17 02:20:36 +04:00
{ USB_DEVICE ( KEYSPAN_VENDOR_ID , KEYSPAN_PDA_FAKE_ID ) } ,
{ } /* Terminating entry */
} ;
# endif
# ifdef XIRCOM
2010-01-10 17:34:24 +03:00
static const struct usb_device_id id_table_fake_xircom [ ] = {
2008-07-22 14:13:42 +04:00
{ USB_DEVICE ( XIRCOM_VENDOR_ID , XIRCOM_FAKE_ID ) } ,
2015-03-16 18:19:55 +03:00
{ USB_DEVICE ( XIRCOM_VENDOR_ID , XIRCOM_FAKE_ID_2 ) } ,
2014-10-04 15:19:59 +04:00
{ USB_DEVICE ( ENTREGA_VENDOR_ID , ENTREGA_FAKE_ID ) } ,
2008-07-22 14:13:42 +04:00
{ }
2005-04-17 02:20:36 +04:00
} ;
# endif
2006-11-22 17:57:56 +03:00
static void keyspan_pda_wakeup_write ( struct work_struct * work )
2005-04-17 02:20:36 +04:00
{
2006-11-22 17:57:56 +03:00
struct keyspan_pda_private * priv =
container_of ( work , struct keyspan_pda_private , wakeup_work ) ;
struct usb_serial_port * port = priv - > port ;
2013-03-07 16:12:29 +04:00
tty_port_tty_wakeup ( & port - > port ) ;
2005-04-17 02:20:36 +04:00
}
2006-11-22 17:57:56 +03:00
static void keyspan_pda_request_unthrottle ( struct work_struct * work )
2005-04-17 02:20:36 +04:00
{
2006-11-22 17:57:56 +03:00
struct keyspan_pda_private * priv =
container_of ( work , struct keyspan_pda_private , unthrottle_work ) ;
struct usb_serial * serial = priv - > serial ;
2005-04-17 02:20:36 +04:00
int result ;
/* ask the device to tell us when the tx buffer becomes
sufficiently empty */
2008-07-22 14:13:42 +04:00
result = usb_control_msg ( serial - > dev ,
2005-04-17 02:20:36 +04:00
usb_sndctrlpipe ( serial - > dev , 0 ) ,
7 , /* request_unthrottle */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE
| USB_DIR_OUT ,
16 , /* value: threshold */
0 , /* index */
NULL ,
0 ,
2000 ) ;
if ( result < 0 )
2012-09-14 23:06:52 +04:00
dev_dbg ( & serial - > dev - > dev , " %s - error %d from usb_control_msg \n " ,
__func__ , result ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-22 14:13:42 +04:00
static void keyspan_pda_rx_interrupt ( struct urb * urb )
2005-04-17 02:20:36 +04:00
{
2008-02-24 13:41:47 +03:00
struct usb_serial_port * port = urb - > context ;
2005-04-17 02:20:36 +04:00
unsigned char * data = urb - > transfer_buffer ;
2017-01-31 19:17:29 +03:00
unsigned int len = urb - > actual_length ;
2007-06-16 02:44:13 +04:00
int retval ;
int status = urb - > status ;
2005-04-17 02:20:36 +04:00
struct keyspan_pda_private * priv ;
priv = usb_get_serial_port_data ( port ) ;
2007-06-16 02:44:13 +04:00
switch ( status ) {
2005-04-17 02:20:36 +04:00
case 0 :
/* success */
break ;
case - ECONNRESET :
case - ENOENT :
case - ESHUTDOWN :
/* this urb is terminated, clean up */
2012-09-14 23:06:52 +04:00
dev_dbg ( & urb - > dev - > dev , " %s - urb shutting down with status: %d \n " , __func__ , status ) ;
2011-02-28 12:34:05 +03:00
return ;
2005-04-17 02:20:36 +04:00
default :
2012-09-14 23:06:52 +04:00
dev_dbg ( & urb - > dev - > dev , " %s - nonzero urb status received: %d \n " , __func__ , status ) ;
2005-04-17 02:20:36 +04:00
goto exit ;
}
2017-01-31 19:17:29 +03:00
if ( len < 1 ) {
dev_warn ( & port - > dev , " short message received \n " ) ;
goto exit ;
}
2008-07-22 14:13:42 +04:00
/* see if the message is data or a status interrupt */
2005-04-17 02:20:36 +04:00
switch ( data [ 0 ] ) {
case 0 :
2011-02-28 12:34:05 +03:00
/* rest of message is rx data */
2017-01-31 19:17:29 +03:00
if ( len < 2 )
break ;
tty_insert_flip_string ( & port - > port , data + 1 , len - 1 ) ;
tty_flip_buffer_push ( & port - > port ) ;
2005-04-17 02:20:36 +04:00
break ;
case 1 :
/* status interrupt */
2017-01-31 19:17:29 +03:00
if ( len < 3 ) {
dev_warn ( & port - > dev , " short interrupt message received \n " ) ;
break ;
}
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " rx int, d1=%d, d2=%d \n " , data [ 1 ] , data [ 2 ] ) ;
2005-04-17 02:20:36 +04:00
switch ( data [ 1 ] ) {
case 1 : /* modemline change */
break ;
case 2 : /* tx unthrottle interrupt */
priv - > tx_throttled = 0 ;
/* queue up a wakeup at scheduler time */
schedule_work ( & priv - > wakeup_work ) ;
break ;
default :
break ;
}
break ;
default :
break ;
}
exit :
2008-07-22 14:13:42 +04:00
retval = usb_submit_urb ( urb , GFP_ATOMIC ) ;
2007-06-16 02:44:13 +04:00
if ( retval )
2008-10-13 13:39:46 +04:00
dev_err ( & port - > dev ,
2014-03-12 22:09:42 +04:00
" %s - usb_submit_urb failed with result %d \n " ,
2008-10-13 13:39:46 +04:00
__func__ , retval ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-22 14:09:07 +04:00
static void keyspan_pda_rx_throttle ( struct tty_struct * tty )
2005-04-17 02:20:36 +04:00
{
/* stop receiving characters. We just turn off the URB request, and
let chars pile up in the device . If we ' re doing hardware
flowcontrol , the device will signal the other end when its buffer
fills up . If we ' re doing XON / XOFF , this would be a good time to
send an XOFF , although it might make sense to foist that off
upon the device too . */
2008-07-22 14:09:07 +04:00
struct usb_serial_port * port = tty - > driver_data ;
2012-05-04 03:44:23 +04:00
2005-04-17 02:20:36 +04:00
usb_kill_urb ( port - > interrupt_in_urb ) ;
}
2008-07-22 14:09:07 +04:00
static void keyspan_pda_rx_unthrottle ( struct tty_struct * tty )
2005-04-17 02:20:36 +04:00
{
2008-07-22 14:09:07 +04:00
struct usb_serial_port * port = tty - > driver_data ;
2005-04-17 02:20:36 +04:00
/* just restart the receive interrupt URB */
2012-05-04 03:44:23 +04:00
2009-10-07 12:50:23 +04:00
if ( usb_submit_urb ( port - > interrupt_in_urb , GFP_KERNEL ) )
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " usb_submit_urb(read urb) failed \n " ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-22 14:13:42 +04:00
static speed_t keyspan_pda_setbaud ( struct usb_serial * serial , speed_t baud )
2005-04-17 02:20:36 +04:00
{
int rc ;
int bindex ;
2008-07-22 14:13:42 +04:00
switch ( baud ) {
case 110 :
bindex = 0 ;
break ;
case 300 :
bindex = 1 ;
break ;
case 1200 :
bindex = 2 ;
break ;
case 2400 :
bindex = 3 ;
break ;
case 4800 :
bindex = 4 ;
break ;
case 9600 :
bindex = 5 ;
break ;
case 19200 :
bindex = 6 ;
break ;
case 38400 :
bindex = 7 ;
break ;
case 57600 :
bindex = 8 ;
break ;
case 115200 :
bindex = 9 ;
break ;
default :
bindex = 5 ; /* Default to 9600 */
baud = 9600 ;
2005-04-17 02:20:36 +04:00
}
/* rather than figure out how to sleep while waiting for this
to complete , I just use the " legacy " API . */
rc = usb_control_msg ( serial - > dev , usb_sndctrlpipe ( serial - > dev , 0 ) ,
0 , /* set baud */
2008-07-22 14:13:42 +04:00
USB_TYPE_VENDOR
2005-04-17 02:20:36 +04:00
| USB_RECIP_INTERFACE
| USB_DIR_OUT , /* type */
bindex , /* value */
0 , /* index */
NULL , /* &data */
0 , /* size */
2000 ) ; /* timeout */
2007-12-14 03:15:28 +03:00
if ( rc < 0 )
return 0 ;
return baud ;
2005-04-17 02:20:36 +04:00
}
2008-07-22 14:09:07 +04:00
static void keyspan_pda_break_ctl ( struct tty_struct * tty , int break_state )
2005-04-17 02:20:36 +04:00
{
2008-07-22 14:09:07 +04:00
struct usb_serial_port * port = tty - > driver_data ;
2005-04-17 02:20:36 +04:00
struct usb_serial * serial = port - > serial ;
int value ;
int result ;
if ( break_state = = - 1 )
value = 1 ; /* start break */
else
value = 0 ; /* clear break */
result = usb_control_msg ( serial - > dev , usb_sndctrlpipe ( serial - > dev , 0 ) ,
2008-07-22 14:13:42 +04:00
4 , /* set break */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT ,
value , 0 , NULL , 0 , 2000 ) ;
2005-04-17 02:20:36 +04:00
if ( result < 0 )
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " %s - error %d from usb_control_msg \n " ,
__func__ , result ) ;
2005-04-17 02:20:36 +04:00
/* there is something funky about this.. the TCSBRK that 'cu' performs
ought to translate into a break_ctl ( - 1 ) , break_ctl ( 0 ) pair HZ / 4
seconds apart , but it feels like the break sent isn ' t as long as it
is on / dev / ttyS0 */
}
2008-07-22 14:09:07 +04:00
static void keyspan_pda_set_termios ( struct tty_struct * tty ,
struct usb_serial_port * port , struct ktermios * old_termios )
2005-04-17 02:20:36 +04:00
{
struct usb_serial * serial = port - > serial ;
2007-12-14 03:15:28 +03:00
speed_t speed ;
2005-04-17 02:20:36 +04:00
/* cflag specifies lots of stuff: number of stop bits, parity, number
of data bits , baud . What can the device actually handle ? :
CSTOPB ( 1 stop bit or 2 )
PARENB ( parity )
CSIZE ( 5 bit . . 8 bit )
There is minimal hw support for parity ( a PSW bit seems to hold the
parity of whatever is in the accumulator ) . The UART either deals
with 10 bits ( start , 8 data , stop ) or 11 bits ( start , 8 data ,
1 special , stop ) . So , with firmware changes , we could do :
8 N1 : 10 bit
8 N2 : 11 bit , extra bit always ( mark ? )
8 [ EOMS ] 1 : 11 bit , extra bit is parity
7 [ EOMS ] 1 : 10 bit , b0 / b7 is parity
7 [ EOMS ] 2 : 11 bit , b0 / b7 is parity , extra bit always ( mark ? )
2012-07-14 18:31:47 +04:00
HW flow control is dictated by the tty - > termios . c_cflags & CRTSCTS
2005-04-17 02:20:36 +04:00
bit .
For now , just do baud . */
2008-07-22 14:09:07 +04:00
speed = tty_get_baud_rate ( tty ) ;
2007-12-14 03:15:28 +03:00
speed = keyspan_pda_setbaud ( serial , speed ) ;
if ( speed = = 0 ) {
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " can't handle requested baud rate \n " ) ;
2007-12-14 03:15:28 +03:00
/* It hasn't changed so.. */
speed = tty_termios_baud_rate ( old_termios ) ;
2005-04-17 02:20:36 +04:00
}
2007-12-14 03:15:28 +03:00
/* Only speed can change so copy the old h/w parameters
then encode the new speed */
2012-07-14 18:31:47 +04:00
tty_termios_copy_hw ( & tty - > termios , old_termios ) ;
2008-07-22 14:09:07 +04:00
tty_encode_baud_rate ( tty , speed , speed ) ;
2005-04-17 02:20:36 +04:00
}
/* modem control pins: DTR and RTS are outputs and can be controlled.
DCD , RI , DSR , CTS are inputs and can be read . All outputs can also be
read . The byte passed is : DTR ( b7 ) DCD RI DSR CTS RTS ( b2 ) unused unused */
static int keyspan_pda_get_modem_info ( struct usb_serial * serial ,
unsigned char * value )
{
int rc ;
2009-12-29 01:01:51 +03:00
u8 * data ;
data = kmalloc ( 1 , GFP_KERNEL ) ;
if ( ! data )
return - ENOMEM ;
2005-04-17 02:20:36 +04:00
rc = usb_control_msg ( serial - > dev , usb_rcvctrlpipe ( serial - > dev , 0 ) ,
3 , /* get pins */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_IN ,
2009-12-29 01:01:51 +03:00
0 , 0 , data , 1 , 2000 ) ;
2008-06-27 13:22:32 +04:00
if ( rc > = 0 )
2009-12-29 01:01:51 +03:00
* value = * data ;
kfree ( data ) ;
2005-04-17 02:20:36 +04:00
return rc ;
}
static int keyspan_pda_set_modem_info ( struct usb_serial * serial ,
unsigned char value )
{
int rc ;
rc = usb_control_msg ( serial - > dev , usb_sndctrlpipe ( serial - > dev , 0 ) ,
3 , /* set pins */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT ,
value , 0 , NULL , 0 , 2000 ) ;
return rc ;
}
2011-02-14 19:26:14 +03:00
static int keyspan_pda_tiocmget ( struct tty_struct * tty )
2005-04-17 02:20:36 +04:00
{
2008-07-22 14:09:07 +04:00
struct usb_serial_port * port = tty - > driver_data ;
2005-04-17 02:20:36 +04:00
struct usb_serial * serial = port - > serial ;
int rc ;
unsigned char status ;
int value ;
rc = keyspan_pda_get_modem_info ( serial , & status ) ;
if ( rc < 0 )
return rc ;
value =
( ( status & ( 1 < < 7 ) ) ? TIOCM_DTR : 0 ) |
( ( status & ( 1 < < 6 ) ) ? TIOCM_CAR : 0 ) |
( ( status & ( 1 < < 5 ) ) ? TIOCM_RNG : 0 ) |
( ( status & ( 1 < < 4 ) ) ? TIOCM_DSR : 0 ) |
( ( status & ( 1 < < 3 ) ) ? TIOCM_CTS : 0 ) |
( ( status & ( 1 < < 2 ) ) ? TIOCM_RTS : 0 ) ;
return value ;
}
2011-02-14 19:26:50 +03:00
static int keyspan_pda_tiocmset ( struct tty_struct * tty ,
2005-04-17 02:20:36 +04:00
unsigned int set , unsigned int clear )
{
2008-07-22 14:09:07 +04:00
struct usb_serial_port * port = tty - > driver_data ;
2005-04-17 02:20:36 +04:00
struct usb_serial * serial = port - > serial ;
int rc ;
unsigned char status ;
rc = keyspan_pda_get_modem_info ( serial , & status ) ;
if ( rc < 0 )
return rc ;
if ( set & TIOCM_RTS )
status | = ( 1 < < 2 ) ;
if ( set & TIOCM_DTR )
status | = ( 1 < < 7 ) ;
if ( clear & TIOCM_RTS )
status & = ~ ( 1 < < 2 ) ;
if ( clear & TIOCM_DTR )
status & = ~ ( 1 < < 7 ) ;
rc = keyspan_pda_set_modem_info ( serial , status ) ;
return rc ;
}
2008-07-22 14:09:07 +04:00
static int keyspan_pda_write ( struct tty_struct * tty ,
struct usb_serial_port * port , const unsigned char * buf , int count )
2005-04-17 02:20:36 +04:00
{
struct usb_serial * serial = port - > serial ;
int request_unthrottle = 0 ;
int rc = 0 ;
struct keyspan_pda_private * priv ;
priv = usb_get_serial_port_data ( port ) ;
/* guess how much room is left in the device's ring buffer, and if we
want to send more than that , check first , updating our notion of
what is left . If our write will result in no room left , ask the
device to give us an interrupt when the room available rises above
a threshold , and hold off all writers ( eventually , those using
select ( ) or poll ( ) too ) until we receive that unthrottle interrupt .
Block if we can ' t write anything at all , otherwise write as much as
we can . */
if ( count = = 0 ) {
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " write request of 0 bytes \n " ) ;
2008-07-22 14:13:42 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
/* we might block because of:
the TX urb is in - flight ( wait until it completes )
the device is full ( wait until it says there is room )
*/
2006-09-25 14:51:41 +04:00
spin_lock_bh ( & port - > lock ) ;
2011-11-06 22:06:24 +04:00
if ( ! test_bit ( 0 , & port - > write_urbs_free ) | | priv - > tx_throttled ) {
2006-09-25 14:51:41 +04:00
spin_unlock_bh ( & port - > lock ) ;
2005-04-23 23:49:16 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2011-11-06 22:06:24 +04:00
clear_bit ( 0 , & port - > write_urbs_free ) ;
2006-09-25 14:51:41 +04:00
spin_unlock_bh ( & port - > lock ) ;
2005-04-17 02:20:36 +04:00
/* At this point the URB is in our control, nobody else can submit it
again ( the only sudden transition was the one from EINPROGRESS to
finished ) . Also , the tx process is not throttled . So we are
ready to write . */
count = ( count > port - > bulk_out_size ) ? port - > bulk_out_size : count ;
/* Check if we might overrun the Tx buffer. If so, ask the
device how much room it really has . This is done only on
scheduler time , since usb_control_msg ( ) sleeps . */
if ( count > priv - > tx_room & & ! in_interrupt ( ) ) {
2009-12-29 01:01:51 +03:00
u8 * room ;
room = kmalloc ( 1 , GFP_KERNEL ) ;
if ( ! room ) {
rc = - ENOMEM ;
goto exit ;
}
2008-07-22 14:13:42 +04:00
rc = usb_control_msg ( serial - > dev ,
2005-04-17 02:20:36 +04:00
usb_rcvctrlpipe ( serial - > dev , 0 ) ,
6 , /* write_room */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE
| USB_DIR_IN ,
0 , /* value: 0 means "remaining room" */
0 , /* index */
2009-12-29 01:01:51 +03:00
room ,
2005-04-17 02:20:36 +04:00
1 ,
2000 ) ;
2009-12-29 01:01:51 +03:00
if ( rc > 0 ) {
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " roomquery says %d \n " , * room ) ;
2009-12-29 01:01:51 +03:00
priv - > tx_room = * room ;
}
kfree ( room ) ;
2005-04-17 02:20:36 +04:00
if ( rc < 0 ) {
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " roomquery failed \n " ) ;
2005-04-17 02:20:36 +04:00
goto exit ;
}
if ( rc = = 0 ) {
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " roomquery returned 0 bytes \n " ) ;
2005-04-17 02:20:36 +04:00
rc = - EIO ; /* device didn't return any data */
goto exit ;
}
}
if ( count > priv - > tx_room ) {
/* we're about to completely fill the Tx buffer, so
we ' ll be throttled afterwards . */
count = priv - > tx_room ;
request_unthrottle = 1 ;
}
if ( count ) {
/* now transfer data */
2008-07-22 14:13:42 +04:00
memcpy ( port - > write_urb - > transfer_buffer , buf , count ) ;
2005-04-17 02:20:36 +04:00
/* send the data out the bulk port */
port - > write_urb - > transfer_buffer_length = count ;
2005-04-23 23:49:16 +04:00
2005-04-17 02:20:36 +04:00
priv - > tx_room - = count ;
rc = usb_submit_urb ( port - > write_urb , GFP_ATOMIC ) ;
if ( rc ) {
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " usb_submit_urb(write bulk) failed \n " ) ;
2005-04-17 02:20:36 +04:00
goto exit ;
}
2008-07-22 14:13:42 +04:00
} else {
2005-04-17 02:20:36 +04:00
/* There wasn't any room left, so we are throttled until
the buffer empties a bit */
request_unthrottle = 1 ;
}
if ( request_unthrottle ) {
priv - > tx_throttled = 1 ; /* block writers */
schedule_work ( & priv - > unthrottle_work ) ;
}
rc = count ;
exit :
2005-04-23 23:49:16 +04:00
if ( rc < 0 )
2011-11-06 22:06:24 +04:00
set_bit ( 0 , & port - > write_urbs_free ) ;
2005-04-17 02:20:36 +04:00
return rc ;
}
2008-07-22 14:13:42 +04:00
static void keyspan_pda_write_bulk_callback ( struct urb * urb )
2005-04-17 02:20:36 +04:00
{
2008-02-24 13:41:47 +03:00
struct usb_serial_port * port = urb - > context ;
2005-04-17 02:20:36 +04:00
struct keyspan_pda_private * priv ;
2011-11-06 22:06:24 +04:00
set_bit ( 0 , & port - > write_urbs_free ) ;
2005-04-17 02:20:36 +04:00
priv = usb_get_serial_port_data ( port ) ;
/* queue up a wakeup at scheduler time */
schedule_work ( & priv - > wakeup_work ) ;
}
2008-07-22 14:09:07 +04:00
static int keyspan_pda_write_room ( struct tty_struct * tty )
2005-04-17 02:20:36 +04:00
{
2008-07-22 14:09:07 +04:00
struct usb_serial_port * port = tty - > driver_data ;
2005-04-17 02:20:36 +04:00
struct keyspan_pda_private * priv ;
priv = usb_get_serial_port_data ( port ) ;
/* used by n_tty.c for processing of tabs and such. Giving it our
conservative guess is probably good enough , but needs testing by
running a console through the device . */
2008-07-22 14:13:42 +04:00
return priv - > tx_room ;
2005-04-17 02:20:36 +04:00
}
2008-07-22 14:09:07 +04:00
static int keyspan_pda_chars_in_buffer ( struct tty_struct * tty )
2005-04-17 02:20:36 +04:00
{
2008-07-22 14:09:07 +04:00
struct usb_serial_port * port = tty - > driver_data ;
2005-04-17 02:20:36 +04:00
struct keyspan_pda_private * priv ;
2008-04-08 20:16:06 +04:00
unsigned long flags ;
int ret = 0 ;
2005-04-23 23:49:16 +04:00
2005-04-17 02:20:36 +04:00
priv = usb_get_serial_port_data ( port ) ;
2005-04-23 23:49:16 +04:00
2005-04-17 02:20:36 +04:00
/* when throttled, return at least WAKEUP_CHARS to tell select() (via
n_tty . c : normal_poll ( ) ) that we ' re not writeable . */
2008-04-08 20:16:06 +04:00
spin_lock_irqsave ( & port - > lock , flags ) ;
2011-11-06 22:06:24 +04:00
if ( ! test_bit ( 0 , & port - > write_urbs_free ) | | priv - > tx_throttled )
2008-04-08 20:16:06 +04:00
ret = 256 ;
spin_unlock_irqrestore ( & port - > lock , flags ) ;
return ret ;
2005-04-17 02:20:36 +04:00
}
2009-06-11 15:26:29 +04:00
static void keyspan_pda_dtr_rts ( struct usb_serial_port * port , int on )
{
struct usb_serial * serial = port - > serial ;
2013-03-21 15:36:33 +04:00
if ( on )
keyspan_pda_set_modem_info ( serial , ( 1 < < 7 ) | ( 1 < < 2 ) ) ;
else
keyspan_pda_set_modem_info ( serial , 0 ) ;
2009-06-11 15:26:29 +04:00
}
2008-07-22 14:09:07 +04:00
static int keyspan_pda_open ( struct tty_struct * tty ,
2009-09-20 00:13:26 +04:00
struct usb_serial_port * port )
2005-04-17 02:20:36 +04:00
{
struct usb_serial * serial = port - > serial ;
2009-12-29 01:01:51 +03:00
u8 * room ;
2005-04-17 02:20:36 +04:00
int rc = 0 ;
struct keyspan_pda_private * priv ;
/* find out how much room is in the Tx ring */
2009-12-29 01:01:51 +03:00
room = kmalloc ( 1 , GFP_KERNEL ) ;
if ( ! room )
return - ENOMEM ;
2005-04-17 02:20:36 +04:00
rc = usb_control_msg ( serial - > dev , usb_rcvctrlpipe ( serial - > dev , 0 ) ,
6 , /* write_room */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE
| USB_DIR_IN ,
0 , /* value */
0 , /* index */
2009-12-29 01:01:51 +03:00
room ,
2005-04-17 02:20:36 +04:00
1 ,
2000 ) ;
if ( rc < 0 ) {
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " %s - roomquery failed \n " , __func__ ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
if ( rc = = 0 ) {
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " %s - roomquery returned 0 bytes \n " , __func__ ) ;
2005-04-17 02:20:36 +04:00
rc = - EIO ;
goto error ;
}
priv = usb_get_serial_port_data ( port ) ;
2009-12-29 01:01:51 +03:00
priv - > tx_room = * room ;
priv - > tx_throttled = * room ? 0 : 1 ;
2005-04-17 02:20:36 +04:00
/*Start reading from the device*/
rc = usb_submit_urb ( port - > interrupt_in_urb , GFP_KERNEL ) ;
if ( rc ) {
2012-09-14 23:06:52 +04:00
dev_dbg ( & port - > dev , " %s - usb_submit_urb(read int) failed \n " , __func__ ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
error :
2009-12-29 01:01:51 +03:00
kfree ( room ) ;
2005-04-17 02:20:36 +04:00
return rc ;
}
2009-06-11 15:26:29 +04:00
static void keyspan_pda_close ( struct usb_serial_port * port )
2005-04-17 02:20:36 +04:00
{
2013-03-21 15:36:34 +04:00
usb_kill_urb ( port - > write_urb ) ;
usb_kill_urb ( port - > interrupt_in_urb ) ;
2005-04-17 02:20:36 +04:00
}
/* download the firmware to a "fake" device (pre-renumeration) */
2008-07-22 14:13:42 +04:00
static int keyspan_pda_fake_startup ( struct usb_serial * serial )
2005-04-17 02:20:36 +04:00
{
int response ;
2008-05-30 16:15:13 +04:00
const char * fw_name ;
2005-04-17 02:20:36 +04:00
/* download the firmware here ... */
2012-09-18 11:00:41 +04:00
response = ezusb_fx1_set_reset ( serial - > dev , 1 ) ;
2005-04-17 02:20:36 +04:00
2008-05-30 16:15:13 +04:00
if ( 0 ) { ; }
2005-04-17 02:20:36 +04:00
# ifdef KEYSPAN
2008-05-30 16:15:13 +04:00
else if ( le16_to_cpu ( serial - > dev - > descriptor . idVendor ) = = KEYSPAN_VENDOR_ID )
fw_name = " keyspan_pda/keyspan_pda.fw " ;
2005-04-17 02:20:36 +04:00
# endif
# ifdef XIRCOM
2008-05-30 16:15:13 +04:00
else if ( ( le16_to_cpu ( serial - > dev - > descriptor . idVendor ) = = XIRCOM_VENDOR_ID ) | |
2014-10-04 15:19:59 +04:00
( le16_to_cpu ( serial - > dev - > descriptor . idVendor ) = = ENTREGA_VENDOR_ID ) )
2008-05-30 16:15:13 +04:00
fw_name = " keyspan_pda/xircom_pgs.fw " ;
2005-04-17 02:20:36 +04:00
# endif
2008-05-30 16:15:13 +04:00
else {
2008-08-21 03:56:34 +04:00
dev_err ( & serial - > dev - > dev , " %s: unknown vendor, aborting. \n " ,
__func__ ) ;
2005-04-17 02:20:36 +04:00
return - ENODEV ;
}
2012-09-18 11:02:01 +04:00
if ( ezusb_fx1_ihex_firmware_download ( serial - > dev , fw_name ) < 0 ) {
2008-08-21 03:56:34 +04:00
dev_err ( & serial - > dev - > dev , " failed to load firmware \" %s \" \n " ,
fw_name ) ;
2008-05-30 16:15:13 +04:00
return - ENOENT ;
}
2012-09-18 11:02:01 +04:00
/* after downloading firmware Renumeration will occur in a
moment and the new device will bind to the real driver */
2005-04-17 02:20:36 +04:00
/* we want this device to fail to have a driver assigned to it. */
2008-07-22 14:13:42 +04:00
return 1 ;
2005-04-17 02:20:36 +04:00
}
2010-01-14 02:34:18 +03:00
# ifdef KEYSPAN
MODULE_FIRMWARE ( " keyspan_pda/keyspan_pda.fw " ) ;
# endif
# ifdef XIRCOM
MODULE_FIRMWARE ( " keyspan_pda/xircom_pgs.fw " ) ;
# endif
2017-01-03 18:39:48 +03:00
static int keyspan_pda_attach ( struct usb_serial * serial )
{
unsigned char num_ports = serial - > num_ports ;
if ( serial - > num_bulk_out < num_ports | |
serial - > num_interrupt_in < num_ports ) {
dev_err ( & serial - > interface - > dev , " missing endpoints \n " ) ;
return - ENODEV ;
}
return 0 ;
}
2012-10-17 15:35:00 +04:00
static int keyspan_pda_port_probe ( struct usb_serial_port * port )
2005-04-17 02:20:36 +04:00
{
struct keyspan_pda_private * priv ;
priv = kmalloc ( sizeof ( struct keyspan_pda_private ) , GFP_KERNEL ) ;
if ( ! priv )
2012-10-17 15:35:00 +04:00
return - ENOMEM ;
2006-11-22 17:57:56 +03:00
INIT_WORK ( & priv - > wakeup_work , keyspan_pda_wakeup_write ) ;
INIT_WORK ( & priv - > unthrottle_work , keyspan_pda_request_unthrottle ) ;
2012-10-17 15:35:00 +04:00
priv - > serial = port - > serial ;
priv - > port = port ;
usb_set_serial_port_data ( port , priv ) ;
2008-07-22 14:13:42 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2012-10-17 15:35:00 +04:00
static int keyspan_pda_port_remove ( struct usb_serial_port * port )
2005-04-17 02:20:36 +04:00
{
2012-10-17 15:35:00 +04:00
struct keyspan_pda_private * priv ;
priv = usb_get_serial_port_data ( port ) ;
kfree ( priv ) ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
# ifdef KEYSPAN
2005-06-21 08:15:16 +04:00
static struct usb_serial_driver keyspan_pda_fake_device = {
2005-06-21 08:15:16 +04:00
. driver = {
. owner = THIS_MODULE ,
2005-06-21 08:15:16 +04:00
. name = " keyspan_pda_pre " ,
2005-06-21 08:15:16 +04:00
} ,
2005-06-21 08:15:16 +04:00
. description = " Keyspan PDA - (prerenumeration) " ,
2005-04-17 02:20:36 +04:00
. id_table = id_table_fake ,
. num_ports = 1 ,
. attach = keyspan_pda_fake_startup ,
} ;
# endif
# ifdef XIRCOM
2005-06-21 08:15:16 +04:00
static struct usb_serial_driver xircom_pgs_fake_device = {
2005-06-21 08:15:16 +04:00
. driver = {
. owner = THIS_MODULE ,
2005-06-21 08:15:16 +04:00
. name = " xircom_no_firm " ,
2005-06-21 08:15:16 +04:00
} ,
2014-10-04 15:19:59 +04:00
. description = " Xircom / Entrega PGS - (prerenumeration) " ,
2005-04-17 02:20:36 +04:00
. id_table = id_table_fake_xircom ,
. num_ports = 1 ,
. attach = keyspan_pda_fake_startup ,
} ;
# endif
2005-06-21 08:15:16 +04:00
static struct usb_serial_driver keyspan_pda_device = {
2005-06-21 08:15:16 +04:00
. driver = {
. owner = THIS_MODULE ,
2005-06-21 08:15:16 +04:00
. name = " keyspan_pda " ,
2005-06-21 08:15:16 +04:00
} ,
2005-06-21 08:15:16 +04:00
. description = " Keyspan PDA " ,
2005-04-17 02:20:36 +04:00
. id_table = id_table_std ,
. num_ports = 1 ,
2009-06-11 15:26:29 +04:00
. dtr_rts = keyspan_pda_dtr_rts ,
2005-04-17 02:20:36 +04:00
. open = keyspan_pda_open ,
. close = keyspan_pda_close ,
. write = keyspan_pda_write ,
. write_room = keyspan_pda_write_room ,
. write_bulk_callback = keyspan_pda_write_bulk_callback ,
. read_int_callback = keyspan_pda_rx_interrupt ,
. chars_in_buffer = keyspan_pda_chars_in_buffer ,
. throttle = keyspan_pda_rx_throttle ,
. unthrottle = keyspan_pda_rx_unthrottle ,
. set_termios = keyspan_pda_set_termios ,
. break_ctl = keyspan_pda_break_ctl ,
. tiocmget = keyspan_pda_tiocmget ,
. tiocmset = keyspan_pda_tiocmset ,
2017-01-03 18:39:48 +03:00
. attach = keyspan_pda_attach ,
2012-10-17 15:35:00 +04:00
. port_probe = keyspan_pda_port_probe ,
. port_remove = keyspan_pda_port_remove ,
2005-04-17 02:20:36 +04:00
} ;
2012-02-25 00:49:34 +04:00
static struct usb_serial_driver * const serial_drivers [ ] = {
& keyspan_pda_device ,
2005-04-17 02:20:36 +04:00
# ifdef KEYSPAN
2012-02-25 00:49:34 +04:00
& keyspan_pda_fake_device ,
2005-04-17 02:20:36 +04:00
# endif
# ifdef XIRCOM
2012-02-25 00:49:34 +04:00
& xircom_pgs_fake_device ,
2005-04-17 02:20:36 +04:00
# endif
2012-02-25 00:49:34 +04:00
NULL
} ;
2005-04-17 02:20:36 +04:00
2012-05-09 02:46:14 +04:00
module_usb_serial_driver ( serial_drivers , id_table_combined ) ;
2005-04-17 02:20:36 +04:00
2008-07-22 14:13:42 +04:00
MODULE_AUTHOR ( DRIVER_AUTHOR ) ;
MODULE_DESCRIPTION ( DRIVER_DESC ) ;
2005-04-17 02:20:36 +04:00
MODULE_LICENSE ( " GPL " ) ;