* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (79 commits)
arm: bus_id -> dev_name() and dev_set_name() conversions
sparc64: fix up bus_id changes in sparc core code
3c59x: handle pci_name() being const
MTD: handle pci_name() being const
HP iLO driver
sysdev: Convert the x86 mce tolerant sysdev attribute to generic attribute
sysdev: Add utility functions for simple int/ulong variable sysdev attributes
sysdev: Pass the attribute to the low level sysdev show/store function
driver core: Suppress sysfs warnings for device_rename().
kobject: Transmit return value of call_usermodehelper() to caller
sysfs-rules.txt: reword API stability statement
debugfs: Implement debugfs_remove_recursive()
HOWTO: change email addresses of James in HOWTO
always enable FW_LOADER unless EMBEDDED=y
uio-howto.tmpl: use unique output names
uio-howto.tmpl: use standard copyright/legal markings
sysfs: don't call notify_change
sysdev: fix debugging statements in registration code.
kobject: should use kobject_put() in kset-example
kobject: reorder kobject to save space on 64 bit builds
...
Hardware handshaking issues.
============================
-The driver can be compiled in two different ways. The default
-("Specialix DTR/RTS pin is RTS" is off) the pin behaves as DTR when
+The driver can be told to operate in two different ways. The default
+behaviour is specialix.sx_rtscts = 0 where the pin behaves as DTR when
hardware handshaking is off. It behaves as the RTS hardware
handshaking signal when hardware handshaking is selected.
software handshaking. So switching on the fly is not really an
option.
-I actually prefer to use the "Specialix DTR/RTS pin is RTS" option.
+I actually prefer to use the "specialix.sx_rtscts=1" option.
This makes the DTR/RTS pin always an RTS pin, and ioctls to
change DTR are always ignored. I have a cable that is configured
for this.
You have to WRITE to the address register to even
read-probe a CD186x register. Disable autodetection?
-- Specialix: any suggestions?
- - Arbitrary baud rates are not implemented yet.
- If you need this, bug me about it.
S: Maintained
TPM DEVICE DRIVER
-P: Debora Velarde
-P: Rajiv Andrade
-M: tpmdd-devel@lists.sourceforge.net
+P: Debora Velarde
+M: debora@linux.vnet.ibm.com
+P: Rajiv Andrade
+M: srajiv@linux.vnet.ibm.com
W: http://tpmdd.sourceforge.net
P: Marcel Selhorst
M: tpm@selhorst.net
@find . $(RCS_FIND_IGNORE) \
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
- -o -name '*.symtypes' -o -name 'modules.order' \) \
+ -o -name '*.symtypes' -o -name 'modules.order' \
+ -o -name 'Module.markers' \) \
-type f -print | xargs rm -f
# mrproper - Delete all generated files, including .config
and compile this driver as kernel loadable module which will be
called specialix.
-config SPECIALIX_RTSCTS
- bool "Specialix DTR/RTS pin is RTS"
- depends on SPECIALIX
- help
- The Specialix IO8+ card can only support either RTS or DTR. If you
- say N here, the driver will use the pin as "DTR" when the tty is in
- software handshake mode. If you say Y here or hardware handshake is
- on, it will always be RTS. Read the file
- <file:Documentation/specialix.txt> for more information.
-
config SX
tristate "Specialix SX (and SI) card support"
depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
#
FONTMAPFILE = cp437.uni
-obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o
+obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o
obj-$(CONFIG_LEGACY_PTYS) += pty.o
obj-$(CONFIG_UNIX98_PTYS) += pty.o
/*
* rs_break() --- routine which turns the break handling on or off
*/
-static void rs_break(struct tty_struct *tty, int break_state)
+static int rs_break(struct tty_struct *tty, int break_state)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
unsigned long flags;
custom.adkcon = AC_UARTBRK;
mb();
local_irq_restore(flags);
+ return 0;
}
/*
* cy_break() --- routine which turns the break handling on or off
*/
-static void cy_break(struct tty_struct *tty, int break_state)
+static int cy_break(struct tty_struct *tty, int break_state)
{
struct cyclades_port *info = tty->driver_data;
struct cyclades_card *card;
unsigned long flags;
+ int retval = 0;
if (serial_paranoia_check(info, tty->name, "cy_break"))
- return;
+ return -EINVAL;
card = info->card;
}
}
} else {
- int retval;
-
if (break_state == -1) {
retval = cyz_issue_cmd(card,
info->line - card->first_line,
}
}
spin_unlock_irqrestore(&card->card_lock, flags);
+ return retval;
} /* cy_break */
static int get_mon_info(struct cyclades_port *info,
static void pc_start(struct tty_struct *);
static void pc_throttle(struct tty_struct *tty);
static void pc_unthrottle(struct tty_struct *tty);
-static void digi_send_break(struct channel *ch, int msec);
+static int pc_send_break(struct tty_struct *tty, int msec);
static void setup_empty_event(struct tty_struct *tty, struct channel *ch);
-static void epca_setup(char *, int *);
static int pc_write(struct tty_struct *, const unsigned char *, int);
static int pc_init(void);
.throttle = pc_throttle,
.unthrottle = pc_unthrottle,
.hangup = pc_hangup,
+ .break_ctl = pc_send_break
};
static int info_open(struct tty_struct *tty, struct file *filp)
pc_driver->init_termios.c_lflag = 0;
pc_driver->init_termios.c_ispeed = 9600;
pc_driver->init_termios.c_ospeed = 9600;
- pc_driver->flags = TTY_DRIVER_REAL_RAW;
+ pc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK;
tty_set_operations(pc_driver, &pc_ops);
pc_info->owner = THIS_MODULE;
unsigned int cmd, unsigned long arg)
{
digiflow_t dflow;
- int retval;
unsigned long flags;
unsigned int mflag, mstat;
unsigned char startc, stopc;
bc = ch->brdchan;
else
return -EINVAL;
- /*
- * For POSIX compliance we need to add more ioctls. See tty_ioctl.c in
- * /usr/src/linux/drivers/char for a good example. In particular think
- * about adding TCSETAF, TCSETAW, TCSETA, TCSETSF, TCSETSW, TCSETS.
- */
switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- /* Setup an event to indicate when the transmit
- buffer empties */
- spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty, ch);
- spin_unlock_irqrestore(&epca_lock, flags);
- tty_wait_until_sent(tty, 0);
- if (!arg)
- digi_send_break(ch, HZ / 4); /* 1/4 second */
- return 0;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- /* Setup an event to indicate when the transmit buffer
- empties */
- spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty, ch);
- spin_unlock_irqrestore(&epca_lock, flags);
- tty_wait_until_sent(tty, 0);
- digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4);
- return 0;
case TIOCMODG:
mflag = pc_tiocmget(tty, file);
if (put_user(mflag, (unsigned long __user *)argp))
}
}
-static void digi_send_break(struct channel *ch, int msec)
+static int pc_send_break(struct tty_struct *tty, int msec)
{
+ struct channel *ch = (struct channel *) tty->driver_data;
unsigned long flags;
+ if (msec == -1)
+ return -EOPNOTSUPP;
+
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
/*
fepcmd(ch, SENDBREAK, msec, 0, 10, 0);
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
+ return 0;
}
/* Caller MUST hold the lock */
memoff(ch);
}
-static void epca_setup(char *str, int *ints)
+#ifndef MODULE
+static void __init epca_setup(char *str, int *ints)
{
struct board_info board;
int index, loop, last;
num_cards++;
}
+static int __init epca_real_setup(char *str)
+{
+ int ints[11];
+
+ epca_setup(get_options(str, 11, ints), ints);
+ return 1;
+}
+
+__setup("digiepca", epca_real_setup);
+#endif
+
enum epic_board_types {
brd_xr = 0,
brd_xem,
/*
* rs_break() --- routine which turns the break handling on or off
*/
-static void esp_break(struct tty_struct *tty, int break_state)
+static int esp_break(struct tty_struct *tty, int break_state)
{
struct esp_struct *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "esp_break"))
- return;
+ return -EINVAL;
if (break_state == -1) {
spin_lock_irqsave(&info->lock, flags);
serial_out(info, UART_ESI_CMD2, 0x00);
spin_unlock_irqrestore(&info->lock, flags);
}
+ return 0;
}
static int rs_ioctl(struct tty_struct *tty, struct file *file,
}
/* ioctl et all */
-static inline void isicom_send_break(struct isi_port *port,
- unsigned long length)
+static int isicom_send_break(struct tty_struct *tty, int length)
{
+ struct isi_port *port = tty->driver_data;
struct isi_board *card = port->card;
unsigned long base = card->base;
+ if (length == -1)
+ return -EOPNOTSUPP;
+
if (!lock_card(card))
- return;
+ return -EINVAL;
outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
outw((length & 0xff) << 8 | 0x00, base);
InterruptTheCard(base);
unlock_card(card);
+ return 0;
}
static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
{
struct isi_port *port = tty->driver_data;
void __user *argp = (void __user *)arg;
- int retval;
if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
return -ENODEV;
switch (cmd) {
- case TCSBRK:
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- if (!arg)
- isicom_send_break(port, HZ/4);
- return 0;
-
- case TCSBRKP:
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
- return 0;
case TIOCGSERIAL:
return isicom_get_serial_info(port, argp);
.flush_buffer = isicom_flush_buffer,
.tiocmget = isicom_tiocmget,
.tiocmset = isicom_tiocmset,
+ .break_ctl = isicom_send_break,
};
static int __devinit reset_card(struct pci_dev *pdev,
isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
CLOCAL;
isicom_normal->flags = TTY_DRIVER_REAL_RAW |
- TTY_DRIVER_DYNAMIC_DEV;
+ TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
tty_set_operations(isicom_normal, &isicom_ops);
retval = tty_register_driver(isicom_normal);
static void stli_stop(struct tty_struct *tty);
static void stli_start(struct tty_struct *tty);
static void stli_flushbuffer(struct tty_struct *tty);
-static void stli_breakctl(struct tty_struct *tty, int state);
+static int stli_breakctl(struct tty_struct *tty, int state);
static void stli_waituntilsent(struct tty_struct *tty, int timeout);
static void stli_sendxchar(struct tty_struct *tty, char ch);
static void stli_hangup(struct tty_struct *tty);
clear_bit(ST_TXBUSY, &portp->state);
clear_bit(ST_RXSTOP, &portp->state);
set_bit(TTY_IO_ERROR, &tty->flags);
- if (tty->ldisc.ops->flush_buffer)
- (tty->ldisc.ops->flush_buffer)(tty);
+ tty_ldisc_flush(tty);
set_bit(ST_DOFLUSHRX, &portp->state);
stli_flushbuffer(tty);
/*****************************************************************************/
-static void stli_breakctl(struct tty_struct *tty, int state)
+static int stli_breakctl(struct tty_struct *tty, int state)
{
struct stlibrd *brdp;
struct stliport *portp;
portp = tty->driver_data;
if (portp == NULL)
- return;
+ return -EINVAL;
if (portp->brdnr >= stli_nrbrds)
- return;
+ return -EINVAL;
brdp = stli_brds[portp->brdnr];
if (brdp == NULL)
- return;
+ return -EINVAL;
arg = (state == -1) ? BREAKON : BREAKOFF;
stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);
+ return 0;
}
/*****************************************************************************/
return ret;
}
-static void moxa_break_ctl(struct tty_struct *tty, int state)
+static int moxa_break_ctl(struct tty_struct *tty, int state)
{
struct moxa_port *port = tty->driver_data;
moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak,
Magic_code);
+ return 0;
}
static const struct tty_operations moxa_ops = {
#include "mxser.h"
-#define MXSER_VERSION "2.0.3" /* 1.11 */
+#define MXSER_VERSION "2.0.4" /* 1.12 */
#define MXSERMAJOR 174
#define MXSERCUMAJOR 175
#define UART_MCR_AFE 0x20
#define UART_LSR_SPECIAL 0x1E
+#define PCI_DEVICE_ID_POS104UL 0x1044
#define PCI_DEVICE_ID_CB108 0x1080
+#define PCI_DEVICE_ID_CP102UF 0x1023
#define PCI_DEVICE_ID_CB114 0x1142
#define PCI_DEVICE_ID_CP114UL 0x1143
#define PCI_DEVICE_ID_CB134I 0x1341
#define PCI_DEVICE_ID_CP138U 0x1380
-#define PCI_DEVICE_ID_POS104UL 0x1044
#define C168_ASIC_ID 1
{ "CB-134I series", 4, },
{ "CP-138U series", 8, },
{ "POS-104UL series", 4, },
- { "CP-114UL series", 4, }
+ { "CP-114UL series", 4, },
+/*30*/ { "CP-102UF series", 2, }
};
/* driver_data correspond to the lines in the structure above
{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 },
{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 },
{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 29 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 30 },
{ }
};
MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
info->port.closing_wait = new_serial.closing_wait * HZ / 100;
info->port.tty->low_latency =
(info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
- info->port.tty->low_latency = 0;
if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
(new_serial.baud_base != info->baud_base ||
new_serial.custom_divisor !=
return put_user(result, value);
}
-/*
- * This routine sends a break character out the serial port.
- */
-static void mxser_send_break(struct mxser_port *info, int duration)
-{
- unsigned long flags;
-
- if (!info->ioaddr)
- return;
- set_current_state(TASK_INTERRUPTIBLE);
- spin_lock_irqsave(&info->slock, flags);
- outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC,
- info->ioaddr + UART_LCR);
- spin_unlock_irqrestore(&info->slock, flags);
- schedule_timeout(duration);
- spin_lock_irqsave(&info->slock, flags);
- outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC,
- info->ioaddr + UART_LCR);
- spin_unlock_irqrestore(&info->slock, flags);
-}
-
static int mxser_tiocmget(struct tty_struct *tty, struct file *file)
{
struct mxser_port *info = tty->driver_data;
return -EIO;
switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- if (!arg)
- mxser_send_break(info, HZ / 4); /* 1/4 second */
- return 0;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
- return 0;
case TIOCGSERIAL:
lock_kernel();
retval = mxser_get_serial_info(info, argp);
/*
* mxser_rs_break() --- routine which turns the break handling on or off
*/
-static void mxser_rs_break(struct tty_struct *tty, int break_state)
+static int mxser_rs_break(struct tty_struct *tty, int break_state)
{
struct mxser_port *info = tty->driver_data;
unsigned long flags;
outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC,
info->ioaddr + UART_LCR);
spin_unlock_irqrestore(&info->slock, flags);
+ return 0;
}
static void mxser_receive_chars(struct mxser_port *port, int *status)
/* Allocate transmit buffer */
/* sleep until transmit buffer available */
while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
+ if (file->f_flags & O_NONBLOCK) {
+ error = -EAGAIN;
+ break;
+ }
schedule();
n_hdlc = tty2n_hdlc (tty);
* Arguments: tty pointer to tty instance data
* break_state -1=set break condition, 0=clear
*/
-static void mgslpc_break(struct tty_struct *tty, int break_state)
+static int mgslpc_break(struct tty_struct *tty, int break_state)
{
MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
unsigned long flags;
__FILE__,__LINE__, info->device_name, break_state);
if (mgslpc_paranoia_check(info, tty->name, "mgslpc_break"))
- return;
+ return -EINVAL;
spin_lock_irqsave(&info->lock,flags);
if (break_state == -1)
else
clear_reg_bits(info, CHA+DAFO, BIT6);
spin_unlock_irqrestore(&info->lock,flags);
+ return 0;
}
/* Service an IOCTL request
return 0;
}
-static void rc_send_break(struct riscom_port *port, unsigned long length)
+static int rc_send_break(struct tty_struct *tty, int length)
{
+ struct riscom_port *port = (struct riscom_port *)tty->driver_data;
struct riscom_board *bp = port_Board(port);
unsigned long flags;
+ if (length == 0 || length == -1)
+ return -EOPNOTSUPP;
+
spin_lock_irqsave(&riscom_lock, flags);
port->break_length = RISCOM_TPS / HZ * length;
rc_wait_CCR(bp);
spin_unlock_irqrestore(&riscom_lock, flags);
+ return 0;
}
static int rc_set_serial_info(struct riscom_port *port,
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
void __user *argp = (void __user *)arg;
- int retval = 0;
+ int retval;
if (rc_paranoia_check(port, tty->name, "rc_ioctl"))
return -ENODEV;
switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- if (!arg)
- rc_send_break(port, HZ/4); /* 1/4 second */
- break;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- rc_send_break(port, arg ? arg*(HZ/10) : HZ/4);
- break;
case TIOCGSERIAL:
lock_kernel();
retval = rc_get_serial_info(port, argp);
.hangup = rc_hangup,
.tiocmget = rc_tiocmget,
.tiocmset = rc_tiocmset,
+ .break_ctl = rc_send_break,
};
static int __init rc_init_drivers(void)
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
riscom_driver->init_termios.c_ispeed = 9600;
riscom_driver->init_termios.c_ospeed = 9600;
- riscom_driver->flags = TTY_DRIVER_REAL_RAW;
+ riscom_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK;
tty_set_operations(riscom_driver, &riscom_ops);
error = tty_register_driver(riscom_driver);
if (error != 0) {
}
}
-static void rp_break(struct tty_struct *tty, int break_state)
+static int rp_break(struct tty_struct *tty, int break_state)
{
struct r_port *info = (struct r_port *) tty->driver_data;
unsigned long flags;
if (rocket_paranoia_check(info, "rp_break"))
- return;
+ return -EINVAL;
spin_lock_irqsave(&info->slock, flags);
if (break_state == -1)
else
sClrBreak(&info->channel);
spin_unlock_irqrestore(&info->slock, flags);
+ return 0;
}
/*
#include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/init.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "specialix_io8.h"
#include "cd1865.h"
static int sx_debug;
static int sx_rxfifo = SPECIALIX_RXFIFO;
+static int sx_rtscts;
#ifdef DEBUG
-#define dprintk(f, str...) if (sx_debug & f) printk (str)
+#define dprintk(f, str...) if (sx_debug & f) printk(str)
#else
#define dprintk(f, str...) /* nothing */
#endif
#define SX_DEBUG_FIFO 0x0800
-#define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__func__)
-#define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __func__)
-
-#define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
+#define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__)
+#define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__)
/* Configurable options: */
/* Am I paranoid or not ? ;-) */
#define SPECIALIX_PARANOIA_CHECK
-/* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
- When the IRQ routine leaves the chip in a state that is keeps on
- requiring attention, the timer doesn't help either. */
-#undef SPECIALIX_TIMER
-
-#ifdef SPECIALIX_TIMER
-static int sx_poll = HZ;
-#endif
-
-
-
/*
* The following defines are mostly for testing purposes. But if you need
* some nice reporting in your syslog, you can define them also.
-#ifdef CONFIG_SPECIALIX_RTSCTS
-#define SX_CRTSCTS(bla) 1
-#else
-#define SX_CRTSCTS(tty) C_CRTSCTS(tty)
-#endif
-
-
-/* Used to be outb (0xff, 0x80); */
-#define short_pause() udelay (1)
-
#define SPECIALIX_LEGAL_FLAGS \
(ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
-#ifdef SPECIALIX_TIMER
-static struct timer_list missed_irq_timer;
-static irqreturn_t sx_interrupt(int irq, void * dev_id);
-#endif
-
-
-
-static inline int sx_paranoia_check(struct specialix_port const * port,
+static int sx_paranoia_check(struct specialix_port const *port,
char *name, const char *routine)
{
#ifdef SPECIALIX_PARANOIA_CHECK
- static const char *badmagic =
- KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
- static const char *badinfo =
- KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
+ static const char *badmagic = KERN_ERR
+ "sx: Warning: bad specialix port magic number for device %s in %s\n";
+ static const char *badinfo = KERN_ERR
+ "sx: Warning: null specialix port for device %s in %s\n";
if (!port) {
printk(badinfo, name, routine);
*/
/* Get board number from pointer */
-static inline int board_No (struct specialix_board * bp)
+static inline int board_No(struct specialix_board *bp)
{
return bp - sx_board;
}
/* Get port number from pointer */
-static inline int port_No (struct specialix_port const * port)
+static inline int port_No(struct specialix_port const *port)
{
return SX_PORT(port - sx_port);
}
/* Get pointer to board from pointer to port */
-static inline struct specialix_board * port_Board(struct specialix_port const * port)
+static inline struct specialix_board *port_Board(
+ struct specialix_port const *port)
{
return &sx_board[SX_BOARD(port - sx_port)];
}
/* Input Byte from CL CD186x register */
-static inline unsigned char sx_in(struct specialix_board * bp, unsigned short reg)
+static inline unsigned char sx_in(struct specialix_board *bp,
+ unsigned short reg)
{
bp->reg = reg | 0x80;
- outb (reg | 0x80, bp->base + SX_ADDR_REG);
- return inb (bp->base + SX_DATA_REG);
+ outb(reg | 0x80, bp->base + SX_ADDR_REG);
+ return inb(bp->base + SX_DATA_REG);
}
/* Output Byte to CL CD186x register */
-static inline void sx_out(struct specialix_board * bp, unsigned short reg,
+static inline void sx_out(struct specialix_board *bp, unsigned short reg,
unsigned char val)
{
bp->reg = reg | 0x80;
- outb (reg | 0x80, bp->base + SX_ADDR_REG);
- outb (val, bp->base + SX_DATA_REG);
+ outb(reg | 0x80, bp->base + SX_ADDR_REG);
+ outb(val, bp->base + SX_DATA_REG);
}
/* Input Byte from CL CD186x register */
-static inline unsigned char sx_in_off(struct specialix_board * bp, unsigned short reg)
+static inline unsigned char sx_in_off(struct specialix_board *bp,
+ unsigned short reg)
{
bp->reg = reg;
- outb (reg, bp->base + SX_ADDR_REG);
- return inb (bp->base + SX_DATA_REG);
+ outb(reg, bp->base + SX_ADDR_REG);
+ return inb(bp->base + SX_DATA_REG);
}
/* Output Byte to CL CD186x register */
-static inline void sx_out_off(struct specialix_board * bp, unsigned short reg,
- unsigned char val)
+static inline void sx_out_off(struct specialix_board *bp,
+ unsigned short reg, unsigned char val)
{
bp->reg = reg;
- outb (reg, bp->base + SX_ADDR_REG);
- outb (val, bp->base + SX_DATA_REG);
+ outb(reg, bp->base + SX_ADDR_REG);
+ outb(val, bp->base + SX_DATA_REG);
}
/* Wait for Channel Command Register ready */
-static inline void sx_wait_CCR(struct specialix_board * bp)
+static void sx_wait_CCR(struct specialix_board *bp)
{
unsigned long delay, flags;
unsigned char ccr;
spin_unlock_irqrestore(&bp->lock, flags);
if (!ccr)
return;
- udelay (1);
+ udelay(1);
}
printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
/* Wait for Channel Command Register ready */
-static inline void sx_wait_CCR_off(struct specialix_board * bp)
+static void sx_wait_CCR_off(struct specialix_board *bp)
{
unsigned long delay;
unsigned char crr;
spin_unlock_irqrestore(&bp->lock, flags);
if (!crr)
return;
- udelay (1);
+ udelay(1);
}
printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
* specialix IO8+ IO range functions.
*/
-static inline int sx_request_io_range(struct specialix_board * bp)
+static int sx_request_io_range(struct specialix_board *bp)
{
return request_region(bp->base,
bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
}
-static inline void sx_release_io_range(struct specialix_board * bp)
+static void sx_release_io_range(struct specialix_board *bp)
{
- release_region(bp->base,
- bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
+ release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ?
+ SX_PCI_IO_SPACE : SX_IO_SPACE);
}
/* Set the IRQ using the RTS lines that run to the PAL on the board.... */
-static int sx_set_irq ( struct specialix_board *bp)
+static int sx_set_irq(struct specialix_board *bp)
{
int virq;
int i;
return 1;
switch (bp->irq) {
/* In the same order as in the docs... */
- case 15: virq = 0;break;
- case 12: virq = 1;break;
- case 11: virq = 2;break;
- case 9: virq = 3;break;
- default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq);
- return 0;
+ case 15:
+ virq = 0;
+ break;
+ case 12:
+ virq = 1;
+ break;
+ case 11:
+ virq = 2;
+ break;
+ case 9:
+ virq = 3;
+ break;
+ default:printk(KERN_ERR
+ "Speclialix: cannot set irq to %d.\n", bp->irq);
+ return 0;
}
spin_lock_irqsave(&bp->lock, flags);
- for (i=0;i<2;i++) {
+ for (i = 0; i < 2; i++) {
sx_out(bp, CD186x_CAR, i);
sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
}
/* Reset and setup CD186x chip */
-static int sx_init_CD186x(struct specialix_board * bp)
+static int sx_init_CD186x(struct specialix_board *bp)
{
unsigned long flags;
int scaler;
sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
/* Set RegAckEn */
- sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
+ sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN);
/* Setting up prescaler. We need 4 ticks per 1 ms */
scaler = SX_OSCFREQ/SPECIALIX_TPS;
sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
spin_unlock_irqrestore(&bp->lock, flags);
- if (!sx_set_irq (bp)) {
+ if (!sx_set_irq(bp)) {
/* Figure out how to pass this along... */
- printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq);
+ printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq);
rv = 0;
}
}
-static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
+static int read_cross_byte(struct specialix_board *bp, int reg, int bit)
{
int i;
int t;
unsigned long flags;
spin_lock_irqsave(&bp->lock, flags);
- for (i=0, t=0;i<8;i++) {
- sx_out_off (bp, CD186x_CAR, i);
- if (sx_in_off (bp, reg) & bit)
+ for (i = 0, t = 0; i < 8; i++) {
+ sx_out_off(bp, CD186x_CAR, i);
+ if (sx_in_off(bp, reg) & bit)
t |= 1 << i;
}
spin_unlock_irqrestore(&bp->lock, flags);
}
-#ifdef SPECIALIX_TIMER
-void missed_irq (unsigned long data)
-{
- unsigned char irq;
- unsigned long flags;
- struct specialix_board *bp = (struct specialix_board *)data;
-
- spin_lock_irqsave(&bp->lock, flags);
- irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) &
- (SRSR_RREQint |
- SRSR_TREQint |
- SRSR_MREQint);
- spin_unlock_irqrestore(&bp->lock, flags);
- if (irq) {
- printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
- sx_interrupt (-1, bp);
- }
- mod_timer(&missed_irq_timer, jiffies + sx_poll);
-}
-#endif
-
-
-
/* Main probing routine, also sets irq. */
static int sx_probe(struct specialix_board *bp)
{
unsigned char val1, val2;
-#if 0
- int irqs = 0;
- int retries;
-#endif
int rev;
int chip;
/* Are the I/O ports here ? */
sx_out_off(bp, CD186x_PPRL, 0x5a);
- short_pause ();
+ udelay(1);
val1 = sx_in_off(bp, CD186x_PPRL);
sx_out_off(bp, CD186x_PPRL, 0xa5);
- short_pause ();
+ udelay(1);
val2 = sx_in_off(bp, CD186x_PPRL);
- if ((val1 != 0x5a) || (val2 != 0xa5)) {
- printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
- board_No(bp), bp->base);
+ if (val1 != 0x5a || val2 != 0xa5) {
+ printk(KERN_INFO
+ "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
+ board_No(bp), bp->base);
sx_release_io_range(bp);
func_exit();
return 1;
/* Check the DSR lines that Specialix uses as board
identification */
- val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
- val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
- dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
- board_No(bp), val1, val2);
+ val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR);
+ val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS);
+ dprintk(SX_DEBUG_INIT,
+ "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
+ board_No(bp), val1, val2);
/* They managed to switch the bit order between the docs and
the IO8+ card. The new PCI card now conforms to old docs.
old card. */
val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
if (val1 != val2) {
- printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
+ printk(KERN_INFO
+ "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
board_No(bp), val2, bp->base, val1);
sx_release_io_range(bp);
func_exit();
}
-#if 0
- /* It's time to find IRQ for this board */
- for (retries = 0; retries < 5 && irqs <= 0; retries++) {
- irqs = probe_irq_on();
- sx_init_CD186x(bp); /* Reset CD186x chip */
- sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
- sx_wait_CCR(bp);
- sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
- sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
- msleep(50);
- irqs = probe_irq_off(irqs);
-
- dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
- dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
- dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
- dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
- dprintk (SX_DEBUG_INIT, "\n");
-
- /* Reset CD186x again */
- if (!sx_init_CD186x(bp)) {
- /* Hmmm. This is dead code anyway. */
- }
-
- dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
- val1, val2, val3);
-
- }
-
-#if 0
- if (irqs <= 0) {
- printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
- board_No(bp), bp->base);
- sx_release_io_range(bp);
- func_exit();
- return 1;
- }
-#endif
- printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
- if (irqs > 0)
- bp->irq = irqs;
-#endif
/* Reset CD186x again */
if (!sx_init_CD186x(bp)) {
sx_release_io_range(bp);
bp->flags |= SX_BOARD_PRESENT;
/* Chip revcode pkgtype
- GFRCR SRCR bit 7
+ GFRCR SRCR bit 7
CD180 rev B 0x81 0
CD180 rev C 0x82 0
CD1864 rev A 0x82 1
*/
switch (sx_in_off(bp, CD186x_GFRCR)) {
- case 0x82:chip = 1864;rev='A';break;
- case 0x83:chip = 1865;rev='A';break;
- case 0x84:chip = 1865;rev='B';break;
- case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
- default:chip=-1;rev='x';
+ case 0x82:
+ chip = 1864;
+ rev = 'A';
+ break;
+ case 0x83:
+ chip = 1865;
+ rev = 'A';
+ break;
+ case 0x84:
+ chip = 1865;
+ rev = 'B';
+ break;
+ case 0x85:
+ chip = 1865;
+ rev = 'C';
+ break; /* Does not exist at this time */
+ default:
+ chip = -1;
+ rev = 'x';
}
- dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
-
-#ifdef SPECIALIX_TIMER
- setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp);
- mod_timer(&missed_irq_timer, jiffies + sx_poll);
-#endif
+ dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR));
- printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
- board_No(bp),
- bp->base, bp->irq,
- chip, rev);
+ printk(KERN_INFO
+ "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
+ board_No(bp), bp->base, bp->irq, chip, rev);
func_exit();
return 0;
* Interrupt processing routines.
* */
-static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
- unsigned char const * what)
+static struct specialix_port *sx_get_port(struct specialix_board *bp,
+ unsigned char const *what)
{
unsigned char channel;
- struct specialix_port * port = NULL;
+ struct specialix_port *port = NULL;
channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
- dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
+ dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel);
if (channel < CD186x_NCH) {
port = &sx_port[board_No(bp) * SX_NPORT + channel];
- dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",board_No(bp) * SX_NPORT + channel, port, port->port.flags & ASYNC_INITIALIZED);
+ dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",
+ board_No(bp) * SX_NPORT + channel, port,
+ port->port.flags & ASYNC_INITIALIZED);
if (port->port.flags & ASYNC_INITIALIZED) {
- dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
+ dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
func_exit();
return port;
}
}
-static inline void sx_receive_exc(struct specialix_board * bp)
+static void sx_receive_exc(struct specialix_board *bp)
{
struct specialix_port *port;
struct tty_struct *tty;
port = sx_get_port(bp, "Receive");
if (!port) {
- dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
+ dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
func_exit();
return;
}
status = sx_in(bp, CD186x_RCSR);
- dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
+ dprintk(SX_DEBUG_RX, "status: 0x%x\n", status);
if (status & RCSR_OE) {
port->overrun++;
- dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
- board_No(bp), port_No(port), port->overrun);
+ dprintk(SX_DEBUG_FIFO,
+ "sx%d: port %d: Overrun. Total %ld overruns.\n",
+ board_No(bp), port_No(port), port->overrun);
}
status &= port->mark_mask;
/* This flip buffer check needs to be below the reading of the
status register to reset the chip's IRQ.... */
if (tty_buffer_request_room(tty, 1) == 0) {
- dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
- board_No(bp), port_No(port));
+ dprintk(SX_DEBUG_FIFO,
+ "sx%d: port %d: Working around flip buffer overflow.\n",
+ board_No(bp), port_No(port));
func_exit();
return;
}
return;
}
if (status & RCSR_TOUT) {
- printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
- board_No(bp), port_No(port));
+ printk(KERN_INFO
+ "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
+ board_No(bp), port_No(port));
func_exit();
return;
else
flag = TTY_NORMAL;
- if(tty_insert_flip_char(tty, ch, flag))
+ if (tty_insert_flip_char(tty, ch, flag))
tty_flip_buffer_push(tty);
func_exit();
}
-static inline void sx_receive(struct specialix_board * bp)
+static void sx_receive(struct specialix_board *bp)
{
struct specialix_port *port;
struct tty_struct *tty;
func_enter();
- if (!(port = sx_get_port(bp, "Receive"))) {
- dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
+ port = sx_get_port(bp, "Receive");
+ if (port == NULL) {
+ dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
func_exit();
return;
}
tty = port->port.tty;
count = sx_in(bp, CD186x_RDCR);
- dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
+ dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
port->hits[count > 8 ? 9 : count]++;
tty_buffer_request_room(tty, count);
}
-static inline void sx_transmit(struct specialix_board * bp)
+static void sx_transmit(struct specialix_board *bp)
{
struct specialix_port *port;
struct tty_struct *tty;
unsigned char count;
func_enter();
- if (!(port = sx_get_port(bp, "Transmit"))) {
+ port = sx_get_port(bp, "Transmit");
+ if (port == NULL) {
func_exit();
return;
}
- dprintk (SX_DEBUG_TX, "port: %p\n", port);
+ dprintk(SX_DEBUG_TX, "port: %p\n", port);
tty = port->port.tty;
if (port->IER & IER_TXEMPTY) {
sx_out(bp, CD186x_TDR, CD186x_C_ESC);
sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
sx_out(bp, CD186x_TDR, count);
- if (!(port->break_length -= count))
+ port->break_length -= count;
+ if (port->break_length == 0)
port->break_length--;
} else {
sx_out(bp, CD186x_TDR, CD186x_C_ESC);
sx_out(bp, CD186x_IER, port->IER);
}
if (port->xmit_cnt <= port->wakeup_chars)
- tty_wakeup(tty);
+ tty_wakeup(tty);
func_exit();
}
-static inline void sx_check_modem(struct specialix_board * bp)
+static void sx_check_modem(struct specialix_board *bp)
{
struct specialix_port *port;
struct tty_struct *tty;
unsigned char mcr;
int msvr_cd;
- dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
- if (!(port = sx_get_port(bp, "Modem")))
+ dprintk(SX_DEBUG_SIGNALS, "Modem intr. ");
+ port = sx_get_port(bp, "Modem");
+ if (port == NULL)
return;
tty = port->port.tty;
mcr = sx_in(bp, CD186x_MCR);
- printk ("mcr = %02x.\n", mcr);
if ((mcr & MCR_CDCHG)) {
- dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
+ dprintk(SX_DEBUG_SIGNALS, "CD just changed... ");
msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
if (msvr_cd) {
- dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
+ dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
wake_up_interruptible(&port->port.open_wait);
} else {
- dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
+ dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n");
tty_hangup(tty);
}
}
spin_lock_irqsave(&bp->lock, flags);
- dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
+ dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__,
+ port_No(sx_get_port(bp, "INT")),
+ SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
if (!(bp->flags & SX_BOARD_ACTIVE)) {
- dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq);
+ dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n",
+ bp->irq);
spin_unlock_irqrestore(&bp->lock, flags);
func_exit();
return IRQ_NONE;
saved_reg = bp->reg;
- while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
- (SRSR_RREQint |
- SRSR_TREQint |
- SRSR_MREQint)))) {
+ while (++loop < 16) {
+ status = sx_in(bp, CD186x_SRSR) &
+ (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
+ if (status == 0)
+ break;
if (status & SRSR_RREQint) {
ack = sx_in(bp, CD186x_RRAR);
else if (ack == (SX_ID | GIVR_IT_REXC))
sx_receive_exc(bp);
else
- printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
- board_No(bp), status, ack);
+ printk(KERN_ERR
+ "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
+ board_No(bp), status, ack);
} else if (status & SRSR_TREQint) {
ack = sx_in(bp, CD186x_TRAR);
sx_transmit(bp);
else
printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
- board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
+ board_No(bp), status, ack,
+ port_No(sx_get_port(bp, "Int")));
} else if (status & SRSR_MREQint) {
ack = sx_in(bp, CD186x_MRAR);
if (ack == (SX_ID | GIVR_IT_MODEM))
sx_check_modem(bp);
else
- printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
+ printk(KERN_ERR
+ "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
board_No(bp), status, ack);
}
sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
}
bp->reg = saved_reg;
- outb (bp->reg, bp->base + SX_ADDR_REG);
+ outb(bp->reg, bp->base + SX_ADDR_REG);
spin_unlock_irqrestore(&bp->lock, flags);
func_exit();
return IRQ_HANDLED;
* Routines for open & close processing.
*/
-static void turn_ints_off (struct specialix_board *bp)
+static void turn_ints_off(struct specialix_board *bp)
{
unsigned long flags;
func_enter();
- if (bp->flags & SX_BOARD_IS_PCI) {
- /* This was intended for enabeling the interrupt on the
- * PCI card. However it seems that it's already enabled
- * and as PCI interrupts can be shared, there is no real
- * reason to have to turn it off. */
- }
-
spin_lock_irqsave(&bp->lock, flags);
- (void) sx_in_off (bp, 0); /* Turn off interrupts. */
+ (void) sx_in_off(bp, 0); /* Turn off interrupts. */
spin_unlock_irqrestore(&bp->lock, flags);
func_exit();
}
-static void turn_ints_on (struct specialix_board *bp)
+static void turn_ints_on(struct specialix_board *bp)
{
unsigned long flags;
func_enter();
- if (bp->flags & SX_BOARD_IS_PCI) {
- /* play with the PCI chip. See comment above. */
- }
spin_lock_irqsave(&bp->lock, flags);
- (void) sx_in (bp, 0); /* Turn ON interrupts. */
+ (void) sx_in(bp, 0); /* Turn ON interrupts. */
spin_unlock_irqrestore(&bp->lock, flags);
func_exit();
/* Called with disabled interrupts */
-static inline int sx_setup_board(struct specialix_board * bp)
+static int sx_setup_board(struct specialix_board *bp)
{
int error;
return 0;
if (bp->flags & SX_BOARD_IS_PCI)
- error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
+ error = request_irq(bp->irq, sx_interrupt,
+ IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
else
- error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED, "specialix IO8+", bp);
+ error = request_irq(bp->irq, sx_interrupt,
+ IRQF_DISABLED, "specialix IO8+", bp);
if (error)
return error;
- turn_ints_on (bp);
+ turn_ints_on(bp);
bp->flags |= SX_BOARD_ACTIVE;
return 0;
/* Called with disabled interrupts */
-static inline void sx_shutdown_board(struct specialix_board *bp)
+static void sx_shutdown_board(struct specialix_board *bp)
{
func_enter();
bp->flags &= ~SX_BOARD_ACTIVE;
- dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
- bp->irq, board_No (bp));
+ dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
+ bp->irq, board_No(bp));
free_irq(bp->irq, bp);
-
- turn_ints_off (bp);
-
-
+ turn_ints_off(bp);
func_exit();
}
+static unsigned int sx_crtscts(struct tty_struct *tty)
+{
+ if (sx_rtscts)
+ return C_CRTSCTS(tty);
+ return 1;
+}
/*
* Setting up port characteristics.
* Must be called with disabled interrupts
*/
-static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
+static void sx_change_speed(struct specialix_board *bp,
+ struct specialix_port *port)
{
struct tty_struct *tty;
unsigned long baud;
func_enter();
- if (!(tty = port->port.tty) || !tty->termios) {
+ tty = port->port.tty;
+ if (!tty || !tty->termios) {
func_exit();
return;
}
/* The Specialix board doens't implement the RTS lines.
They are used to set the IRQ level. Don't touch them. */
- if (SX_CRTSCTS(tty))
+ if (sx_crtscts(tty))
port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
else
port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
spin_unlock_irqrestore(&bp->lock, flags);
- dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
+ dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
baud = tty_get_baud_rate(tty);
if (baud == 38400) {
if (!baud) {
/* Drop DTR & exit */
- dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
- if (!SX_CRTSCTS (tty)) {
- port -> MSVR &= ~ MSVR_DTR;
+ dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
+ if (!sx_crtscts(tty)) {
+ port->MSVR &= ~MSVR_DTR;
spin_lock_irqsave(&bp->lock, flags);
- sx_out(bp, CD186x_MSVR, port->MSVR );
+ sx_out(bp, CD186x_MSVR, port->MSVR);
spin_unlock_irqrestore(&bp->lock, flags);
- }
- else
- dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
+ } else
+ dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
return;
} else {
/* Set DTR on */
- if (!SX_CRTSCTS (tty)) {
- port ->MSVR |= MSVR_DTR;
- }
+ if (!sx_crtscts(tty))
+ port->MSVR |= MSVR_DTR;
}
/*
/* Set baud rate for port */
tmp = port->custom_divisor ;
- if ( tmp )
- printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
- "This is an untested option, please be carefull.\n",
- port_No (port), tmp);
+ if (tmp)
+ printk(KERN_INFO
+ "sx%d: Using custom baud rate divisor %ld. \n"
+ "This is an untested option, please be careful.\n",
+ port_No(port), tmp);
else
- tmp = (((SX_OSCFREQ + baud/2) / baud +
- CD186x_TPC/2) / CD186x_TPC);
+ tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) /
+ CD186x_TPC);
- if ((tmp < 0x10) && time_before(again, jiffies)) {
+ if (tmp < 0x10 && time_before(again, jiffies)) {
again = jiffies + HZ * 60;
/* Page 48 of version 2.0 of the CL-CD1865 databook */
if (tmp >= 12) {
- printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
- "Performance degradation is possible.\n"
- "Read specialix.txt for more info.\n",
- port_No (port), tmp);
+ printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
+ "Performance degradation is possible.\n"
+ "Read specialix.txt for more info.\n",
+ port_No(port), tmp);
} else {
- printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
- "Warning: overstressing Cirrus chip. "
- "This might not work.\n"
- "Read specialix.txt for more info.\n",
- port_No (port), tmp);
+ printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
+ "Warning: overstressing Cirrus chip. This might not work.\n"
+ "Read specialix.txt for more info.\n", port_No(port), tmp);
}
}
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_TBPRL, tmp & 0xff);
spin_unlock_irqrestore(&bp->lock, flags);
if (port->custom_divisor)
- baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
+ baud = (SX_OSCFREQ + port->custom_divisor/2) /
+ port->custom_divisor;
baud = (baud + 5) / 10; /* Estimated CPS */
/* Two timer ticks seems enough to wakeup something like SLIP driver */
sx_out(bp, CD186x_RTPR, tmp);
spin_unlock_irqrestore(&bp->lock, flags);
switch (C_CSIZE(tty)) {
- case CS5:
+ case CS5:
cor1 |= COR1_5BITS;
break;
- case CS6:
+ case CS6:
cor1 |= COR1_6BITS;
break;
- case CS7:
+ case CS7:
cor1 |= COR1_7BITS;
break;
- case CS8:
+ case CS8:
cor1 |= COR1_8BITS;
break;
}
mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
spin_lock_irqsave(&bp->lock, flags);
- tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
+ tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) &
+ (MSVR_CTS|MSVR_DSR));
spin_unlock_irqrestore(&bp->lock, flags);
#else
port->COR2 |= COR2_CTSAE;
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
/* Setting up modem option registers */
- dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
+ dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n",
+ mcor1, mcor2);
sx_out(bp, CD186x_MCOR1, mcor1);
sx_out(bp, CD186x_MCOR2, mcor2);
spin_unlock_irqrestore(&bp->lock, flags);
/* Must be called with interrupts enabled */
-static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
+static int sx_setup_port(struct specialix_board *bp,
+ struct specialix_port *port)
{
unsigned long flags;
/* We may sleep in get_zeroed_page() */
unsigned long tmp;
- if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
+ tmp = get_zeroed_page(GFP_KERNEL);
+ if (tmp == 0L) {
func_exit();
return -ENOMEM;
}
/* Must be called with interrupts disabled */
-static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
+static void sx_shutdown_port(struct specialix_board *bp,
+ struct specialix_port *port)
{
struct tty_struct *tty;
int i;
}
if (sx_debug & SX_DEBUG_FIFO) {
- dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
- board_No(bp), port_No(port), port->overrun);
- for (i = 0; i < 10; i++) {
+ dprintk(SX_DEBUG_FIFO,
+ "sx%d: port %d: %ld overruns, FIFO hits [ ",
+ board_No(bp), port_No(port), port->overrun);
+ for (i = 0; i < 10; i++)
dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
- }
dprintk(SX_DEBUG_FIFO, "].\n");
}
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port));
- if (!(tty = port->port.tty) || C_HUPCL(tty)) {
+ tty = port->port.tty;
+ if (tty == NULL || C_HUPCL(tty)) {
/* Drop DTR */
sx_out(bp, CD186x_MSVDTR, 0);
}
}
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
- struct specialix_port *port)
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+ struct specialix_port *port)
{
DECLARE_WAITQUEUE(wait, current);
struct specialix_board *bp = port_Board(port);
retval = 0;
add_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&port->lock, flags);
- if (!tty_hung_up_p(filp)) {
+ if (!tty_hung_up_p(filp))
port->port.count--;
- }
spin_unlock_irqrestore(&port->lock, flags);
port->port.blocked_open++;
while (1) {
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port));
CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
- if (SX_CRTSCTS (tty)) {
+ if (sx_crtscts(tty)) {
/* Activate RTS */
port->MSVR |= MSVR_DTR; /* WTF? */
- sx_out (bp, CD186x_MSVR, port->MSVR);
+ sx_out(bp, CD186x_MSVR, port->MSVR);
} else {
/* Activate DTR */
port->MSVR |= MSVR_DTR;
- sx_out (bp, CD186x_MSVR, port->MSVR);
+ sx_out(bp, CD186x_MSVR, port->MSVR);
}
spin_unlock_irqrestore(&bp->lock, flags);
set_current_state(TASK_INTERRUPTIBLE);
set_current_state(TASK_RUNNING);
remove_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&port->lock, flags);
- if (!tty_hung_up_p(filp)) {
+ if (!tty_hung_up_p(filp))
port->port.count++;
- }
port->port.blocked_open--;
spin_unlock_irqrestore(&port->lock, flags);
if (retval) {
}
-static int sx_open(struct tty_struct * tty, struct file * filp)
+static int sx_open(struct tty_struct *tty, struct file *filp)
{
int board;
int error;
- struct specialix_port * port;
- struct specialix_board * bp;
+ struct specialix_port *port;
+ struct specialix_board *bp;
int i;
unsigned long flags;
port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
port->overrun = 0;
for (i = 0; i < 10; i++)
- port->hits[i]=0;
+ port->hits[i] = 0;
- dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
- board, bp, port, SX_PORT(tty->index));
+ dprintk(SX_DEBUG_OPEN,
+ "Board = %d, bp = %p, port = %p, portno = %d.\n",
+ board, bp, port, SX_PORT(tty->index));
if (sx_paranoia_check(port, tty->name, "sx_open")) {
func_enter();
return -ENODEV;
}
- if ((error = sx_setup_board(bp))) {
+ error = sx_setup_board(bp);
+ if (error) {
func_exit();
return error;
}
port->port.tty = tty;
spin_unlock_irqrestore(&bp->lock, flags);
- if ((error = sx_setup_port(bp, port))) {
+ error = sx_setup_port(bp, port);
+ if (error) {
func_enter();
return error;
}
- if ((error = block_til_ready(tty, filp, port))) {
+ error = block_til_ready(tty, filp, port);
+ if (error) {
func_enter();
return error;
}
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags;
- struct specialix_board * bp;
+ struct specialix_board *bp;
func_enter();
func_exit();
}
-static void sx_close(struct tty_struct * tty, struct file * filp)
+static void sx_close(struct tty_struct *tty, struct file *filp)
{
- struct specialix_port *port = (struct specialix_port *) tty->driver_data;
+ struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp;
unsigned long flags;
unsigned long timeout;
}
bp = port_Board(port);
- if ((tty->count == 1) && (port->port.count != 1)) {
+ if (tty->count == 1 && port->port.count != 1) {
printk(KERN_ERR "sx%d: sx_close: bad port count;"
" tty->count is 1, port count is %d\n",
board_No(bp), port->port.count);
*/
tty->closing = 1;
spin_unlock_irqrestore(&port->lock, flags);
- dprintk (SX_DEBUG_OPEN, "Closing\n");
- if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+ dprintk(SX_DEBUG_OPEN, "Closing\n");
+ if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
tty_wait_until_sent(tty, port->port.closing_wait);
- }
/*
* At this point we stop accepting input. To do this, we
* disable the receive line status interrupts, and tell the
* interrupt driver to stop checking the data ready bit in the
* line status register.
*/
- dprintk (SX_DEBUG_OPEN, "Closed\n");
+ dprintk(SX_DEBUG_OPEN, "Closed\n");
port->IER &= ~IER_RXD;
if (port->port.flags & ASYNC_INITIALIZED) {
port->IER &= ~IER_TXRDY;
* important if there is a transmit FIFO!
*/
timeout = jiffies+HZ;
- while(port->IER & IER_TXEMPTY) {
- set_current_state (TASK_INTERRUPTIBLE);
+ while (port->IER & IER_TXEMPTY) {
+ set_current_state(TASK_INTERRUPTIBLE);
msleep_interruptible(jiffies_to_msecs(port->timeout));
if (time_after(jiffies, timeout)) {
- printk (KERN_INFO "Timeout waiting for close\n");
+ printk(KERN_INFO "Timeout waiting for close\n");
break;
}
}
}
if (--bp->count < 0) {
- printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
- board_No(bp), bp->count, tty->index);
+ printk(KERN_ERR
+ "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
+ board_No(bp), bp->count, tty->index);
bp->count = 0;
}
if (--port->port.count < 0) {
- printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
- board_No(bp), port_No(port), port->port.count);
+ printk(KERN_ERR
+ "sx%d: sx_close: bad port count for tty%d: %d\n",
+ board_No(bp), port_No(port), port->port.count);
port->port.count = 0;
}
port->port.tty = NULL;
spin_unlock_irqrestore(&port->lock, flags);
if (port->port.blocked_open) {
- if (port->port.close_delay) {
- msleep_interruptible(jiffies_to_msecs(port->port.close_delay));
- }
+ if (port->port.close_delay)
+ msleep_interruptible(
+ jiffies_to_msecs(port->port.close_delay));
wake_up_interruptible(&port->port.open_wait);
}
port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
}
-static int sx_write(struct tty_struct * tty,
- const unsigned char *buf, int count)
+static int sx_write(struct tty_struct *tty,
+ const unsigned char *buf, int count)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp;
}
-static int sx_put_char(struct tty_struct * tty, unsigned char ch)
+static int sx_put_char(struct tty_struct *tty, unsigned char ch)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags;
- struct specialix_board * bp;
+ struct specialix_board *bp;
func_enter();
func_exit();
return 0;
}
- dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
+ dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
if (!port->xmit_buf) {
func_exit();
return 0;
bp = port_Board(port);
spin_lock_irqsave(&port->lock, flags);
- dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
- if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
+ dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n",
+ port->xmit_cnt, port->xmit_buf);
+ if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) {
spin_unlock_irqrestore(&port->lock, flags);
- dprintk (SX_DEBUG_TX, "Exit size\n");
+ dprintk(SX_DEBUG_TX, "Exit size\n");
func_exit();
return 0;
}
- dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
+ dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
port->xmit_buf[port->xmit_head++] = ch;
port->xmit_head &= SERIAL_XMIT_SIZE - 1;
port->xmit_cnt++;
}
-static void sx_flush_chars(struct tty_struct * tty)
+static void sx_flush_chars(struct tty_struct *tty)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags;
- struct specialix_board * bp = port_Board(port);
+ struct specialix_board *bp = port_Board(port);
func_enter();
}
-static int sx_write_room(struct tty_struct * tty)
+static int sx_write_room(struct tty_struct *tty)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
int ret;
return port->xmit_cnt;
}
-
-
static int sx_tiocmget(struct tty_struct *tty, struct file *file)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
- struct specialix_board * bp;
+ struct specialix_board *bp;
unsigned char status;
unsigned int result;
unsigned long flags;
}
bp = port_Board(port);
- spin_lock_irqsave (&bp->lock, flags);
+ spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port));
status = sx_in(bp, CD186x_MSVR);
spin_unlock_irqrestore(&bp->lock, flags);
- dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
- port_No(port), status, sx_in (bp, CD186x_CAR));
- dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
- if (SX_CRTSCTS(port->port.tty)) {
- result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
- | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
- | ((status & MSVR_CD) ? TIOCM_CAR : 0)
- |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
- | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
+ dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
+ port_No(port), status, sx_in(bp, CD186x_CAR));
+ dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
+ if (sx_crtscts(port->port.tty)) {
+ result = TIOCM_DTR | TIOCM_DSR
+ | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
+ | ((status & MSVR_CD) ? TIOCM_CAR : 0)
+ | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
} else {
- result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
- | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
- | ((status & MSVR_CD) ? TIOCM_CAR : 0)
- |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
- | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
+ result = TIOCM_RTS | TIOCM_DSR
+ | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
+ | ((status & MSVR_CD) ? TIOCM_CAR : 0)
+ | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
}
func_exit();
bp = port_Board(port);
spin_lock_irqsave(&port->lock, flags);
- /* if (set & TIOCM_RTS)
- port->MSVR |= MSVR_RTS; */
- /* if (set & TIOCM_DTR)
- port->MSVR |= MSVR_DTR; */
-
- if (SX_CRTSCTS(port->port.tty)) {
+ if (sx_crtscts(port->port.tty)) {
if (set & TIOCM_RTS)
port->MSVR |= MSVR_DTR;
} else {
if (set & TIOCM_DTR)
port->MSVR |= MSVR_DTR;
}
-
- /* if (clear & TIOCM_RTS)
- port->MSVR &= ~MSVR_RTS; */
- /* if (clear & TIOCM_DTR)
- port->MSVR &= ~MSVR_DTR; */
- if (SX_CRTSCTS(port->port.tty)) {
+ if (sx_crtscts(port->port.tty)) {
if (clear & TIOCM_RTS)
port->MSVR &= ~MSVR_DTR;
} else {
}
-static inline void sx_send_break(struct specialix_port * port, unsigned long length)
+static int sx_send_break(struct tty_struct *tty, int length)
{
+ struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp = port_Board(port);
unsigned long flags;
func_enter();
+ if (length == 0 || length == -1)
+ return -EOPNOTSUPP;
- spin_lock_irqsave (&port->lock, flags);
+ spin_lock_irqsave(&port->lock, flags);
port->break_length = SPECIALIX_TPS / HZ * length;
port->COR2 |= COR2_ETC;
port->IER |= IER_TXRDY;
sx_out(bp, CD186x_COR2, port->COR2);
sx_out(bp, CD186x_IER, port->IER);
spin_unlock_irqrestore(&bp->lock, flags);
- spin_unlock_irqrestore (&port->lock, flags);
+ spin_unlock_irqrestore(&port->lock, flags);
sx_wait_CCR(bp);
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CCR, CCR_CORCHG2);
sx_wait_CCR(bp);
func_exit();
+ return 0;
}
-static inline int sx_set_serial_info(struct specialix_port * port,
- struct serial_struct __user * newinfo)
+static int sx_set_serial_info(struct specialix_port *port,
+ struct serial_struct __user *newinfo)
{
struct serial_struct tmp;
struct specialix_board *bp = port_Board(port);
return -EPERM;
}
port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
- (tmp.flags & ASYNC_USR_MASK));
+ (tmp.flags & ASYNC_USR_MASK));
port->custom_divisor = tmp.custom_divisor;
} else {
port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
- (tmp.flags & ASYNC_FLAGS));
+ (tmp.flags & ASYNC_FLAGS));
port->port.close_delay = tmp.close_delay;
port->port.closing_wait = tmp.closing_wait;
port->custom_divisor = tmp.custom_divisor;
}
- if (change_speed) {
+ if (change_speed)
sx_change_speed(bp, port);
- }
+
func_exit();
unlock_kernel();
return 0;
}
-static inline int sx_get_serial_info(struct specialix_port * port,
+static int sx_get_serial_info(struct specialix_port *port,
struct serial_struct __user *retinfo)
{
struct serial_struct tmp;
}
-static int sx_ioctl(struct tty_struct * tty, struct file * filp,
- unsigned int cmd, unsigned long arg)
+static int sx_ioctl(struct tty_struct *tty, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
- int retval;
void __user *argp = (void __user *)arg;
func_enter();
}
switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
- retval = tty_check_change(tty);
- if (retval) {
- func_exit();
- return retval;
- }
- tty_wait_until_sent(tty, 0);
- if (!arg)
- sx_send_break(port, HZ/4); /* 1/4 second */
- return 0;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
- retval = tty_check_change(tty);
- if (retval) {
- func_exit();
- return retval;
- }
- tty_wait_until_sent(tty, 0);
- sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
+ case TIOCGSERIAL:
func_exit();
- return 0;
- case TIOCGSERIAL:
- func_exit();
return sx_get_serial_info(port, argp);
- case TIOCSSERIAL:
- func_exit();
+ case TIOCSSERIAL:
+ func_exit();
return sx_set_serial_info(port, argp);
- default:
- func_exit();
+ default:
+ func_exit();
return -ENOIOCTLCMD;
}
func_exit();
}
-static void sx_throttle(struct tty_struct * tty)
+static void sx_throttle(struct tty_struct *tty)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp;
bp = port_Board(port);
/* Use DTR instead of RTS ! */
- if (SX_CRTSCTS (tty))
+ if (sx_crtscts(tty))
port->MSVR &= ~MSVR_DTR;
else {
/* Auch!!! I think the system shouldn't call this then. */
/* Or maybe we're supposed (allowed?) to do our side of hw
handshake anyway, even when hardware handshake is off.
When you see this in your logs, please report.... */
- printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
- port_No (port));
+ printk(KERN_ERR
+ "sx%d: Need to throttle, but can't (hardware hs is off)\n",
+ port_No(port));
}
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port));
}
-static void sx_unthrottle(struct tty_struct * tty)
+static void sx_unthrottle(struct tty_struct *tty)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp;
spin_lock_irqsave(&port->lock, flags);
/* XXXX Use DTR INSTEAD???? */
- if (SX_CRTSCTS(tty)) {
+ if (sx_crtscts(tty))
port->MSVR |= MSVR_DTR;
- } /* Else clause: see remark in "sx_throttle"... */
+ /* Else clause: see remark in "sx_throttle"... */
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port));
spin_unlock_irqrestore(&bp->lock, flags);
}
-static void sx_stop(struct tty_struct * tty)
+static void sx_stop(struct tty_struct *tty)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp;
}
-static void sx_start(struct tty_struct * tty)
+static void sx_start(struct tty_struct *tty)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp;
func_exit();
}
-static void sx_hangup(struct tty_struct * tty)
+static void sx_hangup(struct tty_struct *tty)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
struct specialix_board *bp;
spin_lock_irqsave(&port->lock, flags);
bp->count -= port->port.count;
if (bp->count < 0) {
- printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
- board_No(bp), bp->count, tty->index);
+ printk(KERN_ERR
+ "sx%d: sx_hangup: bad board count: %d port: %d\n",
+ board_No(bp), bp->count, tty->index);
bp->count = 0;
}
port->port.count = 0;
}
-static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termios)
+static void sx_set_termios(struct tty_struct *tty,
+ struct ktermios *old_termios)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags;
- struct specialix_board * bp;
+ struct specialix_board *bp;
if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
return;
.hangup = sx_hangup,
.tiocmget = sx_tiocmget,
.tiocmset = sx_tiocmset,
+ .break_ctl = sx_send_break,
};
static int sx_init_drivers(void)
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
specialix_driver->init_termios.c_ispeed = 9600;
specialix_driver->init_termios.c_ospeed = 9600;
- specialix_driver->flags = TTY_DRIVER_REAL_RAW;
+ specialix_driver->flags = TTY_DRIVER_REAL_RAW |
+ TTY_DRIVER_HARDWARE_BREAK;
tty_set_operations(specialix_driver, &sx_ops);
- if ((error = tty_register_driver(specialix_driver))) {
+ error = tty_register_driver(specialix_driver);
+ if (error) {
put_tty_driver(specialix_driver);
- printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
- error);
+ printk(KERN_ERR
+ "sx: Couldn't register specialix IO8+ driver, error = %d\n",
+ error);
func_exit();
return 1;
}
printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
-#ifdef CONFIG_SPECIALIX_RTSCTS
- printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
-#else
- printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
-#endif
+ if (sx_rtscts)
+ printk(KERN_INFO
+ "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
+ else
+ printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
for (i = 0; i < SX_NBOARD; i++)
spin_lock_init(&sx_board[i].lock);
{
struct pci_dev *pdev = NULL;
- i=0;
+ i = 0;
while (i < SX_NBOARD) {
if (sx_board[i].flags & SX_BOARD_PRESENT) {
i++;
continue;
}
- pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
- PCI_DEVICE_ID_SPECIALIX_IO8,
- pdev);
- if (!pdev) break;
+ pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX,
+ PCI_DEVICE_ID_SPECIALIX_IO8, pdev);
+ if (!pdev)
+ break;
if (pci_enable_device(pdev))
continue;
sx_board[i].irq = pdev->irq;
- sx_board[i].base = pci_resource_start (pdev, 2);
+ sx_board[i].base = pci_resource_start(pdev, 2);
sx_board[i].flags |= SX_BOARD_IS_PCI;
if (!sx_probe(&sx_board[i]))
- found ++;
+ found++;
}
/* May exit pci_get sequence early with lots of boards */
if (pdev != NULL)
}
static int iobase[SX_NBOARD] = {0,};
-
-static int irq [SX_NBOARD] = {0,};
+static int irq[SX_NBOARD] = {0,};
module_param_array(iobase, int, NULL, 0);
module_param_array(irq, int, NULL, 0);
module_param(sx_debug, int, 0);
+module_param(sx_rtscts, int, 0);
module_param(sx_rxfifo, int, 0);
-#ifdef SPECIALIX_TIMER
-module_param(sx_poll, int, 0);
-#endif
/*
* You can setup up to 4 boards.
func_enter();
if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
- for(i = 0; i < SX_NBOARD; i++) {
+ for (i = 0; i < SX_NBOARD; i++) {
sx_board[i].base = iobase[i];
sx_board[i].irq = irq[i];
- sx_board[i].count= 0;
+ sx_board[i].count = 0;
}
}
for (i = 0; i < SX_NBOARD; i++)
if (sx_board[i].flags & SX_BOARD_PRESENT)
sx_release_io_range(&sx_board[i]);
-#ifdef SPECIALIX_TIMER
- del_timer_sync(&missed_irq_timer);
-#endif
-
func_exit();
}
/*****************************************************************************/
-static void stl_putchar(struct tty_struct *tty, unsigned char ch)
+static int stl_putchar(struct tty_struct *tty, unsigned char ch)
{
struct stlport *portp;
unsigned int len;
pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch);
if (tty == NULL)
- return;
+ return -EINVAL;
portp = tty->driver_data;
if (portp == NULL)
- return;
+ return -EINVAL;
if (portp->tx.buf == NULL)
- return;
+ return -EINVAL;
head = portp->tx.head;
tail = portp->tx.tail;
head = portp->tx.buf;
}
portp->tx.head = head;
+ return 0;
}
/*****************************************************************************/
/*****************************************************************************/
-static void stl_breakctl(struct tty_struct *tty, int state)
+static int stl_breakctl(struct tty_struct *tty, int state)
{
struct stlport *portp;
pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state);
if (tty == NULL)
- return;
+ return -EINVAL;
portp = tty->driver_data;
if (portp == NULL)
- return;
+ return -EINVAL;
stl_sendbreak(portp, ((state == -1) ? 1 : 2));
+ return 0;
}
/*****************************************************************************/
return rc;
}
-static void sx_break(struct tty_struct *tty, int flag)
+static int sx_break(struct tty_struct *tty, int flag)
{
struct sx_port *port = tty->driver_data;
int rv;
read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat)));
unlock_kernel();
func_exit();
+ return 0;
}
static int sx_tiocmget(struct tty_struct *tty, struct file *file)
*
* Arguments: tty pointer to tty instance data
* break_state -1=set break condition, 0=clear
- * Return Value: None
+ * Return Value: error code
*/
-static void mgsl_break(struct tty_struct *tty, int break_state)
+static int mgsl_break(struct tty_struct *tty, int break_state)
{
struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data;
unsigned long flags;
__FILE__,__LINE__, info->device_name, break_state);
if (mgsl_paranoia_check(info, tty->name, "mgsl_break"))
- return;
+ return -EINVAL;
spin_lock_irqsave(&info->irq_spinlock,flags);
if (break_state == -1)
else
usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7));
spin_unlock_irqrestore(&info->irq_spinlock,flags);
+ return 0;
} /* end of mgsl_break() */
static int chars_in_buffer(struct tty_struct *tty);
static void throttle(struct tty_struct * tty);
static void unthrottle(struct tty_struct * tty);
-static void set_break(struct tty_struct *tty, int break_state);
+static int set_break(struct tty_struct *tty, int break_state);
/*
* generic HDLC support and callbacks
char *buf; /* virtual address of data buffer */
unsigned int pdesc; /* physical address of this descriptor */
dma_addr_t buf_dma_addr;
+ unsigned short buf_count;
};
#define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b))
u32 idle_mode;
u32 max_frame_size; /* as set by device config */
- unsigned int raw_rx_size;
+ unsigned int rbuf_fill_level;
unsigned int if_mode;
/* device status */
static void tx_stop(struct slgt_info *info);
static void tx_set_idle(struct slgt_info *info);
static unsigned int free_tbuf_count(struct slgt_info *info);
+static unsigned int tbuf_bytes(struct slgt_info *info);
static void reset_tbufs(struct slgt_info *info);
static void tdma_reset(struct slgt_info *info);
static void tdma_start(struct slgt_info *info);
static int tiocmget(struct tty_struct *tty, struct file *file);
static int tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
-static void set_break(struct tty_struct *tty, int break_state);
+static int set_break(struct tty_struct *tty, int break_state);
static int get_interface(struct slgt_info *info, int __user *if_mode);
static int set_interface(struct slgt_info *info, int if_mode);
static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
int ret = 0;
struct slgt_info *info = tty->driver_data;
unsigned long flags;
+ unsigned int bufs_needed;
if (sanity_check(info, tty->name, "write"))
goto cleanup;
if (!count)
goto cleanup;
- if (info->params.mode == MGSL_MODE_RAW ||
- info->params.mode == MGSL_MODE_MONOSYNC ||
- info->params.mode == MGSL_MODE_BISYNC) {
- unsigned int bufs_needed = (count/DMABUFSIZE);
- unsigned int bufs_free = free_tbuf_count(info);
- if (count % DMABUFSIZE)
- ++bufs_needed;
- if (bufs_needed > bufs_free)
- goto cleanup;
- } else {
- if (info->tx_active)
- goto cleanup;
- if (info->tx_count) {
- /* send accumulated data from send_char() calls */
- /* as frame and wait before accepting more data. */
- tx_load(info, info->tx_buf, info->tx_count);
- goto start;
- }
+ if (!info->tx_active && info->tx_count) {
+ /* send accumulated data from send_char() */
+ tx_load(info, info->tx_buf, info->tx_count);
+ goto start;
}
+ bufs_needed = (count/DMABUFSIZE);
+ if (count % DMABUFSIZE)
+ ++bufs_needed;
+ if (bufs_needed > free_tbuf_count(info))
+ goto cleanup;
ret = info->tx_count = count;
tx_load(info, buf, count);
static int chars_in_buffer(struct tty_struct *tty)
{
struct slgt_info *info = tty->driver_data;
+ int count;
if (sanity_check(info, tty->name, "chars_in_buffer"))
return 0;
- DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, info->tx_count));
- return info->tx_count;
+ count = tbuf_bytes(info);
+ DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, count));
+ return count;
}
/*
* set or clear transmit break condition
* break_state -1=set break condition, 0=clear
*/
-static void set_break(struct tty_struct *tty, int break_state)
+static int set_break(struct tty_struct *tty, int break_state)
{
struct slgt_info *info = tty->driver_data;
unsigned short value;
unsigned long flags;
if (sanity_check(info, tty->name, "set_break"))
- return;
+ return -EINVAL;
DBGINFO(("%s set_break(%d)\n", info->device_name, break_state));
spin_lock_irqsave(&info->lock,flags);
value &= ~BIT6;
wr_reg16(info, TCR, value);
spin_unlock_irqrestore(&info->lock,flags);
+ return 0;
}
#if SYNCLINK_GENERIC_HDLC
static int rx_enable(struct slgt_info *info, int enable)
{
unsigned long flags;
- DBGINFO(("%s rx_enable(%d)\n", info->device_name, enable));
+ unsigned int rbuf_fill_level;
+ DBGINFO(("%s rx_enable(%08x)\n", info->device_name, enable));
spin_lock_irqsave(&info->lock,flags);
+ /*
+ * enable[31..16] = receive DMA buffer fill level
+ * 0 = noop (leave fill level unchanged)
+ * fill level must be multiple of 4 and <= buffer size
+ */
+ rbuf_fill_level = ((unsigned int)enable) >> 16;
+ if (rbuf_fill_level) {
+ if ((rbuf_fill_level > DMABUFSIZE) || (rbuf_fill_level % 4)) {
+ spin_unlock_irqrestore(&info->lock, flags);
+ return -EINVAL;
+ }
+ info->rbuf_fill_level = rbuf_fill_level;
+ rx_stop(info); /* restart receiver to use new fill level */
+ }
+
+ /*
+ * enable[1..0] = receiver enable command
+ * 0 = disable
+ * 1 = enable
+ * 2 = enable or force hunt mode if already enabled
+ */
+ enable &= 3;
if (enable) {
if (!info->rx_enabled)
rx_start(info);
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
- info->raw_rx_size = DMABUFSIZE;
+ info->rbuf_fill_level = DMABUFSIZE;
info->port.close_delay = 5*HZ/10;
info->port.closing_wait = 30*HZ;
init_waitqueue_head(&info->status_event_wait_q);
/* set 1st descriptor address */
wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
- switch(info->params.mode) {
- case MGSL_MODE_RAW:
- case MGSL_MODE_MONOSYNC:
- case MGSL_MODE_BISYNC:
- wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
- break;
- default:
- wr_reg32(info, TDCSR, BIT0); /* DMA enable */
- }
+ wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
}
static void tx_stop(struct slgt_info *info)
* 01 enable
* 00 auto-CTS enable
*/
- val = 0;
+ val = BIT2;
switch(info->params.mode) {
case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
break;
}
+ if (info->if_mode & MGSL_INTERFACE_MSB_FIRST)
+ val |= BIT4;
if (info->signals & SerialSignal_DTR)
val |= BIT3;
if (info->signals & SerialSignal_RTS)
while(!done) {
/* reset current buffer for reuse */
info->rbufs[i].status = 0;
- switch(info->params.mode) {
- case MGSL_MODE_RAW:
- case MGSL_MODE_MONOSYNC:
- case MGSL_MODE_BISYNC:
- set_desc_count(info->rbufs[i], info->raw_rx_size);
- break;
- default:
- set_desc_count(info->rbufs[i], DMABUFSIZE);
- }
-
+ set_desc_count(info->rbufs[i], info->rbuf_fill_level);
if (i == last)
done = 1;
if (++i == info->rbuf_count)
DBGBH(("%s rx frame status=%04X size=%d\n",
info->device_name, status, framesize));
- DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx");
+ DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, info->rbuf_fill_level), "rx");
if (framesize) {
if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) {
info->icount.rxok++;
while(copy_count) {
- int partial_count = min(copy_count, DMABUFSIZE);
+ int partial_count = min_t(int, copy_count, info->rbuf_fill_level);
memcpy(p, info->rbufs[i].buf, partial_count);
p += partial_count;
copy_count -= partial_count;
return count;
}
+/*
+ * return number of bytes in unsent transmit DMA buffers
+ * and the serial controller tx FIFO
+ */
+static unsigned int tbuf_bytes(struct slgt_info *info)
+{
+ unsigned int total_count = 0;
+ unsigned int i = info->tbuf_current;
+ unsigned int reg_value;
+ unsigned int count;
+ unsigned int active_buf_count = 0;
+
+ /*
+ * Add descriptor counts for all tx DMA buffers.
+ * If count is zero (cleared by DMA controller after read),
+ * the buffer is complete or is actively being read from.
+ *
+ * Record buf_count of last buffer with zero count starting
+ * from current ring position. buf_count is mirror
+ * copy of count and is not cleared by serial controller.
+ * If DMA controller is active, that buffer is actively
+ * being read so add to total.
+ */
+ do {
+ count = desc_count(info->tbufs[i]);
+ if (count)
+ total_count += count;
+ else if (!total_count)
+ active_buf_count = info->tbufs[i].buf_count;
+ if (++i == info->tbuf_count)
+ i = 0;
+ } while (i != info->tbuf_current);
+
+ /* read tx DMA status register */
+ reg_value = rd_reg32(info, TDCSR);
+
+ /* if tx DMA active, last zero count buffer is in use */
+ if (reg_value & BIT0)
+ total_count += active_buf_count;
+
+ /* add tx FIFO count = reg_value[15..8] */
+ total_count += (reg_value >> 8) & 0xff;
+
+ /* if transmitter active add one byte for shift register */
+ if (info->tx_active)
+ total_count++;
+
+ return total_count;
+}
+
/*
* load transmit DMA buffer(s) with data
*/
set_desc_eof(*d, 0);
set_desc_count(*d, count);
+ d->buf_count = count;
}
info->tbuf_current = i;
static int chars_in_buffer(struct tty_struct *tty);
static void throttle(struct tty_struct * tty);
static void unthrottle(struct tty_struct * tty);
-static void set_break(struct tty_struct *tty, int break_state);
+static int set_break(struct tty_struct *tty, int break_state);
#if SYNCLINK_GENERIC_HDLC
#define dev_to_port(D) (dev_to_hdlc(D)->priv)
static int tiocmget(struct tty_struct *tty, struct file *file);
static int tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
-static void set_break(struct tty_struct *tty, int break_state);
+static int set_break(struct tty_struct *tty, int break_state);
static void add_device(SLMP_INFO *info);
static void device_init(int adapter_num, struct pci_dev *pdev);
/* set or clear transmit break condition
* break_state -1=set break condition, 0=clear
*/
-static void set_break(struct tty_struct *tty, int break_state)
+static int set_break(struct tty_struct *tty, int break_state)
{
unsigned char RegValue;
SLMP_INFO * info = (SLMP_INFO *)tty->driver_data;
__FILE__,__LINE__, info->device_name, break_state);
if (sanity_check(info, tty->name, "set_break"))
- return;
+ return -EINVAL;
spin_lock_irqsave(&info->lock,flags);
RegValue = read_reg(info, CTL);
RegValue &= ~BIT3;
write_reg(info, CTL, RegValue);
spin_unlock_irqrestore(&info->lock,flags);
+ return 0;
}
#if SYNCLINK_GENERIC_HDLC
-/**
- * tty_set_termios_ldisc - set ldisc field
- * @tty: tty structure
- * @num: line discipline number
- *
- * This is probably overkill for real world processors but
- * they are not on hot paths so a little discipline won't do
- * any harm.
- *
- * Locking: takes termios_mutex
- */
-
-static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
-{
- mutex_lock(&tty->termios_mutex);
- tty->termios->c_line = num;
- mutex_unlock(&tty->termios_mutex);
-}
-
-/*
- * This guards the refcounted line discipline lists. The lock
- * must be taken with irqs off because there are hangup path
- * callers who will do ldisc lookups and cannot sleep.
- */
-
-static DEFINE_SPINLOCK(tty_ldisc_lock);
-static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
-/* Line disc dispatch table */
-static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
-
-/**
- * tty_register_ldisc - install a line discipline
- * @disc: ldisc number
- * @new_ldisc: pointer to the ldisc object
- *
- * Installs a new line discipline into the kernel. The discipline
- * is set up as unreferenced and then made available to the kernel
- * from this point onwards.
- *
- * Locking:
- * takes tty_ldisc_lock to guard against ldisc races
- */
-
-int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
-{
- unsigned long flags;
- int ret = 0;
-
- if (disc < N_TTY || disc >= NR_LDISCS)
- return -EINVAL;
-
- spin_lock_irqsave(&tty_ldisc_lock, flags);
- tty_ldiscs[disc] = new_ldisc;
- new_ldisc->num = disc;
- new_ldisc->refcount = 0;
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(tty_register_ldisc);
-
-/**
- * tty_unregister_ldisc - unload a line discipline
- * @disc: ldisc number
- * @new_ldisc: pointer to the ldisc object
- *
- * Remove a line discipline from the kernel providing it is not
- * currently in use.
- *
- * Locking:
- * takes tty_ldisc_lock to guard against ldisc races
- */
-
-int tty_unregister_ldisc(int disc)
-{
- unsigned long flags;
- int ret = 0;
-
- if (disc < N_TTY || disc >= NR_LDISCS)
- return -EINVAL;
-
- spin_lock_irqsave(&tty_ldisc_lock, flags);
- if (tty_ldiscs[disc]->refcount)
- ret = -EBUSY;
- else
- tty_ldiscs[disc] = NULL;
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(tty_unregister_ldisc);
-
-
-/**
- * tty_ldisc_try_get - try and reference an ldisc
- * @disc: ldisc number
- * @ld: tty ldisc structure to complete
- *
- * Attempt to open and lock a line discipline into place. Return
- * the line discipline refcounted and assigned in ld. On an error
- * report the error code back
- */
-
-static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld)
-{
- unsigned long flags;
- struct tty_ldisc_ops *ldops;
- int err = -EINVAL;
-
- spin_lock_irqsave(&tty_ldisc_lock, flags);
- ld->ops = NULL;
- ldops = tty_ldiscs[disc];
- /* Check the entry is defined */
- if (ldops) {
- /* If the module is being unloaded we can't use it */
- if (!try_module_get(ldops->owner))
- err = -EAGAIN;
- else {
- /* lock it */
- ldops->refcount++;
- ld->ops = ldops;
- err = 0;
- }
- }
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- return err;
-}
-
-/**
- * tty_ldisc_get - take a reference to an ldisc
- * @disc: ldisc number
- * @ld: tty line discipline structure to use
- *
- * Takes a reference to a line discipline. Deals with refcounts and
- * module locking counts. Returns NULL if the discipline is not available.
- * Returns a pointer to the discipline and bumps the ref count if it is
- * available
- *
- * Locking:
- * takes tty_ldisc_lock to guard against ldisc races
- */
-
-static int tty_ldisc_get(int disc, struct tty_ldisc *ld)
-{
- int err;
-
- if (disc < N_TTY || disc >= NR_LDISCS)
- return -EINVAL;
- err = tty_ldisc_try_get(disc, ld);
- if (err == -EAGAIN) {
- request_module("tty-ldisc-%d", disc);
- err = tty_ldisc_try_get(disc, ld);
- }
- return err;
-}
-
-/**
- * tty_ldisc_put - drop ldisc reference
- * @disc: ldisc number
- *
- * Drop a reference to a line discipline. Manage refcounts and
- * module usage counts
- *
- * Locking:
- * takes tty_ldisc_lock to guard against ldisc races
- */
-
-static void tty_ldisc_put(struct tty_ldisc_ops *ld)
-{
- unsigned long flags;
- int disc = ld->num;
-
- BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
-
- spin_lock_irqsave(&tty_ldisc_lock, flags);
- ld = tty_ldiscs[disc];
- BUG_ON(ld->refcount == 0);
- ld->refcount--;
- module_put(ld->owner);
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-}
-
-static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
-{
- return (*pos < NR_LDISCS) ? pos : NULL;
-}
-
-static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
-{
- (*pos)++;
- return (*pos < NR_LDISCS) ? pos : NULL;
-}
-
-static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
-{
-}
-
-static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
-{
- int i = *(loff_t *)v;
- struct tty_ldisc ld;
-
- if (tty_ldisc_get(i, &ld) < 0)
- return 0;
- seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i);
- tty_ldisc_put(ld.ops);
- return 0;
-}
-
-static const struct seq_operations tty_ldiscs_seq_ops = {
- .start = tty_ldiscs_seq_start,
- .next = tty_ldiscs_seq_next,
- .stop = tty_ldiscs_seq_stop,
- .show = tty_ldiscs_seq_show,
-};
-
-static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &tty_ldiscs_seq_ops);
-}
-
-const struct file_operations tty_ldiscs_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_tty_ldiscs_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-/**
- * tty_ldisc_assign - set ldisc on a tty
- * @tty: tty to assign
- * @ld: line discipline
- *
- * Install an instance of a line discipline into a tty structure. The
- * ldisc must have a reference count above zero to ensure it remains/
- * The tty instance refcount starts at zero.
- *
- * Locking:
- * Caller must hold references
- */
-
-static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
-{
- ld->refcount = 0;
- tty->ldisc = *ld;
-}
-
-/**
- * tty_ldisc_try - internal helper
- * @tty: the tty
- *
- * Make a single attempt to grab and bump the refcount on
- * the tty ldisc. Return 0 on failure or 1 on success. This is
- * used to implement both the waiting and non waiting versions
- * of tty_ldisc_ref
- *
- * Locking: takes tty_ldisc_lock
- */
-
-static int tty_ldisc_try(struct tty_struct *tty)
-{
- unsigned long flags;
- struct tty_ldisc *ld;
- int ret = 0;
-
- spin_lock_irqsave(&tty_ldisc_lock, flags);
- ld = &tty->ldisc;
- if (test_bit(TTY_LDISC, &tty->flags)) {
- ld->refcount++;
- ret = 1;
- }
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- return ret;
-}
-
-/**
- * tty_ldisc_ref_wait - wait for the tty ldisc
- * @tty: tty device
- *
- * Dereference the line discipline for the terminal and take a
- * reference to it. If the line discipline is in flux then
- * wait patiently until it changes.
- *
- * Note: Must not be called from an IRQ/timer context. The caller
- * must also be careful not to hold other locks that will deadlock
- * against a discipline change, such as an existing ldisc reference
- * (which we check for)
- *
- * Locking: call functions take tty_ldisc_lock
- */
-
-struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
-{
- /* wait_event is a macro */
- wait_event(tty_ldisc_wait, tty_ldisc_try(tty));
- if (tty->ldisc.refcount == 0)
- printk(KERN_ERR "tty_ldisc_ref_wait\n");
- return &tty->ldisc;
-}
-
-EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
-
-/**
- * tty_ldisc_ref - get the tty ldisc
- * @tty: tty device
- *
- * Dereference the line discipline for the terminal and take a
- * reference to it. If the line discipline is in flux then
- * return NULL. Can be called from IRQ and timer functions.
- *
- * Locking: called functions take tty_ldisc_lock
- */
-
-struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
-{
- if (tty_ldisc_try(tty))
- return &tty->ldisc;
- return NULL;
-}
-
-EXPORT_SYMBOL_GPL(tty_ldisc_ref);
-
-/**
- * tty_ldisc_deref - free a tty ldisc reference
- * @ld: reference to free up
- *
- * Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May
- * be called in IRQ context.
- *
- * Locking: takes tty_ldisc_lock
- */
-
-void tty_ldisc_deref(struct tty_ldisc *ld)
-{
- unsigned long flags;
-
- BUG_ON(ld == NULL);
-
- spin_lock_irqsave(&tty_ldisc_lock, flags);
- if (ld->refcount == 0)
- printk(KERN_ERR "tty_ldisc_deref: no references.\n");
- else
- ld->refcount--;
- if (ld->refcount == 0)
- wake_up(&tty_ldisc_wait);
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-}
-
-EXPORT_SYMBOL_GPL(tty_ldisc_deref);
-
-/**
- * tty_ldisc_enable - allow ldisc use
- * @tty: terminal to activate ldisc on
- *
- * Set the TTY_LDISC flag when the line discipline can be called
- * again. Do necessary wakeups for existing sleepers.
- *
- * Note: nobody should set this bit except via this function. Clearing
- * directly is allowed.
- */
-
-static void tty_ldisc_enable(struct tty_struct *tty)
-{
- set_bit(TTY_LDISC, &tty->flags);
- wake_up(&tty_ldisc_wait);
-}
-
-/**
- * tty_ldisc_restore - helper for tty ldisc change
- * @tty: tty to recover
- * @old: previous ldisc
- *
- * Restore the previous line discipline or N_TTY when a line discipline
- * change fails due to an open error
- */
-
-static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
-{
- char buf[64];
- struct tty_ldisc new_ldisc;
-
- /* There is an outstanding reference here so this is safe */
- tty_ldisc_get(old->ops->num, old);
- tty_ldisc_assign(tty, old);
- tty_set_termios_ldisc(tty, old->ops->num);
- if (old->ops->open && (old->ops->open(tty) < 0)) {
- tty_ldisc_put(old->ops);
- /* This driver is always present */
- if (tty_ldisc_get(N_TTY, &new_ldisc) < 0)
- panic("n_tty: get");
- tty_ldisc_assign(tty, &new_ldisc);
- tty_set_termios_ldisc(tty, N_TTY);
- if (new_ldisc.ops->open) {
- int r = new_ldisc.ops->open(tty);
- if (r < 0)
- panic("Couldn't open N_TTY ldisc for "
- "%s --- error %d.",
- tty_name(tty, buf), r);
- }
- }
-}
-
-/**
- * tty_set_ldisc - set line discipline
- * @tty: the terminal to set
- * @ldisc: the line discipline
- *
- * Set the discipline of a tty line. Must be called from a process
- * context.
- *
- * Locking: takes tty_ldisc_lock.
- * called functions take termios_mutex
- */
-
-static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
-{
- int retval;
- struct tty_ldisc o_ldisc, new_ldisc;
- int work;
- unsigned long flags;
- struct tty_struct *o_tty;
-
-restart:
- /* This is a bit ugly for now but means we can break the 'ldisc
- is part of the tty struct' assumption later */
- retval = tty_ldisc_get(ldisc, &new_ldisc);
- if (retval)
- return retval;
-
- /*
- * Problem: What do we do if this blocks ?
- */
-
- tty_wait_until_sent(tty, 0);
-
- if (tty->ldisc.ops->num == ldisc) {
- tty_ldisc_put(new_ldisc.ops);
- return 0;
- }
-
- /*
- * No more input please, we are switching. The new ldisc
- * will update this value in the ldisc open function
- */
-
- tty->receive_room = 0;
-
- o_ldisc = tty->ldisc;
- o_tty = tty->link;
-
- /*
- * Make sure we don't change while someone holds a
- * reference to the line discipline. The TTY_LDISC bit
- * prevents anyone taking a reference once it is clear.
- * We need the lock to avoid racing reference takers.
- */
-
- spin_lock_irqsave(&tty_ldisc_lock, flags);
- if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
- if (tty->ldisc.refcount) {
- /* Free the new ldisc we grabbed. Must drop the lock
- first. */
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- tty_ldisc_put(o_ldisc.ops);
- /*
- * There are several reasons we may be busy, including
- * random momentary I/O traffic. We must therefore
- * retry. We could distinguish between blocking ops
- * and retries if we made tty_ldisc_wait() smarter.
- * That is up for discussion.
- */
- if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
- return -ERESTARTSYS;
- goto restart;
- }
- if (o_tty && o_tty->ldisc.refcount) {
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- tty_ldisc_put(o_tty->ldisc.ops);
- if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
- return -ERESTARTSYS;
- goto restart;
- }
- }
- /*
- * If the TTY_LDISC bit is set, then we are racing against
- * another ldisc change
- */
- if (!test_bit(TTY_LDISC, &tty->flags)) {
- struct tty_ldisc *ld;
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- tty_ldisc_put(new_ldisc.ops);
- ld = tty_ldisc_ref_wait(tty);
- tty_ldisc_deref(ld);
- goto restart;
- }
-
- clear_bit(TTY_LDISC, &tty->flags);
- if (o_tty)
- clear_bit(TTY_LDISC, &o_tty->flags);
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
- /*
- * From this point on we know nobody has an ldisc
- * usage reference, nor can they obtain one until
- * we say so later on.
- */
-
- work = cancel_delayed_work(&tty->buf.work);
- /*
- * Wait for ->hangup_work and ->buf.work handlers to terminate
- * MUST NOT hold locks here.
- */
- flush_scheduled_work();
- /* Shutdown the current discipline. */
- if (o_ldisc.ops->close)
- (o_ldisc.ops->close)(tty);
-
- /* Now set up the new line discipline. */
- tty_ldisc_assign(tty, &new_ldisc);
- tty_set_termios_ldisc(tty, ldisc);
- if (new_ldisc.ops->open)
- retval = (new_ldisc.ops->open)(tty);
- if (retval < 0) {
- tty_ldisc_put(new_ldisc.ops);
- tty_ldisc_restore(tty, &o_ldisc);
- }
- /* At this point we hold a reference to the new ldisc and a
- a reference to the old ldisc. If we ended up flipping back
- to the existing ldisc we have two references to it */
-
- if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc)
- tty->ops->set_ldisc(tty);
-
- tty_ldisc_put(o_ldisc.ops);
-
- /*
- * Allow ldisc referencing to occur as soon as the driver
- * ldisc callback completes.
- */
-
- tty_ldisc_enable(tty);
- if (o_tty)
- tty_ldisc_enable(o_tty);
-
- /* Restart it in case no characters kick it off. Safe if
- already running */
- if (work)
- schedule_delayed_work(&tty->buf.work, 1);
- return retval;
-}
-
/**
* get_tty_driver - find device of a tty
* @dev_t: device identifier
struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc;
struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
int retval = 0;
- struct tty_ldisc *ld;
/* check whether we're reopening an existing tty */
if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
* If we fail here just call release_tty to clean up. No need
* to decrement the use counts, as release_tty doesn't care.
*/
-
- ld = &tty->ldisc;
- if (ld->ops->open) {
- retval = (ld->ops->open)(tty);
- if (retval)
- goto release_mem_out;
- }
- if (o_tty && o_tty->ldisc.ops->open) {
- retval = (o_tty->ldisc.ops->open)(o_tty);
- if (retval) {
- if (ld->ops->close)
- (ld->ops->close)(tty);
- goto release_mem_out;
- }
- tty_ldisc_enable(o_tty);
- }
- tty_ldisc_enable(tty);
- goto success;
+ retval = tty_ldisc_setup(tty, o_tty);
+
+ if (retval)
+ goto release_mem_out;
+ goto success;
/*
* This fast open can be used if the tty is already open.
static void release_dev(struct file *filp)
{
struct tty_struct *tty, *o_tty;
- struct tty_ldisc ld;
int pty_master, tty_closing, o_tty_closing, do_sleep;
int devpts;
int idx;
char buf[64];
- unsigned long flags;
tty = (struct tty_struct *)filp->private_data;
if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode,
printk(KERN_DEBUG "freeing tty structure...");
#endif
/*
- * Prevent flush_to_ldisc() from rescheduling the work for later. Then
- * kill any delayed work. As this is the final close it does not
- * race with the set_ldisc code path.
+ * Ask the line discipline code to release its structures
*/
- clear_bit(TTY_LDISC, &tty->flags);
- cancel_delayed_work(&tty->buf.work);
-
- /*
- * Wait for ->hangup_work and ->buf.work handlers to terminate
- */
-
- flush_scheduled_work();
-
- /*
- * Wait for any short term users (we know they are just driver
- * side waiters as the file is closing so user count on the file
- * side is zero.
- */
- spin_lock_irqsave(&tty_ldisc_lock, flags);
- while (tty->ldisc.refcount) {
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0);
- spin_lock_irqsave(&tty_ldisc_lock, flags);
- }
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- /*
- * Shutdown the current line discipline, and reset it to N_TTY.
- *
- * FIXME: this MUST get fixed for the new reflocking
- */
- if (tty->ldisc.ops->close)
- (tty->ldisc.ops->close)(tty);
- tty_ldisc_put(tty->ldisc.ops);
-
- /*
- * Switch the line discipline back
- */
- WARN_ON(tty_ldisc_get(N_TTY, &ld));
- tty_ldisc_assign(tty, &ld);
- tty_set_termios_ldisc(tty, N_TTY);
- if (o_tty) {
- /* FIXME: could o_tty be in setldisc here ? */
- clear_bit(TTY_LDISC, &o_tty->flags);
- if (o_tty->ldisc.ops->close)
- (o_tty->ldisc.ops->close)(o_tty);
- tty_ldisc_put(o_tty->ldisc.ops);
- WARN_ON(tty_ldisc_get(N_TTY, &ld));
- tty_ldisc_assign(o_tty, &ld);
- tty_set_termios_ldisc(o_tty, N_TTY);
- }
+ tty_ldisc_release(tty, o_tty);
/*
* The release_tty function takes care of the details of clearing
* the slots and preserving the termios structure.
static int send_break(struct tty_struct *tty, unsigned int duration)
{
- if (tty_write_lock(tty, 0) < 0)
- return -EINTR;
- tty->ops->break_ctl(tty, -1);
- if (!signal_pending(current))
- msleep_interruptible(duration);
- tty->ops->break_ctl(tty, 0);
- tty_write_unlock(tty);
- if (signal_pending(current))
- return -EINTR;
- return 0;
+ int retval;
+
+ if (tty->ops->break_ctl == NULL)
+ return 0;
+
+ if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
+ retval = tty->ops->break_ctl(tty, duration);
+ else {
+ /* Do the work ourselves */
+ if (tty_write_lock(tty, 0) < 0)
+ return -EINTR;
+ retval = tty->ops->break_ctl(tty, -1);
+ if (retval)
+ goto out;
+ if (!signal_pending(current))
+ msleep_interruptible(duration);
+ retval = tty->ops->break_ctl(tty, 0);
+out:
+ tty_write_unlock(tty);
+ if (signal_pending(current))
+ retval = -EINTR;
+ }
+ return retval;
}
/**
tty->driver->subtype == PTY_TYPE_MASTER)
real_tty = tty->link;
- /*
- * Break handling by driver
- */
-
- retval = -EINVAL;
-
- if (!tty->ops->break_ctl) {
- switch (cmd) {
- case TIOCSBRK:
- case TIOCCBRK:
- if (tty->ops->ioctl)
- retval = tty->ops->ioctl(tty, file, cmd, arg);
- if (retval != -EINVAL && retval != -ENOIOCTLCMD)
- printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
- return retval;
-
- /* These two ioctl's always return success; even if */
- /* the driver doesn't support them. */
- case TCSBRK:
- case TCSBRKP:
- if (!tty->ops->ioctl)
- return 0;
- retval = tty->ops->ioctl(tty, file, cmd, arg);
- if (retval != -EINVAL && retval != -ENOIOCTLCMD)
- printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
- if (retval == -ENOIOCTLCMD)
- retval = 0;
- return retval;
- }
- }
/*
* Factor out some common prep work
break;
}
+ /*
+ * Now do the stuff.
+ */
switch (cmd) {
case TIOCSTI:
return tiocsti(tty, p);
*/
case TIOCSBRK: /* Turn break on, unconditionally */
if (tty->ops->break_ctl)
- tty->ops->break_ctl(tty, -1);
+ return tty->ops->break_ctl(tty, -1);
return 0;
-
case TIOCCBRK: /* Turn break off, unconditionally */
if (tty->ops->break_ctl)
- tty->ops->break_ctl(tty, 0);
+ return tty->ops->break_ctl(tty, 0);
return 0;
case TCSBRK: /* SVID version: non-zero arg --> no break */
/* non-zero arg means wait for all output data
static void initialize_tty_struct(struct tty_struct *tty)
{
- struct tty_ldisc ld;
memset(tty, 0, sizeof(struct tty_struct));
tty->magic = TTY_MAGIC;
- if (tty_ldisc_get(N_TTY, &ld) < 0)
- panic("n_tty: init_tty");
- tty_ldisc_assign(tty, &ld);
+ tty_ldisc_init(tty);
tty->session = NULL;
tty->pgrp = NULL;
tty->overrun_time = jiffies;
initcall_t *call;
/* Setup the default TTY line discipline. */
- (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
+ tty_ldisc_begin();
/*
* set up the console device so that later boot sequences can
--- /dev/null
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/devpts_fs.h>
+#include <linux/file.h>
+#include <linux/fdtable.h>
+#include <linux/console.h>
+#include <linux/timer.h>
+#include <linux/ctype.h>
+#include <linux/kd.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+
+#include <linux/uaccess.h>
+#include <asm/system.h>
+
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+
+#include <linux/kmod.h>
+#include <linux/nsproxy.h>
+
+/*
+ * This guards the refcounted line discipline lists. The lock
+ * must be taken with irqs off because there are hangup path
+ * callers who will do ldisc lookups and cannot sleep.
+ */
+
+static DEFINE_SPINLOCK(tty_ldisc_lock);
+static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
+/* Line disc dispatch table */
+static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
+
+/**
+ * tty_register_ldisc - install a line discipline
+ * @disc: ldisc number
+ * @new_ldisc: pointer to the ldisc object
+ *
+ * Installs a new line discipline into the kernel. The discipline
+ * is set up as unreferenced and then made available to the kernel
+ * from this point onwards.
+ *
+ * Locking:
+ * takes tty_ldisc_lock to guard against ldisc races
+ */
+
+int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ if (disc < N_TTY || disc >= NR_LDISCS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ tty_ldiscs[disc] = new_ldisc;
+ new_ldisc->num = disc;
+ new_ldisc->refcount = 0;
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(tty_register_ldisc);
+
+/**
+ * tty_unregister_ldisc - unload a line discipline
+ * @disc: ldisc number
+ * @new_ldisc: pointer to the ldisc object
+ *
+ * Remove a line discipline from the kernel providing it is not
+ * currently in use.
+ *
+ * Locking:
+ * takes tty_ldisc_lock to guard against ldisc races
+ */
+
+int tty_unregister_ldisc(int disc)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ if (disc < N_TTY || disc >= NR_LDISCS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ if (tty_ldiscs[disc]->refcount)
+ ret = -EBUSY;
+ else
+ tty_ldiscs[disc] = NULL;
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(tty_unregister_ldisc);
+
+
+/**
+ * tty_ldisc_try_get - try and reference an ldisc
+ * @disc: ldisc number
+ * @ld: tty ldisc structure to complete
+ *
+ * Attempt to open and lock a line discipline into place. Return
+ * the line discipline refcounted and assigned in ld. On an error
+ * report the error code back
+ */
+
+static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld)
+{
+ unsigned long flags;
+ struct tty_ldisc_ops *ldops;
+ int err = -EINVAL;
+
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ ld->ops = NULL;
+ ldops = tty_ldiscs[disc];
+ /* Check the entry is defined */
+ if (ldops) {
+ /* If the module is being unloaded we can't use it */
+ if (!try_module_get(ldops->owner))
+ err = -EAGAIN;
+ else {
+ /* lock it */
+ ldops->refcount++;
+ ld->ops = ldops;
+ err = 0;
+ }
+ }
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ return err;
+}
+
+/**
+ * tty_ldisc_get - take a reference to an ldisc
+ * @disc: ldisc number
+ * @ld: tty line discipline structure to use
+ *
+ * Takes a reference to a line discipline. Deals with refcounts and
+ * module locking counts. Returns NULL if the discipline is not available.
+ * Returns a pointer to the discipline and bumps the ref count if it is
+ * available
+ *
+ * Locking:
+ * takes tty_ldisc_lock to guard against ldisc races
+ */
+
+static int tty_ldisc_get(int disc, struct tty_ldisc *ld)
+{
+ int err;
+
+ if (disc < N_TTY || disc >= NR_LDISCS)
+ return -EINVAL;
+ err = tty_ldisc_try_get(disc, ld);
+ if (err == -EAGAIN) {
+ request_module("tty-ldisc-%d", disc);
+ err = tty_ldisc_try_get(disc, ld);
+ }
+ return err;
+}
+
+/**
+ * tty_ldisc_put - drop ldisc reference
+ * @disc: ldisc number
+ *
+ * Drop a reference to a line discipline. Manage refcounts and
+ * module usage counts
+ *
+ * Locking:
+ * takes tty_ldisc_lock to guard against ldisc races
+ */
+
+static void tty_ldisc_put(struct tty_ldisc_ops *ld)
+{
+ unsigned long flags;
+ int disc = ld->num;
+
+ BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
+
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ ld = tty_ldiscs[disc];
+ BUG_ON(ld->refcount == 0);
+ ld->refcount--;
+ module_put(ld->owner);
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+}
+
+static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
+{
+ return (*pos < NR_LDISCS) ? pos : NULL;
+}
+
+static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ (*pos)++;
+ return (*pos < NR_LDISCS) ? pos : NULL;
+}
+
+static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
+{
+}
+
+static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
+{
+ int i = *(loff_t *)v;
+ struct tty_ldisc ld;
+
+ if (tty_ldisc_get(i, &ld) < 0)
+ return 0;
+ seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i);
+ tty_ldisc_put(ld.ops);
+ return 0;
+}
+
+static const struct seq_operations tty_ldiscs_seq_ops = {
+ .start = tty_ldiscs_seq_start,
+ .next = tty_ldiscs_seq_next,
+ .stop = tty_ldiscs_seq_stop,
+ .show = tty_ldiscs_seq_show,
+};
+
+static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &tty_ldiscs_seq_ops);
+}
+
+const struct file_operations tty_ldiscs_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = proc_tty_ldiscs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+/**
+ * tty_ldisc_assign - set ldisc on a tty
+ * @tty: tty to assign
+ * @ld: line discipline
+ *
+ * Install an instance of a line discipline into a tty structure. The
+ * ldisc must have a reference count above zero to ensure it remains/
+ * The tty instance refcount starts at zero.
+ *
+ * Locking:
+ * Caller must hold references
+ */
+
+static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
+{
+ ld->refcount = 0;
+ tty->ldisc = *ld;
+}
+
+/**
+ * tty_ldisc_try - internal helper
+ * @tty: the tty
+ *
+ * Make a single attempt to grab and bump the refcount on
+ * the tty ldisc. Return 0 on failure or 1 on success. This is
+ * used to implement both the waiting and non waiting versions
+ * of tty_ldisc_ref
+ *
+ * Locking: takes tty_ldisc_lock
+ */
+
+static int tty_ldisc_try(struct tty_struct *tty)
+{
+ unsigned long flags;
+ struct tty_ldisc *ld;
+ int ret = 0;
+
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ ld = &tty->ldisc;
+ if (test_bit(TTY_LDISC, &tty->flags)) {
+ ld->refcount++;
+ ret = 1;
+ }
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ return ret;
+}
+
+/**
+ * tty_ldisc_ref_wait - wait for the tty ldisc
+ * @tty: tty device
+ *
+ * Dereference the line discipline for the terminal and take a
+ * reference to it. If the line discipline is in flux then
+ * wait patiently until it changes.
+ *
+ * Note: Must not be called from an IRQ/timer context. The caller
+ * must also be careful not to hold other locks that will deadlock
+ * against a discipline change, such as an existing ldisc reference
+ * (which we check for)
+ *
+ * Locking: call functions take tty_ldisc_lock
+ */
+
+struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
+{
+ /* wait_event is a macro */
+ wait_event(tty_ldisc_wait, tty_ldisc_try(tty));
+ if (tty->ldisc.refcount == 0)
+ printk(KERN_ERR "tty_ldisc_ref_wait\n");
+ return &tty->ldisc;
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
+
+/**
+ * tty_ldisc_ref - get the tty ldisc
+ * @tty: tty device
+ *
+ * Dereference the line discipline for the terminal and take a
+ * reference to it. If the line discipline is in flux then
+ * return NULL. Can be called from IRQ and timer functions.
+ *
+ * Locking: called functions take tty_ldisc_lock
+ */
+
+struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
+{
+ if (tty_ldisc_try(tty))
+ return &tty->ldisc;
+ return NULL;
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_ref);
+
+/**
+ * tty_ldisc_deref - free a tty ldisc reference
+ * @ld: reference to free up
+ *
+ * Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May
+ * be called in IRQ context.
+ *
+ * Locking: takes tty_ldisc_lock
+ */
+
+void tty_ldisc_deref(struct tty_ldisc *ld)
+{
+ unsigned long flags;
+
+ BUG_ON(ld == NULL);
+
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ if (ld->refcount == 0)
+ printk(KERN_ERR "tty_ldisc_deref: no references.\n");
+ else
+ ld->refcount--;
+ if (ld->refcount == 0)
+ wake_up(&tty_ldisc_wait);
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_deref);
+
+/**
+ * tty_ldisc_enable - allow ldisc use
+ * @tty: terminal to activate ldisc on
+ *
+ * Set the TTY_LDISC flag when the line discipline can be called
+ * again. Do necessary wakeups for existing sleepers.
+ *
+ * Note: nobody should set this bit except via this function. Clearing
+ * directly is allowed.
+ */
+
+void tty_ldisc_enable(struct tty_struct *tty)
+{
+ set_bit(TTY_LDISC, &tty->flags);
+ wake_up(&tty_ldisc_wait);
+}
+
+/**
+ * tty_set_termios_ldisc - set ldisc field
+ * @tty: tty structure
+ * @num: line discipline number
+ *
+ * This is probably overkill for real world processors but
+ * they are not on hot paths so a little discipline won't do
+ * any harm.
+ *
+ * Locking: takes termios_mutex
+ */
+
+static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
+{
+ mutex_lock(&tty->termios_mutex);
+ tty->termios->c_line = num;
+ mutex_unlock(&tty->termios_mutex);
+}
+
+
+/**
+ * tty_ldisc_restore - helper for tty ldisc change
+ * @tty: tty to recover
+ * @old: previous ldisc
+ *
+ * Restore the previous line discipline or N_TTY when a line discipline
+ * change fails due to an open error
+ */
+
+static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
+{
+ char buf[64];
+ struct tty_ldisc new_ldisc;
+
+ /* There is an outstanding reference here so this is safe */
+ tty_ldisc_get(old->ops->num, old);
+ tty_ldisc_assign(tty, old);
+ tty_set_termios_ldisc(tty, old->ops->num);
+ if (old->ops->open && (old->ops->open(tty) < 0)) {
+ tty_ldisc_put(old->ops);
+ /* This driver is always present */
+ if (tty_ldisc_get(N_TTY, &new_ldisc) < 0)
+ panic("n_tty: get");
+ tty_ldisc_assign(tty, &new_ldisc);
+ tty_set_termios_ldisc(tty, N_TTY);
+ if (new_ldisc.ops->open) {
+ int r = new_ldisc.ops->open(tty);
+ if (r < 0)
+ panic("Couldn't open N_TTY ldisc for "
+ "%s --- error %d.",
+ tty_name(tty, buf), r);
+ }
+ }
+}
+
+/**
+ * tty_set_ldisc - set line discipline
+ * @tty: the terminal to set
+ * @ldisc: the line discipline
+ *
+ * Set the discipline of a tty line. Must be called from a process
+ * context.
+ *
+ * Locking: takes tty_ldisc_lock.
+ * called functions take termios_mutex
+ */
+
+int tty_set_ldisc(struct tty_struct *tty, int ldisc)
+{
+ int retval;
+ struct tty_ldisc o_ldisc, new_ldisc;
+ int work;
+ unsigned long flags;
+ struct tty_struct *o_tty;
+
+restart:
+ /* This is a bit ugly for now but means we can break the 'ldisc
+ is part of the tty struct' assumption later */
+ retval = tty_ldisc_get(ldisc, &new_ldisc);
+ if (retval)
+ return retval;
+
+ /*
+ * Problem: What do we do if this blocks ?
+ */
+
+ tty_wait_until_sent(tty, 0);
+
+ if (tty->ldisc.ops->num == ldisc) {
+ tty_ldisc_put(new_ldisc.ops);
+ return 0;
+ }
+
+ /*
+ * No more input please, we are switching. The new ldisc
+ * will update this value in the ldisc open function
+ */
+
+ tty->receive_room = 0;
+
+ o_ldisc = tty->ldisc;
+ o_tty = tty->link;
+
+ /*
+ * Make sure we don't change while someone holds a
+ * reference to the line discipline. The TTY_LDISC bit
+ * prevents anyone taking a reference once it is clear.
+ * We need the lock to avoid racing reference takers.
+ */
+
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
+ if (tty->ldisc.refcount) {
+ /* Free the new ldisc we grabbed. Must drop the lock
+ first. */
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ tty_ldisc_put(o_ldisc.ops);
+ /*
+ * There are several reasons we may be busy, including
+ * random momentary I/O traffic. We must therefore
+ * retry. We could distinguish between blocking ops
+ * and retries if we made tty_ldisc_wait() smarter.
+ * That is up for discussion.
+ */
+ if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
+ return -ERESTARTSYS;
+ goto restart;
+ }
+ if (o_tty && o_tty->ldisc.refcount) {
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ tty_ldisc_put(o_tty->ldisc.ops);
+ if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
+ return -ERESTARTSYS;
+ goto restart;
+ }
+ }
+ /*
+ * If the TTY_LDISC bit is set, then we are racing against
+ * another ldisc change
+ */
+ if (!test_bit(TTY_LDISC, &tty->flags)) {
+ struct tty_ldisc *ld;
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ tty_ldisc_put(new_ldisc.ops);
+ ld = tty_ldisc_ref_wait(tty);
+ tty_ldisc_deref(ld);
+ goto restart;
+ }
+
+ clear_bit(TTY_LDISC, &tty->flags);
+ if (o_tty)
+ clear_bit(TTY_LDISC, &o_tty->flags);
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+ /*
+ * From this point on we know nobody has an ldisc
+ * usage reference, nor can they obtain one until
+ * we say so later on.
+ */
+
+ work = cancel_delayed_work(&tty->buf.work);
+ /*
+ * Wait for ->hangup_work and ->buf.work handlers to terminate
+ * MUST NOT hold locks here.
+ */
+ flush_scheduled_work();
+ /* Shutdown the current discipline. */
+ if (o_ldisc.ops->close)
+ (o_ldisc.ops->close)(tty);
+
+ /* Now set up the new line discipline. */
+ tty_ldisc_assign(tty, &new_ldisc);
+ tty_set_termios_ldisc(tty, ldisc);
+ if (new_ldisc.ops->open)
+ retval = (new_ldisc.ops->open)(tty);
+ if (retval < 0) {
+ tty_ldisc_put(new_ldisc.ops);
+ tty_ldisc_restore(tty, &o_ldisc);
+ }
+ /* At this point we hold a reference to the new ldisc and a
+ a reference to the old ldisc. If we ended up flipping back
+ to the existing ldisc we have two references to it */
+
+ if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc)
+ tty->ops->set_ldisc(tty);
+
+ tty_ldisc_put(o_ldisc.ops);
+
+ /*
+ * Allow ldisc referencing to occur as soon as the driver
+ * ldisc callback completes.
+ */
+
+ tty_ldisc_enable(tty);
+ if (o_tty)
+ tty_ldisc_enable(o_tty);
+
+ /* Restart it in case no characters kick it off. Safe if
+ already running */
+ if (work)
+ schedule_delayed_work(&tty->buf.work, 1);
+ return retval;
+}
+
+
+/**
+ * tty_ldisc_setup - open line discipline
+ * @tty: tty being shut down
+ * @o_tty: pair tty for pty/tty pairs
+ *
+ * Called during the initial open of a tty/pty pair in order to set up the
+ * line discplines and bind them to the tty.
+ */
+
+int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
+{
+ struct tty_ldisc *ld = &tty->ldisc;
+ int retval;
+
+ if (ld->ops->open) {
+ retval = (ld->ops->open)(tty);
+ if (retval)
+ return retval;
+ }
+ if (o_tty && o_tty->ldisc.ops->open) {
+ retval = (o_tty->ldisc.ops->open)(o_tty);
+ if (retval) {
+ if (ld->ops->close)
+ (ld->ops->close)(tty);
+ return retval;
+ }
+ tty_ldisc_enable(o_tty);
+ }
+ tty_ldisc_enable(tty);
+ return 0;
+}
+
+/**
+ * tty_ldisc_release - release line discipline
+ * @tty: tty being shut down
+ * @o_tty: pair tty for pty/tty pairs
+ *
+ * Called during the final close of a tty/pty pair in order to shut down the
+ * line discpline layer.
+ */
+
+void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
+{
+ unsigned long flags;
+ struct tty_ldisc ld;
+ /*
+ * Prevent flush_to_ldisc() from rescheduling the work for later. Then
+ * kill any delayed work. As this is the final close it does not
+ * race with the set_ldisc code path.
+ */
+ clear_bit(TTY_LDISC, &tty->flags);
+ cancel_delayed_work(&tty->buf.work);
+
+ /*
+ * Wait for ->hangup_work and ->buf.work handlers to terminate
+ */
+
+ flush_scheduled_work();
+
+ /*
+ * Wait for any short term users (we know they are just driver
+ * side waiters as the file is closing so user count on the file
+ * side is zero.
+ */
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ while (tty->ldisc.refcount) {
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0);
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ }
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ /*
+ * Shutdown the current line discipline, and reset it to N_TTY.
+ *
+ * FIXME: this MUST get fixed for the new reflocking
+ */
+ if (tty->ldisc.ops->close)
+ (tty->ldisc.ops->close)(tty);
+ tty_ldisc_put(tty->ldisc.ops);
+
+ /*
+ * Switch the line discipline back
+ */
+ WARN_ON(tty_ldisc_get(N_TTY, &ld));
+ tty_ldisc_assign(tty, &ld);
+ tty_set_termios_ldisc(tty, N_TTY);
+ if (o_tty) {
+ /* FIXME: could o_tty be in setldisc here ? */
+ clear_bit(TTY_LDISC, &o_tty->flags);
+ if (o_tty->ldisc.ops->close)
+ (o_tty->ldisc.ops->close)(o_tty);
+ tty_ldisc_put(o_tty->ldisc.ops);
+ WARN_ON(tty_ldisc_get(N_TTY, &ld));
+ tty_ldisc_assign(o_tty, &ld);
+ tty_set_termios_ldisc(o_tty, N_TTY);
+ }
+}
+
+/**
+ * tty_ldisc_init - ldisc setup for new tty
+ * @tty: tty being allocated
+ *
+ * Set up the line discipline objects for a newly allocated tty. Note that
+ * the tty structure is not completely set up when this call is made.
+ */
+
+void tty_ldisc_init(struct tty_struct *tty)
+{
+ struct tty_ldisc ld;
+ if (tty_ldisc_get(N_TTY, &ld) < 0)
+ panic("n_tty: init_tty");
+ tty_ldisc_assign(tty, &ld);
+}
+
+void tty_ldisc_begin(void)
+{
+ /* Setup the default TTY line discipline. */
+ (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
+}
static irqreturn_t scc_stat_int(int irq, void *data);
static irqreturn_t scc_spcond_int(int irq, void *data);
static void scc_setsignals(struct scc_port *port, int dtr, int rts);
-static void scc_break_ctl(struct tty_struct *tty, int break_state);
+static int scc_break_ctl(struct tty_struct *tty, int break_state);
static struct tty_driver *scc_driver;
}
-static void scc_break_ctl(struct tty_struct *tty, int break_state)
+static int scc_break_ctl(struct tty_struct *tty, int break_state)
{
struct scc_port *port = (struct scc_port *)tty->driver_data;
unsigned long flags;
SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK,
break_state ? TCR_SEND_BREAK : 0);
local_irq_restore(flags);
+ return 0;
}
will be called pca953x.
config GPIO_PCF857X
- tristate "PCF857x, PCA857x, and PCA967x I2C GPIO expanders"
+ tristate "PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders"
depends on I2C
help
Say yes here to provide access to most "quasi-bidirectional" I2C
some of them. Compatible models include:
8 bits: pcf8574, pcf8574a, pca8574, pca8574a,
- pca9670, pca9672, pca9674, pca9674a
+ pca9670, pca9672, pca9674, pca9674a,
+ max7328, max7329
16 bits: pcf8575, pcf8575c, pca8575,
pca9671, pca9673, pca9675
comment "SPI GPIO expanders:"
+config GPIO_MAX7301
+ tristate "Maxim MAX7301 GPIO expander"
+ depends on SPI_MASTER
+ help
+ gpio driver for Maxim MAX7301 SPI GPIO expander.
+
config GPIO_MCP23S08
tristate "Microchip MCP23S08 I/O expander"
depends on SPI_MASTER
obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o
+obj-$(CONFIG_GPIO_MAX7301) += max7301.o
obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o
obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
--- /dev/null
+/**
+ * drivers/gpio/max7301.c
+ *
+ * Copyright (C) 2006 Juergen Beisert, Pengutronix
+ * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The Maxim's MAX7301 device is an SPI driven GPIO expander. There are
+ * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
+ * details
+ * Note:
+ * - DIN must be stable at the rising edge of clock.
+ * - when writing:
+ * - always clock in 16 clocks at once
+ * - at DIN: D15 first, D0 last
+ * - D0..D7 = databyte, D8..D14 = commandbyte
+ * - D15 = low -> write command
+ * - when reading
+ * - always clock in 16 clocks at once
+ * - at DIN: D15 first, D0 last
+ * - D0..D7 = dummy, D8..D14 = register address
+ * - D15 = high -> read command
+ * - raise CS and assert it again
+ * - always clock in 16 clocks at once
+ * - at DOUT: D15 first, D0 last
+ * - D0..D7 contains the data from the first cycle
+ *
+ * The driver exports a standard gpiochip interface
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/max7301.h>
+#include <linux/gpio.h>
+
+#define DRIVER_NAME "max7301"
+
+/*
+ * Pin configurations, see MAX7301 datasheet page 6
+ */
+#define PIN_CONFIG_MASK 0x03
+#define PIN_CONFIG_IN_PULLUP 0x03
+#define PIN_CONFIG_IN_WO_PULLUP 0x02
+#define PIN_CONFIG_OUT 0x01
+
+#define PIN_NUMBER 28
+
+
+/*
+ * Some registers must be read back to modify.
+ * To save time we cache them here in memory
+ */
+struct max7301 {
+ struct mutex lock;
+ u8 port_config[8]; /* field 0 is unused */
+ u32 out_level; /* cached output levels */
+ struct gpio_chip chip;
+ struct spi_device *spi;
+};
+
+/**
+ * max7301_write - Write a new register content
+ * @spi: The SPI device
+ * @reg: Register offset
+ * @val: Value to write
+ *
+ * A write to the MAX7301 means one message with one transfer
+ *
+ * Returns 0 if successful or a negative value on error
+ */
+static int max7301_write(struct spi_device *spi, unsigned int reg, unsigned int val)
+{
+ u16 word = ((reg & 0x7F) << 8) | (val & 0xFF);
+ return spi_write(spi, (const u8 *)&word, sizeof(word));
+}
+
+/**
+ * max7301_read - Read back register content
+ * @spi: The SPI device
+ * @reg: Register offset
+ *
+ * A read from the MAX7301 means two transfers; here, one message each
+ *
+ * Returns positive 8 bit value from device if successful or a
+ * negative value on error
+ */
+static int max7301_read(struct spi_device *spi, unsigned int reg)
+{
+ int ret;
+ u16 word;
+
+ word = 0x8000 | (reg << 8);
+ ret = spi_write(spi, (const u8 *)&word, sizeof(word));
+ if (ret)
+ return ret;
+ /*
+ * This relies on the fact, that a transfer with NULL tx_buf shifts out
+ * zero bytes (=NOOP for MAX7301)
+ */
+ ret = spi_read(spi, (u8 *)&word, sizeof(word));
+ if (ret)
+ return ret;
+ return word & 0xff;
+}
+
+static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+ u8 *config;
+ int ret;
+
+ /* First 4 pins are unused in the controller */
+ offset += 4;
+
+ config = &ts->port_config[offset >> 2];
+
+ mutex_lock(&ts->lock);
+
+ /* Standard GPIO API doesn't support pull-ups, has to be extended.
+ * Hard-coding no pollup for now. */
+ *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
+
+ ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
+
+ mutex_unlock(&ts->lock);
+
+ return ret;
+}
+
+static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
+{
+ if (value) {
+ ts->out_level |= 1 << offset;
+ return max7301_write(ts->spi, 0x20 + offset, 0x01);
+ } else {
+ ts->out_level &= ~(1 << offset);
+ return max7301_write(ts->spi, 0x20 + offset, 0x00);
+ }
+}
+
+static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+ u8 *config;
+ int ret;
+
+ /* First 4 pins are unused in the controller */
+ offset += 4;
+
+ config = &ts->port_config[offset >> 2];
+
+ mutex_lock(&ts->lock);
+
+ *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
+
+ ret = __max7301_set(ts, offset, value);
+
+ if (!ret)
+ ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
+
+ mutex_unlock(&ts->lock);
+
+ return ret;
+}
+
+static int max7301_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+ int config, level = -EINVAL;
+
+ /* First 4 pins are unused in the controller */
+ offset += 4;
+
+ mutex_lock(&ts->lock);
+
+ config = (ts->port_config[offset >> 2] >> ((offset & 3) * 2)) & 3;
+
+ switch (config) {
+ case 1:
+ /* Output: return cached level */
+ level = !!(ts->out_level & (1 << offset));
+ break;
+ case 2:
+ case 3:
+ /* Input: read out */
+ level = max7301_read(ts->spi, 0x20 + offset) & 0x01;
+ }
+ mutex_unlock(&ts->lock);
+
+ return level;
+}
+
+static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+
+ /* First 4 pins are unused in the controller */
+ offset += 4;
+
+ mutex_lock(&ts->lock);
+
+ __max7301_set(ts, offset, value);
+
+ mutex_unlock(&ts->lock);
+}
+
+static int __devinit max7301_probe(struct spi_device *spi)
+{
+ struct max7301 *ts;
+ struct max7301_platform_data *pdata;
+ int i, ret;
+
+ pdata = spi->dev.platform_data;
+ if (!pdata || !pdata->base)
+ return -ENODEV;
+
+ /*
+ * bits_per_word cannot be configured in platform data
+ */
+ spi->bits_per_word = 16;
+
+ ret = spi_setup(spi);
+ if (ret < 0)
+ return ret;
+
+ ts = kzalloc(sizeof(struct max7301), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ mutex_init(&ts->lock);
+
+ dev_set_drvdata(&spi->dev, ts);
+
+ /* Power up the chip and disable IRQ output */
+ max7301_write(spi, 0x04, 0x01);
+
+ ts->spi = spi;
+
+ ts->chip.label = DRIVER_NAME,
+
+ ts->chip.direction_input = max7301_direction_input;
+ ts->chip.get = max7301_get;
+ ts->chip.direction_output = max7301_direction_output;
+ ts->chip.set = max7301_set;
+
+ ts->chip.base = pdata->base;
+ ts->chip.ngpio = PIN_NUMBER;
+ ts->chip.can_sleep = 1;
+ ts->chip.dev = &spi->dev;
+ ts->chip.owner = THIS_MODULE;
+
+ ret = gpiochip_add(&ts->chip);
+ if (ret)
+ goto exit_destroy;
+
+ /*
+ * tristate all pins in hardware and cache the
+ * register values for later use.
+ */
+ for (i = 1; i < 8; i++) {
+ int j;
+ /* 0xAA means input with internal pullup disabled */
+ max7301_write(spi, 0x08 + i, 0xAA);
+ ts->port_config[i] = 0xAA;
+ for (j = 0; j < 4; j++) {
+ int idx = ts->chip.base + (i - 1) * 4 + j;
+ ret = gpio_direction_input(idx);
+ if (ret)
+ goto exit_remove;
+ gpio_free(idx);
+ }
+ }
+ return ret;
+
+exit_remove:
+ gpiochip_remove(&ts->chip);
+exit_destroy:
+ dev_set_drvdata(&spi->dev, NULL);
+ mutex_destroy(&ts->lock);
+ kfree(ts);
+ return ret;
+}
+
+static int max7301_remove(struct spi_device *spi)
+{
+ struct max7301 *ts;
+ int ret;
+
+ ts = dev_get_drvdata(&spi->dev);
+ if (ts == NULL)
+ return -ENODEV;
+
+ dev_set_drvdata(&spi->dev, NULL);
+
+ /* Power down the chip and disable IRQ output */
+ max7301_write(spi, 0x04, 0x00);
+
+ ret = gpiochip_remove(&ts->chip);
+ if (!ret) {
+ mutex_destroy(&ts->lock);
+ kfree(ts);
+ } else
+ dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
+ ret);
+
+ return ret;
+}
+
+static struct spi_driver max7301_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = max7301_probe,
+ .remove = __devexit_p(max7301_remove),
+};
+
+static int __init max7301_init(void)
+{
+ return spi_register_driver(&max7301_driver);
+}
+
+static void __exit max7301_exit(void)
+{
+ spi_unregister_driver(&max7301_driver);
+}
+
+module_init(max7301_init);
+module_exit(max7301_exit);
+
+MODULE_AUTHOR("Juergen Beisert");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MAX7301 SPI based GPIO-Expander");
{ "pca9671", 16 },
{ "pca9673", 16 },
{ "pca9675", 16 },
+ { "max7328", 8 },
+ { "max7329", 8 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pcf857x_id);
struct pcf857x {
struct gpio_chip chip;
struct i2c_client *client;
+ struct mutex lock; /* protect 'out' */
unsigned out; /* software latch */
};
static int pcf857x_input8(struct gpio_chip *chip, unsigned offset)
{
struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
+ int status;
+ mutex_lock(&gpio->lock);
gpio->out |= (1 << offset);
- return i2c_smbus_write_byte(gpio->client, gpio->out);
+ status = i2c_smbus_write_byte(gpio->client, gpio->out);
+ mutex_unlock(&gpio->lock);
+
+ return status;
}
static int pcf857x_get8(struct gpio_chip *chip, unsigned offset)
{
struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
unsigned bit = 1 << offset;
+ int status;
+ mutex_lock(&gpio->lock);
if (value)
gpio->out |= bit;
else
gpio->out &= ~bit;
- return i2c_smbus_write_byte(gpio->client, gpio->out);
+ status = i2c_smbus_write_byte(gpio->client, gpio->out);
+ mutex_unlock(&gpio->lock);
+
+ return status;
}
static void pcf857x_set8(struct gpio_chip *chip, unsigned offset, int value)
static int pcf857x_input16(struct gpio_chip *chip, unsigned offset)
{
struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
+ int status;
+ mutex_lock(&gpio->lock);
gpio->out |= (1 << offset);
- return i2c_write_le16(gpio->client, gpio->out);
+ status = i2c_write_le16(gpio->client, gpio->out);
+ mutex_unlock(&gpio->lock);
+
+ return status;
}
static int pcf857x_get16(struct gpio_chip *chip, unsigned offset)
{
struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
unsigned bit = 1 << offset;
+ int status;
+ mutex_lock(&gpio->lock);
if (value)
gpio->out |= bit;
else
gpio->out &= ~bit;
- return i2c_write_le16(gpio->client, gpio->out);
+ status = i2c_write_le16(gpio->client, gpio->out);
+ mutex_unlock(&gpio->lock);
+
+ return status;
}
static void pcf857x_set16(struct gpio_chip *chip, unsigned offset, int value)
if (!gpio)
return -ENOMEM;
+ mutex_init(&gpio->lock);
+
gpio->chip.base = pdata->gpio_base;
gpio->chip.can_sleep = 1;
gpio->chip.owner = THIS_MODULE;
#endif
}
-static void capinc_tty_break_ctl(struct tty_struct *tty, int state)
+static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
{
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
#endif
+ return 0;
}
static void capinc_tty_flush_buffer(struct tty_struct *tty)
* the interrupt is enabled. Delays are necessary to
* allow register changes to become visible.
*/
- spin_lock_irqsave(&up->port.lock, flags);
+ spin_lock(&up->port.lock);
+ if (up->port.flags & UPF_SHARE_IRQ)
+ disable_irq_nosync(up->port.irq);
wait_for_xmitr(up, UART_LSR_THRE);
serial_out_sync(up, UART_IER, UART_IER_THRI);
iir = serial_in(up, UART_IIR);
serial_out(up, UART_IER, 0);
- spin_unlock_irqrestore(&up->port.lock, flags);
+ if (up->port.flags & UPF_SHARE_IRQ)
+ enable_irq(up->port.irq);
+ spin_unlock(&up->port.lock);
/*
* If the interrupt is not reasserted, setup a timer to
int i;
unsigned char ch;
u8 *cp;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
cbd_t __iomem *bdp;
u16 status;
static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
{
short int count, rcv_buff;
- struct tty_struct *tty = icom_port->uart_port.info->tty;
+ struct tty_struct *tty = icom_port->uart_port.info->port.tty;
unsigned short int status;
struct uart_icount *icount;
unsigned long offset;
{
struct s3c24xx_uart_port *ourport = dev_id;
struct uart_port *port = &ourport->port;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned int ufcon, ch, flag, ufstat, uerstat;
int max_count = 64;
return ret;
}
-static void uart_break_ctl(struct tty_struct *tty, int break_state)
+static int uart_break_ctl(struct tty_struct *tty, int break_state)
{
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->port;
port->ops->break_ctl(port, break_state);
mutex_unlock(&state->mutex);
+ return 0;
}
static int uart_do_autoconfig(struct uart_state *state)
static inline void
receive_chars(struct uart_txx9_port *up, unsigned int *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned char ch;
unsigned int disr = *status;
int max_count = 256;
tasklet_schedule(&acm->urb_task);
}
-static void acm_tty_break_ctl(struct tty_struct *tty, int state)
+static int acm_tty_break_ctl(struct tty_struct *tty, int state)
{
struct acm *acm = tty->driver_data;
+ int retval;
if (!ACM_READY(acm))
- return;
- if (acm_send_break(acm, state ? 0xffff : 0))
+ return -EINVAL;
+ retval = acm_send_break(acm, state ? 0xffff : 0);
+ if (retval < 0)
dbg("send break failed");
+ return retval;
}
static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file)
* 64 bytes, to ensure I do not get throttled.
* Ask USB mailing list for better aproach.
*/
- tty = port->tty;
+ tty = port->port.tty;
if (!tty) {
schedule_work(&priv->rx_work);
}
}
-static int aircable_write_room(struct usb_serial_port *port)
+static int aircable_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct aircable_private *priv = usb_get_serial_port_data(port);
return serial_buf_data_avail(priv->tx_buf);
}
-static int aircable_write(struct usb_serial_port *port,
+static int aircable_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *source, int count)
{
struct aircable_private *priv = usb_get_serial_port_data(port);
if (status) {
dbg("%s - urb status = %d", __func__, status);
- if (!port->open_count) {
+ if (!port->port.count) {
dbg("%s - port is closed, exiting.", __func__);
return;
}
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, urb->transfer_buffer);
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
if (urb->actual_length <= 2) {
/* This is an incomplete package */
}
/* Schedule the next read _if_ we are still open */
- if (port->open_count) {
+ if (port->port.count) {
usb_fill_bulk_urb(port->read_urb, port->serial->dev,
usb_rcvbulkpipe(port->serial->dev,
port->bulk_in_endpointAddress),
}
/* Based on ftdi_sio.c throttle */
-static void aircable_throttle(struct usb_serial_port *port)
+static void aircable_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct aircable_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
}
/* Based on ftdi_sio.c unthrottle */
-static void aircable_unthrottle(struct usb_serial_port *port)
+static void aircable_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct aircable_private *priv = usb_get_serial_port_data(port);
int actually_throttled;
unsigned long flags;
--- /dev/null
+/*
+ * AirPrime CDMA Wireless Serial USB driver
+ *
+ * Copyright (C) 2005-2006 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+static struct usb_device_id id_table [] = {
+ { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
+ { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+#define URB_TRANSFER_BUFFER_SIZE 4096
+#define NUM_READ_URBS 4
+#define NUM_WRITE_URBS 4
+#define NUM_BULK_EPS 3
+#define MAX_BULK_EPS 6
+
+/* if overridden by the user, then use their value for the size of the
+ * read and write urbs, and the number of endpoints */
+static int buffer_size = URB_TRANSFER_BUFFER_SIZE;
+static int endpoints = NUM_BULK_EPS;
+static int debug;
+struct airprime_private {
+ spinlock_t lock;
+ int outstanding_urbs;
+ int throttled;
+ struct urb *read_urbp[NUM_READ_URBS];
+
+ /* Settings for the port */
+ int rts_state; /* Handshaking pins (outputs) */
+ int dtr_state;
+ int cts_state; /* Handshaking pins (inputs) */
+ int dsr_state;
+ int dcd_state;
+ int ri_state;
+};
+
+static int airprime_send_setup(struct usb_serial_port *port)
+{
+ struct usb_serial *serial = port->serial;
+ struct airprime_private *priv;
+
+ dbg("%s", __func__);
+
+ if (port->number != 0)
+ return 0;
+
+ priv = usb_get_serial_port_data(port);
+
+ if (port->port.tty) {
+ int val = 0;
+ if (priv->dtr_state)
+ val |= 0x01;
+ if (priv->rts_state)
+ val |= 0x02;
+
+ return usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ 0x22, 0x21, val, 0, NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
+ }
+
+ return 0;
+}
+
+static void airprime_read_bulk_callback(struct urb *urb)
+{
+ struct usb_serial_port *port = urb->context;
+ unsigned char *data = urb->transfer_buffer;
+ struct tty_struct *tty;
+ int result;
+ int status = urb->status;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ if (status) {
+ dbg("%s - nonzero read bulk status received: %d",
+ __func__, status);
+ return;
+ }
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
+
+ tty = port->port.tty;
+ if (tty && urb->actual_length) {
+ tty_insert_flip_string(tty, data, urb->actual_length);
+ tty_flip_buffer_push(tty);
+ }
+
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result)
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
+ return;
+}
+
+static void airprime_write_bulk_callback(struct urb *urb)
+{
+ struct usb_serial_port *port = urb->context;
+ struct airprime_private *priv = usb_get_serial_port_data(port);
+ int status = urb->status;
+ unsigned long flags;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /* free up the transfer buffer, as usb_free_urb() does not do this */
+ kfree(urb->transfer_buffer);
+
+ if (status)
+ dbg("%s - nonzero write bulk status received: %d",
+ __func__, status);
+ spin_lock_irqsave(&priv->lock, flags);
+ --priv->outstanding_urbs;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ usb_serial_port_softint(port);
+}
+
+static int airprime_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct airprime_private *priv = usb_get_serial_port_data(port);
+ struct usb_serial *serial = port->serial;
+ struct urb *urb;
+ char *buffer = NULL;
+ int i;
+ int result = 0;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /* initialize our private data structure if it isn't already created */
+ if (!priv) {
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ result = -ENOMEM;
+ goto out;
+ }
+ spin_lock_init(&priv->lock);
+ usb_set_serial_port_data(port, priv);
+ }
+
+ /* Set some sane defaults */
+ priv->rts_state = 1;
+ priv->dtr_state = 1;
+
+ for (i = 0; i < NUM_READ_URBS; ++i) {
+ buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!buffer) {
+ dev_err(&port->dev, "%s - out of memory.\n",
+ __func__);
+ result = -ENOMEM;
+ goto errout;
+ }
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ kfree(buffer);
+ dev_err(&port->dev, "%s - no more urbs?\n",
+ __func__);
+ result = -ENOMEM;
+ goto errout;
+ }
+ usb_fill_bulk_urb(urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->bulk_out_endpointAddress),
+ buffer, buffer_size,
+ airprime_read_bulk_callback, port);
+ result = usb_submit_urb(urb, GFP_KERNEL);
+ if (result) {
+ usb_free_urb(urb);
+ kfree(buffer);
+ dev_err(&port->dev,
+ "%s - failed submitting read urb %d for port %d, error %d\n",
+ __func__, i, port->number, result);
+ goto errout;
+ }
+ /* remember this urb so we can kill it when the
+ port is closed */
+ priv->read_urbp[i] = urb;
+ }
+
+ airprime_send_setup(port);
+
+ goto out;
+
+ errout:
+ /* some error happened, cancel any submitted urbs and clean up
+ anything that got allocated successfully */
+
+ while (i-- != 0) {
+ urb = priv->read_urbp[i];
+ buffer = urb->transfer_buffer;
+ usb_kill_urb(urb);
+ usb_free_urb(urb);
+ kfree(buffer);
+ }
+
+ out:
+ return result;
+}
+
+static void airprime_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
+{
+ struct airprime_private *priv = usb_get_serial_port_data(port);
+ int i;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ priv->rts_state = 0;
+ priv->dtr_state = 0;
+
+ mutex_lock(&port->serial->disc_mutex);
+ if (!port->serial->disconnected)
+ airprime_send_setup(port);
+ mutex_unlock(&port->serial->disc_mutex);
+
+ for (i = 0; i < NUM_READ_URBS; ++i) {
+ usb_kill_urb(priv->read_urbp[i]);
+ kfree(priv->read_urbp[i]->transfer_buffer);
+ usb_free_urb(priv->read_urbp[i]);
+ }
+
+ /* free up private structure */
+ kfree(priv);
+ usb_set_serial_port_data(port, NULL);
+}
+
+static int airprime_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
+{
+ struct airprime_private *priv = usb_get_serial_port_data(port);
+ struct usb_serial *serial = port->serial;
+ struct urb *urb;
+ unsigned char *buffer;
+ unsigned long flags;
+ int status;
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->outstanding_urbs > NUM_WRITE_URBS) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dbg("%s - write limit hit\n", __func__);
+ return 0;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+ buffer = kmalloc(count, GFP_ATOMIC);
+ if (!buffer) {
+ dev_err(&port->dev, "out of memory\n");
+ return -ENOMEM;
+ }
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ dev_err(&port->dev, "no more free urbs\n");
+ kfree(buffer);
+ return -ENOMEM;
+ }
+ memcpy(buffer, buf, count);
+
+ usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
+
+ usb_fill_bulk_urb(urb, serial->dev,
+ usb_sndbulkpipe(serial->dev,
+ port->bulk_out_endpointAddress),
+ buffer, count,
+ airprime_write_bulk_callback, port);
+
+ /* send it down the pipe */
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status) {
+ dev_err(&port->dev,
+ "%s - usb_submit_urb(write bulk) failed with status = %d\n",
+ __func__, status);
+ count = status;
+ kfree(buffer);
+ } else {
+ spin_lock_irqsave(&priv->lock, flags);
+ ++priv->outstanding_urbs;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+ /* we are done with this urb, so let the host driver
+ * really free it when it is finished with it */
+ usb_free_urb(urb);
+ return count;
+}
+
+static struct usb_driver airprime_driver = {
+ .name = "airprime",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+ .no_dynamic_id = 1,
+};
+
+static struct usb_serial_driver airprime_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "airprime",
+ },
+ .usb_driver = &airprime_driver,
+ .id_table = id_table,
+ .open = airprime_open,
+ .close = airprime_close,
+ .write = airprime_write,
+};
+
+static int __init airprime_init(void)
+{
+ int retval;
+
+ airprime_device.num_ports = endpoints;
+ if (endpoints < 0 || endpoints >= MAX_BULK_EPS)
+ airprime_device.num_ports = NUM_BULK_EPS;
+
+ retval = usb_serial_register(&airprime_device);
+ if (retval)
+ return retval;
+ retval = usb_register(&airprime_driver);
+ if (retval)
+ usb_serial_deregister(&airprime_device);
+ return retval;
+}
+
+static void __exit airprime_exit(void)
+{
+ dbg("%s", __func__);
+
+ usb_deregister(&airprime_driver);
+ usb_serial_deregister(&airprime_device);
+}
+
+module_init(airprime_init);
+module_exit(airprime_exit);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled");
+module_param(buffer_size, int, 0);
+MODULE_PARM_DESC(buffer_size,
+ "Size of the transfer buffers in bytes (default 4096)");
+module_param(endpoints, int, 0);
+MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)");
return -ENOMEM;
}
-static void ark3116_set_termios(struct usb_serial_port *port,
+static void ark3116_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
struct ark3116_private *priv = usb_get_serial_port_data(port);
- struct ktermios *termios = port->tty->termios;
+ struct ktermios *termios = tty->termios;
unsigned int cflag = termios->c_cflag;
unsigned long flags;
int baud;
spin_lock_irqsave(&priv->lock, flags);
if (!priv->termios_initialized) {
- *(port->tty->termios) = tty_std_termios;
- port->tty->termios->c_cflag = B9600 | CS8
+ *termios = tty_std_termios;
+ termios->c_cflag = B9600 | CS8
| CREAD | HUPCL | CLOCAL;
termios->c_ispeed = 9600;
termios->c_ospeed = 9600;
buf = kmalloc(1, GFP_KERNEL);
if (!buf) {
dbg("error kmalloc");
- *port->tty->termios = *old_termios;
+ *termios = *old_termios;
return;
}
}
/* set baudrate */
- baud = tty_get_baud_rate(port->tty);
+ baud = tty_get_baud_rate(tty);
switch (baud) {
case 75:
case 230400:
case 460800:
/* Report the resulting rate back to the caller */
- tty_encode_baud_rate(port->tty, baud, baud);
+ tty_encode_baud_rate(tty, baud, baud);
break;
/* set 9600 as default (if given baudrate is invalid for example) */
default:
- tty_encode_baud_rate(port->tty, 9600, 9600);
+ tty_encode_baud_rate(tty, 9600, 9600);
case 0:
baud = 9600;
}
return;
}
-static int ark3116_open(struct usb_serial_port *port, struct file *filp)
+static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
struct ktermios tmp_termios;
struct usb_serial *serial = port->serial;
return -ENOMEM;
}
- result = usb_serial_generic_open(port, filp);
+ result = usb_serial_generic_open(tty, port, filp);
if (result)
goto err_out;
ARK3116_RCV(serial, 124, 0xFE, 0xC0, 0x0000, 0x0006, 0xFF, buf);
/* initialise termios */
- if (port->tty)
- ark3116_set_termios(port, &tmp_termios);
+ if (tty)
+ ark3116_set_termios(tty, port, &tmp_termios);
err_out:
kfree(buf);
return result;
}
-static int ark3116_ioctl(struct usb_serial_port *port, struct file *file,
+static int ark3116_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
struct serial_struct serstruct;
void __user *user_arg = (void __user *)arg;
return -ENOIOCTLCMD;
}
-static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file)
+static int ark3116_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
char *buf;
char temp;
* This program is largely derived from work by the linux-usb group
* and associated source files. Please see the usb/serial files for
* individual credits and copyrights.
- *
+ *
* 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.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
* TODO:
* -- Add true modem contol line query capability. Currently we track the
* compressed all the differnent device entries into 1.
*
* 30-May-2001 gkh
- * switched from using spinlock to a semaphore, which fixes lots of problems.
+ * switched from using spinlock to a semaphore, which fixes lots of
+ * problems.
*
* 08-Apr-2001 gb
* - Identify version on module load.
* - Added support for the old Belkin and Peracom devices.
* - Made the port able to be opened multiple times.
* - Added some defaults incase the line settings are things these devices
- * can't support.
+ * can't support.
*
* 18-Oct-2000 William Greathouse
* Released into the wild (linux-usb-devel)
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "belkin_sa.h"
#define DRIVER_DESC "USB Belkin Serial converter driver"
/* function prototypes for a Belkin USB Serial Adapter F5U103 */
-static int belkin_sa_startup (struct usb_serial *serial);
-static void belkin_sa_shutdown (struct usb_serial *serial);
-static int belkin_sa_open (struct usb_serial_port *port, struct file *filp);
-static void belkin_sa_close (struct usb_serial_port *port, struct file *filp);
-static void belkin_sa_read_int_callback (struct urb *urb);
-static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios * old);
-static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void belkin_sa_break_ctl (struct usb_serial_port *port, int break_state );
-static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file);
-static int belkin_sa_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
+static int belkin_sa_startup(struct usb_serial *serial);
+static void belkin_sa_shutdown(struct usb_serial *serial);
+static int belkin_sa_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void belkin_sa_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void belkin_sa_read_int_callback(struct urb *urb);
+static void belkin_sa_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios * old);
+static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state);
+static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file);
+static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
{ USB_DEVICE(GOHUBS_VID, HANDYLINK_PID) },
{ USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
- { } /* Terminating entry */
+ { } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver belkin_driver = {
.name = "belkin",
.num_ports = 1,
.open = belkin_sa_open,
.close = belkin_sa_close,
- .read_int_callback = belkin_sa_read_int_callback, /* How we get the status info */
- .ioctl = belkin_sa_ioctl,
+ .read_int_callback = belkin_sa_read_int_callback,
+ /* How we get the status info */
.set_termios = belkin_sa_set_termios,
.break_ctl = belkin_sa_break_ctl,
.tiocmget = belkin_sa_tiocmget,
#define WDR_TIMEOUT 5000 /* default urb timeout */
/* assumes that struct usb_serial *serial is available */
-#define BSA_USB_CMD(c,v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \
+#define BSA_USB_CMD(c, v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \
(c), BELKIN_SA_SET_REQUEST_TYPE, \
(v), 0, NULL, 0, WDR_TIMEOUT)
/* do some startup allocations not currently performed by usb_serial_probe() */
-static int belkin_sa_startup (struct usb_serial *serial)
+static int belkin_sa_startup(struct usb_serial *serial)
{
struct usb_device *dev = serial->dev;
struct belkin_sa_private *priv;
/* allocate the private data structure */
priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL);
if (!priv)
- return (-1); /* error */
+ return -1; /* error */
/* set initial values for control structures */
spin_lock_init(&priv->lock);
priv->control_state = 0;
priv->last_lsr = 0;
priv->last_msr = 0;
/* see comments at top of file */
- priv->bad_flow_control = (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
- info("bcdDevice: %04x, bfc: %d", le16_to_cpu(dev->descriptor.bcdDevice), priv->bad_flow_control);
+ priv->bad_flow_control =
+ (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
+ info("bcdDevice: %04x, bfc: %d",
+ le16_to_cpu(dev->descriptor.bcdDevice),
+ priv->bad_flow_control);
init_waitqueue_head(&serial->port[0]->write_wait);
usb_set_serial_port_data(serial->port[0], priv);
-
- return (0);
+
+ return 0;
}
-static void belkin_sa_shutdown (struct usb_serial *serial)
+static void belkin_sa_shutdown(struct usb_serial *serial)
{
struct belkin_sa_private *priv;
int i;
-
- dbg ("%s", __func__);
+
+ dbg("%s", __func__);
/* stop reads and writes on all ports */
- for (i=0; i < serial->num_ports; ++i) {
+ for (i = 0; i < serial->num_ports; ++i) {
/* My special items, the standard routines free my urbs */
priv = usb_get_serial_port_data(serial->port[i]);
kfree(priv);
}
-static int belkin_sa_open (struct usb_serial_port *port, struct file *filp)
+static int belkin_sa_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
int retval = 0;
} /* belkin_sa_open */
-static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
+static void belkin_sa_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
dbg("%s port %d", __func__, port->number);
} /* belkin_sa_close */
-static void belkin_sa_read_int_callback (struct urb *urb)
+static void belkin_sa_read_int_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct belkin_sa_private *priv;
goto exit;
}
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
/* Handle known interrupt data */
/* ignore data[0] and data[1] */
priv = usb_get_serial_port_data(port);
spin_lock_irqsave(&priv->lock, flags);
priv->last_msr = data[BELKIN_SA_MSR_INDEX];
-
+
/* Record Control Line states */
if (priv->last_msr & BELKIN_SA_MSR_DSR)
priv->control_state |= TIOCM_DSR;
* to look in to this before committing any code.
*/
if (priv->last_lsr & BELKIN_SA_LSR_ERR) {
- tty = port->tty;
+ tty = port->port.tty;
/* Overrun Error */
if (priv->last_lsr & BELKIN_SA_LSR_OE) {
}
#endif
spin_unlock_irqrestore(&priv->lock, flags);
exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
- err ("%s - usb_submit_urb failed with result %d",
+ err("%s - usb_submit_urb failed with result %d",
__func__, retval);
}
-static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void belkin_sa_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
struct belkin_sa_private *priv = usb_get_serial_port_data(port);
unsigned long control_state;
int bad_flow_control;
speed_t baud;
- struct ktermios *termios = port->tty->termios;
-
+ struct ktermios *termios = tty->termios;
+
iflag = termios->c_iflag;
cflag = termios->c_cflag;
control_state = priv->control_state;
bad_flow_control = priv->bad_flow_control;
spin_unlock_irqrestore(&priv->lock, flags);
-
+
old_iflag = old_termios->c_iflag;
old_cflag = old_termios->c_cflag;
/* Set the baud rate */
if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
/* reassert DTR and (maybe) RTS on transition from B0 */
- if( (old_cflag&CBAUD) == B0 ) {
+ if ((old_cflag & CBAUD) == B0) {
control_state |= (TIOCM_DTR|TIOCM_RTS);
if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0)
err("Set DTR error");
/* don't set RTS if using hardware flow control */
if (!(old_cflag & CRTSCTS))
- if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0)
+ if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST
+ , 1) < 0)
err("Set RTS error");
}
}
- baud = tty_get_baud_rate(port->tty);
+ baud = tty_get_baud_rate(tty);
if (baud) {
urb_value = BELKIN_SA_BAUD(baud);
/* Clip to maximum speed */
baud = BELKIN_SA_BAUD(urb_value);
/* Report the actual baud rate back to the caller */
- tty_encode_baud_rate(port->tty, baud, baud);
+ tty_encode_baud_rate(tty, baud, baud);
if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0)
err("Set baudrate error");
} else {
/* Disable flow control */
- if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0)
+ if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST,
+ BELKIN_SA_FLOW_NONE) < 0)
err("Disable flowcontrol error");
/* Drop RTS and DTR */
control_state &= ~(TIOCM_DTR | TIOCM_RTS);
}
/* set the parity */
- if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) {
+ if ((cflag ^ old_cflag) & (PARENB | PARODD)) {
if (cflag & PARENB)
- urb_value = (cflag & PARODD) ? BELKIN_SA_PARITY_ODD : BELKIN_SA_PARITY_EVEN;
+ urb_value = (cflag & PARODD) ? BELKIN_SA_PARITY_ODD
+ : BELKIN_SA_PARITY_EVEN;
else
urb_value = BELKIN_SA_PARITY_NONE;
if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0)
}
/* set the number of data bits */
- if( (cflag&CSIZE) != (old_cflag&CSIZE) ) {
+ if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
switch (cflag & CSIZE) {
- case CS5: urb_value = BELKIN_SA_DATA_BITS(5); break;
- case CS6: urb_value = BELKIN_SA_DATA_BITS(6); break;
- case CS7: urb_value = BELKIN_SA_DATA_BITS(7); break;
- case CS8: urb_value = BELKIN_SA_DATA_BITS(8); break;
- default: dbg("CSIZE was not CS5-CS8, using default of 8");
- urb_value = BELKIN_SA_DATA_BITS(8);
- break;
+ case CS5:
+ urb_value = BELKIN_SA_DATA_BITS(5);
+ break;
+ case CS6:
+ urb_value = BELKIN_SA_DATA_BITS(6);
+ break;
+ case CS7:
+ urb_value = BELKIN_SA_DATA_BITS(7);
+ break;
+ case CS8:
+ urb_value = BELKIN_SA_DATA_BITS(8);
+ break;
+ default: dbg("CSIZE was not CS5-CS8, using default of 8");
+ urb_value = BELKIN_SA_DATA_BITS(8);
+ break;
}
if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0)
err("Set data bits error");
}
/* set the number of stop bits */
- if( (cflag&CSTOPB) != (old_cflag&CSTOPB) ) {
- urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2) : BELKIN_SA_STOP_BITS(1);
- if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST, urb_value) < 0)
+ if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
+ urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2)
+ : BELKIN_SA_STOP_BITS(1);
+ if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST,
+ urb_value) < 0)
err("Set stop bits error");
}
/* Set flow control */
- if( (iflag&IXOFF) != (old_iflag&IXOFF)
- || (iflag&IXON) != (old_iflag&IXON)
- || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) {
+ if (((iflag ^ old_iflag) & (IXOFF | IXON)) ||
+ ((cflag ^ old_cflag) & CRTSCTS)) {
urb_value = 0;
if ((iflag & IXOFF) || (iflag & IXON))
urb_value |= (BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON);
} /* belkin_sa_set_termios */
-static void belkin_sa_break_ctl( struct usb_serial_port *port, int break_state )
+static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0)
}
-static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file)
+static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct belkin_sa_private *priv = usb_get_serial_port_data(port);
unsigned long control_state;
unsigned long flags;
-
+
dbg("%s", __func__);
spin_lock_irqsave(&priv->lock, flags);
}
-static int belkin_sa_tiocmset (struct usb_serial_port *port, struct file *file,
+static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
struct belkin_sa_private *priv = usb_get_serial_port_data(port);
unsigned long control_state;
int retval;
int rts = 0;
int dtr = 0;
-
+
dbg("%s", __func__);
spin_lock_irqsave(&priv->lock, flags);
}
-static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
- case TIOCMIWAIT:
- /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
- /* TODO */
- return( 0 );
-
- case TIOCGICOUNT:
- /* return count of modemline transitions */
- /* TODO */
- return 0;
-
- default:
- dbg("belkin_sa_ioctl arg not supported - 0x%04x",cmd);
- return(-ENOIOCTLCMD);
- break;
- }
- return 0;
-} /* belkin_sa_ioctl */
-
-
-static int __init belkin_sa_init (void)
+static int __init belkin_sa_init(void)
{
int retval;
retval = usb_serial_register(&belkin_device);
static void __exit belkin_sa_exit (void)
{
- usb_deregister (&belkin_driver);
- usb_serial_deregister (&belkin_device);
+ usb_deregister(&belkin_driver);
+ usb_serial_deregister(&belkin_device);
}
-module_init (belkin_sa_init);
-module_exit (belkin_sa_exit);
+module_init(belkin_sa_init);
+module_exit(belkin_sa_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_VERSION( DRIVER_VERSION );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
* This program is largely derived from work by the linux-usb group
* and associated source files. Please see the usb/serial files for
* individual credits and copyrights.
- *
+ *
* 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.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
* 12-Mar-2001 gkh
* Added GoHubs GO-COM232 device id.
* adapter, so pardon any stupid mistakes. All of the information
* I am using to write this driver was acquired by using a modified
* UsbSnoop on Windows2000.
- *
+ *
*/
#ifndef __LINUX_USB_SERIAL_BSA_H
/*
* It seems that the interrupt pipe is closely modelled after the
- * 16550 register layout. This is probably because the adapter can
+ * 16550 register layout. This is probably because the adapter can
* be used in a "DOS" environment to simulate a standard hardware port.
*/
-#define BELKIN_SA_LSR_INDEX 2 /* Line Status Register */
+#define BELKIN_SA_LSR_INDEX 2 /* Line Status Register */
#define BELKIN_SA_LSR_RDR 0x01 /* receive data ready */
#define BELKIN_SA_LSR_OE 0x02 /* overrun error */
#define BELKIN_SA_LSR_PE 0x04 /* parity error */
#define BELKIN_SA_LSR_FE 0x08 /* framing error */
#define BELKIN_SA_LSR_BI 0x10 /* break indicator */
-#define BELKIN_SA_LSR_THE 0x20 /* transmit holding register empty */
+#define BELKIN_SA_LSR_THE 0x20 /* tx holding register empty */
#define BELKIN_SA_LSR_TE 0x40 /* transmit register empty */
#define BELKIN_SA_LSR_ERR 0x80 /* OE | PE | FE | BI */
-#define BELKIN_SA_MSR_INDEX 3 /* Modem Status Register */
+#define BELKIN_SA_MSR_INDEX 3 /* Modem Status Register */
#define BELKIN_SA_MSR_DCTS 0x01 /* Delta CTS */
#define BELKIN_SA_MSR_DDSR 0x02 /* Delta DSR */
#define BELKIN_SA_MSR_DRI 0x04 /* Delta RI */
#include <linux/usb.h>
#include <linux/usb/serial.h>
-static int usb_serial_device_match (struct device *dev, struct device_driver *drv)
+static int usb_serial_device_match(struct device *dev,
+ struct device_driver *drv)
{
struct usb_serial_driver *driver;
const struct usb_serial_port *port;
static DEVICE_ATTR(port_number, S_IRUGO, show_port_number, NULL);
-static int usb_serial_device_probe (struct device *dev)
+static int usb_serial_device_probe(struct device *dev)
{
struct usb_serial_driver *driver;
struct usb_serial_port *port;
retval = -EIO;
goto exit;
}
- retval = driver->port_probe (port);
+ retval = driver->port_probe(port);
module_put(driver->driver.owner);
if (retval)
goto exit;
goto exit;
minor = port->number;
- tty_register_device (usb_serial_tty_driver, minor, dev);
- dev_info(&port->serial->dev->dev,
+ tty_register_device(usb_serial_tty_driver, minor, dev);
+ dev_info(&port->serial->dev->dev,
"%s converter now attached to ttyUSB%d\n",
driver->description, minor);
return retval;
}
-static int usb_serial_device_remove (struct device *dev)
+static int usb_serial_device_remove(struct device *dev)
{
struct usb_serial_driver *driver;
struct usb_serial_port *port;
int minor;
port = to_usb_serial_port(dev);
- if (!port) {
+ if (!port)
return -ENODEV;
- }
device_remove_file(&port->dev, &dev_attr_port_number);
retval = -EIO;
goto exit;
}
- retval = driver->port_remove (port);
+ retval = driver->port_remove(port);
module_put(driver->driver.owner);
}
exit:
minor = port->number;
- tty_unregister_device (usb_serial_tty_driver, minor);
+ tty_unregister_device(usb_serial_tty_driver, minor);
dev_info(dev, "%s converter now disconnected from ttyUSB%d\n",
driver->description, minor);
}
/* open this device, set default parameters */
-static int ch341_open(struct usb_serial_port *port, struct file *filp)
+static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
struct usb_serial *serial = port->serial;
struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]);
if (r)
goto out;
- r = usb_serial_generic_open(port, filp);
+ r = usb_serial_generic_open(tty, port, filp);
out: return r;
}
/* Old_termios contains the original termios settings and
* tty->termios contains the new setting to be used.
*/
-static void ch341_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void ch341_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct ch341_private *priv = usb_get_serial_port_data(port);
- struct tty_struct *tty = port->tty;
unsigned baud_rate;
dbg("ch341_set_termios()");
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
- *
+ *
* Thanks to Randy Dunlap for the original version of this code.
*
*/
struct tty_struct *tty = NULL;
struct ktermios *termios = NULL, dummy;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
if (options) {
baud = simple_strtoul(options, NULL, 10);
if (*s)
doflow = (*s++ == 'r');
}
+
+ /* Sane default */
+ if (baud == 0)
+ baud = 9600;
- /* build a cflag setting */
- switch (baud) {
- case 1200:
- cflag |= B1200;
- break;
- case 2400:
- cflag |= B2400;
- break;
- case 4800:
- cflag |= B4800;
- break;
- case 19200:
- cflag |= B19200;
- break;
- case 38400:
- cflag |= B38400;
- break;
- case 57600:
- cflag |= B57600;
- break;
- case 115200:
- cflag |= B115200;
- break;
- case 9600:
- default:
- cflag |= B9600;
- /*
- * Set this to a sane value to prevent a divide error
- */
- baud = 9600;
- break;
- }
switch (bits) {
- case 7:
- cflag |= CS7;
- break;
- default:
- case 8:
- cflag |= CS8;
- break;
+ case 7:
+ cflag |= CS7;
+ break;
+ default:
+ case 8:
+ cflag |= CS8;
+ break;
}
switch (parity) {
- case 'o': case 'O':
- cflag |= PARODD;
- break;
- case 'e': case 'E':
- cflag |= PARENB;
- break;
+ case 'o': case 'O':
+ cflag |= PARODD;
+ break;
+ case 'e': case 'E':
+ cflag |= PARENB;
+ break;
}
co->cflag = cflag;
serial = usb_serial_get_by_index(co->index);
if (serial == NULL) {
/* no device is connected yet, sorry :( */
- err ("No USB device connected to ttyUSB%i", co->index);
+ err("No USB device connected to ttyUSB%i", co->index);
return -ENODEV;
}
port = serial->port[0];
- port->tty = NULL;
+ port->port.tty = NULL;
info->port = port;
-
- ++port->open_count;
- if (port->open_count == 1) {
+
+ ++port->port.count;
+ if (port->port.count == 1) {
if (serial->type->set_termios) {
/*
* allocate a fake tty so the driver can initialize
}
memset(&dummy, 0, sizeof(struct ktermios));
tty->termios = termios;
- port->tty = tty;
+ port->port.tty = tty;
}
- /* only call the device specific open if this
+ /* only call the device specific open if this
* is the first time the port is opened */
if (serial->type->open)
- retval = serial->type->open(port, NULL);
+ retval = serial->type->open(NULL, port, NULL);
else
- retval = usb_serial_generic_open(port, NULL);
+ retval = usb_serial_generic_open(NULL, port, NULL);
if (retval) {
err("could not open USB console port");
if (serial->type->set_termios) {
termios->c_cflag = cflag;
- serial->type->set_termios(port, &dummy);
+ tty_termios_encode_baud_rate(termios, baud, baud);
+ serial->type->set_termios(NULL, port, &dummy);
- port->tty = NULL;
+ port->port.tty = NULL;
kfree(termios);
kfree(tty);
}
return retval;
free_termios:
kfree(termios);
- port->tty = NULL;
+ port->port.tty = NULL;
free_tty:
kfree(tty);
reset_open_count:
- port->open_count = 0;
+ port->port.count = 0;
goto out;
}
-static void usb_console_write(struct console *co, const char *buf, unsigned count)
+static void usb_console_write(struct console *co,
+ const char *buf, unsigned count)
{
static struct usbcons_info *info = &usbcons_info;
struct usb_serial_port *port = info->port;
dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
- if (!port->open_count) {
- dbg ("%s - port not opened", __func__);
+ if (!port->port.count) {
+ dbg("%s - port not opened", __func__);
return;
}
unsigned int i;
unsigned int lf;
/* search for LF so we can insert CR if necessary */
- for (i=0, lf=0 ; i < count ; i++) {
+ for (i = 0, lf = 0 ; i < count ; i++) {
if (*(buf + i) == 10) {
lf = 1;
i++;
break;
}
}
- /* pass on to the driver specific version of this function if it is available */
+ /* pass on to the driver specific version of this function if
+ it is available */
if (serial->type->write)
- retval = serial->type->write(port, buf, i);
+ retval = serial->type->write(NULL, port, buf, i);
else
- retval = usb_serial_generic_write(port, buf, i);
+ retval = usb_serial_generic_write(NULL, port, buf, i);
dbg("%s - return value : %d", __func__, retval);
if (lf) {
/* append CR after LF */
unsigned char cr = 13;
if (serial->type->write)
- retval = serial->type->write(port, &cr, 1);
+ retval = serial->type->write(NULL,
+ port, &cr, 1);
else
- retval = usb_serial_generic_write(port, &cr, 1);
+ retval = usb_serial_generic_write(NULL,
+ port, &cr, 1);
dbg("%s - return value : %d", __func__, retval);
}
buf += i;
void usb_serial_console_disconnect(struct usb_serial *serial)
{
- if (serial && serial->port && serial->port[0] && serial->port[0] == usbcons_info.port) {
+ if (serial && serial->port && serial->port[0]
+ && serial->port[0] == usbcons_info.port) {
usb_serial_console_exit();
usb_serial_put(serial);
}
}
-void usb_serial_console_init (int serial_debug, int minor)
+void usb_serial_console_init(int serial_debug, int minor)
{
debug = serial_debug;
if (minor == 0) {
- /*
+ /*
* Call register_console() if this is the first device plugged
* in. If we call it earlier, then the callback to
* console_setup() will fail, as there is not a device seen by
/*
* Register console.
* NOTES:
- * console_setup() is called (back) immediately (from register_console).
- * console_write() is called immediately from register_console iff
- * CON_PRINTBUFFER is set in flags.
+ * console_setup() is called (back) immediately (from
+ * register_console). console_write() is called immediately
+ * from register_console iff CON_PRINTBUFFER is set in flags.
*/
- dbg ("registering the USB serial console.");
+ dbg("registering the USB serial console.");
register_console(&usbcons);
}
}
-void usb_serial_console_exit (void)
+void usb_serial_console_exit(void)
{
if (usbcons_info.port) {
unregister_console(&usbcons);
- if (usbcons_info.port->open_count)
- usbcons_info.port->open_count--;
+ if (usbcons_info.port->port.count)
+ usbcons_info.port->port.count--;
usbcons_info.port = NULL;
}
}
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/usb.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb/serial.h>
/*
/*
* Function Prototypes
*/
-static int cp2101_open(struct usb_serial_port*, struct file*);
-static void cp2101_cleanup(struct usb_serial_port*);
-static void cp2101_close(struct usb_serial_port*, struct file*);
-static void cp2101_get_termios(struct usb_serial_port*);
-static void cp2101_set_termios(struct usb_serial_port*, struct ktermios*);
-static int cp2101_tiocmget (struct usb_serial_port *, struct file *);
-static int cp2101_tiocmset (struct usb_serial_port *, struct file *,
+static int cp2101_open(struct tty_struct *, struct usb_serial_port *,
+ struct file *);
+static void cp2101_cleanup(struct usb_serial_port *);
+static void cp2101_close(struct tty_struct *, struct usb_serial_port *,
+ struct file*);
+static void cp2101_get_termios(struct tty_struct *);
+static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *,
+ struct ktermios*);
+static int cp2101_tiocmget(struct tty_struct *, struct file *);
+static int cp2101_tiocmset(struct tty_struct *, struct file *,
unsigned int, unsigned int);
-static void cp2101_break_ctl(struct usb_serial_port*, int);
-static int cp2101_startup (struct usb_serial *);
-static void cp2101_shutdown(struct usb_serial*);
+static void cp2101_break_ctl(struct tty_struct *, int);
+static int cp2101_startup(struct usb_serial *);
+static void cp2101_shutdown(struct usb_serial *);
static int debug;
{ } /* Terminating Entry */
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver cp2101_driver = {
.name = "cp2101",
* 'data' is a pointer to a pre-allocated array of integers large
* enough to hold 'size' bytes (with 4 bytes to each integer)
*/
-static int cp2101_get_config(struct usb_serial_port* port, u8 request,
+static int cp2101_get_config(struct usb_serial_port *port, u8 request,
unsigned int *data, int size)
{
struct usb_serial *serial = port->serial;
request++;
/* Issue the request, attempting to read 'size' bytes */
- result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0),
+ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
request, REQTYPE_DEVICE_TO_HOST, 0x0000,
0, buf, size, 300);
/* Convert data into an array of integers */
- for (i=0; i<length; i++)
+ for (i = 0; i < length; i++)
data[i] = le32_to_cpu(buf[i]);
kfree(buf);
* Values less than 16 bits wide are sent directly
* 'size' is specified in bytes.
*/
-static int cp2101_set_config(struct usb_serial_port* port, u8 request,
+static int cp2101_set_config(struct usb_serial_port *port, u8 request,
unsigned int *data, int size)
{
struct usb_serial *serial = port->serial;
buf[i] = cpu_to_le32(data[i]);
if (size > 2) {
- result = usb_control_msg (serial->dev,
+ result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_DEVICE, 0x0000,
0, buf, size, 300);
} else {
- result = usb_control_msg (serial->dev,
+ result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_DEVICE, data[0],
0, NULL, 0, 300);
}
/* Single data value */
- result = usb_control_msg (serial->dev,
+ result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_DEVICE, data[0],
0, NULL, 0, 300);
* Convenience function for calling cp2101_set_config on single data values
* without requiring an integer pointer
*/
-static inline int cp2101_set_config_single(struct usb_serial_port* port,
+static inline int cp2101_set_config_single(struct usb_serial_port *port,
u8 request, unsigned int data)
{
return cp2101_set_config(port, request, &data, 2);
}
-static int cp2101_open (struct usb_serial_port *port, struct file *filp)
+static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
struct usb_serial *serial = port->serial;
int result;
}
/* Start reading from the device */
- usb_fill_bulk_urb (port->read_urb, serial->dev,
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
}
/* Configure the termios structure */
- cp2101_get_termios(port);
+ cp2101_get_termios(tty);
/* Set the DTR and RTS pins low */
- cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0);
+ cp2101_tiocmset(tty, NULL, TIOCM_DTR | TIOCM_RTS, 0);
return 0;
}
-static void cp2101_cleanup (struct usb_serial_port *port)
+static void cp2101_cleanup(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
}
}
-static void cp2101_close (struct usb_serial_port *port, struct file * filp)
+static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
dbg("%s - port %d", __func__, port->number);
* from the device, corrects any unsupported values, and configures the
* termios structure to reflect the state of the device
*/
-static void cp2101_get_termios (struct usb_serial_port *port)
+static void cp2101_get_termios (struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned int cflag, modem_ctl[4];
unsigned int baud;
unsigned int bits;
dbg("%s - port %d", __func__, port->number);
- if (!port->tty || !port->tty->termios) {
- dbg("%s - no tty structures", __func__);
- return;
- }
-
cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
/* Convert to baudrate */
if (baud)
dbg("%s - baud rate = %d", __func__, baud);
- tty_encode_baud_rate(port->tty, baud, baud);
- cflag = port->tty->termios->c_cflag;
+ tty_encode_baud_rate(tty, baud, baud);
+ cflag = tty->termios->c_cflag;
cp2101_get_config(port, CP2101_BITS, &bits, 2);
cflag &= ~CSIZE;
- switch(bits & BITS_DATA_MASK) {
- case BITS_DATA_5:
- dbg("%s - data bits = 5", __func__);
- cflag |= CS5;
- break;
- case BITS_DATA_6:
- dbg("%s - data bits = 6", __func__);
- cflag |= CS6;
- break;
- case BITS_DATA_7:
- dbg("%s - data bits = 7", __func__);
- cflag |= CS7;
- break;
- case BITS_DATA_8:
- dbg("%s - data bits = 8", __func__);
- cflag |= CS8;
- break;
- case BITS_DATA_9:
- dbg("%s - data bits = 9 (not supported, "
- "using 8 data bits)", __func__);
- cflag |= CS8;
- bits &= ~BITS_DATA_MASK;
- bits |= BITS_DATA_8;
- cp2101_set_config(port, CP2101_BITS, &bits, 2);
- break;
- default:
- dbg("%s - Unknown number of data bits, "
- "using 8", __func__);
- cflag |= CS8;
- bits &= ~BITS_DATA_MASK;
- bits |= BITS_DATA_8;
- cp2101_set_config(port, CP2101_BITS, &bits, 2);
- break;
+ switch (bits & BITS_DATA_MASK) {
+ case BITS_DATA_5:
+ dbg("%s - data bits = 5", __func__);
+ cflag |= CS5;
+ break;
+ case BITS_DATA_6:
+ dbg("%s - data bits = 6", __func__);
+ cflag |= CS6;
+ break;
+ case BITS_DATA_7:
+ dbg("%s - data bits = 7", __func__);
+ cflag |= CS7;
+ break;
+ case BITS_DATA_8:
+ dbg("%s - data bits = 8", __func__);
+ cflag |= CS8;
+ break;
+ case BITS_DATA_9:
+ dbg("%s - data bits = 9 (not supported, using 8 data bits)",
+ __func__);
+ cflag |= CS8;
+ bits &= ~BITS_DATA_MASK;
+ bits |= BITS_DATA_8;
+ cp2101_set_config(port, CP2101_BITS, &bits, 2);
+ break;
+ default:
+ dbg("%s - Unknown number of data bits, using 8", __func__);
+ cflag |= CS8;
+ bits &= ~BITS_DATA_MASK;
+ bits |= BITS_DATA_8;
+ cp2101_set_config(port, CP2101_BITS, &bits, 2);
+ break;
}
- switch(bits & BITS_PARITY_MASK) {
- case BITS_PARITY_NONE:
- dbg("%s - parity = NONE", __func__);
- cflag &= ~PARENB;
- break;
- case BITS_PARITY_ODD:
- dbg("%s - parity = ODD", __func__);
- cflag |= (PARENB|PARODD);
- break;
- case BITS_PARITY_EVEN:
- dbg("%s - parity = EVEN", __func__);
- cflag &= ~PARODD;
- cflag |= PARENB;
- break;
- case BITS_PARITY_MARK:
- dbg("%s - parity = MARK (not supported, "
- "disabling parity)", __func__);
- cflag &= ~PARENB;
- bits &= ~BITS_PARITY_MASK;
- cp2101_set_config(port, CP2101_BITS, &bits, 2);
- break;
- case BITS_PARITY_SPACE:
- dbg("%s - parity = SPACE (not supported, "
- "disabling parity)", __func__);
- cflag &= ~PARENB;
- bits &= ~BITS_PARITY_MASK;
- cp2101_set_config(port, CP2101_BITS, &bits, 2);
- break;
- default:
- dbg("%s - Unknown parity mode, "
- "disabling parity", __func__);
- cflag &= ~PARENB;
- bits &= ~BITS_PARITY_MASK;
- cp2101_set_config(port, CP2101_BITS, &bits, 2);
- break;
+ switch (bits & BITS_PARITY_MASK) {
+ case BITS_PARITY_NONE:
+ dbg("%s - parity = NONE", __func__);
+ cflag &= ~PARENB;
+ break;
+ case BITS_PARITY_ODD:
+ dbg("%s - parity = ODD", __func__);
+ cflag |= (PARENB|PARODD);
+ break;
+ case BITS_PARITY_EVEN:
+ dbg("%s - parity = EVEN", __func__);
+ cflag &= ~PARODD;
+ cflag |= PARENB;
+ break;
+ case BITS_PARITY_MARK:
+ dbg("%s - parity = MARK (not supported, disabling parity)",
+ __func__);
+ cflag &= ~PARENB;
+ bits &= ~BITS_PARITY_MASK;
+ cp2101_set_config(port, CP2101_BITS, &bits, 2);
+ break;
+ case BITS_PARITY_SPACE:
+ dbg("%s - parity = SPACE (not supported, disabling parity)",
+ __func__);
+ cflag &= ~PARENB;
+ bits &= ~BITS_PARITY_MASK;
+ cp2101_set_config(port, CP2101_BITS, &bits, 2);
+ break;
+ default:
+ dbg("%s - Unknown parity mode, disabling parity", __func__);
+ cflag &= ~PARENB;
+ bits &= ~BITS_PARITY_MASK;
+ cp2101_set_config(port, CP2101_BITS, &bits, 2);
+ break;
}
cflag &= ~CSTOPB;
- switch(bits & BITS_STOP_MASK) {
- case BITS_STOP_1:
- dbg("%s - stop bits = 1", __func__);
- break;
- case BITS_STOP_1_5:
- dbg("%s - stop bits = 1.5 (not supported, "
- "using 1 stop bit)", __func__);
- bits &= ~BITS_STOP_MASK;
- cp2101_set_config(port, CP2101_BITS, &bits, 2);
- break;
- case BITS_STOP_2:
- dbg("%s - stop bits = 2", __func__);
- cflag |= CSTOPB;
- break;
- default:
- dbg("%s - Unknown number of stop bits, "
- "using 1 stop bit", __func__);
- bits &= ~BITS_STOP_MASK;
- cp2101_set_config(port, CP2101_BITS, &bits, 2);
- break;
+ switch (bits & BITS_STOP_MASK) {
+ case BITS_STOP_1:
+ dbg("%s - stop bits = 1", __func__);
+ break;
+ case BITS_STOP_1_5:
+ dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)",
+ __func__);
+ bits &= ~BITS_STOP_MASK;
+ cp2101_set_config(port, CP2101_BITS, &bits, 2);
+ break;
+ case BITS_STOP_2:
+ dbg("%s - stop bits = 2", __func__);
+ cflag |= CSTOPB;
+ break;
+ default:
+ dbg("%s - Unknown number of stop bits, using 1 stop bit",
+ __func__);
+ bits &= ~BITS_STOP_MASK;
+ cp2101_set_config(port, CP2101_BITS, &bits, 2);
+ break;
}
cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
cflag &= ~CRTSCTS;
}
- port->tty->termios->c_cflag = cflag;
+ tty->termios->c_cflag = cflag;
}
-static void cp2101_set_termios (struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void cp2101_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
unsigned int cflag, old_cflag;
unsigned int baud = 0, bits;
dbg("%s - port %d", __func__, port->number);
- if (!port->tty || !port->tty->termios) {
- dbg("%s - no tty structures", __func__);
+ if (!tty)
return;
- }
- port->tty->termios->c_cflag &= ~CMSPAR;
- cflag = port->tty->termios->c_cflag;
+ tty->termios->c_cflag &= ~CMSPAR;
+ cflag = tty->termios->c_cflag;
old_cflag = old_termios->c_cflag;
- baud = tty_get_baud_rate(port->tty);
+ baud = tty_get_baud_rate(tty);
/* If the baud rate is to be updated*/
if (baud != tty_termios_baud_rate(old_termios)) {
switch (baud) {
- case 0:
- case 600:
- case 1200:
- case 1800:
- case 2400:
- case 4800:
- case 7200:
- case 9600:
- case 14400:
- case 19200:
- case 28800:
- case 38400:
- case 55854:
- case 57600:
- case 115200:
- case 127117:
- case 230400:
- case 460800:
- case 921600:
- case 3686400:
- break;
- default:
- baud = 9600;
- break;
+ case 0:
+ case 600:
+ case 1200:
+ case 1800:
+ case 2400:
+ case 4800:
+ case 7200:
+ case 9600:
+ case 14400:
+ case 19200:
+ case 28800:
+ case 38400:
+ case 55854:
+ case 57600:
+ case 115200:
+ case 127117:
+ case 230400:
+ case 460800:
+ case 921600:
+ case 3686400:
+ break;
+ default:
+ baud = 9600;
+ break;
}
if (baud) {
}
}
/* Report back the resulting baud rate */
- tty_encode_baud_rate(port->tty, baud, baud);
+ tty_encode_baud_rate(tty, baud, baud);
/* If the number of data bits is to be updated */
if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
cp2101_get_config(port, CP2101_BITS, &bits, 2);
bits &= ~BITS_DATA_MASK;
switch (cflag & CSIZE) {
- case CS5:
- bits |= BITS_DATA_5;
- dbg("%s - data bits = 5", __func__);
- break;
- case CS6:
- bits |= BITS_DATA_6;
- dbg("%s - data bits = 6", __func__);
- break;
- case CS7:
- bits |= BITS_DATA_7;
- dbg("%s - data bits = 7", __func__);
- break;
- case CS8:
- bits |= BITS_DATA_8;
- dbg("%s - data bits = 8", __func__);
- break;
- /*case CS9:
- bits |= BITS_DATA_9;
- dbg("%s - data bits = 9", __func__);
- break;*/
- default:
- dev_err(&port->dev, "cp2101 driver does not "
+ case CS5:
+ bits |= BITS_DATA_5;
+ dbg("%s - data bits = 5", __func__);
+ break;
+ case CS6:
+ bits |= BITS_DATA_6;
+ dbg("%s - data bits = 6", __func__);
+ break;
+ case CS7:
+ bits |= BITS_DATA_7;
+ dbg("%s - data bits = 7", __func__);
+ break;
+ case CS8:
+ bits |= BITS_DATA_8;
+ dbg("%s - data bits = 8", __func__);
+ break;
+ /*case CS9:
+ bits |= BITS_DATA_9;
+ dbg("%s - data bits = 9", __func__);
+ break;*/
+ default:
+ dev_err(&port->dev, "cp2101 driver does not "
"support the number of bits requested,"
" using 8 bit mode\n");
bits |= BITS_DATA_8;
}
-static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file,
+static int cp2101_tiocmset (struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned int control = 0;
dbg("%s - port %d", __func__, port->number);
}
-static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file)
+static int cp2101_tiocmget (struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned int control;
int result;
return result;
}
-static void cp2101_break_ctl (struct usb_serial_port *port, int break_state)
+static void cp2101_break_ctl (struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned int state;
dbg("%s - port %d", __func__, port->number);
else
state = BREAK_ON;
dbg("%s - turning break %s", __func__,
- state==BREAK_OFF ? "off" : "on");
+ state == BREAK_OFF ? "off" : "on");
cp2101_set_config(port, CP2101_BREAK, &state, 2);
}
-static int cp2101_startup (struct usb_serial *serial)
+static int cp2101_startup(struct usb_serial *serial)
{
/* CP2101 buffers behave strangely unless device is reset */
usb_reset_device(serial->dev);
return 0;
}
-static void cp2101_shutdown (struct usb_serial *serial)
+static void cp2101_shutdown(struct usb_serial *serial)
{
int i;
dbg("%s", __func__);
/* Stop reads and writes on all ports */
- for (i=0; i < serial->num_ports; ++i) {
+ for (i = 0; i < serial->num_ports; ++i)
cp2101_cleanup(serial->port[i]);
- }
}
-static int __init cp2101_init (void)
+static int __init cp2101_init(void)
{
int retval;
return 0;
}
-static void __exit cp2101_exit (void)
+static void __exit cp2101_exit(void)
{
- usb_deregister (&cp2101_driver);
- usb_serial_deregister (&cp2101_device);
+ usb_deregister(&cp2101_driver);
+ usb_serial_deregister(&cp2101_device);
}
module_init(cp2101_init);
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#define CYBERJACK_PRODUCT_ID 0x0100
/* Function prototypes */
-static int cyberjack_startup (struct usb_serial *serial);
-static void cyberjack_shutdown (struct usb_serial *serial);
-static int cyberjack_open (struct usb_serial_port *port, struct file *filp);
-static void cyberjack_close (struct usb_serial_port *port, struct file *filp);
-static int cyberjack_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int cyberjack_write_room( struct usb_serial_port *port );
-static void cyberjack_read_int_callback (struct urb *urb);
-static void cyberjack_read_bulk_callback (struct urb *urb);
-static void cyberjack_write_bulk_callback (struct urb *urb);
+static int cyberjack_startup(struct usb_serial *serial);
+static void cyberjack_shutdown(struct usb_serial *serial);
+static int cyberjack_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void cyberjack_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static int cyberjack_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count);
+static int cyberjack_write_room(struct tty_struct *tty);
+static void cyberjack_read_int_callback(struct urb *urb);
+static void cyberjack_read_bulk_callback(struct urb *urb);
+static void cyberjack_write_bulk_callback(struct urb *urb);
static struct usb_device_id id_table [] = {
{ USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver cyberjack_driver = {
.name = "cyberjack",
};
/* do some startup allocations not currently performed by usb_serial_probe() */
-static int cyberjack_startup (struct usb_serial *serial)
+static int cyberjack_startup(struct usb_serial *serial)
{
struct cyberjack_private *priv;
int i;
for (i = 0; i < serial->num_ports; ++i) {
int result;
serial->port[i]->interrupt_in_urb->dev = serial->dev;
- result = usb_submit_urb(serial->port[i]->interrupt_in_urb,
+ result = usb_submit_urb(serial->port[i]->interrupt_in_urb,
GFP_KERNEL);
if (result)
err(" usb_submit_urb(read int) failed");
dbg("%s - usb_submit_urb(int urb)", __func__);
}
- return( 0 );
+ return 0;
}
-static void cyberjack_shutdown (struct usb_serial *serial)
+static void cyberjack_shutdown(struct usb_serial *serial)
{
int i;
-
+
dbg("%s", __func__);
for (i = 0; i < serial->num_ports; ++i) {
usb_set_serial_port_data(serial->port[i], NULL);
}
}
-
-static int cyberjack_open (struct usb_serial_port *port, struct file *filp)
+
+static int cyberjack_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct cyberjack_private *priv;
unsigned long flags;
dbg("%s - port %d", __func__, port->number);
- dbg("%s - usb_clear_halt", __func__ );
+ dbg("%s - usb_clear_halt", __func__);
usb_clear_halt(port->serial->dev, port->write_urb->pipe);
/* force low_latency on so that our tty_push actually forces
* the data through, otherwise it is scheduled, and with high
* data rates (like with OHCI) data can get lost.
*/
- port->tty->low_latency = 1;
+ if (tty)
+ tty->low_latency = 1;
priv = usb_get_serial_port_data(port);
spin_lock_irqsave(&priv->lock, flags);
return result;
}
-static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
+static void cyberjack_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
dbg("%s - port %d", __func__, port->number);
}
}
-static int cyberjack_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int cyberjack_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct usb_serial *serial = port->serial;
struct cyberjack_private *priv = usb_get_serial_port_data(port);
spin_lock_irqsave(&priv->lock, flags);
- if( (count+priv->wrfilled) > sizeof(priv->wrbuf) ) {
+ if (count+priv->wrfilled > sizeof(priv->wrbuf)) {
/* To much data for buffer. Reset buffer. */
priv->wrfilled = 0;
port->write_urb_busy = 0;
}
/* Copy data */
- memcpy (priv->wrbuf+priv->wrfilled, buf, count);
+ memcpy(priv->wrbuf + priv->wrfilled, buf, count);
usb_serial_debug_data(debug, &port->dev, __func__, count,
- priv->wrbuf+priv->wrfilled);
+ priv->wrbuf + priv->wrfilled);
priv->wrfilled += count;
- if( priv->wrfilled >= 3 ) {
+ if (priv->wrfilled >= 3) {
wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
dbg("%s - expected data: %d", __func__, wrexpected);
- } else {
+ } else
wrexpected = sizeof(priv->wrbuf);
- }
- if( priv->wrfilled >= wrexpected ) {
+ if (priv->wrfilled >= wrexpected) {
/* We have enough data to begin transmission */
int length;
dbg("%s - transmitting data (frame 1)", __func__);
- length = (wrexpected > port->bulk_out_size) ? port->bulk_out_size : wrexpected;
+ length = (wrexpected > port->bulk_out_size) ?
+ port->bulk_out_size : wrexpected;
- memcpy (port->write_urb->transfer_buffer, priv->wrbuf, length );
- priv->wrsent=length;
+ memcpy(port->write_urb->transfer_buffer, priv->wrbuf, length);
+ priv->wrsent = length;
/* set up our urb */
- usb_fill_bulk_urb(port->write_urb, serial->dev,
+ usb_fill_bulk_urb(port->write_urb, serial->dev,
usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
port->write_urb->transfer_buffer, length,
- ((serial->type->write_bulk_callback) ?
- serial->type->write_bulk_callback :
- cyberjack_write_bulk_callback),
+ ((serial->type->write_bulk_callback) ?
+ serial->type->write_bulk_callback :
+ cyberjack_write_bulk_callback),
port);
/* send the data out the bulk port */
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (result) {
- err("%s - failed submitting write urb, error %d", __func__, result);
+ err("%s - failed submitting write urb, error %d",
+ __func__, result);
/* Throw away data. No better idea what to do with it. */
priv->wrfilled = 0;
priv->wrsent = 0;
return 0;
}
- dbg("%s - priv->wrsent=%d", __func__,priv->wrsent);
- dbg("%s - priv->wrfilled=%d", __func__,priv->wrfilled);
+ dbg("%s - priv->wrsent=%d", __func__, priv->wrsent);
+ dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled);
- if( priv->wrsent>=priv->wrfilled ) {
+ if (priv->wrsent >= priv->wrfilled) {
dbg("%s - buffer cleaned", __func__);
- memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
+ memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
priv->wrfilled = 0;
priv->wrsent = 0;
}
spin_unlock_irqrestore(&priv->lock, flags);
- return (count);
-}
+ return count;
+}
-static int cyberjack_write_room( struct usb_serial_port *port )
+static int cyberjack_write_room(struct tty_struct *tty)
{
/* FIXME: .... */
return CYBERJACK_LOCAL_BUF_SIZE;
}
-static void cyberjack_read_int_callback( struct urb *urb )
+static void cyberjack_read_int_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct cyberjack_private *priv = usb_get_serial_port_data(port);
if (status)
return;
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
/* React only to interrupts signaling a bulk_in transfer */
- if( (urb->actual_length == 4) && (data[0] == 0x01) ) {
+ if (urb->actual_length == 4 && data[0] == 0x01) {
short old_rdtodo;
/* This is a announcement of coming bulk_ins. */
old_rdtodo = priv->rdtodo;
- if( (old_rdtodo+size)<(old_rdtodo) ) {
- dbg( "To many bulk_in urbs to do." );
+ if (old_rdtodo + size < old_rdtodo) {
+ dbg("To many bulk_in urbs to do.");
spin_unlock(&priv->lock);
goto resubmit;
}
spin_unlock(&priv->lock);
- if( !old_rdtodo ) {
+ if (!old_rdtodo) {
port->read_urb->dev = port->serial->dev;
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
- if( result )
+ if (result)
err("%s - failed resubmitting read urb, error %d", __func__, result);
dbg("%s - usb_submit_urb(read urb)", __func__);
}
dbg("%s - usb_submit_urb(int urb)", __func__);
}
-static void cyberjack_read_bulk_callback (struct urb *urb)
+static void cyberjack_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct cyberjack_private *priv = usb_get_serial_port_data(port);
dbg("%s - port %d", __func__, port->number);
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
if (status) {
dbg("%s - nonzero read bulk status received: %d",
__func__, status);
return;
}
- tty = port->tty;
+ tty = port->port.tty;
if (!tty) {
dbg("%s - ignoring since device not open\n", __func__);
return;
if (urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
- tty_flip_buffer_push(tty);
+ tty_flip_buffer_push(tty);
}
spin_lock(&priv->lock);
/* Reduce urbs to do by one. */
- priv->rdtodo-=urb->actual_length;
+ priv->rdtodo -= urb->actual_length;
/* Just to be sure */
- if ( priv->rdtodo<0 ) priv->rdtodo = 0;
+ if (priv->rdtodo < 0)
+ priv->rdtodo = 0;
todo = priv->rdtodo;
spin_unlock(&priv->lock);
dbg("%s - rdtodo: %d", __func__, todo);
/* Continue to read if we have still urbs to do. */
- if( todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) {
+ if (todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/) {
port->read_urb->dev = port->serial->dev;
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d", __func__, result);
+ err("%s - failed resubmitting read urb, error %d",
+ __func__, result);
dbg("%s - usb_submit_urb(read urb)", __func__);
}
}
-static void cyberjack_write_bulk_callback (struct urb *urb)
+static void cyberjack_write_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct cyberjack_private *priv = usb_get_serial_port_data(port);
spin_lock(&priv->lock);
/* only do something if we have more data to send */
- if( priv->wrfilled ) {
+ if (priv->wrfilled) {
int length, blksize, result;
dbg("%s - transmitting data (frame n)", __func__);
length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
port->bulk_out_size : (priv->wrfilled - priv->wrsent);
- memcpy (port->write_urb->transfer_buffer, priv->wrbuf + priv->wrsent,
- length );
- priv->wrsent+=length;
+ memcpy(port->write_urb->transfer_buffer,
+ priv->wrbuf + priv->wrsent, length);
+ priv->wrsent += length;
/* set up our urb */
- usb_fill_bulk_urb(port->write_urb, port->serial->dev,
+ usb_fill_bulk_urb(port->write_urb, port->serial->dev,
usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
port->write_urb->transfer_buffer, length,
- ((port->serial->type->write_bulk_callback) ?
- port->serial->type->write_bulk_callback :
- cyberjack_write_bulk_callback),
+ ((port->serial->type->write_bulk_callback) ?
+ port->serial->type->write_bulk_callback :
+ cyberjack_write_bulk_callback),
port);
/* send the data out the bulk port */
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (result) {
- err("%s - failed submitting write urb, error %d", __func__, result);
+ err("%s - failed submitting write urb, error %d",
+ __func__, result);
/* Throw away data. No better idea what to do with it. */
priv->wrfilled = 0;
priv->wrsent = 0;
goto exit;
}
- dbg("%s - priv->wrsent=%d", __func__,priv->wrsent);
- dbg("%s - priv->wrfilled=%d", __func__,priv->wrfilled);
+ dbg("%s - priv->wrsent=%d", __func__, priv->wrsent);
+ dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled);
blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
- if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) {
+ if (priv->wrsent >= priv->wrfilled ||
+ priv->wrsent >= blksize) {
dbg("%s - buffer cleaned", __func__);
- memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
+ memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
priv->wrfilled = 0;
priv->wrsent = 0;
}
usb_serial_port_softint(port);
}
-static int __init cyberjack_init (void)
+static int __init cyberjack_init(void)
{
int retval;
retval = usb_serial_register(&cyberjack_device);
if (retval)
goto failed_usb_serial_register;
retval = usb_register(&cyberjack_driver);
- if (retval)
+ if (retval)
goto failed_usb_register;
info(DRIVER_VERSION " " DRIVER_AUTHOR);
return retval;
}
-static void __exit cyberjack_exit (void)
+static void __exit cyberjack_exit(void)
{
- usb_deregister (&cyberjack_driver);
- usb_serial_deregister (&cyberjack_device);
+ usb_deregister(&cyberjack_driver);
+ usb_serial_deregister(&cyberjack_device);
}
module_init(cyberjack_init);
module_exit(cyberjack_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_VERSION( DRIVER_VERSION );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
* USB Cypress M8 driver
*
* Copyright (C) 2004
- * Lonnie Mendez (dignome@gmail.com)
+ * Lonnie Mendez (dignome@gmail.com)
* Copyright (C) 2003,2004
* Neil Whelchel (koyama@firstlight.net)
*
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
* See http://geocities.com/i0xox0i for information on this driver and the
* earthmate usb device.
*
* Lonnie Mendez <dignome@gmail.com>
* 4-29-2005
- * Fixed problem where setting or retreiving the serial config would fail with
- * EPIPE. Removed CRTS toggling so the driver behaves more like other usbserial
- * adapters. Issued new interval of 1ms instead of the default 10ms. As a
- * result, transfer speed has been substantially increased. From avg. 850bps to
- * avg. 3300bps. initial termios has also been modified. Cleaned up code and
- * formatting issues so it is more readable. Replaced the C++ style comments.
+ * Fixed problem where setting or retreiving the serial config would fail
+ * with EPIPE. Removed CRTS toggling so the driver behaves more like
+ * other usbserial adapters. Issued new interval of 1ms instead of the
+ * default 10ms. As a result, transfer speed has been substantially
+ * increased from avg. 850bps to avg. 3300bps. initial termios has also
+ * been modified. Cleaned up code and formatting issues so it is more
+ * readable. Replaced the C++ style comments.
*
* Lonnie Mendez <dignome@gmail.com>
* 12-15-2004
*
*/
-/* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */
+/* Thanks to Neil Whelchel for writing the first cypress m8 implementation
+ for linux. */
/* Thanks to cypress for providing references for the hid reports. */
/* Thanks to Jiang Zhang for providing links and for general help. */
-/* Code originates and was built up from ftdi_sio, belkin, pl2303 and others. */
+/* Code originates and was built up from ftdi_sio, belkin, pl2303 and others.*/
#include <linux/kernel.h>
#include <linux/usb/serial.h>
#include <linux/serial.h>
#include <linux/delay.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "cypress_m8.h"
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver cypress_driver = {
.name = "cypress",
__u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */
enum packet_format pkt_fmt; /* format to use for packet send / receive */
int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */
- int baud_rate; /* stores current baud rate in integer form */
+ int baud_rate; /* stores current baud rate in
+ integer form */
int isthrottled; /* if throttled, discard reads */
wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */
char prev_status, diff_status; /* used for TIOCMIWAIT */
- /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
+ /* we pass a pointer to this as the arguement sent to
+ cypress_set_termios old_termios */
struct ktermios tmp_termios; /* stores the old termios settings */
};
};
/* function prototypes for the Cypress USB to serial device */
-static int cypress_earthmate_startup (struct usb_serial *serial);
-static int cypress_hidcom_startup (struct usb_serial *serial);
-static int cypress_ca42v2_startup (struct usb_serial *serial);
-static void cypress_shutdown (struct usb_serial *serial);
-static int cypress_open (struct usb_serial_port *port, struct file *filp);
-static void cypress_close (struct usb_serial_port *port, struct file *filp);
-static int cypress_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-static void cypress_send (struct usb_serial_port *port);
-static int cypress_write_room (struct usb_serial_port *port);
-static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void cypress_set_termios (struct usb_serial_port *port, struct ktermios * old);
-static int cypress_tiocmget (struct usb_serial_port *port, struct file *file);
-static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
-static int cypress_chars_in_buffer (struct usb_serial_port *port);
-static void cypress_throttle (struct usb_serial_port *port);
-static void cypress_unthrottle (struct usb_serial_port *port);
-static void cypress_set_dead (struct usb_serial_port *port);
-static void cypress_read_int_callback (struct urb *urb);
-static void cypress_write_int_callback (struct urb *urb);
+static int cypress_earthmate_startup(struct usb_serial *serial);
+static int cypress_hidcom_startup(struct usb_serial *serial);
+static int cypress_ca42v2_startup(struct usb_serial *serial);
+static void cypress_shutdown(struct usb_serial *serial);
+static int cypress_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void cypress_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+static void cypress_send(struct usb_serial_port *port);
+static int cypress_write_room(struct tty_struct *tty);
+static int cypress_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void cypress_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
+static int cypress_tiocmget(struct tty_struct *tty, struct file *file);
+static int cypress_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static int cypress_chars_in_buffer(struct tty_struct *tty);
+static void cypress_throttle(struct tty_struct *tty);
+static void cypress_unthrottle(struct tty_struct *tty);
+static void cypress_set_dead(struct usb_serial_port *port);
+static void cypress_read_int_callback(struct urb *urb);
+static void cypress_write_int_callback(struct urb *urb);
/* write buffer functions */
static struct cypress_buf *cypress_buf_alloc(unsigned int size);
-static void cypress_buf_free(struct cypress_buf *cb);
-static void cypress_buf_clear(struct cypress_buf *cb);
-static unsigned int cypress_buf_data_avail(struct cypress_buf *cb);
-static unsigned int cypress_buf_space_avail(struct cypress_buf *cb);
-static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, unsigned int count);
-static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count);
+static void cypress_buf_free(struct cypress_buf *cb);
+static void cypress_buf_clear(struct cypress_buf *cb);
+static unsigned int cypress_buf_data_avail(struct cypress_buf *cb);
+static unsigned int cypress_buf_space_avail(struct cypress_buf *cb);
+static unsigned int cypress_buf_put(struct cypress_buf *cb,
+ const char *buf, unsigned int count);
+static unsigned int cypress_buf_get(struct cypress_buf *cb,
+ char *buf, unsigned int count);
static struct usb_serial_driver cypress_earthmate_device = {
static struct usb_serial_driver cypress_ca42v2_device = {
.driver = {
.owner = THIS_MODULE,
- .name = "nokiaca42v2",
+ .name = "nokiaca42v2",
},
.description = "Nokia CA-42 V2 Adapter",
.usb_driver = &cypress_driver,
/* This function can either set or retrieve the current serial line settings */
-static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_rate, int data_bits, int stop_bits,
- int parity_enable, int parity_type, int reset, int cypress_request_type)
+static int cypress_serial_control(struct tty_struct *tty,
+ struct usb_serial_port *port, speed_t baud_rate, int data_bits,
+ int stop_bits, int parity_enable, int parity_type, int reset,
+ int cypress_request_type)
{
int new_baudrate = 0, retval = 0, tries = 0;
struct cypress_private *priv;
unsigned long flags;
dbg("%s", __func__);
-
+
priv = usb_get_serial_port_data(port);
if (!priv->comm_is_ok)
return -ENODEV;
- switch(cypress_request_type) {
- case CYPRESS_SET_CONFIG:
+ switch (cypress_request_type) {
+ case CYPRESS_SET_CONFIG:
+ new_baudrate = priv->baud_rate;
+ /* 0 means 'Hang up' so doesn't change the true bit rate */
+ if (baud_rate == 0)
new_baudrate = priv->baud_rate;
- /* 0 means 'Hang up' so doesn't change the true bit rate */
- if (baud_rate == 0)
- new_baudrate = priv->baud_rate;
- /* Change of speed ? */
- else if (baud_rate != priv->baud_rate) {
- dbg("%s - baud rate is changing", __func__);
- retval = analyze_baud_rate(port, baud_rate);
- if (retval >= 0) {
- new_baudrate = retval;
- dbg("%s - New baud rate set to %d",
- __func__, new_baudrate);
- }
- }
- dbg("%s - baud rate is being sent as %d", __func__, new_baudrate);
-
- memset(feature_buffer, 0, sizeof(feature_buffer));
- /* fill the feature_buffer with new configuration */
- *((u_int32_t *)feature_buffer) = new_baudrate;
-
- feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */
- /* 1 bit gap */
- feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */
- feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */
- feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */
- /* 1 bit gap */
- feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */
-
- dbg("%s - device is being sent this feature report:", __func__);
- dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__, feature_buffer[0], feature_buffer[1],
- feature_buffer[2], feature_buffer[3], feature_buffer[4]);
-
- do {
- retval = usb_control_msg(port->serial->dev,
- usb_sndctrlpipe(port->serial->dev, 0),
- HID_REQ_SET_REPORT,
- USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
- 0x0300, 0, feature_buffer,
- sizeof(feature_buffer), 500);
-
- if (tries++ >= 3)
- break;
-
- } while (retval != sizeof(feature_buffer) &&
- retval != -ENODEV);
-
- if (retval != sizeof(feature_buffer)) {
- err("%s - failed sending serial line settings - %d", __func__, retval);
- cypress_set_dead(port);
- } else {
- spin_lock_irqsave(&priv->lock, flags);
- priv->baud_rate = new_baudrate;
- priv->current_config = feature_buffer[4];
- spin_unlock_irqrestore(&priv->lock, flags);
- /* If we asked for a speed change encode it */
- if (baud_rate)
- tty_encode_baud_rate(port->tty,
- new_baudrate, new_baudrate);
- }
- break;
- case CYPRESS_GET_CONFIG:
- if (priv->get_cfg_unsafe) {
- /* Not implemented for this device,
- and if we try to do it we're likely
- to crash the hardware. */
- return -ENOTTY;
- }
- dbg("%s - retreiving serial line settings", __func__);
- /* set initial values in feature buffer */
- memset(feature_buffer, 0, sizeof(feature_buffer));
-
- do {
- retval = usb_control_msg(port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0),
- HID_REQ_GET_REPORT,
- USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
- 0x0300, 0, feature_buffer,
- sizeof(feature_buffer), 500);
-
- if (tries++ >= 3)
- break;
-
- } while (retval != sizeof(feature_buffer) &&
- retval != -ENODEV);
-
- if (retval != sizeof(feature_buffer)) {
- err("%s - failed to retrieve serial line settings - %d", __func__, retval);
- cypress_set_dead(port);
- return retval;
- } else {
- spin_lock_irqsave(&priv->lock, flags);
-
- /* store the config in one byte, and later use bit masks to check values */
- priv->current_config = feature_buffer[4];
- priv->baud_rate = *((u_int32_t *)feature_buffer);
- spin_unlock_irqrestore(&priv->lock, flags);
+ /* Change of speed ? */
+ else if (baud_rate != priv->baud_rate) {
+ dbg("%s - baud rate is changing", __func__);
+ retval = analyze_baud_rate(port, baud_rate);
+ if (retval >= 0) {
+ new_baudrate = retval;
+ dbg("%s - New baud rate set to %d",
+ __func__, new_baudrate);
}
+ }
+ dbg("%s - baud rate is being sent as %d",
+ __func__, new_baudrate);
+
+ memset(feature_buffer, 0, sizeof(feature_buffer));
+ /* fill the feature_buffer with new configuration */
+ *((u_int32_t *)feature_buffer) = new_baudrate;
+ feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */
+ /* 1 bit gap */
+ feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */
+ feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */
+ feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */
+ /* 1 bit gap */
+ feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */
+
+ dbg("%s - device is being sent this feature report:",
+ __func__);
+ dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__,
+ feature_buffer[0], feature_buffer[1],
+ feature_buffer[2], feature_buffer[3],
+ feature_buffer[4]);
+
+ do {
+ retval = usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ HID_REQ_SET_REPORT,
+ USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
+ 0x0300, 0, feature_buffer,
+ sizeof(feature_buffer), 500);
+
+ if (tries++ >= 3)
+ break;
+
+ } while (retval != sizeof(feature_buffer) &&
+ retval != -ENODEV);
+
+ if (retval != sizeof(feature_buffer)) {
+ err("%s - failed sending serial line settings - %d",
+ __func__, retval);
+ cypress_set_dead(port);
+ } else {
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->baud_rate = new_baudrate;
+ priv->current_config = feature_buffer[4];
+ spin_unlock_irqrestore(&priv->lock, flags);
+ /* If we asked for a speed change encode it */
+ if (baud_rate)
+ tty_encode_baud_rate(tty,
+ new_baudrate, new_baudrate);
+ }
+ break;
+ case CYPRESS_GET_CONFIG:
+ if (priv->get_cfg_unsafe) {
+ /* Not implemented for this device,
+ and if we try to do it we're likely
+ to crash the hardware. */
+ return -ENOTTY;
+ }
+ dbg("%s - retreiving serial line settings", __func__);
+ /* set initial values in feature buffer */
+ memset(feature_buffer, 0, sizeof(feature_buffer));
+
+ do {
+ retval = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ HID_REQ_GET_REPORT,
+ USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
+ 0x0300, 0, feature_buffer,
+ sizeof(feature_buffer), 500);
+
+ if (tries++ >= 3)
+ break;
+ } while (retval != sizeof(feature_buffer)
+ && retval != -ENODEV);
+
+ if (retval != sizeof(feature_buffer)) {
+ err("%s - failed to retrieve serial line settings - %d", __func__, retval);
+ cypress_set_dead(port);
+ return retval;
+ } else {
+ spin_lock_irqsave(&priv->lock, flags);
+ /* store the config in one byte, and later
+ use bit masks to check values */
+ priv->current_config = feature_buffer[4];
+ priv->baud_rate = *((u_int32_t *)feature_buffer);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
}
spin_lock_irqsave(&priv->lock, flags);
++priv->cmd_count;
*****************************************************************************/
-static int generic_startup (struct usb_serial *serial)
+static int generic_startup(struct usb_serial *serial)
{
struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0];
dbg("%s - port %d", __func__, port->number);
- priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL);
+ priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
return -ENOMEM;
}
init_waitqueue_head(&priv->delta_msr_wait);
-
- usb_reset_configuration (serial->dev);
-
+
+ usb_reset_configuration(serial->dev);
+
priv->cmd_ctrl = 0;
priv->line_control = 0;
priv->termios_initialized = 0;
small. Otherwise we can use the slightly more compact
format. This is in accordance with the cypress_m8 serial
converter app note. */
- if (port->interrupt_out_size > 9) {
+ if (port->interrupt_out_size > 9)
priv->pkt_fmt = packet_format_1;
- } else {
+ else
priv->pkt_fmt = packet_format_2;
- }
+
if (interval > 0) {
priv->write_urb_interval = interval;
priv->read_urb_interval = interval;
dbg("%s - port %d read & write intervals forced to %d",
- __func__,port->number,interval);
+ __func__, port->number, interval);
} else {
priv->write_urb_interval = port->interrupt_out_urb->interval;
priv->read_urb_interval = port->interrupt_in_urb->interval;
dbg("%s - port %d intervals: read=%d write=%d",
- __func__,port->number,
- priv->read_urb_interval,priv->write_urb_interval);
+ __func__, port->number,
+ priv->read_urb_interval, priv->write_urb_interval);
}
usb_set_serial_port_data(port, priv);
-
+
return 0;
}
-static int cypress_earthmate_startup (struct usb_serial *serial)
+static int cypress_earthmate_startup(struct usb_serial *serial)
{
struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0];
/* All Earthmate devices use the separated-count packet
format! Idiotic. */
priv->pkt_fmt = packet_format_1;
- if (serial->dev->descriptor.idProduct != cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) {
+ if (serial->dev->descriptor.idProduct !=
+ cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) {
/* The old original USB Earthmate seemed able to
handle GET_CONFIG requests; everything they've
produced since that time crashes if this command is
} /* cypress_earthmate_startup */
-static int cypress_hidcom_startup (struct usb_serial *serial)
+static int cypress_hidcom_startup(struct usb_serial *serial)
{
struct cypress_private *priv;
priv = usb_get_serial_port_data(serial->port[0]);
priv->chiptype = CT_CYPHIDCOM;
-
+
return 0;
} /* cypress_hidcom_startup */
-static int cypress_ca42v2_startup (struct usb_serial *serial)
+static int cypress_ca42v2_startup(struct usb_serial *serial)
{
struct cypress_private *priv;
} /* cypress_ca42v2_startup */
-static void cypress_shutdown (struct usb_serial *serial)
+static void cypress_shutdown(struct usb_serial *serial)
{
struct cypress_private *priv;
- dbg ("%s - port %d", __func__, serial->port[0]->number);
+ dbg("%s - port %d", __func__, serial->port[0]->number);
/* all open ports are closed at this point */
}
-static int cypress_open (struct usb_serial_port *port, struct file *filp)
+static int cypress_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct cypress_private *priv = usb_get_serial_port_data(port);
struct usb_serial *serial = port->serial;
spin_unlock_irqrestore(&priv->lock, flags);
/* setting to zero could cause data loss */
- port->tty->low_latency = 1;
+ if (tty)
+ tty->low_latency = 1;
/* raise both lines and set termios */
spin_lock_irqsave(&priv->lock, flags);
priv->line_control = CONTROL_DTR | CONTROL_RTS;
priv->cmd_ctrl = 1;
spin_unlock_irqrestore(&priv->lock, flags);
- result = cypress_write(port, NULL, 0);
+ result = cypress_write(tty, port, NULL, 0);
if (result) {
- dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __func__, result);
+ dev_err(&port->dev,
+ "%s - failed setting the control lines - error %d\n",
+ __func__, result);
return result;
} else
dbg("%s - success setting the control lines", __func__);
- cypress_set_termios(port, &priv->tmp_termios);
+ if (tty)
+ cypress_set_termios(tty, port, &priv->tmp_termios);
/* setup the port and start reading from the device */
- if(!port->interrupt_in_urb){
+ if (!port->interrupt_in_urb) {
err("%s - interrupt_in_urb is empty!", __func__);
- return(-1);
+ return -1;
}
usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
- port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length,
+ port->interrupt_in_urb->transfer_buffer,
+ port->interrupt_in_urb->transfer_buffer_length,
cypress_read_int_callback, port, priv->read_urb_interval);
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
- if (result){
- dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
+ if (result) {
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
cypress_set_dead(port);
}
} /* cypress_open */
-static void cypress_close(struct usb_serial_port *port, struct file * filp)
+static void cypress_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct cypress_private *priv = usb_get_serial_port_data(port);
unsigned int c_cflag;
spin_lock_irq(&priv->lock);
timeout = CYPRESS_CLOSING_WAIT;
init_waitqueue_entry(&wait, current);
- add_wait_queue(&port->tty->write_wait, &wait);
+ add_wait_queue(&tty->write_wait, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (cypress_buf_data_avail(priv->buf) == 0
spin_lock_irq(&priv->lock);
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->tty->write_wait, &wait);
+ remove_wait_queue(&tty->write_wait, &wait);
/* clear out any remaining data in the buffer */
cypress_buf_clear(priv->buf);
spin_unlock_irq(&priv->lock);
return;
}
/* wait for characters to drain from device */
- bps = tty_get_baud_rate(port->tty);
- if (bps > 1200)
- timeout = max((HZ*2560)/bps,HZ/10);
- else
- timeout = 2*HZ;
- schedule_timeout_interruptible(timeout);
+ if (tty) {
+ bps = tty_get_baud_rate(tty);
+ if (bps > 1200)
+ timeout = max((HZ * 2560) / bps, HZ / 10);
+ else
+ timeout = 2 * HZ;
+ schedule_timeout_interruptible(timeout);
+ }
dbg("%s - stopping urbs", __func__);
- usb_kill_urb (port->interrupt_in_urb);
- usb_kill_urb (port->interrupt_out_urb);
+ usb_kill_urb(port->interrupt_in_urb);
+ usb_kill_urb(port->interrupt_out_urb);
- if (port->tty) {
- c_cflag = port->tty->termios->c_cflag;
+ if (tty) {
+ c_cflag = tty->termios->c_cflag;
if (c_cflag & HUPCL) {
/* drop dtr and rts */
priv = usb_get_serial_port_data(port);
priv->line_control = 0;
priv->cmd_ctrl = 1;
spin_unlock_irq(&priv->lock);
- cypress_write(port, NULL, 0);
+ cypress_write(tty, port, NULL, 0);
}
}
if (stats)
- dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
- priv->bytes_in, priv->bytes_out, priv->cmd_count);
+ dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
+ priv->bytes_in, priv->bytes_out, priv->cmd_count);
mutex_unlock(&port->serial->disc_mutex);
} /* cypress_close */
-static int cypress_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
struct cypress_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
-
+
dbg("%s - port %d, %d bytes", __func__, port->number, count);
/* line control commands, which need to be executed immediately,
count = 0;
goto finish;
}
-
+
if (!count)
return count;
-
+
spin_lock_irqsave(&priv->lock, flags);
count = cypress_buf_put(priv->buf, buf, count);
spin_unlock_irqrestore(&priv->lock, flags);
int count = 0, result, offset, actual_size;
struct cypress_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
-
+
if (!priv->comm_is_ok)
return;
dbg("%s - port %d", __func__, port->number);
- dbg("%s - interrupt out size is %d", __func__, port->interrupt_out_size);
-
+ dbg("%s - interrupt out size is %d", __func__,
+ port->interrupt_out_size);
+
spin_lock_irqsave(&priv->lock, flags);
if (priv->write_urb_in_use) {
dbg("%s - can't write, urb in use", __func__);
spin_unlock_irqrestore(&priv->lock, flags);
/* clear buffer */
- memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size);
+ memset(port->interrupt_out_urb->transfer_buffer, 0,
+ port->interrupt_out_size);
spin_lock_irqsave(&priv->lock, flags);
switch (priv->pkt_fmt) {
count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset],
port->interrupt_out_size-offset);
- if (count == 0) {
+ if (count == 0)
return;
- }
switch (priv->pkt_fmt) {
default:
actual_size = count +
(priv->pkt_fmt == packet_format_1 ? 2 : 1);
- usb_serial_debug_data(debug, &port->dev, __func__, port->interrupt_out_size,
- port->interrupt_out_urb->transfer_buffer);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ port->interrupt_out_size,
+ port->interrupt_out_urb->transfer_buffer);
usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev,
usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
port->interrupt_out_buffer, port->interrupt_out_size,
cypress_write_int_callback, port, priv->write_urb_interval);
- result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
+ result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
if (result) {
- dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__,
- result);
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, result);
priv->write_urb_in_use = 0;
cypress_set_dead(port);
}
spin_lock_irqsave(&priv->lock, flags);
- if (priv->cmd_ctrl) {
+ if (priv->cmd_ctrl)
priv->cmd_ctrl = 0;
- }
- priv->bytes_out += count; /* do not count the line control and size bytes */
+
+ /* do not count the line control and size bytes */
+ priv->bytes_out += count;
spin_unlock_irqrestore(&priv->lock, flags);
usb_serial_port_softint(port);
/* returns how much space is available in the soft buffer */
-static int cypress_write_room(struct usb_serial_port *port)
+static int cypress_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct cypress_private *priv = usb_get_serial_port_data(port);
int room = 0;
unsigned long flags;
}
-static int cypress_tiocmget (struct usb_serial_port *port, struct file *file)
+static int cypress_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct cypress_private *priv = usb_get_serial_port_data(port);
__u8 status, control;
unsigned int result = 0;
unsigned long flags;
-
+
dbg("%s - port %d", __func__, port->number);
spin_lock_irqsave(&priv->lock, flags);
}
-static int cypress_tiocmset (struct usb_serial_port *port, struct file *file,
+static int cypress_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct cypress_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
-
+
dbg("%s - port %d", __func__, port->number);
spin_lock_irqsave(&priv->lock, flags);
priv->cmd_ctrl = 1;
spin_unlock_irqrestore(&priv->lock, flags);
- return cypress_write(port, NULL, 0);
+ return cypress_write(tty, port, NULL, 0);
}
-static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+static int cypress_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
struct cypress_private *priv = usb_get_serial_port_data(port);
dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
switch (cmd) {
- /* This code comes from drivers/char/serial.c and ftdi_sio.c */
- case TIOCMIWAIT:
- while (priv != NULL) {
- interruptible_sleep_on(&priv->delta_msr_wait);
- /* see if a signal did it */
- if (signal_pending(current))
- return -ERESTARTSYS;
- else {
- char diff = priv->diff_status;
-
- if (diff == 0) {
- return -EIO; /* no change => error */
- }
-
- /* consume all events */
- priv->diff_status = 0;
-
- /* return 0 if caller wanted to know about these bits */
- if ( ((arg & TIOCM_RNG) && (diff & UART_RI)) ||
- ((arg & TIOCM_DSR) && (diff & UART_DSR)) ||
- ((arg & TIOCM_CD) && (diff & UART_CD)) ||
- ((arg & TIOCM_CTS) && (diff & UART_CTS)) ) {
- return 0;
- }
- /* otherwise caller can't care less about what happened,
- * and so we continue to wait for more events.
- */
- }
+ /* This code comes from drivers/char/serial.c and ftdi_sio.c */
+ case TIOCMIWAIT:
+ while (priv != NULL) {
+ interruptible_sleep_on(&priv->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ else {
+ char diff = priv->diff_status;
+ if (diff == 0)
+ return -EIO; /* no change => error */
+
+ /* consume all events */
+ priv->diff_status = 0;
+
+ /* return 0 if caller wanted to know about
+ these bits */
+ if (((arg & TIOCM_RNG) && (diff & UART_RI)) ||
+ ((arg & TIOCM_DSR) && (diff & UART_DSR)) ||
+ ((arg & TIOCM_CD) && (diff & UART_CD)) ||
+ ((arg & TIOCM_CTS) && (diff & UART_CTS)))
+ return 0;
+ /* otherwise caller can't care less about what
+ * happened, and so we continue to wait for
+ * more events.
+ */
}
- return 0;
- break;
- default:
- break;
+ }
+ return 0;
+ default:
+ break;
}
-
dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd);
-
return -ENOIOCTLCMD;
} /* cypress_ioctl */
-static void cypress_set_termios (struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void cypress_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct cypress_private *priv = usb_get_serial_port_data(port);
- struct tty_struct *tty;
int data_bits, stop_bits, parity_type, parity_enable;
unsigned cflag, iflag;
unsigned long flags;
dbg("%s - port %d", __func__, port->number);
- tty = port->tty;
-
spin_lock_irqsave(&priv->lock, flags);
if (!priv->termios_initialized) {
if (priv->chiptype == CT_EARTHMATE) {
} else
parity_enable = parity_type = 0;
- if (cflag & CSIZE) {
- switch (cflag & CSIZE) {
- case CS5:
- data_bits = 0;
- break;
- case CS6:
- data_bits = 1;
- break;
- case CS7:
- data_bits = 2;
- break;
- case CS8:
- data_bits = 3;
- break;
- default:
- err("%s - CSIZE was set, but not CS5-CS8",
- __func__);
- data_bits = 3;
- }
- } else
+ switch (cflag & CSIZE) {
+ case CS5:
+ data_bits = 0;
+ break;
+ case CS6:
+ data_bits = 1;
+ break;
+ case CS7:
+ data_bits = 2;
+ break;
+ case CS8:
data_bits = 3;
-
+ break;
+ default:
+ err("%s - CSIZE was set, but not CS5-CS8",
+ __func__);
+ data_bits = 3;
+ }
spin_lock_irqsave(&priv->lock, flags);
oldlines = priv->line_control;
if ((cflag & CBAUD) == B0) {
"%d data_bits (+5)", __func__, stop_bits,
parity_enable, parity_type, data_bits);
- cypress_serial_control(port, tty_get_baud_rate(tty), data_bits, stop_bits,
- parity_enable, parity_type, 0, CYPRESS_SET_CONFIG);
+ cypress_serial_control(tty, port, tty_get_baud_rate(tty),
+ data_bits, stop_bits,
+ parity_enable, parity_type,
+ 0, CYPRESS_SET_CONFIG);
/* we perform a CYPRESS_GET_CONFIG so that the current settings are
* filled into the private structure this should confirm that all is
* working if it returns what we just set */
- cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
+ cypress_serial_control(tty, port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
/* Here we can define custom tty settings for devices; the main tty
* termios flag base comes from empeg.c */
spin_lock_irqsave(&priv->lock, flags);
- if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) {
+ if (priv->chiptype == CT_EARTHMATE && priv->baud_rate == 4800) {
dbg("Using custom termios settings for a baud rate of "
"4800bps.");
/* define custom termios settings for NMEA protocol */
/* if necessary, set lines */
if (linechange) {
priv->cmd_ctrl = 1;
- cypress_write(port, NULL, 0);
+ cypress_write(tty, port, NULL, 0);
}
} /* cypress_set_termios */
/* returns amount of data still left in soft buffer */
-static int cypress_chars_in_buffer(struct usb_serial_port *port)
+static int cypress_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct cypress_private *priv = usb_get_serial_port_data(port);
int chars = 0;
unsigned long flags;
dbg("%s - port %d", __func__, port->number);
-
+
spin_lock_irqsave(&priv->lock, flags);
chars = cypress_buf_data_avail(priv->buf);
spin_unlock_irqrestore(&priv->lock, flags);
}
-static void cypress_throttle (struct usb_serial_port *port)
+static void cypress_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct cypress_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
}
-static void cypress_unthrottle (struct usb_serial_port *port)
+static void cypress_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct cypress_private *priv = usb_get_serial_port_data(port);
int actually_throttled, result;
unsigned long flags;
/* precursor to disconnect so just go away */
return;
case -EPIPE:
- usb_clear_halt(port->serial->dev,0x81);
+ usb_clear_halt(port->serial->dev, 0x81);
break;
default:
/* something ugly is going on... */
- dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n",
- __func__, status);
+ dev_err(&urb->dev->dev,
+ "%s - unexpected nonzero read status received: %d\n",
+ __func__, status);
cypress_set_dead(port);
return;
}
}
spin_unlock_irqrestore(&priv->lock, flags);
- tty = port->tty;
+ tty = port->port.tty;
if (!tty) {
dbg("%s - bad tty pointer - exiting", __func__);
return;
goto continue_read;
}
- usb_serial_debug_data (debug, &port->dev, __func__,
- urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
spin_lock_irqsave(&priv->lock, flags);
/* check to see if status has changed */
data[i]);
tty_insert_flip_char(tty, data[i], tty_flag);
}
- tty_flip_buffer_push(port->tty);
+ tty_flip_buffer_push(port->port.tty);
}
spin_lock_irqsave(&priv->lock, flags);
/* Continue trying to always read... unless the port has closed. */
- if (port->open_count > 0 && priv->comm_is_ok) {
+ if (port->port.count > 0 && priv->comm_is_ok) {
usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
usb_rcvintpipe(port->serial->dev,
port->interrupt_in_endpointAddress),
port->interrupt_in_urb->transfer_buffer,
port->interrupt_in_urb->transfer_buffer_length,
- cypress_read_int_callback, port, priv->read_urb_interval);
+ cypress_read_int_callback, port,
+ priv->read_urb_interval);
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result) {
dev_err(&urb->dev->dev, "%s - failed resubmitting "
dbg("%s - port %d", __func__, port->number);
switch (status) {
- case 0:
- /* success */
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d",
+ __func__, status);
+ priv->write_urb_in_use = 0;
+ return;
+ case -EPIPE: /* no break needed; clear halt and resubmit */
+ if (!priv->comm_is_ok)
break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d",
- __func__, status);
- priv->write_urb_in_use = 0;
+ usb_clear_halt(port->serial->dev, 0x02);
+ /* error in the urb, so we have to resubmit it */
+ dbg("%s - nonzero write bulk status received: %d",
+ __func__, status);
+ port->interrupt_out_urb->transfer_buffer_length = 1;
+ port->interrupt_out_urb->dev = port->serial->dev;
+ result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
+ if (!result)
return;
- case -EPIPE: /* no break needed; clear halt and resubmit */
- if (!priv->comm_is_ok)
- break;
- usb_clear_halt(port->serial->dev, 0x02);
- /* error in the urb, so we have to resubmit it */
- dbg("%s - nonzero write bulk status received: %d",
- __func__, status);
- port->interrupt_out_urb->transfer_buffer_length = 1;
- port->interrupt_out_urb->dev = port->serial->dev;
- result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
- if (!result)
- return;
- dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n",
- __func__, result);
- cypress_set_dead(port);
- break;
- default:
- dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n",
- __func__, status);
- cypress_set_dead(port);
- break;
+ dev_err(&urb->dev->dev,
+ "%s - failed resubmitting write urb, error %d\n",
+ __func__, result);
+ cypress_set_dead(port);
+ break;
+ default:
+ dev_err(&urb->dev->dev,
+ "%s - unexpected nonzero write status received: %d\n",
+ __func__, status);
+ cypress_set_dead(port);
+ break;
}
-
priv->write_urb_in_use = 0;
-
+
/* send any buffered data */
cypress_send(port);
}
static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
{
if (cb != NULL)
- return ((cb->buf_size + cb->buf_put - cb->buf_get) % cb->buf_size);
+ return (cb->buf_size + cb->buf_put - cb->buf_get)
+ % cb->buf_size;
else
return 0;
}
static unsigned int cypress_buf_space_avail(struct cypress_buf *cb)
{
if (cb != NULL)
- return ((cb->buf_size + cb->buf_get - cb->buf_put - 1) % cb->buf_size);
+ return (cb->buf_size + cb->buf_get - cb->buf_put - 1)
+ % cb->buf_size;
else
return 0;
}
static int __init cypress_init(void)
{
int retval;
-
+
dbg("%s", __func__);
-
+
retval = usb_serial_register(&cypress_earthmate_device);
if (retval)
goto failed_em_register;
}
-static void __exit cypress_exit (void)
+static void __exit cypress_exit(void)
{
dbg("%s", __func__);
- usb_deregister (&cypress_driver);
- usb_serial_deregister (&cypress_earthmate_device);
- usb_serial_deregister (&cypress_hidcom_device);
- usb_serial_deregister (&cypress_ca42v2_device);
+ usb_deregister(&cypress_driver);
+ usb_serial_deregister(&cypress_earthmate_device);
+ usb_serial_deregister(&cypress_hidcom_device);
+ usb_serial_deregister(&cypress_ca42v2_device);
}
module_init(cypress_init);
module_exit(cypress_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_VERSION( DRIVER_VERSION );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
#define UART_DSR 0x20 /* data set ready - flow control - device to host */
#define CONTROL_RTS 0x10 /* request to send - flow control - host to device */
#define UART_CTS 0x10 /* clear to send - flow control - device to host */
-#define UART_RI 0x10 /* ring indicator - modem - device to host */
+#define UART_RI 0x10 /* ring indicator - modem - device to host */
#define UART_CD 0x40 /* carrier detect - modem - device to host */
#define CYP_ERROR 0x08 /* received from input report - device to host */
/* Note - the below has nothing to to with the "feature report" reset */
* Al Borchers (borchers@steinerpoint.com)
*
* (12/03/2001) gkh
-* switched to using port->open_count instead of private version.
+* switched to using port->port.count instead of private version.
* Removed port->active
*
* (04/08/2001) gb
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/wait.h>
#include <linux/usb/serial.h>
unsigned int modem_signals, int interruptible);
static int digi_transmit_idle(struct usb_serial_port *port,
unsigned long timeout);
-static void digi_rx_throttle (struct usb_serial_port *port);
-static void digi_rx_unthrottle (struct usb_serial_port *port);
-static void digi_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios);
-static void digi_break_ctl(struct usb_serial_port *port, int break_state);
-static int digi_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg);
-static int digi_tiocmget(struct usb_serial_port *port, struct file *file);
-static int digi_tiocmset(struct usb_serial_port *port, struct file *file,
+static void digi_rx_throttle(struct tty_struct *tty);
+static void digi_rx_unthrottle(struct tty_struct *tty);
+static void digi_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios);
+static void digi_break_ctl(struct tty_struct *tty, int break_state);
+static int digi_tiocmget(struct tty_struct *tty, struct file *file);
+static int digi_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
-static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count);
+static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
static void digi_write_bulk_callback(struct urb *urb);
-static int digi_write_room(struct usb_serial_port *port);
-static int digi_chars_in_buffer(struct usb_serial_port *port);
-static int digi_open(struct usb_serial_port *port, struct file *filp);
-static void digi_close(struct usb_serial_port *port, struct file *filp);
+static int digi_write_room(struct tty_struct *tty);
+static int digi_chars_in_buffer(struct tty_struct *tty);
+static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
static int digi_startup_device(struct usb_serial *serial);
static int digi_startup(struct usb_serial *serial);
static void digi_shutdown(struct usb_serial *serial);
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver digi_driver = {
.name = "digi_acceleport",
.chars_in_buffer = digi_chars_in_buffer,
.throttle = digi_rx_throttle,
.unthrottle = digi_rx_unthrottle,
- .ioctl = digi_ioctl,
.set_termios = digi_set_termios,
.break_ctl = digi_break_ctl,
.tiocmget = digi_tiocmget,
.chars_in_buffer = digi_chars_in_buffer,
.throttle = digi_rx_throttle,
.unthrottle = digi_rx_unthrottle,
- .ioctl = digi_ioctl,
.set_termios = digi_set_termios,
.break_ctl = digi_break_ctl,
.tiocmget = digi_tiocmget,
/* Functions */
/*
-* Cond Wait Interruptible Timeout Irqrestore
-*
-* Do spin_unlock_irqrestore and interruptible_sleep_on_timeout
-* so that wake ups are not lost if they occur between the unlock
-* and the sleep. In other words, spin_unlock_irqrestore and
-* interruptible_sleep_on_timeout are "atomic" with respect to
-* wake ups. This is used to implement condition variables.
-*
-* interruptible_sleep_on_timeout is deprecated and has been replaced
-* with the equivalent code.
-*/
+ * Cond Wait Interruptible Timeout Irqrestore
+ *
+ * Do spin_unlock_irqrestore and interruptible_sleep_on_timeout
+ * so that wake ups are not lost if they occur between the unlock
+ * and the sleep. In other words, spin_unlock_irqrestore and
+ * interruptible_sleep_on_timeout are "atomic" with respect to
+ * wake ups. This is used to implement condition variables.
+ *
+ * interruptible_sleep_on_timeout is deprecated and has been replaced
+ * with the equivalent code.
+ */
static long cond_wait_interruptible_timeout_irqrestore(
wait_queue_head_t *q, long timeout,
/*
-* Digi Wakeup Write
-*
-* Wake up port, line discipline, and tty processes sleeping
-* on writes.
-*/
+ * Digi Wakeup Write
+ *
+ * Wake up port, line discipline, and tty processes sleeping
+ * on writes.
+ */
static void digi_wakeup_write_lock(struct work_struct *work)
{
- struct digi_port *priv = container_of(work, struct digi_port, dp_wakeup_work);
+ struct digi_port *priv =
+ container_of(work, struct digi_port, dp_wakeup_work);
struct usb_serial_port *port = priv->dp_port;
unsigned long flags;
static void digi_wakeup_write(struct usb_serial_port *port)
{
- tty_wakeup(port->tty);
+ tty_wakeup(port->port.tty);
}
/*
-* Digi Write OOB Command
-*
-* Write commands on the out of band port. Commands are 4
-* bytes each, multiple commands can be sent at once, and
-* no command will be split across USB packets. Returns 0
-* if successful, -EINTR if interrupted while sleeping and
-* the interruptible flag is true, or a negative error
-* returned by usb_submit_urb.
-*/
+ * Digi Write OOB Command
+ *
+ * Write commands on the out of band port. Commands are 4
+ * bytes each, multiple commands can be sent at once, and
+ * no command will be split across USB packets. Returns 0
+ * if successful, -EINTR if interrupted while sleeping and
+ * the interruptible flag is true, or a negative error
+ * returned by usb_submit_urb.
+ */
static int digi_write_oob_command(struct usb_serial_port *port,
unsigned char *buf, int count, int interruptible)
dbg("digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count);
spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
- while(count > 0) {
- while(oob_port->write_urb->status == -EINPROGRESS
+ while (count > 0) {
+ while (oob_port->write_urb->status == -EINPROGRESS
|| oob_priv->dp_write_urb_in_use) {
cond_wait_interruptible_timeout_irqrestore(
&oob_port->write_wait, DIGI_RETRY_TIMEOUT,
memcpy(oob_port->write_urb->transfer_buffer, buf, len);
oob_port->write_urb->transfer_buffer_length = len;
oob_port->write_urb->dev = port->serial->dev;
- if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) {
+ ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
+ if (ret == 0) {
oob_priv->dp_write_urb_in_use = 1;
count -= len;
buf += len;
/*
-* Digi Write In Band Command
-*
-* Write commands on the given port. Commands are 4
-* bytes each, multiple commands can be sent at once, and
-* no command will be split across USB packets. If timeout
-* is non-zero, write in band command will return after
-* waiting unsuccessfully for the URB status to clear for
-* timeout ticks. Returns 0 if successful, or a negative
-* error returned by digi_write.
-*/
+ * Digi Write In Band Command
+ *
+ * Write commands on the given port. Commands are 4
+ * bytes each, multiple commands can be sent at once, and
+ * no command will be split across USB packets. If timeout
+ * is non-zero, write in band command will return after
+ * waiting unsuccessfully for the URB status to clear for
+ * timeout ticks. Returns 0 if successful, or a negative
+ * error returned by digi_write.
+ */
static int digi_write_inb_command(struct usb_serial_port *port,
unsigned char *buf, int count, unsigned long timeout)
timeout = ULONG_MAX;
spin_lock_irqsave(&priv->dp_port_lock, flags);
- while(count > 0 && ret == 0) {
- while((port->write_urb->status == -EINPROGRESS
- || priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) {
+ while (count > 0 && ret == 0) {
+ while ((port->write_urb->status == -EINPROGRESS
+ || priv->dp_write_urb_in_use)
+ && time_before(jiffies, timeout)) {
cond_wait_interruptible_timeout_irqrestore(
&port->write_wait, DIGI_RETRY_TIMEOUT,
&priv->dp_port_lock, flags);
}
port->write_urb->dev = port->serial->dev;
- if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {
+ ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+ if (ret == 0) {
priv->dp_write_urb_in_use = 1;
priv->dp_out_buf_len = 0;
count -= len;
/*
-* Digi Set Modem Signals
-*
-* Sets or clears DTR and RTS on the port, according to the
-* modem_signals argument. Use TIOCM_DTR and TIOCM_RTS flags
-* for the modem_signals argument. Returns 0 if successful,
-* -EINTR if interrupted while sleeping, or a non-zero error
-* returned by usb_submit_urb.
-*/
+ * Digi Set Modem Signals
+ *
+ * Sets or clears DTR and RTS on the port, according to the
+ * modem_signals argument. Use TIOCM_DTR and TIOCM_RTS flags
+ * for the modem_signals argument. Returns 0 if successful,
+ * -EINTR if interrupted while sleeping, or a non-zero error
+ * returned by usb_submit_urb.
+ */
static int digi_set_modem_signals(struct usb_serial_port *port,
unsigned int modem_signals, int interruptible)
int ret;
struct digi_port *port_priv = usb_get_serial_port_data(port);
- struct usb_serial_port *oob_port = (struct usb_serial_port *)((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port;
+ struct usb_serial_port *oob_port = (struct usb_serial_port *) ((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port;
struct digi_port *oob_priv = usb_get_serial_port_data(oob_port);
unsigned char *data = oob_port->write_urb->transfer_buffer;
unsigned long flags = 0;
spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
spin_lock(&port_priv->dp_port_lock);
- while(oob_port->write_urb->status == -EINPROGRESS || oob_priv->dp_write_urb_in_use) {
+ while (oob_port->write_urb->status == -EINPROGRESS ||
+ oob_priv->dp_write_urb_in_use) {
spin_unlock(&port_priv->dp_port_lock);
cond_wait_interruptible_timeout_irqrestore(
&oob_port->write_wait, DIGI_RETRY_TIMEOUT,
}
data[0] = DIGI_CMD_SET_DTR_SIGNAL;
data[1] = port_priv->dp_port_num;
- data[2] = (modem_signals&TIOCM_DTR) ? DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE;
+ data[2] = (modem_signals & TIOCM_DTR) ?
+ DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE;
data[3] = 0;
data[4] = DIGI_CMD_SET_RTS_SIGNAL;
data[5] = port_priv->dp_port_num;
- data[6] = (modem_signals&TIOCM_RTS) ? DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE;
+ data[6] = (modem_signals & TIOCM_RTS) ?
+ DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE;
data[7] = 0;
oob_port->write_urb->transfer_buffer_length = 8;
oob_port->write_urb->dev = port->serial->dev;
- if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) {
+ ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
+ if (ret == 0) {
oob_priv->dp_write_urb_in_use = 1;
port_priv->dp_modem_signals =
(port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS))
}
/*
-* Digi Transmit Idle
-*
-* Digi transmit idle waits, up to timeout ticks, for the transmitter
-* to go idle. It returns 0 if successful or a negative error.
-*
-* There are race conditions here if more than one process is calling
-* digi_transmit_idle on the same port at the same time. However, this
-* is only called from close, and only one process can be in close on a
-* port at a time, so its ok.
-*/
+ * Digi Transmit Idle
+ *
+ * Digi transmit idle waits, up to timeout ticks, for the transmitter
+ * to go idle. It returns 0 if successful or a negative error.
+ *
+ * There are race conditions here if more than one process is calling
+ * digi_transmit_idle on the same port at the same time. However, this
+ * is only called from close, and only one process can be in close on a
+ * port at a time, so its ok.
+ */
static int digi_transmit_idle(struct usb_serial_port *port,
unsigned long timeout)
timeout += jiffies;
- if ((ret = digi_write_inb_command(port, buf, 2, timeout - jiffies)) != 0)
+ ret = digi_write_inb_command(port, buf, 2, timeout - jiffies);
+ if (ret != 0)
return ret;
spin_lock_irqsave(&priv->dp_port_lock, flags);
- while(time_before(jiffies, timeout) && !priv->dp_transmit_idle) {
+ while (time_before(jiffies, timeout) && !priv->dp_transmit_idle) {
cond_wait_interruptible_timeout_irqrestore(
&priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT,
&priv->dp_port_lock, flags);
}
-static void digi_rx_throttle(struct usb_serial_port *port)
+static void digi_rx_throttle(struct tty_struct *tty)
{
unsigned long flags;
+ struct usb_serial_port *port = tty->driver_data;
struct digi_port *priv = usb_get_serial_port_data(port);
}
-static void digi_rx_unthrottle(struct usb_serial_port *port)
+static void digi_rx_unthrottle(struct tty_struct *tty)
{
int ret = 0;
unsigned long flags;
+ struct usb_serial_port *port = tty->driver_data;
struct digi_port *priv = usb_get_serial_port_data(port);
dbg("digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num);
}
-static void digi_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void digi_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
-
struct digi_port *priv = usb_get_serial_port_data(port);
- struct tty_struct *tty = port->tty;
unsigned int iflag = tty->termios->c_iflag;
unsigned int cflag = tty->termios->c_cflag;
unsigned int old_iflag = old_termios->c_iflag;
unsigned int old_cflag = old_termios->c_cflag;
unsigned char buf[32];
unsigned int modem_signals;
- int arg,ret;
+ int arg, ret;
int i = 0;
speed_t baud;
dbg("digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag);
/* set baud rate */
- if ((baud = tty_get_baud_rate(tty)) != tty_termios_baud_rate(old_termios)) {
+ baud = tty_get_baud_rate(tty);
+ if (baud != tty_termios_baud_rate(old_termios)) {
arg = -1;
/* reassert DTR and (maybe) RTS on transition from B0 */
digi_set_modem_signals(port, modem_signals, 1);
}
switch (baud) {
- /* drop DTR and RTS on transition to B0 */
- case 0: digi_set_modem_signals(port, 0, 1); break;
- case 50: arg = DIGI_BAUD_50; break;
- case 75: arg = DIGI_BAUD_75; break;
- case 110: arg = DIGI_BAUD_110; break;
- case 150: arg = DIGI_BAUD_150; break;
- case 200: arg = DIGI_BAUD_200; break;
- case 300: arg = DIGI_BAUD_300; break;
- case 600: arg = DIGI_BAUD_600; break;
- case 1200: arg = DIGI_BAUD_1200; break;
- case 1800: arg = DIGI_BAUD_1800; break;
- case 2400: arg = DIGI_BAUD_2400; break;
- case 4800: arg = DIGI_BAUD_4800; break;
- case 9600: arg = DIGI_BAUD_9600; break;
- case 19200: arg = DIGI_BAUD_19200; break;
- case 38400: arg = DIGI_BAUD_38400; break;
- case 57600: arg = DIGI_BAUD_57600; break;
- case 115200: arg = DIGI_BAUD_115200; break;
- case 230400: arg = DIGI_BAUD_230400; break;
- case 460800: arg = DIGI_BAUD_460800; break;
- default:
- arg = DIGI_BAUD_9600;
- baud = 9600;
- break;
+ /* drop DTR and RTS on transition to B0 */
+ case 0: digi_set_modem_signals(port, 0, 1); break;
+ case 50: arg = DIGI_BAUD_50; break;
+ case 75: arg = DIGI_BAUD_75; break;
+ case 110: arg = DIGI_BAUD_110; break;
+ case 150: arg = DIGI_BAUD_150; break;
+ case 200: arg = DIGI_BAUD_200; break;
+ case 300: arg = DIGI_BAUD_300; break;
+ case 600: arg = DIGI_BAUD_600; break;
+ case 1200: arg = DIGI_BAUD_1200; break;
+ case 1800: arg = DIGI_BAUD_1800; break;
+ case 2400: arg = DIGI_BAUD_2400; break;
+ case 4800: arg = DIGI_BAUD_4800; break;
+ case 9600: arg = DIGI_BAUD_9600; break;
+ case 19200: arg = DIGI_BAUD_19200; break;
+ case 38400: arg = DIGI_BAUD_38400; break;
+ case 57600: arg = DIGI_BAUD_57600; break;
+ case 115200: arg = DIGI_BAUD_115200; break;
+ case 230400: arg = DIGI_BAUD_230400; break;
+ case 460800: arg = DIGI_BAUD_460800; break;
+ default:
+ arg = DIGI_BAUD_9600;
+ baud = 9600;
+ break;
}
if (arg != -1) {
buf[i++] = DIGI_CMD_SET_BAUD_RATE;
buf[i++] = arg;
buf[i++] = 0;
}
- if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0)
+ ret = digi_write_oob_command(port, buf, i, 1);
+ if (ret != 0)
dbg("digi_set_termios: write oob failed, ret=%d", ret);
tty_encode_baud_rate(tty, baud, baud);
}
-static void digi_break_ctl(struct usb_serial_port *port, int break_state)
+static void digi_break_ctl(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned char buf[4];
buf[0] = DIGI_CMD_BREAK_CONTROL;
}
-static int digi_tiocmget(struct usb_serial_port *port, struct file *file)
+static int digi_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct digi_port *priv = usb_get_serial_port_data(port);
unsigned int val;
unsigned long flags;
}
-static int digi_tiocmset(struct usb_serial_port *port, struct file *file,
+static int digi_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct digi_port *priv = usb_get_serial_port_data(port);
unsigned int val;
unsigned long flags;
}
-static int digi_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct digi_port *priv = usb_get_serial_port_data(port);
- dbg("digi_ioctl: TOP: port=%d, cmd=0x%x", priv->dp_port_num, cmd);
-
- switch (cmd) {
- case TIOCMIWAIT:
- /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
- /* TODO */
- return 0;
- case TIOCGICOUNT:
- /* return count of modemline transitions */
- /* TODO */
- return 0;
- }
- return -ENOIOCTLCMD;
-
-}
-
-static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
- int ret,data_len,new_len;
+ int ret, data_len, new_len;
struct digi_port *priv = usb_get_serial_port_data(port);
unsigned char *data = port->write_urb->transfer_buffer;
unsigned long flags = 0;
spin_lock_irqsave(&priv->dp_port_lock, flags);
/* wait for urb status clear to submit another urb */
- if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) {
+ if (port->write_urb->status == -EINPROGRESS ||
+ priv->dp_write_urb_in_use) {
/* buffer data if count is 1 (probably put_char) if possible */
if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) {
priv->dp_out_buf[priv->dp_out_buf_len++] = *buf;
/* copy in new data */
memcpy(data, buf, new_len);
- if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {
+ ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+ if (ret == 0) {
priv->dp_write_urb_in_use = 1;
ret = new_len;
priv->dp_out_buf_len = 0;
dbg("digi_write: returning %d", ret);
return ret;
-}
+}
static void digi_write_bulk_callback(struct urb *urb)
{
dbg("digi_write_bulk_callback: TOP, urb->status=%d", status);
/* port and serial sanity check */
- if (port == NULL || (priv=usb_get_serial_port_data(port)) == NULL) {
+ if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
err("%s: port or port->private is NULL, status=%d",
__func__, status);
return;
}
serial = port->serial;
- if (serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL) {
+ if (serial == NULL || (serial_priv = usb_get_serial_data(serial)) == NULL) {
err("%s: serial or serial->private is NULL, status=%d",
__func__, status);
return;
/* try to send any buffered data on this port, if it is open */
spin_lock(&priv->dp_port_lock);
priv->dp_write_urb_in_use = 0;
- if (port->open_count && port->write_urb->status != -EINPROGRESS
+ if (port->port.count && port->write_urb->status != -EINPROGRESS
&& priv->dp_out_buf_len > 0) {
*((unsigned char *)(port->write_urb->transfer_buffer))
= (unsigned char)DIGI_CMD_SEND_DATA;
- *((unsigned char *)(port->write_urb->transfer_buffer)+1)
+ *((unsigned char *)(port->write_urb->transfer_buffer) + 1)
= (unsigned char)priv->dp_out_buf_len;
- port->write_urb->transfer_buffer_length = priv->dp_out_buf_len+2;
+ port->write_urb->transfer_buffer_length =
+ priv->dp_out_buf_len + 2;
port->write_urb->dev = serial->dev;
- memcpy(port->write_urb->transfer_buffer+2, priv->dp_out_buf,
+ memcpy(port->write_urb->transfer_buffer + 2, priv->dp_out_buf,
priv->dp_out_buf_len);
- if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {
+ ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+ if (ret == 0) {
priv->dp_write_urb_in_use = 1;
priv->dp_out_buf_len = 0;
}
__func__, ret, priv->dp_port_num);
}
-static int digi_write_room(struct usb_serial_port *port)
+static int digi_write_room(struct tty_struct *tty)
{
-
- int room;
+ struct usb_serial_port *port = tty->driver_data;
struct digi_port *priv = usb_get_serial_port_data(port);
+ int room;
unsigned long flags = 0;
spin_lock_irqsave(&priv->dp_port_lock, flags);
- if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use)
+ if (port->write_urb->status == -EINPROGRESS ||
+ priv->dp_write_urb_in_use)
room = 0;
else
room = port->bulk_out_size - 2 - priv->dp_out_buf_len;
}
-static int digi_chars_in_buffer(struct usb_serial_port *port)
+static int digi_chars_in_buffer(struct tty_struct *tty)
{
-
+ struct usb_serial_port *port = tty->driver_data;
struct digi_port *priv = usb_get_serial_port_data(port);
-
if (port->write_urb->status == -EINPROGRESS
|| priv->dp_write_urb_in_use) {
dbg("digi_chars_in_buffer: port=%d, chars=%d",
}
-static int digi_open(struct usb_serial_port *port, struct file *filp)
+static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
int ret;
unsigned char buf[32];
unsigned long flags = 0;
dbg("digi_open: TOP: port=%d, open_count=%d",
- priv->dp_port_num, port->open_count);
+ priv->dp_port_num, port->port.count);
/* be sure the device is started up */
if (digi_startup_device(port->serial) != 0)
}
/* wait for a close in progress to finish */
- while(priv->dp_in_close) {
+ while (priv->dp_in_close) {
cond_wait_interruptible_timeout_irqrestore(
&priv->dp_close_wait, DIGI_RETRY_TIMEOUT,
&priv->dp_port_lock, flags);
}
spin_unlock_irqrestore(&priv->dp_port_lock, flags);
-
+
/* read modem signals automatically whenever they change */
buf[0] = DIGI_CMD_READ_INPUT_SIGNALS;
buf[1] = priv->dp_port_num;
buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
buf[7] = 0;
- if ((ret = digi_write_oob_command(port, buf, 8, 1)) != 0)
+ ret = digi_write_oob_command(port, buf, 8, 1);
+ if (ret != 0)
dbg("digi_open: write oob failed, ret=%d", ret);
/* set termios settings */
- not_termios.c_cflag = ~port->tty->termios->c_cflag;
- not_termios.c_iflag = ~port->tty->termios->c_iflag;
- digi_set_termios(port, ¬_termios);
+ if (tty) {
+ not_termios.c_cflag = ~tty->termios->c_cflag;
+ not_termios.c_iflag = ~tty->termios->c_iflag;
+ digi_set_termios(tty, port, ¬_termios);
+ }
/* set DTR and RTS */
digi_set_modem_signals(port, TIOCM_DTR|TIOCM_RTS, 1);
}
-static void digi_close(struct usb_serial_port *port, struct file *filp)
+static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
DEFINE_WAIT(wait);
int ret;
unsigned char buf[32];
- struct tty_struct *tty = port->tty;
struct digi_port *priv = usb_get_serial_port_data(port);
dbg("digi_close: TOP: port=%d, open_count=%d",
- priv->dp_port_num, port->open_count);
+ priv->dp_port_num, port->port.count);
mutex_lock(&port->serial->disc_mutex);
/* if disconnected, just clear flags */
if (port->serial->dev) {
/* wait for transmit idle */
- if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) {
+ if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0)
digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT);
- }
/* drop DTR and RTS */
digi_set_modem_signals(port, 0, 0);
buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
buf[19] = 0;
- if ((ret = digi_write_oob_command(port, buf, 20, 0)) != 0)
+ ret = digi_write_oob_command(port, buf, 20, 0);
+ if (ret != 0)
dbg("digi_close: write oob failed, ret=%d", ret);
/* wait for final commands on oob port to complete */
- prepare_to_wait(&priv->dp_flush_wait, &wait, TASK_INTERRUPTIBLE);
+ prepare_to_wait(&priv->dp_flush_wait, &wait,
+ TASK_INTERRUPTIBLE);
schedule_timeout(DIGI_CLOSE_TIMEOUT);
finish_wait(&priv->dp_flush_wait, &wait);
/*
-* Digi Startup Device
-*
-* Starts reads on all ports. Must be called AFTER startup, with
-* urbs initialized. Returns 0 if successful, non-zero error otherwise.
-*/
+ * Digi Startup Device
+ *
+ * Starts reads on all ports. Must be called AFTER startup, with
+ * urbs initialized. Returns 0 if successful, non-zero error otherwise.
+ */
static int digi_startup_device(struct usb_serial *serial)
{
- int i,ret = 0;
+ int i, ret = 0;
struct digi_serial *serial_priv = usb_get_serial_data(serial);
struct usb_serial_port *port;
for (i = 0; i < serial->type->num_ports + 1; i++) {
port = serial->port[i];
port->write_urb->dev = port->serial->dev;
- if ((ret = usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0) {
+ ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
+ if (ret != 0) {
err("%s: usb_submit_urb failed, ret=%d, port=%d",
__func__, ret, i);
break;
/* allocate the private data structures for all ports */
/* number of regular ports + 1 for the out-of-band port */
- for(i = 0; i < serial->type->num_ports + 1; i++) {
+ for (i = 0; i < serial->type->num_ports + 1; i++) {
/* allocate port private structure */
priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL);
if (priv == NULL) {
/* free the private data structures for all ports */
/* number of regular ports + 1 for the out-of-band port */
- for(i = 0; i < serial->type->num_ports + 1; i++)
+ for (i = 0; i < serial->type->num_ports + 1; i++)
kfree(usb_get_serial_port_data(serial->port[i]));
kfree(usb_get_serial_data(serial));
}
return;
}
if (port->serial == NULL ||
- (serial_priv=usb_get_serial_data(port->serial)) == NULL) {
+ (serial_priv = usb_get_serial_data(port->serial)) == NULL) {
err("%s: serial is bad or serial->private is NULL, status=%d",
__func__, status);
return;
/* continue read */
urb->dev = port->serial->dev;
- if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret != 0) {
err("%s: failed resubmitting urb, ret=%d, port=%d",
__func__, ret, priv->dp_port_num);
}
}
-/*
-* Digi Read INB Callback
-*
-* Digi Read INB Callback handles reads on the in band ports, sending
-* the data on to the tty subsystem. When called we know port and
-* port->private are not NULL and port->serial has been validated.
-* It returns 0 if successful, 1 if successful but the port is
-* throttled, and -1 if the sanity checks failed.
-*/
+/*
+ * Digi Read INB Callback
+ *
+ * Digi Read INB Callback handles reads on the in band ports, sending
+ * the data on to the tty subsystem. When called we know port and
+ * port->private are not NULL and port->serial has been validated.
+ * It returns 0 if successful, 1 if successful but the port is
+ * throttled, and -1 if the sanity checks failed.
+ */
static int digi_read_inb_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
struct digi_port *priv = usb_get_serial_port_data(port);
int opcode = ((unsigned char *)urb->transfer_buffer)[0];
int len = ((unsigned char *)urb->transfer_buffer)[1];
int port_status = ((unsigned char *)urb->transfer_buffer)[2];
- unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3;
- int flag,throttled;
+ unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3;
+ int flag, throttled;
int i;
int status = urb->status;
/* do not process callbacks on closed ports */
/* but do continue the read chain */
- if (port->open_count == 0)
+ if (port->port.count == 0)
return 0;
/* short/multiple packet check */
if (urb->actual_length != len + 2) {
- err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, "
+ err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, "
"port=%d, opcode=%d, len=%d, actual_length=%d, "
"status=%d", __func__, status, priv->dp_port_num,
opcode, len, urb->actual_length, port_status);
if (flag == TTY_NORMAL)
tty_insert_flip_string(tty, data, len);
else {
- for(i = 0; i < len; i++)
- tty_insert_flip_char(tty, data[i], flag);
+ for (i = 0; i < len; i++)
+ tty_insert_flip_char(tty,
+ data[i], flag);
}
tty_flip_buffer_push(tty);
}
else if (opcode != DIGI_CMD_RECEIVE_DATA)
dbg("%s: unknown opcode: %d", __func__, opcode);
- return(throttled ? 1 : 0);
+ return throttled ? 1 : 0;
}
-/*
-* Digi Read OOB Callback
-*
-* Digi Read OOB Callback handles reads on the out of band port.
-* When called we know port and port->private are not NULL and
-* the port->serial is valid. It returns 0 if successful, and
-* -1 if the sanity checks failed.
-*/
+/*
+ * Digi Read OOB Callback
+ *
+ * Digi Read OOB Callback handles reads on the out of band port.
+ * When called we know port and port->private are not NULL and
+ * the port->serial is valid. It returns 0 if successful, and
+ * -1 if the sanity checks failed.
+ */
static int digi_read_oob_callback(struct urb *urb)
{
struct digi_port *priv = usb_get_serial_port_data(port);
int opcode, line, status, val;
int i;
+ unsigned int rts;
dbg("digi_read_oob_callback: port=%d, len=%d",
priv->dp_port_num, urb->actual_length);
/* handle each oob command */
- for(i = 0; i < urb->actual_length - 3;) {
+ for (i = 0; i < urb->actual_length - 3;) {
opcode = ((unsigned char *)urb->transfer_buffer)[i++];
line = ((unsigned char *)urb->transfer_buffer)[i++];
status = ((unsigned char *)urb->transfer_buffer)[i++];
port = serial->port[line];
- if ((priv=usb_get_serial_port_data(port)) == NULL)
+ priv = usb_get_serial_port_data(port);
+ if (priv == NULL)
return -1;
+ rts = 0;
+ if (port->port.count)
+ rts = port->port.tty->termios->c_cflag & CRTSCTS;
+
if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) {
spin_lock(&priv->dp_port_lock);
/* convert from digi flags to termiox flags */
if (val & DIGI_READ_INPUT_SIGNALS_CTS) {
priv->dp_modem_signals |= TIOCM_CTS;
/* port must be open to use tty struct */
- if (port->open_count
- && port->tty->termios->c_cflag & CRTSCTS) {
- port->tty->hw_stopped = 0;
+ if (rts) {
+ port->port.tty->hw_stopped = 0;
digi_wakeup_write(port);
}
} else {
priv->dp_modem_signals &= ~TIOCM_CTS;
/* port must be open to use tty struct */
- if (port->open_count
- && port->tty->termios->c_cflag & CRTSCTS) {
- port->tty->hw_stopped = 1;
- }
+ if (rts)
+ port->port.tty->hw_stopped = 1;
}
if (val & DIGI_READ_INPUT_SIGNALS_DSR)
priv->dp_modem_signals |= TIOCM_DSR;
if (retval)
goto failed_acceleport_2_device;
retval = usb_serial_register(&digi_acceleport_4_device);
- if (retval)
+ if (retval)
goto failed_acceleport_4_device;
retval = usb_register(&digi_driver);
if (retval)
* it under the terms of the GNU General Public License, as published by
* the Free Software Foundation, version 2.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
- *
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
+ *
* (07/16/2001) gb
- * remove unused code in empeg_close() (thanks to Oliver Neukum for pointing this
- * out) and rewrote empeg_set_termios().
- *
+ * remove unused code in empeg_close() (thanks to Oliver Neukum for
+ * pointing this out) and rewrote empeg_set_termios().
+ *
* (05/30/2001) gkh
- * switched from using spinlock to a semaphore, which fixes lots of problems.
+ * switched from using spinlock to a semaphore, which fixes lots of
+ * problems.
*
* (04/08/2001) gb
* Identify version on module load.
- *
+ *
* (01/22/2001) gb
- * Added write_room() and chars_in_buffer() support.
- *
+ * Added write_room() and chars_in_buffer() support.
+ *
* (12/21/2000) gb
* Moved termio stuff inside the port->active check.
* Moved MOD_DEC_USE_COUNT to end of empeg_close().
- *
+ *
* (12/03/2000) gb
- * Added port->tty->ldisc.set_termios(port->tty, NULL) to empeg_open()
- * This notifies the tty driver that the termios have changed.
- *
+ * Added port->port.tty->ldisc.set_termios(port->port.tty, NULL) to
+ * empeg_open(). This notifies the tty driver that the termios have
+ * changed.
+ *
* (11/13/2000) gb
- * Moved tty->low_latency = 1 from empeg_read_bulk_callback() to empeg_open()
- * (It only needs to be set once - Doh!)
- *
+ * Moved tty->low_latency = 1 from empeg_read_bulk_callback() to
+ * empeg_open() (It only needs to be set once - Doh!)
+ *
* (11/11/2000) gb
* Updated to work with id_table structure.
- *
+ *
* (11/04/2000) gb
* Forked this from visor.c, and hacked it up to work with an
* Empeg ltd. empeg-car player. Constructive criticism welcomed.
* use of his code, and for his guidance, advice and patience. :)
* A 'Thank You' is in order for John Ripley of Empeg ltd for his
* advice, and patience too.
- *
+ *
*/
#include <linux/kernel.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#define EMPEG_PRODUCT_ID 0x0001
/* function prototypes for an empeg-car player */
-static int empeg_open (struct usb_serial_port *port, struct file *filp);
-static void empeg_close (struct usb_serial_port *port, struct file *filp);
-static int empeg_write (struct usb_serial_port *port,
- const unsigned char *buf,
- int count);
-static int empeg_write_room (struct usb_serial_port *port);
-static int empeg_chars_in_buffer (struct usb_serial_port *port);
-static void empeg_throttle (struct usb_serial_port *port);
-static void empeg_unthrottle (struct usb_serial_port *port);
-static int empeg_startup (struct usb_serial *serial);
-static void empeg_shutdown (struct usb_serial *serial);
-static int empeg_ioctl (struct usb_serial_port *port,
- struct file * file,
- unsigned int cmd,
- unsigned long arg);
-static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
-static void empeg_write_bulk_callback (struct urb *urb);
-static void empeg_read_bulk_callback (struct urb *urb);
+static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf,
+ int count);
+static int empeg_write_room(struct tty_struct *tty);
+static int empeg_chars_in_buffer(struct tty_struct *tty);
+static void empeg_throttle(struct tty_struct *tty);
+static void empeg_unthrottle(struct tty_struct *tty);
+static int empeg_startup(struct usb_serial *serial);
+static void empeg_shutdown(struct usb_serial *serial);
+static void empeg_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios);
+static void empeg_write_bulk_callback(struct urb *urb);
+static void empeg_read_bulk_callback(struct urb *urb);
static struct usb_device_id id_table [] = {
{ USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) },
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver empeg_driver = {
.name = "empeg",
.unthrottle = empeg_unthrottle,
.attach = empeg_startup,
.shutdown = empeg_shutdown,
- .ioctl = empeg_ioctl,
.set_termios = empeg_set_termios,
.write = empeg_write,
.write_room = empeg_write_room,
/******************************************************************************
* Empeg specific driver functions
******************************************************************************/
-static int empeg_open (struct usb_serial_port *port, struct file *filp)
+static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
struct usb_serial *serial = port->serial;
int result = 0;
dbg("%s - port %d", __func__, port->number);
/* Force default termio settings */
- empeg_set_termios (port, NULL) ;
+ empeg_set_termios(tty, port, NULL) ;
bytes_in = 0;
bytes_out = 0;
/* Start reading from the device */
usb_fill_bulk_urb(
port->read_urb,
- serial->dev,
+ serial->dev,
usb_rcvbulkpipe(serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
- dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
return result;
}
-static void empeg_close (struct usb_serial_port *port, struct file * filp)
+static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
dbg("%s - port %d", __func__, port->number);
}
-static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
struct usb_serial *serial = port->serial;
struct urb *urb;
dbg("%s - port %d", __func__, port->number);
while (count > 0) {
-
/* try to find a free urb in our list of them */
urb = NULL;
- spin_lock_irqsave (&write_urb_pool_lock, flags);
+ spin_lock_irqsave(&write_urb_pool_lock, flags);
for (i = 0; i < NUM_URBS; ++i) {
if (write_urb_pool[i]->status != -EINPROGRESS) {
}
}
- spin_unlock_irqrestore (&write_urb_pool_lock, flags);
+ spin_unlock_irqrestore(&write_urb_pool_lock, flags);
if (urb == NULL) {
dbg("%s - no more free urbs", __func__);
}
if (urb->transfer_buffer == NULL) {
- urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
+ urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
if (urb->transfer_buffer == NULL) {
- dev_err(&port->dev, "%s no more kernel memory...\n", __func__);
+ dev_err(&port->dev,
+ "%s no more kernel memory...\n",
+ __func__);
goto exit;
}
}
- transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);
+ transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
- memcpy (urb->transfer_buffer, current_position, transfer_size);
+ memcpy(urb->transfer_buffer, current_position, transfer_size);
usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, urb->transfer_buffer);
/* build up our urb */
- usb_fill_bulk_urb (
+ usb_fill_bulk_urb(
urb,
serial->dev,
usb_sndbulkpipe(serial->dev,
- port->bulk_out_endpointAddress),
+ port->bulk_out_endpointAddress),
urb->transfer_buffer,
transfer_size,
empeg_write_bulk_callback,
bytes_out += transfer_size;
}
-
exit:
return bytes_sent;
-
-}
+}
-static int empeg_write_room (struct usb_serial_port *port)
+static int empeg_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned long flags;
int i;
int room = 0;
dbg("%s - port %d", __func__, port->number);
- spin_lock_irqsave (&write_urb_pool_lock, flags);
-
+ spin_lock_irqsave(&write_urb_pool_lock, flags);
/* tally up the number of bytes available */
for (i = 0; i < NUM_URBS; ++i) {
- if (write_urb_pool[i]->status != -EINPROGRESS) {
+ if (write_urb_pool[i]->status != -EINPROGRESS)
room += URB_TRANSFER_BUFFER_SIZE;
- }
- }
-
- spin_unlock_irqrestore (&write_urb_pool_lock, flags);
-
+ }
+ spin_unlock_irqrestore(&write_urb_pool_lock, flags);
dbg("%s - returns %d", __func__, room);
-
- return (room);
+ return room;
}
-static int empeg_chars_in_buffer (struct usb_serial_port *port)
+static int empeg_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned long flags;
int i;
int chars = 0;
dbg("%s - port %d", __func__, port->number);
- spin_lock_irqsave (&write_urb_pool_lock, flags);
+ spin_lock_irqsave(&write_urb_pool_lock, flags);
/* tally up the number of bytes waiting */
for (i = 0; i < NUM_URBS; ++i) {
- if (write_urb_pool[i]->status == -EINPROGRESS) {
+ if (write_urb_pool[i]->status == -EINPROGRESS)
chars += URB_TRANSFER_BUFFER_SIZE;
- }
}
- spin_unlock_irqrestore (&write_urb_pool_lock, flags);
-
+ spin_unlock_irqrestore(&write_urb_pool_lock, flags);
dbg("%s - returns %d", __func__, chars);
-
- return (chars);
-
+ return chars;
}
-static void empeg_write_bulk_callback (struct urb *urb)
+static void empeg_write_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
int status = urb->status;
}
-static void empeg_read_bulk_callback (struct urb *urb)
+static void empeg_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct tty_struct *tty;
return;
}
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
-
- tty = port->tty;
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
+ tty = port->port.tty;
if (urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
/* Continue trying to always read */
usb_fill_bulk_urb(
port->read_urb,
- port->serial->dev,
+ port->serial->dev,
usb_rcvbulkpipe(port->serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
+ dev_err(&urb->dev->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
return;
}
-static void empeg_throttle (struct usb_serial_port *port)
+static void empeg_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __func__, port->number);
usb_kill_urb(port->read_urb);
}
-static void empeg_unthrottle (struct usb_serial_port *port)
+static void empeg_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
int result;
-
dbg("%s - port %d", __func__, port->number);
port->read_urb->dev = port->serial->dev;
-
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
-
if (result)
- dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
-
- return;
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
}
-static int empeg_startup (struct usb_serial *serial)
+static int empeg_startup(struct usb_serial *serial)
{
int r;
return -ENODEV;
}
dbg("%s - reset config", __func__);
- r = usb_reset_configuration (serial->dev);
+ r = usb_reset_configuration(serial->dev);
/* continue on with initialization */
return r;
}
-static void empeg_shutdown (struct usb_serial *serial)
+static void empeg_shutdown(struct usb_serial *serial)
{
- dbg ("%s", __func__);
-}
-
-
-static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
-{
- dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
-
- return -ENOIOCTLCMD;
+ dbg("%s", __func__);
}
-static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void empeg_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
- struct ktermios *termios = port->tty->termios;
+ struct ktermios *termios = tty->termios;
dbg("%s - port %d", __func__, port->number);
/*
- * The empeg-car player wants these particular tty settings.
- * You could, for example, change the baud rate, however the
- * player only supports 115200 (currently), so there is really
- * no point in support for changes to the tty settings.
- * (at least for now)
- *
- * The default requirements for this device are:
- */
+ * The empeg-car player wants these particular tty settings.
+ * You could, for example, change the baud rate, however the
+ * player only supports 115200 (currently), so there is really
+ * no point in support for changes to the tty settings.
+ * (at least for now)
+ *
+ * The default requirements for this device are:
+ */
termios->c_iflag
&= ~(IGNBRK /* disable ignore break */
| BRKINT /* disable break causes interrupt */
* this is bad as it opens up the possibility of dropping bytes
* on the floor. We don't want to drop bytes on the floor. :)
*/
- port->tty->low_latency = 1;
- tty_encode_baud_rate(port->tty, 115200, 115200);
+ tty->low_latency = 1;
+ tty_encode_baud_rate(tty, 115200, 115200);
}
-static int __init empeg_init (void)
+static int __init empeg_init(void)
{
struct urb *urb;
int i, retval;
- /* create our write urb pool and transfer buffers */
- spin_lock_init (&write_urb_pool_lock);
+ /* create our write urb pool and transfer buffers */
+ spin_lock_init(&write_urb_pool_lock);
for (i = 0; i < NUM_URBS; ++i) {
urb = usb_alloc_urb(0, GFP_KERNEL);
write_urb_pool[i] = urb;
continue;
}
- urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+ urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
+ GFP_KERNEL);
if (!urb->transfer_buffer) {
- err("%s - out of memory for urb buffers.",
+ err("%s - out of memory for urb buffers.",
__func__);
continue;
}
}
-static void __exit empeg_exit (void)
+static void __exit empeg_exit(void)
{
int i;
unsigned long flags;
usb_deregister(&empeg_driver);
- usb_serial_deregister (&empeg_device);
+ usb_serial_deregister(&empeg_device);
- spin_lock_irqsave (&write_urb_pool_lock, flags);
+ spin_lock_irqsave(&write_urb_pool_lock, flags);
for (i = 0; i < NUM_URBS; ++i) {
if (write_urb_pool[i]) {
- /* FIXME - uncomment the following usb_kill_urb call when
- * the host controllers get fixed to set urb->dev = NULL after
- * the urb is finished. Otherwise this call oopses. */
+ /* FIXME - uncomment the following usb_kill_urb call
+ * when the host controllers get fixed to set urb->dev
+ * = NULL after the urb is finished. Otherwise this
+ * call oopses. */
/* usb_kill_urb(write_urb_pool[i]); */
kfree(write_urb_pool[i]->transfer_buffer);
- usb_free_urb (write_urb_pool[i]);
+ usb_free_urb(write_urb_pool[i]);
}
}
-
- spin_unlock_irqrestore (&write_urb_pool_lock, flags);
+ spin_unlock_irqrestore(&write_urb_pool_lock, flags);
}
module_init(empeg_init);
module_exit(empeg_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
#define CPUCS_REG 0x7F92
-int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest)
+int ezusb_writememory(struct usb_serial *serial, int address,
+ unsigned char *data, int length, __u8 request)
{
int result;
unsigned char *transfer_buffer;
transfer_buffer = kmemdup(data, length, GFP_KERNEL);
if (!transfer_buffer) {
- dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, length);
+ dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n",
+ __func__, length);
return -ENOMEM;
}
- result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 3000);
- kfree (transfer_buffer);
+ result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ request, 0x40, address, 0, transfer_buffer, length, 3000);
+ kfree(transfer_buffer);
return result;
}
+EXPORT_SYMBOL_GPL(ezusb_writememory);
-int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit)
+int ezusb_set_reset(struct usb_serial *serial, unsigned char reset_bit)
{
int response;
/* dbg("%s - %d", __func__, reset_bit); */
- response = ezusb_writememory (serial, CPUCS_REG, &reset_bit, 1, 0xa0);
+ response = ezusb_writememory(serial, CPUCS_REG, &reset_bit, 1, 0xa0);
if (response < 0)
- dev_err(&serial->dev->dev, "%s- %d failed\n", __func__, reset_bit);
+ dev_err(&serial->dev->dev, "%s- %d failed\n",
+ __func__, reset_bit);
return response;
}
-
-
-EXPORT_SYMBOL_GPL(ezusb_writememory);
EXPORT_SYMBOL_GPL(ezusb_set_reset);
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
* See http://ftdi-usb-sio.sourceforge.net for upto date testing info
* and extra documentation
/* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */
/* Thanx to FTDI for so kindly providing details of the protocol required */
/* to talk to the device */
-/* Thanx to gkh and the rest of the usb dev group for all code I have assimilated :-) */
+/* Thanx to gkh and the rest of the usb dev group for all code I have
+ assimilated :-) */
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/serial.h>
#include <linux/usb/serial.h>
struct ftdi_private {
ftdi_chip_type_t chip_type;
- /* type of the device, either SIO or FT8U232AM */
+ /* type of device, either SIO or FT8U232AM */
int baud_base; /* baud base clock for divisor setting */
- int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */
+ int custom_divisor; /* custom_divisor kludge, this is for
+ baud_base (different from what goes to the
+ chip!) */
__u16 last_set_data_urb_value ;
- /* the last data state set - needed for doing a break */
- int write_offset; /* This is the offset in the usb data block to write the serial data -
- * it is different between devices
+ /* the last data state set - needed for doing
+ * a break
+ */
+ int write_offset; /* This is the offset in the usb data block to
+ * write the serial data - it varies between
+ * devices
*/
int flags; /* some ASYNC_xxxx flags are supported */
unsigned long last_dtr_rts; /* saved modem control outputs */
- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+ wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
char prev_status, diff_status; /* Used for TIOCMIWAIT */
__u8 rx_flags; /* receive state flags (throttling) */
spinlock_t rx_lock; /* spinlock for receive state */
__u16 interface; /* FT2232C port interface (0 for FT232/245) */
- speed_t force_baud; /* if non-zero, force the baud rate to this value */
- int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
+ speed_t force_baud; /* if non-zero, force the baud rate to
+ this value */
+ int force_rtscts; /* if non-zero, force RTS-CTS to always
+ be enabled */
spinlock_t tx_lock; /* spinlock for transmit state */
unsigned long tx_bytes;
/* struct ftdi_sio_quirk is used by devices requiring special attention. */
struct ftdi_sio_quirk {
int (*probe)(struct usb_serial *);
- void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */
+ /* Special settings for probed ports. */
+ void (*port_probe)(struct ftdi_private *);
};
-static int ftdi_jtag_probe (struct usb_serial *serial);
-static int ftdi_mtxorb_hack_setup (struct usb_serial *serial);
-static void ftdi_USB_UIRT_setup (struct ftdi_private *priv);
-static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv);
+static int ftdi_jtag_probe(struct usb_serial *serial);
+static int ftdi_mtxorb_hack_setup(struct usb_serial *serial);
+static void ftdi_USB_UIRT_setup(struct ftdi_private *priv);
+static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
static struct ftdi_sio_quirk ftdi_jtag_quirk = {
.probe = ftdi_jtag_probe,
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0100_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0101_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0102_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0103_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0104_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0105_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0106_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0107_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0108_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0109_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010C_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0110_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0111_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0112_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0113_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0114_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0115_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0116_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0117_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0118_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0119_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011C_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0120_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0121_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0122_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0123_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0124_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0125_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0126_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0127_PID),
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0103_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0104_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0105_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0106_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0107_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0108_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0109_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0110_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0111_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0112_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0113_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0114_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0115_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0116_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0117_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0118_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0119_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0120_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0121_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0122_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0123_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0124_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0125_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0126_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0127_PID),
.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0128_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0129_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012C_PID),
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0128_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0129_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012C_PID),
.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0130_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0131_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0132_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0133_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0134_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0135_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0136_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0137_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0138_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0139_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013C_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0140_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0141_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0142_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0143_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0144_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0145_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0146_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0147_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0148_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0149_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014C_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0150_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0151_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0152_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0153_PID),
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0130_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0131_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0132_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0133_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0134_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0135_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0136_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0137_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0138_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0139_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0140_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0141_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0142_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0143_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0144_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0145_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0146_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0147_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0148_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0149_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0150_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0151_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0152_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0153_PID),
.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0154_PID),
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0154_PID),
.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0155_PID),
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0155_PID),
.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0156_PID),
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0156_PID),
.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0157_PID),
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0157_PID),
.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0158_PID),
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0158_PID),
.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0159_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015C_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0160_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0161_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0162_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0163_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0164_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0165_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0166_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0167_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0168_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0169_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016C_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0170_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0171_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0172_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0173_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0174_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0175_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0176_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0177_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0178_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0179_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017C_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0180_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0181_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0182_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0183_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0184_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0185_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0186_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0187_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0188_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0189_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018C_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0190_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0191_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0192_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0193_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0194_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0195_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0196_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0197_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0198_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0199_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019A_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019B_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019C_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019D_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019E_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019F_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A0_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A1_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A2_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A3_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A4_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A5_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A6_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A7_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A8_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A9_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AA_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AB_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AC_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AD_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AE_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AF_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B0_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B1_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B2_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B3_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B4_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B5_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B6_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B7_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B8_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B9_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BA_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BB_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BC_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BD_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BE_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BF_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C0_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C1_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C2_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C3_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C4_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C5_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C6_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C7_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C8_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C9_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CA_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CB_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CC_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CD_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CE_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CF_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D0_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D1_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D2_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D3_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D4_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D5_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D6_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D7_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D8_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D9_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DA_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DB_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DC_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DD_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DE_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DF_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E0_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E1_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E2_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E3_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E4_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E5_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E6_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E7_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E8_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E9_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EA_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EB_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EC_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01ED_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EE_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EF_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F0_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F1_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F2_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F3_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F4_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F5_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F6_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F7_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F8_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F9_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FA_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FB_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FC_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FD_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FE_PID) },
- { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0159_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0160_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0161_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0162_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0163_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0164_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0165_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0166_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0167_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0168_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0169_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0170_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0171_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0172_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0173_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0174_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0175_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0176_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0177_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0178_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0179_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0180_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0181_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0182_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0183_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0184_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0185_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0186_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0187_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0188_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0189_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0190_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0191_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0192_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0193_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0194_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0195_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0196_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0197_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0198_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0199_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019A_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019B_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019C_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019D_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019E_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019F_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01ED_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EF_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F0_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F1_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F2_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F3_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F4_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F5_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F6_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F7_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F8_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F9_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FA_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FB_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FC_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FD_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FE_PID) },
+ { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FF_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver ftdi_driver = {
.name = "ftdi_sio",
| ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP)
/* function prototypes for a FTDI serial converter */
-static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id);
-static void ftdi_shutdown (struct usb_serial *serial);
-static int ftdi_sio_port_probe (struct usb_serial_port *port);
-static int ftdi_sio_port_remove (struct usb_serial_port *port);
-static int ftdi_open (struct usb_serial_port *port, struct file *filp);
-static void ftdi_close (struct usb_serial_port *port, struct file *filp);
-static int ftdi_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int ftdi_write_room (struct usb_serial_port *port);
-static int ftdi_chars_in_buffer (struct usb_serial_port *port);
-static void ftdi_write_bulk_callback (struct urb *urb);
-static void ftdi_read_bulk_callback (struct urb *urb);
-static void ftdi_process_read (struct work_struct *work);
-static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios * old);
-static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file);
-static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear);
-static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void ftdi_break_ctl (struct usb_serial_port *port, int break_state );
-static void ftdi_throttle (struct usb_serial_port *port);
-static void ftdi_unthrottle (struct usb_serial_port *port);
-
-static unsigned short int ftdi_232am_baud_base_to_divisor (int baud, int base);
-static unsigned short int ftdi_232am_baud_to_divisor (int baud);
-static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base);
-static __u32 ftdi_232bm_baud_to_divisor (int baud);
+static int ftdi_sio_probe(struct usb_serial *serial,
+ const struct usb_device_id *id);
+static void ftdi_shutdown(struct usb_serial *serial);
+static int ftdi_sio_port_probe(struct usb_serial_port *port);
+static int ftdi_sio_port_remove(struct usb_serial_port *port);
+static int ftdi_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void ftdi_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+static int ftdi_write_room(struct tty_struct *tty);
+static int ftdi_chars_in_buffer(struct tty_struct *tty);
+static void ftdi_write_bulk_callback(struct urb *urb);
+static void ftdi_read_bulk_callback(struct urb *urb);
+static void ftdi_process_read(struct work_struct *work);
+static void ftdi_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
+static int ftdi_tiocmget(struct tty_struct *tty, struct file *file);
+static int ftdi_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static int ftdi_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
+static void ftdi_throttle(struct tty_struct *tty);
+static void ftdi_unthrottle(struct tty_struct *tty);
+
+static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base);
+static unsigned short int ftdi_232am_baud_to_divisor(int baud);
+static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base);
+static __u32 ftdi_232bm_baud_to_divisor(int baud);
static struct usb_serial_driver ftdi_sio_device = {
.driver = {
static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base)
{
unsigned short int divisor;
- int divisor3 = base / 2 / baud; // divisor shifted 3 bits to the left
- if ((divisor3 & 0x7) == 7) divisor3 ++; // round x.7/8 up to x+1
+ /* divisor shifted 3 bits to the left */
+ int divisor3 = base / 2 / baud;
+ if ((divisor3 & 0x7) == 7)
+ divisor3++; /* round x.7/8 up to x+1 */
divisor = divisor3 >> 3;
divisor3 &= 0x7;
- if (divisor3 == 1) divisor |= 0xc000; else // 0.125
- if (divisor3 >= 4) divisor |= 0x4000; else // 0.5
- if (divisor3 != 0) divisor |= 0x8000; // 0.25
- if (divisor == 1) divisor = 0; /* special case for maximum baud rate */
+ if (divisor3 == 1)
+ divisor |= 0xc000;
+ else if (divisor3 >= 4)
+ divisor |= 0x4000;
+ else if (divisor3 != 0)
+ divisor |= 0x8000;
+ else if (divisor == 1)
+ divisor = 0; /* special case for maximum baud rate */
return divisor;
}
static unsigned short int ftdi_232am_baud_to_divisor(int baud)
{
- return(ftdi_232am_baud_base_to_divisor(baud, 48000000));
+ return ftdi_232am_baud_base_to_divisor(baud, 48000000);
}
static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base)
{
static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
__u32 divisor;
- int divisor3 = base / 2 / baud; // divisor shifted 3 bits to the left
+ /* divisor shifted 3 bits to the left */
+ int divisor3 = base / 2 / baud;
divisor = divisor3 >> 3;
divisor |= (__u32)divfrac[divisor3 & 0x7] << 14;
/* Deal with special cases for highest baud rates. */
- if (divisor == 1) divisor = 0; else // 1.0
- if (divisor == 0x4001) divisor = 1; // 1.5
+ if (divisor == 1)
+ divisor = 0;
+ else if (divisor == 0x4001)
+ divisor = 1;
return divisor;
}
static __u32 ftdi_232bm_baud_to_divisor(int baud)
{
- return(ftdi_232bm_baud_base_to_divisor(baud, 48000000));
+ return ftdi_232bm_baud_base_to_divisor(baud, 48000000);
}
#define set_mctrl(port, set) update_mctrl((port), (set), 0)
#define clear_mctrl(port, clear) update_mctrl((port), 0, (clear))
-static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned int clear)
+static int update_mctrl(struct usb_serial_port *port, unsigned int set,
+ unsigned int clear)
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
char *buf;
}
-static __u32 get_ftdi_divisor(struct usb_serial_port * port);
-
-
-static int change_speed(struct usb_serial_port *port)
-{
- struct ftdi_private *priv = usb_get_serial_port_data(port);
- char *buf;
- __u16 urb_value;
- __u16 urb_index;
- __u32 urb_index_value;
- int rv;
-
- buf = kmalloc(1, GFP_NOIO);
- if (!buf)
- return -ENOMEM;
-
- urb_index_value = get_ftdi_divisor(port);
- urb_value = (__u16)urb_index_value;
- urb_index = (__u16)(urb_index_value >> 16);
- if (priv->interface) { /* FT2232C */
- urb_index = (__u16)((urb_index << 8) | priv->interface);
- }
-
- rv = usb_control_msg(port->serial->dev,
- usb_sndctrlpipe(port->serial->dev, 0),
- FTDI_SIO_SET_BAUDRATE_REQUEST,
- FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
- urb_value, urb_index,
- buf, 0, WDR_SHORT_TIMEOUT);
-
- kfree(buf);
- return rv;
-}
-
-
-static __u32 get_ftdi_divisor(struct usb_serial_port * port)
+static __u32 get_ftdi_divisor(struct tty_struct *tty,
+ struct usb_serial_port *port)
{ /* get_ftdi_divisor */
struct ftdi_private *priv = usb_get_serial_port_data(port);
__u32 div_value = 0;
int baud;
/*
- * The logic involved in setting the baudrate can be cleanly split in 3 steps.
- * Obtaining the actual baud rate is a little tricky since unix traditionally
- * somehow ignored the possibility to set non-standard baud rates.
+ * The logic involved in setting the baudrate can be cleanly split into
+ * 3 steps.
* 1. Standard baud rates are set in tty->termios->c_cflag
- * 2. If these are not enough, you can set any speed using alt_speed as follows:
+ * 2. If these are not enough, you can set any speed using alt_speed as
+ * follows:
* - set tty->termios->c_cflag speed to B38400
* - set your real speed in tty->alt_speed; it gets ignored when
* alt_speed==0, (or)
- * - call TIOCSSERIAL ioctl with (struct serial_struct) set as follows:
- * flags & ASYNC_SPD_MASK == ASYNC_SPD_[HI, VHI, SHI, WARP], this just
- * sets alt_speed to (HI: 57600, VHI: 115200, SHI: 230400, WARP: 460800)
+ * - call TIOCSSERIAL ioctl with (struct serial_struct) set as
+ * follows:
+ * flags & ASYNC_SPD_MASK == ASYNC_SPD_[HI, VHI, SHI, WARP],
+ * this just sets alt_speed to (HI: 57600, VHI: 115200,
+ * SHI: 230400, WARP: 460800)
* ** Steps 1, 2 are done courtesy of tty_get_baud_rate
* 3. You can also set baud rate by setting custom divisor as follows
* - set tty->termios->c_cflag speed to B38400
- * - call TIOCSSERIAL ioctl with (struct serial_struct) set as follows:
+ * - call TIOCSSERIAL ioctl with (struct serial_struct) set as
+ * follows:
* o flags & ASYNC_SPD_MASK == ASYNC_SPD_CUST
* o custom_divisor set to baud_base / your_new_baudrate
- * ** Step 3 is done courtesy of code borrowed from serial.c - I should really
- * spend some time and separate+move this common code to serial.c, it is
- * replicated in nearly every serial driver you see.
+ * ** Step 3 is done courtesy of code borrowed from serial.c
+ * I should really spend some time and separate + move this common
+ * code to serial.c, it is replicated in nearly every serial driver
+ * you see.
*/
- /* 1. Get the baud rate from the tty settings, this observes alt_speed hack */
+ /* 1. Get the baud rate from the tty settings, this observes
+ alt_speed hack */
- baud = tty_get_baud_rate(port->tty);
+ baud = tty_get_baud_rate(tty);
dbg("%s - tty_get_baud_rate reports speed %d", __func__, baud);
- /* 2. Observe async-compatible custom_divisor hack, update baudrate if needed */
+ /* 2. Observe async-compatible custom_divisor hack, update baudrate
+ if needed */
if (baud == 38400 &&
((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
(priv->custom_divisor)) {
baud = priv->baud_base / priv->custom_divisor;
- dbg("%s - custom divisor %d sets baud rate to %d", __func__, priv->custom_divisor, baud);
+ dbg("%s - custom divisor %d sets baud rate to %d",
+ __func__, priv->custom_divisor, baud);
}
/* 3. Convert baudrate to device-specific divisor */
- if (!baud) baud = 9600;
- switch(priv->chip_type) {
+ if (!baud)
+ baud = 9600;
+ switch (priv->chip_type) {
case SIO: /* SIO chip */
- switch(baud) {
+ switch (baud) {
case 300: div_value = ftdi_sio_b300; break;
case 600: div_value = ftdi_sio_b600; break;
case 1200: div_value = ftdi_sio_b1200; break;
case 115200: div_value = ftdi_sio_b115200; break;
} /* baud */
if (div_value == 0) {
- dbg("%s - Baudrate (%d) requested is not supported", __func__, baud);
+ dbg("%s - Baudrate (%d) requested is not supported",
+ __func__, baud);
div_value = ftdi_sio_b9600;
baud = 9600;
div_okay = 0;
if (baud <= 3000000) {
div_value = ftdi_232am_baud_to_divisor(baud);
} else {
- dbg("%s - Baud rate too high!", __func__);
+ dbg("%s - Baud rate too high!", __func__);
baud = 9600;
div_value = ftdi_232am_baud_to_divisor(9600);
div_okay = 0;
if (baud <= 3000000) {
div_value = ftdi_232bm_baud_to_divisor(baud);
} else {
- dbg("%s - Baud rate too high!", __func__);
+ dbg("%s - Baud rate too high!", __func__);
div_value = ftdi_232bm_baud_to_divisor(9600);
div_okay = 0;
baud = 9600;
ftdi_chip_name[priv->chip_type]);
}
- tty_encode_baud_rate(port->tty, baud, baud);
- return(div_value);
+ tty_encode_baud_rate(tty, baud, baud);
+ return div_value;
+}
+
+static int change_speed(struct tty_struct *tty, struct usb_serial_port *port)
+{
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ char *buf;
+ __u16 urb_value;
+ __u16 urb_index;
+ __u32 urb_index_value;
+ int rv;
+
+ buf = kmalloc(1, GFP_NOIO);
+ if (!buf)
+ return -ENOMEM;
+
+ urb_index_value = get_ftdi_divisor(tty, port);
+ urb_value = (__u16)urb_index_value;
+ urb_index = (__u16)(urb_index_value >> 16);
+ if (priv->interface) { /* FT2232C */
+ urb_index = (__u16)((urb_index << 8) | priv->interface);
+ }
+
+ rv = usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ FTDI_SIO_SET_BAUDRATE_REQUEST,
+ FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
+ urb_value, urb_index,
+ buf, 0, WDR_SHORT_TIMEOUT);
+
+ kfree(buf);
+ return rv;
}
-static int get_serial_info(struct usb_serial_port * port, struct serial_struct __user * retinfo)
+
+static int get_serial_info(struct usb_serial_port *port,
+ struct serial_struct __user *retinfo)
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
struct serial_struct tmp;
} /* get_serial_info */
-static int set_serial_info(struct usb_serial_port * port, struct serial_struct __user * newinfo)
+static int set_serial_info(struct tty_struct *tty,
+ struct usb_serial_port *port, struct serial_struct __user *newinfo)
{ /* set_serial_info */
struct ftdi_private *priv = usb_get_serial_port_data(port);
struct serial_struct new_serial;
if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
return -EFAULT;
- old_priv = * priv;
+ old_priv = *priv;
/* Do error checking and permission checking */
/* Make the changes - these are privileged changes! */
priv->flags = ((priv->flags & ~ASYNC_FLAGS) |
- (new_serial.flags & ASYNC_FLAGS));
+ (new_serial.flags & ASYNC_FLAGS));
priv->custom_divisor = new_serial.custom_divisor;
- port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
check_and_exit:
if ((old_priv.flags & ASYNC_SPD_MASK) !=
(priv->flags & ASYNC_SPD_MASK)) {
if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- port->tty->alt_speed = 57600;
+ tty->alt_speed = 57600;
else if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- port->tty->alt_speed = 115200;
+ tty->alt_speed = 115200;
else if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- port->tty->alt_speed = 230400;
+ tty->alt_speed = 230400;
else if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- port->tty->alt_speed = 460800;
+ tty->alt_speed = 460800;
else
- port->tty->alt_speed = 0;
+ tty->alt_speed = 0;
}
if (((old_priv.flags & ASYNC_SPD_MASK) !=
(priv->flags & ASYNC_SPD_MASK)) ||
(((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
(old_priv.custom_divisor != priv->custom_divisor))) {
- change_speed(port);
+ change_speed(tty, port);
}
-
- return (0);
+ return 0;
} /* set_serial_info */
priv->chip_type = FT2232C;
/* Determine interface code. */
inter = serial->interface->altsetting->desc.bInterfaceNumber;
- if (inter == 0) {
+ if (inter == 0)
priv->interface = PIT_SIOA;
- } else {
+ else
priv->interface = PIT_SIOB;
- }
/* BM-type devices have a bug where bcdDevice gets set
* to 0x200 when iSerialNumber is 0. */
if (version < 0x500) {
* ***************************************************************************
*/
-static ssize_t show_latency_timer(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_latency_timer(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct usb_serial_port *port = to_usb_serial_port(dev);
struct ftdi_private *priv = usb_get_serial_port_data(port);
int rv = 0;
- dbg("%s",__func__);
+ dbg("%s", __func__);
rv = usb_control_msg(udev,
usb_rcvctrlpipe(udev, 0),
FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
0, priv->interface,
- (char*) &latency, 1, WDR_TIMEOUT);
+ (char *) &latency, 1, WDR_TIMEOUT);
if (rv < 0) {
dev_err(dev, "Unable to read latency timer: %i\n", rv);
}
/* Write a new value of the latency timer, in units of milliseconds. */
-static ssize_t store_latency_timer(struct device *dev, struct device_attribute *attr, const char *valbuf,
- size_t count)
+static ssize_t store_latency_timer(struct device *dev,
+ struct device_attribute *attr, const char *valbuf,
+ size_t count)
{
struct usb_serial_port *port = to_usb_serial_port(dev);
struct ftdi_private *priv = usb_get_serial_port_data(port);
/* Write an event character directly to the FTDI register. The ASCII
value is in the low 8 bits, with the enable bit in the 9th bit. */
-static ssize_t store_event_char(struct device *dev, struct device_attribute *attr, const char *valbuf,
- size_t count)
+static ssize_t store_event_char(struct device *dev,
+ struct device_attribute *attr, const char *valbuf, size_t count)
{
struct usb_serial_port *port = to_usb_serial_port(dev);
struct ftdi_private *priv = usb_get_serial_port_data(port);
return count;
}
-static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer);
+static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer,
+ store_latency_timer);
static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char);
static int create_sysfs_attrs(struct usb_serial_port *port)
struct ftdi_private *priv = usb_get_serial_port_data(port);
int retval = 0;
- dbg("%s",__func__);
+ dbg("%s", __func__);
/* XXX I've no idea if the original SIO supports the event_char
* sysfs parameter, so I'm playing it safe. */
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
- dbg("%s",__func__);
+ dbg("%s", __func__);
/* XXX see create_sysfs_attrs */
if (priv->chip_type != SIO) {
*/
/* Probe function to check for special devices */
-static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
+static int ftdi_sio_probe(struct usb_serial *serial,
+ const struct usb_device_id *id)
{
- struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info;
+ struct ftdi_sio_quirk *quirk =
+ (struct ftdi_sio_quirk *)id->driver_info;
if (quirk && quirk->probe) {
int ret = quirk->probe(serial);
struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
- dbg("%s",__func__);
+ dbg("%s", __func__);
priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL);
- if (!priv){
- err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct ftdi_private));
+ if (!priv) {
+ err("%s- kmalloc(%Zd) failed.", __func__,
+ sizeof(struct ftdi_private));
return -ENOMEM;
}
spin_lock_init(&priv->rx_lock);
spin_lock_init(&priv->tx_lock);
- init_waitqueue_head(&priv->delta_msr_wait);
+ init_waitqueue_head(&priv->delta_msr_wait);
/* This will push the characters through immediately rather
than queue a task to deliver them */
priv->flags = ASYNC_LOW_LATENCY;
/* Increase the size of read buffers */
kfree(port->bulk_in_buffer);
- port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL);
+ port->bulk_in_buffer = kmalloc(BUFSZ, GFP_KERNEL);
if (!port->bulk_in_buffer) {
- kfree (priv);
+ kfree(priv);
return -ENOMEM;
}
if (port->read_urb) {
/* Free port's existing write urb and transfer buffer. */
if (port->write_urb) {
- usb_free_urb (port->write_urb);
+ usb_free_urb(port->write_urb);
port->write_urb = NULL;
}
kfree(port->bulk_out_buffer);
usb_set_serial_port_data(port, priv);
- ftdi_determine_type (port);
+ ftdi_determine_type(port);
create_sysfs_attrs(port);
return 0;
}
/* Setup for the USB-UIRT device, which requires hardwired
* baudrate (38400 gets mapped to 312500) */
/* Called from usbserial:serial_probe */
-static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
+static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
{
- dbg("%s",__func__);
+ dbg("%s", __func__);
priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 77;
/* Setup for the HE-TIRA1 device, which requires hardwired
* baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */
-static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
+
+static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
{
- dbg("%s",__func__);
+ dbg("%s", __func__);
priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 240;
struct usb_device *udev = serial->dev;
struct usb_interface *interface = serial->interface;
- dbg("%s",__func__);
+ dbg("%s", __func__);
if (interface == udev->actconfig->interface[0]) {
info("Ignoring serial port reserved for JTAG");
* calls __serial_close for each open of the port
* shutdown is called then (ie ftdi_shutdown)
*/
-static void ftdi_shutdown (struct usb_serial *serial)
+static void ftdi_shutdown(struct usb_serial *serial)
{
dbg("%s", __func__);
}
remove_sysfs_attrs(port);
/* all open ports are closed at this point
- * (by usbserial.c:__serial_close, which calls ftdi_close)
+ * (by usbserial.c:__serial_close, which calls ftdi_close)
*/
if (priv) {
return 0;
}
-static int ftdi_open (struct usb_serial_port *port, struct file *filp)
+static int ftdi_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{ /* ftdi_open */
struct usb_device *dev = port->serial->dev;
struct ftdi_private *priv = usb_get_serial_port_data(port);
priv->rx_bytes = 0;
spin_unlock_irqrestore(&priv->rx_lock, flags);
- if (port->tty)
- port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ if (tty)
+ tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
/* No error checking for this (will get errors later anyway) */
/* See ftdi_sio.h for description of what is reset */
This is same behaviour as serial.c/rs_open() - Kuba */
/* ftdi_set_termios will send usb control messages */
- if (port->tty)
- ftdi_set_termios(port, port->tty->termios);
+ if (tty)
+ ftdi_set_termios(tty, port, tty->termios);
/* FIXME: Flow control might be enabled, so it should be checked -
we have no control of defaults! */
/* Start reading from the device */
priv->rx_processed = 0;
usb_fill_bulk_urb(port->read_urb, dev,
- usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
- ftdi_read_bulk_callback, port);
+ usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ ftdi_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
- err("%s - failed submitting read urb, error %d", __func__, result);
+ err("%s - failed submitting read urb, error %d",
+ __func__, result);
return result;
*
*/
-static void ftdi_close (struct usb_serial_port *port, struct file *filp)
+static void ftdi_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{ /* ftdi_close */
- unsigned int c_cflag = port->tty->termios->c_cflag;
+ unsigned int c_cflag = tty->termios->c_cflag;
struct ftdi_private *priv = usb_get_serial_port_data(port);
char buf[1];
dbg("%s", __func__);
mutex_lock(&port->serial->disc_mutex);
- if (c_cflag & HUPCL && !port->serial->disconnected){
+ if (c_cflag & HUPCL && !port->serial->disconnected) {
/* Disable flow control */
if (usb_control_msg(port->serial->dev,
usb_sndctrlpipe(port->serial->dev, 0),
*
* The new devices do not require this byte
*/
-static int ftdi_write (struct usb_serial_port *port,
+static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count)
{ /* ftdi_write */
struct ftdi_private *priv = usb_get_serial_port_data(port);
spin_unlock_irqrestore(&priv->tx_lock, flags);
data_offset = priv->write_offset;
- dbg("data_offset set to %d",data_offset);
+ dbg("data_offset set to %d", data_offset);
/* Determine total transfer size */
transfer_size = count;
(PKTSZ - data_offset)));
}
- buffer = kmalloc (transfer_size, GFP_ATOMIC);
+ buffer = kmalloc(transfer_size, GFP_ATOMIC);
if (!buffer) {
err("%s ran out of kernel memory for urb ...", __func__);
count = -ENOMEM;
/* Copy data */
if (data_offset > 0) {
- /* Original sio requires control byte at start of each packet. */
+ /* Original sio requires control byte at start of
+ each packet. */
int user_pktsz = PKTSZ - data_offset;
int todo = count;
unsigned char *first_byte = buffer;
const unsigned char *current_position = buf;
while (todo > 0) {
- if (user_pktsz > todo) {
+ if (user_pktsz > todo)
user_pktsz = todo;
- }
/* Write the control byte at the front of the packet*/
*first_byte = 1 | ((user_pktsz) << 2);
/* Copy data for packet */
- memcpy (first_byte + data_offset,
+ memcpy(first_byte + data_offset,
current_position, user_pktsz);
first_byte += user_pktsz + data_offset;
current_position += user_pktsz;
} else {
/* No control byte required. */
/* Copy in the data to send */
- memcpy (buffer, buf, count);
+ memcpy(buffer, buf, count);
}
- usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, buffer);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ transfer_size, buffer);
/* fill the buffer and send it */
usb_fill_bulk_urb(urb, port->serial->dev,
- usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
- buffer, transfer_size,
- ftdi_write_bulk_callback, port);
+ usb_sndbulkpipe(port->serial->dev,
+ port->bulk_out_endpointAddress),
+ buffer, transfer_size,
+ ftdi_write_bulk_callback, port);
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
- err("%s - failed submitting write urb, error %d", __func__, status);
+ err("%s - failed submitting write urb, error %d",
+ __func__, status);
count = status;
goto error;
} else {
error:
usb_free_urb(urb);
error_no_urb:
- kfree (buffer);
+ kfree(buffer);
error_no_buffer:
spin_lock_irqsave(&priv->tx_lock, flags);
priv->tx_outstanding_urbs--;
/* This function may get called when the device is closed */
-static void ftdi_write_bulk_callback (struct urb *urb)
+static void ftdi_write_bulk_callback(struct urb *urb)
{
unsigned long flags;
struct usb_serial_port *port = urb->context;
int status = urb->status;
/* free up the transfer buffer, as usb_free_urb() does not do this */
- kfree (urb->transfer_buffer);
+ kfree(urb->transfer_buffer);
dbg("%s - port %d", __func__, port->number);
} /* ftdi_write_bulk_callback */
-static int ftdi_write_room( struct usb_serial_port *port )
+static int ftdi_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
int room;
unsigned long flags;
}
spin_unlock_irqrestore(&priv->tx_lock, flags);
return room;
-} /* ftdi_write_room */
-
+}
-static int ftdi_chars_in_buffer (struct usb_serial_port *port)
-{ /* ftdi_chars_in_buffer */
+static int ftdi_chars_in_buffer(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
int buffered;
unsigned long flags;
buffered = 0;
}
return buffered;
-} /* ftdi_chars_in_buffer */
-
-
+}
-static void ftdi_read_bulk_callback (struct urb *urb)
-{ /* ftdi_read_bulk_callback */
+static void ftdi_read_bulk_callback(struct urb *urb)
+{
struct usb_serial_port *port = urb->context;
struct tty_struct *tty;
struct ftdi_private *priv;
int status = urb->status;
if (urb->number_of_packets > 0) {
- err("%s transfer_buffer_length %d actual_length %d number of packets %d",__func__,
- urb->transfer_buffer_length, urb->actual_length, urb->number_of_packets );
- err("%s transfer_flags %x ", __func__,urb->transfer_flags );
+ err("%s transfer_buffer_length %d actual_length %d number of packets %d",
+ __func__,
+ urb->transfer_buffer_length,
+ urb->actual_length, urb->number_of_packets);
+ err("%s transfer_flags %x ", __func__, urb->transfer_flags);
}
dbg("%s - port %d", __func__, port->number);
- if (port->open_count <= 0)
+ if (port->port.count <= 0)
return;
- tty = port->tty;
+ tty = port->port.tty;
if (!tty) {
- dbg("%s - bad tty pointer - exiting",__func__);
+ dbg("%s - bad tty pointer - exiting", __func__);
return;
}
return;
}
- if (urb != port->read_urb) {
+ if (urb != port->read_urb)
err("%s - Not my urb!", __func__);
- }
if (status) {
- /* This will happen at close every time so it is a dbg not an err */
- dbg("(this is ok on close) nonzero read bulk status received: "
- "%d", status);
+ /* This will happen at close every time so it is a dbg not an
+ err */
+ dbg("(this is ok on close) nonzero read bulk status received: %d", status);
return;
}
} /* ftdi_read_bulk_callback */
-static void ftdi_process_read (struct work_struct *work)
+static void ftdi_process_read(struct work_struct *work)
{ /* ftdi_process_read */
struct ftdi_private *priv =
container_of(work, struct ftdi_private, rx_work.work);
dbg("%s - port %d", __func__, port->number);
- if (port->open_count <= 0)
+ if (port->port.count <= 0)
return;
- tty = port->tty;
+ tty = port->port.tty;
if (!tty) {
- dbg("%s - bad tty pointer - exiting",__func__);
+ dbg("%s - bad tty pointer - exiting", __func__);
return;
}
urb->actual_length - priv->rx_processed);
} else {
/* The first two bytes of every read packet are status */
- if (urb->actual_length > 2) {
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
- } else {
- dbg("Status only: %03oo %03oo",data[0],data[1]);
- }
+ if (urb->actual_length > 2)
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
+ else
+ dbg("Status only: %03oo %03oo", data[0], data[1]);
}
/* if CD is dropped and the line is not CLOCAL then we should hangup */
need_flip = 0;
- for (packet_offset = priv->rx_processed; packet_offset < urb->actual_length; packet_offset += PKTSZ) {
+ for (packet_offset = priv->rx_processed;
+ packet_offset < urb->actual_length; packet_offset += PKTSZ) {
int length;
- /* Compare new line status to the old one, signal if different */
- /* N.B. packet may be processed more than once, but differences
- * are only processed once. */
+ /* Compare new line status to the old one, signal if different/
+ N.B. packet may be processed more than once, but differences
+ are only processed once. */
if (priv != NULL) {
- char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK;
+ char new_status = data[packet_offset + 0] &
+ FTDI_STATUS_B0_MASK;
if (new_status != priv->prev_status) {
- priv->diff_status |= new_status ^ priv->prev_status;
+ priv->diff_status |=
+ new_status ^ priv->prev_status;
wake_up_interruptible(&priv->delta_msr_wait);
priv->prev_status = new_status;
}
break;
}
if (tty_buffer_request_room(tty, length) < length) {
- /* break out & wait for throttling/unthrottling to happen */
+ /* break out & wait for throttling/unthrottling to
+ happen */
dbg("%s - receive room low", __func__);
break;
}
/* Handle errors and break */
error_flag = TTY_NORMAL;
- /* Although the device uses a bitmask and hence can have multiple */
- /* errors on a packet - the order here sets the priority the */
- /* error is returned to the tty layer */
+ /* Although the device uses a bitmask and hence can have
+ multiple errors on a packet - the order here sets the
+ priority the error is returned to the tty layer */
- if ( data[packet_offset+1] & FTDI_RS_OE ) {
+ if (data[packet_offset+1] & FTDI_RS_OE) {
error_flag = TTY_OVERRUN;
dbg("OVERRRUN error");
}
- if ( data[packet_offset+1] & FTDI_RS_BI ) {
+ if (data[packet_offset+1] & FTDI_RS_BI) {
error_flag = TTY_BREAK;
dbg("BREAK received");
}
- if ( data[packet_offset+1] & FTDI_RS_PE ) {
+ if (data[packet_offset+1] & FTDI_RS_PE) {
error_flag = TTY_PARITY;
dbg("PARITY error");
}
- if ( data[packet_offset+1] & FTDI_RS_FE ) {
+ if (data[packet_offset+1] & FTDI_RS_FE) {
error_flag = TTY_FRAME;
dbg("FRAMING error");
}
/* Note that the error flag is duplicated for
every character received since we don't know
which character it applied to */
- tty_insert_flip_char(tty, data[packet_offset+i], error_flag);
+ tty_insert_flip_char(tty,
+ data[packet_offset + i], error_flag);
}
need_flip = 1;
}
#ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW
/* if a parity error is detected you get status packets forever
until a character is sent without a parity error.
- This doesn't work well since the application receives a never
- ending stream of bad data - even though new data hasn't been sent.
- Therefore I (bill) have taken this out.
+ This doesn't work well since the application receives a
+ never ending stream of bad data - even though new data
+ hasn't been sent. Therefore I (bill) have taken this out.
However - this might make sense for framing errors and so on
so I am leaving the code in for now.
*/
else {
- if (error_flag != TTY_NORMAL){
+ if (error_flag != TTY_NORMAL) {
dbg("error_flag is not normal");
- /* In this case it is just status - if that is an error send a bad character */
- if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ /* In this case it is just status - if that is
+ an error send a bad character */
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
tty_flip_buffer_push(tty);
- }
tty_insert_flip_char(tty, 0xff, error_flag);
need_flip = 1;
}
} /* "for(packet_offset=0..." */
/* Low latency */
- if (need_flip) {
+ if (need_flip)
tty_flip_buffer_push(tty);
- }
if (packet_offset < urb->actual_length) {
/* not completely processed - record progress */
}
spin_unlock_irqrestore(&priv->rx_lock, flags);
/* if the port is closed stop trying to read */
- if (port->open_count > 0){
+ if (port->port.count > 0)
/* delay processing of remainder */
schedule_delayed_work(&priv->rx_work, 1);
- } else {
+ else
dbg("%s - port is closed", __func__);
- }
return;
}
priv->rx_processed = 0;
/* if the port is closed stop trying to read */
- if (port->open_count > 0){
+ if (port->port.count > 0) {
/* Continue trying to always read */
usb_fill_bulk_urb(port->read_urb, port->serial->dev,
- usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
- ftdi_read_bulk_callback, port);
+ usb_rcvbulkpipe(port->serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ ftdi_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d", __func__, result);
+ err("%s - failed resubmitting read urb, error %d",
+ __func__, result);
}
-
- return;
} /* ftdi_process_read */
-static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
+static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
__u16 urb_value = 0;
char buf[1];
/* see drivers/char/tty_io.c to see it used */
/* last_set_data_urb_value NEVER has the break bit set in it */
- if (break_state) {
+ if (break_state)
urb_value = priv->last_set_data_urb_value | FTDI_SIO_SET_BREAK;
- } else {
+ else
urb_value = priv->last_set_data_urb_value;
- }
-
- if (usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
- FTDI_SIO_SET_DATA_REQUEST,
- FTDI_SIO_SET_DATA_REQUEST_TYPE,
- urb_value , priv->interface,
- buf, 0, WDR_TIMEOUT) < 0) {
- err("%s FAILED to enable/disable break state (state was %d)", __func__,break_state);
+ if (usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ FTDI_SIO_SET_DATA_REQUEST,
+ FTDI_SIO_SET_DATA_REQUEST_TYPE,
+ urb_value , priv->interface,
+ buf, 0, WDR_TIMEOUT) < 0) {
+ err("%s FAILED to enable/disable break state (state was %d)",
+ __func__, break_state);
}
- dbg("%s break state is %d - urb is %d", __func__,break_state, urb_value);
+ dbg("%s break state is %d - urb is %d", __func__,
+ break_state, urb_value);
}
* WARNING: set_termios calls this with old_termios in kernel space
*/
-static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void ftdi_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{ /* ftdi_termios */
struct usb_device *dev = port->serial->dev;
struct ftdi_private *priv = usb_get_serial_port_data(port);
- struct ktermios *termios = port->tty->termios;
+ struct ktermios *termios = tty->termios;
unsigned int cflag = termios->c_cflag;
__u16 urb_value; /* will hold the new flags */
char buf[1]; /* Perhaps I should dynamically alloc this? */
- // Added for xon/xoff support
+ /* Added for xon/xoff support */
unsigned int iflag = termios->c_iflag;
unsigned char vstop;
unsigned char vstart;
dbg("%s", __func__);
- /* Force baud rate if this device requires it, unless it is set to B0. */
+ /* Force baud rate if this device requires it, unless it is set to
+ B0. */
if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) {
dbg("%s: forcing baud rate for this device", __func__);
- tty_encode_baud_rate(port->tty, priv->force_baud,
+ tty_encode_baud_rate(tty, priv->force_baud,
priv->force_baud);
}
not - so just do the change regardless - should be able to
compare old_termios and tty->termios */
/* NOTE These routines can get interrupted by
- ftdi_sio_read_bulk_callback - need to examine what this
- means - don't see any problems yet */
+ ftdi_sio_read_bulk_callback - need to examine what this means -
+ don't see any problems yet */
/* Set number of data bits, parity, stop bits */
}
}
- /* This is needed by the break command since it uses the same command - but is
- * or'ed with this value */
+ /* This is needed by the break command since it uses the same command
+ - but is or'ed with this value */
priv->last_set_data_urb_value = urb_value;
if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
}
/* Now do the baudrate */
- if ((cflag & CBAUD) == B0 ) {
+ if ((cflag & CBAUD) == B0) {
/* Disable flow control */
if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
FTDI_SIO_SET_FLOW_CTRL_REQUEST,
clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
} else {
/* set the baudrate determined before */
- if (change_speed(port)) {
+ if (change_speed(tty, port))
err("%s urb failed to set baudrate", __func__);
- }
/* Ensure RTS and DTR are raised when baudrate changed from 0 */
- if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) {
+ if (!old_termios || (old_termios->c_cflag & CBAUD) == B0)
set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
- }
}
/* Set flow control */
/*
* Xon/Xoff code
*
- * Check the IXOFF status in the iflag component of the termios structure
- * if IXOFF is not set, the pre-xon/xoff code is executed.
- */
+ * Check the IXOFF status in the iflag component of the
+ * termios structure. If IXOFF is not set, the pre-xon/xoff
+ * code is executed.
+ */
if (iflag & IXOFF) {
- dbg("%s request to enable xonxoff iflag=%04x",__func__,iflag);
- // Try to enable the XON/XOFF on the ftdi_sio
- // Set the vstart and vstop -- could have been done up above where
- // a lot of other dereferencing is done but that would be very
- // inefficient as vstart and vstop are not always needed
+ dbg("%s request to enable xonxoff iflag=%04x",
+ __func__, iflag);
+ /* Try to enable the XON/XOFF on the ftdi_sio
+ * Set the vstart and vstop -- could have been done up
+ * above where a lot of other dereferencing is done but
+ * that would be very inefficient as vstart and vstop
+ * are not always needed.
+ */
vstart = termios->c_cc[VSTART];
vstop = termios->c_cc[VSTOP];
- urb_value=(vstop << 8) | (vstart);
+ urb_value = (vstop << 8) | (vstart);
if (usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
err("urb failed to set to xon/xoff flow control");
}
} else {
- /* else clause to only run if cfag ! CRTSCTS and iflag ! XOFF */
- /* CHECKME Assuming XON/XOFF handled by tty stack - not by device */
+ /* else clause to only run if cflag ! CRTSCTS and iflag
+ * ! XOFF. CHECKME Assuming XON/XOFF handled by tty
+ * stack - not by device */
dbg("%s Turning off hardware flow control", __func__);
if (usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
}
return;
-} /* ftdi_termios */
-
+}
-static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file)
+static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
unsigned char buf[2];
int ret;
switch (priv->chip_type) {
case SIO:
/* Request the status from the device */
- if ((ret = usb_control_msg(port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0),
- FTDI_SIO_GET_MODEM_STATUS_REQUEST,
- FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
- 0, 0,
- buf, 1, WDR_TIMEOUT)) < 0 ) {
+ ret = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ FTDI_SIO_GET_MODEM_STATUS_REQUEST,
+ FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
+ 0, 0,
+ buf, 1, WDR_TIMEOUT);
+ if (ret < 0) {
err("%s Could not get modem status of device - err: %d", __func__,
ret);
- return(ret);
+ return ret;
}
break;
case FT8U232AM:
case FT232BM:
case FT2232C:
case FT232RL:
- /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same
- format as the data returned from the in point */
- if ((ret = usb_control_msg(port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0),
- FTDI_SIO_GET_MODEM_STATUS_REQUEST,
- FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
- 0, priv->interface,
- buf, 2, WDR_TIMEOUT)) < 0 ) {
+ /* the 8U232AM returns a two byte value (the sio is a 1 byte
+ value) - in the same format as the data returned from the in
+ point */
+ ret = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ FTDI_SIO_GET_MODEM_STATUS_REQUEST,
+ FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
+ 0, priv->interface,
+ buf, 2, WDR_TIMEOUT);
+ if (ret < 0) {
err("%s Could not get modem status of device - err: %d", __func__,
ret);
- return(ret);
+ return ret;
}
break;
default:
priv->last_dtr_rts;
}
-static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear)
+static int ftdi_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s TIOCMSET", __func__);
return update_mctrl(port, set, clear);
}
-static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+static int ftdi_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
dbg("%s cmd 0x%04x", __func__, cmd);
switch (cmd) {
case TIOCGSERIAL: /* gets serial port data */
- return get_serial_info(port, (struct serial_struct __user *) arg);
+ return get_serial_info(port,
+ (struct serial_struct __user *) arg);
case TIOCSSERIAL: /* sets serial port data */
- return set_serial_info(port, (struct serial_struct __user *) arg);
+ return set_serial_info(tty, port,
+ (struct serial_struct __user *) arg);
/*
* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
else {
char diff = priv->diff_status;
- if (diff == 0) {
+ if (diff == 0)
return -EIO; /* no change => error */
- }
/* Consume all events */
priv->diff_status = 0;
- /* Return 0 if caller wanted to know about these bits */
- if ( ((arg & TIOCM_RNG) && (diff & FTDI_RS0_RI)) ||
- ((arg & TIOCM_DSR) && (diff & FTDI_RS0_DSR)) ||
- ((arg & TIOCM_CD) && (diff & FTDI_RS0_RLSD)) ||
- ((arg & TIOCM_CTS) && (diff & FTDI_RS0_CTS)) ) {
+ /* Return 0 if caller wanted to know about
+ these bits */
+ if (((arg & TIOCM_RNG) && (diff & FTDI_RS0_RI)) ||
+ ((arg & TIOCM_DSR) && (diff & FTDI_RS0_DSR)) ||
+ ((arg & TIOCM_CD) && (diff & FTDI_RS0_RLSD)) ||
+ ((arg & TIOCM_CTS) && (diff & FTDI_RS0_CTS))) {
return 0;
}
/*
- * Otherwise caller can't care less about what happened,
- * and so we continue to wait for more events.
+ * Otherwise caller can't care less about what
+ * happened,and so we continue to wait for more
+ * events.
*/
}
}
- return(0);
- break;
+ return 0;
default:
break;
-
}
-
-
- /* This is not necessarily an error - turns out the higher layers will do
- * some ioctls itself (see comment above)
+ /* This is not necessarily an error - turns out the higher layers
+ * will do some ioctls themselves (see comment above)
*/
dbg("%s arg not supported - it was 0x%04x - check /usr/include/asm/ioctls.h", __func__, cmd);
+ return -ENOIOCTLCMD;
+}
- return(-ENOIOCTLCMD);
-} /* ftdi_ioctl */
-
-
-static void ftdi_throttle (struct usb_serial_port *port)
+static void ftdi_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
}
-static void ftdi_unthrottle (struct usb_serial_port *port)
+static void ftdi_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
int actually_throttled;
unsigned long flags;
schedule_delayed_work(&priv->rx_work, 0);
}
-static int __init ftdi_init (void)
+static int __init ftdi_init(void)
{
int retval;
}
-static void __exit ftdi_exit (void)
+static void __exit ftdi_exit(void)
{
dbg("%s", __func__);
- usb_deregister (&ftdi_driver);
- usb_serial_deregister (&ftdi_sio_device);
+ usb_deregister(&ftdi_driver);
+ usb_serial_deregister(&ftdi_sio_device);
}
module_init(ftdi_init);
module_exit(ftdi_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
/*
- * Definitions for the FTDI USB Single Port Serial Converter -
- * known as FTDI_SIO (Serial Input/Output application of the chipset)
+ * Definitions for the FTDI USB Single Port Serial Converter -
+ * known as FTDI_SIO (Serial Input/Output application of the chipset)
*
* The example I have is known as the USC-1000 which is available from
* http://www.dse.co.nz - cat no XH4214 It looks similar to this:
* http://www.dansdata.com/usbser.htm but I can't be sure There are other
* USC-1000s which don't look like my device though so beware!
*
- * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side,
+ * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side,
* USB on the other.
*
* Thanx to FTDI (http://www.ftdi.co.uk) for so kindly providing details
* of the protocol required to talk to the device and ongoing assistence
* during development.
*
- * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the
+ * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the
* FTDI_SIO implementation.
*
* Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
/*
* DSS-20 Sync Station for Sony Ericsson P800
*/
-#define FTDI_DSS20_PID 0xFC82
+#define FTDI_DSS20_PID 0xFC82
/*
* Home Electronics (www.home-electro.com) USB gadgets
/*
* BmRequestType: 0100 0000B
* bRequest: FTDI_SIO_RESET
- * wValue: Control Value
+ * wValue: Control Value
* 0 = Reset SIO
* 1 = Purge RX buffer
* 2 = Purge TX buffer
* 101 - add .625 to divisor
* 110 - add .750 to divisor
* 111 - add .875 to divisor
- * Bits 15 to 0 of the 17-bit divisor are placed in the urb value. Bit 16 is
+ * Bits 15 to 0 of the 17-bit divisor are placed in the urb value. Bit 16 is
* placed in bit 0 of the urb index.
*
* Note that there are a couple of special cases to support the highest baud
} ftdi_chip_type_t;
typedef enum {
- ftdi_sio_b300 = 0,
- ftdi_sio_b600 = 1,
+ ftdi_sio_b300 = 0,
+ ftdi_sio_b600 = 1,
ftdi_sio_b1200 = 2,
ftdi_sio_b2400 = 3,
ftdi_sio_b4800 = 4,
ftdi_sio_b38400 = 7,
ftdi_sio_b57600 = 8,
ftdi_sio_b115200 = 9
-} FTDI_SIO_baudrate_t ;
+} FTDI_SIO_baudrate_t;
/*
* The ftdi_8U232AM_xxMHz_byyy constants have been removed. The encoded divisor values
#define FTDI_SIO_SET_DATA_REQUEST FTDI_SIO_SET_DATA
#define FTDI_SIO_SET_DATA_REQUEST_TYPE 0x40
-#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8 )
-#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8 )
-#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8 )
-#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8 )
-#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8 )
-#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11 )
-#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11 )
-#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11 )
+#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8)
+#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11)
+#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11)
+#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11)
#define FTDI_SIO_SET_BREAK (0x1 << 14)
/* FTDI_SIO_SET_DATA */
/*
- * BmRequestType: 0100 0000B
+ * BmRequestType: 0100 0000B
* bRequest: FTDI_SIO_SET_DATA
* wValue: Data characteristics (see below)
* wIndex: Port
#define FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE 0x40
#define FTDI_SIO_SET_MODEM_CTRL_REQUEST FTDI_SIO_MODEM_CTRL
-/*
+/*
* BmRequestType: 0100 0000B
* bRequest: FTDI_SIO_MODEM_CTRL
* wValue: ControlValue (see below)
*/
#define FTDI_SIO_SET_DTR_MASK 0x1
-#define FTDI_SIO_SET_DTR_HIGH ( 1 | ( FTDI_SIO_SET_DTR_MASK << 8))
-#define FTDI_SIO_SET_DTR_LOW ( 0 | ( FTDI_SIO_SET_DTR_MASK << 8))
+#define FTDI_SIO_SET_DTR_HIGH (1 | (FTDI_SIO_SET_DTR_MASK << 8))
+#define FTDI_SIO_SET_DTR_LOW (0 | (FTDI_SIO_SET_DTR_MASK << 8))
#define FTDI_SIO_SET_RTS_MASK 0x2
-#define FTDI_SIO_SET_RTS_HIGH ( 2 | ( FTDI_SIO_SET_RTS_MASK << 8 ))
-#define FTDI_SIO_SET_RTS_LOW ( 0 | ( FTDI_SIO_SET_RTS_MASK << 8 ))
+#define FTDI_SIO_SET_RTS_HIGH (2 | (FTDI_SIO_SET_RTS_MASK << 8))
+#define FTDI_SIO_SET_RTS_LOW (0 | (FTDI_SIO_SET_RTS_MASK << 8))
/*
* ControlValue
/* FTDI_SIO_SET_FLOW_CTRL */
#define FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE 0x40
#define FTDI_SIO_SET_FLOW_CTRL_REQUEST FTDI_SIO_SET_FLOW_CTRL
-#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0
+#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0
#define FTDI_SIO_RTS_CTS_HS (0x1 << 8)
#define FTDI_SIO_DTR_DSR_HS (0x2 << 8)
#define FTDI_SIO_XON_XOFF_HS (0x4 << 8)
* bRequest: FTDI_SIO_SET_FLOW_CTRL
* wValue: Xoff/Xon
* wIndex: Protocol/Port - hIndex is protocl / lIndex is port
- * wLength: 0
+ * wLength: 0
* Data: None
*
* hIndex protocol is:
*
* A value of zero in the hIndex field disables handshaking
*
- * If Xon/Xoff handshaking is specified, the hValue field should contain the XOFF character
+ * If Xon/Xoff handshaking is specified, the hValue field should contain the XOFF character
* and the lValue field contains the XON character.
- */
-
+ */
+
/*
* FTDI_SIO_GET_LATENCY_TIMER
*
#define FTDI_SIO_GET_LATENCY_TIMER_REQUEST FTDI_SIO_GET_LATENCY_TIMER
#define FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE 0xC0
-/*
+/*
* BmRequestType: 1100 0000b
* bRequest: FTDI_SIO_GET_LATENCY_TIMER
* wValue: 0
* Data: latency (on return)
*/
-/*
+/*
* FTDI_SIO_SET_LATENCY_TIMER
*
* Set the timeout interval. The FTDI collects data from the slave
#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST FTDI_SIO_SET_LATENCY_TIMER
#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE 0x40
-/*
+/*
* BmRequestType: 0100 0000b
* bRequest: FTDI_SIO_SET_LATENCY_TIMER
* wValue: Latency (milliseconds)
*/
/*
- * FTDI_SIO_SET_EVENT_CHAR
+ * FTDI_SIO_SET_EVENT_CHAR
*
* Set the special event character for the specified communications port.
* If the device sees this character it will immediately return the
#define FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE 0x40
-/*
+/*
* BmRequestType: 0100 0000b
* bRequest: FTDI_SIO_SET_EVENT_CHAR
* wValue: EventChar
* B9..15 Reserved
*
*/
-
+
/* FTDI_SIO_SET_ERROR_CHAR */
/* Set the parity error replacement character for the specified communications port */
-/*
+/*
* BmRequestType: 0100 0000b
* bRequest: FTDI_SIO_SET_EVENT_CHAR
* wValue: Error Char
#define FTDI_SIO_DSR_MASK 0x20
#define FTDI_SIO_RI_MASK 0x40
#define FTDI_SIO_RLSD_MASK 0x80
-/*
+/*
* BmRequestType: 1100 0000b
* bRequest: FTDI_SIO_GET_MODEM_STATUS
* wValue: zero
* wIndex: Port
* wLength: 1
* Data: Status
- *
- * One byte of data is returned
+ *
+ * One byte of data is returned
* B0..3 0
* B4 CTS
* 0 = inactive
* 1 = active
* B7 Receive Line Signal Detect (RLSD)
* 0 = inactive
- * 1 = active
+ * 1 = active
*/
-/* Descriptors returned by the device
- *
+/* Descriptors returned by the device
+ *
* Device Descriptor
- *
+ *
* Offset Field Size Value Description
* 0 bLength 1 0x12 Size of descriptor in bytes
* 1 bDescriptorType 1 0x01 DEVICE Descriptor Type
* 15 iProduct 1 0x02 Index of prod string desc
* 16 iSerialNumber 1 0x02 Index of serial nmr string desc
* 17 bNumConfigurations 1 0x01 Number of possible configurations
- *
+ *
* Configuration Descriptor
- *
+ *
* Offset Field Size Value
* 0 bLength 1 0x09 Size of descriptor in bytes
* 1 bDescriptorType 1 0x02 CONFIGURATION Descriptor Type
* 6 iConfiguration 1 0x02 Index of config string descriptor
* 7 bmAttributes 1 0x20 Config characteristics Remote Wakeup
* 8 MaxPower 1 0x1E Max power consumption
- *
+ *
* Interface Descriptor
- *
+ *
* Offset Field Size Value
* 0 bLength 1 0x09 Size of descriptor in bytes
* 1 bDescriptorType 1 0x04 INTERFACE Descriptor Type
* 6 bInterfaceSubClass 1 0xFF Subclass Code
* 7 bInterfaceProtocol 1 0xFF Protocol Code
* 8 iInterface 1 0x02 Index of interface string description
- *
+ *
* IN Endpoint Descriptor
- *
+ *
* Offset Field Size Value
* 0 bLength 1 0x07 Size of descriptor in bytes
* 1 bDescriptorType 1 0x05 ENDPOINT descriptor type
* 3 bmAttributes 1 0x02 Endpoint attributes - Bulk
* 4 bNumEndpoints 2 0x0040 maximum packet size
* 5 bInterval 1 0x00 Interval for polling endpoint
- *
+ *
* OUT Endpoint Descriptor
- *
+ *
* Offset Field Size Value
* 0 bLength 1 0x07 Size of descriptor in bytes
* 1 bDescriptorType 1 0x05 ENDPOINT descriptor type
* 3 bmAttributes 1 0x02 Endpoint attributes - Bulk
* 4 bNumEndpoints 2 0x0040 maximum packet size
* 5 bInterval 1 0x00 Interval for polling endpoint
- *
+ *
* DATA FORMAT
- *
+ *
* IN Endpoint
- *
+ *
* The device reserves the first two bytes of data on this endpoint to contain the current
* values of the modem and line status registers. In the absence of data, the device
* generates a message consisting of these two status bytes every 40 ms
- *
+ *
* Byte 0: Modem Status
- *
+ *
* Offset Description
* B0 Reserved - must be 1
* B1 Reserved - must be 0
* B5 Data Set Ready (DSR)
* B6 Ring Indicator (RI)
* B7 Receive Line Signal Detect (RLSD)
- *
+ *
* Byte 1: Line Status
- *
+ *
* Offset Description
* B0 Data Ready (DR)
* B1 Overrun Error (OE)
* B5 Transmitter Holding Register (THRE)
* B6 Transmitter Empty (TEMT)
* B7 Error in RCVR FIFO
- *
+ *
*/
#define FTDI_RS0_CTS (1 << 4)
#define FTDI_RS0_DSR (1 << 5)
/*
* OUT Endpoint
- *
+ *
* This device reserves the first bytes of data on this endpoint contain the length
* and port identifier of the message. For the FTDI USB Serial converter the port
* identifier is always 1.
- *
+ *
* Byte 0: Line Status
- *
+ *
* Offset Description
* B0 Reserved - must be 1
* B1 Reserved - must be 0
* B2..7 Length of message - (not including Byte 0)
- *
+ *
*/
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
static int debug;
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/atomic.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
static int initial_mode = 1;
/* debug flag */
-static int debug = 0;
+static int debug;
#define GARMIN_VENDOR_ID 0x091E
#define VERSION_MINOR 31
#define _STR(s) #s
-#define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b)
+#define _DRIVER_VERSION(a, b) "v" _STR(a) "." _STR(b)
#define DRIVER_VERSION _DRIVER_VERSION(VERSION_MAJOR, VERSION_MINOR)
#define DRIVER_AUTHOR "hermann kneissel"
#define DRIVER_DESC "garmin gps driver"
#define EINVPKT 1000 /* invalid packet structure */
-// size of the header of a packet using the usb protocol
+/* size of the header of a packet using the usb protocol */
#define GARMIN_PKTHDR_LENGTH 12
-// max. possible size of a packet using the serial protocol
-#define MAX_SERIAL_PKT_SIZ (3+255+3)
+/* max. possible size of a packet using the serial protocol */
+#define MAX_SERIAL_PKT_SIZ (3 + 255 + 3)
-// max. possible size of a packet with worst case stuffing
-#define MAX_SERIAL_PKT_SIZ_STUFFED MAX_SERIAL_PKT_SIZ+256
+/* max. possible size of a packet with worst case stuffing */
+#define MAX_SERIAL_PKT_SIZ_STUFFED (MAX_SERIAL_PKT_SIZ + 256)
-// size of a buffer able to hold a complete (no stuffing) packet
-// (the document protocol does not contain packets with a larger
-// size, but in theory a packet may be 64k+12 bytes - if in
-// later protocol versions larger packet sizes occur, this value
-// should be increased accordingly, so the input buffer is always
-// large enough the store a complete packet inclusive header)
-#define GPS_IN_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ)
+/* size of a buffer able to hold a complete (no stuffing) packet
+ * (the document protocol does not contain packets with a larger
+ * size, but in theory a packet may be 64k+12 bytes - if in
+ * later protocol versions larger packet sizes occur, this value
+ * should be increased accordingly, so the input buffer is always
+ * large enough the store a complete packet inclusive header) */
+#define GPS_IN_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ)
-// size of a buffer able to hold a complete (incl. stuffing) packet
-#define GPS_OUT_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ_STUFFED)
+/* size of a buffer able to hold a complete (incl. stuffing) packet */
+#define GPS_OUT_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ_STUFFED)
-// where to place the packet id of a serial packet, so we can
-// prepend the usb-packet header without the need to move the
-// packets data
+/* where to place the packet id of a serial packet, so we can
+ * prepend the usb-packet header without the need to move the
+ * packets data */
#define GSP_INITIAL_OFFSET (GARMIN_PKTHDR_LENGTH-2)
-// max. size of incoming private packets (header+1 param)
+/* max. size of incoming private packets (header+1 param) */
#define PRIVPKTSIZ (GARMIN_PKTHDR_LENGTH+4)
#define GARMIN_LAYERID_TRANSPORT 0
#define GARMIN_LAYERID_APPL 20
-// our own layer-id to use for some control mechanisms
+/* our own layer-id to use for some control mechanisms */
#define GARMIN_LAYERID_PRIVATE 0x01106E4B
#define GARMIN_PKTID_PVT_DATA 51
#define CMND_ABORT_TRANSFER 0
-// packet ids used in private layer
+/* packet ids used in private layer */
#define PRIV_PKTID_SET_DEBUG 1
#define PRIV_PKTID_SET_MODE 2
#define PRIV_PKTID_INFO_REQ 3
struct garmin_packet {
struct list_head list;
int seq;
- int size; // the real size of the data array, always > 0
+ /* the real size of the data array, always > 0 */
+ int size;
__u8 data[1];
};
#define MODE_NATIVE 0
#define MODE_GARMIN_SERIAL 1
-// Flags used in garmin_data.flags:
+/* Flags used in garmin_data.flags: */
#define FLAGS_SESSION_REPLY_MASK 0x00C0
#define FLAGS_SESSION_REPLY1_SEEN 0x0080
#define FLAGS_SESSION_REPLY2_SEEN 0x0040
/* function prototypes */
-static void gsp_next_packet(struct garmin_data * garmin_data_p);
+static void gsp_next_packet(struct garmin_data *garmin_data_p);
static int garmin_write_bulk(struct usb_serial_port *port,
const unsigned char *buf, int count,
int dismiss_ack);
static struct usb_device_id id_table [] = {
- /* the same device id seems to be used by all usb enabled gps devices */
- { USB_DEVICE(GARMIN_VENDOR_ID, 3 ) },
+ /* the same device id seems to be used by all
+ usb enabled GPS devices */
+ { USB_DEVICE(GARMIN_VENDOR_ID, 3) },
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver garmin_driver = {
.name = "garmin_gps",
};
-static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p)
+static inline int noResponseFromAppLayer(struct garmin_data *garmin_data_p)
{
- return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count);
+ return atomic_read(&garmin_data_p->req_count) ==
+ atomic_read(&garmin_data_p->resp_count);
}
*/
static inline int isAbortTrfCmnd(const unsigned char *buf)
{
- if (0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ,
- sizeof(GARMIN_STOP_TRANSFER_REQ)) ||
- 0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ_V2,
- sizeof(GARMIN_STOP_TRANSFER_REQ_V2)))
+ if (0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ,
+ sizeof(GARMIN_STOP_TRANSFER_REQ)) ||
+ 0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ_V2,
+ sizeof(GARMIN_STOP_TRANSFER_REQ_V2)))
return 1;
else
return 0;
static void send_to_tty(struct usb_serial_port *port,
char *data, unsigned int actual_length)
{
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
if (tty && actual_length) {
- usb_serial_debug_data(debug, &port->dev,
+ usb_serial_debug_data(debug, &port->dev,
__func__, actual_length, data);
tty_buffer_request_room(tty, actual_length);
/*
* queue a received (usb-)packet for later processing
*/
-static int pkt_add(struct garmin_data * garmin_data_p,
+static int pkt_add(struct garmin_data *garmin_data_p,
unsigned char *data, unsigned int data_length)
{
int state = 0;
/* process only packets containg data ... */
if (data_length) {
pkt = kmalloc(sizeof(struct garmin_packet)+data_length,
- GFP_ATOMIC);
+ GFP_ATOMIC);
if (pkt == NULL) {
dev_err(&garmin_data_p->port->dev, "out of memory\n");
return 0;
/* in serial mode, if someone is waiting for data from
the device, iconvert and send the next packet to tty. */
- if (result && (state == STATE_GSP_WAIT_DATA)) {
+ if (result && (state == STATE_GSP_WAIT_DATA))
gsp_next_packet(garmin_data_p);
- }
}
return result;
}
/* get the next pending packet */
-static struct garmin_packet *pkt_pop(struct garmin_data * garmin_data_p)
+static struct garmin_packet *pkt_pop(struct garmin_data *garmin_data_p)
{
unsigned long flags;
struct garmin_packet *result = NULL;
/* free up all queued data */
-static void pkt_clear(struct garmin_data * garmin_data_p)
+static void pkt_clear(struct garmin_data *garmin_data_p)
{
unsigned long flags;
struct garmin_packet *result = NULL;
******************************************************************************/
/* send an ack packet back to the tty */
-static int gsp_send_ack(struct garmin_data * garmin_data_p, __u8 pkt_id)
+static int gsp_send_ack(struct garmin_data *garmin_data_p, __u8 pkt_id)
{
__u8 pkt[10];
__u8 cksum = 0;
*ptr++ = pkt_id;
cksum += pkt_id;
- if (pkt_id == DLE) {
+ if (pkt_id == DLE)
*ptr++ = DLE;
- }
*ptr++ = 0;
*ptr++ = 0xFF & (-cksum);
* at GSP_INITIAL_OFFSET.
*
* count - number of bytes in the input buffer including space reserved for
- * the usb header: GSP_INITIAL_OFFSET + number of bytes in packet
+ * the usb header: GSP_INITIAL_OFFSET + number of bytes in packet
* (including pkt-id, data-length a. cksum)
*/
-static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
+static int gsp_rec_packet(struct garmin_data *garmin_data_p, int count)
{
- const __u8* recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET;
+ const __u8 *recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET;
__le32 *usbdata = (__le32 *) garmin_data_p->inbuffer;
int cksum = 0;
cksum += *recpkt++;
cksum += *recpkt++;
- // sanity check, remove after test ...
- if ((__u8*)&(usbdata[3]) != recpkt) {
+ /* sanity check, remove after test ... */
+ if ((__u8 *)&(usbdata[3]) != recpkt) {
dbg("%s - ptr mismatch %p - %p",
__func__, &(usbdata[4]), recpkt);
return -EINVPKT;
usbdata[1] = __cpu_to_le32(pktid);
usbdata[2] = __cpu_to_le32(size);
- garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer,
+ garmin_write_bulk(garmin_data_p->port, garmin_data_p->inbuffer,
GARMIN_PKTHDR_LENGTH+size, 0);
/* if this was an abort-transfer command, flush all
* if the input is an abort command, drop all queued data.
*/
-static int gsp_receive(struct garmin_data * garmin_data_p,
+static int gsp_receive(struct garmin_data *garmin_data_p,
const unsigned char *buf, int count)
{
unsigned long flags;
int i = 0;
__u8 *dest;
int size;
- // dleSeen: set if last byte read was a DLE
+ /* dleSeen: set if last byte read was a DLE */
int dleSeen;
- // skip: if set, skip incoming data until possible start of
- // new packet
+ /* skip: if set, skip incoming data until possible start of
+ * new packet
+ */
int skip;
__u8 data;
dbg("%s - dle=%d skip=%d size=%d count=%d",
__func__, dleSeen, skip, size, count);
- if (size == 0) {
+ if (size == 0)
size = GSP_INITIAL_OFFSET;
- }
while (offs < count) {
data = *(buf+offs);
- offs ++;
+ offs++;
if (data == DLE) {
if (skip) { /* start of a new pkt */
ack_or_nak_seen = NAK;
dbg("NAK packet complete.");
} else {
- dbg("packet complete "
- "- id=0x%X.",
- 0xFF & data);
+ dbg("packet complete - id=0x%X.",
+ 0xFF & data);
gsp_rec_packet(garmin_data_p, size);
}
garmin_data_p->insize = size;
- // copy flags back to structure
+ /* copy flags back to structure */
if (skip)
garmin_data_p->flags |= FLAGS_GSP_SKIP;
else
else
garmin_data_p->flags &= ~FLAGS_GSP_DLESEEN;
- if (ack_or_nak_seen) {
+ if (ack_or_nak_seen)
garmin_data_p->state = STATE_GSP_WAIT_DATA;
- }
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
- if (ack_or_nak_seen) {
+ if (ack_or_nak_seen)
gsp_next_packet(garmin_data_p);
- }
-
return count;
}
*
* return <0 on error, 0 if packet is incomplete or > 0 if packet was sent
*/
-static int gsp_send(struct garmin_data * garmin_data_p,
+static int gsp_send(struct garmin_data *garmin_data_p,
const unsigned char *buf, int count)
{
const unsigned char *src;
int pktid = 0;
int datalen = 0;
int cksum = 0;
- int i=0;
+ int i = 0;
int k;
dbg("%s - state %d - %d bytes.", __func__,
- garmin_data_p->state, count);
+ garmin_data_p->state, count);
k = garmin_data_p->outsize;
if ((k+count) > GPS_OUT_BUFSIZ) {
if (k >= GARMIN_PKTHDR_LENGTH) {
pktid = getPacketId(garmin_data_p->outbuffer);
- datalen= getDataLength(garmin_data_p->outbuffer);
+ datalen = getDataLength(garmin_data_p->outbuffer);
i = GARMIN_PKTHDR_LENGTH + datalen;
if (k < i)
return 0;
return 0;
}
- dbg("%s - %d bytes in buffer, %d bytes in pkt.", __func__,
- k, i);
+ dbg("%s - %d bytes in buffer, %d bytes in pkt.", __func__, k, i);
/* garmin_data_p->outbuffer now contains a complete packet */
usb_serial_debug_data(debug, &garmin_data_p->port->dev,
- __func__, k, garmin_data_p->outbuffer);
+ __func__, k, garmin_data_p->outbuffer);
garmin_data_p->outsize = 0;
if (GARMIN_LAYERID_APPL != getLayerId(garmin_data_p->outbuffer)) {
- dbg("not an application packet (%d)",
- getLayerId(garmin_data_p->outbuffer));
+ dbg("not an application packet (%d)",
+ getLayerId(garmin_data_p->outbuffer));
return -1;
}
k = 0;
src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
- for (i=0; i<datalen; i++) {
+ for (i = 0; i < datalen; i++) {
if (*src++ == DLE)
k++;
}
src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
if (k > (GARMIN_PKTHDR_LENGTH-2)) {
- /* can't add stuffing DLEs in place, move data to end
+ /* can't add stuffing DLEs in place, move data to end
of buffer ... */
dst = garmin_data_p->outbuffer+GPS_OUT_BUFSIZ-datalen;
memcpy(dst, src, datalen);
if (datalen == DLE)
*dst++ = DLE;
- for (i=0; i<datalen; i++) {
+ for (i = 0; i < datalen; i++) {
__u8 c = *src++;
*dst++ = c;
cksum += c;
if (c == DLE)
*dst++ = DLE;
}
-
+
cksum = 0xFF & -cksum;
*dst++ = cksum;
if (cksum == DLE)
/*
* Process the next pending data packet - if there is one
*/
-static void gsp_next_packet(struct garmin_data * garmin_data_p)
+static void gsp_next_packet(struct garmin_data *garmin_data_p)
{
struct garmin_packet *pkt = NULL;
* buf contains the data read, it may span more than one packet
* or even incomplete packets
*/
-static int nat_receive(struct garmin_data * garmin_data_p,
+static int nat_receive(struct garmin_data *garmin_data_p,
const unsigned char *buf, int count)
{
unsigned long flags;
- __u8 * dest;
+ __u8 *dest;
int offs = 0;
int result = count;
int len;
while (offs < count) {
- // if buffer contains header, copy rest of data
+ /* if buffer contains header, copy rest of data */
if (garmin_data_p->insize >= GARMIN_PKTHDR_LENGTH)
len = GARMIN_PKTHDR_LENGTH
+getDataLength(garmin_data_p->inbuffer);
len = GARMIN_PKTHDR_LENGTH;
if (len >= GPS_IN_BUFSIZ) {
- /* seem to be an invalid packet, ignore rest of input */
- dbg("%s - packet size too large: %d",
- __func__, len);
+ /* seems to be an invalid packet, ignore rest
+ of input */
+ dbg("%s - packet size too large: %d", __func__, len);
garmin_data_p->insize = 0;
count = 0;
result = -EINVPKT;
len = (count-offs);
if (len > 0) {
dest = garmin_data_p->inbuffer
- +garmin_data_p->insize;
+ + garmin_data_p->insize;
memcpy(dest, buf+offs, len);
garmin_data_p->insize += len;
offs += len;
len = GARMIN_PKTHDR_LENGTH+
getDataLength(garmin_data_p->inbuffer);
if (garmin_data_p->insize >= len) {
- garmin_write_bulk (garmin_data_p->port,
- garmin_data_p->inbuffer,
- len, 0);
+ garmin_write_bulk(garmin_data_p->port,
+ garmin_data_p->inbuffer,
+ len, 0);
garmin_data_p->insize = 0;
/* if this was an abort-transfer command,
flush all queued data. */
if (isAbortTrfCmnd(garmin_data_p->inbuffer)) {
- spin_lock_irqsave(&garmin_data_p->lock, flags);
+ spin_lock_irqsave(&garmin_data_p->lock,
+ flags);
garmin_data_p->flags |= FLAGS_DROP_DATA;
- spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+ spin_unlock_irqrestore(
+ &garmin_data_p->lock, flags);
pkt_clear(garmin_data_p);
}
}
static void priv_status_resp(struct usb_serial_port *port)
{
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
__le32 *pkt = (__le32 *)garmin_data_p->privpkt;
pkt[0] = __cpu_to_le32(GARMIN_LAYERID_PRIVATE);
pkt[4] = __cpu_to_le32(garmin_data_p->mode);
pkt[5] = __cpu_to_le32(garmin_data_p->serial_num);
- send_to_tty(port, (__u8*)pkt, 6*4);
+ send_to_tty(port, (__u8 *)pkt, 6 * 4);
}
{
unsigned long flags;
int status;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags &= ~(CLEAR_HALT_REQUIRED);
garmin_data_p->serial_num = 0;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
- usb_kill_urb (port->interrupt_in_urb);
- dbg("%s - usb_reset_device", __func__ );
+ usb_kill_urb(port->interrupt_in_urb);
+ dbg("%s - usb_reset_device", __func__);
status = usb_reset_device(port->serial->dev);
if (status)
dbg("%s - usb_reset_device failed: %d",
/*
* clear all cached data
*/
-static int garmin_clear(struct garmin_data * garmin_data_p)
+static int garmin_clear(struct garmin_data *garmin_data_p)
{
unsigned long flags;
int status = 0;
if (port != NULL && atomic_read(&garmin_data_p->resp_count)) {
/* send a terminate command */
status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
- sizeof(GARMIN_STOP_TRANSFER_REQ),
- 1);
+ sizeof(GARMIN_STOP_TRANSFER_REQ), 1);
}
/* flush all queued data */
{
unsigned long flags;
struct usb_serial *serial = port->serial;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
int status = 0;
if (status == 0) {
- usb_kill_urb (port->interrupt_in_urb);
+ usb_kill_urb(port->interrupt_in_urb);
dbg("%s - adding interrupt input", __func__);
port->interrupt_in_urb->dev = serial->dev;
status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (status)
dev_err(&serial->dev->dev,
- "%s - failed submitting interrupt urb,"
- " error %d\n",
- __func__, status);
+ "%s - failed submitting interrupt urb, error %d\n",
+ __func__, status);
}
if (status == 0) {
dbg("%s - starting session ...", __func__);
garmin_data_p->state = STATE_ACTIVE;
status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
- sizeof(GARMIN_START_SESSION_REQ),
- 0);
+ sizeof(GARMIN_START_SESSION_REQ), 0);
if (status >= 0) {
/* not needed, but the win32 driver does it too ... */
status = garmin_write_bulk(port,
- GARMIN_START_SESSION_REQ2,
- sizeof(GARMIN_START_SESSION_REQ2),
- 0);
+ GARMIN_START_SESSION_REQ2,
+ sizeof(GARMIN_START_SESSION_REQ2), 0);
if (status >= 0) {
status = 0;
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->ignorePkts++;
- spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+ spin_unlock_irqrestore(&garmin_data_p->lock,
+ flags);
}
}
}
-static int garmin_open (struct usb_serial_port *port, struct file *filp)
+static int garmin_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
unsigned long flags;
int status = 0;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
dbg("%s - port %d", __func__, port->number);
* through, otherwise it is scheduled, and with high data rates (like
* with OHCI) data can get lost.
*/
- if (port->tty)
- port->tty->low_latency = 1;
+ if (tty)
+ tty->low_latency = 1;
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->mode = initial_mode;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
/* shutdown any bulk reads that might be going on */
- usb_kill_urb (port->write_urb);
- usb_kill_urb (port->read_urb);
+ usb_kill_urb(port->write_urb);
+ usb_kill_urb(port->read_urb);
- if (garmin_data_p->state == STATE_RESET) {
+ if (garmin_data_p->state == STATE_RESET)
status = garmin_init_session(port);
- }
garmin_data_p->state = STATE_ACTIVE;
-
return status;
}
-static void garmin_close (struct usb_serial_port *port, struct file * filp)
+static void garmin_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
dbg("%s - port %d - mode=%d state=%d flags=0x%X", __func__,
port->number, garmin_data_p->mode,
garmin_clear(garmin_data_p);
/* shutdown our urbs */
- usb_kill_urb (port->read_urb);
- usb_kill_urb (port->write_urb);
+ usb_kill_urb(port->read_urb);
+ usb_kill_urb(port->write_urb);
if (!port->serial->disconnected) {
if (noResponseFromAppLayer(garmin_data_p) ||
mutex_unlock(&port->serial->disc_mutex);
}
-
-static void garmin_write_bulk_callback (struct urb *urb)
+static void garmin_write_bulk_callback(struct urb *urb)
{
unsigned long flags;
struct usb_serial_port *port = urb->context;
int status = urb->status;
if (port) {
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p =
+ usb_get_serial_port_data(port);
dbg("%s - port %d", __func__, port->number);
if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)
&& (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {
- gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]);
+ gsp_send_ack(garmin_data_p,
+ ((__u8 *)urb->transfer_buffer)[4]);
}
if (status) {
usb_serial_port_softint(port);
}
- /* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */
+ /* Ignore errors that resulted from garmin_write_bulk with
+ dismiss_ack = 1 */
/* free up the transfer buffer, as usb_free_urb() does not do this */
- kfree (urb->transfer_buffer);
+ kfree(urb->transfer_buffer);
}
-static int garmin_write_bulk (struct usb_serial_port *port,
+static int garmin_write_bulk(struct usb_serial_port *port,
const unsigned char *buf, int count,
int dismiss_ack)
{
unsigned long flags;
struct usb_serial *serial = port->serial;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
struct urb *urb;
unsigned char *buffer;
int status;
garmin_data_p->flags &= ~FLAGS_DROP_DATA;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
- buffer = kmalloc (count, GFP_ATOMIC);
+ buffer = kmalloc(count, GFP_ATOMIC);
if (!buffer) {
dev_err(&port->dev, "out of memory\n");
return -ENOMEM;
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
dev_err(&port->dev, "no more free urbs\n");
- kfree (buffer);
+ kfree(buffer);
return -ENOMEM;
}
- memcpy (buffer, buf, count);
+ memcpy(buffer, buf, count);
usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
- usb_fill_bulk_urb (urb, serial->dev,
- usb_sndbulkpipe (serial->dev,
- port->bulk_out_endpointAddress),
+ usb_fill_bulk_urb(urb, serial->dev,
+ usb_sndbulkpipe(serial->dev,
+ port->bulk_out_endpointAddress),
buffer, count,
garmin_write_bulk_callback,
dismiss_ack ? NULL : port);
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
dev_err(&port->dev,
- "%s - usb_submit_urb(write bulk) "
- "failed with status = %d\n",
+ "%s - usb_submit_urb(write bulk) failed with status = %d\n",
__func__, status);
count = status;
}
/* we are done with this urb, so let the host driver
* really free it when it is finished with it */
- usb_free_urb (urb);
+ usb_free_urb(urb);
return count;
}
-
-
-static int garmin_write (struct usb_serial_port *port,
- const unsigned char *buf, int count)
+static int garmin_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
int pktid, pktsiz, len;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
__le32 *privpkt = (__le32 *)garmin_data_p->privpkt;
usb_serial_debug_data(debug, &port->dev, __func__, count, buf);
/* check for our private packets */
if (count >= GARMIN_PKTHDR_LENGTH) {
-
len = PRIVPKTSIZ;
if (count < len)
len = count;
pktid = getPacketId(garmin_data_p->privpkt);
if (count == (GARMIN_PKTHDR_LENGTH+pktsiz)
- && GARMIN_LAYERID_PRIVATE == getLayerId(garmin_data_p->privpkt)) {
+ && GARMIN_LAYERID_PRIVATE ==
+ getLayerId(garmin_data_p->privpkt)) {
dbg("%s - processing private request %d",
__func__, pktid);
- // drop all unfinished transfers
+ /* drop all unfinished transfers */
garmin_clear(garmin_data_p);
- switch(pktid) {
+ switch (pktid) {
case PRIV_PKTID_SET_DEBUG:
if (pktsiz != 4)
}
-static int garmin_write_room (struct usb_serial_port *port)
+static int garmin_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
/*
* Report back the bytes currently available in the output buffer.
*/
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
return GPS_OUT_BUFSIZ-garmin_data_p->outsize;
}
-static int garmin_chars_in_buffer (struct usb_serial_port *port)
-{
- /*
- * Report back the number of bytes currently in our input buffer.
- * Will this lock up the driver - the buffer contains an incomplete
- * package which will not be written to the device until it
- * has been completed ?
- */
- //struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
- //return garmin_data_p->insize;
- return 0;
-}
-
-
-static void garmin_read_process(struct garmin_data * garmin_data_p,
+static void garmin_read_process(struct garmin_data *garmin_data_p,
unsigned char *data, unsigned data_length)
{
if (garmin_data_p->flags & FLAGS_DROP_DATA) {
/* abort-transfer cmd is actice */
dbg("%s - pkt dropped", __func__);
} else if (garmin_data_p->state != STATE_DISCONNECTED &&
- garmin_data_p->state != STATE_RESET ) {
+ garmin_data_p->state != STATE_RESET) {
/* remember any appl.layer packets, so we know
if a reset is required or not when closing
the device */
if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,
- sizeof(GARMIN_APP_LAYER_REPLY))) {
+ sizeof(GARMIN_APP_LAYER_REPLY))) {
atomic_inc(&garmin_data_p->resp_count);
}
if (garmin_data_p->flags & FLAGS_QUEUING) {
pkt_add(garmin_data_p, data, data_length);
} else if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
- if (getLayerId(data) == GARMIN_LAYERID_APPL) {
+ if (getLayerId(data) == GARMIN_LAYERID_APPL)
pkt_add(garmin_data_p, data, data_length);
- }
} else {
send_to_tty(garmin_data_p->port, data, data_length);
}
}
-static void garmin_read_bulk_callback (struct urb *urb)
+static void garmin_read_bulk_callback(struct urb *urb)
{
unsigned long flags;
struct usb_serial_port *port = urb->context;
struct usb_serial *serial = port->serial;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
unsigned char *data = urb->transfer_buffer;
int status = urb->status;
int retval;
return;
}
- usb_serial_debug_data(debug, &port->dev,
+ usb_serial_debug_data(debug, &port->dev,
__func__, urb->actual_length, data);
garmin_read_process(garmin_data_p, data, urb->actual_length);
}
-static void garmin_read_int_callback (struct urb *urb)
+static void garmin_read_int_callback(struct urb *urb)
{
unsigned long flags;
int retval;
struct usb_serial_port *port = urb->context;
struct usb_serial *serial = port->serial;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
unsigned char *data = urb->transfer_buffer;
int status = urb->status;
if (urb->actual_length == sizeof(GARMIN_BULK_IN_AVAIL_REPLY) &&
0 == memcmp(data, GARMIN_BULK_IN_AVAIL_REPLY,
- sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) {
+ sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) {
dbg("%s - bulk data available.", __func__);
if (0 == (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) {
/* bulk data available */
- usb_fill_bulk_urb (port->read_urb, serial->dev,
- usb_rcvbulkpipe (serial->dev,
- port->bulk_in_endpointAddress),
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
garmin_read_bulk_callback, port);
retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (retval) {
dev_err(&port->dev,
- "%s - failed submitting read urb, error %d\n",
- __func__, retval);
+ "%s - failed submitting read urb, error %d\n",
+ __func__, retval);
} else {
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE;
/* do not send this packet to the user */
garmin_data_p->ignorePkts = 1;
- spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+ spin_unlock_irqrestore(&garmin_data_p->lock,
+ flags);
}
} else {
/* bulk-in transfer still active */
} else if (urb->actual_length == (4+sizeof(GARMIN_START_SESSION_REPLY))
&& 0 == memcmp(data, GARMIN_START_SESSION_REPLY,
- sizeof(GARMIN_START_SESSION_REPLY))) {
+ sizeof(GARMIN_START_SESSION_REPLY))) {
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= FLAGS_SESSION_REPLY1_SEEN;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
/* save the serial number */
- garmin_data_p->serial_num
- = __le32_to_cpup((__le32*)(data+GARMIN_PKTHDR_LENGTH));
+ garmin_data_p->serial_num = __le32_to_cpup(
+ (__le32 *)(data+GARMIN_PKTHDR_LENGTH));
dbg("%s - start-of-session reply seen - serial %u.",
__func__, garmin_data_p->serial_num);
}
port->interrupt_in_urb->dev = port->serial->dev;
- retval = usb_submit_urb (urb, GFP_ATOMIC);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
dev_err(&urb->dev->dev,
"%s - Error %d submitting interrupt urb\n",
* and then sets a timer to call itself again until all queued data
* is sent.
*/
-static int garmin_flush_queue(struct garmin_data * garmin_data_p)
+static int garmin_flush_queue(struct garmin_data *garmin_data_p)
{
unsigned long flags;
struct garmin_packet *pkt;
}
-static void garmin_throttle (struct usb_serial_port *port)
+static void garmin_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
unsigned long flags;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
dbg("%s - port %d", __func__, port->number);
/* set flag, data received will be put into a queue
}
-static void garmin_unthrottle (struct usb_serial_port *port)
+static void garmin_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
unsigned long flags;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
int status;
dbg("%s - port %d", __func__, port->number);
}
}
-
-
/*
* The timer is currently only used to send queued packets to
* the tty in cases where the protocol provides no own handshaking
-static int garmin_attach (struct usb_serial *serial)
+static int garmin_attach(struct usb_serial *serial)
{
int status = 0;
struct usb_serial_port *port = serial->port[0];
- struct garmin_data * garmin_data_p = NULL;
+ struct garmin_data *garmin_data_p = NULL;
dbg("%s", __func__);
init_timer(&garmin_data_p->timer);
spin_lock_init(&garmin_data_p->lock);
INIT_LIST_HEAD(&garmin_data_p->pktlist);
- //garmin_data_p->timer.expires = jiffies + session_timeout;
+ /* garmin_data_p->timer.expires = jiffies + session_timeout; */
garmin_data_p->timer.data = (unsigned long)garmin_data_p;
garmin_data_p->timer.function = timeout_handler;
garmin_data_p->port = port;
}
-static void garmin_shutdown (struct usb_serial *serial)
+static void garmin_shutdown(struct usb_serial *serial)
{
struct usb_serial_port *port = serial->port[0];
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
dbg("%s", __func__);
- usb_kill_urb (port->interrupt_in_urb);
+ usb_kill_urb(port->interrupt_in_urb);
del_timer_sync(&garmin_data_p->timer);
- kfree (garmin_data_p);
+ kfree(garmin_data_p);
usb_set_serial_port_data(port, NULL);
}
.shutdown = garmin_shutdown,
.write = garmin_write,
.write_room = garmin_write_room,
- .chars_in_buffer = garmin_chars_in_buffer,
.write_bulk_callback = garmin_write_bulk_callback,
.read_bulk_callback = garmin_read_bulk_callback,
.read_int_callback = garmin_read_int_callback,
-static int __init garmin_init (void)
+static int __init garmin_init(void)
{
int retval;
}
-static void __exit garmin_exit (void)
+static void __exit garmin_exit(void)
{
- usb_deregister (&garmin_driver);
- usb_serial_deregister (&garmin_device);
+ usb_deregister(&garmin_driver);
+ usb_serial_deregister(&garmin_device);
}
module_init(garmin_init);
module_exit(garmin_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IWUSR | S_IRUGO);
#include <linux/moduleparam.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
static int debug;
}
#endif
-int usb_serial_generic_register (int _debug)
+int usb_serial_generic_register(int _debug)
{
int retval = 0;
#ifdef CONFIG_USB_SERIAL_GENERIC
generic_device_ids[0].idVendor = vendor;
generic_device_ids[0].idProduct = product;
- generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
+ generic_device_ids[0].match_flags =
+ USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
/* register our generic driver with ourselves */
- retval = usb_serial_register (&usb_serial_generic_device);
+ retval = usb_serial_register(&usb_serial_generic_device);
if (retval)
goto exit;
retval = usb_register(&generic_driver);
return retval;
}
-void usb_serial_generic_deregister (void)
+void usb_serial_generic_deregister(void)
{
#ifdef CONFIG_USB_SERIAL_GENERIC
/* remove our generic driver */
usb_deregister(&generic_driver);
- usb_serial_deregister (&usb_serial_generic_device);
+ usb_serial_deregister(&usb_serial_generic_device);
#endif
}
-int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
+int usb_serial_generic_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
int result = 0;
dbg("%s - port %d", __func__, port->number);
- /* force low_latency on so that our tty_push actually forces the data through,
- otherwise it is scheduled, and with high data rates (like with OHCI) data
- can get lost. */
- if (port->tty)
- port->tty->low_latency = 1;
+ /* force low_latency on so that our tty_push actually forces the data
+ through, otherwise it is scheduled, and with high data rates (like
+ with OHCI) data can get lost. */
+ if (tty)
+ tty->low_latency = 1;
/* clear the throttle flags */
spin_lock_irqsave(&port->lock, flags);
/* if we have a bulk endpoint, start reading from it */
if (serial->num_bulk_in) {
/* Start reading from the device */
- usb_fill_bulk_urb (port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
((serial->type->read_bulk_callback) ?
port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
- dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
}
return result;
}
EXPORT_SYMBOL_GPL(usb_serial_generic_open);
-static void generic_cleanup (struct usb_serial_port *port)
+static void generic_cleanup(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
#endif
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
- if (port->open_count && port->read_urb) {
+ if (port->port.count && port->read_urb) {
r = usb_submit_urb(port->read_urb, GFP_NOIO);
if (r < 0)
c++;
return c ? -EIO : 0;
}
-void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp)
+void usb_serial_generic_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
dbg("%s - port %d", __func__, port->number);
- generic_cleanup (port);
+ generic_cleanup(port);
}
-int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+int usb_serial_generic_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct usb_serial *serial = port->serial;
int result;
if (count == 0) {
dbg("%s - write request of 0 bytes", __func__);
- return (0);
+ return 0;
}
/* only do something if we have a bulk out endpoint */
port->write_urb_busy = 1;
spin_unlock_irqrestore(&port->lock, flags);
- count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
+ count = (count > port->bulk_out_size) ?
+ port->bulk_out_size : count;
- memcpy (port->write_urb->transfer_buffer, buf, count);
+ memcpy(port->write_urb->transfer_buffer, buf, count);
data = port->write_urb->transfer_buffer;
usb_serial_debug_data(debug, &port->dev, __func__, count, data);
/* set up our urb */
- usb_fill_bulk_urb (port->write_urb, serial->dev,
- usb_sndbulkpipe (serial->dev,
- port->bulk_out_endpointAddress),
+ usb_fill_bulk_urb(port->write_urb, serial->dev,
+ usb_sndbulkpipe(serial->dev,
+ port->bulk_out_endpointAddress),
port->write_urb->transfer_buffer, count,
- ((serial->type->write_bulk_callback) ?
+ ((serial->type->write_bulk_callback) ?
serial->type->write_bulk_callback :
- usb_serial_generic_write_bulk_callback), port);
+ usb_serial_generic_write_bulk_callback),
+ port);
/* send the data out the bulk port */
port->write_urb_busy = 1;
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (result) {
- dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result);
- /* don't have to grab the lock here, as we will retry if != 0 */
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, result);
+ /* don't have to grab the lock here, as we will
+ retry if != 0 */
port->write_urb_busy = 0;
} else
result = count;
return 0;
}
-int usb_serial_generic_write_room (struct usb_serial_port *port)
+int usb_serial_generic_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
int room = 0;
return room;
}
-int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
+int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
int chars = 0;
}
dbg("%s - returns %d", __func__, chars);
- return (chars);
+ return chars;
}
int result;
/* Continue reading from device */
- usb_fill_bulk_urb (urb, serial->dev,
- usb_rcvbulkpipe (serial->dev,
- port->bulk_in_endpointAddress),
+ usb_fill_bulk_urb(urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->bulk_in_endpointAddress),
urb->transfer_buffer,
urb->transfer_buffer_length,
- ((serial->type->read_bulk_callback) ?
- serial->type->read_bulk_callback :
+ ((serial->type->read_bulk_callback) ?
+ serial->type->read_bulk_callback :
usb_serial_generic_read_bulk_callback), port);
result = usb_submit_urb(urb, mem_flags);
if (result)
- dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
}
/* Push data to tty layer and resubmit the bulk read URB */
-static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
+static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
{
struct urb *urb = port->read_urb;
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
int room;
/* Push data to tty */
resubmit_read_urb(port, GFP_ATOMIC);
}
-void usb_serial_generic_read_bulk_callback (struct urb *urb)
+void usb_serial_generic_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
unsigned char *data = urb->transfer_buffer;
return;
}
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
/* Throttle the device if requested by tty */
spin_lock_irqsave(&port->lock, flags);
- if (!(port->throttled = port->throttle_req)) {
+ port->throttled = port->throttle_req;
+ if (!port->throttled) {
spin_unlock_irqrestore(&port->lock, flags);
flush_and_resubmit_read_urb(port);
- } else {
+ } else
spin_unlock_irqrestore(&port->lock, flags);
- }
}
EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
-void usb_serial_generic_write_bulk_callback (struct urb *urb)
+void usb_serial_generic_write_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
int status = urb->status;
}
EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
-void usb_serial_generic_throttle (struct usb_serial_port *port)
+void usb_serial_generic_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned long flags;
dbg("%s - port %d", __func__, port->number);
spin_unlock_irqrestore(&port->lock, flags);
}
-void usb_serial_generic_unthrottle (struct usb_serial_port *port)
+void usb_serial_generic_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
int was_throttled;
unsigned long flags;
}
}
-void usb_serial_generic_shutdown (struct usb_serial *serial)
+void usb_serial_generic_shutdown(struct usb_serial *serial)
{
int i;
dbg("%s", __func__);
/* stop reads and writes on all ports */
- for (i=0; i < serial->num_ports; ++i) {
+ for (i = 0; i < serial->num_ports; ++i)
generic_cleanup(serial->port[i]);
- }
}
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*/
#include <linux/kernel.h>
#include <linux/wait.h>
#include <linux/firmware.h>
#include <linux/ihex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "io_edgeport.h"
/* receive port state */
enum RXSTATE {
- EXPECT_HDR1 = 0, /* Expect header byte 1 */
- EXPECT_HDR2 = 1, /* Expect header byte 2 */
- EXPECT_DATA = 2, /* Expect 'RxBytesRemaining' data */
- EXPECT_HDR3 = 3, /* Expect header byte 3 (for status hdrs only) */
+ EXPECT_HDR1 = 0, /* Expect header byte 1 */
+ EXPECT_HDR2 = 1, /* Expect header byte 2 */
+ EXPECT_DATA = 2, /* Expect 'RxBytesRemaining' data */
+ EXPECT_HDR3 = 3, /* Expect header byte 3 (for status hdrs only) */
};
-/* Transmit Fifo
- * This Transmit queue is an extension of the edgeport Rx buffer.
- * The maximum amount of data buffered in both the edgeport
+/* Transmit Fifo
+ * This Transmit queue is an extension of the edgeport Rx buffer.
+ * The maximum amount of data buffered in both the edgeport
* Rx buffer (maxTxCredits) and this buffer will never exceed maxTxCredits.
*/
struct TxFifo {
int is_epic; /* flag if EPiC device or not */
__u8 interrupt_in_endpoint; /* the interrupt endpoint handle */
- unsigned char * interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */
- struct urb * interrupt_read_urb; /* our interrupt urb */
+ unsigned char *interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */
+ struct urb *interrupt_read_urb; /* our interrupt urb */
__u8 bulk_in_endpoint; /* the bulk in endpoint handle */
- unsigned char * bulk_in_buffer; /* the buffer we use for the bulk in endpoint */
- struct urb * read_urb; /* our bulk read urb */
+ unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */
+ struct urb *read_urb; /* our bulk read urb */
bool read_in_progress;
spinlock_t es_lock;
__u16 Divisor;
};
-//
-// Define table of divisors for Rev A EdgePort/4 hardware
-// These assume a 3.6864MHz crystal, the standard /16, and
-// MCR.7 = 0.
-//
+/*
+ * Define table of divisors for Rev A EdgePort/4 hardware
+ * These assume a 3.6864MHz crystal, the standard /16, and
+ * MCR.7 = 0.
+ */
+
static const struct divisor_table_entry divisor_table[] = {
- { 50, 4608},
- { 75, 3072},
- { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */
- { 134, 1713}, /* 1713.011152 => 230398.5 => .00065% under */
+ { 50, 4608},
+ { 75, 3072},
+ { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */
+ { 134, 1713}, /* 1713.011152 => 230398.5 => .00065% under */
{ 150, 1536},
{ 300, 768},
{ 600, 384},
static int low_latency = 1; /* tty low latency flag, on by default */
-static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */
+static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */
/* local function prototypes */
/* function prototypes for all URB callbacks */
-static void edge_interrupt_callback (struct urb *urb);
-static void edge_bulk_in_callback (struct urb *urb);
-static void edge_bulk_out_data_callback (struct urb *urb);
-static void edge_bulk_out_cmd_callback (struct urb *urb);
+static void edge_interrupt_callback(struct urb *urb);
+static void edge_bulk_in_callback(struct urb *urb);
+static void edge_bulk_out_data_callback(struct urb *urb);
+static void edge_bulk_out_cmd_callback(struct urb *urb);
/* function prototypes for the usbserial callbacks */
-static int edge_open (struct usb_serial_port *port, struct file *filp);
-static void edge_close (struct usb_serial_port *port, struct file *filp);
-static int edge_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int edge_write_room (struct usb_serial_port *port);
-static int edge_chars_in_buffer (struct usb_serial_port *port);
-static void edge_throttle (struct usb_serial_port *port);
-static void edge_unthrottle (struct usb_serial_port *port);
-static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
-static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
-static void edge_break (struct usb_serial_port *port, int break_state);
-static int edge_tiocmget (struct usb_serial_port *port, struct file *file);
-static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
-static int edge_startup (struct usb_serial *serial);
-static void edge_shutdown (struct usb_serial *serial);
-
+static int edge_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static void edge_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+static int edge_write_room(struct tty_struct *tty);
+static int edge_chars_in_buffer(struct tty_struct *tty);
+static void edge_throttle(struct tty_struct *tty);
+static void edge_unthrottle(struct tty_struct *tty);
+static void edge_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ struct ktermios *old_termios);
+static int edge_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void edge_break(struct tty_struct *tty, int break_state);
+static int edge_tiocmget(struct tty_struct *tty, struct file *file);
+static int edge_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static int edge_startup(struct usb_serial *serial);
+static void edge_shutdown(struct usb_serial *serial);
#include "io_tables.h" /* all of the devices that this driver supports */
/* function prototypes for all of our local functions */
-static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength);
-static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3);
-static void edge_tty_recv (struct device *dev, struct tty_struct *tty, unsigned char *data, int length);
-static void handle_new_msr (struct edgeport_port *edge_port, __u8 newMsr);
-static void handle_new_lsr (struct edgeport_port *edge_port, __u8 lsrData, __u8 lsr, __u8 data);
-static int send_iosp_ext_cmd (struct edgeport_port *edge_port, __u8 command, __u8 param);
-static int calc_baud_rate_divisor (int baud_rate, int *divisor);
-static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate);
-static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios);
-static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue);
-static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer, int writeLength);
-static void send_more_port_data (struct edgeport_serial *edge_serial, struct edgeport_port *edge_port);
-
-static int sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data);
-static int rom_read (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data);
-static int rom_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data);
-static void get_manufacturing_desc (struct edgeport_serial *edge_serial);
-static void get_boot_desc (struct edgeport_serial *edge_serial);
-static void load_application_firmware (struct edgeport_serial *edge_serial);
-
-static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size);
-
-
-// ************************************************************************
-// ************************************************************************
-// ************************************************************************
-// ************************************************************************
+
+static void process_rcvd_data(struct edgeport_serial *edge_serial,
+ unsigned char *buffer, __u16 bufferLength);
+static void process_rcvd_status(struct edgeport_serial *edge_serial,
+ __u8 byte2, __u8 byte3);
+static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
+ unsigned char *data, int length);
+static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr);
+static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData,
+ __u8 lsr, __u8 data);
+static int send_iosp_ext_cmd(struct edgeport_port *edge_port, __u8 command,
+ __u8 param);
+static int calc_baud_rate_divisor(int baud_rate, int *divisor);
+static int send_cmd_write_baud_rate(struct edgeport_port *edge_port,
+ int baudRate);
+static void change_port_settings(struct tty_struct *tty,
+ struct edgeport_port *edge_port,
+ struct ktermios *old_termios);
+static int send_cmd_write_uart_register(struct edgeport_port *edge_port,
+ __u8 regNum, __u8 regValue);
+static int write_cmd_usb(struct edgeport_port *edge_port,
+ unsigned char *buffer, int writeLength);
+static void send_more_port_data(struct edgeport_serial *edge_serial,
+ struct edgeport_port *edge_port);
+
+static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+ __u16 length, const __u8 *data);
+static int rom_read(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+ __u16 length, __u8 *data);
+static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+ __u16 length, const __u8 *data);
+static void get_manufacturing_desc(struct edgeport_serial *edge_serial);
+static void get_boot_desc(struct edgeport_serial *edge_serial);
+static void load_application_firmware(struct edgeport_serial *edge_serial);
+
+static void unicode_to_ascii(char *string, int buflen,
+ __le16 *unicode, int unicode_size);
+
+
+/* ************************************************************************ */
+/* ************************************************************************ */
+/* ************************************************************************ */
+/* ************************************************************************ */
/************************************************************************
* *
* embedded in this driver *
* *
************************************************************************/
-static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial)
+static void update_edgeport_E2PROM(struct edgeport_serial *edge_serial)
{
__u32 BootCurVer;
__u32 BootNewVer;
int response;
switch (edge_serial->product_info.iDownloadFile) {
- case EDGE_DOWNLOAD_FILE_I930:
- fw_name = "edgeport/boot.fw";
- break;
-
- case EDGE_DOWNLOAD_FILE_80251:
- fw_name = "edgeport/boot2.fw";
- break;
-
- default:
- return;
+ case EDGE_DOWNLOAD_FILE_I930:
+ fw_name = "edgeport/boot.fw";
+ break;
+ case EDGE_DOWNLOAD_FILE_80251:
+ fw_name = "edgeport/boot2.fw";
+ break;
+ default:
+ return;
}
response = request_ihex_firmware(&fw, fw_name,
BootMinorVersion = rec->data[1];
BootBuildNumber = (rec->data[2] << 8) | rec->data[3];
- // Check Boot Image Version
+ /* Check Boot Image Version */
BootCurVer = (edge_serial->boot_descriptor.MajorVersion << 24) +
(edge_serial->boot_descriptor.MinorVersion << 16) +
le16_to_cpu(edge_serial->boot_descriptor.BuildNumber);
* Get string descriptor from device *
* *
************************************************************************/
-static int get_string (struct usb_device *dev, int Id, char *string, int buflen)
+static int get_string(struct usb_device *dev, int Id, char *string, int buflen)
{
struct usb_string_descriptor StringDesc;
struct usb_string_descriptor *pStringDesc;
- dbg("%s - USB String ID = %d", __func__, Id );
+ dbg("%s - USB String ID = %d", __func__, Id);
- if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) {
+ if (!usb_get_descriptor(dev, USB_DT_STRING, Id,
+ &StringDesc, sizeof(StringDesc)))
return 0;
- }
- pStringDesc = kmalloc (StringDesc.bLength, GFP_KERNEL);
-
- if (!pStringDesc) {
+ pStringDesc = kmalloc(StringDesc.bLength, GFP_KERNEL);
+ if (!pStringDesc)
return 0;
- }
- if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, StringDesc.bLength )) {
+ if (!usb_get_descriptor(dev, USB_DT_STRING, Id,
+ pStringDesc, StringDesc.bLength)) {
kfree(pStringDesc);
return 0;
}
- unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2);
+ unicode_to_ascii(string, buflen,
+ pStringDesc->wData, pStringDesc->bLength/2);
kfree(pStringDesc);
dbg("%s - USB String %s", __func__, string);
* Get string descriptor from device
*
************************************************************************/
-static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_descriptor **pRetDesc)
+static int get_string_desc(struct usb_device *dev, int Id,
+ struct usb_string_descriptor **pRetDesc)
{
struct usb_string_descriptor StringDesc;
struct usb_string_descriptor *pStringDesc;
- dbg("%s - USB String ID = %d", __func__, Id );
+ dbg("%s - USB String ID = %d", __func__, Id);
- if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) {
+ if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc,
+ sizeof(StringDesc)))
return 0;
- }
- pStringDesc = kmalloc (StringDesc.bLength, GFP_KERNEL);
-
- if (!pStringDesc) {
+ pStringDesc = kmalloc(StringDesc.bLength, GFP_KERNEL);
+ if (!pStringDesc)
return -1;
- }
- if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, StringDesc.bLength )) {
+ if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc,
+ StringDesc.bLength)) {
kfree(pStringDesc);
return -1;
}
static void dump_product_info(struct edgeport_product_info *product_info)
{
- // Dump Product Info structure
+ /* Dump Product Info structure */
dbg("**Product Information:");
- dbg(" ProductId %x", product_info->ProductId );
- dbg(" NumPorts %d", product_info->NumPorts );
- dbg(" ProdInfoVer %d", product_info->ProdInfoVer );
+ dbg(" ProductId %x", product_info->ProductId);
+ dbg(" NumPorts %d", product_info->NumPorts);
+ dbg(" ProdInfoVer %d", product_info->ProdInfoVer);
dbg(" IsServer %d", product_info->IsServer);
- dbg(" IsRS232 %d", product_info->IsRS232 );
- dbg(" IsRS422 %d", product_info->IsRS422 );
- dbg(" IsRS485 %d", product_info->IsRS485 );
- dbg(" RomSize %d", product_info->RomSize );
- dbg(" RamSize %d", product_info->RamSize );
- dbg(" CpuRev %x", product_info->CpuRev );
+ dbg(" IsRS232 %d", product_info->IsRS232);
+ dbg(" IsRS422 %d", product_info->IsRS422);
+ dbg(" IsRS485 %d", product_info->IsRS485);
+ dbg(" RomSize %d", product_info->RomSize);
+ dbg(" RamSize %d", product_info->RamSize);
+ dbg(" CpuRev %x", product_info->CpuRev);
dbg(" BoardRev %x", product_info->BoardRev);
dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion,
product_info->BootMinorVersion,
le16_to_cpu(product_info->BootBuildNumber));
- dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0],
- product_info->ManufactureDescDate[1],
- product_info->ManufactureDescDate[2]+1900);
+ dbg(" FirmwareMajorVersion %d.%d.%d",
+ product_info->FirmwareMajorVersion,
+ product_info->FirmwareMinorVersion,
+ le16_to_cpu(product_info->FirmwareBuildNumber));
+ dbg(" ManufactureDescDate %d/%d/%d",
+ product_info->ManufactureDescDate[0],
+ product_info->ManufactureDescDate[1],
+ product_info->ManufactureDescDate[2]+1900);
dbg(" iDownloadFile 0x%x", product_info->iDownloadFile);
dbg(" EpicVer %d", product_info->EpicVer);
}
{
struct edgeport_product_info *product_info = &edge_serial->product_info;
- memset (product_info, 0, sizeof(struct edgeport_product_info));
-
- product_info->ProductId = (__u16)(le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ~ION_DEVICE_ID_80251_NETCHIP);
- product_info->NumPorts = edge_serial->manuf_descriptor.NumPorts;
- product_info->ProdInfoVer = 0;
-
- product_info->RomSize = edge_serial->manuf_descriptor.RomSize;
- product_info->RamSize = edge_serial->manuf_descriptor.RamSize;
- product_info->CpuRev = edge_serial->manuf_descriptor.CpuRev;
- product_info->BoardRev = edge_serial->manuf_descriptor.BoardRev;
-
- product_info->BootMajorVersion = edge_serial->boot_descriptor.MajorVersion;
- product_info->BootMinorVersion = edge_serial->boot_descriptor.MinorVersion;
- product_info->BootBuildNumber = edge_serial->boot_descriptor.BuildNumber;
-
- memcpy(product_info->ManufactureDescDate, edge_serial->manuf_descriptor.DescDate, sizeof(edge_serial->manuf_descriptor.DescDate));
-
- // check if this is 2nd generation hardware
- if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ION_DEVICE_ID_80251_NETCHIP) {
- product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_80251;
- } else {
- product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_I930;
- }
-
- // Determine Product type and set appropriate flags
+ memset(product_info, 0, sizeof(struct edgeport_product_info));
+
+ product_info->ProductId = (__u16)(le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ~ION_DEVICE_ID_80251_NETCHIP);
+ product_info->NumPorts = edge_serial->manuf_descriptor.NumPorts;
+ product_info->ProdInfoVer = 0;
+
+ product_info->RomSize = edge_serial->manuf_descriptor.RomSize;
+ product_info->RamSize = edge_serial->manuf_descriptor.RamSize;
+ product_info->CpuRev = edge_serial->manuf_descriptor.CpuRev;
+ product_info->BoardRev = edge_serial->manuf_descriptor.BoardRev;
+
+ product_info->BootMajorVersion =
+ edge_serial->boot_descriptor.MajorVersion;
+ product_info->BootMinorVersion =
+ edge_serial->boot_descriptor.MinorVersion;
+ product_info->BootBuildNumber =
+ edge_serial->boot_descriptor.BuildNumber;
+
+ memcpy(product_info->ManufactureDescDate,
+ edge_serial->manuf_descriptor.DescDate,
+ sizeof(edge_serial->manuf_descriptor.DescDate));
+
+ /* check if this is 2nd generation hardware */
+ if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct)
+ & ION_DEVICE_ID_80251_NETCHIP)
+ product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_80251;
+ else
+ product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_I930;
+
+ /* Determine Product type and set appropriate flags */
switch (DEVICE_ID_FROM_USB_PRODUCT_ID(product_info->ProductId)) {
- case ION_DEVICE_ID_EDGEPORT_COMPATIBLE:
- case ION_DEVICE_ID_EDGEPORT_4T:
- case ION_DEVICE_ID_EDGEPORT_4:
- case ION_DEVICE_ID_EDGEPORT_2:
- case ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU:
- case ION_DEVICE_ID_EDGEPORT_8:
- case ION_DEVICE_ID_EDGEPORT_421:
- case ION_DEVICE_ID_EDGEPORT_21:
- case ION_DEVICE_ID_EDGEPORT_2_DIN:
- case ION_DEVICE_ID_EDGEPORT_4_DIN:
- case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU:
- product_info->IsRS232 = 1;
- break;
+ case ION_DEVICE_ID_EDGEPORT_COMPATIBLE:
+ case ION_DEVICE_ID_EDGEPORT_4T:
+ case ION_DEVICE_ID_EDGEPORT_4:
+ case ION_DEVICE_ID_EDGEPORT_2:
+ case ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU:
+ case ION_DEVICE_ID_EDGEPORT_8:
+ case ION_DEVICE_ID_EDGEPORT_421:
+ case ION_DEVICE_ID_EDGEPORT_21:
+ case ION_DEVICE_ID_EDGEPORT_2_DIN:
+ case ION_DEVICE_ID_EDGEPORT_4_DIN:
+ case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU:
+ product_info->IsRS232 = 1;
+ break;
- case ION_DEVICE_ID_EDGEPORT_2I: // Edgeport/2 RS422/RS485
- product_info->IsRS422 = 1;
- product_info->IsRS485 = 1;
- break;
+ case ION_DEVICE_ID_EDGEPORT_2I: /* Edgeport/2 RS422/RS485 */
+ product_info->IsRS422 = 1;
+ product_info->IsRS485 = 1;
+ break;
- case ION_DEVICE_ID_EDGEPORT_8I: // Edgeport/4 RS422
- case ION_DEVICE_ID_EDGEPORT_4I: // Edgeport/4 RS422
- product_info->IsRS422 = 1;
- break;
+ case ION_DEVICE_ID_EDGEPORT_8I: /* Edgeport/4 RS422 */
+ case ION_DEVICE_ID_EDGEPORT_4I: /* Edgeport/4 RS422 */
+ product_info->IsRS422 = 1;
+ break;
}
dump_product_info(product_info);
ep->is_epic = 1;
memset(product_info, 0, sizeof(struct edgeport_product_info));
- product_info->NumPorts = epic->NumPorts;
- product_info->ProdInfoVer = 0;
- product_info->FirmwareMajorVersion = epic->MajorVersion;
- product_info->FirmwareMinorVersion = epic->MinorVersion;
- product_info->FirmwareBuildNumber = epic->BuildNumber;
- product_info->iDownloadFile = epic->iDownloadFile;
- product_info->EpicVer = epic->EpicVer;
- product_info->Epic = epic->Supports;
- product_info->ProductId = ION_DEVICE_ID_EDGEPORT_COMPATIBLE;
+ product_info->NumPorts = epic->NumPorts;
+ product_info->ProdInfoVer = 0;
+ product_info->FirmwareMajorVersion = epic->MajorVersion;
+ product_info->FirmwareMinorVersion = epic->MinorVersion;
+ product_info->FirmwareBuildNumber = epic->BuildNumber;
+ product_info->iDownloadFile = epic->iDownloadFile;
+ product_info->EpicVer = epic->EpicVer;
+ product_info->Epic = epic->Supports;
+ product_info->ProductId = ION_DEVICE_ID_EDGEPORT_COMPATIBLE;
dump_product_info(product_info);
bits = &ep->epic_descriptor.Supports;
dbg("**EPIC descriptor:");
dbg(" VendEnableSuspend: %s", bits->VendEnableSuspend ? "TRUE": "FALSE");
- dbg(" IOSPOpen : %s", bits->IOSPOpen ? "TRUE": "FALSE" );
- dbg(" IOSPClose : %s", bits->IOSPClose ? "TRUE": "FALSE" );
- dbg(" IOSPChase : %s", bits->IOSPChase ? "TRUE": "FALSE" );
- dbg(" IOSPSetRxFlow : %s", bits->IOSPSetRxFlow ? "TRUE": "FALSE" );
- dbg(" IOSPSetTxFlow : %s", bits->IOSPSetTxFlow ? "TRUE": "FALSE" );
- dbg(" IOSPSetXChar : %s", bits->IOSPSetXChar ? "TRUE": "FALSE" );
- dbg(" IOSPRxCheck : %s", bits->IOSPRxCheck ? "TRUE": "FALSE" );
- dbg(" IOSPSetClrBreak : %s", bits->IOSPSetClrBreak ? "TRUE": "FALSE" );
- dbg(" IOSPWriteMCR : %s", bits->IOSPWriteMCR ? "TRUE": "FALSE" );
- dbg(" IOSPWriteLCR : %s", bits->IOSPWriteLCR ? "TRUE": "FALSE" );
- dbg(" IOSPSetBaudRate : %s", bits->IOSPSetBaudRate ? "TRUE": "FALSE" );
- dbg(" TrueEdgeport : %s", bits->TrueEdgeport ? "TRUE": "FALSE" );
+ dbg(" IOSPOpen : %s", bits->IOSPOpen ? "TRUE": "FALSE");
+ dbg(" IOSPClose : %s", bits->IOSPClose ? "TRUE": "FALSE");
+ dbg(" IOSPChase : %s", bits->IOSPChase ? "TRUE": "FALSE");
+ dbg(" IOSPSetRxFlow : %s", bits->IOSPSetRxFlow ? "TRUE": "FALSE");
+ dbg(" IOSPSetTxFlow : %s", bits->IOSPSetTxFlow ? "TRUE": "FALSE");
+ dbg(" IOSPSetXChar : %s", bits->IOSPSetXChar ? "TRUE": "FALSE");
+ dbg(" IOSPRxCheck : %s", bits->IOSPRxCheck ? "TRUE": "FALSE");
+ dbg(" IOSPSetClrBreak : %s", bits->IOSPSetClrBreak ? "TRUE": "FALSE");
+ dbg(" IOSPWriteMCR : %s", bits->IOSPWriteMCR ? "TRUE": "FALSE");
+ dbg(" IOSPWriteLCR : %s", bits->IOSPWriteLCR ? "TRUE": "FALSE");
+ dbg(" IOSPSetBaudRate : %s", bits->IOSPSetBaudRate ? "TRUE": "FALSE");
+ dbg(" TrueEdgeport : %s", bits->TrueEdgeport ? "TRUE": "FALSE");
}
return result;
/*****************************************************************************
* edge_interrupt_callback
- * this is the callback function for when we have received data on the
+ * this is the callback function for when we have received data on the
* interrupt endpoint.
*****************************************************************************/
-static void edge_interrupt_callback (struct urb *urb)
+static void edge_interrupt_callback(struct urb *urb)
{
struct edgeport_serial *edge_serial = urb->context;
struct edgeport_port *edge_port;
case -ESHUTDOWN:
/* this urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d",
- __func__, status);
+ __func__, status);
return;
default:
- dbg("%s - nonzero urb status received: %d",
- __func__, status);
+ dbg("%s - nonzero urb status received: %d", __func__, status);
goto exit;
}
- // process this interrupt-read even if there are no ports open
+ /* process this interrupt-read even if there are no ports open */
if (length) {
- usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __func__, length, data);
+ usb_serial_debug_data(debug, &edge_serial->serial->dev->dev,
+ __func__, length, data);
if (length > 1) {
bytes_avail = data[0] | (data[1] << 8);
dbg("%s - posting a read", __func__);
edge_serial->read_in_progress = true;
- /* we have pending bytes on the bulk in pipe, send a request */
+ /* we have pending bytes on the
+ bulk in pipe, send a request */
edge_serial->read_urb->dev = edge_serial->serial->dev;
result = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC);
if (result) {
/* grab the txcredits for the ports if available */
position = 2;
portNumber = 0;
- while ((position < length) && (portNumber < edge_serial->serial->num_ports)) {
+ while ((position < length) &&
+ (portNumber < edge_serial->serial->num_ports)) {
txCredits = data[position] | (data[position+1] << 8);
if (txCredits) {
port = edge_serial->serial->port[portNumber];
spin_lock(&edge_port->ep_lock);
edge_port->txCredits += txCredits;
spin_unlock(&edge_port->ep_lock);
- dbg("%s - txcredits for port%d = %d", __func__, portNumber, edge_port->txCredits);
-
- /* tell the tty driver that something has changed */
- if (edge_port->port->tty)
- tty_wakeup(edge_port->port->tty);
-
- // Since we have more credit, check if more data can be sent
- send_more_port_data(edge_serial, edge_port);
+ dbg("%s - txcredits for port%d = %d",
+ __func__, portNumber,
+ edge_port->txCredits);
+
+ /* tell the tty driver that something
+ has changed */
+ if (edge_port->port->port.tty)
+ tty_wakeup(edge_port->port->port.tty);
+
+ /* Since we have more credit, check
+ if more data can be sent */
+ send_more_port_data(edge_serial,
+ edge_port);
}
}
position += 2;
}
exit:
- result = usb_submit_urb (urb, GFP_ATOMIC);
- if (result) {
- dev_err(&urb->dev->dev, "%s - Error %d submitting control urb\n", __func__, result);
- }
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result)
+ dev_err(&urb->dev->dev,
+ "%s - Error %d submitting control urb\n",
+ __func__, result);
}
/*****************************************************************************
* edge_bulk_in_callback
- * this is the callback function for when we have received data on the
+ * this is the callback function for when we have received data on the
* bulk in endpoint.
*****************************************************************************/
-static void edge_bulk_in_callback (struct urb *urb)
+static void edge_bulk_in_callback(struct urb *urb)
{
struct edgeport_serial *edge_serial = urb->context;
unsigned char *data = urb->transfer_buffer;
raw_data_length = urb->actual_length;
- usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __func__, raw_data_length, data);
+ usb_serial_debug_data(debug, &edge_serial->serial->dev->dev,
+ __func__, raw_data_length, data);
spin_lock(&edge_serial->es_lock);
/* decrement our rxBytes available by the number that we just got */
edge_serial->rxBytesAvail -= raw_data_length;
- dbg("%s - Received = %d, rxBytesAvail %d", __func__, raw_data_length, edge_serial->rxBytesAvail);
+ dbg("%s - Received = %d, rxBytesAvail %d", __func__,
+ raw_data_length, edge_serial->rxBytesAvail);
- process_rcvd_data (edge_serial, data, urb->actual_length);
+ process_rcvd_data(edge_serial, data, urb->actual_length);
/* check to see if there's any more data for us to read */
if (edge_serial->rxBytesAvail > 0) {
/*****************************************************************************
* edge_bulk_out_data_callback
- * this is the callback function for when we have finished sending serial data
- * on the bulk out endpoint.
+ * this is the callback function for when we have finished sending
+ * serial data on the bulk out endpoint.
*****************************************************************************/
-static void edge_bulk_out_data_callback (struct urb *urb)
+static void edge_bulk_out_data_callback(struct urb *urb)
{
struct edgeport_port *edge_port = urb->context;
struct tty_struct *tty;
__func__, status);
}
- tty = edge_port->port->tty;
+ tty = edge_port->port->port.tty;
if (tty && edge_port->open) {
- /* let the tty driver wakeup if it has a special write_wakeup function */
+ /* let the tty driver wakeup if it has a special
+ write_wakeup function */
tty_wakeup(tty);
}
- // Release the Write URB
+ /* Release the Write URB */
edge_port->write_in_progress = false;
- // Check if more data needs to be sent
- send_more_port_data((struct edgeport_serial *)(usb_get_serial_data(edge_port->port->serial)), edge_port);
+ /* Check if more data needs to be sent */
+ send_more_port_data((struct edgeport_serial *)
+ (usb_get_serial_data(edge_port->port->serial)), edge_port);
}
/*****************************************************************************
* BulkOutCmdCallback
- * this is the callback function for when we have finished sending a command
- * on the bulk out endpoint.
+ * this is the callback function for when we have finished sending a
+ * command on the bulk out endpoint.
*****************************************************************************/
-static void edge_bulk_out_cmd_callback (struct urb *urb)
+static void edge_bulk_out_cmd_callback(struct urb *urb)
{
struct edgeport_port *edge_port = urb->context;
struct tty_struct *tty;
dbg("%s", __func__);
atomic_dec(&CmdUrbs);
- dbg("%s - FREE URB %p (outstanding %d)", __func__, urb, atomic_read(&CmdUrbs));
+ dbg("%s - FREE URB %p (outstanding %d)", __func__,
+ urb, atomic_read(&CmdUrbs));
/* clean up the transfer buffer */
kfree(urb->transfer_buffer);
/* Free the command urb */
- usb_free_urb (urb);
+ usb_free_urb(urb);
if (status) {
- dbg("%s - nonzero write bulk status received: %d", __func__, status);
+ dbg("%s - nonzero write bulk status received: %d",
+ __func__, status);
return;
}
/* Get pointer to tty */
- tty = edge_port->port->tty;
+ tty = edge_port->port->port.tty;
/* tell the tty driver that something has changed */
if (tty && edge_port->open)
* If successful, we return 0
* Otherwise we return a negative error number.
*****************************************************************************/
-static int edge_open (struct usb_serial_port *port, struct file * filp)
+static int edge_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
struct usb_serial *serial;
if (edge_port == NULL)
return -ENODEV;
- if (port->tty)
- port->tty->low_latency = low_latency;
+ if (tty)
+ tty->low_latency = low_latency;
- /* see if we've set up our endpoint info yet (can't set it up in edge_startup
- as the structures were not set up at that time.) */
+ /* see if we've set up our endpoint info yet (can't set it up
+ in edge_startup as the structures were not set up at that time.) */
serial = port->serial;
edge_serial = usb_get_serial_data(serial);
- if (edge_serial == NULL) {
+ if (edge_serial == NULL)
return -ENODEV;
- }
if (edge_serial->interrupt_in_buffer == NULL) {
struct usb_serial_port *port0 = serial->port[0];
-
+
/* not set up yet, so do it now */
- edge_serial->interrupt_in_buffer = port0->interrupt_in_buffer;
- edge_serial->interrupt_in_endpoint = port0->interrupt_in_endpointAddress;
+ edge_serial->interrupt_in_buffer =
+ port0->interrupt_in_buffer;
+ edge_serial->interrupt_in_endpoint =
+ port0->interrupt_in_endpointAddress;
edge_serial->interrupt_read_urb = port0->interrupt_in_urb;
edge_serial->bulk_in_buffer = port0->bulk_in_buffer;
- edge_serial->bulk_in_endpoint = port0->bulk_in_endpointAddress;
+ edge_serial->bulk_in_endpoint =
+ port0->bulk_in_endpointAddress;
edge_serial->read_urb = port0->read_urb;
- edge_serial->bulk_out_endpoint = port0->bulk_out_endpointAddress;
-
+ edge_serial->bulk_out_endpoint =
+ port0->bulk_out_endpointAddress;
+
/* set up our interrupt urb */
usb_fill_int_urb(edge_serial->interrupt_read_urb,
- serial->dev,
- usb_rcvintpipe(serial->dev,
- port0->interrupt_in_endpointAddress),
- port0->interrupt_in_buffer,
- edge_serial->interrupt_read_urb->transfer_buffer_length,
- edge_interrupt_callback, edge_serial,
- edge_serial->interrupt_read_urb->interval);
-
+ serial->dev,
+ usb_rcvintpipe(serial->dev,
+ port0->interrupt_in_endpointAddress),
+ port0->interrupt_in_buffer,
+ edge_serial->interrupt_read_urb->transfer_buffer_length,
+ edge_interrupt_callback, edge_serial,
+ edge_serial->interrupt_read_urb->interval);
+
/* set up our bulk in urb */
usb_fill_bulk_urb(edge_serial->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev,
- port0->bulk_in_endpointAddress),
- port0->bulk_in_buffer,
- edge_serial->read_urb->transfer_buffer_length,
- edge_bulk_in_callback, edge_serial);
+ usb_rcvbulkpipe(serial->dev,
+ port0->bulk_in_endpointAddress),
+ port0->bulk_in_buffer,
+ edge_serial->read_urb->transfer_buffer_length,
+ edge_bulk_in_callback, edge_serial);
edge_serial->read_in_progress = false;
/* start interrupt read for this edgeport
- * this interrupt will continue as long as the edgeport is connected */
- response = usb_submit_urb (edge_serial->interrupt_read_urb, GFP_KERNEL);
+ * this interrupt will continue as long
+ * as the edgeport is connected */
+ response = usb_submit_urb(edge_serial->interrupt_read_urb,
+ GFP_KERNEL);
if (response) {
- dev_err(&port->dev, "%s - Error %d submitting control urb\n", __func__, response);
+ dev_err(&port->dev,
+ "%s - Error %d submitting control urb\n",
+ __func__, response);
}
}
-
+
/* initialize our wait queues */
init_waitqueue_head(&edge_port->wait_open);
init_waitqueue_head(&edge_port->wait_chase);
init_waitqueue_head(&edge_port->wait_command);
/* initialize our icount structure */
- memset (&(edge_port->icount), 0x00, sizeof(edge_port->icount));
+ memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
/* initialize our port settings */
- edge_port->txCredits = 0; /* Can't send any data yet */
- edge_port->shadowMCR = MCR_MASTER_IE; /* Must always set this bit to enable ints! */
+ edge_port->txCredits = 0; /* Can't send any data yet */
+ /* Must always set this bit to enable ints! */
+ edge_port->shadowMCR = MCR_MASTER_IE;
edge_port->chaseResponsePending = false;
/* send a open port command */
edge_port->openPending = true;
edge_port->open = false;
- response = send_iosp_ext_cmd (edge_port, IOSP_CMD_OPEN_PORT, 0);
+ response = send_iosp_ext_cmd(edge_port, IOSP_CMD_OPEN_PORT, 0);
if (response < 0) {
- dev_err(&port->dev, "%s - error sending open port command\n", __func__);
+ dev_err(&port->dev, "%s - error sending open port command\n",
+ __func__);
edge_port->openPending = false;
return -ENODEV;
}
/* now wait for the port to be completely opened */
- wait_event_timeout(edge_port->wait_open, !edge_port->openPending, OPEN_TIMEOUT);
+ wait_event_timeout(edge_port->wait_open, !edge_port->openPending,
+ OPEN_TIMEOUT);
if (!edge_port->open) {
/* open timed out */
edge_port->txfifo.tail = 0;
edge_port->txfifo.count = 0;
edge_port->txfifo.size = edge_port->maxTxCredits;
- edge_port->txfifo.fifo = kmalloc (edge_port->maxTxCredits, GFP_KERNEL);
+ edge_port->txfifo.fifo = kmalloc(edge_port->maxTxCredits, GFP_KERNEL);
if (!edge_port->txfifo.fifo) {
dbg("%s - no memory", __func__);
- edge_close (port, filp);
+ edge_close(tty, port, filp);
return -ENOMEM;
}
/* Allocate a URB for the write */
- edge_port->write_urb = usb_alloc_urb (0, GFP_KERNEL);
+ edge_port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
edge_port->write_in_progress = false;
if (!edge_port->write_urb) {
dbg("%s - no memory", __func__);
- edge_close (port, filp);
+ edge_close(tty, port, filp);
return -ENOMEM;
}
- dbg("%s(%d) - Initialize TX fifo to %d bytes", __func__, port->number, edge_port->maxTxCredits);
+ dbg("%s(%d) - Initialize TX fifo to %d bytes",
+ __func__, port->number, edge_port->maxTxCredits);
dbg("%s exited", __func__);
int loop = 10;
while (1) {
- // Save Last credits
+ /* Save Last credits */
lastCredits = edge_port->txCredits;
- // Did we get our Chase response
+ /* Did we get our Chase response */
if (!edge_port->chaseResponsePending) {
dbg("%s - Got Chase Response", __func__);
- // did we get all of our credit back?
- if (edge_port->txCredits == edge_port->maxTxCredits ) {
+ /* did we get all of our credit back? */
+ if (edge_port->txCredits == edge_port->maxTxCredits) {
dbg("%s - Got all credits", __func__);
return;
}
}
- // Block the thread for a while
- prepare_to_wait(&edge_port->wait_chase, &wait, TASK_UNINTERRUPTIBLE);
+ /* Block the thread for a while */
+ prepare_to_wait(&edge_port->wait_chase, &wait,
+ TASK_UNINTERRUPTIBLE);
schedule_timeout(timeout);
finish_wait(&edge_port->wait_chase, &wait);
if (lastCredits == edge_port->txCredits) {
- // No activity.. count down.
+ /* No activity.. count down. */
loop--;
if (loop == 0) {
edge_port->chaseResponsePending = false;
return;
}
} else {
- // Reset timeout value back to 10 seconds
- dbg("%s - Last %d, Current %d", __func__, lastCredits, edge_port->txCredits);
+ /* Reset timeout value back to 10 seconds */
+ dbg("%s - Last %d, Current %d", __func__,
+ lastCredits, edge_port->txCredits);
loop = 10;
}
}
* 3. A timeout of 3 seconds without activity has expired
*
************************************************************************/
-static void block_until_tx_empty (struct edgeport_port *edge_port)
+static void block_until_tx_empty(struct edgeport_port *edge_port)
{
DEFINE_WAIT(wait);
struct TxFifo *fifo = &edge_port->txfifo;
int loop = 30;
while (1) {
- // Save Last count
+ /* Save Last count */
lastCount = fifo->count;
- // Is the Edgeport Buffer empty?
+ /* Is the Edgeport Buffer empty? */
if (lastCount == 0) {
dbg("%s - TX Buffer Empty", __func__);
return;
}
- // Block the thread for a while
- prepare_to_wait (&edge_port->wait_chase, &wait, TASK_UNINTERRUPTIBLE);
+ /* Block the thread for a while */
+ prepare_to_wait(&edge_port->wait_chase, &wait,
+ TASK_UNINTERRUPTIBLE);
schedule_timeout(timeout);
finish_wait(&edge_port->wait_chase, &wait);
dbg("%s wait", __func__);
if (lastCount == fifo->count) {
- // No activity.. count down.
+ /* No activity.. count down. */
loop--;
if (loop == 0) {
dbg("%s - TIMEOUT", __func__);
return;
}
} else {
- // Reset timeout value back to seconds
+ /* Reset timeout value back to seconds */
loop = 30;
}
}
* edge_close
* this function is called by the tty driver when a port is closed
*****************************************************************************/
-static void edge_close (struct usb_serial_port *port, struct file * filp)
+static void edge_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
int status;
dbg("%s - port %d", __func__, port->number);
-
+
edge_serial = usb_get_serial_data(port->serial);
edge_port = usb_get_serial_port_data(port);
- if ((edge_serial == NULL) || (edge_port == NULL))
+ if (edge_serial == NULL || edge_port == NULL)
return;
-
- // block until tx is empty
+
+ /* block until tx is empty */
block_until_tx_empty(edge_port);
edge_port->closePending = true;
edge_port->chaseResponsePending = true;
dbg("%s - Sending IOSP_CMD_CHASE_PORT", __func__);
- status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0);
- if (status == 0) {
- // block until chase finished
+ status = send_iosp_ext_cmd(edge_port, IOSP_CMD_CHASE_PORT, 0);
+ if (status == 0)
+ /* block until chase finished */
block_until_chase_response(edge_port);
- } else {
+ else
edge_port->chaseResponsePending = false;
- }
}
if ((!edge_serial->is_epic) ||
(edge_serial->epic_descriptor.Supports.IOSPClose))) {
/* close the port */
dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __func__);
- send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0);
+ send_iosp_ext_cmd(edge_port, IOSP_CMD_CLOSE_PORT, 0);
}
- //port->close = true;
+ /* port->close = true; */
edge_port->closePending = false;
edge_port->open = false;
edge_port->openPending = false;
usb_kill_urb(edge_port->write_urb);
if (edge_port->write_urb) {
- /* if this urb had a transfer buffer already (old transfer) free it */
+ /* if this urb had a transfer buffer already
+ (old transfer) free it */
kfree(edge_port->write_urb->transfer_buffer);
usb_free_urb(edge_port->write_urb);
edge_port->write_urb = NULL;
edge_port->txfifo.fifo = NULL;
dbg("%s exited", __func__);
-}
+}
/*****************************************************************************
* SerialWrite
- * this function is called by the tty driver when data should be written to
- * the port.
- * If successful, we return the number of bytes written, otherwise we return
- * a negative error number.
+ * this function is called by the tty driver when data should be written
+ * to the port.
+ * If successful, we return the number of bytes written, otherwise we
+ * return a negative error number.
*****************************************************************************/
-static int edge_write (struct usb_serial_port *port, const unsigned char *data, int count)
+static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *data, int count)
{
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
struct TxFifo *fifo;
if (edge_port == NULL)
return -ENODEV;
- // get a pointer to the Tx fifo
+ /* get a pointer to the Tx fifo */
fifo = &edge_port->txfifo;
spin_lock_irqsave(&edge_port->ep_lock, flags);
- // calculate number of bytes to put in fifo
- copySize = min ((unsigned int)count, (edge_port->txCredits - fifo->count));
+ /* calculate number of bytes to put in fifo */
+ copySize = min((unsigned int)count,
+ (edge_port->txCredits - fifo->count));
- dbg("%s(%d) of %d byte(s) Fifo room %d -- will copy %d bytes", __func__,
- port->number, count, edge_port->txCredits - fifo->count, copySize);
+ dbg("%s(%d) of %d byte(s) Fifo room %d -- will copy %d bytes",
+ __func__, port->number, count,
+ edge_port->txCredits - fifo->count, copySize);
- /* catch writes of 0 bytes which the tty driver likes to give us, and when txCredits is empty */
+ /* catch writes of 0 bytes which the tty driver likes to give us,
+ and when txCredits is empty */
if (copySize == 0) {
dbg("%s - copySize = Zero", __func__);
goto finish_write;
}
- // queue the data
- // since we can never overflow the buffer we do not have to check for full condition
-
- // the copy is done is two parts -- first fill to the end of the buffer
- // then copy the reset from the start of the buffer
-
+ /* queue the data
+ * since we can never overflow the buffer we do not have to check for a
+ * full condition
+ *
+ * the copy is done is two parts -- first fill to the end of the buffer
+ * then copy the reset from the start of the buffer
+ */
bytesleft = fifo->size - fifo->head;
- firsthalf = min (bytesleft, copySize);
- dbg("%s - copy %d bytes of %d into fifo ", __func__, firsthalf, bytesleft);
+ firsthalf = min(bytesleft, copySize);
+ dbg("%s - copy %d bytes of %d into fifo ", __func__,
+ firsthalf, bytesleft);
/* now copy our data */
memcpy(&fifo->fifo[fifo->head], data, firsthalf);
- usb_serial_debug_data(debug, &port->dev, __func__, firsthalf, &fifo->fifo[fifo->head]);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ firsthalf, &fifo->fifo[fifo->head]);
- // update the index and size
+ /* update the index and size */
fifo->head += firsthalf;
fifo->count += firsthalf;
- // wrap the index
- if (fifo->head == fifo->size) {
+ /* wrap the index */
+ if (fifo->head == fifo->size)
fifo->head = 0;
- }
secondhalf = copySize-firsthalf;
if (secondhalf) {
dbg("%s - copy rest of data %d", __func__, secondhalf);
memcpy(&fifo->fifo[fifo->head], &data[firsthalf], secondhalf);
- usb_serial_debug_data(debug, &port->dev, __func__, secondhalf, &fifo->fifo[fifo->head]);
- // update the index and size
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ secondhalf, &fifo->fifo[fifo->head]);
+ /* update the index and size */
fifo->count += secondhalf;
fifo->head += secondhalf;
- // No need to check for wrap since we can not get to end of fifo in this part
+ /* No need to check for wrap since we can not get to end of
+ * the fifo in this part
+ */
}
finish_write:
spin_unlock_irqrestore(&edge_port->ep_lock, flags);
- send_more_port_data((struct edgeport_serial *)usb_get_serial_data(port->serial), edge_port);
+ send_more_port_data((struct edgeport_serial *)
+ usb_get_serial_data(port->serial), edge_port);
- dbg("%s wrote %d byte(s) TxCredits %d, Fifo %d", __func__, copySize, edge_port->txCredits, fifo->count);
+ dbg("%s wrote %d byte(s) TxCredits %d, Fifo %d", __func__,
+ copySize, edge_port->txCredits, fifo->count);
- return copySize;
+ return copySize;
}
* can transmit more.
*
************************************************************************/
-static void send_more_port_data(struct edgeport_serial *edge_serial, struct edgeport_port *edge_port)
+static void send_more_port_data(struct edgeport_serial *edge_serial,
+ struct edgeport_port *edge_port)
{
struct TxFifo *fifo = &edge_port->txfifo;
struct urb *urb;
if (edge_port->write_in_progress ||
!edge_port->open ||
(fifo->count == 0)) {
- dbg("%s(%d) EXIT - fifo %d, PendingWrite = %d", __func__, edge_port->port->number, fifo->count, edge_port->write_in_progress);
+ dbg("%s(%d) EXIT - fifo %d, PendingWrite = %d",
+ __func__, edge_port->port->number,
+ fifo->count, edge_port->write_in_progress);
goto exit_send;
}
- // since the amount of data in the fifo will always fit into the
- // edgeport buffer we do not need to check the write length
-
- // Do we have enough credits for this port to make it worthwhile
- // to bother queueing a write. If it's too small, say a few bytes,
- // it's better to wait for more credits so we can do a larger
- // write.
- if (edge_port->txCredits < EDGE_FW_GET_TX_CREDITS_SEND_THRESHOLD(edge_port->maxTxCredits,EDGE_FW_BULK_MAX_PACKET_SIZE)) {
- dbg("%s(%d) Not enough credit - fifo %d TxCredit %d", __func__, edge_port->port->number, fifo->count, edge_port->txCredits );
+ /* since the amount of data in the fifo will always fit into the
+ * edgeport buffer we do not need to check the write length
+ *
+ * Do we have enough credits for this port to make it worthwhile
+ * to bother queueing a write. If it's too small, say a few bytes,
+ * it's better to wait for more credits so we can do a larger write.
+ */
+ if (edge_port->txCredits < EDGE_FW_GET_TX_CREDITS_SEND_THRESHOLD(edge_port->maxTxCredits, EDGE_FW_BULK_MAX_PACKET_SIZE)) {
+ dbg("%s(%d) Not enough credit - fifo %d TxCredit %d",
+ __func__, edge_port->port->number, fifo->count,
+ edge_port->txCredits);
goto exit_send;
}
- // lock this write
+ /* lock this write */
edge_port->write_in_progress = true;
- // get a pointer to the write_urb
+ /* get a pointer to the write_urb */
urb = edge_port->write_urb;
/* make sure transfer buffer is freed */
kfree(urb->transfer_buffer);
urb->transfer_buffer = NULL;
- /* build the data header for the buffer and port that we are about to send out */
+ /* build the data header for the buffer and port that we are about
+ to send out */
count = fifo->count;
- buffer = kmalloc (count+2, GFP_ATOMIC);
+ buffer = kmalloc(count+2, GFP_ATOMIC);
if (buffer == NULL) {
- dev_err(&edge_port->port->dev, "%s - no more kernel memory...\n", __func__);
+ dev_err(&edge_port->port->dev,
+ "%s - no more kernel memory...\n", __func__);
edge_port->write_in_progress = false;
goto exit_send;
}
- buffer[0] = IOSP_BUILD_DATA_HDR1 (edge_port->port->number - edge_port->port->serial->minor, count);
- buffer[1] = IOSP_BUILD_DATA_HDR2 (edge_port->port->number - edge_port->port->serial->minor, count);
+ buffer[0] = IOSP_BUILD_DATA_HDR1(edge_port->port->number
+ - edge_port->port->serial->minor, count);
+ buffer[1] = IOSP_BUILD_DATA_HDR2(edge_port->port->number
+ - edge_port->port->serial->minor, count);
/* now copy our data */
bytesleft = fifo->size - fifo->tail;
- firsthalf = min (bytesleft, count);
+ firsthalf = min(bytesleft, count);
memcpy(&buffer[2], &fifo->fifo[fifo->tail], firsthalf);
fifo->tail += firsthalf;
fifo->count -= firsthalf;
- if (fifo->tail == fifo->size) {
+ if (fifo->tail == fifo->size)
fifo->tail = 0;
- }
secondhalf = count-firsthalf;
if (secondhalf) {
- memcpy(&buffer[2+firsthalf], &fifo->fifo[fifo->tail], secondhalf);
+ memcpy(&buffer[2+firsthalf], &fifo->fifo[fifo->tail],
+ secondhalf);
fifo->tail += secondhalf;
fifo->count -= secondhalf;
}
if (count)
- usb_serial_debug_data(debug, &edge_port->port->dev, __func__, count, &buffer[2]);
+ usb_serial_debug_data(debug, &edge_port->port->dev,
+ __func__, count, &buffer[2]);
/* fill up the urb with all of our data and submit it */
- usb_fill_bulk_urb (urb, edge_serial->serial->dev,
- usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint),
- buffer, count+2, edge_bulk_out_data_callback, edge_port);
+ usb_fill_bulk_urb(urb, edge_serial->serial->dev,
+ usb_sndbulkpipe(edge_serial->serial->dev,
+ edge_serial->bulk_out_endpoint),
+ buffer, count+2,
+ edge_bulk_out_data_callback, edge_port);
/* decrement the number of credits we have by the number we just sent */
edge_port->txCredits -= count;
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
/* something went wrong */
- dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n", __func__, status);
+ dev_err(&edge_port->port->dev,
+ "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n",
+ __func__, status);
edge_port->write_in_progress = false;
/* revert the credits as something bad happened. */
edge_port->txCredits += count;
edge_port->icount.tx -= count;
}
- dbg("%s wrote %d byte(s) TxCredit %d, Fifo %d", __func__, count, edge_port->txCredits, fifo->count);
+ dbg("%s wrote %d byte(s) TxCredit %d, Fifo %d",
+ __func__, count, edge_port->txCredits, fifo->count);
exit_send:
spin_unlock_irqrestore(&edge_port->ep_lock, flags);
/*****************************************************************************
* edge_write_room
- * this function is called by the tty driver when it wants to know how many
- * bytes of data we can accept for a specific port.
- * If successful, we return the amount of room that we have for this port
- * (the txCredits),
- * Otherwise we return a negative error number.
+ * this function is called by the tty driver when it wants to know how
+ * many bytes of data we can accept for a specific port. If successful,
+ * we return the amount of room that we have for this port (the txCredits)
+ * otherwise we return a negative error number.
*****************************************************************************/
-static int edge_write_room (struct usb_serial_port *port)
+static int edge_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
int room;
unsigned long flags;
dbg("%s", __func__);
if (edge_port == NULL)
- return -ENODEV;
+ return 0;
if (edge_port->closePending)
- return -ENODEV;
+ return 0;
dbg("%s - port %d", __func__, port->number);
if (!edge_port->open) {
dbg("%s - port not opened", __func__);
- return -EINVAL;
+ return 0;
}
- // total of both buffers is still txCredit
+ /* total of both buffers is still txCredit */
spin_lock_irqsave(&edge_port->ep_lock, flags);
room = edge_port->txCredits - edge_port->txfifo.count;
spin_unlock_irqrestore(&edge_port->ep_lock, flags);
/*****************************************************************************
* edge_chars_in_buffer
- * this function is called by the tty driver when it wants to know how many
- * bytes of data we currently have outstanding in the port (data that has
- * been written, but hasn't made it out the port yet)
- * If successful, we return the number of bytes left to be written in the
- * system,
+ * this function is called by the tty driver when it wants to know how
+ * many bytes of data we currently have outstanding in the port (data that
+ * has been written, but hasn't made it out the port yet)
+ * If successful, we return the number of bytes left to be written in the
+ * system,
* Otherwise we return a negative error number.
*****************************************************************************/
-static int edge_chars_in_buffer (struct usb_serial_port *port)
+static int edge_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
int num_chars;
unsigned long flags;
dbg("%s", __func__);
if (edge_port == NULL)
- return -ENODEV;
+ return 0;
if (edge_port->closePending)
- return -ENODEV;
+ return 0;
if (!edge_port->open) {
dbg("%s - port not opened", __func__);
- return -EINVAL;
+ return 0;
}
spin_lock_irqsave(&edge_port->ep_lock, flags);
- num_chars = edge_port->maxTxCredits - edge_port->txCredits + edge_port->txfifo.count;
+ num_chars = edge_port->maxTxCredits - edge_port->txCredits +
+ edge_port->txfifo.count;
spin_unlock_irqrestore(&edge_port->ep_lock, flags);
if (num_chars) {
- dbg("%s(port %d) - returns %d", __func__, port->number, num_chars);
+ dbg("%s(port %d) - returns %d", __func__,
+ port->number, num_chars);
}
return num_chars;
* this function is called by the tty driver when it wants to stop the data
* being read from the port.
*****************************************************************************/
-static void edge_throttle (struct usb_serial_port *port)
+static void edge_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
- struct tty_struct *tty;
int status;
dbg("%s - port %d", __func__, port->number);
return;
}
- tty = port->tty;
- if (!tty) {
- dbg ("%s - no tty available", __func__);
- return;
- }
-
/* if we are implementing XON/XOFF, send the stop character */
if (I_IXOFF(tty)) {
unsigned char stop_char = STOP_CHAR(tty);
- status = edge_write (port, &stop_char, 1);
- if (status <= 0) {
+ status = edge_write(tty, port, &stop_char, 1);
+ if (status <= 0)
return;
- }
}
/* if we are implementing RTS/CTS, toggle that line */
if (tty->termios->c_cflag & CRTSCTS) {
edge_port->shadowMCR &= ~MCR_RTS;
- status = send_cmd_write_uart_register(edge_port, MCR, edge_port->shadowMCR);
- if (status != 0) {
+ status = send_cmd_write_uart_register(edge_port, MCR,
+ edge_port->shadowMCR);
+ if (status != 0)
return;
- }
}
return;
/*****************************************************************************
* edge_unthrottle
- * this function is called by the tty driver when it wants to resume the data
- * being read from the port (called after SerialThrottle is called)
+ * this function is called by the tty driver when it wants to resume the
+ * data being read from the port (called after SerialThrottle is called)
*****************************************************************************/
-static void edge_unthrottle (struct usb_serial_port *port)
+static void edge_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
- struct tty_struct *tty;
int status;
dbg("%s - port %d", __func__, port->number);
return;
}
- tty = port->tty;
- if (!tty) {
- dbg ("%s - no tty available", __func__);
- return;
- }
-
/* if we are implementing XON/XOFF, send the start character */
if (I_IXOFF(tty)) {
unsigned char start_char = START_CHAR(tty);
- status = edge_write (port, &start_char, 1);
- if (status <= 0) {
+ status = edge_write(tty, port, &start_char, 1);
+ if (status <= 0)
return;
- }
}
-
/* if we are implementing RTS/CTS, toggle that line */
if (tty->termios->c_cflag & CRTSCTS) {
edge_port->shadowMCR |= MCR_RTS;
- status = send_cmd_write_uart_register(edge_port, MCR, edge_port->shadowMCR);
- if (status != 0) {
- return;
- }
+ send_cmd_write_uart_register(edge_port, MCR,
+ edge_port->shadowMCR);
}
-
- return;
}
/*****************************************************************************
* SerialSetTermios
- * this function is called by the tty driver when it wants to change the termios structure
+ * this function is called by the tty driver when it wants to change
+ * the termios structure
*****************************************************************************/
-static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void edge_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
- /* FIXME: This function appears unused ?? */
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
- struct tty_struct *tty = port->tty;
unsigned int cflag;
cflag = tty->termios->c_cflag;
}
/* change the port settings to the new ones specified */
- change_port_settings (edge_port, old_termios);
-
- return;
+ change_port_settings(tty, edge_port, old_termios);
}
* release the bus after transmitting. This must be done when
* the transmit shift register is empty, not be done when the
* transmit holding register is empty. This functionality
- * allows an RS485 driver to be written in user space.
+ * allows an RS485 driver to be written in user space.
*****************************************************************************/
-static int get_lsr_info(struct edgeport_port *edge_port, unsigned int __user *value)
+static int get_lsr_info(struct edgeport_port *edge_port,
+ unsigned int __user *value)
{
unsigned int result = 0;
unsigned long flags;
return 0;
}
-static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int __user *value)
-{
- unsigned int result = 0;
- struct tty_struct *tty = edge_port->port->tty;
-
- if (!tty)
- return -ENOIOCTLCMD;
-
- result = tty->read_cnt;
-
- dbg("%s(%d) = %d", __func__, edge_port->port->number, result);
- if (copy_to_user(value, &result, sizeof(int)))
- return -EFAULT;
- //return 0;
- return -ENOIOCTLCMD;
-}
-
-static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear)
+static int edge_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
unsigned int mcr;
return 0;
}
-static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
+static int edge_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
unsigned int result = 0;
unsigned int msr;
return result;
}
-static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct __user *retinfo)
+static int get_serial_info(struct edgeport_port *edge_port,
+ struct serial_struct __user *retinfo)
{
struct serial_struct tmp;
tmp.baud_base = 9600;
tmp.close_delay = 5*HZ;
tmp.closing_wait = 30*HZ;
-// tmp.custom_divisor = state->custom_divisor;
-// tmp.hub6 = state->hub6;
-// tmp.io_type = state->io_type;
if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
return -EFAULT;
* SerialIoctl
* this function handles any ioctl calls to the driver
*****************************************************************************/
-static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg)
+static int edge_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
DEFINE_WAIT(wait);
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
struct async_icount cnow;
dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
switch (cmd) {
- // return number of bytes available
- case TIOCINQ:
- dbg("%s (%d) TIOCINQ", __func__, port->number);
- return get_number_bytes_avail(edge_port, (unsigned int __user *) arg);
- break;
-
- case TIOCSERGETLSR:
- dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
- return get_lsr_info(edge_port, (unsigned int __user *) arg);
- return 0;
-
- case TIOCGSERIAL:
- dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
- return get_serial_info(edge_port, (struct serial_struct __user *) arg);
-
- case TIOCSSERIAL:
- dbg("%s (%d) TIOCSSERIAL", __func__, port->number);
- break;
-
- case TIOCMIWAIT:
- dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
- cprev = edge_port->icount;
- while (1) {
- prepare_to_wait(&edge_port->delta_msr_wait, &wait, TASK_INTERRUPTIBLE);
- schedule();
- finish_wait(&edge_port->delta_msr_wait, &wait);
- /* see if a signal did it */
- if (signal_pending(current))
- return -ERESTARTSYS;
- cnow = edge_port->icount;
- if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
- cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
- return -EIO; /* no change => error */
- if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
- return 0;
- }
- cprev = cnow;
+ case TIOCSERGETLSR:
+ dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
+ return get_lsr_info(edge_port, (unsigned int __user *) arg);
+
+ case TIOCGSERIAL:
+ dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
+ return get_serial_info(edge_port, (struct serial_struct __user *) arg);
+
+ case TIOCMIWAIT:
+ dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
+ cprev = edge_port->icount;
+ while (1) {
+ prepare_to_wait(&edge_port->delta_msr_wait,
+ &wait, TASK_INTERRUPTIBLE);
+ schedule();
+ finish_wait(&edge_port->delta_msr_wait, &wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ cnow = edge_port->icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+ return -EIO; /* no change => error */
+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+ return 0;
}
- /* NOTREACHED */
- break;
+ cprev = cnow;
+ }
+ /* NOTREACHED */
+ break;
- case TIOCGICOUNT:
- cnow = edge_port->icount;
- memset(&icount, 0, sizeof(icount));
- icount.cts = cnow.cts;
- icount.dsr = cnow.dsr;
- icount.rng = cnow.rng;
- icount.dcd = cnow.dcd;
- icount.rx = cnow.rx;
- icount.tx = cnow.tx;
- icount.frame = cnow.frame;
- icount.overrun = cnow.overrun;
- icount.parity = cnow.parity;
- icount.brk = cnow.brk;
- icount.buf_overrun = cnow.buf_overrun;
-
- dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, port->number, icount.rx, icount.tx );
- if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
- return -EFAULT;
- return 0;
+ case TIOCGICOUNT:
+ cnow = edge_port->icount;
+ memset(&icount, 0, sizeof(icount));
+ icount.cts = cnow.cts;
+ icount.dsr = cnow.dsr;
+ icount.rng = cnow.rng;
+ icount.dcd = cnow.dcd;
+ icount.rx = cnow.rx;
+ icount.tx = cnow.tx;
+ icount.frame = cnow.frame;
+ icount.overrun = cnow.overrun;
+ icount.parity = cnow.parity;
+ icount.brk = cnow.brk;
+ icount.buf_overrun = cnow.buf_overrun;
+
+ dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d",
+ __func__, port->number, icount.rx, icount.tx);
+ if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
+ return -EFAULT;
+ return 0;
}
-
return -ENOIOCTLCMD;
}
* SerialBreak
* this function sends a break to the port
*****************************************************************************/
-static void edge_break (struct usb_serial_port *port, int break_state)
+static void edge_break(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial);
int status;
edge_port->chaseResponsePending = true;
dbg("%s - Sending IOSP_CMD_CHASE_PORT", __func__);
- status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0);
+ status = send_iosp_ext_cmd(edge_port, IOSP_CMD_CHASE_PORT, 0);
if (status == 0) {
- // block until chase finished
+ /* block until chase finished */
block_until_chase_response(edge_port);
} else {
edge_port->chaseResponsePending = false;
(edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) {
if (break_state == -1) {
dbg("%s - Sending IOSP_CMD_SET_BREAK", __func__);
- status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0);
+ status = send_iosp_ext_cmd(edge_port,
+ IOSP_CMD_SET_BREAK, 0);
} else {
dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __func__);
- status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0);
- }
- if (status) {
- dbg("%s - error sending break set/clear command.", __func__);
+ status = send_iosp_ext_cmd(edge_port,
+ IOSP_CMD_CLEAR_BREAK, 0);
}
+ if (status)
+ dbg("%s - error sending break set/clear command.",
+ __func__);
}
return;
* process_rcvd_data
* this function handles the data received on the bulk in pipe.
*****************************************************************************/
-static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char * buffer, __u16 bufferLength)
+static void process_rcvd_data(struct edgeport_serial *edge_serial,
+ unsigned char *buffer, __u16 bufferLength)
{
struct usb_serial_port *port;
struct edgeport_port *edge_port;
lastBufferLength = bufferLength;
switch (edge_serial->rxState) {
- case EXPECT_HDR1:
- edge_serial->rxHeader1 = *buffer;
- ++buffer;
- --bufferLength;
+ case EXPECT_HDR1:
+ edge_serial->rxHeader1 = *buffer;
+ ++buffer;
+ --bufferLength;
- if (bufferLength == 0) {
- edge_serial->rxState = EXPECT_HDR2;
+ if (bufferLength == 0) {
+ edge_serial->rxState = EXPECT_HDR2;
+ break;
+ }
+ /* otherwise, drop on through */
+ case EXPECT_HDR2:
+ edge_serial->rxHeader2 = *buffer;
+ ++buffer;
+ --bufferLength;
+
+ dbg("%s - Hdr1=%02X Hdr2=%02X", __func__,
+ edge_serial->rxHeader1, edge_serial->rxHeader2);
+ /* Process depending on whether this header is
+ * data or status */
+
+ if (IS_CMD_STAT_HDR(edge_serial->rxHeader1)) {
+ /* Decode this status header and go to
+ * EXPECT_HDR1 (if we can process the status
+ * with only 2 bytes), or go to EXPECT_HDR3 to
+ * get the third byte. */
+ edge_serial->rxPort =
+ IOSP_GET_HDR_PORT(edge_serial->rxHeader1);
+ edge_serial->rxStatusCode =
+ IOSP_GET_STATUS_CODE(
+ edge_serial->rxHeader1);
+
+ if (!IOSP_STATUS_IS_2BYTE(
+ edge_serial->rxStatusCode)) {
+ /* This status needs additional bytes.
+ * Save what we have and then wait for
+ * more data.
+ */
+ edge_serial->rxStatusParam
+ = edge_serial->rxHeader2;
+ edge_serial->rxState = EXPECT_HDR3;
break;
}
- /* otherwise, drop on through */
-
- case EXPECT_HDR2:
- edge_serial->rxHeader2 = *buffer;
- ++buffer;
- --bufferLength;
-
- dbg("%s - Hdr1=%02X Hdr2=%02X", __func__, edge_serial->rxHeader1, edge_serial->rxHeader2);
-
- // Process depending on whether this header is
- // data or status
-
- if (IS_CMD_STAT_HDR(edge_serial->rxHeader1)) {
- // Decode this status header and goto EXPECT_HDR1 (if we
- // can process the status with only 2 bytes), or goto
- // EXPECT_HDR3 to get the third byte.
-
- edge_serial->rxPort = IOSP_GET_HDR_PORT(edge_serial->rxHeader1);
- edge_serial->rxStatusCode = IOSP_GET_STATUS_CODE(edge_serial->rxHeader1);
-
- if (!IOSP_STATUS_IS_2BYTE(edge_serial->rxStatusCode)) {
- // This status needs additional bytes. Save what we have
- // and then wait for more data.
- edge_serial->rxStatusParam = edge_serial->rxHeader2;
-
- edge_serial->rxState = EXPECT_HDR3;
- break;
- }
+ /* We have all the header bytes, process the
+ status now */
+ process_rcvd_status(edge_serial,
+ edge_serial->rxHeader2, 0);
+ edge_serial->rxState = EXPECT_HDR1;
+ break;
+ } else {
+ edge_serial->rxPort =
+ IOSP_GET_HDR_PORT(edge_serial->rxHeader1);
+ edge_serial->rxBytesRemaining =
+ IOSP_GET_HDR_DATA_LEN(
+ edge_serial->rxHeader1,
+ edge_serial->rxHeader2);
+ dbg("%s - Data for Port %u Len %u",
+ __func__,
+ edge_serial->rxPort,
+ edge_serial->rxBytesRemaining);
+
+ /* ASSERT(DevExt->RxPort < DevExt->NumPorts);
+ * ASSERT(DevExt->RxBytesRemaining <
+ * IOSP_MAX_DATA_LENGTH);
+ */
- // We have all the header bytes, process the status now
- process_rcvd_status (edge_serial, edge_serial->rxHeader2, 0);
- edge_serial->rxState = EXPECT_HDR1;
+ if (bufferLength == 0) {
+ edge_serial->rxState = EXPECT_DATA;
break;
- } else {
- edge_serial->rxPort = IOSP_GET_HDR_PORT(edge_serial->rxHeader1);
- edge_serial->rxBytesRemaining = IOSP_GET_HDR_DATA_LEN(edge_serial->rxHeader1, edge_serial->rxHeader2);
-
- dbg("%s - Data for Port %u Len %u", __func__, edge_serial->rxPort, edge_serial->rxBytesRemaining);
-
- //ASSERT( DevExt->RxPort < DevExt->NumPorts );
- //ASSERT( DevExt->RxBytesRemaining < IOSP_MAX_DATA_LENGTH );
-
- if (bufferLength == 0 ) {
- edge_serial->rxState = EXPECT_DATA;
- break;
- }
- // Else, drop through
}
+ /* Else, drop through */
+ }
+ case EXPECT_DATA: /* Expect data */
+ if (bufferLength < edge_serial->rxBytesRemaining) {
+ rxLen = bufferLength;
+ /* Expect data to start next buffer */
+ edge_serial->rxState = EXPECT_DATA;
+ } else {
+ /* BufLen >= RxBytesRemaining */
+ rxLen = edge_serial->rxBytesRemaining;
+ /* Start another header next time */
+ edge_serial->rxState = EXPECT_HDR1;
+ }
- case EXPECT_DATA: // Expect data
-
- if (bufferLength < edge_serial->rxBytesRemaining) {
- rxLen = bufferLength;
- edge_serial->rxState = EXPECT_DATA; // Expect data to start next buffer
- } else {
- // BufLen >= RxBytesRemaining
- rxLen = edge_serial->rxBytesRemaining;
- edge_serial->rxState = EXPECT_HDR1; // Start another header next time
- }
+ bufferLength -= rxLen;
+ edge_serial->rxBytesRemaining -= rxLen;
- bufferLength -= rxLen;
- edge_serial->rxBytesRemaining -= rxLen;
-
- /* spit this data back into the tty driver if this port is open */
- if (rxLen) {
- port = edge_serial->serial->port[edge_serial->rxPort];
- edge_port = usb_get_serial_port_data(port);
- if (edge_port->open) {
- tty = edge_port->port->tty;
- if (tty) {
- dbg("%s - Sending %d bytes to TTY for port %d", __func__, rxLen, edge_serial->rxPort);
- edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen);
- }
- edge_port->icount.rx += rxLen;
+ /* spit this data back into the tty driver if this
+ port is open */
+ if (rxLen) {
+ port = edge_serial->serial->port[
+ edge_serial->rxPort];
+ edge_port = usb_get_serial_port_data(port);
+ if (edge_port->open) {
+ tty = edge_port->port->port.tty;
+ if (tty) {
+ dbg("%s - Sending %d bytes to TTY for port %d",
+ __func__, rxLen, edge_serial->rxPort);
+ edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen);
}
- buffer += rxLen;
+ edge_port->icount.rx += rxLen;
}
+ buffer += rxLen;
+ }
+ break;
- break;
-
- case EXPECT_HDR3: // Expect 3rd byte of status header
- edge_serial->rxHeader3 = *buffer;
- ++buffer;
- --bufferLength;
-
- // We have all the header bytes, process the status now
- process_rcvd_status (edge_serial, edge_serial->rxStatusParam, edge_serial->rxHeader3);
- edge_serial->rxState = EXPECT_HDR1;
- break;
-
+ case EXPECT_HDR3: /* Expect 3rd byte of status header */
+ edge_serial->rxHeader3 = *buffer;
+ ++buffer;
+ --bufferLength;
+
+ /* We have all the header bytes, process the
+ status now */
+ process_rcvd_status(edge_serial,
+ edge_serial->rxStatusParam,
+ edge_serial->rxHeader3);
+ edge_serial->rxState = EXPECT_HDR1;
+ break;
}
}
}
/*****************************************************************************
* process_rcvd_status
- * this function handles the any status messages received on the bulk in pipe.
+ * this function handles the any status messages received on the
+ * bulk in pipe.
*****************************************************************************/
-static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3)
+static void process_rcvd_status(struct edgeport_serial *edge_serial,
+ __u8 byte2, __u8 byte3)
{
struct usb_serial_port *port;
struct edgeport_port *edge_port;
port = edge_serial->serial->port[edge_serial->rxPort];
edge_port = usb_get_serial_port_data(port);
if (edge_port == NULL) {
- dev_err(&edge_serial->serial->dev->dev, "%s - edge_port == NULL for port %d\n", __func__, edge_serial->rxPort);
+ dev_err(&edge_serial->serial->dev->dev,
+ "%s - edge_port == NULL for port %d\n",
+ __func__, edge_serial->rxPort);
return;
}
if (code == IOSP_EXT_STATUS) {
switch (byte2) {
- case IOSP_EXT_STATUS_CHASE_RSP:
- // we want to do EXT status regardless of port open/closed
- dbg("%s - Port %u EXT CHASE_RSP Data = %02x", __func__, edge_serial->rxPort, byte3 );
- // Currently, the only EXT_STATUS is Chase, so process here instead of one more call
- // to one more subroutine. If/when more EXT_STATUS, there'll be more work to do.
- // Also, we currently clear flag and close the port regardless of content of above's Byte3.
- // We could choose to do something else when Byte3 says Timeout on Chase from Edgeport,
- // like wait longer in block_until_chase_response, but for now we don't.
- edge_port->chaseResponsePending = false;
- wake_up (&edge_port->wait_chase);
- return;
+ case IOSP_EXT_STATUS_CHASE_RSP:
+ /* we want to do EXT status regardless of port
+ * open/closed */
+ dbg("%s - Port %u EXT CHASE_RSP Data = %02x",
+ __func__, edge_serial->rxPort, byte3);
+ /* Currently, the only EXT_STATUS is Chase, so process
+ * here instead of one more call to one more subroutine
+ * If/when more EXT_STATUS, there'll be more work to do
+ * Also, we currently clear flag and close the port
+ * regardless of content of above's Byte3.
+ * We could choose to do something else when Byte3 says
+ * Timeout on Chase from Edgeport, like wait longer in
+ * block_until_chase_response, but for now we don't.
+ */
+ edge_port->chaseResponsePending = false;
+ wake_up(&edge_port->wait_chase);
+ return;
- case IOSP_EXT_STATUS_RX_CHECK_RSP:
- dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __func__, edge_serial->rxPort, byte3 );
- //Port->RxCheckRsp = true;
- return;
+ case IOSP_EXT_STATUS_RX_CHECK_RSP:
+ dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __func__, edge_serial->rxPort, byte3);
+ /* Port->RxCheckRsp = true; */
+ return;
}
}
edge_port->txCredits = GET_TX_BUFFER_SIZE(byte3);
edge_port->maxTxCredits = edge_port->txCredits;
dbg("%s - Port %u Open Response Inital MSR = %02x TxBufferSize = %d", __func__, edge_serial->rxPort, byte2, edge_port->txCredits);
- handle_new_msr (edge_port, byte2);
+ handle_new_msr(edge_port, byte2);
- /* send the current line settings to the port so we are in sync with any further termios calls */
- if (edge_port->port->tty)
- change_port_settings (edge_port, edge_port->port->tty->termios);
+ /* send the current line settings to the port so we are
+ in sync with any further termios calls */
+ /* FIXME: locking on tty */
+ if (edge_port->port->port.tty)
+ change_port_settings(edge_port->port->port.tty,
+ edge_port, edge_port->port->port.tty->termios);
/* we have completed the open */
edge_port->openPending = false;
return;
}
- // If port is closed, silently discard all rcvd status. We can
- // have cases where buffered status is received AFTER the close
- // port command is sent to the Edgeport.
- if (!edge_port->open || edge_port->closePending) {
+ /* If port is closed, silently discard all rcvd status. We can
+ * have cases where buffered status is received AFTER the close
+ * port command is sent to the Edgeport.
+ */
+ if (!edge_port->open || edge_port->closePending)
return;
- }
switch (code) {
- // Not currently sent by Edgeport
- case IOSP_STATUS_LSR:
- dbg("%s - Port %u LSR Status = %02x", __func__, edge_serial->rxPort, byte2);
- handle_new_lsr(edge_port, false, byte2, 0);
- break;
+ /* Not currently sent by Edgeport */
+ case IOSP_STATUS_LSR:
+ dbg("%s - Port %u LSR Status = %02x",
+ __func__, edge_serial->rxPort, byte2);
+ handle_new_lsr(edge_port, false, byte2, 0);
+ break;
- case IOSP_STATUS_LSR_DATA:
- dbg("%s - Port %u LSR Status = %02x, Data = %02x", __func__, edge_serial->rxPort, byte2, byte3);
- // byte2 is LSR Register
- // byte3 is broken data byte
- handle_new_lsr(edge_port, true, byte2, byte3);
- break;
- //
- // case IOSP_EXT_4_STATUS:
- // dbg("%s - Port %u LSR Status = %02x Data = %02x", __func__, edge_serial->rxPort, byte2, byte3);
- // break;
- //
- case IOSP_STATUS_MSR:
- dbg("%s - Port %u MSR Status = %02x", __func__, edge_serial->rxPort, byte2);
-
- // Process this new modem status and generate appropriate
- // events, etc, based on the new status. This routine
- // also saves the MSR in Port->ShadowMsr.
- handle_new_msr(edge_port, byte2);
- break;
+ case IOSP_STATUS_LSR_DATA:
+ dbg("%s - Port %u LSR Status = %02x, Data = %02x",
+ __func__, edge_serial->rxPort, byte2, byte3);
+ /* byte2 is LSR Register */
+ /* byte3 is broken data byte */
+ handle_new_lsr(edge_port, true, byte2, byte3);
+ break;
+ /*
+ * case IOSP_EXT_4_STATUS:
+ * dbg("%s - Port %u LSR Status = %02x Data = %02x",
+ * __func__, edge_serial->rxPort, byte2, byte3);
+ * break;
+ */
+ case IOSP_STATUS_MSR:
+ dbg("%s - Port %u MSR Status = %02x",
+ __func__, edge_serial->rxPort, byte2);
+ /*
+ * Process this new modem status and generate appropriate
+ * events, etc, based on the new status. This routine
+ * also saves the MSR in Port->ShadowMsr.
+ */
+ handle_new_msr(edge_port, byte2);
+ break;
- default:
- dbg("%s - Unrecognized IOSP status code %u\n", __func__, code);
- break;
+ default:
+ dbg("%s - Unrecognized IOSP status code %u\n", __func__, code);
+ break;
}
-
return;
}
* edge_tty_recv
* this function passes data on to the tty flip buffer
*****************************************************************************/
-static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length)
+static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
+ unsigned char *data, int length)
{
int cnt;
if (cnt < length) {
dev_err(dev, "%s - dropping data, %d bytes lost\n",
__func__, length - cnt);
- if(cnt == 0)
+ if (cnt == 0)
break;
}
tty_insert_flip_string(tty, data, cnt);
dbg("%s %02x", __func__, newMsr);
- if (newMsr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) {
+ if (newMsr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR |
+ EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) {
icount = &edge_port->icount;
/* update input line counters */
- if (newMsr & EDGEPORT_MSR_DELTA_CTS) {
+ if (newMsr & EDGEPORT_MSR_DELTA_CTS)
icount->cts++;
- }
- if (newMsr & EDGEPORT_MSR_DELTA_DSR) {
+ if (newMsr & EDGEPORT_MSR_DELTA_DSR)
icount->dsr++;
- }
- if (newMsr & EDGEPORT_MSR_DELTA_CD) {
+ if (newMsr & EDGEPORT_MSR_DELTA_CD)
icount->dcd++;
- }
- if (newMsr & EDGEPORT_MSR_DELTA_RI) {
+ if (newMsr & EDGEPORT_MSR_DELTA_RI)
icount->rng++;
- }
wake_up_interruptible(&edge_port->delta_msr_wait);
}
* handle_new_lsr
* this function handles any change to the lsr register for a port.
*****************************************************************************/
-static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, __u8 lsr, __u8 data)
+static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData,
+ __u8 lsr, __u8 data)
{
- __u8 newLsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK));
- struct async_icount *icount;
+ __u8 newLsr = (__u8) (lsr & (__u8)
+ (LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK));
+ struct async_icount *icount;
dbg("%s - %02x", __func__, newLsr);
edge_port->shadowLSR = lsr;
if (newLsr & LSR_BREAK) {
- //
- // Parity and Framing errors only count if they
- // occur exclusive of a break being
- // received.
- //
+ /*
+ * Parity and Framing errors only count if they
+ * occur exclusive of a break being
+ * received.
+ */
newLsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK);
}
/* Place LSR data byte into Rx buffer */
- if (lsrData && edge_port->port->tty)
- edge_tty_recv(&edge_port->port->dev, edge_port->port->tty, &data, 1);
+ if (lsrData && edge_port->port->port.tty)
+ edge_tty_recv(&edge_port->port->dev,
+ edge_port->port->port.tty, &data, 1);
/* update input line counters */
icount = &edge_port->icount;
- if (newLsr & LSR_BREAK) {
+ if (newLsr & LSR_BREAK)
icount->brk++;
- }
- if (newLsr & LSR_OVER_ERR) {
+ if (newLsr & LSR_OVER_ERR)
icount->overrun++;
- }
- if (newLsr & LSR_PAR_ERR) {
+ if (newLsr & LSR_PAR_ERR)
icount->parity++;
- }
- if (newLsr & LSR_FRM_ERR) {
+ if (newLsr & LSR_FRM_ERR)
icount->frame++;
- }
return;
}
/****************************************************************************
* sram_write
- * writes a number of bytes to the Edgeport device's sram starting at the
+ * writes a number of bytes to the Edgeport device's sram starting at the
* given address.
* If successful returns the number of bytes written, otherwise it returns
* a negative error number of the problem.
****************************************************************************/
-static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data)
+static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+ __u16 length, const __u8 *data)
{
int result;
__u16 current_length;
dbg("%s - %x, %x, %d", __func__, extAddr, addr, length);
- transfer_buffer = kmalloc (64, GFP_KERNEL);
+ transfer_buffer = kmalloc(64, GFP_KERNEL);
if (!transfer_buffer) {
- dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, 64);
+ dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n",
+ __func__, 64);
return -ENOMEM;
}
/* need to split these writes up into 64 byte chunks */
result = 0;
while (length > 0) {
- if (length > 64) {
+ if (length > 64)
current_length = 64;
- } else {
+ else
current_length = length;
- }
-// dbg("%s - writing %x, %x, %d", __func__, extAddr, addr, current_length);
- memcpy (transfer_buffer, data, current_length);
- result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), USB_REQUEST_ION_WRITE_RAM,
- 0x40, addr, extAddr, transfer_buffer, current_length, 300);
+
+/* dbg("%s - writing %x, %x, %d", __func__,
+ extAddr, addr, current_length); */
+ memcpy(transfer_buffer, data, current_length);
+ result = usb_control_msg(serial->dev,
+ usb_sndctrlpipe(serial->dev, 0),
+ USB_REQUEST_ION_WRITE_RAM,
+ 0x40, addr, extAddr, transfer_buffer,
+ current_length, 300);
if (result < 0)
break;
length -= current_length;
addr += current_length;
data += current_length;
- }
+ }
- kfree (transfer_buffer);
+ kfree(transfer_buffer);
return result;
}
* If successful returns the number of bytes written, otherwise it returns
* a negative error number of the problem.
****************************************************************************/
-static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data)
+static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+ __u16 length, const __u8 *data)
{
int result;
__u16 current_length;
unsigned char *transfer_buffer;
-// dbg("%s - %x, %x, %d", __func__, extAddr, addr, length);
+/* dbg("%s - %x, %x, %d", __func__, extAddr, addr, length); */
- transfer_buffer = kmalloc (64, GFP_KERNEL);
+ transfer_buffer = kmalloc(64, GFP_KERNEL);
if (!transfer_buffer) {
- dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, 64);
+ dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n",
+ __func__, 64);
return -ENOMEM;
}
/* need to split these writes up into 64 byte chunks */
result = 0;
while (length > 0) {
- if (length > 64) {
+ if (length > 64)
current_length = 64;
- } else {
+ else
current_length = length;
- }
-// dbg("%s - writing %x, %x, %d", __func__, extAddr, addr, current_length);
- memcpy (transfer_buffer, data, current_length);
- result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), USB_REQUEST_ION_WRITE_ROM,
- 0x40, addr, extAddr, transfer_buffer, current_length, 300);
+/* dbg("%s - writing %x, %x, %d", __func__,
+ extAddr, addr, current_length); */
+ memcpy(transfer_buffer, data, current_length);
+ result = usb_control_msg(serial->dev,
+ usb_sndctrlpipe(serial->dev, 0),
+ USB_REQUEST_ION_WRITE_ROM, 0x40,
+ addr, extAddr,
+ transfer_buffer, current_length, 300);
if (result < 0)
break;
length -= current_length;
addr += current_length;
data += current_length;
- }
+ }
- kfree (transfer_buffer);
+ kfree(transfer_buffer);
return result;
}
* If successful returns the number of bytes read, otherwise it returns
* a negative error number of the problem.
****************************************************************************/
-static int rom_read (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data)
+static int rom_read(struct usb_serial *serial, __u16 extAddr,
+ __u16 addr, __u16 length, __u8 *data)
{
int result;
__u16 current_length;
dbg("%s - %x, %x, %d", __func__, extAddr, addr, length);
- transfer_buffer = kmalloc (64, GFP_KERNEL);
+ transfer_buffer = kmalloc(64, GFP_KERNEL);
if (!transfer_buffer) {
- dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, 64);
+ dev_err(&serial->dev->dev,
+ "%s - kmalloc(%d) failed.\n", __func__, 64);
return -ENOMEM;
}
/* need to split these reads up into 64 byte chunks */
result = 0;
while (length > 0) {
- if (length > 64) {
+ if (length > 64)
current_length = 64;
- } else {
+ else
current_length = length;
- }
-// dbg("%s - %x, %x, %d", __func__, extAddr, addr, current_length);
- result = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), USB_REQUEST_ION_READ_ROM,
- 0xC0, addr, extAddr, transfer_buffer, current_length, 300);
+/* dbg("%s - %x, %x, %d", __func__,
+ extAddr, addr, current_length); */
+ result = usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ USB_REQUEST_ION_READ_ROM,
+ 0xC0, addr, extAddr, transfer_buffer,
+ current_length, 300);
if (result < 0)
break;
- memcpy (data, transfer_buffer, current_length);
+ memcpy(data, transfer_buffer, current_length);
length -= current_length;
addr += current_length;
data += current_length;
- }
+ }
- kfree (transfer_buffer);
+ kfree(transfer_buffer);
return result;
}
* send_iosp_ext_cmd
* Is used to send a IOSP message to the Edgeport device
****************************************************************************/
-static int send_iosp_ext_cmd (struct edgeport_port *edge_port, __u8 command, __u8 param)
+static int send_iosp_ext_cmd(struct edgeport_port *edge_port,
+ __u8 command, __u8 param)
{
unsigned char *buffer;
unsigned char *currentCommand;
dbg("%s - %d, %d", __func__, command, param);
- buffer = kmalloc (10, GFP_ATOMIC);
+ buffer = kmalloc(10, GFP_ATOMIC);
if (!buffer) {
- dev_err(&edge_port->port->dev, "%s - kmalloc(%d) failed.\n", __func__, 10);
+ dev_err(&edge_port->port->dev,
+ "%s - kmalloc(%d) failed.\n", __func__, 10);
return -ENOMEM;
}
currentCommand = buffer;
- MAKE_CMD_EXT_CMD (¤tCommand, &length,
- edge_port->port->number - edge_port->port->serial->minor,
- command, param);
+ MAKE_CMD_EXT_CMD(¤tCommand, &length,
+ edge_port->port->number - edge_port->port->serial->minor,
+ command, param);
- status = write_cmd_usb (edge_port, buffer, length);
+ status = write_cmd_usb(edge_port, buffer, length);
if (status) {
/* something bad happened, let's free up the memory */
kfree(buffer);
* write_cmd_usb
* this function writes the given buffer out to the bulk write endpoint.
*****************************************************************************/
-static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer, int length)
+static int write_cmd_usb(struct edgeport_port *edge_port,
+ unsigned char *buffer, int length)
{
- struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
+ struct edgeport_serial *edge_serial =
+ usb_get_serial_data(edge_port->port->serial);
int status = 0;
struct urb *urb;
int timeout;
- usb_serial_debug_data(debug, &edge_port->port->dev, __func__, length, buffer);
+ usb_serial_debug_data(debug, &edge_port->port->dev,
+ __func__, length, buffer);
/* Allocate our next urb */
- urb = usb_alloc_urb (0, GFP_ATOMIC);
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb)
return -ENOMEM;
atomic_inc(&CmdUrbs);
- dbg("%s - ALLOCATE URB %p (outstanding %d)", __func__, urb, atomic_read(&CmdUrbs));
+ dbg("%s - ALLOCATE URB %p (outstanding %d)",
+ __func__, urb, atomic_read(&CmdUrbs));
- usb_fill_bulk_urb (urb, edge_serial->serial->dev,
- usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint),
- buffer, length, edge_bulk_out_cmd_callback, edge_port);
+ usb_fill_bulk_urb(urb, edge_serial->serial->dev,
+ usb_sndbulkpipe(edge_serial->serial->dev,
+ edge_serial->bulk_out_endpoint),
+ buffer, length, edge_bulk_out_cmd_callback, edge_port);
edge_port->commandPending = true;
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
/* something went wrong */
- dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write command) failed, status = %d\n", __func__, status);
+ dev_err(&edge_port->port->dev,
+ "%s - usb_submit_urb(write command) failed, status = %d\n",
+ __func__, status);
usb_kill_urb(urb);
usb_free_urb(urb);
atomic_dec(&CmdUrbs);
return status;
}
- // wait for command to finish
+ /* wait for command to finish */
timeout = COMMAND_TIMEOUT;
#if 0
- wait_event (&edge_port->wait_command, !edge_port->commandPending);
+ wait_event(&edge_port->wait_command, !edge_port->commandPending);
if (edge_port->commandPending) {
/* command timed out */
* this function sends the proper command to change the baud rate of the
* specified port.
*****************************************************************************/
-static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate)
+static int send_cmd_write_baud_rate(struct edgeport_port *edge_port,
+ int baudRate)
{
- struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
+ struct edgeport_serial *edge_serial =
+ usb_get_serial_data(edge_port->port->serial);
unsigned char *cmdBuffer;
unsigned char *currCmd;
int cmdLen = 0;
int divisor;
int status;
- unsigned char number = edge_port->port->number - edge_port->port->serial->minor;
+ unsigned char number =
+ edge_port->port->number - edge_port->port->serial->minor;
if (edge_serial->is_epic &&
!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate) {
return 0;
}
- dbg("%s - port = %d, baud = %d", __func__, edge_port->port->number, baudRate);
+ dbg("%s - port = %d, baud = %d", __func__,
+ edge_port->port->number, baudRate);
- status = calc_baud_rate_divisor (baudRate, &divisor);
+ status = calc_baud_rate_divisor(baudRate, &divisor);
if (status) {
- dev_err(&edge_port->port->dev, "%s - bad baud rate\n", __func__);
+ dev_err(&edge_port->port->dev, "%s - bad baud rate\n",
+ __func__);
return status;
}
- // Alloc memory for the string of commands.
- cmdBuffer = kmalloc (0x100, GFP_ATOMIC);
+ /* Alloc memory for the string of commands. */
+ cmdBuffer = kmalloc(0x100, GFP_ATOMIC);
if (!cmdBuffer) {
- dev_err(&edge_port->port->dev, "%s - kmalloc(%d) failed.\n", __func__, 0x100);
+ dev_err(&edge_port->port->dev,
+ "%s - kmalloc(%d) failed.\n", __func__, 0x100);
return -ENOMEM;
}
currCmd = cmdBuffer;
- // Enable access to divisor latch
- MAKE_CMD_WRITE_REG( &currCmd, &cmdLen, number, LCR, LCR_DL_ENABLE );
+ /* Enable access to divisor latch */
+ MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, LCR, LCR_DL_ENABLE);
- // Write the divisor itself
- MAKE_CMD_WRITE_REG( &currCmd, &cmdLen, number, DLL, LOW8 (divisor) );
- MAKE_CMD_WRITE_REG( &currCmd, &cmdLen, number, DLM, HIGH8(divisor) );
+ /* Write the divisor itself */
+ MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, DLL, LOW8(divisor));
+ MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, DLM, HIGH8(divisor));
- // Restore original value to disable access to divisor latch
- MAKE_CMD_WRITE_REG( &currCmd, &cmdLen, number, LCR, edge_port->shadowLCR);
+ /* Restore original value to disable access to divisor latch */
+ MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, LCR,
+ edge_port->shadowLCR);
- status = write_cmd_usb(edge_port, cmdBuffer, cmdLen );
+ status = write_cmd_usb(edge_port, cmdBuffer, cmdLen);
if (status) {
/* something bad happened, let's free up the memory */
- kfree (cmdBuffer);
+ kfree(cmdBuffer);
}
return status;
* this function calculates the proper baud rate divisor for the specified
* baud rate.
*****************************************************************************/
-static int calc_baud_rate_divisor (int baudrate, int *divisor)
+static int calc_baud_rate_divisor(int baudrate, int *divisor)
{
int i;
__u16 custom;
dbg("%s - %d", __func__, baudrate);
for (i = 0; i < ARRAY_SIZE(divisor_table); i++) {
- if ( divisor_table[i].BaudRate == baudrate ) {
+ if (divisor_table[i].BaudRate == baudrate) {
*divisor = divisor_table[i].Divisor;
return 0;
}
}
- // We have tried all of the standard baud rates
- // lets try to calculate the divisor for this baud rate
- // Make sure the baud rate is reasonable
+ /* We have tried all of the standard baud rates
+ * lets try to calculate the divisor for this baud rate
+ * Make sure the baud rate is reasonable */
if (baudrate > 50 && baudrate < 230400) {
- // get divisor
+ /* get divisor */
custom = (__u16)((230400L + baudrate/2) / baudrate);
*divisor = custom;
/*****************************************************************************
* send_cmd_write_uart_register
- * this function builds up a uart register message and sends to to the device.
+ * this function builds up a uart register message and sends to to the device.
*****************************************************************************/
-static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue)
+static int send_cmd_write_uart_register(struct edgeport_port *edge_port,
+ __u8 regNum, __u8 regValue)
{
- struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
+ struct edgeport_serial *edge_serial =
+ usb_get_serial_data(edge_port->port->serial);
unsigned char *cmdBuffer;
unsigned char *currCmd;
unsigned long cmdLen = 0;
int status;
- dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __func__, regValue);
+ dbg("%s - write to %s register 0x%02x",
+ (regNum == MCR) ? "MCR" : "LCR", __func__, regValue);
if (edge_serial->is_epic &&
!edge_serial->epic_descriptor.Supports.IOSPWriteMCR &&
if (edge_serial->is_epic &&
!edge_serial->epic_descriptor.Supports.IOSPWriteLCR &&
regNum == LCR) {
- dbg ("SendCmdWriteUartReg - Not writing to LCR Register");
+ dbg("SendCmdWriteUartReg - Not writing to LCR Register");
return 0;
}
- // Alloc memory for the string of commands.
- cmdBuffer = kmalloc (0x10, GFP_ATOMIC);
- if (cmdBuffer == NULL ) {
+ /* Alloc memory for the string of commands. */
+ cmdBuffer = kmalloc(0x10, GFP_ATOMIC);
+ if (cmdBuffer == NULL)
return -ENOMEM;
- }
currCmd = cmdBuffer;
- // Build a cmd in the buffer to write the given register
- MAKE_CMD_WRITE_REG (&currCmd, &cmdLen,
- edge_port->port->number - edge_port->port->serial->minor,
- regNum, regValue);
+ /* Build a cmd in the buffer to write the given register */
+ MAKE_CMD_WRITE_REG(&currCmd, &cmdLen,
+ edge_port->port->number - edge_port->port->serial->minor,
+ regNum, regValue);
status = write_cmd_usb(edge_port, cmdBuffer, cmdLen);
if (status) {
/* something bad happened, let's free up the memory */
- kfree (cmdBuffer);
+ kfree(cmdBuffer);
}
return status;
/*****************************************************************************
* change_port_settings
- * This routine is called to set the UART on the device to match the specified
- * new settings.
+ * This routine is called to set the UART on the device to match the
+ * specified new settings.
*****************************************************************************/
-#ifndef CMSPAR
-#define CMSPAR 0
-#endif
-static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios)
+
+static void change_port_settings(struct tty_struct *tty,
+ struct edgeport_port *edge_port, struct ktermios *old_termios)
{
- struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
- struct tty_struct *tty;
+ struct edgeport_serial *edge_serial =
+ usb_get_serial_data(edge_port->port->serial);
int baud;
unsigned cflag;
__u8 mask = 0xff;
return;
}
- tty = edge_port->port->tty;
- if ((!tty) ||
- (!tty->termios)) {
- dbg("%s - no tty structures", __func__);
- return;
- }
-
cflag = tty->termios->c_cflag;
switch (cflag & CSIZE) {
- case CS5: lData = LCR_BITS_5; mask = 0x1f; dbg("%s - data bits = 5", __func__); break;
- case CS6: lData = LCR_BITS_6; mask = 0x3f; dbg("%s - data bits = 6", __func__); break;
- case CS7: lData = LCR_BITS_7; mask = 0x7f; dbg("%s - data bits = 7", __func__); break;
- default:
- case CS8: lData = LCR_BITS_8; dbg("%s - data bits = 8", __func__); break;
+ case CS5:
+ lData = LCR_BITS_5; mask = 0x1f;
+ dbg("%s - data bits = 5", __func__);
+ break;
+ case CS6:
+ lData = LCR_BITS_6; mask = 0x3f;
+ dbg("%s - data bits = 6", __func__);
+ break;
+ case CS7:
+ lData = LCR_BITS_7; mask = 0x7f;
+ dbg("%s - data bits = 7", __func__);
+ break;
+ default:
+ case CS8:
+ lData = LCR_BITS_8;
+ dbg("%s - data bits = 8", __func__);
+ break;
}
lParity = LCR_PAR_NONE;
dbg("%s - RTS/CTS is disabled", __func__);
}
- /* if we are implementing XON/XOFF, set the start and stop character in the device */
+ /* if we are implementing XON/XOFF, set the start and stop character
+ in the device */
if (I_IXOFF(tty) || I_IXON(tty)) {
unsigned char stop_char = STOP_CHAR(tty);
unsigned char start_char = START_CHAR(tty);
if ((!edge_serial->is_epic) ||
((edge_serial->is_epic) &&
(edge_serial->epic_descriptor.Supports.IOSPSetXChar))) {
- send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XON_CHAR, start_char);
- send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char);
+ send_iosp_ext_cmd(edge_port,
+ IOSP_CMD_SET_XON_CHAR, start_char);
+ send_iosp_ext_cmd(edge_port,
+ IOSP_CMD_SET_XOFF_CHAR, stop_char);
}
/* if we are implementing INBOUND XON/XOFF */
if (I_IXOFF(tty)) {
rxFlow |= IOSP_RX_FLOW_XON_XOFF;
- dbg("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __func__, start_char, stop_char);
+ dbg("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x",
+ __func__, start_char, stop_char);
} else {
dbg("%s - INBOUND XON/XOFF is disabled", __func__);
}
/* if we are implementing OUTBOUND XON/XOFF */
if (I_IXON(tty)) {
txFlow |= IOSP_TX_FLOW_XON_XOFF;
- dbg("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __func__, start_char, stop_char);
+ dbg("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x",
+ __func__, start_char, stop_char);
} else {
dbg("%s - OUTBOUND XON/XOFF is disabled", __func__);
}
edge_port->validDataMask = mask;
/* Send the updated LCR value to the EdgePort */
- status = send_cmd_write_uart_register(edge_port, LCR, edge_port->shadowLCR);
- if (status != 0) {
+ status = send_cmd_write_uart_register(edge_port, LCR,
+ edge_port->shadowLCR);
+ if (status != 0)
return;
- }
/* set up the MCR register and send it to the EdgePort */
edge_port->shadowMCR = MCR_MASTER_IE;
- if (cflag & CBAUD) {
+ if (cflag & CBAUD)
edge_port->shadowMCR |= (MCR_DTR | MCR_RTS);
- }
- status = send_cmd_write_uart_register(edge_port, MCR, edge_port->shadowMCR);
- if (status != 0) {
+
+ status = send_cmd_write_uart_register(edge_port, MCR,
+ edge_port->shadowMCR);
+ if (status != 0)
return;
- }
/* Determine divisor based on baud rate */
baud = tty_get_baud_rate(tty);
}
dbg("%s - baud rate = %d", __func__, baud);
- status = send_cmd_write_baud_rate (edge_port, baud);
+ status = send_cmd_write_baud_rate(edge_port, baud);
if (status == -1) {
/* Speed change was not possible - put back the old speed */
baud = tty_termios_baud_rate(old_termios);
* ASCII range, but it's only for debugging...
* NOTE: expects the unicode in LE format
****************************************************************************/
-static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size)
+static void unicode_to_ascii(char *string, int buflen,
+ __le16 *unicode, int unicode_size)
{
int i;
/****************************************************************************
* get_manufacturing_desc
- * reads in the manufacturing descriptor and stores it into the serial
+ * reads in the manufacturing descriptor and stores it into the serial
* structure.
****************************************************************************/
-static void get_manufacturing_desc (struct edgeport_serial *edge_serial)
+static void get_manufacturing_desc(struct edgeport_serial *edge_serial)
{
int response;
dbg("getting manufacturer descriptor");
- response = rom_read (edge_serial->serial, (EDGE_MANUF_DESC_ADDR & 0xffff0000) >> 16,
- (__u16)(EDGE_MANUF_DESC_ADDR & 0x0000ffff), EDGE_MANUF_DESC_LEN,
- (__u8 *)(&edge_serial->manuf_descriptor));
+ response = rom_read(edge_serial->serial,
+ (EDGE_MANUF_DESC_ADDR & 0xffff0000) >> 16,
+ (__u16)(EDGE_MANUF_DESC_ADDR & 0x0000ffff),
+ EDGE_MANUF_DESC_LEN,
+ (__u8 *)(&edge_serial->manuf_descriptor));
- if (response < 1) {
- dev_err(&edge_serial->serial->dev->dev, "error in getting manufacturer descriptor\n");
- } else {
+ if (response < 1)
+ dev_err(&edge_serial->serial->dev->dev,
+ "error in getting manufacturer descriptor\n");
+ else {
char string[30];
dbg("**Manufacturer Descriptor");
- dbg(" RomSize: %dK", edge_serial->manuf_descriptor.RomSize);
- dbg(" RamSize: %dK", edge_serial->manuf_descriptor.RamSize);
- dbg(" CpuRev: %d", edge_serial->manuf_descriptor.CpuRev);
- dbg(" BoardRev: %d", edge_serial->manuf_descriptor.BoardRev);
- dbg(" NumPorts: %d", edge_serial->manuf_descriptor.NumPorts);
- dbg(" DescDate: %d/%d/%d", edge_serial->manuf_descriptor.DescDate[0], edge_serial->manuf_descriptor.DescDate[1], edge_serial->manuf_descriptor.DescDate[2]+1900);
+ dbg(" RomSize: %dK",
+ edge_serial->manuf_descriptor.RomSize);
+ dbg(" RamSize: %dK",
+ edge_serial->manuf_descriptor.RamSize);
+ dbg(" CpuRev: %d",
+ edge_serial->manuf_descriptor.CpuRev);
+ dbg(" BoardRev: %d",
+ edge_serial->manuf_descriptor.BoardRev);
+ dbg(" NumPorts: %d",
+ edge_serial->manuf_descriptor.NumPorts);
+ dbg(" DescDate: %d/%d/%d",
+ edge_serial->manuf_descriptor.DescDate[0],
+ edge_serial->manuf_descriptor.DescDate[1],
+ edge_serial->manuf_descriptor.DescDate[2]+1900);
unicode_to_ascii(string, sizeof(string),
- edge_serial->manuf_descriptor.SerialNumber,
- edge_serial->manuf_descriptor.SerNumLength/2);
+ edge_serial->manuf_descriptor.SerialNumber,
+ edge_serial->manuf_descriptor.SerNumLength/2);
dbg(" SerialNumber: %s", string);
unicode_to_ascii(string, sizeof(string),
- edge_serial->manuf_descriptor.AssemblyNumber,
- edge_serial->manuf_descriptor.AssemblyNumLength/2);
+ edge_serial->manuf_descriptor.AssemblyNumber,
+ edge_serial->manuf_descriptor.AssemblyNumLength/2);
dbg(" AssemblyNumber: %s", string);
unicode_to_ascii(string, sizeof(string),
edge_serial->manuf_descriptor.OemAssyNumber,
edge_serial->manuf_descriptor.OemAssyNumLength/2);
dbg(" OemAssyNumber: %s", string);
- dbg(" UartType: %d", edge_serial->manuf_descriptor.UartType);
- dbg(" IonPid: %d", edge_serial->manuf_descriptor.IonPid);
- dbg(" IonConfig: %d", edge_serial->manuf_descriptor.IonConfig);
+ dbg(" UartType: %d",
+ edge_serial->manuf_descriptor.UartType);
+ dbg(" IonPid: %d",
+ edge_serial->manuf_descriptor.IonPid);
+ dbg(" IonConfig: %d",
+ edge_serial->manuf_descriptor.IonConfig);
}
}
/****************************************************************************
* get_boot_desc
- * reads in the bootloader descriptor and stores it into the serial
+ * reads in the bootloader descriptor and stores it into the serial
* structure.
****************************************************************************/
-static void get_boot_desc (struct edgeport_serial *edge_serial)
+static void get_boot_desc(struct edgeport_serial *edge_serial)
{
int response;
dbg("getting boot descriptor");
- response = rom_read (edge_serial->serial, (EDGE_BOOT_DESC_ADDR & 0xffff0000) >> 16,
- (__u16)(EDGE_BOOT_DESC_ADDR & 0x0000ffff), EDGE_BOOT_DESC_LEN,
- (__u8 *)(&edge_serial->boot_descriptor));
+ response = rom_read(edge_serial->serial,
+ (EDGE_BOOT_DESC_ADDR & 0xffff0000) >> 16,
+ (__u16)(EDGE_BOOT_DESC_ADDR & 0x0000ffff),
+ EDGE_BOOT_DESC_LEN,
+ (__u8 *)(&edge_serial->boot_descriptor));
- if (response < 1) {
- dev_err(&edge_serial->serial->dev->dev, "error in getting boot descriptor\n");
- } else {
+ if (response < 1)
+ dev_err(&edge_serial->serial->dev->dev,
+ "error in getting boot descriptor\n");
+ else {
dbg("**Boot Descriptor:");
- dbg(" BootCodeLength: %d", le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength));
- dbg(" MajorVersion: %d", edge_serial->boot_descriptor.MajorVersion);
- dbg(" MinorVersion: %d", edge_serial->boot_descriptor.MinorVersion);
- dbg(" BuildNumber: %d", le16_to_cpu(edge_serial->boot_descriptor.BuildNumber));
- dbg(" Capabilities: 0x%x", le16_to_cpu(edge_serial->boot_descriptor.Capabilities));
- dbg(" UConfig0: %d", edge_serial->boot_descriptor.UConfig0);
- dbg(" UConfig1: %d", edge_serial->boot_descriptor.UConfig1);
+ dbg(" BootCodeLength: %d",
+ le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength));
+ dbg(" MajorVersion: %d",
+ edge_serial->boot_descriptor.MajorVersion);
+ dbg(" MinorVersion: %d",
+ edge_serial->boot_descriptor.MinorVersion);
+ dbg(" BuildNumber: %d",
+ le16_to_cpu(edge_serial->boot_descriptor.BuildNumber));
+ dbg(" Capabilities: 0x%x",
+ le16_to_cpu(edge_serial->boot_descriptor.Capabilities));
+ dbg(" UConfig0: %d",
+ edge_serial->boot_descriptor.UConfig0);
+ dbg(" UConfig1: %d",
+ edge_serial->boot_descriptor.UConfig1);
}
}
* load_application_firmware
* This is called to load the application firmware to the device
****************************************************************************/
-static void load_application_firmware (struct edgeport_serial *edge_serial)
+static void load_application_firmware(struct edgeport_serial *edge_serial)
{
const struct ihex_binrec *rec;
const struct firmware *fw;
/****************************************************************************
* edge_startup
****************************************************************************/
-static int edge_startup (struct usb_serial *serial)
+static int edge_startup(struct usb_serial *serial)
{
struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
sizeof(struct edge_compatibility_bits));
/* get the manufacturing descriptor for this device */
- get_manufacturing_desc (edge_serial);
+ get_manufacturing_desc(edge_serial);
/* get the boot descriptor */
- get_boot_desc (edge_serial);
+ get_boot_desc(edge_serial);
get_product_info(edge_serial);
}
/* If not an EPiC device */
if (!edge_serial->is_epic) {
/* now load the application firmware into this device */
- load_application_firmware (edge_serial);
+ load_application_firmware(edge_serial);
dbg("%s - time 2 %ld", __func__, jiffies);
/* Check current Edgeport EEPROM and update if necessary */
- update_edgeport_E2PROM (edge_serial);
+ update_edgeport_E2PROM(edge_serial);
dbg("%s - time 3 %ld", __func__, jiffies);
/* set the configuration to use #1 */
-// dbg("set_configuration 1");
-// usb_set_configuration (dev, 1);
+/* dbg("set_configuration 1"); */
+/* usb_set_configuration (dev, 1); */
}
dbg(" FirmwareMajorVersion %d.%d.%d",
edge_serial->product_info.FirmwareMajorVersion,
edge_serial->product_info.FirmwareMinorVersion,
le16_to_cpu(edge_serial->product_info.FirmwareBuildNumber));
- /* we set up the pointers to the endpoints in the edge_open function,
+ /* we set up the pointers to the endpoints in the edge_open function,
* as the structures aren't created yet. */
/* set up our port private structures */
for (i = 0; i < serial->num_ports; ++i) {
- edge_port = kmalloc (sizeof(struct edgeport_port), GFP_KERNEL);
+ edge_port = kmalloc(sizeof(struct edgeport_port), GFP_KERNEL);
if (edge_port == NULL) {
- dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
+ dev_err(&serial->dev->dev, "%s - Out of memory\n",
+ __func__);
for (j = 0; j < i; ++j) {
- kfree (usb_get_serial_port_data(serial->port[j]));
- usb_set_serial_port_data(serial->port[j], NULL);
+ kfree(usb_get_serial_port_data(serial->port[j]));
+ usb_set_serial_port_data(serial->port[j],
+ NULL);
}
usb_set_serial_data(serial, NULL);
kfree(edge_serial);
return -ENOMEM;
}
- memset (edge_port, 0, sizeof(struct edgeport_port));
+ memset(edge_port, 0, sizeof(struct edgeport_port));
spin_lock_init(&edge_port->ep_lock);
edge_port->port = serial->port[i];
usb_set_serial_port_data(serial->port[i], edge_port);
response = 0;
if (edge_serial->is_epic) {
- /* EPIC thing, set up our interrupt polling now and our read urb, so
- * that the device knows it really is connected. */
+ /* EPIC thing, set up our interrupt polling now and our read
+ * urb, so that the device knows it really is connected. */
interrupt_in_found = bulk_in_found = bulk_out_found = false;
- for (i = 0; i < serial->interface->altsetting[0].desc.bNumEndpoints; ++i) {
+ for (i = 0; i < serial->interface->altsetting[0]
+ .desc.bNumEndpoints; ++i) {
struct usb_endpoint_descriptor *endpoint;
int buffer_size;
- endpoint = &serial->interface->altsetting[0].endpoint[i].desc;
+ endpoint = &serial->interface->altsetting[0].
+ endpoint[i].desc;
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
if (!interrupt_in_found &&
(usb_endpoint_is_int_in(endpoint))) {
dbg("found interrupt in");
/* not set up yet, so do it now */
- edge_serial->interrupt_read_urb = usb_alloc_urb(0, GFP_KERNEL);
+ edge_serial->interrupt_read_urb =
+ usb_alloc_urb(0, GFP_KERNEL);
if (!edge_serial->interrupt_read_urb) {
err("out of memory");
return -ENOMEM;
}
- edge_serial->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ edge_serial->interrupt_in_buffer =
+ kmalloc(buffer_size, GFP_KERNEL);
if (!edge_serial->interrupt_in_buffer) {
err("out of memory");
usb_free_urb(edge_serial->interrupt_read_urb);
return -ENOMEM;
}
- edge_serial->interrupt_in_endpoint = endpoint->bEndpointAddress;
+ edge_serial->interrupt_in_endpoint =
+ endpoint->bEndpointAddress;
/* set up our interrupt urb */
- usb_fill_int_urb(edge_serial->interrupt_read_urb,
- dev,
- usb_rcvintpipe(dev, endpoint->bEndpointAddress),
- edge_serial->interrupt_in_buffer,
- buffer_size,
- edge_interrupt_callback,
- edge_serial,
- endpoint->bInterval);
+ usb_fill_int_urb(
+ edge_serial->interrupt_read_urb,
+ dev,
+ usb_rcvintpipe(dev,
+ endpoint->bEndpointAddress),
+ edge_serial->interrupt_in_buffer,
+ buffer_size,
+ edge_interrupt_callback,
+ edge_serial,
+ endpoint->bInterval);
interrupt_in_found = true;
}
if (!bulk_in_found &&
- (usb_endpoint_is_bulk_in(endpoint))) {
+ (usb_endpoint_is_bulk_in(endpoint))) {
/* we found a bulk in endpoint */
dbg("found bulk in");
/* not set up yet, so do it now */
- edge_serial->read_urb = usb_alloc_urb(0, GFP_KERNEL);
+ edge_serial->read_urb =
+ usb_alloc_urb(0, GFP_KERNEL);
if (!edge_serial->read_urb) {
err("out of memory");
return -ENOMEM;
}
- edge_serial->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ edge_serial->bulk_in_buffer =
+ kmalloc(buffer_size, GFP_KERNEL);
if (!edge_serial->bulk_in_buffer) {
- err ("out of memory");
+ err("out of memory");
usb_free_urb(edge_serial->read_urb);
return -ENOMEM;
}
- edge_serial->bulk_in_endpoint = endpoint->bEndpointAddress;
+ edge_serial->bulk_in_endpoint =
+ endpoint->bEndpointAddress;
/* set up our bulk in urb */
usb_fill_bulk_urb(edge_serial->read_urb, dev,
- usb_rcvbulkpipe(dev, endpoint->bEndpointAddress),
- edge_serial->bulk_in_buffer,
- le16_to_cpu(endpoint->wMaxPacketSize),
- edge_bulk_in_callback,
- edge_serial);
+ usb_rcvbulkpipe(dev,
+ endpoint->bEndpointAddress),
+ edge_serial->bulk_in_buffer,
+ le16_to_cpu(endpoint->wMaxPacketSize),
+ edge_bulk_in_callback,
+ edge_serial);
bulk_in_found = true;
}
(usb_endpoint_is_bulk_out(endpoint))) {
/* we found a bulk out endpoint */
dbg("found bulk out");
- edge_serial->bulk_out_endpoint = endpoint->bEndpointAddress;
+ edge_serial->bulk_out_endpoint =
+ endpoint->bEndpointAddress;
bulk_out_found = true;
}
}
if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) {
- err ("Error - the proper endpoints were not found!");
+ err("Error - the proper endpoints were not found!");
return -ENODEV;
}
/* start interrupt read for this edgeport this interrupt will
* continue as long as the edgeport is connected */
- response = usb_submit_urb(edge_serial->interrupt_read_urb, GFP_KERNEL);
+ response = usb_submit_urb(edge_serial->interrupt_read_urb,
+ GFP_KERNEL);
if (response)
- err("%s - Error %d submitting control urb", __func__, response);
+ err("%s - Error %d submitting control urb",
+ __func__, response);
}
return response;
}
* edge_shutdown
* This function is called whenever the device is removed from the usb bus.
****************************************************************************/
-static void edge_shutdown (struct usb_serial *serial)
+static void edge_shutdown(struct usb_serial *serial)
{
struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
int i;
dbg("%s", __func__);
/* stop reads and writes on all ports */
- for (i=0; i < serial->num_ports; ++i) {
- kfree (usb_get_serial_port_data(serial->port[i]));
+ for (i = 0; i < serial->num_ports; ++i) {
+ kfree(usb_get_serial_port_data(serial->port[i]));
usb_set_serial_port_data(serial->port[i], NULL);
}
/* free up our endpoint stuff */
if (retval)
goto failed_epic_device_register;
retval = usb_register(&io_driver);
- if (retval)
+ if (retval)
goto failed_usb_register;
atomic_set(&CmdUrbs, 0);
info(DRIVER_DESC " " DRIVER_VERSION);
****************************************************************************/
static void __exit edgeport_exit (void)
{
- usb_deregister (&io_driver);
- usb_serial_deregister (&edgeport_2port_device);
- usb_serial_deregister (&edgeport_4port_device);
- usb_serial_deregister (&edgeport_8port_device);
- usb_serial_deregister (&epic_device);
+ usb_deregister(&io_driver);
+ usb_serial_deregister(&edgeport_2port_device);
+ usb_serial_deregister(&edgeport_4port_device);
+ usb_serial_deregister(&edgeport_8port_device);
+ usb_serial_deregister(&epic_device);
}
module_init(edgeport_init);
module_exit(edgeport_exit);
/* Module information */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("edgeport/boot.fw");
MODULE_FIRMWARE("edgeport/boot2.fw");
* 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.
- *
+ *
*/
#ifndef IO_TABLES_H
{ USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) },
{ USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) },
{ USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) },
- { } /* Terminating entry */
+ { } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver io_driver = {
.name = "io_edgeport",
static void stop_read(struct edgeport_port *edge_port);
static int restart_read(struct edgeport_port *edge_port);
-static void edge_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios);
-static void edge_send(struct usb_serial_port *port);
+static void edge_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios);
+static void edge_send(struct tty_struct *tty);
/* sysfs attributes */
static int edge_create_sysfs_attrs(struct usb_serial_port *port);
int flush)
{
int baud_rate;
- struct tty_struct *tty = port->port->tty;
+ struct tty_struct *tty = port->port->port.tty;
wait_queue_t wait;
unsigned long flags;
/* Save the new modem status */
edge_port->shadow_msr = msr & 0xf0;
- tty = edge_port->port->tty;
+ tty = edge_port->port->port.tty;
/* handle CTS flow control */
if (tty && C_CRTSCTS(tty)) {
if (msr & EDGEPORT_MSR_CTS) {
new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK);
/* Place LSR data byte into Rx buffer */
- if (lsr_data && edge_port->port->tty)
- edge_tty_recv(&edge_port->port->dev, edge_port->port->tty,
- &data, 1);
+ if (lsr_data && edge_port->port->port.tty)
+ edge_tty_recv(&edge_port->port->dev, edge_port->port->port.tty, &data, 1);
/* update input line counters */
icount = &edge_port->icount;
++data;
}
- tty = edge_port->port->tty;
+ tty = edge_port->port->port.tty;
if (tty && urb->actual_length) {
usb_serial_debug_data(debug, &edge_port->port->dev,
__func__, urb->actual_length, data);
}
/* send any buffered data */
- edge_send(port);
+ edge_send(port->port.tty);
}
-static int edge_open(struct usb_serial_port *port, struct file *filp)
+static int edge_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
struct edgeport_serial *edge_serial;
if (edge_port == NULL)
return -ENODEV;
- port->tty->low_latency = low_latency;
+ if (tty)
+ tty->low_latency = low_latency;
port_number = port->number - port->serial->minor;
switch (port_number) {
}
/* set up the port settings */
- edge_set_termios(port, port->tty->termios);
+ if (tty)
+ edge_set_termios(tty, port, port->port.tty->termios);
/* open up the port */
return status;
}
-static void edge_close(struct usb_serial_port *port, struct file *filp)
+static void edge_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
dbg("%s - exited", __func__);
}
-static int edge_write(struct usb_serial_port *port, const unsigned char *data,
- int count)
+static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *data, int count)
{
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
unsigned long flags;
count = edge_buf_put(edge_port->ep_out_buf, data, count);
spin_unlock_irqrestore(&edge_port->ep_lock, flags);
- edge_send(port);
+ edge_send(tty);
return count;
}
-static void edge_send(struct usb_serial_port *port)
+static void edge_send(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
int count, result;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
- struct tty_struct *tty = port->tty;
unsigned long flags;
tty_wakeup(tty);
}
-static int edge_write_room(struct usb_serial_port *port)
+static int edge_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
int room = 0;
unsigned long flags;
return room;
}
-static int edge_chars_in_buffer(struct usb_serial_port *port)
+static int edge_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
int chars = 0;
unsigned long flags;
return chars;
}
-static void edge_throttle(struct usb_serial_port *port)
+static void edge_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
- struct tty_struct *tty = port->tty;
int status;
dbg("%s - port %d", __func__, port->number);
/* if we are implementing XON/XOFF, send the stop character */
if (I_IXOFF(tty)) {
unsigned char stop_char = STOP_CHAR(tty);
- status = edge_write(port, &stop_char, 1);
- if (status <= 0)
- dev_err(&port->dev,
- "%s - failed to write stop character, %d\n",
- __func__, status);
+ status = edge_write(tty, port, &stop_char, 1);
+ if (status <= 0) {
+ dev_err(&port->dev, "%s - failed to write stop character, %d\n", __func__, status);
+ }
}
/* if we are implementing RTS/CTS, stop reads */
}
-static void edge_unthrottle(struct usb_serial_port *port)
+static void edge_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
- struct tty_struct *tty = port->tty;
int status;
dbg("%s - port %d", __func__, port->number);
/* if we are implementing XON/XOFF, send the start character */
if (I_IXOFF(tty)) {
unsigned char start_char = START_CHAR(tty);
- status = edge_write(port, &start_char, 1);
- if (status <= 0)
- dev_err(&port->dev,
- "%s - failed to write start character, %d\n",
- __func__, status);
+ status = edge_write(tty, port, &start_char, 1);
+ if (status <= 0) {
+ dev_err(&port->dev, "%s - failed to write start character, %d\n", __func__, status);
+ }
}
/* if we are implementing RTS/CTS, restart reads */
/* are the Edgeport will assert the RTS line */
return status;
}
-static void change_port_settings(struct edgeport_port *edge_port,
- struct ktermios *old_termios)
+static void change_port_settings(struct tty_struct *tty,
+ struct edgeport_port *edge_port, struct ktermios *old_termios)
{
struct ump_uart_config *config;
- struct tty_struct *tty;
int baud;
unsigned cflag;
int status;
dbg("%s - port %d", __func__, edge_port->port->number);
- tty = edge_port->port->tty;
-
- config = kmalloc(sizeof(*config), GFP_KERNEL);
+ config = kmalloc (sizeof (*config), GFP_KERNEL);
if (!config) {
*tty->termios = *old_termios;
dev_err(&edge_port->port->dev, "%s - out of memory\n",
return;
}
-static void edge_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void edge_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
- struct tty_struct *tty = port->tty;
+ unsigned int cflag;
+
+ cflag = tty->termios->c_cflag;
dbg("%s - clfag %08x iflag %08x", __func__,
tty->termios->c_cflag, tty->termios->c_iflag);
if (edge_port == NULL)
return;
/* change the port settings to the new ones specified */
- change_port_settings(edge_port, old_termios);
+ change_port_settings(tty, edge_port, old_termios);
+ return;
}
-static int edge_tiocmset(struct usb_serial_port *port, struct file *file,
+static int edge_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
unsigned int mcr;
unsigned long flags;
return 0;
}
-static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
+static int edge_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
unsigned int result = 0;
unsigned int msr;
return 0;
}
-static int edge_ioctl(struct usb_serial_port *port, struct file *file,
+static int edge_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
struct async_icount cnow;
struct async_icount cprev;
return -ENOIOCTLCMD;
}
-static void edge_break(struct usb_serial_port *port, int on)
+static void edge_break(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
int status;
int bv = 0; /* Off */
- dbg("%s - state = %d", __func__, on);
+ dbg("%s - state = %d", __func__, break_state);
/* chase the port close */
chase_port(edge_port, 0, 0);
- if (on == -1)
+ if (break_state == -1)
bv = 1; /* On */
status = ti_do_config(edge_port, UMPC_SET_CLR_BREAK, bv);
if (status)
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "ipaq.h"
static int initial_wait;
/* Function prototypes for an ipaq */
-static int ipaq_open (struct usb_serial_port *port, struct file *filp);
-static void ipaq_close (struct usb_serial_port *port, struct file *filp);
-static int ipaq_startup (struct usb_serial *serial);
-static void ipaq_shutdown (struct usb_serial *serial);
-static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf,
- int count);
-static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *buf,
- int count);
+static int ipaq_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void ipaq_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static int ipaq_startup(struct usb_serial *serial);
+static void ipaq_shutdown(struct usb_serial *serial);
+static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+static int ipaq_write_bulk(struct usb_serial_port *port,
+ const unsigned char *buf, int count);
static void ipaq_write_gather(struct usb_serial_port *port);
-static void ipaq_read_bulk_callback (struct urb *urb);
+static void ipaq_read_bulk_callback(struct urb *urb);
static void ipaq_write_bulk_callback(struct urb *urb);
-static int ipaq_write_room(struct usb_serial_port *port);
-static int ipaq_chars_in_buffer(struct usb_serial_port *port);
+static int ipaq_write_room(struct tty_struct *tty);
+static int ipaq_chars_in_buffer(struct tty_struct *tty);
static void ipaq_destroy_lists(struct usb_serial_port *port);
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, ipaq_id_table);
+MODULE_DEVICE_TABLE(usb, ipaq_id_table);
static struct usb_driver ipaq_driver = {
.name = "ipaq",
static int bytes_in;
static int bytes_out;
-static int ipaq_open(struct usb_serial_port *port, struct file *filp)
+static int ipaq_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
struct ipaq_private *priv;
for (i = 0; i < URBDATA_QUEUE_MAX / PACKET_SIZE; i++) {
pkt = kmalloc(sizeof(struct ipaq_packet), GFP_KERNEL);
- if (pkt == NULL) {
+ if (pkt == NULL)
goto enomem;
- }
+
pkt->data = kmalloc(PACKET_SIZE, GFP_KERNEL);
if (pkt->data == NULL) {
kfree(pkt);
* discipline instead of queueing.
*/
- port->tty->low_latency = 1;
- port->tty->raw = 1;
- port->tty->real_raw = 1;
-
+ if (tty) {
+ tty->low_latency = 1;
+ /* FIXME: These two are bogus */
+ tty->raw = 1;
+ tty->real_raw = 1;
+ }
/*
* Lose the small buffers usbserial provides. Make larger ones.
*/
port->read_urb->transfer_buffer = port->bulk_in_buffer;
port->write_urb->transfer_buffer = port->bulk_out_buffer;
port->read_urb->transfer_buffer_length = URBDATA_SIZE;
- port->bulk_out_size = port->write_urb->transfer_buffer_length = URBDATA_SIZE;
-
+ port->bulk_out_size = port->write_urb->transfer_buffer_length
+ = URBDATA_SIZE;
+
msleep(1000*initial_wait);
/*
/* Start reading from the device */
usb_fill_bulk_urb(port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
- ipaq_read_bulk_callback, port);
+ usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ ipaq_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result) {
- err("%s - failed submitting read urb, error %d", __func__, result);
+ err("%s - failed submitting read urb, error %d",
+ __func__, result);
goto error;
}
}
-static void ipaq_close(struct usb_serial_port *port, struct file *filp)
+static void ipaq_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct ipaq_private *priv = usb_get_serial_port_data(port);
dbg("%s - port %d", __func__, port->number);
-
+
/*
* shut down bulk read and write
*/
kfree(priv);
usb_set_serial_port_data(port, NULL);
- /* Uncomment the following line if you want to see some statistics in your syslog */
+ /* Uncomment the following line if you want to see some statistics
+ * in your syslog */
/* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
}
return;
}
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
}
/* Continue trying to always read */
- usb_fill_bulk_urb(port->read_urb, port->serial->dev,
- usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
- ipaq_read_bulk_callback, port);
+ usb_fill_bulk_urb(port->read_urb, port->serial->dev,
+ usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ ipaq_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d", __func__, result);
+ err("%s - failed resubmitting read urb, error %d",
+ __func__, result);
return;
}
-static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf,
- int count)
+static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
const unsigned char *current_position = buf;
int bytes_sent = 0;
while (count > 0) {
transfer_size = min(count, PACKET_SIZE);
- if (ipaq_write_bulk(port, current_position, transfer_size)) {
+ if (ipaq_write_bulk(port, current_position, transfer_size))
break;
- }
current_position += transfer_size;
bytes_sent += transfer_size;
count -= transfer_size;
}
return bytes_sent;
-}
+}
-static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *buf,
- int count)
+static int ipaq_write_bulk(struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
struct ipaq_private *priv = usb_get_serial_port_data(port);
struct ipaq_packet *pkt = NULL;
ipaq_write_gather(port);
spin_unlock_irqrestore(&write_list_lock, flags);
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
- if (result) {
- err("%s - failed submitting write urb, error %d", __func__, result);
- }
+ if (result)
+ err("%s - failed submitting write urb, error %d",
+ __func__, result);
} else {
spin_unlock_irqrestore(&write_list_lock, flags);
}
list_move(&pkt->list, &priv->freelist);
priv->free_len += PACKET_SIZE;
}
- if (room == 0) {
+ if (room == 0)
break;
- }
}
count = URBDATA_SIZE - room;
- usb_fill_bulk_urb(port->write_urb, serial->dev,
- usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
- port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback,
- port);
+ usb_fill_bulk_urb(port->write_urb, serial->dev,
+ usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
+ port->write_urb->transfer_buffer, count,
+ ipaq_write_bulk_callback, port);
return;
}
ipaq_write_gather(port);
spin_unlock_irqrestore(&write_list_lock, flags);
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
- if (result) {
- err("%s - failed submitting write urb, error %d", __func__, result);
- }
+ if (result)
+ err("%s - failed submitting write urb, error %d",
+ __func__, result);
} else {
priv->active = 0;
spin_unlock_irqrestore(&write_list_lock, flags);
usb_serial_port_softint(port);
}
-static int ipaq_write_room(struct usb_serial_port *port)
+static int ipaq_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ipaq_private *priv = usb_get_serial_port_data(port);
dbg("%s - freelen %d", __func__, priv->free_len);
return priv->free_len;
}
-static int ipaq_chars_in_buffer(struct usb_serial_port *port)
+static int ipaq_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ipaq_private *priv = usb_get_serial_port_data(port);
dbg("%s - queuelen %d", __func__, priv->queue_len);
serial->dev->actconfig->desc.bConfigurationValue);
return -ENODEV;
}
- return usb_reset_configuration (serial->dev);
+ return usb_reset_configuration(serial->dev);
}
static void ipaq_shutdown(struct usb_serial *serial)
int retval;
spin_lock_init(&write_list_lock);
retval = usb_serial_register(&ipaq_device);
- if (retval)
+ if (retval)
goto failed_usb_serial_register;
info(DRIVER_DESC " " DRIVER_VERSION);
if (vendor) {
retval = usb_register(&ipaq_driver);
if (retval)
goto failed_usb_register;
-
+
return 0;
failed_usb_register:
usb_serial_deregister(&ipaq_device);
module_init(ipaq_init);
module_exit(ipaq_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(product, "User specified USB idProduct");
module_param(connect_retries, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(connect_retries, "Maximum number of connect retries (one second each)");
+MODULE_PARM_DESC(connect_retries,
+ "Maximum number of connect retries (one second each)");
module_param(initial_wait, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(initial_wait, "Time to wait before attempting a connection (in seconds)");
+MODULE_PARM_DESC(initial_wait,
+ "Time to wait before attempting a connection (in seconds)");
* (at your option) any later version.
*
* All information about the device was acquired using SnoopyPro
- * on MSFT's O/S, and examing the MSFT drivers' debug output
+ * on MSFT's O/S, and examing the MSFT drivers' debug output
* (insanely left _on_ in the enduser version)
*
* It was written out of frustration with the IPWireless USB modem
* supplied by Axity3G/Sentech South Africa not supporting
* Linux whatsoever.
*
- * Nobody provided any proprietary information that was not already
+ * Nobody provided any proprietary information that was not already
* available for this device.
- *
- * The modem adheres to the "3GPP TS 27.007 AT command set for 3G
- * User Equipment (UE)" standard, available from
+ *
+ * The modem adheres to the "3GPP TS 27.007 AT command set for 3G
+ * User Equipment (UE)" standard, available from
* http://www.3gpp.org/ftp/Specs/html-info/27007.htm
*
* The code was only tested the IPWireless handheld modem distributed
* in South Africa by Sentech.
- *
+ *
* It may work for Woosh Inc in .nz too, as it appears they use the
* same kit.
*
- * There is still some work to be done in terms of handling
+ * There is still some work to be done in terms of handling
* DCD, DTR, RTS, CTS which are currently faked.
* It's good enough for PPP at this point. It's based off all kinds of
* code found in usb/serial and usb/class
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
/*
* Version Information
/* Message sizes */
#define EVENT_BUFFER_SIZE 0xFF
-#define CHAR2INT16(c1,c0) (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff))
+#define CHAR2INT16(c1, c0) (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff))
#define NUM_BULK_URBS 24
#define NUM_CONTROL_URBS 16
/* data bits */
#define ipw_dtb_7 0x700
-#define ipw_dtb_8 0x810 // ok so the define is misleading, I know, but forces 8,n,1
- // I mean, is there a point to any other setting these days? :)
+#define ipw_dtb_8 0x810 /* ok so the define is misleading, I know, but forces 8,n,1 */
+ /* I mean, is there a point to any other setting these days? :) */
/* usb control request types : */
-#define IPW_SIO_RXCTL 0x00 // control bulk rx channel transmissions, value=1/0 (on/off)
-#define IPW_SIO_SET_BAUD 0x01 // set baud, value=requested ipw_sio_bxxxx
-#define IPW_SIO_SET_LINE 0x03 // set databits, parity. value=ipw_dtb_x
-#define IPW_SIO_SET_PIN 0x03 // set/clear dtr/rts value=ipw_pin_xxx
-#define IPW_SIO_POLL 0x08 // get serial port status byte, call with value=0
-#define IPW_SIO_INIT 0x11 // initializes ? value=0 (appears as first thing todo on open)
-#define IPW_SIO_PURGE 0x12 // purge all transmissions?, call with value=numchar_to_purge
-#define IPW_SIO_HANDFLOW 0x13 // set xon/xoff limits value=0, and a buffer of 0x10 bytes
-#define IPW_SIO_SETCHARS 0x13 // set the flowcontrol special chars, value=0, buf=6 bytes,
- // last 2 bytes contain flowcontrol chars e.g. 00 00 00 00 11 13
+#define IPW_SIO_RXCTL 0x00 /* control bulk rx channel transmissions, value=1/0 (on/off) */
+#define IPW_SIO_SET_BAUD 0x01 /* set baud, value=requested ipw_sio_bxxxx */
+#define IPW_SIO_SET_LINE 0x03 /* set databits, parity. value=ipw_dtb_x */
+#define IPW_SIO_SET_PIN 0x03 /* set/clear dtr/rts value=ipw_pin_xxx */
+#define IPW_SIO_POLL 0x08 /* get serial port status byte, call with value=0 */
+#define IPW_SIO_INIT 0x11 /* initializes ? value=0 (appears as first thing todo on open) */
+#define IPW_SIO_PURGE 0x12 /* purge all transmissions?, call with value=numchar_to_purge */
+#define IPW_SIO_HANDFLOW 0x13 /* set xon/xoff limits value=0, and a buffer of 0x10 bytes */
+#define IPW_SIO_SETCHARS 0x13 /* set the flowcontrol special chars, value=0, buf=6 bytes, */
+ /* last 2 bytes contain flowcontrol chars e.g. 00 00 00 00 11 13 */
/* values used for request IPW_SIO_SET_PIN */
#define IPW_PIN_SETDTR 0x101
#define IPW_PIN_SETRTS 0x202
#define IPW_PIN_CLRDTR 0x100
-#define IPW_PIN_CLRRTS 0x200 // unconfirmed
+#define IPW_PIN_CLRRTS 0x200 /* unconfirmed */
/* values used for request IPW_SIO_RXCTL */
#define IPW_RXBULK_ON 1
#define IPW_RXBULK_OFF 0
/* various 16 byte hardcoded transferbuffers used by flow control */
-#define IPW_BYTES_FLOWINIT { 0x01, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+#define IPW_BYTES_FLOWINIT { 0x01, 0, 0, 0, 0x40, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0 }
/* Interpretation of modem status lines */
/* These need sorting out by individually connecting pins and checking
#define IPW_CTS ((1<<5) | (1<<4))
#define IPW_WANTS_TO_SEND 0x30
-//#define IPW_DTR /* Data Terminal Ready */
-//#define IPW_CTS /* Clear To Send */
-//#define IPW_CD /* Carrier Detect */
-//#define IPW_DSR /* Data Set Ready */
-//#define IPW_RxD /* Receive pin */
-
-//#define IPW_LE
-//#define IPW_RTS
-//#define IPW_ST
-//#define IPW_SR
-//#define IPW_RI /* Ring Indicator */
static struct usb_device_id usb_ipw_ids[] = {
{ USB_DEVICE(IPW_VID, IPW_PID) },
return;
}
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
}
/* Continue trying to always read */
- usb_fill_bulk_urb (port->read_urb, port->serial->dev,
- usb_rcvbulkpipe(port->serial->dev,
+ usb_fill_bulk_urb(port->read_urb, port->serial->dev,
+ usb_rcvbulkpipe(port->serial->dev,
port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer,
- port->read_urb->transfer_buffer_length,
- ipw_read_bulk_callback, port);
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ ipw_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
return;
}
-static int ipw_open(struct usb_serial_port *port, struct file *filp)
+static int ipw_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_device *dev = port->serial->dev;
u8 buf_flow_static[16] = IPW_BYTES_FLOWINIT;
if (!buf_flow_init)
return -ENOMEM;
- if (port->tty)
- port->tty->low_latency = 1;
-
- /* --1: Tell the modem to initialize (we think) From sniffs this is always the
- * first thing that gets sent to the modem during opening of the device */
- dbg("%s: Sending SIO_INIT (we guess)",__func__);
- result = usb_control_msg(dev, usb_sndctrlpipe(dev,0),
- IPW_SIO_INIT,
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- 0,
- 0, /* index */
- NULL,
- 0,
- 100000);
+ if (tty)
+ tty->low_latency = 1;
+
+ /* --1: Tell the modem to initialize (we think) From sniffs this is
+ * always the first thing that gets sent to the modem during
+ * opening of the device */
+ dbg("%s: Sending SIO_INIT (we guess)", __func__);
+ result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ IPW_SIO_INIT,
+ USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ 0,
+ 0, /* index */
+ NULL,
+ 0,
+ 100000);
if (result < 0)
- dev_err(&port->dev, "Init of modem failed (error = %d)\n", result);
+ dev_err(&port->dev,
+ "Init of modem failed (error = %d)\n", result);
/* reset the bulk pipes */
- usb_clear_halt(dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress));
- usb_clear_halt(dev, usb_sndbulkpipe(dev, port->bulk_out_endpointAddress));
+ usb_clear_halt(dev,
+ usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress));
+ usb_clear_halt(dev,
+ usb_sndbulkpipe(dev, port->bulk_out_endpointAddress));
- /*--2: Start reading from the device */
- dbg("%s: setting up bulk read callback",__func__);
+ /*--2: Start reading from the device */
+ dbg("%s: setting up bulk read callback", __func__);
usb_fill_bulk_urb(port->read_urb, dev,
usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
port->bulk_in_buffer,
ipw_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result < 0)
- dbg("%s - usb_submit_urb(read bulk) failed with status %d", __func__, result);
+ dbg("%s - usb_submit_urb(read bulk) failed with status %d",
+ __func__, result);
/*--3: Tell the modem to open the floodgates on the rx bulk channel */
- dbg("%s:asking modem for RxRead (RXBULK_ON)",__func__);
+ dbg("%s:asking modem for RxRead (RXBULK_ON)", __func__);
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- IPW_SIO_RXCTL,
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- IPW_RXBULK_ON,
- 0, /* index */
- NULL,
- 0,
- 100000);
- if (result < 0)
- dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)\n", result);
+ IPW_SIO_RXCTL,
+ USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ IPW_RXBULK_ON,
+ 0, /* index */
+ NULL,
+ 0,
+ 100000);
+ if (result < 0)
+ dev_err(&port->dev,
+ "Enabling bulk RxRead failed (error = %d)\n", result);
/*--4: setup the initial flowcontrol */
- dbg("%s:setting init flowcontrol (%s)",__func__,buf_flow_init);
+ dbg("%s:setting init flowcontrol (%s)", __func__, buf_flow_init);
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- IPW_SIO_HANDFLOW,
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- 0,
- 0,
- buf_flow_init,
- 0x10,
- 200000);
+ IPW_SIO_HANDFLOW,
+ USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ 0,
+ 0,
+ buf_flow_init,
+ 0x10,
+ 200000);
if (result < 0)
- dev_err(&port->dev, "initial flowcontrol failed (error = %d)\n", result);
+ dev_err(&port->dev,
+ "initial flowcontrol failed (error = %d)\n", result);
/*--5: raise the dtr */
- dbg("%s:raising dtr",__func__);
+ dbg("%s:raising dtr", __func__);
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- IPW_SIO_SET_PIN,
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- IPW_PIN_SETDTR,
- 0,
- NULL,
- 0,
- 200000);
+ IPW_SIO_SET_PIN,
+ USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ IPW_PIN_SETDTR,
+ 0,
+ NULL,
+ 0,
+ 200000);
if (result < 0)
- dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
+ dev_err(&port->dev,
+ "setting dtr failed (error = %d)\n", result);
/*--6: raise the rts */
- dbg("%s:raising rts",__func__);
+ dbg("%s:raising rts", __func__);
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- IPW_SIO_SET_PIN,
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- IPW_PIN_SETRTS,
- 0,
- NULL,
- 0,
- 200000);
+ IPW_SIO_SET_PIN,
+ USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ IPW_PIN_SETRTS,
+ 0,
+ NULL,
+ 0,
+ 200000);
if (result < 0)
- dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
-
+ dev_err(&port->dev,
+ "setting dtr failed (error = %d)\n", result);
+
kfree(buf_flow_init);
return 0;
}
-static void ipw_close(struct usb_serial_port *port, struct file * filp)
+static void ipw_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_device *dev = port->serial->dev;
int result;
}
/*--1: drop the dtr */
- dbg("%s:dropping dtr",__func__);
+ dbg("%s:dropping dtr", __func__);
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- IPW_SIO_SET_PIN,
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- IPW_PIN_CLRDTR,
- 0,
- NULL,
- 0,
- 200000);
+ IPW_SIO_SET_PIN,
+ USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ IPW_PIN_CLRDTR,
+ 0,
+ NULL,
+ 0,
+ 200000);
if (result < 0)
- dev_err(&port->dev, "dropping dtr failed (error = %d)\n", result);
+ dev_err(&port->dev, "dropping dtr failed (error = %d)\n",
+ result);
/*--2: drop the rts */
- dbg("%s:dropping rts",__func__);
+ dbg("%s:dropping rts", __func__);
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- IPW_SIO_SET_PIN, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- IPW_PIN_CLRRTS,
- 0,
- NULL,
- 0,
- 200000);
+ IPW_SIO_SET_PIN, USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE | USB_DIR_OUT,
+ IPW_PIN_CLRRTS,
+ 0,
+ NULL,
+ 0,
+ 200000);
if (result < 0)
- dev_err(&port->dev, "dropping rts failed (error = %d)\n", result);
+ dev_err(&port->dev,
+ "dropping rts failed (error = %d)\n", result);
/*--3: purge */
- dbg("%s:sending purge",__func__);
+ dbg("%s:sending purge", __func__);
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- IPW_SIO_PURGE, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- 0x03,
- 0,
- NULL,
- 0,
- 200000);
+ IPW_SIO_PURGE, USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE | USB_DIR_OUT,
+ 0x03,
+ 0,
+ NULL,
+ 0,
+ 200000);
if (result < 0)
dev_err(&port->dev, "purge failed (error = %d)\n", result);
- /* send RXBULK_off (tell modem to stop transmitting bulk data on rx chan) */
+ /* send RXBULK_off (tell modem to stop transmitting bulk data on
+ rx chan) */
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- IPW_SIO_RXCTL,
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- IPW_RXBULK_OFF,
- 0, /* index */
- NULL,
- 0,
- 100000);
+ IPW_SIO_RXCTL,
+ USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ IPW_RXBULK_OFF,
+ 0, /* index */
+ NULL,
+ 0,
+ 100000);
if (result < 0)
- dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)\n", result);
+ dev_err(&port->dev,
+ "Disabling bulk RxRead failed (error = %d)\n", result);
/* shutdown any in-flight urbs that we know about */
usb_kill_urb(port->read_urb);
usb_serial_port_softint(port);
}
-static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+static int ipw_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
struct usb_device *dev = port->serial->dev;
int ret;
dbg("%s: TOP: count=%d, in_interrupt=%ld", __func__,
- count, in_interrupt() );
+ count, in_interrupt());
if (count == 0) {
dbg("%s - write request of 0 bytes", __func__);
ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (ret != 0) {
port->write_urb_busy = 0;
- dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __func__, ret);
+ dbg("%s - usb_submit_urb(write bulk) failed with error = %d",
+ __func__, ret);
return ret;
}
dbg("%s returning %d", __func__, count);
return count;
-}
+}
static int ipw_probe(struct usb_serial_port *port)
{
module_exit(usb_ipw_exit);
/* Module information */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
/* if overridden by the user, then use the specified number of XBOFs */
static int xbof = -1;
-static int ir_startup(struct usb_serial *serial);
-static int ir_open(struct usb_serial_port *port, struct file *filep);
-static void ir_close(struct usb_serial_port *port, struct file *filep);
-static int ir_write(struct usb_serial_port *port,
- const unsigned char *buf, int count);
-static void ir_write_bulk_callback(struct urb *urb);
-static void ir_read_bulk_callback(struct urb *urb);
-static void ir_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios);
+static int ir_startup (struct usb_serial *serial);
+static int ir_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filep);
+static void ir_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filep);
+static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+static void ir_write_bulk_callback (struct urb *urb);
+static void ir_read_bulk_callback (struct urb *urb);
+static void ir_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios);
/* Not that this lot means you can only have one per system */
static u8 ir_baud;
return 0;
}
-static int ir_open(struct usb_serial_port *port, struct file *filp)
+static int ir_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
char *buffer;
int result = 0;
return result;
}
-static void ir_close(struct usb_serial_port *port, struct file *filp)
+static void ir_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file * filp)
{
dbg("%s - port %d", __func__, port->number);
usb_kill_urb(port->read_urb);
}
-static int ir_write(struct usb_serial_port *port,
- const unsigned char *buf, int count)
+static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
unsigned char *transfer_buffer;
int result;
dbg("%s - port = %d, count = %d", __func__, port->number, count);
- if (!port->tty) {
- dev_err(&port->dev, "%s - no tty???\n", __func__);
- return 0;
- }
-
if (count == 0)
return 0;
dbg("%s - port %d", __func__, port->number);
- if (!port->open_count) {
+ if (!port->port.count) {
dbg("%s - port closed.", __func__);
return;
}
switch (status) {
case 0: /* Successful */
-
/*
* The first byte of the packet we get from the device
* contains a busy indicator and baud rate change.
*/
if ((*data & 0x0f) > 0)
ir_baud = *data & 0x0f;
-
- usb_serial_debug_data(
- debug,
- &port->dev,
- __func__,
- urb->actual_length,
- data);
-
- tty = port->tty;
-
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
+ tty = port->port.tty;
if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
- tty_insert_flip_string(tty, data + 1,
- urb->actual_length - 1);
+ tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
tty_flip_buffer_push(tty);
}
*/
case -EPROTO: /* taking inspiration from pl2303.c */
-
- /* Continue trying to always read */
+ /* Continue trying to always read */
usb_fill_bulk_urb(
port->read_urb,
- port->serial->dev,
+ port->serial->dev,
usb_rcvbulkpipe(port->serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- dev_err(&port->dev,
- "%s - failed resubmitting read urb, error %d\n",
+ dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
__func__, result);
- break;
-
+ break ;
default:
dbg("%s - nonzero read bulk status received: %d",
- __func__,
- status);
- break;
+ __func__, status);
+ break ;
}
-
return;
}
-static void ir_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void ir_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
unsigned char *transfer_buffer;
int result;
dbg("%s - port %d", __func__, port->number);
- baud = tty_get_baud_rate(port->tty);
+ baud = tty_get_baud_rate(tty);
/*
* FIXME, we should compare the baud request against the
__func__, result);
/* Only speed changes are supported */
- tty_termios_copy_hw(port->tty->termios, old_termios);
- tty_encode_baud_rate(port->tty, baud, baud);
+ tty_termios_copy_hw(tty->termios, old_termios);
+ tty_encode_baud_rate(tty, baud, baud);
}
static int __init ir_init(void)
}
}
-static int iuu_tiocmset(struct usb_serial_port *port, struct file *file,
+static int iuu_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct iuu_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
* When no card , the reader respond with TIOCM_CD
* This is known as CD autodetect mechanism
*/
-static int iuu_tiocmget(struct usb_serial_port *port, struct file *file)
+static int iuu_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct iuu_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
int rc;
port->bulk_out_endpointAddress), buf,
count, &actual, HZ * 1);
- if (status != IUU_OPERATION_OK) {
+ if (status != IUU_OPERATION_OK)
dbg("%s - error = %2x", __func__, status);
- } else {
+ else
dbg("%s - write OK !", __func__);
- }
return status;
}
port->bulk_in_endpointAddress), buf,
count, &actual, HZ * 1);
- if (status != IUU_OPERATION_OK) {
+ if (status != IUU_OPERATION_OK)
dbg("%s - error = %2x", __func__, status);
- } else {
+ else
dbg("%s - read OK !", __func__);
- }
-
return status;
}
}
dbg("%s - %i chars to write", __func__, urb->actual_length);
- tty = port->tty;
+ tty = port->port.tty;
if (data == NULL)
dbg("%s - data is NULL !!!", __func__);
if (tty && urb->actual_length && data) {
/* if nothing to write call again rxcmd */
dbg("%s - rxcmd recall", __func__);
iuu_led_activity_off(urb);
- return;
}
-static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf,
- int count)
+static int iuu_uart_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const u8 *buf, int count)
{
struct iuu_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
if (priv->writelen > 0) {
/* buffer already filled but not commited */
spin_unlock_irqrestore(&priv->lock, flags);
- return (0);
+ return 0;
}
/* fill the buffer */
memcpy(priv->writebuf, buf, count);
priv->writelen = count;
spin_unlock_irqrestore(&priv->lock, flags);
- return (count);
+ return count;
}
static void read_rxcmd_callback(struct urb *urb)
return 0;
}
-static void iuu_close(struct usb_serial_port *port, struct file *filp)
+static void iuu_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
/* iuu_led (port,255,0,0,0); */
struct usb_serial *serial;
iuu_uart_off(port);
if (serial->dev) {
- if (port->tty) {
- c_cflag = port->tty->termios->c_cflag;
+ if (tty) {
+ c_cflag = tty->termios->c_cflag;
if (c_cflag & HUPCL) {
/* drop DTR and RTS */
priv = usb_get_serial_port_data(port);
}
}
-static int iuu_open(struct usb_serial_port *port, struct file *filp)
+static int iuu_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
u8 *buf;
/* set the termios structure */
spin_lock_irqsave(&priv->lock, flags);
- if (!priv->termios_initialized) {
- *(port->tty->termios) = tty_std_termios;
- port->tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
- | TIOCM_CTS | CSTOPB | PARENB;
- port->tty->termios->c_lflag = 0;
- port->tty->termios->c_oflag = 0;
- port->tty->termios->c_iflag = 0;
+ if (tty && !priv->termios_initialized) {
+ *(tty->termios) = tty_std_termios;
+ tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
+ | TIOCM_CTS | CSTOPB | PARENB;
+ tty->termios->c_ispeed = 9600;
+ tty->termios->c_ospeed = 9600;
+ tty->termios->c_lflag = 0;
+ tty->termios->c_oflag = 0;
+ tty->termios->c_iflag = 0;
priv->termios_initialized = 1;
- port->tty->low_latency = 1;
+ tty->low_latency = 1;
priv->poll = 0;
}
spin_unlock_irqrestore(&priv->lock, flags);
if (result) {
dev_err(&port->dev, "%s - failed submitting read urb,"
" error %d\n", __func__, result);
- iuu_close(port, NULL);
+ iuu_close(tty, port, NULL);
return -EPROTO;
} else {
dbg("%s - rxcmd OK", __func__);
/*
Keyspan USB to Serial Converter driver
-
+
(C) Copyright (C) 2000-2001 Hugh Blemings <hugh@blemings.org>
(C) Copyright (C) 2002 Greg Kroah-Hartman <greg@kroah.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.
See http://misc.nu/hugh/keyspan.html for more information.
-
+
Code in this driver inspired by and in a number of places taken
from Brian Warner's original Keyspan-PDA driver.
This driver has been put together with the support of Innosys, Inc.
and Keyspan, Inc the manufacturers of the Keyspan USB-serial products.
Thanks Guys :)
-
+
Thanks to Paulus for miscellaneous tidy ups, some largish chunks
of much nicer and/or completely new code and (perhaps most uniquely)
having the patience to sit down and explain why and where he'd changed
- stuff.
-
- Tip 'o the hat to IBM (and previously Linuxcare :) for supporting
+ stuff.
+
+ Tip 'o the hat to IBM (and previously Linuxcare :) for supporting
staff in their work on open source projects.
Change History
Thu May 31 11:56:42 PDT 2001 gkh
switched from using spinlock to a semaphore
-
+
(04/08/2001) gb
Identify version on module load.
-
+
(11/01/2000) Adam J. Richter
usb_device_id table support.
-
+
Tue Oct 10 23:15:33 EST 2000 Hugh
Merged Paul's changes with my USA-49W mods. Work in progress
still...
-
+
Wed Jul 19 14:00:42 EST 2000 gkh
Added module_init and module_exit functions to handle the fact that
this driver is a loadable module now.
-
+
Tue Jul 18 16:14:52 EST 2000 Hugh
Basic character input/output for USA-19 now mostly works,
fixed at 9600 baud for the moment.
#include <linux/spinlock.h>
#include <linux/firmware.h>
#include <linux/ihex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "keyspan.h"
struct urb *instat_urb;
char instat_buf[INSTAT_BUFLEN];
- /* added to support 49wg, where data from all 4 ports comes in on 1 EP */
- /* and high-speed supported */
+ /* added to support 49wg, where data from all 4 ports comes in
+ on 1 EP and high-speed supported */
struct urb *indat_urb;
char indat_buf[INDAT49W_BUFLEN];
/* XXX this one probably will need a lock */
struct urb *glocont_urb;
char glocont_buf[GLOCONT_BUFLEN];
- char ctrl_buf[8]; // for EP0 control message
+ char ctrl_buf[8]; /* for EP0 control message */
};
struct keyspan_port_private {
int resend_cont; /* need to resend control packet */
};
-
/* Include Keyspan message headers. All current Keyspan Adapters
make use of one of five message formats which are referred
- to as USA-26, USA-28, USA-49, USA-90, USA-67 by Keyspan and within this driver. */
+ to as USA-26, USA-28, USA-49, USA-90, USA-67 by Keyspan and
+ within this driver. */
#include "keyspan_usa26msg.h"
#include "keyspan_usa28msg.h"
#include "keyspan_usa49msg.h"
#include "keyspan_usa90msg.h"
#include "keyspan_usa67msg.h"
-
+
/* Functions used by new usb-serial code. */
-static int __init keyspan_init (void)
+static int __init keyspan_init(void)
{
int retval;
retval = usb_serial_register(&keyspan_pre_device);
if (retval)
goto failed_4port_device_register;
retval = usb_register(&keyspan_driver);
- if (retval)
+ if (retval)
goto failed_usb_register;
info(DRIVER_VERSION ":" DRIVER_DESC);
return retval;
}
-static void __exit keyspan_exit (void)
+static void __exit keyspan_exit(void)
{
- usb_deregister (&keyspan_driver);
- usb_serial_deregister (&keyspan_pre_device);
- usb_serial_deregister (&keyspan_1port_device);
- usb_serial_deregister (&keyspan_2port_device);
- usb_serial_deregister (&keyspan_4port_device);
+ usb_deregister(&keyspan_driver);
+ usb_serial_deregister(&keyspan_pre_device);
+ usb_serial_deregister(&keyspan_1port_device);
+ usb_serial_deregister(&keyspan_2port_device);
+ usb_serial_deregister(&keyspan_4port_device);
}
module_init(keyspan_init);
module_exit(keyspan_exit);
-static void keyspan_rx_throttle (struct usb_serial_port *port)
-{
- dbg("%s - port %d", __func__, port->number);
-}
-
-
-static void keyspan_rx_unthrottle (struct usb_serial_port *port)
-{
- dbg("%s - port %d", __func__, port->number);
-}
-
-
-static void keyspan_break_ctl (struct usb_serial_port *port, int break_state)
+static void keyspan_break_ctl(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct keyspan_port_private *p_priv;
- dbg("%s", __func__);
+ dbg("%s", __func__);
p_priv = usb_get_serial_port_data(port);
}
-static void keyspan_set_termios (struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void keyspan_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
int baud_rate, device_port;
struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
unsigned int cflag;
- struct tty_struct *tty = port->tty;
dbg("%s", __func__);
/* Baud rate calculation takes baud rate as an integer
so other rates can be generated if desired. */
baud_rate = tty_get_baud_rate(tty);
- /* If no match or invalid, don't change */
+ /* If no match or invalid, don't change */
if (d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
/* FIXME - more to do here to ensure rate changes cleanly */
keyspan_send_setup(port, 0);
}
-static int keyspan_tiocmget(struct usb_serial_port *port, struct file *file)
+static int keyspan_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
+ struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
unsigned int value;
- struct keyspan_port_private *p_priv;
- p_priv = usb_get_serial_port_data(port);
-
value = ((p_priv->rts_state) ? TIOCM_RTS : 0) |
((p_priv->dtr_state) ? TIOCM_DTR : 0) |
((p_priv->cts_state) ? TIOCM_CTS : 0) |
((p_priv->dsr_state) ? TIOCM_DSR : 0) |
((p_priv->dcd_state) ? TIOCM_CAR : 0) |
- ((p_priv->ri_state) ? TIOCM_RNG : 0);
+ ((p_priv->ri_state) ? TIOCM_RNG : 0);
return value;
}
-static int keyspan_tiocmset(struct usb_serial_port *port, struct file *file,
+static int keyspan_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
- struct keyspan_port_private *p_priv;
+ struct usb_serial_port *port = tty->driver_data;
+ struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
- p_priv = usb_get_serial_port_data(port);
-
if (set & TIOCM_RTS)
p_priv->rts_state = 1;
if (set & TIOCM_DTR)
p_priv->dtr_state = 1;
-
if (clear & TIOCM_RTS)
p_priv->rts_state = 0;
if (clear & TIOCM_DTR)
return 0;
}
-static int keyspan_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- return -ENOIOCTLCMD;
-}
-
- /* Write function is similar for the four protocols used
- with only a minor change for usa90 (usa19hs) required */
-static int keyspan_write(struct usb_serial_port *port,
- const unsigned char *buf, int count)
+/* Write function is similar for the four protocols used
+ with only a minor change for usa90 (usa19hs) required */
+static int keyspan_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
int flip;
int left, todo;
struct urb *this_urb;
- int err, maxDataLen, dataOffset;
+ int err, maxDataLen, dataOffset;
p_priv = usb_get_serial_port_data(port);
d_details = p_priv->device_details;
if (d_details->msg_format == msg_usa90) {
- maxDataLen = 64;
+ maxDataLen = 64;
dataOffset = 0;
} else {
maxDataLen = 63;
dataOffset = 1;
}
-
+
dbg("%s - for port %d (%d chars), flip=%d",
__func__, port->number, count, p_priv->out_flip);
todo = maxDataLen;
flip = p_priv->out_flip;
-
+
/* Check we have a valid urb/endpoint before we use it... */
- if ((this_urb = p_priv->out_urbs[flip]) == NULL) {
+ this_urb = p_priv->out_urbs[flip];
+ if (this_urb == NULL) {
/* no bulk out, so return 0 bytes written */
dbg("%s - no output urb :(", __func__);
return count;
}
- dbg("%s - endpoint %d flip %d", __func__, usb_pipeendpoint(this_urb->pipe), flip);
+ dbg("%s - endpoint %d flip %d",
+ __func__, usb_pipeendpoint(this_urb->pipe), flip);
if (this_urb->status == -EINPROGRESS) {
- if (time_before(jiffies, p_priv->tx_start_time[flip] + 10 * HZ))
+ if (time_before(jiffies,
+ p_priv->tx_start_time[flip] + 10 * HZ))
break;
usb_unlink_urb(this_urb);
break;
}
- /* First byte in buffer is "last flag" (except for usa19hx) - unused so
- for now so set to zero */
+ /* First byte in buffer is "last flag" (except for usa19hx)
+ - unused so for now so set to zero */
((char *)this_urb->transfer_buffer)[0] = 0;
- memcpy (this_urb->transfer_buffer + dataOffset, buf, todo);
+ memcpy(this_urb->transfer_buffer + dataOffset, buf, todo);
buf += todo;
/* send the data out the bulk port */
this_urb->transfer_buffer_length = todo + dataOffset;
this_urb->dev = port->serial->dev;
- if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+ err = usb_submit_urb(this_urb, GFP_ATOMIC);
+ if (err != 0)
dbg("usb_submit_urb(write bulk) failed (%d)", err);
- }
p_priv->tx_start_time[flip] = jiffies;
/* Flip for next time if usa26 or usa28 interface
unsigned char *data = urb->transfer_buffer;
int status = urb->status;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
endpoint = usb_pipeendpoint(urb->pipe);
}
port = urb->context;
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
/* 0x80 bit is error flag */
if ((data[0] & 0x80) == 0) {
- /* no errors on individual bytes, only possible overrun err*/
+ /* no errors on individual bytes, only
+ possible overrun err */
if (data[0] & RXERROR_OVERRUN)
- err = TTY_OVERRUN;
- else err = 0;
- for (i = 1; i < urb->actual_length ; ++i) {
+ err = TTY_OVERRUN;
+ else
+ err = 0;
+ for (i = 1; i < urb->actual_length ; ++i)
tty_insert_flip_char(tty, data[i], err);
- }
} else {
/* some bytes had errors, every byte has status */
dbg("%s - RX error!!!!", __func__);
}
tty_flip_buffer_push(tty);
}
-
- /* Resubmit urb so we continue receiving */
+
+ /* Resubmit urb so we continue receiving */
urb->dev = port->serial->dev;
- if (port->open_count)
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
- dbg("%s - resubmit read urb failed. (%d)", __func__, err);
- }
+ if (port->port.count) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err != 0)
+ dbg("%s - resubmit read urb failed. (%d)",
+ __func__, err);
+ }
return;
}
- /* Outdat handling is common for all devices */
+/* Outdat handling is common for all devices */
static void usa2x_outdat_callback(struct urb *urb)
{
struct usb_serial_port *port;
port = urb->context;
p_priv = usb_get_serial_port_data(port);
- dbg ("%s - urb %d", __func__, urb == p_priv->out_urbs[1]);
+ dbg("%s - urb %d", __func__, urb == p_priv->out_urbs[1]);
- if (port->open_count)
+ if (port->port.count)
usb_serial_port_softint(port);
}
static void usa26_inack_callback(struct urb *urb)
{
- dbg ("%s", __func__);
-
+ dbg("%s", __func__);
+
}
static void usa26_outcont_callback(struct urb *urb)
p_priv = usb_get_serial_port_data(port);
if (p_priv->resend_cont) {
- dbg ("%s - sending setup", __func__);
- keyspan_usa26_send_setup(port->serial, port, p_priv->resend_cont - 1);
+ dbg("%s - sending setup", __func__);
+ keyspan_usa26_send_setup(port->serial, port,
+ p_priv->resend_cont - 1);
}
}
/* Now do something useful with the data */
- /* Check port number from message and retrieve private data */
+ /* Check port number from message and retrieve private data */
if (msg->port >= serial->num_ports) {
- dbg ("%s - Unexpected port number %d", __func__, msg->port);
+ dbg("%s - Unexpected port number %d", __func__, msg->port);
goto exit;
}
port = serial->port[msg->port];
p_priv = usb_get_serial_port_data(port);
-
+
/* Update handshaking pin state information */
old_dcd_state = p_priv->dcd_state;
p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
p_priv->ri_state = ((msg->ri) ? 1 : 0);
- if (port->tty && !C_CLOCAL(port->tty)
+ if (port->port.tty && !C_CLOCAL(port->port.tty)
&& old_dcd_state != p_priv->dcd_state) {
if (old_dcd_state)
- tty_hangup(port->tty);
+ tty_hangup(port->port.tty);
/* else */
/* wake_up_interruptible(&p_priv->open_wait); */
}
-
+
/* Resubmit urb so we continue receiving */
urb->dev = serial->dev;
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err != 0)
dbg("%s - resubmit read urb failed. (%d)", __func__, err);
- }
exit: ;
}
static void usa26_glocont_callback(struct urb *urb)
{
- dbg ("%s", __func__);
-
+ dbg("%s", __func__);
}
static void usa28_indat_callback(struct urb *urb)
{
- int i, err;
+ int err;
struct usb_serial_port *port;
struct tty_struct *tty;
unsigned char *data;
struct keyspan_port_private *p_priv;
int status = urb->status;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
port = urb->context;
p_priv = usb_get_serial_port_data(port);
p_priv = usb_get_serial_port_data(port);
data = urb->transfer_buffer;
- tty = port->tty;
+ tty = port->port.tty;
if (urb->actual_length) {
- for (i = 0; i < urb->actual_length ; ++i) {
- tty_insert_flip_char(tty, data[i], 0);
- }
+ tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
/* Resubmit urb so we continue receiving */
urb->dev = port->serial->dev;
- if (port->open_count)
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
- dbg("%s - resubmit read urb failed. (%d)", __func__, err);
- }
+ if (port->port.count) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err != 0)
+ dbg("%s - resubmit read urb failed. (%d)",
+ __func__, err);
+ }
p_priv->in_flip ^= 1;
urb = p_priv->in_urbs[p_priv->in_flip];
static void usa28_inack_callback(struct urb *urb)
{
- dbg ("%s", __func__);
+ dbg("%s", __func__);
}
static void usa28_outcont_callback(struct urb *urb)
p_priv = usb_get_serial_port_data(port);
if (p_priv->resend_cont) {
- dbg ("%s - sending setup", __func__);
- keyspan_usa28_send_setup(port->serial, port, p_priv->resend_cont - 1);
+ dbg("%s - sending setup", __func__);
+ keyspan_usa28_send_setup(port->serial, port,
+ p_priv->resend_cont - 1);
}
}
/*dbg("%s %x %x %x %x %x %x %x %x %x %x %x %x", __func__
data[0], data[1], data[2], data[3], data[4], data[5],
data[6], data[7], data[8], data[9], data[10], data[11]);*/
-
- /* Now do something useful with the data */
- msg = (struct keyspan_usa28_portStatusMessage *)data;
+ /* Now do something useful with the data */
+ msg = (struct keyspan_usa28_portStatusMessage *)data;
- /* Check port number from message and retrieve private data */
+ /* Check port number from message and retrieve private data */
if (msg->port >= serial->num_ports) {
- dbg ("%s - Unexpected port number %d", __func__, msg->port);
+ dbg("%s - Unexpected port number %d", __func__, msg->port);
goto exit;
}
port = serial->port[msg->port];
p_priv = usb_get_serial_port_data(port);
-
+
/* Update handshaking pin state information */
old_dcd_state = p_priv->dcd_state;
p_priv->cts_state = ((msg->cts) ? 1 : 0);
p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
p_priv->ri_state = ((msg->ri) ? 1 : 0);
- if (port->tty && !C_CLOCAL(port->tty)
+ if (port->port.tty && !C_CLOCAL(port->port.tty)
&& old_dcd_state != p_priv->dcd_state) {
if (old_dcd_state)
- tty_hangup(port->tty);
+ tty_hangup(port->port.tty);
/* else */
/* wake_up_interruptible(&p_priv->open_wait); */
}
/* Resubmit urb so we continue receiving */
urb->dev = serial->dev;
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err != 0)
dbg("%s - resubmit read urb failed. (%d)", __func__, err);
- }
exit: ;
}
static void usa28_glocont_callback(struct urb *urb)
{
- dbg ("%s", __func__);
+ dbg("%s", __func__);
}
struct keyspan_port_private *p_priv;
int i;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
serial = urb->context;
for (i = 0; i < serial->num_ports; ++i) {
p_priv = usb_get_serial_port_data(port);
if (p_priv->resend_cont) {
- dbg ("%s - sending setup", __func__);
- keyspan_usa49_send_setup(serial, port, p_priv->resend_cont - 1);
+ dbg("%s - sending setup", __func__);
+ keyspan_usa49_send_setup(serial, port,
+ p_priv->resend_cont - 1);
break;
}
}
int old_dcd_state;
int status = urb->status;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
serial = urb->context;
return;
}
- if (urb->actual_length != sizeof(struct keyspan_usa49_portStatusMessage)) {
+ if (urb->actual_length !=
+ sizeof(struct keyspan_usa49_portStatusMessage)) {
dbg("%s - bad length %d", __func__, urb->actual_length);
goto exit;
}
/*dbg(" %x %x %x %x %x %x %x %x %x %x %x", __func__,
data[0], data[1], data[2], data[3], data[4], data[5],
data[6], data[7], data[8], data[9], data[10]);*/
-
- /* Now do something useful with the data */
+
+ /* Now do something useful with the data */
msg = (struct keyspan_usa49_portStatusMessage *)data;
- /* Check port number from message and retrieve private data */
+ /* Check port number from message and retrieve private data */
if (msg->portNumber >= serial->num_ports) {
- dbg ("%s - Unexpected port number %d", __func__, msg->portNumber);
+ dbg("%s - Unexpected port number %d",
+ __func__, msg->portNumber);
goto exit;
}
port = serial->port[msg->portNumber];
p_priv = usb_get_serial_port_data(port);
-
+
/* Update handshaking pin state information */
old_dcd_state = p_priv->dcd_state;
p_priv->cts_state = ((msg->cts) ? 1 : 0);
p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
p_priv->ri_state = ((msg->ri) ? 1 : 0);
- if (port->tty && !C_CLOCAL(port->tty)
+ if (port->port.tty && !C_CLOCAL(port->port.tty)
&& old_dcd_state != p_priv->dcd_state) {
if (old_dcd_state)
- tty_hangup(port->tty);
+ tty_hangup(port->port.tty);
/* else */
/* wake_up_interruptible(&p_priv->open_wait); */
}
- /* Resubmit urb so we continue receiving */
+ /* Resubmit urb so we continue receiving */
urb->dev = serial->dev;
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err != 0)
dbg("%s - resubmit read urb failed. (%d)", __func__, err);
- }
exit: ;
}
static void usa49_inack_callback(struct urb *urb)
{
- dbg ("%s", __func__);
+ dbg("%s", __func__);
}
static void usa49_indat_callback(struct urb *urb)
unsigned char *data = urb->transfer_buffer;
int status = urb->status;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
endpoint = usb_pipeendpoint(urb->pipe);
}
port = urb->context;
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
/* 0x80 bit is error flag */
if ((data[0] & 0x80) == 0) {
/* no error on any byte */
- for (i = 1; i < urb->actual_length ; ++i) {
- tty_insert_flip_char(tty, data[i], 0);
- }
+ tty_insert_flip_string(tty, data + 1,
+ urb->actual_length - 1);
} else {
/* some bytes had errors, every byte has status */
for (i = 0; i + 1 < urb->actual_length; i += 2) {
}
tty_flip_buffer_push(tty);
}
-
- /* Resubmit urb so we continue receiving */
+
+ /* Resubmit urb so we continue receiving */
urb->dev = port->serial->dev;
- if (port->open_count)
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
- dbg("%s - resubmit read urb failed. (%d)", __func__, err);
- }
+ if (port->port.count) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err != 0)
+ dbg("%s - resubmit read urb failed. (%d)",
+ __func__, err);
+ }
}
static void usa49wg_indat_callback(struct urb *urb)
unsigned char *data = urb->transfer_buffer;
int status = urb->status;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
serial = urb->context;
/* Check port number from message*/
if (data[i] >= serial->num_ports) {
- dbg ("%s - Unexpected port number %d",
+ dbg("%s - Unexpected port number %d",
__func__, data[i]);
return;
}
port = serial->port[data[i++]];
- tty = port->tty;
+ tty = port->port.tty;
len = data[i++];
/* 0x80 bit is error flag */
/* no error on any byte */
i++;
for (x = 1; x < len ; ++x)
- if (port->open_count)
+ if (port->port.count)
tty_insert_flip_char(tty,
data[i++], 0);
else
if (stat & RXERROR_PARITY)
flag |= TTY_PARITY;
/* XXX should handle break (0x10) */
- if (port->open_count)
+ if (port->port.count)
tty_insert_flip_char(tty,
data[i+1], flag);
i += 2;
}
}
- if (port->open_count)
+ if (port->port.count)
tty_flip_buffer_push(tty);
}
}
/* not used, usa-49 doesn't have per-port control endpoints */
static void usa49_outcont_callback(struct urb *urb)
{
- dbg ("%s", __func__);
+ dbg("%s", __func__);
}
static void usa90_indat_callback(struct urb *urb)
unsigned char *data = urb->transfer_buffer;
int status = urb->status;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
endpoint = usb_pipeendpoint(urb->pipe);
port = urb->context;
p_priv = usb_get_serial_port_data(port);
- tty = port->tty;
+ tty = port->port.tty;
if (urb->actual_length) {
-
/* if current mode is DMA, looks like usa28 format
- otherwise looks like usa26 data format */
+ otherwise looks like usa26 data format */
- if (p_priv->baud > 57600) {
- for (i = 0; i < urb->actual_length ; ++i)
- tty_insert_flip_char(tty, data[i], 0);
- }
+ if (p_priv->baud > 57600)
+ tty_insert_flip_string(tty, data, urb->actual_length);
else {
-
/* 0x80 bit is error flag */
if ((data[0] & 0x80) == 0) {
- /* no errors on individual bytes, only possible overrun err*/
+ /* no errors on individual bytes, only
+ possible overrun err*/
if (data[0] & RXERROR_OVERRUN)
- err = TTY_OVERRUN;
- else err = 0;
- for (i = 1; i < urb->actual_length ; ++i)
- tty_insert_flip_char(tty, data[i], err);
-
- }
- else {
+ err = TTY_OVERRUN;
+ else
+ err = 0;
+ for (i = 1; i < urb->actual_length ; ++i)
+ tty_insert_flip_char(tty, data[i],
+ err);
+ } else {
/* some bytes had errors, every byte has status */
dbg("%s - RX error!!!!", __func__);
for (i = 0; i + 1 < urb->actual_length; i += 2) {
if (stat & RXERROR_PARITY)
flag |= TTY_PARITY;
/* XXX should handle break (0x10) */
- tty_insert_flip_char(tty, data[i+1], flag);
+ tty_insert_flip_char(tty, data[i+1],
+ flag);
}
}
}
tty_flip_buffer_push(tty);
}
-
+
/* Resubmit urb so we continue receiving */
urb->dev = port->serial->dev;
- if (port->open_count)
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
- dbg("%s - resubmit read urb failed. (%d)", __func__, err);
- }
+ if (port->port.count) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err != 0)
+ dbg("%s - resubmit read urb failed. (%d)",
+ __func__, err);
+ }
return;
}
port = serial->port[0];
p_priv = usb_get_serial_port_data(port);
-
+
/* Update handshaking pin state information */
old_dcd_state = p_priv->dcd_state;
p_priv->cts_state = ((msg->cts) ? 1 : 0);
p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
p_priv->ri_state = ((msg->ri) ? 1 : 0);
- if (port->tty && !C_CLOCAL(port->tty)
+ if (port->port.tty && !C_CLOCAL(port->port.tty)
&& old_dcd_state != p_priv->dcd_state) {
if (old_dcd_state)
- tty_hangup(port->tty);
+ tty_hangup(port->port.tty);
/* else */
/* wake_up_interruptible(&p_priv->open_wait); */
}
-
+
/* Resubmit urb so we continue receiving */
urb->dev = serial->dev;
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err != 0)
dbg("%s - resubmit read urb failed. (%d)", __func__, err);
- }
exit:
;
}
p_priv = usb_get_serial_port_data(port);
if (p_priv->resend_cont) {
- dbg ("%s - sending setup", __func__);
- keyspan_usa90_send_setup(port->serial, port, p_priv->resend_cont - 1);
+ dbg("%s - sending setup", __func__);
+ keyspan_usa90_send_setup(port->serial, port,
+ p_priv->resend_cont - 1);
}
}
int old_dcd_state;
int status = urb->status;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
serial = urb->context;
return;
}
- if (urb->actual_length != sizeof(struct keyspan_usa67_portStatusMessage)) {
+ if (urb->actual_length !=
+ sizeof(struct keyspan_usa67_portStatusMessage)) {
dbg("%s - bad length %d", __func__, urb->actual_length);
return;
}
/* Check port number from message and retrieve private data */
if (msg->port >= serial->num_ports) {
- dbg ("%s - Unexpected port number %d", __func__, msg->port);
+ dbg("%s - Unexpected port number %d", __func__, msg->port);
return;
}
p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
- if (port->tty && !C_CLOCAL(port->tty)
+ if (port->port.tty && !C_CLOCAL(port->port.tty)
&& old_dcd_state != p_priv->dcd_state) {
if (old_dcd_state)
- tty_hangup(port->tty);
+ tty_hangup(port->port.tty);
/* else */
/* wake_up_interruptible(&p_priv->open_wait); */
}
struct keyspan_port_private *p_priv;
int i;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
serial = urb->context;
for (i = 0; i < serial->num_ports; ++i) {
p_priv = usb_get_serial_port_data(port);
if (p_priv->resend_cont) {
- dbg ("%s - sending setup", __func__);
+ dbg("%s - sending setup", __func__);
keyspan_usa67_send_setup(serial, port,
p_priv->resend_cont - 1);
break;
}
}
-static int keyspan_write_room (struct usb_serial_port *port)
+static int keyspan_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
int flip;
/* FIXME: locking */
if (d_details->msg_format == msg_usa90)
- data_len = 64;
+ data_len = 64;
else
data_len = 63;
flip = p_priv->out_flip;
/* Check both endpoints to see if any are available. */
- if ((this_urb = p_priv->out_urbs[flip]) != NULL) {
+ this_urb = p_priv->out_urbs[flip];
+ if (this_urb != NULL) {
if (this_urb->status != -EINPROGRESS)
- return (data_len);
- flip = (flip + 1) & d_details->outdat_endp_flip;
- if ((this_urb = p_priv->out_urbs[flip]) != NULL)
+ return data_len;
+ flip = (flip + 1) & d_details->outdat_endp_flip;
+ this_urb = p_priv->out_urbs[flip];
+ if (this_urb != NULL) {
if (this_urb->status != -EINPROGRESS)
- return (data_len);
+ return data_len;
+ }
}
return 0;
}
-static int keyspan_chars_in_buffer (struct usb_serial_port *port)
-{
- return 0;
-}
-
-
-static int keyspan_open (struct usb_serial_port *port, struct file *filp)
+static int keyspan_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct keyspan_port_private *p_priv;
struct keyspan_serial_private *s_priv;
int i, err;
int baud_rate, device_port;
struct urb *urb;
- unsigned int cflag;
+ unsigned int cflag = 0;
s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
/* Reset low level data toggle and start reading from endpoints */
for (i = 0; i < 2; i++) {
- if ((urb = p_priv->in_urbs[i]) == NULL)
+ urb = p_priv->in_urbs[i];
+ if (urb == NULL)
continue;
urb->dev = serial->dev;
- /* make sure endpoint data toggle is synchronized with the device */
-
+ /* make sure endpoint data toggle is synchronized
+ with the device */
usb_clear_halt(urb->dev, urb->pipe);
-
- if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
- dbg("%s - submit urb %d failed (%d)", __func__, i, err);
- }
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err != 0)
+ dbg("%s - submit urb %d failed (%d)",
+ __func__, i, err);
}
/* Reset low level data toggle on out endpoints */
for (i = 0; i < 2; i++) {
- if ((urb = p_priv->out_urbs[i]) == NULL)
+ urb = p_priv->out_urbs[i];
+ if (urb == NULL)
continue;
urb->dev = serial->dev;
- /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
+ /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+ usb_pipeout(urb->pipe), 0); */
}
/* get the terminal config for the setup message now so we don't
* need to send 2 of them */
- cflag = port->tty->termios->c_cflag;
device_port = port->number - port->serial->minor;
-
- /* Baud rate calculation takes baud rate as an integer
- so other rates can be generated if desired. */
- baud_rate = tty_get_baud_rate(port->tty);
- /* If no match or invalid, leave as default */
- if (baud_rate >= 0
- && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
- NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
- p_priv->baud = baud_rate;
+ if (tty) {
+ cflag = tty->termios->c_cflag;
+ /* Baud rate calculation takes baud rate as an integer
+ so other rates can be generated if desired. */
+ baud_rate = tty_get_baud_rate(tty);
+ /* If no match or invalid, leave as default */
+ if (baud_rate >= 0
+ && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
+ NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
+ p_priv->baud = baud_rate;
+ }
}
-
/* set CTS/RTS handshake etc. */
p_priv->cflag = cflag;
p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
keyspan_send_setup(port, 1);
- //mdelay(100);
- //keyspan_set_termios(port, NULL);
+ /* mdelay(100); */
+ /* keyspan_set_termios(port, NULL); */
return 0;
}
usb_kill_urb(urb);
}
-static void keyspan_close(struct usb_serial_port *port, struct file *filp)
+static void keyspan_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
int i;
struct usb_serial *serial = port->serial;
dbg("%s", __func__);
s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
-
+
p_priv->rts_state = 0;
p_priv->dtr_state = 0;
-
+
if (serial->dev) {
keyspan_send_setup(port, 2);
/* pilot-xfer seems to work best with this delay */
mdelay(100);
- // keyspan_set_termios(port, NULL);
+ /* keyspan_set_termios(port, NULL); */
}
/*while (p_priv->outcont_urb->status == -EINPROGRESS) {
stop_urb(p_priv->out_urbs[i]);
}
}
- port->tty = NULL;
+ port->port.tty = NULL;
}
- /* download the firmware to a pre-renumeration device */
-static int keyspan_fake_startup (struct usb_serial *serial)
+/* download the firmware to a pre-renumeration device */
+static int keyspan_fake_startup(struct usb_serial *serial)
{
int response;
const struct ihex_binrec *record;
dbg("Keyspan startup version %04x product %04x",
le16_to_cpu(serial->dev->descriptor.bcdDevice),
le16_to_cpu(serial->dev->descriptor.idProduct));
-
- if ((le16_to_cpu(serial->dev->descriptor.bcdDevice) & 0x8000) != 0x8000) {
+
+ if ((le16_to_cpu(serial->dev->descriptor.bcdDevice) & 0x8000)
+ != 0x8000) {
dbg("Firmware already loaded. Quitting.");
- return(1);
+ return 1;
}
/* Select firmware image on the basis of idProduct */
case keyspan_usa19_pre_product_id:
fw_name = "keyspan/usa19.fw";
break;
-
+
case keyspan_usa19qi_pre_product_id:
fw_name = "keyspan/usa19qi.fw";
break;
-
+
case keyspan_mpr_pre_product_id:
fw_name = "keyspan/mpr.fw";
break;
case keyspan_usa19qw_pre_product_id:
fw_name = "keyspan/usa19qw.fw";
break;
-
+
case keyspan_usa18x_pre_product_id:
fw_name = "keyspan/usa18x.fw";
break;
-
+
case keyspan_usa19w_pre_product_id:
fw_name = "keyspan/usa19w.fw";
break;
-
+
case keyspan_usa49w_pre_product_id:
fw_name = "keyspan/usa49w.fw";
break;
(unsigned char *)record->data,
be16_to_cpu(record->len), 0xa0);
if (response < 0) {
- dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan"
- "firmware (%d %04X %p %d)\n",
+ dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan firmware (%d %04X %p %d)\n",
response, be32_to_cpu(record->addr),
record->data, be16_to_cpu(record->len));
break;
response = ezusb_set_reset(serial, 0);
/* we don't want this device to have a driver assigned to it. */
- return (1);
+ return 1;
}
/* Helper functions used by keyspan_setup_urbs */
return NULL;
}
-static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
+static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint,
int dir, void *ctx, char *buf, int len,
void (*callback)(struct urb *))
{
if (endpoint == -1)
return NULL; /* endpoint not needed */
- dbg ("%s - alloc for endpoint %d.", __func__, endpoint);
+ dbg("%s - alloc for endpoint %d.", __func__, endpoint);
urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
if (urb == NULL) {
- dbg ("%s - alloc for endpoint %d failed.", __func__, endpoint);
+ dbg("%s - alloc for endpoint %d failed.", __func__, endpoint);
return NULL;
}
}, {
/* msg_usa90 callbacks */
.instat_callback = usa90_instat_callback,
- .glocont_callback = usa28_glocont_callback,
+ .glocont_callback = usa28_glocont_callback,
.indat_callback = usa90_indat_callback,
.outdat_callback = usa2x_outdat_callback,
.inack_callback = usa28_inack_callback,
struct callbacks *cback;
int endp;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
s_priv = usb_get_serial_data(serial);
d_details = s_priv->device_details;
- /* Setup values for the various callback routines */
+ /* Setup values for the various callback routines */
cback = &keyspan_callbacks[d_details->msg_format];
- /* Allocate and set up urbs for each one that is in use,
- starting with instat endpoints */
+ /* Allocate and set up urbs for each one that is in use,
+ starting with instat endpoints */
s_priv->instat_urb = keyspan_setup_urb
(serial, d_details->instat_endpoint, USB_DIR_IN,
serial, s_priv->instat_buf, INSTAT_BUFLEN,
serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
cback->glocont_callback);
- /* Setup endpoints for each port specific thing */
- for (i = 0; i < d_details->num_ports; i ++) {
+ /* Setup endpoints for each port specific thing */
+ for (i = 0; i < d_details->num_ports; i++) {
port = serial->port[i];
p_priv = usb_get_serial_port_data(port);
(serial, d_details->outcont_endpoints[i], USB_DIR_OUT,
port, p_priv->outcont_buffer, 64,
cback->outcont_callback);
- }
-
+ }
}
/* usa19 function doesn't require prescaler */
u8 *rate_low, u8 *prescaler, int portnum)
{
u32 b16, /* baud rate times 16 (actual rate used internally) */
- div, /* divisor */
+ div, /* divisor */
cnt; /* inverse of divisor (programmed into 8051) */
-
- dbg ("%s - %d.", __func__, baud_rate);
-
- /* prevent divide by zero... */
- if( (b16 = (baud_rate * 16L)) == 0) {
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
- /* Any "standard" rate over 57k6 is marginal on the USA-19
- as we run out of divisor resolution. */
- if (baud_rate > 57600) {
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
-
- /* calculate the divisor and the counter (its inverse) */
- if( (div = (baudclk / b16)) == 0) {
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
- else {
+ dbg("%s - %d.", __func__, baud_rate);
+
+ /* prevent divide by zero... */
+ b16 = baud_rate * 16L;
+ if (b16 == 0)
+ return KEYSPAN_INVALID_BAUD_RATE;
+ /* Any "standard" rate over 57k6 is marginal on the USA-19
+ as we run out of divisor resolution. */
+ if (baud_rate > 57600)
+ return KEYSPAN_INVALID_BAUD_RATE;
+
+ /* calculate the divisor and the counter (its inverse) */
+ div = baudclk / b16;
+ if (div == 0)
+ return KEYSPAN_INVALID_BAUD_RATE;
+ else
cnt = 0 - div;
- }
- if(div > 0xffff) {
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
+ if (div > 0xffff)
+ return KEYSPAN_INVALID_BAUD_RATE;
- /* return the counter values if non-null */
- if (rate_low) {
+ /* return the counter values if non-null */
+ if (rate_low)
*rate_low = (u8) (cnt & 0xff);
- }
- if (rate_hi) {
+ if (rate_hi)
*rate_hi = (u8) ((cnt >> 8) & 0xff);
- }
- if (rate_low && rate_hi) {
- dbg ("%s - %d %02x %02x.", __func__, baud_rate, *rate_hi, *rate_low);
- }
-
- return (KEYSPAN_BAUD_RATE_OK);
+ if (rate_low && rate_hi)
+ dbg("%s - %d %02x %02x.",
+ __func__, baud_rate, *rate_hi, *rate_low);
+ return KEYSPAN_BAUD_RATE_OK;
}
/* usa19hs function doesn't require prescaler */
u8 *rate_low, u8 *prescaler, int portnum)
{
u32 b16, /* baud rate times 16 (actual rate used internally) */
- div; /* divisor */
-
- dbg ("%s - %d.", __func__, baud_rate);
+ div; /* divisor */
- /* prevent divide by zero... */
- if( (b16 = (baud_rate * 16L)) == 0)
- return (KEYSPAN_INVALID_BAUD_RATE);
-
+ dbg("%s - %d.", __func__, baud_rate);
+ /* prevent divide by zero... */
+ b16 = baud_rate * 16L;
+ if (b16 == 0)
+ return KEYSPAN_INVALID_BAUD_RATE;
- /* calculate the divisor */
- if( (div = (baudclk / b16)) == 0)
- return (KEYSPAN_INVALID_BAUD_RATE);
+ /* calculate the divisor */
+ div = baudclk / b16;
+ if (div == 0)
+ return KEYSPAN_INVALID_BAUD_RATE;
- if(div > 0xffff)
- return (KEYSPAN_INVALID_BAUD_RATE);
+ if (div > 0xffff)
+ return KEYSPAN_INVALID_BAUD_RATE;
- /* return the counter values if non-null */
- if (rate_low)
+ /* return the counter values if non-null */
+ if (rate_low)
*rate_low = (u8) (div & 0xff);
-
- if (rate_hi)
+
+ if (rate_hi)
*rate_hi = (u8) ((div >> 8) & 0xff);
-
- if (rate_low && rate_hi)
- dbg ("%s - %d %02x %02x.", __func__, baud_rate, *rate_hi, *rate_low);
-
- return (KEYSPAN_BAUD_RATE_OK);
+
+ if (rate_low && rate_hi)
+ dbg("%s - %d %02x %02x.",
+ __func__, baud_rate, *rate_hi, *rate_low);
+
+ return KEYSPAN_BAUD_RATE_OK;
}
static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
{
u32 b16, /* baud rate times 16 (actual rate used internally) */
clk, /* clock with 13/8 prescaler */
- div, /* divisor using 13/8 prescaler */
+ div, /* divisor using 13/8 prescaler */
res, /* resulting baud rate using 13/8 prescaler */
diff, /* error using 13/8 prescaler */
smallest_diff;
u8 best_prescaler;
int i;
- dbg ("%s - %d.", __func__, baud_rate);
+ dbg("%s - %d.", __func__, baud_rate);
- /* prevent divide by zero */
- if( (b16 = baud_rate * 16L) == 0) {
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
+ /* prevent divide by zero */
+ b16 = baud_rate * 16L;
+ if (b16 == 0)
+ return KEYSPAN_INVALID_BAUD_RATE;
- /* Calculate prescaler by trying them all and looking
- for best fit */
-
- /* start with largest possible difference */
+ /* Calculate prescaler by trying them all and looking
+ for best fit */
+
+ /* start with largest possible difference */
smallest_diff = 0xffffffff;
/* 0 is an invalid prescaler, used as a flag */
best_prescaler = 0;
- for(i = 8; i <= 0xff; ++i) {
+ for (i = 8; i <= 0xff; ++i) {
clk = (baudclk * 8) / (u32) i;
-
- if( (div = clk / b16) == 0) {
+
+ div = clk / b16;
+ if (div == 0)
continue;
- }
res = clk / div;
- diff= (res > b16) ? (res-b16) : (b16-res);
+ diff = (res > b16) ? (res-b16) : (b16-res);
- if(diff < smallest_diff) {
+ if (diff < smallest_diff) {
best_prescaler = i;
smallest_diff = diff;
}
}
- if(best_prescaler == 0) {
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
+ if (best_prescaler == 0)
+ return KEYSPAN_INVALID_BAUD_RATE;
clk = (baudclk * 8) / (u32) best_prescaler;
div = clk / b16;
- /* return the divisor and prescaler if non-null */
- if (rate_low) {
+ /* return the divisor and prescaler if non-null */
+ if (rate_low)
*rate_low = (u8) (div & 0xff);
- }
- if (rate_hi) {
+ if (rate_hi)
*rate_hi = (u8) ((div >> 8) & 0xff);
- }
if (prescaler) {
*prescaler = best_prescaler;
/* dbg("%s - %d %d", __func__, *prescaler, div); */
}
- return (KEYSPAN_BAUD_RATE_OK);
+ return KEYSPAN_BAUD_RATE_OK;
}
/* USA-28 supports different maximum baud rates on each port */
u8 *rate_low, u8 *prescaler, int portnum)
{
u32 b16, /* baud rate times 16 (actual rate used internally) */
- div, /* divisor */
+ div, /* divisor */
cnt; /* inverse of divisor (programmed into 8051) */
- dbg ("%s - %d.", __func__, baud_rate);
+ dbg("%s - %d.", __func__, baud_rate);
/* prevent divide by zero */
- if ((b16 = baud_rate * 16L) == 0)
- return (KEYSPAN_INVALID_BAUD_RATE);
-
- /* calculate the divisor and the counter (its inverse) */
- if ((div = (KEYSPAN_USA28_BAUDCLK / b16)) == 0) {
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
- else {
+ b16 = baud_rate * 16L;
+ if (b16 == 0)
+ return KEYSPAN_INVALID_BAUD_RATE;
+
+ /* calculate the divisor and the counter (its inverse) */
+ div = KEYSPAN_USA28_BAUDCLK / b16;
+ if (div == 0)
+ return KEYSPAN_INVALID_BAUD_RATE;
+ else
cnt = 0 - div;
- }
- /* check for out of range, based on portnum,
- and return result */
- if(portnum == 0) {
- if(div > 0xffff)
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
- else {
- if(portnum == 1) {
- if(div > 0xff) {
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
- }
- else {
- return (KEYSPAN_INVALID_BAUD_RATE);
- }
+ /* check for out of range, based on portnum,
+ and return result */
+ if (portnum == 0) {
+ if (div > 0xffff)
+ return KEYSPAN_INVALID_BAUD_RATE;
+ } else {
+ if (portnum == 1) {
+ if (div > 0xff)
+ return KEYSPAN_INVALID_BAUD_RATE;
+ } else
+ return KEYSPAN_INVALID_BAUD_RATE;
}
/* return the counter values if not NULL
(port 1 will ignore retHi) */
- if (rate_low) {
+ if (rate_low)
*rate_low = (u8) (cnt & 0xff);
- }
- if (rate_hi) {
+ if (rate_hi)
*rate_hi = (u8) ((cnt >> 8) & 0xff);
- }
- dbg ("%s - %d OK.", __func__, baud_rate);
- return (KEYSPAN_BAUD_RATE_OK);
+ dbg("%s - %d OK.", __func__, baud_rate);
+ return KEYSPAN_BAUD_RATE_OK;
}
static int keyspan_usa26_send_setup(struct usb_serial *serial,
struct usb_serial_port *port,
int reset_port)
{
- struct keyspan_usa26_portControlMessage msg;
+ struct keyspan_usa26_portControlMessage msg;
struct keyspan_serial_private *s_priv;
struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
struct urb *this_urb;
int device_port, err;
- dbg ("%s reset=%d", __func__, reset_port);
+ dbg("%s reset=%d", __func__, reset_port);
s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
if ((reset_port + 1) > p_priv->resend_cont)
p_priv->resend_cont = reset_port + 1;
if (this_urb->status == -EINPROGRESS) {
- /* dbg ("%s - already writing", __func__); */
+ /* dbg("%s - already writing", __func__); */
mdelay(5);
- return(-1);
+ return -1;
}
- memset(&msg, 0, sizeof (struct keyspan_usa26_portControlMessage));
-
- /* Only set baud rate if it's changed */
+ memset(&msg, 0, sizeof(struct keyspan_usa26_portControlMessage));
+
+ /* Only set baud rate if it's changed */
if (p_priv->old_baud != p_priv->baud) {
p_priv->old_baud = p_priv->baud;
msg.setClocking = 0xff;
if (d_details->calculate_baud_rate
(p_priv->baud, d_details->baudclk, &msg.baudHi,
- &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
- dbg("%s - Invalid baud rate %d requested, using 9600.", __func__,
- p_priv->baud);
+ &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE) {
+ dbg("%s - Invalid baud rate %d requested, using 9600.",
+ __func__, p_priv->baud);
msg.baudLo = 0;
msg.baudHi = 125; /* Values for 9600 baud */
msg.prescaler = 10;
if (p_priv->cflag & PARENB) {
/* note USA_PARITY_NONE == 0 */
msg.lcr |= (p_priv->cflag & PARODD)?
- USA_PARITY_ODD: USA_PARITY_EVEN;
+ USA_PARITY_ODD : USA_PARITY_EVEN;
}
msg.setLcr = 0xff;
/* Sending intermediate configs */
else {
- msg._txOn = (! p_priv->break_on);
+ msg._txOn = (!p_priv->break_on);
msg._txOff = 0;
msg.txFlush = 0;
msg.txBreak = (p_priv->break_on);
msg.resetDataToggle = 0x0;
}
- /* Do handshaking outputs */
+ /* Do handshaking outputs */
msg.setTxTriState_setRts = 0xff;
msg.txTriState_rts = p_priv->rts_state;
msg.setHskoa_setDtr = 0xff;
msg.hskoa_dtr = p_priv->dtr_state;
-
+
p_priv->resend_cont = 0;
- memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
-
+ memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
+
/* send the data out the device on control endpoint */
this_urb->transfer_buffer_length = sizeof(msg);
this_urb->dev = serial->dev;
- if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+ err = usb_submit_urb(this_urb, GFP_ATOMIC);
+ if (err != 0)
dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err);
- }
#if 0
else {
dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __func__
struct usb_serial_port *port,
int reset_port)
{
- struct keyspan_usa28_portControlMessage msg;
+ struct keyspan_usa28_portControlMessage msg;
struct keyspan_serial_private *s_priv;
struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
struct urb *this_urb;
int device_port, err;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
device_port = port->number - port->serial->minor;
/* only do something if we have a bulk out endpoint */
- if ((this_urb = p_priv->outcont_urb) == NULL) {
+ this_urb = p_priv->outcont_urb;
+ if (this_urb == NULL) {
dbg("%s - oops no urb.", __func__);
return -1;
}
if ((reset_port + 1) > p_priv->resend_cont)
p_priv->resend_cont = reset_port + 1;
if (this_urb->status == -EINPROGRESS) {
- dbg ("%s already writing", __func__);
+ dbg("%s already writing", __func__);
mdelay(5);
- return(-1);
+ return -1;
}
- memset(&msg, 0, sizeof (struct keyspan_usa28_portControlMessage));
+ memset(&msg, 0, sizeof(struct keyspan_usa28_portControlMessage));
msg.setBaudRate = 1;
if (d_details->calculate_baud_rate(p_priv->baud, d_details->baudclk,
- &msg.baudHi, &msg.baudLo, NULL, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
- dbg("%s - Invalid baud rate requested %d.", __func__, p_priv->baud);
+ &msg.baudHi, &msg.baudLo, NULL, device_port) == KEYSPAN_INVALID_BAUD_RATE) {
+ dbg("%s - Invalid baud rate requested %d.",
+ __func__, p_priv->baud);
msg.baudLo = 0xff;
msg.baudHi = 0xb2; /* Values for 9600 baud */
}
msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
msg.xonFlowControl = 0;
- /* Do handshaking outputs, DTR is inverted relative to RTS */
+ /* Do handshaking outputs, DTR is inverted relative to RTS */
msg.rts = p_priv->rts_state;
msg.dtr = p_priv->dtr_state;
}
/* Sending intermediate configs */
else {
- msg._txOn = (! p_priv->break_on);
+ msg._txOn = (!p_priv->break_on);
msg._txOff = 0;
msg.txFlush = 0;
msg.txForceXoff = 0;
}
p_priv->resend_cont = 0;
- memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
+ memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
/* send the data out the device on control endpoint */
this_urb->transfer_buffer_length = sizeof(msg);
this_urb->dev = serial->dev;
- if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+ err = usb_submit_urb(this_urb, GFP_ATOMIC);
+ if (err != 0)
dbg("%s - usb_submit_urb(setup) failed", __func__);
- }
#if 0
else {
dbg("%s - usb_submit_urb(setup) OK %d bytes", __func__,
struct urb *this_urb;
int err, device_port;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
/* Work out which port within the device is being setup */
device_port = port->number - port->serial->minor;
- dbg("%s - endpoint %d port %d (%d)",__func__, usb_pipeendpoint(this_urb->pipe), port->number, device_port);
+ dbg("%s - endpoint %d port %d (%d)",
+ __func__, usb_pipeendpoint(this_urb->pipe),
+ port->number, device_port);
/* Make sure we have an urb then send the message */
if (this_urb == NULL) {
p_priv->resend_cont = reset_port + 1;
if (this_urb->status == -EINPROGRESS) {
- /* dbg ("%s - already writing", __func__); */
+ /* dbg("%s - already writing", __func__); */
mdelay(5);
- return(-1);
+ return -1;
}
- memset(&msg, 0, sizeof (struct keyspan_usa49_portControlMessage));
+ memset(&msg, 0, sizeof(struct keyspan_usa49_portControlMessage));
/*msg.portNumber = port->number;*/
msg.portNumber = device_port;
-
- /* Only set baud rate if it's changed */
+
+ /* Only set baud rate if it's changed */
if (p_priv->old_baud != p_priv->baud) {
p_priv->old_baud = p_priv->baud;
msg.setClocking = 0xff;
if (d_details->calculate_baud_rate
(p_priv->baud, d_details->baudclk, &msg.baudHi,
- &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
- dbg("%s - Invalid baud rate %d requested, using 9600.", __func__,
- p_priv->baud);
+ &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE) {
+ dbg("%s - Invalid baud rate %d requested, using 9600.",
+ __func__, p_priv->baud);
msg.baudLo = 0;
msg.baudHi = 125; /* Values for 9600 baud */
msg.prescaler = 10;
}
- //msg.setPrescaler = 0xff;
+ /* msg.setPrescaler = 0xff; */
}
msg.lcr = (p_priv->cflag & CSTOPB)? STOPBITS_678_2: STOPBITS_5678_1;
if (p_priv->cflag & PARENB) {
/* note USA_PARITY_NONE == 0 */
msg.lcr |= (p_priv->cflag & PARODD)?
- USA_PARITY_ODD: USA_PARITY_EVEN;
+ USA_PARITY_ODD : USA_PARITY_EVEN;
}
msg.setLcr = 0xff;
msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
msg.xonFlowControl = 0;
msg.setFlowControl = 0xff;
-
+
msg.forwardingLength = 16;
msg.xonChar = 17;
msg.xoffChar = 19;
- /* Opening port */
+ /* Opening port */
if (reset_port == 1) {
msg._txOn = 1;
msg._txOff = 0;
}
/* Sending intermediate configs */
else {
- msg._txOn = (! p_priv->break_on);
+ msg._txOn = (!p_priv->break_on);
msg._txOff = 0;
msg.txFlush = 0;
msg.txBreak = (p_priv->break_on);
msg.disablePort = 0;
}
- /* Do handshaking outputs */
+ /* Do handshaking outputs */
msg.setRts = 0xff;
msg.rts = p_priv->rts_state;
msg.setDtr = 0xff;
msg.dtr = p_priv->dtr_state;
-
+
p_priv->resend_cont = 0;
- /* if the device is a 49wg, we send control message on usb control EP 0 */
+ /* if the device is a 49wg, we send control message on usb
+ control EP 0 */
if (d_details->product_id == keyspan_usa49wg_product_id) {
dr = (void *)(s_priv->ctrl_buf);
dr->wIndex = 0;
dr->wLength = cpu_to_le16(sizeof(msg));
- memcpy (s_priv->glocont_buf, &msg, sizeof(msg));
+ memcpy(s_priv->glocont_buf, &msg, sizeof(msg));
- usb_fill_control_urb(this_urb, serial->dev, usb_sndctrlpipe(serial->dev, 0),
- (unsigned char *)dr, s_priv->glocont_buf, sizeof(msg),
- usa49_glocont_callback, serial);
+ usb_fill_control_urb(this_urb, serial->dev,
+ usb_sndctrlpipe(serial->dev, 0),
+ (unsigned char *)dr, s_priv->glocont_buf,
+ sizeof(msg), usa49_glocont_callback, serial);
} else {
memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
-
+
/* send the data out the device on control endpoint */
this_urb->transfer_buffer_length = sizeof(msg);
this_urb->dev = serial->dev;
}
- if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+ err = usb_submit_urb(this_urb, GFP_ATOMIC);
+ if (err != 0)
dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err);
- }
#if 0
else {
dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __func__,
struct usb_serial_port *port,
int reset_port)
{
- struct keyspan_usa90_portControlMessage msg;
+ struct keyspan_usa90_portControlMessage msg;
struct keyspan_serial_private *s_priv;
struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
int err;
u8 prescaler;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
d_details = s_priv->device_details;
/* only do something if we have a bulk out endpoint */
- if ((this_urb = p_priv->outcont_urb) == NULL) {
+ this_urb = p_priv->outcont_urb;
+ if (this_urb == NULL) {
dbg("%s - oops no urb.", __func__);
return -1;
}
if ((reset_port + 1) > p_priv->resend_cont)
p_priv->resend_cont = reset_port + 1;
if (this_urb->status == -EINPROGRESS) {
- dbg ("%s already writing", __func__);
+ dbg("%s already writing", __func__);
mdelay(5);
- return(-1);
+ return -1;
}
- memset(&msg, 0, sizeof (struct keyspan_usa90_portControlMessage));
+ memset(&msg, 0, sizeof(struct keyspan_usa90_portControlMessage));
- /* Only set baud rate if it's changed */
+ /* Only set baud rate if it's changed */
if (p_priv->old_baud != p_priv->baud) {
p_priv->old_baud = p_priv->baud;
msg.setClocking = 0x01;
if (d_details->calculate_baud_rate
(p_priv->baud, d_details->baudclk, &msg.baudHi,
- &msg.baudLo, &prescaler, 0) == KEYSPAN_INVALID_BAUD_RATE ) {
- dbg("%s - Invalid baud rate %d requested, using 9600.", __func__,
- p_priv->baud);
+ &msg.baudLo, &prescaler, 0) == KEYSPAN_INVALID_BAUD_RATE) {
+ dbg("%s - Invalid baud rate %d requested, using 9600.",
+ __func__, p_priv->baud);
p_priv->baud = 9600;
- d_details->calculate_baud_rate (p_priv->baud, d_details->baudclk,
+ d_details->calculate_baud_rate(p_priv->baud, d_details->baudclk,
&msg.baudHi, &msg.baudLo, &prescaler, 0);
}
msg.setRxMode = 1;
}
/* modes must always be correctly specified */
- if (p_priv->baud > 57600)
- {
+ if (p_priv->baud > 57600) {
msg.rxMode = RXMODE_DMA;
msg.txMode = TXMODE_DMA;
- }
- else
- {
+ } else {
msg.rxMode = RXMODE_BYHAND;
msg.txMode = TXMODE_BYHAND;
}
if (p_priv->cflag & PARENB) {
/* note USA_PARITY_NONE == 0 */
msg.lcr |= (p_priv->cflag & PARODD)?
- USA_PARITY_ODD: USA_PARITY_EVEN;
+ USA_PARITY_ODD : USA_PARITY_EVEN;
}
if (p_priv->old_cflag != p_priv->cflag) {
p_priv->old_cflag = p_priv->cflag;
msg.txFlowControl = TXFLOW_CTS;
msg.setTxFlowControl = 0x01;
msg.setRxFlowControl = 0x01;
-
+
msg.rxForwardingLength = 16;
- msg.rxForwardingTimeout = 16;
+ msg.rxForwardingTimeout = 16;
msg.txAckSetting = 0;
msg.xonChar = 17;
msg.xoffChar = 19;
- /* Opening port */
+ /* Opening port */
if (reset_port == 1) {
msg.portEnabled = 1;
msg.rxFlush = 1;
msg.txBreak = (p_priv->break_on);
}
/* Closing port */
- else if (reset_port == 2) {
+ else if (reset_port == 2)
msg.portEnabled = 0;
- }
/* Sending intermediate configs */
else {
- if (port->open_count)
+ if (port->port.count)
msg.portEnabled = 1;
msg.txBreak = (p_priv->break_on);
}
- /* Do handshaking outputs */
+ /* Do handshaking outputs */
msg.setRts = 0x01;
msg.rts = p_priv->rts_state;
msg.setDtr = 0x01;
msg.dtr = p_priv->dtr_state;
-
+
p_priv->resend_cont = 0;
- memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
-
+ memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
+
/* send the data out the device on control endpoint */
this_urb->transfer_buffer_length = sizeof(msg);
this_urb->dev = serial->dev;
- if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+ err = usb_submit_urb(this_urb, GFP_ATOMIC);
+ if (err != 0)
dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err);
- }
return 0;
}
struct urb *this_urb;
int err, device_port;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
if ((reset_port + 1) > p_priv->resend_cont)
p_priv->resend_cont = reset_port + 1;
if (this_urb->status == -EINPROGRESS) {
- /* dbg ("%s - already writing", __func__); */
+ /* dbg("%s - already writing", __func__); */
mdelay(5);
- return(-1);
+ return -1;
}
memset(&msg, 0, sizeof(struct keyspan_usa67_portControlMessage));
msg.setClocking = 0xff;
if (d_details->calculate_baud_rate
(p_priv->baud, d_details->baudclk, &msg.baudHi,
- &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
- dbg("%s - Invalid baud rate %d requested, using 9600.", __func__,
- p_priv->baud);
+ &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE) {
+ dbg("%s - Invalid baud rate %d requested, using 9600.",
+ __func__, p_priv->baud);
msg.baudLo = 0;
msg.baudHi = 125; /* Values for 9600 baud */
msg.prescaler = 10;
if (p_priv->cflag & PARENB) {
/* note USA_PARITY_NONE == 0 */
msg.lcr |= (p_priv->cflag & PARODD)?
- USA_PARITY_ODD: USA_PARITY_EVEN;
+ USA_PARITY_ODD : USA_PARITY_EVEN;
}
msg.setLcr = 0xff;
msg.resetDataToggle = 0;
} else {
/* Sending intermediate configs */
- msg._txOn = (! p_priv->break_on);
+ msg._txOn = (!p_priv->break_on);
msg._txOff = 0;
msg.txFlush = 0;
msg.txBreak = (p_priv->break_on);
struct keyspan_serial_private *s_priv;
const struct keyspan_device_details *d_details;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
s_priv = usb_get_serial_data(serial);
d_details = s_priv->device_details;
/* Gets called by the "real" driver (ie once firmware is loaded
and renumeration has taken place. */
-static int keyspan_startup (struct usb_serial *serial)
+static int keyspan_startup(struct usb_serial *serial)
{
int i, err;
struct usb_serial_port *port;
dbg("%s", __func__);
for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
- if (d_details->product_id == le16_to_cpu(serial->dev->descriptor.idProduct))
+ if (d_details->product_id ==
+ le16_to_cpu(serial->dev->descriptor.idProduct))
break;
if (d_details == NULL) {
- dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __func__, le16_to_cpu(serial->dev->descriptor.idProduct));
+ dev_err(&serial->dev->dev, "%s - unknown product id %x\n",
+ __func__, le16_to_cpu(serial->dev->descriptor.idProduct));
return 1;
}
/* Setup private data for serial driver */
s_priv = kzalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL);
if (!s_priv) {
- dbg("%s - kmalloc for keyspan_serial_private failed.", __func__);
+ dbg("%s - kmalloc for keyspan_serial_private failed.",
+ __func__);
return -ENOMEM;
}
/* Now setup per port private data */
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
- p_priv = kzalloc(sizeof(struct keyspan_port_private), GFP_KERNEL);
+ p_priv = kzalloc(sizeof(struct keyspan_port_private),
+ GFP_KERNEL);
if (!p_priv) {
dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __func__, i);
- return (1);
+ return 1;
}
p_priv->device_details = d_details;
usb_set_serial_port_data(port, p_priv);
dbg("%s - submit indat urb failed %d", __func__,
err);
}
-
+
return 0;
}
-static void keyspan_shutdown (struct usb_serial *serial)
+static void keyspan_shutdown(struct usb_serial *serial)
{
int i, j;
struct usb_serial_port *port;
}
}
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("keyspan/usa28.fw");
/* Function prototypes for Keyspan serial converter */
-static int keyspan_open (struct usb_serial_port *port,
+static int keyspan_open (struct tty_struct *tty,
+ struct usb_serial_port *port,
struct file *filp);
-static void keyspan_close (struct usb_serial_port *port,
+static void keyspan_close (struct tty_struct *tty,
+ struct usb_serial_port *port,
struct file *filp);
static int keyspan_startup (struct usb_serial *serial);
static void keyspan_shutdown (struct usb_serial *serial);
-static void keyspan_rx_throttle (struct usb_serial_port *port);
-static void keyspan_rx_unthrottle (struct usb_serial_port *port);
-static int keyspan_write_room (struct usb_serial_port *port);
+static int keyspan_write_room (struct tty_struct *tty);
-static int keyspan_write (struct usb_serial_port *port,
+static int keyspan_write (struct tty_struct *tty,
+ struct usb_serial_port *port,
const unsigned char *buf,
int count);
int reset_port);
-static int keyspan_chars_in_buffer (struct usb_serial_port *port);
-static int keyspan_ioctl (struct usb_serial_port *port,
- struct file *file,
- unsigned int cmd,
- unsigned long arg);
-static void keyspan_set_termios (struct usb_serial_port *port,
+static void keyspan_set_termios (struct tty_struct *tty,
+ struct usb_serial_port *port,
struct ktermios *old);
-static void keyspan_break_ctl (struct usb_serial_port *port,
+static void keyspan_break_ctl (struct tty_struct *tty,
int break_state);
-static int keyspan_tiocmget (struct usb_serial_port *port,
+static int keyspan_tiocmget (struct tty_struct *tty,
struct file *file);
-static int keyspan_tiocmset (struct usb_serial_port *port,
+static int keyspan_tiocmset (struct tty_struct *tty,
struct file *file, unsigned int set,
unsigned int clear);
static int keyspan_fake_startup (struct usb_serial *serial);
.close = keyspan_close,
.write = keyspan_write,
.write_room = keyspan_write_room,
- .chars_in_buffer = keyspan_chars_in_buffer,
- .throttle = keyspan_rx_throttle,
- .unthrottle = keyspan_rx_unthrottle,
- .ioctl = keyspan_ioctl,
.set_termios = keyspan_set_termios,
.break_ctl = keyspan_break_ctl,
.tiocmget = keyspan_tiocmget,
.close = keyspan_close,
.write = keyspan_write,
.write_room = keyspan_write_room,
- .chars_in_buffer = keyspan_chars_in_buffer,
- .throttle = keyspan_rx_throttle,
- .unthrottle = keyspan_rx_unthrottle,
- .ioctl = keyspan_ioctl,
.set_termios = keyspan_set_termios,
.break_ctl = keyspan_break_ctl,
.tiocmget = keyspan_tiocmget,
.close = keyspan_close,
.write = keyspan_write,
.write_room = keyspan_write_room,
- .chars_in_buffer = keyspan_chars_in_buffer,
- .throttle = keyspan_rx_throttle,
- .unthrottle = keyspan_rx_unthrottle,
- .ioctl = keyspan_ioctl,
.set_termios = keyspan_set_termios,
.break_ctl = keyspan_break_ctl,
.tiocmget = keyspan_tiocmget,
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
- *
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
+ *
* (09/07/2001) gkh
* cleaned up the Xircom support. Added ids for Entregra device which is
* the same as the Xircom device. Enabled the code to be compiled for
* support for Xircom PGSDB9
*
* (05/31/2001) gkh
- * switched from using spinlock to a semaphore, which fixes lots of problems.
+ * switched from using spinlock to a semaphore, which fixes lots of
+ * problems.
*
* (04/08/2001) gb
* Identify version on module load.
- *
+ *
* (11/01/2000) Adam J. Richter
* usb_device_id table support
- *
+ *
* (10/05/2000) gkh
* Fixed bug with urb->dev not being set properly, now that the usb
* core needs it.
- *
+ *
* (08/28/2000) gkh
* Added locks for SMP safeness.
- * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
+ * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
* than once.
- *
+ *
* (07/20/2000) borchers
* - keyspan_pda_write no longer sleeps if it is called on interrupt time;
* PPP and the line discipline with stty echo on can call write on
* than done directly from the callback to avoid the race in write_chan
* - keyspan_pda_chars_in_buffer also indicates its buffer is full if the
* urb status is -EINPROGRESS, meaning it cannot write at the moment
- *
+ *
* (07/19/2000) gkh
* Added module_init and module_exit functions to handle the fact that this
* driver is a loadable module now.
*
* (03/26/2000) gkh
* Split driver up into device specific pieces.
- *
+ *
*/
#include <linux/workqueue.h>
#include <linux/firmware.h>
#include <linux/ihex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver keyspan_pda_driver = {
.name = "keyspan_pda",
#ifdef XIRCOM
static struct usb_device_id id_table_fake_xircom [] = {
- { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
- { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
- { }
+ { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
+ { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
+ { }
};
#endif
container_of(work, struct keyspan_pda_private, wakeup_work);
struct usb_serial_port *port = priv->port;
- tty_wakeup(port->tty);
+ tty_wakeup(port->port.tty);
}
static void keyspan_pda_request_unthrottle(struct work_struct *work)
dbg(" request_unthrottle");
/* ask the device to tell us when the tx buffer becomes
sufficiently empty */
- result = usb_control_msg(serial->dev,
+ result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
7, /* request_unthrottle */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE
0,
2000);
if (result < 0)
- dbg("%s - error %d from usb_control_msg",
+ dbg("%s - error %d from usb_control_msg",
__func__, result);
}
-static void keyspan_pda_rx_interrupt (struct urb *urb)
+static void keyspan_pda_rx_interrupt(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
unsigned char *data = urb->transfer_buffer;
- int i;
int retval;
int status = urb->status;
struct keyspan_pda_private *priv;
goto exit;
}
- /* see if the message is data or a status interrupt */
+ /* see if the message is data or a status interrupt */
switch (data[0]) {
case 0:
/* rest of message is rx data */
if (urb->actual_length) {
- for (i = 1; i < urb->actual_length ; ++i) {
- tty_insert_flip_char(tty, data[i], 0);
- }
+ tty_insert_flip_string(tty, data + 1,
+ urb->actual_length - 1);
tty_flip_buffer_push(tty);
}
break;
}
exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
- err ("%s - usb_submit_urb failed with result %d",
+ err("%s - usb_submit_urb failed with result %d",
__func__, retval);
}
-static void keyspan_pda_rx_throttle (struct usb_serial_port *port)
+static void keyspan_pda_rx_throttle(struct tty_struct *tty)
{
/* stop receiving characters. We just turn off the URB request, and
let chars pile up in the device. If we're doing hardware
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. */
-
+ struct usb_serial_port *port = tty->driver_data;
dbg("keyspan_pda_rx_throttle port %d", port->number);
usb_kill_urb(port->interrupt_in_urb);
}
-static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port)
+static void keyspan_pda_rx_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
/* just restart the receive interrupt URB */
dbg("keyspan_pda_rx_unthrottle port %d", port->number);
port->interrupt_in_urb->dev = port->serial->dev;
}
-static speed_t keyspan_pda_setbaud (struct usb_serial *serial, speed_t baud)
+static speed_t keyspan_pda_setbaud(struct usb_serial *serial, speed_t baud)
{
int rc;
int bindex;
- 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;
+ 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;
}
/* 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 */
- USB_TYPE_VENDOR
+ USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
| USB_DIR_OUT, /* type */
bindex, /* value */
}
-static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state)
+static void keyspan_pda_break_ctl(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
int value;
int result;
else
value = 0; /* clear break */
result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- 4, /* set break */
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- value, 0, NULL, 0, 2000);
+ 4, /* set break */
+ USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ value, 0, NULL, 0, 2000);
if (result < 0)
- dbg("%s - error %d from usb_control_msg",
+ dbg("%s - error %d from usb_control_msg",
__func__, result);
/* 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
}
-static void keyspan_pda_set_termios (struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void keyspan_pda_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
speed_t speed;
For now, just do baud. */
- speed = tty_get_baud_rate(port->tty);
+ speed = tty_get_baud_rate(tty);
speed = keyspan_pda_setbaud(serial, speed);
if (speed == 0) {
}
/* Only speed can change so copy the old h/w parameters
then encode the new speed */
- tty_termios_copy_hw(port->tty->termios, old_termios);
- tty_encode_baud_rate(port->tty, speed, speed);
+ tty_termios_copy_hw(tty->termios, old_termios);
+ tty_encode_baud_rate(tty, speed, speed);
}
return rc;
}
-static int keyspan_pda_tiocmget(struct usb_serial_port *port, struct file *file)
+static int keyspan_pda_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
int rc;
unsigned char status;
return value;
}
-static int keyspan_pda_tiocmset(struct usb_serial_port *port, struct file *file,
+static int keyspan_pda_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
int rc;
unsigned char status;
return rc;
}
-static int keyspan_pda_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
- case TIOCMIWAIT:
- /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
- /* TODO */
- case TIOCGICOUNT:
- /* return count of modemline transitions */
- return 0; /* TODO */
- }
-
- return -ENOIOCTLCMD;
-}
-
-static int keyspan_pda_write(struct usb_serial_port *port,
- const unsigned char *buf, int count)
+static int keyspan_pda_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct usb_serial *serial = port->serial;
int request_unthrottle = 0;
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. */
- dbg("keyspan_pda_write(%d)",count);
+ dbg("keyspan_pda_write(%d)", count);
if (count == 0) {
dbg(" write request of 0 bytes");
- return (0);
+ return 0;
}
/* we might block because of:
scheduler time, since usb_control_msg() sleeps. */
if (count > priv->tx_room && !in_interrupt()) {
unsigned char room;
- rc = usb_control_msg(serial->dev,
+ rc = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
6, /* write_room */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE
if (count) {
/* now transfer data */
- memcpy (port->write_urb->transfer_buffer, buf, count);
+ memcpy(port->write_urb->transfer_buffer, buf, count);
/* send the data out the bulk port */
port->write_urb->transfer_buffer_length = count;
dbg(" usb_submit_urb(write bulk) failed");
goto exit;
}
- }
- else {
+ } else {
/* There wasn't any room left, so we are throttled until
the buffer empties a bit */
request_unthrottle = 1;
}
-static void keyspan_pda_write_bulk_callback (struct urb *urb)
+static void keyspan_pda_write_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct keyspan_pda_private *priv;
}
-static int keyspan_pda_write_room (struct usb_serial_port *port)
+static int keyspan_pda_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
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. */
-
- return (priv->tx_room);
+ return priv->tx_room;
}
-static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
+static int keyspan_pda_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct keyspan_pda_private *priv;
unsigned long flags;
int ret = 0;
}
-static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
+static int keyspan_pda_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
unsigned char room;
/* the normal serial device seems to always turn on DTR and RTS here,
so do the same */
- if (port->tty->termios->c_cflag & CBAUD)
- keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2) );
+ if (tty && (tty->termios->c_cflag & CBAUD))
+ keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2));
else
keyspan_pda_set_modem_info(serial, 0);
}
-static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
+static void keyspan_pda_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
if (serial->dev) {
- /* the normal serial device seems to always shut off DTR and RTS now */
- if (port->tty->termios->c_cflag & HUPCL)
+ /* the normal serial device seems to always shut
+ off DTR and RTS now */
+ if (tty->termios->c_cflag & HUPCL)
keyspan_pda_set_modem_info(serial, 0);
/* shutdown our bulk reads and writes */
/* download the firmware to a "fake" device (pre-renumeration) */
-static int keyspan_pda_fake_startup (struct usb_serial *serial)
+static int keyspan_pda_fake_startup(struct usb_serial *serial)
{
int response;
const char *fw_name;
response = ezusb_set_reset(serial, 0);
/* we want this device to fail to have a driver assigned to it. */
- return (1);
+ return 1;
}
-static int keyspan_pda_startup (struct usb_serial *serial)
+static int keyspan_pda_startup(struct usb_serial *serial)
{
struct keyspan_pda_private *priv;
priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL);
if (!priv)
- return (1); /* error */
+ return 1; /* error */
usb_set_serial_port_data(serial->port[0], priv);
init_waitqueue_head(&serial->port[0]->write_wait);
INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write);
INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
priv->serial = serial;
priv->port = serial->port[0];
- return (0);
+ return 0;
}
-static void keyspan_pda_shutdown (struct usb_serial *serial)
+static void keyspan_pda_shutdown(struct usb_serial *serial)
{
dbg("%s", __func__);
-
+
kfree(usb_get_serial_port_data(serial->port[0]));
}
.chars_in_buffer = keyspan_pda_chars_in_buffer,
.throttle = keyspan_pda_rx_throttle,
.unthrottle = keyspan_pda_rx_unthrottle,
- .ioctl = keyspan_pda_ioctl,
.set_termios = keyspan_pda_set_termios,
.break_ctl = keyspan_pda_break_ctl,
.tiocmget = keyspan_pda_tiocmget,
};
-static int __init keyspan_pda_init (void)
+static int __init keyspan_pda_init(void)
{
int retval;
retval = usb_serial_register(&keyspan_pda_device);
goto failed_usb_register;
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
-failed_usb_register:
+failed_usb_register:
#ifdef XIRCOM
usb_serial_deregister(&xircom_pgs_fake_device);
failed_xircom_register:
}
-static void __exit keyspan_pda_exit (void)
+static void __exit keyspan_pda_exit(void)
{
- usb_deregister (&keyspan_pda_driver);
- usb_serial_deregister (&keyspan_pda_device);
+ usb_deregister(&keyspan_pda_driver);
+ usb_serial_deregister(&keyspan_pda_device);
#ifdef KEYSPAN
- usb_serial_deregister (&keyspan_pda_fake_device);
+ usb_serial_deregister(&keyspan_pda_fake_device);
#endif
#ifdef XIRCOM
- usb_serial_deregister (&xircom_pgs_fake_device);
+ usb_serial_deregister(&xircom_pgs_fake_device);
#endif
}
module_init(keyspan_pda_init);
module_exit(keyspan_pda_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
* Neither Palm, nor their contractor (MCCI) or their supplier (KLSI) provided
* information that was not already available.
*
- * It seems that KLSI bought some silicon-design information from ScanLogic,
+ * It seems that KLSI bought some silicon-design information from ScanLogic,
* whose SL11R processor is at the core of the KL5KUSB chipset from KLSI.
* KLSI has firmware available for their devices; it is probable that the
* firmware differs from that used by KLSI in their products. If you have an
- * original KLSI device and can provide some information on it, I would be
- * most interested in adding support for it here. If you have any information
+ * original KLSI device and can provide some information on it, I would be
+ * most interested in adding support for it here. If you have any information
* on the protocol used (or find errors in my reverse-engineered stuff), please
* let me know.
*
* 0.2 - TIOCMGET works, so autopilot(1) can be used!
* 0.1 - can be used to to pilot-xfer -p /dev/ttyUSB0 -l
*
- * The driver skeleton is mainly based on mct_u232.c and various other
+ * The driver skeleton is mainly based on mct_u232.c and various other
* pieces of code shamelessly copied from the drivers/usb/serial/ directory.
*/
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
/*
* Function prototypes
*/
-static int klsi_105_startup (struct usb_serial *serial);
-static void klsi_105_shutdown (struct usb_serial *serial);
-static int klsi_105_open (struct usb_serial_port *port,
- struct file *filp);
-static void klsi_105_close (struct usb_serial_port *port,
- struct file *filp);
-static int klsi_105_write (struct usb_serial_port *port,
- const unsigned char *buf,
- int count);
-static void klsi_105_write_bulk_callback (struct urb *urb);
-static int klsi_105_chars_in_buffer (struct usb_serial_port *port);
-static int klsi_105_write_room (struct usb_serial_port *port);
-
-static void klsi_105_read_bulk_callback (struct urb *urb);
-static void klsi_105_set_termios (struct usb_serial_port *port,
- struct ktermios *old);
-static void klsi_105_throttle (struct usb_serial_port *port);
-static void klsi_105_unthrottle (struct usb_serial_port *port);
-/*
-static void klsi_105_break_ctl (struct usb_serial_port *port,
- int break_state );
- */
-static int klsi_105_tiocmget (struct usb_serial_port *port,
- struct file *file);
-static int klsi_105_tiocmset (struct usb_serial_port *port,
- struct file *file, unsigned int set,
- unsigned int clear);
+static int klsi_105_startup(struct usb_serial *serial);
+static void klsi_105_shutdown(struct usb_serial *serial);
+static int klsi_105_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void klsi_105_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static int klsi_105_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count);
+static void klsi_105_write_bulk_callback(struct urb *urb);
+static int klsi_105_chars_in_buffer(struct tty_struct *tty);
+static int klsi_105_write_room(struct tty_struct *tty);
+static void klsi_105_read_bulk_callback(struct urb *urb);
+static void klsi_105_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
+static void klsi_105_throttle(struct tty_struct *tty);
+static void klsi_105_unthrottle(struct tty_struct *tty);
+static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file);
+static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
/*
* All of the device info needed for the KLSI converters.
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver kl5kusb105d_driver = {
.name = "kl5kusb105d",
.write_bulk_callback = klsi_105_write_bulk_callback,
.chars_in_buffer = klsi_105_chars_in_buffer,
.write_room = klsi_105_write_room,
- .read_bulk_callback =klsi_105_read_bulk_callback,
+ .read_bulk_callback = klsi_105_read_bulk_callback,
.set_termios = klsi_105_set_termios,
/*.break_ctl = klsi_105_break_ctl,*/
.tiocmget = klsi_105_tiocmget,
struct ktermios termios;
unsigned long line_state; /* modem line settings */
/* write pool */
- struct urb * write_urb_pool[NUM_URBS];
+ struct urb *write_urb_pool[NUM_URBS];
spinlock_t lock;
unsigned long bytes_in;
unsigned long bytes_out;
{
int rc;
- rc = usb_control_msg(port->serial->dev,
- usb_sndctrlpipe(port->serial->dev, 0),
- KL5KUSB105A_SIO_SET_DATA,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_INTERFACE,
- 0, /* value */
- 0, /* index */
- settings,
- sizeof(struct klsi_105_port_settings),
- KLSI_TIMEOUT);
+ rc = usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ KL5KUSB105A_SIO_SET_DATA,
+ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_INTERFACE,
+ 0, /* value */
+ 0, /* index */
+ settings,
+ sizeof(struct klsi_105_port_settings),
+ KLSI_TIMEOUT);
if (rc < 0)
err("Change port settings failed (error = %d)", rc);
info("%s - %d byte block, baudrate %x, databits %d, u1 %d, u2 %d",
settings->pktlen,
settings->baudrate, settings->databits,
settings->unknown1, settings->unknown2);
- return rc;
+ return rc;
} /* klsi_105_chg_port_settings */
/* translate a 16-bit status value from the device to linux's TIO bits */
return res;
}
-/*
+/*
* Read line control via vendor command and return result through
- * *line_state_p
+ * *line_state_p
*/
/* It seems that the status buffer has always only 2 bytes length */
#define KLSI_STATUSBUF_LEN 2
unsigned long *line_state_p)
{
int rc;
- __u8 status_buf[KLSI_STATUSBUF_LEN] = { -1,-1};
+ __u8 status_buf[KLSI_STATUSBUF_LEN] = { -1, -1};
__u16 status;
info("%s - sending SIO Poll request", __func__);
- rc = usb_control_msg(port->serial->dev,
+ rc = usb_control_msg(port->serial->dev,
usb_rcvctrlpipe(port->serial->dev, 0),
KL5KUSB105A_SIO_POLL,
- USB_TYPE_VENDOR | USB_DIR_IN,
+ USB_TYPE_VENDOR | USB_DIR_IN,
0, /* value */
0, /* index */
status_buf, KLSI_STATUSBUF_LEN,
*line_state_p = klsi_105_status2linestate(status);
}
-
- return rc;
+ return rc;
}
* Driver's tty interface functions
*/
-static int klsi_105_startup (struct usb_serial *serial)
+static int klsi_105_startup(struct usb_serial *serial)
{
struct klsi_105_private *priv;
int i, j;
*/
/* allocate the private data structure */
- for (i=0; i<serial->num_ports; i++) {
+ for (i = 0; i < serial->num_ports; i++) {
priv = kmalloc(sizeof(struct klsi_105_private),
GFP_KERNEL);
if (!priv) {
priv->bytes_out = 0;
usb_set_serial_port_data(serial->port[i], priv);
- spin_lock_init (&priv->lock);
- for (j=0; j<NUM_URBS; j++) {
- struct urb* urb = usb_alloc_urb(0, GFP_KERNEL);
+ spin_lock_init(&priv->lock);
+ for (j = 0; j < NUM_URBS; j++) {
+ struct urb *urb = usb_alloc_urb(0, GFP_KERNEL);
priv->write_urb_pool[j] = urb;
if (urb == NULL) {
goto err_cleanup;
}
- urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE,
- GFP_KERNEL);
+ urb->transfer_buffer =
+ kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
if (!urb->transfer_buffer) {
- err("%s - out of memory for urb buffers.", __func__);
+ err("%s - out of memory for urb buffers.",
+ __func__);
goto err_cleanup;
}
}
/* priv->termios is left uninitalized until port opening */
init_waitqueue_head(&serial->port[i]->write_wait);
}
-
+
return 0;
err_cleanup:
for (; i >= 0; i--) {
priv = usb_get_serial_port_data(serial->port[i]);
- for (j=0; j < NUM_URBS; j++) {
+ for (j = 0; j < NUM_URBS; j++) {
if (priv->write_urb_pool[j]) {
kfree(priv->write_urb_pool[j]->transfer_buffer);
usb_free_urb(priv->write_urb_pool[j]);
} /* klsi_105_startup */
-static void klsi_105_shutdown (struct usb_serial *serial)
+static void klsi_105_shutdown(struct usb_serial *serial)
{
int i;
-
+
dbg("%s", __func__);
/* stop reads and writes on all ports */
- for (i=0; i < serial->num_ports; ++i) {
- struct klsi_105_private *priv = usb_get_serial_port_data(serial->port[i]);
+ for (i = 0; i < serial->num_ports; ++i) {
+ struct klsi_105_private *priv =
+ usb_get_serial_port_data(serial->port[i]);
unsigned long flags;
if (priv) {
/* kill our write urb pool */
int j;
struct urb **write_urbs = priv->write_urb_pool;
- spin_lock_irqsave(&priv->lock,flags);
+ spin_lock_irqsave(&priv->lock, flags);
for (j = 0; j < NUM_URBS; j++) {
if (write_urbs[j]) {
* oopses. */
/* usb_kill_urb(write_urbs[j]); */
kfree(write_urbs[j]->transfer_buffer);
- usb_free_urb (write_urbs[j]);
+ usb_free_urb(write_urbs[j]);
}
}
-
- spin_unlock_irqrestore (&priv->lock, flags);
-
+ spin_unlock_irqrestore(&priv->lock, flags);
kfree(priv);
usb_set_serial_port_data(serial->port[i], NULL);
}
}
} /* klsi_105_shutdown */
-static int klsi_105_open (struct usb_serial_port *port, struct file *filp)
+static int klsi_105_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct klsi_105_private *priv = usb_get_serial_port_data(port);
int retval = 0;
/* force low_latency on so that our tty_push actually forces
* the data through
- * port->tty->low_latency = 1; */
+ * tty->low_latency = 1; */
/* Do a defined restart:
* Set up sane default baud rate and send the 'READ_ON'
- * vendor command.
+ * vendor command.
* FIXME: set modem line control (how?)
* Then read the modem line control and store values in
* priv->line_state.
cfg.unknown1 = 0;
cfg.unknown2 = 1;
klsi_105_chg_port_settings(port, &cfg);
-
+
/* set up termios structure */
- spin_lock_irqsave (&priv->lock, flags);
- priv->termios.c_iflag = port->tty->termios->c_iflag;
- priv->termios.c_oflag = port->tty->termios->c_oflag;
- priv->termios.c_cflag = port->tty->termios->c_cflag;
- priv->termios.c_lflag = port->tty->termios->c_lflag;
- for (i=0; i<NCCS; i++)
- priv->termios.c_cc[i] = port->tty->termios->c_cc[i];
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->termios.c_iflag = tty->termios->c_iflag;
+ priv->termios.c_oflag = tty->termios->c_oflag;
+ priv->termios.c_cflag = tty->termios->c_cflag;
+ priv->termios.c_lflag = tty->termios->c_lflag;
+ for (i = 0; i < NCCS; i++)
+ priv->termios.c_cc[i] = tty->termios->c_cc[i];
priv->cfg.pktlen = cfg.pktlen;
priv->cfg.baudrate = cfg.baudrate;
priv->cfg.databits = cfg.databits;
priv->cfg.unknown1 = cfg.unknown1;
priv->cfg.unknown2 = cfg.unknown2;
- spin_unlock_irqrestore (&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
/* READ_ON and urb submission */
- usb_fill_bulk_urb(port->read_urb, port->serial->dev,
+ usb_fill_bulk_urb(port->read_urb, port->serial->dev,
usb_rcvbulkpipe(port->serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
}
rc = usb_control_msg(port->serial->dev,
- usb_sndctrlpipe(port->serial->dev,0),
+ usb_sndctrlpipe(port->serial->dev, 0),
KL5KUSB105A_SIO_CONFIGURE,
USB_TYPE_VENDOR|USB_DIR_OUT|USB_RECIP_INTERFACE,
KL5KUSB105A_SIO_CONFIGURE_READ_ON,
if (rc < 0) {
err("Enabling read failed (error = %d)", rc);
retval = rc;
- } else
+ } else
dbg("%s - enabled reading", __func__);
rc = klsi_105_get_line_state(port, &line_state);
if (rc >= 0) {
- spin_lock_irqsave (&priv->lock, flags);
+ spin_lock_irqsave(&priv->lock, flags);
priv->line_state = line_state;
- spin_unlock_irqrestore (&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
dbg("%s - read line state 0x%lx", __func__, line_state);
retval = 0;
} else
} /* klsi_105_open */
-static void klsi_105_close (struct usb_serial_port *port, struct file *filp)
+static void klsi_105_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct klsi_105_private *priv = usb_get_serial_port_data(port);
int rc;
mutex_lock(&port->serial->disc_mutex);
if (!port->serial->disconnected) {
/* send READ_OFF */
- rc = usb_control_msg (port->serial->dev,
- usb_sndctrlpipe(port->serial->dev, 0),
- KL5KUSB105A_SIO_CONFIGURE,
- USB_TYPE_VENDOR | USB_DIR_OUT,
- KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
- 0, /* index */
- NULL, 0,
- KLSI_TIMEOUT);
+ rc = usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ KL5KUSB105A_SIO_CONFIGURE,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
+ 0, /* index */
+ NULL, 0,
+ KLSI_TIMEOUT);
if (rc < 0)
err("Disabling read failed (error = %d)", rc);
}
/* FIXME */
/* wgg - do I need this? I think so. */
usb_kill_urb(port->interrupt_in_urb);
- info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", priv->bytes_in, priv->bytes_out);
+ info("kl5kusb105 port stats: %ld bytes in, %ld bytes out",
+ priv->bytes_in, priv->bytes_out);
} /* klsi_105_close */
/* We need to write a complete 64-byte data block and encode the
- * number actually sent in the first double-byte, LSB-order. That
+ * number actually sent in the first double-byte, LSB-order. That
* leaves at most 62 bytes of payload.
*/
#define KLSI_105_DATA_OFFSET 2 /* in the bulk urb data block */
-static int klsi_105_write (struct usb_serial_port *port,
- const unsigned char *buf, int count)
+static int klsi_105_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct klsi_105_private *priv = usb_get_serial_port_data(port);
int result, size;
- int bytes_sent=0;
+ int bytes_sent = 0;
dbg("%s - port %d", __func__, port->number);
struct urb *urb = NULL;
unsigned long flags;
int i;
- /* since the pool is per-port we might not need the spin lock !? */
- spin_lock_irqsave (&priv->lock, flags);
- for (i=0; i<NUM_URBS; i++) {
+ /* since the pool is per-port we might not need
+ the spin lock !? */
+ spin_lock_irqsave(&priv->lock, flags);
+ for (i = 0; i < NUM_URBS; i++) {
if (priv->write_urb_pool[i]->status != -EINPROGRESS) {
urb = priv->write_urb_pool[i];
dbg("%s - using pool URB %d", __func__, i);
break;
}
}
- spin_unlock_irqrestore (&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
- if (urb==NULL) {
+ if (urb == NULL) {
dbg("%s - no more free urbs", __func__);
goto exit;
}
if (urb->transfer_buffer == NULL) {
- urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
+ urb->transfer_buffer =
+ kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
if (urb->transfer_buffer == NULL) {
err("%s - no more kernel memory...", __func__);
goto exit;
}
}
- size = min (count, port->bulk_out_size - KLSI_105_DATA_OFFSET);
- size = min (size, URB_TRANSFER_BUFFER_SIZE - KLSI_105_DATA_OFFSET);
+ size = min(count, port->bulk_out_size - KLSI_105_DATA_OFFSET);
+ size = min(size, URB_TRANSFER_BUFFER_SIZE -
+ KLSI_105_DATA_OFFSET);
- memcpy (urb->transfer_buffer + KLSI_105_DATA_OFFSET, buf, size);
+ memcpy(urb->transfer_buffer + KLSI_105_DATA_OFFSET, buf, size);
/* write payload size into transfer buffer */
((__u8 *)urb->transfer_buffer)[0] = (__u8) (size & 0xFF);
/* send the data out the bulk port */
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result) {
- err("%s - failed submitting write urb, error %d", __func__, result);
+ err("%s - failed submitting write urb, error %d",
+ __func__, result);
goto exit;
}
buf += size;
}
exit:
/* lockless, but it's for debug info only... */
- priv->bytes_out+=bytes_sent;
+ priv->bytes_out += bytes_sent;
return bytes_sent; /* that's how much we wrote */
} /* klsi_105_write */
-static void klsi_105_write_bulk_callback ( struct urb *urb)
+static void klsi_105_write_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
int status = urb->status;
/* return number of characters currently in the writing process */
-static int klsi_105_chars_in_buffer (struct usb_serial_port *port)
+static int klsi_105_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
int chars = 0;
int i;
unsigned long flags;
struct klsi_105_private *priv = usb_get_serial_port_data(port);
- spin_lock_irqsave (&priv->lock, flags);
+ spin_lock_irqsave(&priv->lock, flags);
for (i = 0; i < NUM_URBS; ++i) {
- if (priv->write_urb_pool[i]->status == -EINPROGRESS) {
+ if (priv->write_urb_pool[i]->status == -EINPROGRESS)
chars += URB_TRANSFER_BUFFER_SIZE;
- }
}
- spin_unlock_irqrestore (&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
dbg("%s - returns %d", __func__, chars);
- return (chars);
+ return chars;
}
-static int klsi_105_write_room (struct usb_serial_port *port)
+static int klsi_105_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned long flags;
int i;
int room = 0;
struct klsi_105_private *priv = usb_get_serial_port_data(port);
- spin_lock_irqsave (&priv->lock, flags);
+ spin_lock_irqsave(&priv->lock, flags);
for (i = 0; i < NUM_URBS; ++i) {
- if (priv->write_urb_pool[i]->status != -EINPROGRESS) {
+ if (priv->write_urb_pool[i]->status != -EINPROGRESS)
room += URB_TRANSFER_BUFFER_SIZE;
- }
}
- spin_unlock_irqrestore (&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
dbg("%s - returns %d", __func__, room);
- return (room);
+ return room;
}
-static void klsi_105_read_bulk_callback (struct urb *urb)
+static void klsi_105_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct klsi_105_private *priv = usb_get_serial_port_data(port);
} else {
int bytes_sent = ((__u8 *) data)[0] +
((unsigned int) ((__u8 *) data)[1] << 8);
- tty = port->tty;
+ tty = port->port.tty;
/* we should immediately resubmit the URB, before attempting
* to pass the data on to the tty layer. But that needs locking
* against re-entry an then mixed-up data because of
* intermixed tty_flip_buffer_push()s
* FIXME
- */
+ */
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, data);
priv->bytes_in += bytes_sent;
}
/* Continue trying to always read */
- usb_fill_bulk_urb(port->read_urb, port->serial->dev,
+ usb_fill_bulk_urb(port->read_urb, port->serial->dev,
usb_rcvbulkpipe(port->serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port);
rc = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (rc)
- err("%s - failed resubmitting read urb, error %d", __func__, rc);
+ err("%s - failed resubmitting read urb, error %d",
+ __func__, rc);
} /* klsi_105_read_bulk_callback */
-static void klsi_105_set_termios (struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void klsi_105_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ struct ktermios *old_termios)
{
struct klsi_105_private *priv = usb_get_serial_port_data(port);
- struct tty_struct *tty = port->tty;
unsigned int iflag = tty->termios->c_iflag;
unsigned int old_iflag = old_termios->c_iflag;
unsigned int cflag = tty->termios->c_cflag;
struct klsi_105_port_settings cfg;
unsigned long flags;
speed_t baud;
-
+
/* lock while we are modifying the settings */
- spin_lock_irqsave (&priv->lock, flags);
-
+ spin_lock_irqsave(&priv->lock, flags);
+
/*
* Update baud rate
*/
baud = tty_get_baud_rate(tty);
- if( (cflag & CBAUD) != (old_cflag & CBAUD) ) {
- /* reassert DTR and (maybe) RTS on transition from B0 */
- if( (old_cflag & CBAUD) == B0 ) {
+ if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
+ /* reassert DTR and (maybe) RTS on transition from B0 */
+ if ((old_cflag & CBAUD) == B0) {
dbg("%s: baud was B0", __func__);
#if 0
priv->control_state |= TIOCM_DTR;
/* don't set RTS if using hardware flow control */
- if (!(old_cflag & CRTSCTS)) {
+ if (!(old_cflag & CRTSCTS))
priv->control_state |= TIOCM_RTS;
- }
mct_u232_set_modem_ctrl(serial, priv->control_state);
#endif
}
}
- switch(baud) {
- case 0: /* handled below */
- break;
- case 1200:
- priv->cfg.baudrate = kl5kusb105a_sio_b1200;
- break;
- case 2400:
- priv->cfg.baudrate = kl5kusb105a_sio_b2400;
- break;
- case 4800:
- priv->cfg.baudrate = kl5kusb105a_sio_b4800;
- break;
- case 9600:
- priv->cfg.baudrate = kl5kusb105a_sio_b9600;
- break;
- case 19200:
- priv->cfg.baudrate = kl5kusb105a_sio_b19200;
- break;
- case 38400:
- priv->cfg.baudrate = kl5kusb105a_sio_b38400;
- break;
- case 57600:
- priv->cfg.baudrate = kl5kusb105a_sio_b57600;
- break;
- case 115200:
- priv->cfg.baudrate = kl5kusb105a_sio_b115200;
- break;
- default:
- dbg("KLSI USB->Serial converter:"
- " unsupported baudrate request, using default"
- " of 9600");
+ switch (baud) {
+ case 0: /* handled below */
+ break;
+ case 1200:
+ priv->cfg.baudrate = kl5kusb105a_sio_b1200;
+ break;
+ case 2400:
+ priv->cfg.baudrate = kl5kusb105a_sio_b2400;
+ break;
+ case 4800:
+ priv->cfg.baudrate = kl5kusb105a_sio_b4800;
+ break;
+ case 9600:
+ priv->cfg.baudrate = kl5kusb105a_sio_b9600;
+ break;
+ case 19200:
+ priv->cfg.baudrate = kl5kusb105a_sio_b19200;
+ break;
+ case 38400:
+ priv->cfg.baudrate = kl5kusb105a_sio_b38400;
+ break;
+ case 57600:
+ priv->cfg.baudrate = kl5kusb105a_sio_b57600;
+ break;
+ case 115200:
+ priv->cfg.baudrate = kl5kusb105a_sio_b115200;
+ break;
+ default:
+ dbg("KLSI USB->Serial converter:"
+ " unsupported baudrate request, using default of 9600");
priv->cfg.baudrate = kl5kusb105a_sio_b9600;
- baud = 9600;
- break;
+ baud = 9600;
+ break;
}
- if ((cflag & CBAUD) == B0 ) {
+ if ((cflag & CBAUD) == B0) {
dbg("%s: baud is B0", __func__);
/* Drop RTS and DTR */
/* maybe this should be simulated by sending read
;
#if 0
priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
- mct_u232_set_modem_ctrl(serial, priv->control_state);
+ mct_u232_set_modem_ctrl(serial, priv->control_state);
#endif
}
tty_encode_baud_rate(tty, baud, baud);
switch (cflag & CSIZE) {
case CS5:
dbg("%s - 5 bits/byte not supported", __func__);
- spin_unlock_irqrestore (&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
return ;
case CS6:
dbg("%s - 6 bits/byte not supported", __func__);
- spin_unlock_irqrestore (&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
return ;
case CS7:
priv->cfg.databits = kl5kusb105a_dtb_7;
* Update line control register (LCR)
*/
if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))
- || (cflag & CSTOPB) != (old_cflag & CSTOPB) ) {
-
+ || (cflag & CSTOPB) != (old_cflag & CSTOPB)) {
/* Not currently supported */
tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB);
#if 0
#endif
;
}
-
/*
* Set flow control: well, I do not really now how to handle DTR/RTS.
* Just do what we have seen with SniffUSB on Win98.
*/
- if( (iflag & IXOFF) != (old_iflag & IXOFF)
+ if ((iflag & IXOFF) != (old_iflag & IXOFF)
|| (iflag & IXON) != (old_iflag & IXON)
- || (cflag & CRTSCTS) != (old_cflag & CRTSCTS) ) {
-
+ || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
/* Not currently supported */
tty->termios->c_cflag &= ~CRTSCTS;
/* Drop DTR/RTS if no flow control otherwise assert */
#if 0
- if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS) )
+ if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
priv->control_state |= TIOCM_DTR | TIOCM_RTS;
else
priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
#endif
;
}
- memcpy (&cfg, &priv->cfg, sizeof(cfg));
- spin_unlock_irqrestore (&priv->lock, flags);
-
+ memcpy(&cfg, &priv->cfg, sizeof(cfg));
+ spin_unlock_irqrestore(&priv->lock, flags);
+
/* now commit changes to device */
klsi_105_chg_port_settings(port, &cfg);
} /* klsi_105_set_termios */
#if 0
-static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
+static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
- struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
+ struct mct_u232_private *priv =
+ (struct mct_u232_private *)port->private;
unsigned char lcr = priv->last_lcr;
dbg("%sstate=%d", __func__, break_state);
} /* mct_u232_break_ctl */
#endif
-static int klsi_105_tiocmget (struct usb_serial_port *port, struct file *file)
+static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct klsi_105_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
int rc;
return rc;
}
- spin_lock_irqsave (&priv->lock, flags);
+ spin_lock_irqsave(&priv->lock, flags);
priv->line_state = line_state;
- spin_unlock_irqrestore (&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
dbg("%s - read line state 0x%lx", __func__, line_state);
return (int)line_state;
}
-static int klsi_105_tiocmset (struct usb_serial_port *port, struct file *file,
- unsigned int set, unsigned int clear)
+static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
{
int retval = -EINVAL;
-
+
dbg("%s", __func__);
/* if this ever gets implemented, it should be done something like this:
return retval;
}
-static void klsi_105_throttle (struct usb_serial_port *port)
+static void klsi_105_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __func__, port->number);
usb_kill_urb(port->read_urb);
}
-static void klsi_105_unthrottle (struct usb_serial_port *port)
+static void klsi_105_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
int result;
dbg("%s - port %d", __func__, port->number);
-static int __init klsi_105_init (void)
+static int __init klsi_105_init(void)
{
int retval;
retval = usb_serial_register(&kl5kusb105d_device);
}
-static void __exit klsi_105_exit (void)
+static void __exit klsi_105_exit(void)
{
- usb_deregister (&kl5kusb105d_driver);
- usb_serial_deregister (&kl5kusb105d_device);
+ usb_deregister(&kl5kusb105d_driver);
+ usb_serial_deregister(&kl5kusb105d_device);
}
-module_init (klsi_105_init);
-module_exit (klsi_105_exit);
+module_init(klsi_105_init);
+module_exit(klsi_105_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_LICENSE("GPL");
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
/*
* KOBIL USB Smart Card Terminal Driver
*
- * Copyright (C) 2002 KOBIL Systems GmbH
+ * Copyright (C) 2002 KOBIL Systems GmbH
* Author: Thomas Wahrenbruch
*
* Contact: linuxusb@kobil.de
*
* Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
* (Adapter K), B1 Professional and KAAN Professional (Adapter B)
- *
+ *
* (21/05/2004) tw
* Fix bug with P'n'P readers
*
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <linux/ioctl.h>
/* Function prototypes */
-static int kobil_startup (struct usb_serial *serial);
-static void kobil_shutdown (struct usb_serial *serial);
-static int kobil_open (struct usb_serial_port *port, struct file *filp);
-static void kobil_close (struct usb_serial_port *port, struct file *filp);
-static int kobil_write (struct usb_serial_port *port,
+static int kobil_startup(struct usb_serial *serial);
+static void kobil_shutdown(struct usb_serial *serial);
+static int kobil_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void kobil_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
-static int kobil_write_room(struct usb_serial_port *port);
-static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
+static int kobil_write_room(struct tty_struct *tty);
+static int kobil_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg);
-static int kobil_tiocmget(struct usb_serial_port *port, struct file *file);
-static int kobil_tiocmset(struct usb_serial_port *port, struct file *file,
+static int kobil_tiocmget(struct tty_struct *tty, struct file *file);
+static int kobil_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
-static void kobil_read_int_callback( struct urb *urb );
-static void kobil_write_callback( struct urb *purb );
-static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old);
+static void kobil_read_int_callback(struct urb *urb);
+static void kobil_write_callback(struct urb *purb);
+static void kobil_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
static struct usb_device_id id_table [] = {
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver kobil_driver = {
.name = "kobil",
struct kobil_private {
int write_int_endpoint_address;
int read_int_endpoint_address;
- unsigned char buf[KOBIL_BUF_LENGTH]; // buffer for the APDU to send
- int filled; // index of the last char in buf
- int cur_pos; // index of the next char to send in buf
+ unsigned char buf[KOBIL_BUF_LENGTH]; /* buffer for the APDU to send */
+ int filled; /* index of the last char in buf */
+ int cur_pos; /* index of the next char to send in buf */
__u16 device_type;
};
-static int kobil_startup (struct usb_serial *serial)
+static int kobil_startup(struct usb_serial *serial)
{
int i;
struct kobil_private *priv;
struct usb_host_endpoint *endpoint;
priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL);
- if (!priv){
+ if (!priv)
return -ENOMEM;
- }
priv->filled = 0;
priv->cur_pos = 0;
priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct);
- switch (priv->device_type){
+ switch (priv->device_type) {
case KOBIL_ADAPTER_B_PRODUCT_ID:
printk(KERN_DEBUG "KOBIL B1 PRO / KAAN PRO detected\n");
break;
case KOBIL_ADAPTER_K_PRODUCT_ID:
- printk(KERN_DEBUG "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n");
+ printk(KERN_DEBUG
+ "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n");
break;
case KOBIL_USBTWIN_PRODUCT_ID:
printk(KERN_DEBUG "KOBIL USBTWIN detected\n");
}
usb_set_serial_port_data(serial->port[0], priv);
- // search for the necessary endpoints
+ /* search for the necessary endpoints */
pdev = serial->dev;
- actconfig = pdev->actconfig;
- interface = actconfig->interface[0];
+ actconfig = pdev->actconfig;
+ interface = actconfig->interface[0];
altsetting = interface->cur_altsetting;
- endpoint = altsetting->endpoint;
-
- for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
+ endpoint = altsetting->endpoint;
+
+ for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
endpoint = &altsetting->endpoint[i];
if (usb_endpoint_is_int_out(&endpoint->desc)) {
- dbg("%s Found interrupt out endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress);
- priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress;
- }
+ dbg("%s Found interrupt out endpoint. Address: %d",
+ __func__, endpoint->desc.bEndpointAddress);
+ priv->write_int_endpoint_address =
+ endpoint->desc.bEndpointAddress;
+ }
if (usb_endpoint_is_int_in(&endpoint->desc)) {
- dbg("%s Found interrupt in endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress);
- priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress;
- }
+ dbg("%s Found interrupt in endpoint. Address: %d",
+ __func__, endpoint->desc.bEndpointAddress);
+ priv->read_int_endpoint_address =
+ endpoint->desc.bEndpointAddress;
+ }
}
return 0;
}
-static void kobil_shutdown (struct usb_serial *serial)
+static void kobil_shutdown(struct usb_serial *serial)
{
int i;
dbg("%s - port %d", __func__, serial->port[0]->number);
- for (i=0; i < serial->num_ports; ++i) {
- while (serial->port[i]->open_count > 0) {
- kobil_close (serial->port[i], NULL);
- }
+ for (i = 0; i < serial->num_ports; ++i) {
+ while (serial->port[i]->port.count > 0)
+ kobil_close(NULL, serial->port[i], NULL);
kfree(usb_get_serial_port_data(serial->port[i]));
usb_set_serial_port_data(serial->port[i], NULL);
}
}
-static int kobil_open (struct usb_serial_port *port, struct file *filp)
+static int kobil_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
int result = 0;
struct kobil_private *priv;
dbg("%s - port %d", __func__, port->number);
priv = usb_get_serial_port_data(port);
- // someone sets the dev to 0 if the close method has been called
+ /* someone sets the dev to 0 if the close method has been called */
port->interrupt_in_urb->dev = port->serial->dev;
* the data through, otherwise it is scheduled, and with high
* data rates (like with OHCI) data can get lost.
*/
- port->tty->low_latency = 1;
-
- // without this, every push_tty_char is echoed :-(
- port->tty->termios->c_lflag = 0;
- port->tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
- port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
- port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D)
-
- // allocate memory for transfer buffer
+ if (tty) {
+ tty->low_latency = 1;
+
+ /* Default to echo off and other sane device settings */
+ tty->termios->c_lflag = 0;
+ tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN |
+ XCASE);
+ tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
+ /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
+ tty->termios->c_oflag &= ~ONLCR;
+ }
+ /* allocate memory for transfer buffer */
transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
- if (! transfer_buffer) {
+ if (!transfer_buffer)
return -ENOMEM;
- }
-
- // allocate write_urb
- if (!port->write_urb) {
- dbg("%s - port %d Allocating port->write_urb", __func__, port->number);
- port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+
+ /* allocate write_urb */
+ if (!port->write_urb) {
+ dbg("%s - port %d Allocating port->write_urb",
+ __func__, port->number);
+ port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!port->write_urb) {
- dbg("%s - port %d usb_alloc_urb failed", __func__, port->number);
+ dbg("%s - port %d usb_alloc_urb failed",
+ __func__, port->number);
kfree(transfer_buffer);
return -ENOMEM;
}
}
- // allocate memory for write_urb transfer buffer
- port->write_urb->transfer_buffer = kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
- if (! port->write_urb->transfer_buffer) {
+ /* allocate memory for write_urb transfer buffer */
+ port->write_urb->transfer_buffer =
+ kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
+ if (!port->write_urb->transfer_buffer) {
kfree(transfer_buffer);
usb_free_urb(port->write_urb);
port->write_urb = NULL;
return -ENOMEM;
- }
-
- // get hardware version
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_GetMisc,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
- SUSBCR_MSC_GetHWVersion,
- 0,
- transfer_buffer,
- transfer_buffer_length,
- KOBIL_TIMEOUT
+ }
+
+ /* get hardware version */
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ SUSBCRequest_GetMisc,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
+ SUSBCR_MSC_GetHWVersion,
+ 0,
+ transfer_buffer,
+ transfer_buffer_length,
+ KOBIL_TIMEOUT
+ );
+ dbg("%s - port %d Send get_HW_version URB returns: %i",
+ __func__, port->number, result);
+ dbg("Harware version: %i.%i.%i",
+ transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]);
+
+ /* get firmware version */
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ SUSBCRequest_GetMisc,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
+ SUSBCR_MSC_GetFWVersion,
+ 0,
+ transfer_buffer,
+ transfer_buffer_length,
+ KOBIL_TIMEOUT
+ );
+ dbg("%s - port %d Send get_FW_version URB returns: %i",
+ __func__, port->number, result);
+ dbg("Firmware version: %i.%i.%i",
+ transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]);
+
+ if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
+ priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
+ /* Setting Baudrate, Parity and Stopbits */
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ SUSBCRequest_SetBaudRateParityAndStopBits,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity |
+ SUSBCR_SPASB_1StopBit,
+ 0,
+ transfer_buffer,
+ 0,
+ KOBIL_TIMEOUT
);
- dbg("%s - port %d Send get_HW_version URB returns: %i", __func__, port->number, result);
- dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] );
-
- // get firmware version
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_GetMisc,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
- SUSBCR_MSC_GetFWVersion,
- 0,
- transfer_buffer,
- transfer_buffer_length,
- KOBIL_TIMEOUT
+ dbg("%s - port %d Send set_baudrate URB returns: %i",
+ __func__, port->number, result);
+
+ /* reset all queues */
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ SUSBCRequest_Misc,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ SUSBCR_MSC_ResetAllQueues,
+ 0,
+ transfer_buffer,
+ 0,
+ KOBIL_TIMEOUT
);
- dbg("%s - port %d Send get_FW_version URB returns: %i", __func__, port->number, result);
- dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] );
-
- if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
- // Setting Baudrate, Parity and Stopbits
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_SetBaudRateParityAndStopBits,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | SUSBCR_SPASB_1StopBit,
- 0,
- transfer_buffer,
- 0,
- KOBIL_TIMEOUT
- );
- dbg("%s - port %d Send set_baudrate URB returns: %i", __func__, port->number, result);
-
- // reset all queues
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_Misc,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- SUSBCR_MSC_ResetAllQueues,
- 0,
- transfer_buffer,
- 0,
- KOBIL_TIMEOUT
- );
- dbg("%s - port %d Send reset_all_queues URB returns: %i", __func__, port->number, result);
+ dbg("%s - port %d Send reset_all_queues URB returns: %i",
+ __func__, port->number, result);
}
- if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
+ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
+ priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
- // start reading (Adapter B 'cause PNP string)
- result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC );
- dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result);
+ /* start reading (Adapter B 'cause PNP string) */
+ result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
+ dbg("%s - port %d Send read URB returns: %i",
+ __func__, port->number, result);
}
kfree(transfer_buffer);
}
-static void kobil_close (struct usb_serial_port *port, struct file *filp)
+static void kobil_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
dbg("%s - port %d", __func__, port->number);
if (port->write_urb) {
usb_kill_urb(port->write_urb);
- usb_free_urb( port->write_urb );
+ usb_free_urb(port->write_urb);
port->write_urb = NULL;
}
usb_kill_urb(port->interrupt_in_urb);
struct tty_struct *tty;
unsigned char *data = urb->transfer_buffer;
int status = urb->status;
-// char *dbg_data;
+/* char *dbg_data; */
dbg("%s - port %d", __func__, port->number);
return;
}
- tty = port->tty;
+ tty = port->port.tty;
if (urb->actual_length) {
- // BEGIN DEBUG
+ /* BEGIN DEBUG */
/*
- dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
+ dbg_data = kzalloc((3 * purb->actual_length + 10)
+ * sizeof(char), GFP_KERNEL);
if (! dbg_data) {
- return;
+ return;
}
- for (i = 0; i < purb->actual_length; i++) {
- sprintf(dbg_data +3*i, "%02X ", data[i]);
+ for (i = 0; i < purb->actual_length; i++) {
+ sprintf(dbg_data +3*i, "%02X ", data[i]);
}
- dbg(" <-- %s", dbg_data );
+ dbg(" <-- %s", dbg_data);
kfree(dbg_data);
*/
- // END DEBUG
+ /* END DEBUG */
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
-
- // someone sets the dev to 0 if the close method has been called
+ /* someone sets the dev to 0 if the close method has been called */
port->interrupt_in_urb->dev = port->serial->dev;
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
- dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result);
+ dbg("%s - port %d Send read URB returns: %i",
+ __func__, port->number, result);
}
-static void kobil_write_callback( struct urb *purb )
+static void kobil_write_callback(struct urb *purb)
{
}
-static int kobil_write (struct usb_serial_port *port,
+static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count)
{
int length = 0;
int result = 0;
int todo = 0;
- struct kobil_private * priv;
+ struct kobil_private *priv;
if (count == 0) {
- dbg("%s - port %d write request of 0 bytes", __func__, port->number);
+ dbg("%s - port %d write request of 0 bytes",
+ __func__, port->number);
return 0;
}
return -ENOMEM;
}
- // Copy data to buffer
- memcpy (priv->buf + priv->filled, buf, count);
-
- usb_serial_debug_data(debug, &port->dev, __func__, count, priv->buf + priv->filled);
-
+ /* Copy data to buffer */
+ memcpy(priv->buf + priv->filled, buf, count);
+ usb_serial_debug_data(debug, &port->dev, __func__, count,
+ priv->buf + priv->filled);
priv->filled = priv->filled + count;
-
- // only send complete block. TWIN, KAAN SIM and adapter K use the same protocol.
- if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) ||
- ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) {
-
- // stop reading (except TWIN and KAAN SIM)
- if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) )
+ /* only send complete block. TWIN, KAAN SIM and adapter K
+ use the same protocol. */
+ if (((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) ||
+ ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4)))) {
+ /* stop reading (except TWIN and KAAN SIM) */
+ if ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID)
+ || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID))
usb_kill_urb(port->interrupt_in_urb);
todo = priv->filled - priv->cur_pos;
- while(todo > 0) {
- // max 8 byte in one urb (endpoint size)
+ while (todo > 0) {
+ /* max 8 byte in one urb (endpoint size) */
length = (todo < 8) ? todo : 8;
- // copy data to transfer buffer
- memcpy(port->write_urb->transfer_buffer, priv->buf + priv->cur_pos, length );
- usb_fill_int_urb( port->write_urb,
- port->serial->dev,
- usb_sndintpipe(port->serial->dev, priv->write_int_endpoint_address),
- port->write_urb->transfer_buffer,
- length,
- kobil_write_callback,
- port,
- 8
- );
+ /* copy data to transfer buffer */
+ memcpy(port->write_urb->transfer_buffer,
+ priv->buf + priv->cur_pos, length);
+ usb_fill_int_urb(port->write_urb,
+ port->serial->dev,
+ usb_sndintpipe(port->serial->dev,
+ priv->write_int_endpoint_address),
+ port->write_urb->transfer_buffer,
+ length,
+ kobil_write_callback,
+ port,
+ 8
+ );
priv->cur_pos = priv->cur_pos + length;
- result = usb_submit_urb( port->write_urb, GFP_NOIO );
- dbg("%s - port %d Send write URB returns: %i", __func__, port->number, result);
+ result = usb_submit_urb(port->write_urb, GFP_NOIO);
+ dbg("%s - port %d Send write URB returns: %i",
+ __func__, port->number, result);
todo = priv->filled - priv->cur_pos;
- if (todo > 0) {
+ if (todo > 0)
msleep(24);
- }
+ }
- } // end while
-
priv->filled = 0;
priv->cur_pos = 0;
- // someone sets the dev to 0 if the close method has been called
+ /* someone sets the dev to 0 if the close method
+ has been called */
port->interrupt_in_urb->dev = port->serial->dev;
-
- // start reading (except TWIN and KAAN SIM)
- if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) {
- // someone sets the dev to 0 if the close method has been called
+
+ /* start reading (except TWIN and KAAN SIM) */
+ if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
+ priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
+ /* someone sets the dev to 0 if the close method has
+ been called */
port->interrupt_in_urb->dev = port->serial->dev;
-
- result = usb_submit_urb( port->interrupt_in_urb, GFP_NOIO );
- dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result);
+
+ result = usb_submit_urb(port->interrupt_in_urb,
+ GFP_NOIO);
+ dbg("%s - port %d Send read URB returns: %i",
+ __func__, port->number, result);
}
}
return count;
}
-static int kobil_write_room (struct usb_serial_port *port)
+static int kobil_write_room(struct tty_struct *tty)
{
- //dbg("%s - port %d", __func__, port->number);
+ /* dbg("%s - port %d", __func__, port->number); */
+ /* FIXME */
return 8;
}
-static int kobil_tiocmget(struct usb_serial_port *port, struct file *file)
+static int kobil_tiocmget(struct tty_struct *tty, struct file *file)
{
- struct kobil_private * priv;
+ struct usb_serial_port *port = tty->driver_data;
+ struct kobil_private *priv;
int result;
unsigned char *transfer_buffer;
int transfer_buffer_length = 8;
priv = usb_get_serial_port_data(port);
- if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
- // This device doesn't support ioctl calls
+ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID
+ || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
+ /* This device doesn't support ioctl calls */
return -EINVAL;
}
- // allocate memory for transfer buffer
+ /* allocate memory for transfer buffer */
transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
- if (!transfer_buffer) {
+ if (!transfer_buffer)
return -ENOMEM;
- }
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_GetStatusLineState,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
- 0,
- 0,
- transfer_buffer,
- transfer_buffer_length,
- KOBIL_TIMEOUT);
-
- dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x",
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ SUSBCRequest_GetStatusLineState,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
+ 0,
+ 0,
+ transfer_buffer,
+ transfer_buffer_length,
+ KOBIL_TIMEOUT);
+
+ dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x",
__func__, port->number, result, transfer_buffer[0]);
result = 0;
return result;
}
-static int kobil_tiocmset(struct usb_serial_port *port, struct file *file,
+static int kobil_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
- struct kobil_private * priv;
+ struct usb_serial_port *port = tty->driver_data;
+ struct kobil_private *priv;
int result;
int dtr = 0;
int rts = 0;
/* FIXME: locking ? */
priv = usb_get_serial_port_data(port);
- if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
- // This device doesn't support ioctl calls
+ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID
+ || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
+ /* This device doesn't support ioctl calls */
return -EINVAL;
}
- // allocate memory for transfer buffer
+ /* allocate memory for transfer buffer */
transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
- if (! transfer_buffer) {
+ if (!transfer_buffer)
return -ENOMEM;
- }
if (set & TIOCM_RTS)
rts = 1;
if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) {
if (dtr != 0)
- dbg("%s - port %d Setting DTR", __func__, port->number);
+ dbg("%s - port %d Setting DTR",
+ __func__, port->number);
else
- dbg("%s - port %d Clearing DTR", __func__, port->number);
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_SetStatusLinesOrQueues,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),
- 0,
- transfer_buffer,
- 0,
- KOBIL_TIMEOUT);
+ dbg("%s - port %d Clearing DTR",
+ __func__, port->number);
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ SUSBCRequest_SetStatusLinesOrQueues,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),
+ 0,
+ transfer_buffer,
+ 0,
+ KOBIL_TIMEOUT);
} else {
if (rts != 0)
- dbg("%s - port %d Setting RTS", __func__, port->number);
+ dbg("%s - port %d Setting RTS",
+ __func__, port->number);
else
- dbg("%s - port %d Clearing RTS", __func__, port->number);
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_SetStatusLinesOrQueues,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),
- 0,
- transfer_buffer,
- 0,
- KOBIL_TIMEOUT);
+ dbg("%s - port %d Clearing RTS",
+ __func__, port->number);
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ SUSBCRequest_SetStatusLinesOrQueues,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),
+ 0,
+ transfer_buffer,
+ 0,
+ KOBIL_TIMEOUT);
}
- dbg("%s - port %d Send set_status_line URB returns: %i", __func__, port->number, result);
+ dbg("%s - port %d Send set_status_line URB returns: %i",
+ __func__, port->number, result);
kfree(transfer_buffer);
return (result < 0) ? result : 0;
}
-static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old)
+static void kobil_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old)
{
- struct kobil_private * priv;
+ struct kobil_private *priv;
int result;
unsigned short urb_val = 0;
- int c_cflag = port->tty->termios->c_cflag;
+ int c_cflag = tty->termios->c_cflag;
speed_t speed;
- void * settings;
+ void *settings;
priv = usb_get_serial_port_data(port);
- if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
- // This device doesn't support ioctl calls
+ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
+ priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
+ /* This device doesn't support ioctl calls */
+ *tty->termios = *old;
return;
+ }
- switch (speed = tty_get_baud_rate(port->tty)) {
- case 1200:
- urb_val = SUSBCR_SBR_1200;
- break;
- default:
- speed = 9600;
- case 9600:
- urb_val = SUSBCR_SBR_9600;
- break;
+ speed = tty_get_baud_rate(tty);
+ switch (speed) {
+ case 1200:
+ urb_val = SUSBCR_SBR_1200;
+ break;
+ default:
+ speed = 9600;
+ case 9600:
+ urb_val = SUSBCR_SBR_9600;
+ break;
}
- urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;
+ urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits :
+ SUSBCR_SPASB_1StopBit;
settings = kzalloc(50, GFP_KERNEL);
- if (! settings)
+ if (!settings)
return;
sprintf(settings, "%d ", speed);
urb_val |= SUSBCR_SPASB_NoParity;
strcat(settings, "No Parity");
}
- port->tty->termios->c_cflag &= ~CMSPAR;
- tty_encode_baud_rate(port->tty, speed, speed);
-
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_SetBaudRateParityAndStopBits,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- urb_val,
- 0,
- settings,
- 0,
- KOBIL_TIMEOUT
+ tty->termios->c_cflag &= ~CMSPAR;
+ tty_encode_baud_rate(tty, speed, speed);
+
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ SUSBCRequest_SetBaudRateParityAndStopBits,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ urb_val,
+ 0,
+ settings,
+ 0,
+ KOBIL_TIMEOUT
);
kfree(settings);
}
-static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+static int kobil_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
- struct kobil_private * priv = usb_get_serial_port_data(port);
+ struct usb_serial_port *port = tty->driver_data;
+ struct kobil_private *priv = usb_get_serial_port_data(port);
unsigned char *transfer_buffer;
int transfer_buffer_length = 8;
int result;
- if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
- // This device doesn't support ioctl calls
- return 0;
+ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
+ priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
+ /* This device doesn't support ioctl calls */
+ return -ENOIOCTLCMD;
switch (cmd) {
- case TCFLSH: // 0x540B
+ case TCFLSH:
transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
- if (! transfer_buffer)
- return -ENOBUFS;
-
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_Misc,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- SUSBCR_MSC_ResetAllQueues,
- 0,
- NULL,//transfer_buffer,
- 0,
- KOBIL_TIMEOUT
+ if (!transfer_buffer)
+ return -ENOBUFS;
+
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ SUSBCRequest_Misc,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ SUSBCR_MSC_ResetAllQueues,
+ 0,
+ NULL, /* transfer_buffer, */
+ 0,
+ KOBIL_TIMEOUT
);
-
+
dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __func__, port->number, result);
kfree(transfer_buffer);
- return (result < 0) ? -EFAULT : 0;
+ return (result < 0) ? -EIO: 0;
default:
return -ENOIOCTLCMD;
}
}
-static int __init kobil_init (void)
+static int __init kobil_init(void)
{
int retval;
retval = usb_serial_register(&kobil_device);
if (retval)
goto failed_usb_serial_register;
retval = usb_register(&kobil_driver);
- if (retval)
+ if (retval)
goto failed_usb_register;
info(DRIVER_VERSION " " DRIVER_AUTHOR);
}
-static void __exit kobil_exit (void)
+static void __exit kobil_exit(void)
{
- usb_deregister (&kobil_driver);
- usb_serial_deregister (&kobil_device);
+ usb_deregister(&kobil_driver);
+ usb_serial_deregister(&kobil_device);
}
module_init(kobil_init);
module_exit(kobil_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_LICENSE( "GPL" );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
* - Fixed an endianess problem with the baudrate selection for PowerPC.
*
* 06-Dec-2001 Martin Hamilton <martinh@gnu.org>
- * Added support for the Belkin F5U109 DB9 adaptor
+ * - Added support for the Belkin F5U109 DB9 adaptor
*
* 30-May-2001 Greg Kroah-Hartman
- * switched from using spinlock to a semaphore, which fixes lots of problems.
+ * - switched from using spinlock to a semaphore, which fixes lots of
+ * problems.
*
* 04-May-2001 Stelian Pop
* - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes
* 08-Apr-2001 gb
* - Identify version on module load.
*
- * 06-Jan-2001 Cornel Ciocirlan
+ * 06-Jan-2001 Cornel Ciocirlan
* - Added support for Sitecom U232-P25 model (Product Id 0x0230)
* - Added support for D-Link DU-H3SP USB BAY (Product Id 0x0200)
*
* (lots of things will change if/when the usb-serial core changes to
* handle these issues.
*
- * 27-Nov-2000 Wolfgang Grandegger
- * A version for kernel 2.4.0-test10 released to the Linux community
+ * 27-Nov-2000 Wolfgang Grandegge
+ * A version for kernel 2.4.0-test10 released to the Linux community
* (via linux-usb-devel).
*/
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "mct_u232.h"
/*
* Function prototypes
*/
-static int mct_u232_startup (struct usb_serial *serial);
-static void mct_u232_shutdown (struct usb_serial *serial);
-static int mct_u232_open (struct usb_serial_port *port,
- struct file *filp);
-static void mct_u232_close (struct usb_serial_port *port,
- struct file *filp);
-static void mct_u232_read_int_callback (struct urb *urb);
-static void mct_u232_set_termios (struct usb_serial_port *port,
- struct ktermios * old);
-static int mct_u232_ioctl (struct usb_serial_port *port,
- struct file * file,
- unsigned int cmd,
- unsigned long arg);
-static void mct_u232_break_ctl (struct usb_serial_port *port,
- int break_state );
-static int mct_u232_tiocmget (struct usb_serial_port *port,
- struct file *file);
-static int mct_u232_tiocmset (struct usb_serial_port *port,
- struct file *file, unsigned int set,
- unsigned int clear);
-static void mct_u232_throttle (struct usb_serial_port *port);
-static void mct_u232_unthrottle (struct usb_serial_port *port);
+static int mct_u232_startup(struct usb_serial *serial);
+static void mct_u232_shutdown(struct usb_serial *serial);
+static int mct_u232_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void mct_u232_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void mct_u232_read_int_callback(struct urb *urb);
+static void mct_u232_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
+static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
+static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file);
+static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static void mct_u232_throttle(struct tty_struct *tty);
+static void mct_u232_unthrottle(struct tty_struct *tty);
/*
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver mct_u232_driver = {
.name = "mct_u232",
.throttle = mct_u232_throttle,
.unthrottle = mct_u232_unthrottle,
.read_int_callback = mct_u232_read_int_callback,
- .ioctl = mct_u232_ioctl,
.set_termios = mct_u232_set_termios,
.break_ctl = mct_u232_break_ctl,
.tiocmget = mct_u232_tiocmget,
* Later day 2.6.0-test kernels have new baud rates like B230400 which
* we do not know how to support. We ignore them for the moment.
*/
-static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value, speed_t *result)
+static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
+ speed_t value, speed_t *result)
{
*result = value;
if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
- || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
+ || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
switch (value) {
- case 300: return 0x01;
- case 600: return 0x02; /* this one not tested */
- case 1200: return 0x03;
- case 2400: return 0x04;
- case 4800: return 0x06;
- case 9600: return 0x08;
- case 19200: return 0x09;
- case 38400: return 0x0a;
- case 57600: return 0x0b;
- case 115200: return 0x0c;
+ case 300:
+ return 0x01;
+ case 600:
+ return 0x02; /* this one not tested */
+ case 1200:
+ return 0x03;
+ case 2400:
+ return 0x04;
+ case 4800:
+ return 0x06;
+ case 9600:
+ return 0x08;
+ case 19200:
+ return 0x09;
+ case 38400:
+ return 0x0a;
+ case 57600:
+ return 0x0b;
+ case 115200:
+ return 0x0c;
default:
*result = 9600;
return 0x08;
}
}
-static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_port *port,
- speed_t value)
+static int mct_u232_set_baud_rate(struct tty_struct *tty,
+ struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
{
__le32 divisor;
- int rc;
- unsigned char zero_byte = 0;
- unsigned char cts_enable_byte = 0;
- speed_t speed;
-
- divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value, &speed));
-
- rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- MCT_U232_SET_BAUD_RATE_REQUEST,
- MCT_U232_SET_REQUEST_TYPE,
- 0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
- WDR_TIMEOUT);
+ int rc;
+ unsigned char zero_byte = 0;
+ unsigned char cts_enable_byte = 0;
+ speed_t speed;
+
+ divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value,
+ &speed));
+
+ rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ MCT_U232_SET_BAUD_RATE_REQUEST,
+ MCT_U232_SET_REQUEST_TYPE,
+ 0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
+ WDR_TIMEOUT);
if (rc < 0) /*FIXME: What value speed results */
err("Set BAUD RATE %d failed (error = %d)", value, rc);
else
- tty_encode_baud_rate(port->tty, speed, speed);
+ tty_encode_baud_rate(tty, speed, speed);
dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
/* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
whether data will be transmitted to a device which is not asserting
the 'CTS' signal. If the second message's data byte is zero, data
will be transmitted even if 'CTS' is not asserted (i.e. no hardware
- flow control). if the second message's data byte is nonzero (a value
- of 1 is used by this driver), data will not be transmitted to a device
- which is not asserting 'CTS'.
+ flow control). if the second message's data byte is nonzero (a
+ value of 1 is used by this driver), data will not be transmitted to
+ a device which is not asserting 'CTS'.
*/
rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- MCT_U232_SET_UNKNOWN1_REQUEST,
- MCT_U232_SET_REQUEST_TYPE,
- 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE,
- WDR_TIMEOUT);
+ MCT_U232_SET_UNKNOWN1_REQUEST,
+ MCT_U232_SET_REQUEST_TYPE,
+ 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE,
+ WDR_TIMEOUT);
if (rc < 0)
- err("Sending USB device request code %d failed (error = %d)",
+ err("Sending USB device request code %d failed (error = %d)",
MCT_U232_SET_UNKNOWN1_REQUEST, rc);
- if (port && C_CRTSCTS(port->tty)) {
+ if (port && C_CRTSCTS(tty))
cts_enable_byte = 1;
- }
- dbg("set_baud_rate: send second control message, data = %02X", cts_enable_byte);
+ dbg("set_baud_rate: send second control message, data = %02X",
+ cts_enable_byte);
rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- MCT_U232_SET_CTS_REQUEST,
- MCT_U232_SET_REQUEST_TYPE,
- 0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE,
- WDR_TIMEOUT);
+ MCT_U232_SET_CTS_REQUEST,
+ MCT_U232_SET_REQUEST_TYPE,
+ 0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE,
+ WDR_TIMEOUT);
if (rc < 0)
- err("Sending USB device request code %d failed (error = %d)",
- MCT_U232_SET_CTS_REQUEST, rc);
+ err("Sending USB device request code %d failed (error = %d)",
+ MCT_U232_SET_CTS_REQUEST, rc);
- return rc;
+ return rc;
} /* mct_u232_set_baud_rate */
static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
{
- int rc;
- rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- MCT_U232_SET_LINE_CTRL_REQUEST,
- MCT_U232_SET_REQUEST_TYPE,
- 0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
- WDR_TIMEOUT);
+ int rc;
+ rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ MCT_U232_SET_LINE_CTRL_REQUEST,
+ MCT_U232_SET_REQUEST_TYPE,
+ 0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
+ WDR_TIMEOUT);
if (rc < 0)
err("Set LINE CTRL 0x%x failed (error = %d)", lcr, rc);
dbg("set_line_ctrl: 0x%x", lcr);
- return rc;
+ return rc;
} /* mct_u232_set_line_ctrl */
static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
unsigned int control_state)
{
- int rc;
+ int rc;
unsigned char mcr = MCT_U232_MCR_NONE;
if (control_state & TIOCM_DTR)
if (control_state & TIOCM_RTS)
mcr |= MCT_U232_MCR_RTS;
- rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- MCT_U232_SET_MODEM_CTRL_REQUEST,
- MCT_U232_SET_REQUEST_TYPE,
- 0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
- WDR_TIMEOUT);
+ rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ MCT_U232_SET_MODEM_CTRL_REQUEST,
+ MCT_U232_SET_REQUEST_TYPE,
+ 0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
+ WDR_TIMEOUT);
if (rc < 0)
err("Set MODEM CTRL 0x%x failed (error = %d)", mcr, rc);
dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
- return rc;
+ return rc;
} /* mct_u232_set_modem_ctrl */
-static int mct_u232_get_modem_stat(struct usb_serial *serial, unsigned char *msr)
+static int mct_u232_get_modem_stat(struct usb_serial *serial,
+ unsigned char *msr)
{
- int rc;
- rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- MCT_U232_GET_MODEM_STAT_REQUEST,
- MCT_U232_GET_REQUEST_TYPE,
- 0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
- WDR_TIMEOUT);
+ int rc;
+ rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ MCT_U232_GET_MODEM_STAT_REQUEST,
+ MCT_U232_GET_REQUEST_TYPE,
+ 0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
+ WDR_TIMEOUT);
if (rc < 0) {
err("Get MODEM STATus failed (error = %d)", rc);
*msr = 0;
}
dbg("get_modem_stat: 0x%x", *msr);
- return rc;
+ return rc;
} /* mct_u232_get_modem_stat */
-static void mct_u232_msr_to_state(unsigned int *control_state, unsigned char msr)
+static void mct_u232_msr_to_state(unsigned int *control_state,
+ unsigned char msr)
{
- /* Translate Control Line states */
+ /* Translate Control Line states */
if (msr & MCT_U232_MSR_DSR)
*control_state |= TIOCM_DSR;
else
*control_state |= TIOCM_CD;
else
*control_state &= ~TIOCM_CD;
- dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
+ dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
} /* mct_u232_msr_to_state */
/*
* Driver's tty interface functions
*/
-static int mct_u232_startup (struct usb_serial *serial)
+static int mct_u232_startup(struct usb_serial *serial)
{
struct mct_u232_private *priv;
struct usb_serial_port *port, *rport;
rport->interrupt_in_urb = NULL;
port->read_urb->context = port;
- return (0);
+ return 0;
} /* mct_u232_startup */
-static void mct_u232_shutdown (struct usb_serial *serial)
+static void mct_u232_shutdown(struct usb_serial *serial)
{
struct mct_u232_private *priv;
int i;
-
+
dbg("%s", __func__);
- for (i=0; i < serial->num_ports; ++i) {
+ for (i = 0; i < serial->num_ports; ++i) {
/* My special items, the standard routines free my urbs */
priv = usb_get_serial_port_data(serial->port[i]);
if (priv) {
}
} /* mct_u232_shutdown */
-static int mct_u232_open (struct usb_serial_port *port, struct file *filp)
+static int mct_u232_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
* it seems to be able to accept only 16 bytes (and that's what
* SniffUSB says too...)
*/
- if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID)
+ if (le16_to_cpu(serial->dev->descriptor.idProduct)
+ == MCT_U232_SITECOM_PID)
port->bulk_out_size = 16;
- /* Do a defined restart: the normal serial device seems to
+ /* Do a defined restart: the normal serial device seems to
* always turn on DTR and RTS here, so do the same. I'm not
* sure if this is really necessary. But it should not harm
* either.
*/
spin_lock_irqsave(&priv->lock, flags);
- if (port->tty->termios->c_cflag & CBAUD)
+ if (tty && (tty->termios->c_cflag & CBAUD))
priv->control_state = TIOCM_DTR | TIOCM_RTS;
else
priv->control_state = 0;
-
- priv->last_lcr = (MCT_U232_DATA_BITS_8 |
+
+ priv->last_lcr = (MCT_U232_DATA_BITS_8 |
MCT_U232_PARITY_NONE |
MCT_U232_STOP_BITS_1);
control_state = priv->control_state;
} /* mct_u232_open */
-static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
+static void mct_u232_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
unsigned int c_cflag;
unsigned int control_state;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
dbg("%s port %d", __func__, port->number);
- if (port->tty) {
- c_cflag = port->tty->termios->c_cflag;
+ if (tty) {
+ c_cflag = tty->termios->c_cflag;
mutex_lock(&port->serial->disc_mutex);
if (c_cflag & HUPCL && !port->serial->disconnected) {
/* drop DTR and RTS */
} /* mct_u232_close */
-static void mct_u232_read_int_callback (struct urb *urb)
+static void mct_u232_read_int_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
return;
}
- dbg("%s - port %d", __func__, port->number);
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+ dbg("%s - port %d", __func__, port->number);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
/*
* Work-a-round: handle the 'usual' bulk-in pipe here
*/
if (urb->transfer_buffer_length > 2) {
- int i;
- tty = port->tty;
+ tty = port->port.tty;
if (urb->actual_length) {
- for (i = 0; i < urb->actual_length ; ++i) {
- tty_insert_flip_char(tty, data[i], 0);
- }
+ tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
goto exit;
}
-
+
/*
* The interrupt-in pipe signals exceptional conditions (modem line
* signal changes and errors). data[0] holds MSR, data[1] holds LSR.
*/
spin_lock_irqsave(&priv->lock, flags);
priv->last_msr = data[MCT_U232_MSR_INDEX];
-
+
/* Record Control Line states */
mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
#if 0
- /* Not yet handled. See belin_sa.c for further information */
+ /* Not yet handled. See belkin_sa.c for further information */
/* Now to report any errors */
priv->last_lsr = data[MCT_U232_LSR_INDEX];
/*
* to look in to this before committing any code.
*/
if (priv->last_lsr & MCT_U232_LSR_ERR) {
- tty = port->tty;
+ tty = port->port.tty;
/* Overrun Error */
if (priv->last_lsr & MCT_U232_LSR_OE) {
}
#endif
spin_unlock_irqrestore(&priv->lock, flags);
exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
- err ("%s - usb_submit_urb failed with result %d",
+ err("%s - usb_submit_urb failed with result %d",
__func__, retval);
} /* mct_u232_read_int_callback */
-static void mct_u232_set_termios (struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void mct_u232_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
- struct ktermios *termios = port->tty->termios;
+ struct ktermios *termios = tty->termios;
unsigned int cflag = termios->c_cflag;
unsigned int old_cflag = old_termios->c_cflag;
unsigned long flags;
* Premature optimization is the root of all evil.
*/
- /* reassert DTR and RTS on transition from B0 */
+ /* reassert DTR and RTS on transition from B0 */
if ((old_cflag & CBAUD) == B0) {
dbg("%s: baud was B0", __func__);
control_state |= TIOCM_DTR | TIOCM_RTS;
mct_u232_set_modem_ctrl(serial, control_state);
}
- mct_u232_set_baud_rate(serial, port, tty_get_baud_rate(port->tty));
+ mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
- if ((cflag & CBAUD) == B0 ) {
+ if ((cflag & CBAUD) == B0) {
dbg("%s: baud is B0", __func__);
/* Drop RTS and DTR */
control_state &= ~(TIOCM_DTR | TIOCM_RTS);
- mct_u232_set_modem_ctrl(serial, control_state);
+ mct_u232_set_modem_ctrl(serial, control_state);
}
/*
spin_unlock_irqrestore(&priv->lock, flags);
} /* mct_u232_set_termios */
-static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
+static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
unsigned char lcr;
} /* mct_u232_break_ctl */
-static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file)
+static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
unsigned int control_state;
unsigned long flags;
-
+
dbg("%s", __func__);
spin_lock_irqsave(&priv->lock, flags);
return control_state;
}
-static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file,
+static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
unsigned int control_state;
unsigned long flags;
-
+
dbg("%s", __func__);
spin_lock_irqsave(&priv->lock, flags);
return mct_u232_set_modem_ctrl(serial, control_state);
}
-static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
- unsigned int cmd, unsigned long arg)
-{
- dbg("%scmd=0x%x", __func__, cmd);
-
- /* Based on code from acm.c and others */
- switch (cmd) {
- case TIOCMIWAIT:
- /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
- /* TODO */
- return( 0 );
-
- case TIOCGICOUNT:
- /* return count of modemline transitions */
- /* TODO */
- return 0;
-
- default:
- dbg("%s: arg not supported - 0x%04x", __func__,cmd);
- return(-ENOIOCTLCMD);
- break;
- }
- return 0;
-} /* mct_u232_ioctl */
-
-static void mct_u232_throttle (struct usb_serial_port *port)
+static void mct_u232_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
unsigned int control_state;
- struct tty_struct *tty;
- tty = port->tty;
dbg("%s - port %d", __func__, port->number);
spin_lock_irqsave(&priv->lock, flags);
priv->rx_flags |= THROTTLED;
if (C_CRTSCTS(tty)) {
- priv->control_state &= ~TIOCM_RTS;
- control_state = priv->control_state;
- spin_unlock_irqrestore(&priv->lock, flags);
- (void) mct_u232_set_modem_ctrl(port->serial, control_state);
+ priv->control_state &= ~TIOCM_RTS;
+ control_state = priv->control_state;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ (void) mct_u232_set_modem_ctrl(port->serial, control_state);
} else {
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
}
-static void mct_u232_unthrottle (struct usb_serial_port *port)
+static void mct_u232_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
unsigned int control_state;
- struct tty_struct *tty;
dbg("%s - port %d", __func__, port->number);
- tty = port->tty;
spin_lock_irqsave(&priv->lock, flags);
if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
- priv->rx_flags &= ~THROTTLED;
- priv->control_state |= TIOCM_RTS;
- control_state = priv->control_state;
- spin_unlock_irqrestore(&priv->lock, flags);
- (void) mct_u232_set_modem_ctrl(port->serial, control_state);
+ priv->rx_flags &= ~THROTTLED;
+ priv->control_state |= TIOCM_RTS;
+ control_state = priv->control_state;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ (void) mct_u232_set_modem_ctrl(port->serial, control_state);
} else {
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
}
-static int __init mct_u232_init (void)
+static int __init mct_u232_init(void)
{
int retval;
retval = usb_serial_register(&mct_u232_device);
}
-static void __exit mct_u232_exit (void)
+static void __exit mct_u232_exit(void)
{
- usb_deregister (&mct_u232_driver);
- usb_serial_deregister (&mct_u232_device);
+ usb_deregister(&mct_u232_driver);
+ usb_serial_deregister(&mct_u232_device);
}
-
-module_init (mct_u232_init);
+module_init(mct_u232_init);
module_exit(mct_u232_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
#include <linux/serial_reg.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
/*
#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
/* This structure holds all of the local port information */
-struct moschip_port
-{
+struct moschip_port {
__u8 shadowLCR; /* last LCR value received */
__u8 shadowMCR; /* last MCR value received */
__u8 shadowMSR; /* last MSR value received */
};
/* This structure holds all of the individual serial device information */
-struct moschip_serial
-{
+struct moschip_serial {
int interrupt_started;
};
#define MOSCHIP_DEVICE_ID_7715 0x7715
static struct usb_device_id moschip_port_id_table [] = {
- { USB_DEVICE(USB_VENDOR_ID_MOSCHIP,MOSCHIP_DEVICE_ID_7720) },
+ { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) },
{ } /* terminating entry */
};
MODULE_DEVICE_TABLE(usb, moschip_port_id_table);
__u8 sp1;
__u8 sp2;
- dbg("%s"," : Entering\n");
+ dbg("%s", " : Entering\n");
switch (status) {
case 0:
mos7720_port = urb->context;
if (!mos7720_port) {
- dbg("%s","NULL mos7720_port pointer \n");
+ dbg("%s", "NULL mos7720_port pointer \n");
return ;
}
data = urb->transfer_buffer;
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
dbg("Entering .........");
- tty = mos7720_port->port->tty;
+ tty = mos7720_port->port->port.tty;
if (tty && mos7720_port->open)
tty_wakeup(tty);
__u16 size = 0x0000;
if (value < MOS_MAX_PORT) {
- if (product == MOSCHIP_DEVICE_ID_7715) {
+ if (product == MOSCHIP_DEVICE_ID_7715)
value = value*0x100+0x100;
- } else {
+ else
value = value*0x100+0x200;
- }
} else {
value = 0x0000;
if ((product == MOSCHIP_DEVICE_ID_7715) &&
(index != 0x08)) {
dbg("serial->product== MOSCHIP_DEVICE_ID_7715");
- //index = 0x01 ;
+ /* index = 0x01 ; */
}
}
request = (__u8)MOS_READ;
requesttype = (__u8)0xC0;
size = 0x01;
- pipe = usb_rcvctrlpipe(serial->dev,0);
+ pipe = usb_rcvctrlpipe(serial->dev, 0);
}
status = usb_control_msg(serial->dev, pipe, request, requesttype,
value, index, data, size, MOS_WDR_TIMEOUT);
if (status < 0)
- dbg("Command Write failed Value %x index %x\n",value,index);
+ dbg("Command Write failed Value %x index %x\n", value, index);
return status;
}
-static int mos7720_open(struct usb_serial_port *port, struct file * filp)
+static int mos7720_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial;
struct usb_serial_port *port0;
/* Initialising the write urb pool */
for (j = 0; j < NUM_URBS; ++j) {
- urb = usb_alloc_urb(0,GFP_KERNEL);
+ urb = usb_alloc_urb(0, GFP_KERNEL);
mos7720_port->write_urb_pool[j] = urb;
if (urb == NULL) {
*/
port_number = port->number - port->serial->minor;
send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data);
- dbg("SS::%p LSR:%x\n",mos7720_port, data);
+ dbg("SS::%p LSR:%x\n", mos7720_port, data);
dbg("Check:Sending Command ..........");
data = 0xCF;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
data = 0x03;
- mos7720_port->shadowLCR = data;
+ mos7720_port->shadowLCR = data;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
data = 0x0b;
- mos7720_port->shadowMCR = data;
+ mos7720_port->shadowMCR = data;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
data = 0x0b;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
data = 0x03;
send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
data = 0x00;
- send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
+ send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT,
+ port_number + 1, &data);
*/
data = 0x00;
send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
data = 0x83;
- mos7720_port->shadowLCR = data;
+ mos7720_port->shadowLCR = data;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
data = 0x0c;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
data = 0x00;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
data = 0x03;
- mos7720_port->shadowLCR = data;
+ mos7720_port->shadowLCR = data;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
data = 0x0c;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
data = 0x0c;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
-//Matrix
-
/* force low_latency on so that our tty_push actually forces *
* the data through,otherwise it is scheduled, and with *
* high data rates (like with OHCI) data can get lost. */
- if (port->tty)
- port->tty->low_latency = 1;
+ if (tty)
+ tty->low_latency = 1;
/* see if we've set up our endpoint info yet *
* (can't set it up in mos7720_startup as the *
/* set up our interrupt urb */
usb_fill_int_urb(port0->interrupt_in_urb, serial->dev,
- usb_rcvintpipe(serial->dev,
- port->interrupt_in_endpointAddress),
- port0->interrupt_in_buffer,
- port0->interrupt_in_urb->transfer_buffer_length,
- mos7720_interrupt_callback, mos7720_port,
- port0->interrupt_in_urb->interval);
+ usb_rcvintpipe(serial->dev,
+ port->interrupt_in_endpointAddress),
+ port0->interrupt_in_buffer,
+ port0->interrupt_in_urb->transfer_buffer_length,
+ mos7720_interrupt_callback, mos7720_port,
+ port0->interrupt_in_urb->interval);
/* start interrupt read for this mos7720 this interrupt *
- * will continue as long as the mos7720 is connected */
+ * will continue as long as the mos7720 is connected */
dbg("Submit URB over !!!");
response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL);
if (response)
/* set up our bulk in urb */
usb_fill_bulk_urb(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev,
- port->bulk_in_endpointAddress),
+ port->bulk_in_endpointAddress),
port->bulk_in_buffer,
port->read_urb->transfer_buffer_length,
mos7720_bulk_in_callback, mos7720_port);
response = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (response)
- dev_err(&port->dev,
- "%s - Error %d submitting read urb\n", __func__, response);
+ dev_err(&port->dev, "%s - Error %d submitting read urb\n",
+ __func__, response);
/* initialize our icount structure */
memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount));
* system,
* Otherwise we return a negative error number.
*/
-static int mos7720_chars_in_buffer(struct usb_serial_port *port)
+static int mos7720_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
int i;
int chars = 0;
struct moschip_port *mos7720_port;
}
for (i = 0; i < NUM_URBS; ++i) {
- if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status == -EINPROGRESS)
+ if (mos7720_port->write_urb_pool[i] &&
+ mos7720_port->write_urb_pool[i]->status == -EINPROGRESS)
chars += URB_TRANSFER_BUFFER_SIZE;
}
dbg("%s - returns %d", __func__, chars);
return chars;
}
-static void mos7720_close(struct usb_serial_port *port, struct file *filp)
+static void mos7720_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial;
struct moschip_port *mos7720_port;
* been disconnected */
if (!serial->disconnected) {
data = 0x00;
- send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
- 0x04, &data);
+ send_mos_cmd(serial, MOS_WRITE,
+ port->number - port->serial->minor, 0x04, &data);
data = 0x00;
- send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
- 0x01, &data);
+ send_mos_cmd(serial, MOS_WRITE,
+ port->number - port->serial->minor, 0x01, &data);
}
mutex_unlock(&serial->disc_mutex);
mos7720_port->open = 0;
dbg("Leaving %s", __func__);
}
-static void mos7720_break(struct usb_serial_port *port, int break_state)
+static void mos7720_break(struct tty_struct *tty, int break_state)
{
- unsigned char data;
+ struct usb_serial_port *port = tty->driver_data;
+ unsigned char data;
struct usb_serial *serial;
struct moschip_port *mos7720_port;
* If successful, we return the amount of room that we have for this port
* Otherwise we return a negative error number.
*/
-static int mos7720_write_room(struct usb_serial_port *port)
+static int mos7720_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7720_port;
int room = 0;
int i;
/* FIXME: Locking */
for (i = 0; i < NUM_URBS; ++i) {
- if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS)
+ if (mos7720_port->write_urb_pool[i] &&
+ mos7720_port->write_urb_pool[i]->status != -EINPROGRESS)
room += URB_TRANSFER_BUFFER_SIZE;
}
return room;
}
-static int mos7720_write(struct usb_serial_port *port,
- const unsigned char *data, int count)
+static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *data, int count)
{
int status;
int i;
urb = NULL;
for (i = 0; i < NUM_URBS; ++i) {
- if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) {
+ if (mos7720_port->write_urb_pool[i] &&
+ mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) {
urb = mos7720_port->write_urb_pool[i];
- dbg("URB:%d",i);
+ dbg("URB:%d", i);
break;
}
}
goto exit;
}
}
- transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);
+ transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
memcpy(urb->transfer_buffer, current_position, transfer_size);
usb_serial_debug_data(debug, &port->dev, __func__, transfer_size,
/* fill urb with data and submit */
usb_fill_bulk_urb(urb, serial->dev,
usb_sndbulkpipe(serial->dev,
- port->bulk_out_endpointAddress),
+ port->bulk_out_endpointAddress),
urb->transfer_buffer, transfer_size,
mos7720_bulk_out_data_callback, mos7720_port);
/* send it down the pipe */
- status = usb_submit_urb(urb,GFP_ATOMIC);
+ status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
err("%s - usb_submit_urb(write bulk) failed with status = %d",
__func__, status);
return bytes_sent;
}
-static void mos7720_throttle(struct usb_serial_port *port)
+static void mos7720_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7720_port;
- struct tty_struct *tty;
int status;
dbg("%s- port %d\n", __func__, port->number);
dbg("%s: Entering ..........", __func__);
- tty = port->tty;
- if (!tty) {
- dbg("%s - no tty available", __func__);
- return;
- }
-
/* if we are implementing XON/XOFF, send the stop character */
if (I_IXOFF(tty)) {
unsigned char stop_char = STOP_CHAR(tty);
- status = mos7720_write(port, &stop_char, 1);
+ status = mos7720_write(tty, port, &stop_char, 1);
if (status <= 0)
return;
}
}
}
-static void mos7720_unthrottle(struct usb_serial_port *port)
+static void mos7720_unthrottle(struct tty_struct *tty)
{
- struct tty_struct *tty;
- int status;
+ struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
+ int status;
if (mos7720_port == NULL)
return;
dbg("%s: Entering ..........", __func__);
- tty = port->tty;
- if (!tty) {
- dbg("%s - no tty available", __func__);
- return;
- }
-
/* if we are implementing XON/XOFF, send the start character */
if (I_IXOFF(tty)) {
unsigned char start_char = START_CHAR(tty);
- status = mos7720_write(port, &start_char, 1);
+ status = mos7720_write(tty, port, &start_char, 1);
if (status <= 0)
return;
}
port = mos7720_port->port;
serial = port->serial;
- /***********************************************
- * Init Sequence for higher rates
- ***********************************************/
+ /***********************************************
+ * Init Sequence for higher rates
+ ***********************************************/
dbg("Sending Setting Commands ..........");
port_number = port->number - port->serial->minor;
data = 0x0CF;
send_mos_cmd(serial, MOS_WRITE, port->number, 0x02, &data);
data = 0x00b;
- mos7720_port->shadowMCR = data;
+ mos7720_port->shadowMCR = data;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
data = 0x00b;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
- /***********************************************
- * Set for higher rates *
- ***********************************************/
+ /***********************************************
+ * Set for higher rates *
+ ***********************************************/
data = baud * 0x10;
- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1,&data);
+ send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
data = 0x003;
send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
data = 0x02b;
- mos7720_port->shadowMCR = data;
+ mos7720_port->shadowMCR = data;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
data = 0x02b;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
- /***********************************************
- * Set DLL/DLM
- ***********************************************/
+ /***********************************************
+ * Set DLL/DLM
+ ***********************************************/
data = mos7720_port->shadowLCR | UART_LCR_DLAB;
- mos7720_port->shadowLCR = data;
+ mos7720_port->shadowLCR = data;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
data = 0x001; /* DLL */
- send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
+ send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
data = 0x000; /* DLM */
- send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+ send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
- mos7720_port->shadowLCR = data;
+ mos7720_port->shadowLCR = data;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
return 0;
}
/* baud rate information */
-struct divisor_table_entry
-{
+struct divisor_table_entry {
__u32 baudrate;
__u16 divisor;
};
}
}
- /* After trying for all the standard baud rates *
- * Try calculating the divisor for this baud rate */
+ /* After trying for all the standard baud rates *
+ * Try calculating the divisor for this baud rate */
if (baudrate > 75 && baudrate < 230400) {
/* get the divisor */
custom = (__u16)(230400L / baudrate);
custom++;
*divisor = custom;
- dbg("Baud %d = %d",baudrate, custom);
+ dbg("Baud %d = %d", baudrate, custom);
return 0;
}
number = port->number - port->serial->minor;
dbg("%s - port = %d, baud = %d", __func__, port->number, baudrate);
- /* Calculate the Divisor */
+ /* Calculate the Divisor */
status = calc_baud_rate_divisor(baudrate, &divisor);
if (status) {
err("%s - bad baud rate", __func__);
return status;
}
- /* Enable access to divisor latch */
- data = mos7720_port->shadowLCR | UART_LCR_DLAB;
- mos7720_port->shadowLCR = data;
- send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data);
+ /* Enable access to divisor latch */
+ data = mos7720_port->shadowLCR | UART_LCR_DLAB;
+ mos7720_port->shadowLCR = data;
+ send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data);
/* Write the divisor */
data = ((unsigned char)(divisor & 0xff));
- send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data);
+ send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data);
data = ((unsigned char)((divisor & 0xff00) >> 8));
- send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data);
+ send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data);
- /* Disable access to divisor latch */
- data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
- mos7720_port->shadowLCR = data;
- send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data);
+ /* Disable access to divisor latch */
+ data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
+ mos7720_port->shadowLCR = data;
+ send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data);
return status;
}
* This routine is called to set the UART on the device to match
* the specified new settings.
*/
-static void change_port_settings(struct moschip_port *mos7720_port,
+static void change_port_settings(struct tty_struct *tty,
+ struct moschip_port *mos7720_port,
struct ktermios *old_termios)
{
struct usb_serial_port *port;
struct usb_serial *serial;
- struct tty_struct *tty;
int baud;
unsigned cflag;
unsigned iflag;
return;
}
- tty = mos7720_port->port->tty;
-
dbg("%s: Entering ..........", __func__);
lData = UART_LCR_WLEN8;
#define LCR_PAR_MASK 0x38 /* Mask for parity field */
/* Update the LCR with the correct value */
- mos7720_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
+ mos7720_port->shadowLCR &=
+ ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
mos7720_port->shadowLCR |= (lData | lParity | lStop);
/* Disable Interrupts */
data = 0x00;
- send_mos_cmd(serial,MOS_WRITE,port->number - port->serial->minor, UART_IER, &data);
+ send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
+ UART_IER, &data);
data = 0x00;
- send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
+ send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
data = 0xcf;
- send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
+ send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
/* Send the updated LCR value to the mos7720 */
data = mos7720_port->shadowLCR;
- send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data);
+ send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data);
- data = 0x00b;
- mos7720_port->shadowMCR = data;
- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
- data = 0x00b;
- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+ data = 0x00b;
+ mos7720_port->shadowMCR = data;
+ send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+ data = 0x00b;
+ send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
/* set up the MCR register and send it to the mos7720 */
mos7720_port->shadowMCR = UART_MCR_OUT2;
if (cflag & CRTSCTS) {
mos7720_port->shadowMCR |= (UART_MCR_XONANY);
-
- /* To set hardware flow control to the specified *
- * serial port, in SP1/2_CONTROL_REG */
+ /* To set hardware flow control to the specified *
+ * serial port, in SP1/2_CONTROL_REG */
if (port->number) {
data = 0x001;
send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT,
* this function is called by the tty driver when it wants to change the
* termios structure.
*/
-static void mos7720_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void mos7720_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
int status;
unsigned int cflag;
struct usb_serial *serial;
struct moschip_port *mos7720_port;
- struct tty_struct *tty;
serial = port->serial;
if (mos7720_port == NULL)
return;
- tty = port->tty;
-
-
if (!mos7720_port->open) {
dbg("%s - port not opened", __func__);
return;
}
- dbg("%s\n","setting termios - ASPIRE");
+ dbg("%s\n", "setting termios - ASPIRE");
cflag = tty->termios->c_cflag;
dbg("%s - port %d", __func__, port->number);
/* change the port settings to the new ones specified */
- change_port_settings(mos7720_port, old_termios);
+ change_port_settings(tty, mos7720_port, old_termios);
- if(!port->read_urb) {
- dbg("%s","URB KILLED !!!!!\n");
+ if (!port->read_urb) {
+ dbg("%s", "URB KILLED !!!!!\n");
return;
}
- if(port->read_urb->status != -EINPROGRESS) {
+ if (port->read_urb->status != -EINPROGRESS) {
port->read_urb->dev = serial->dev;
status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (status)
* transmit holding register is empty. This functionality
* allows an RS485 driver to be written in user space.
*/
-static int get_lsr_info(struct moschip_port *mos7720_port,
- unsigned int __user *value)
+static int get_lsr_info(struct tty_struct *tty,
+ struct moschip_port *mos7720_port, unsigned int __user *value)
{
int count;
unsigned int result = 0;
- count = mos7720_chars_in_buffer(mos7720_port->port);
+ count = mos7720_chars_in_buffer(tty);
if (count == 0) {
dbg("%s -- Empty", __func__);
result = TIOCSER_TEMT;
unsigned int __user *value)
{
unsigned int result = 0;
- struct tty_struct *tty = mos7720_port->port->tty;
+ struct tty_struct *tty = mos7720_port->port->port.tty;
if (!tty)
return -ENOIOCTLCMD;
if (mos7720_port == NULL)
return -1;
- port = (struct usb_serial_port*)mos7720_port->port;
+ port = (struct usb_serial_port *)mos7720_port->port;
mcr = mos7720_port->shadowMCR;
if (copy_from_user(&arg, value, sizeof(int)))
tmp.port = mos7720_port->port->number;
tmp.irq = 0;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
- tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
+ tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
tmp.baud_base = 9600;
tmp.close_delay = 5*HZ;
tmp.closing_wait = 30*HZ;
return 0;
}
-static int mos7720_ioctl(struct usb_serial_port *port, struct file *file,
+static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7720_port;
struct async_icount cnow;
struct async_icount cprev;
case TIOCSERGETLSR:
dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
- return get_lsr_info(mos7720_port, (unsigned int __user *)arg);
+ return get_lsr_info(tty, mos7720_port,
+ (unsigned int __user *)arg);
return 0;
+ /* FIXME: These should be using the mode methods */
case TIOCMBIS:
case TIOCMBIC:
case TIOCMSET:
- dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__,
- port->number);
+ dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET",
+ __func__, port->number);
return set_modem_info(mos7720_port, cmd,
(unsigned int __user *)arg);
return get_serial_info(mos7720_port,
(struct serial_struct __user *)arg);
- case TIOCSSERIAL:
- dbg("%s (%d) TIOCSSERIAL", __func__, port->number);
- break;
-
case TIOCMIWAIT:
dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
cprev = mos7720_port->icount;
if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
return 0;
}
cprev = cnow;
icount.buf_overrun = cnow.buf_overrun;
dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
- port->number, icount.rx, icount.tx );
+ port->number, icount.rx, icount.tx);
if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
return -EFAULT;
return 0;
/* Initialize all port interrupt end point to port 0 int
* endpoint. Our device has only one interrupt endpoint
* comman to all ports */
- serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress;
+ serial->port[i]->interrupt_in_endpointAddress =
+ serial->port[0]->interrupt_in_endpointAddress;
mos7720_port->port = serial->port[i];
usb_set_serial_port_data(serial->port[i], mos7720_port);
/* setting configuration feature to one */
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- (__u8)0x03, 0x00,0x01,0x00, NULL, 0x00, 5*HZ);
+ (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
- send_mos_cmd(serial,MOS_READ,0x00, UART_LSR, &data); // LSR For Port 1
- dbg("LSR:%x",data);
+ /* LSR For Port 1 */
+ send_mos_cmd(serial, MOS_READ, 0x00, UART_LSR, &data);
+ dbg("LSR:%x", data);
- send_mos_cmd(serial,MOS_READ,0x01, UART_LSR, &data); // LSR For Port 2
- dbg("LSR:%x",data);
+ /* LSR For Port 2 */
+ send_mos_cmd(serial, MOS_READ, 0x01, UART_LSR, &data);
+ dbg("LSR:%x", data);
return 0;
}
int i;
/* free private structure allocated for serial port */
- for (i=0; i < serial->num_ports; ++i) {
+ for (i = 0; i < serial->num_ports; ++i) {
kfree(usb_get_serial_port_data(serial->port[i]));
usb_set_serial_port_data(serial->port[i], NULL);
}
module_exit(moschip7720_exit);
/* Module information */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
#include <linux/serial.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
/*
* Version Information
* Defines used for sending commands to port
*/
-#define WAIT_FOR_EVER (HZ * 0 ) /* timeout urb is wait for ever */
-#define MOS_WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
+#define WAIT_FOR_EVER (HZ * 0) /* timeout urb is wait for ever */
+#define MOS_WDR_TIMEOUT (HZ * 5) /* default urb timeout */
#define MOS_PORT1 0x0200
#define MOS_PORT2 0x0300
#define MAX_NAME_LEN 64
-#define ZLP_REG1 0x3A //Zero_Flag_Reg1 58
-#define ZLP_REG5 0x3E //Zero_Flag_Reg5 62
+#define ZLP_REG1 0x3A /* Zero_Flag_Reg1 58 */
+#define ZLP_REG5 0x3E /* Zero_Flag_Reg5 62 */
/* For higher baud Rates use TIOCEXBAUD */
#define TIOCEXBAUD 0x5462
#define MOS_MSR_DELTA_RI 0x40
#define MOS_MSR_DELTA_CD 0x80
-// Serial Port register Address
+/* Serial Port register Address */
#define INTERRUPT_ENABLE_REGISTER ((__u16)(0x01))
#define FIFO_CONTROL_REGISTER ((__u16)(0x02))
#define LINE_CONTROL_REGISTER ((__u16)(0x03))
struct async_icount icount;
struct usb_serial_port *port; /* loop back to the owner of this object */
- /*Offsets */
+ /* Offsets */
__u8 SpRegOffset;
__u8 ControlRegOffset;
__u8 DcrRegOffset;
- //for processing control URBS in interrupt context
+ /* for processing control URBS in interrupt context */
struct urb *control_urb;
struct usb_ctrlrequest *dr;
char *ctrl_buf;
*/
static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg,
- __u16 * val)
+ __u16 *val)
{
struct usb_device *dev = port->serial->dev;
int ret = 0;
struct usb_device *dev = port->serial->dev;
val = val & 0x00ff;
- // For the UART control registers, the application number need to be Or'ed
+ /* For the UART control registers, the application number need
+ to be Or'ed */
if (port->serial->num_ports == 4) {
- val |=
- (((__u16) port->number - (__u16) (port->serial->minor)) +
- 1) << 8;
+ val |= (((__u16) port->number -
+ (__u16) (port->serial->minor)) + 1) << 8;
dbg("mos7840_set_uart_reg application number is %x\n", val);
} else {
if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) {
- val |=
- (((__u16) port->number -
+ val |= (((__u16) port->number -
(__u16) (port->serial->minor)) + 1) << 8;
dbg("mos7840_set_uart_reg application number is %x\n",
val);
* by passing usb_rcvctrlpipe function as parameter.
*/
static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg,
- __u16 * val)
+ __u16 *val)
{
struct usb_device *dev = port->serial->dev;
int ret = 0;
__u16 Wval;
- //dbg("application number is %4x \n",(((__u16)port->number - (__u16)(port->serial->minor))+1)<<8);
- /*Wval is same as application number */
+ /* dbg("application number is %4x \n",
+ (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */
+ /* Wval is same as application number */
if (port->serial->num_ports == 4) {
Wval =
(((__u16) port->number - (__u16) (port->serial->minor)) +
dbg("mos7840_get_uart_reg application number is %x\n", Wval);
} else {
if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) {
- Wval =
- (((__u16) port->number -
+ Wval = (((__u16) port->number -
(__u16) (port->serial->minor)) + 1) << 8;
dbg("mos7840_get_uart_reg application number is %x\n",
Wval);
} else {
- Wval =
- (((__u16) port->number -
+ Wval = (((__u16) port->number -
(__u16) (port->serial->minor)) + 2) << 8;
dbg("mos7840_get_uart_reg application number is %x\n",
Wval);
dbg("%s - %02x", __func__, new_lsr);
if (new_lsr & SERIAL_LSR_BI) {
- //
- // Parity and Framing errors only count if they
- // occur exclusive of a break being
- // received.
- //
+ /*
+ * Parity and Framing errors only count if they
+ * occur exclusive of a break being
+ * received.
+ */
new_lsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI);
}
}
static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
- __u16 * val)
+ __u16 *val)
{
struct usb_device *dev = mcs->port->serial->dev;
struct usb_ctrlrequest *dr = mcs->dr;
dr->bRequestType = MCS_RD_RTYPE;
dr->bRequest = MCS_RDREQ;
- dr->wValue = cpu_to_le16(Wval); //0;
+ dr->wValue = cpu_to_le16(Wval); /* 0 */
dr->wIndex = cpu_to_le16(reg);
dr->wLength = cpu_to_le16(2);
}
}
}
- if (!(rv < 0)) /* the completion handler for the control urb will resubmit */
+ if (!(rv < 0))
+ /* the completion handler for the control urb will resubmit */
return;
exit:
result = usb_submit_urb(urb, GFP_ATOMIC);
if (!port ||
mos7840_port_paranoia_check(port, function) ||
mos7840_serial_paranoia_check(port->serial, function)) {
- /* then say that we don't have a valid usb_serial thing, which will
- * end up genrating -ENODEV return values */
+ /* then say that we don't have a valid usb_serial thing,
+ * which will end up genrating -ENODEV return values */
return NULL;
}
dbg("%s", "Entering ........... \n");
if (urb->actual_length) {
- tty = mos7840_port->port->tty;
+ tty = mos7840_port->port->port.tty;
if (tty) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
/*****************************************************************************
* mos7840_bulk_out_data_callback
- * this is the callback function for when we have finished sending serial data
- * on the bulk out endpoint.
+ * this is the callback function for when we have finished sending
+ * serial data on the bulk out endpoint.
*****************************************************************************/
static void mos7840_bulk_out_data_callback(struct urb *urb)
dbg("%s \n", "Entering .........");
- tty = mos7840_port->port->tty;
+ tty = mos7840_port->port->port.tty;
if (tty && mos7840_port->open)
tty_wakeup(tty);
* Otherwise we return a negative error number.
*****************************************************************************/
-static int mos7840_open(struct usb_serial_port *port, struct file *filp)
+static int mos7840_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
int response;
int j;
continue;
}
- urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+ urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
+ GFP_KERNEL);
if (!urb->transfer_buffer) {
usb_free_urb(urb);
mos7840_port->write_urb_pool[j] = NULL;
* 0x08 : SP1/2 Control Reg
*****************************************************************************/
-//NEED to check the following Block
+ /* NEED to check the following Block */
- status = 0;
Data = 0x0;
status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
if (status < 0) {
dbg("writing Spreg failed\n");
return -1;
}
-//End of block to be checked
+ /* End of block to be checked */
- status = 0;
Data = 0x0;
- status =
- mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);
+ status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
+ &Data);
if (status < 0) {
dbg("Reading Controlreg failed\n");
return -1;
}
- Data |= 0x08; //Driver done bit
- Data |= 0x20; //rx_disable
- status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);
+ Data |= 0x08; /* Driver done bit */
+ Data |= 0x20; /* rx_disable */
+ status = mos7840_set_reg_sync(port,
+ mos7840_port->ControlRegOffset, Data);
if (status < 0) {
dbg("writing Controlreg failed\n");
return -1;
}
- //do register settings here
- // Set all regs to the device default values.
- ////////////////////////////////////
- // First Disable all interrupts.
- ////////////////////////////////////
-
+ /* do register settings here */
+ /* Set all regs to the device default values. */
+ /***********************************
+ * First Disable all interrupts.
+ ***********************************/
Data = 0x00;
status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
if (status < 0) {
dbg("disableing interrupts failed\n");
return -1;
}
- // Set FIFO_CONTROL_REGISTER to the default value
+ /* Set FIFO_CONTROL_REGISTER to the default value */
Data = 0x00;
status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
if (status < 0) {
status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
mos7840_port->shadowLCR = Data;
- Data |= SERIAL_LCR_DLAB; //data latch enable in LCR 0x80
+ Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */
status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
Data = 0x0c;
- status = 0;
status = mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
Data = 0x0;
- status = 0;
status = mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
Data = 0x00;
- status = 0;
status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
Data = Data & ~SERIAL_LCR_DLAB;
- status = 0;
status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
mos7840_port->shadowLCR = Data;
- //clearing Bulkin and Bulkout Fifo
+ /* clearing Bulkin and Bulkout Fifo */
Data = 0x0;
- status = 0;
status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
Data = Data | 0x0c;
- status = 0;
status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
Data = Data & ~0x0c;
- status = 0;
status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
- //Finally enable all interrupts
- Data = 0x0;
+ /* Finally enable all interrupts */
Data = 0x0c;
- status = 0;
status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
- //clearing rx_disable
+ /* clearing rx_disable */
Data = 0x0;
- status = 0;
- status =
- mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);
+ status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
+ &Data);
Data = Data & ~0x20;
- status = 0;
- status =
- mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);
+ status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
+ Data);
- // rx_negate
+ /* rx_negate */
Data = 0x0;
- status = 0;
- status =
- mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);
+ status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
+ &Data);
Data = Data | 0x10;
- status = 0;
- status =
- mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);
+ status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
+ Data);
/* force low_latency on so that our tty_push actually forces *
* the data through,otherwise it is scheduled, and with *
* high data rates (like with OHCI) data can get lost. */
+ if (tty)
+ tty->low_latency = 1;
- if (port->tty)
- port->tty->low_latency = 1;
-/* Check to see if we've set up our endpoint info yet *
- * (can't set it up in mos7840_startup as the structures *
- * were not set up at that time.) */
+ /* Check to see if we've set up our endpoint info yet *
+ * (can't set it up in mos7840_startup as the structures *
+ * were not set up at that time.) */
if (port0->open_ports == 1) {
if (serial->port[0]->interrupt_in_buffer == NULL) {
-
/* set up interrupt urb */
-
usb_fill_int_urb(serial->port[0]->interrupt_in_urb,
- serial->dev,
- usb_rcvintpipe(serial->dev,
- serial->port[0]->
- interrupt_in_endpointAddress),
- serial->port[0]->interrupt_in_buffer,
- serial->port[0]->interrupt_in_urb->
- transfer_buffer_length,
- mos7840_interrupt_callback,
- serial,
- serial->port[0]->interrupt_in_urb->
- interval);
+ serial->dev,
+ usb_rcvintpipe(serial->dev,
+ serial->port[0]->interrupt_in_endpointAddress),
+ serial->port[0]->interrupt_in_buffer,
+ serial->port[0]->interrupt_in_urb->
+ transfer_buffer_length,
+ mos7840_interrupt_callback,
+ serial,
+ serial->port[0]->interrupt_in_urb->interval);
/* start interrupt read for mos7840 *
* will continue as long as mos7840 is connected */
memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
/* initialize our port settings */
- mos7840_port->shadowMCR = MCR_MASTER_IE; /* Must set to enable ints! */
+ /* Must set to enable ints! */
+ mos7840_port->shadowMCR = MCR_MASTER_IE;
/* send a open port command */
mos7840_port->open = 1;
- //mos7840_change_port_settings(mos7840_port,old_termios);
+ /* mos7840_change_port_settings(mos7840_port,old_termios); */
mos7840_port->icount.tx = 0;
mos7840_port->icount.rx = 0;
- dbg("\n\nusb_serial serial:%p mos7840_port:%p\n usb_serial_port port:%p\n\n", serial, mos7840_port, port);
+ dbg("\n\nusb_serial serial:%p mos7840_port:%p\n usb_serial_port port:%p\n\n",
+ serial, mos7840_port, port);
return 0;
* been written, but hasn't made it out the port yet)
* If successful, we return the number of bytes left to be written in the
* system,
- * Otherwise we return a negative error number.
+ * Otherwise we return zero.
*****************************************************************************/
-static int mos7840_chars_in_buffer(struct usb_serial_port *port)
+static int mos7840_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
int i;
int chars = 0;
unsigned long flags;
if (mos7840_port_paranoia_check(port, __func__)) {
dbg("%s", "Invalid port \n");
- return -1;
+ return 0;
}
mos7840_port = mos7840_get_port_private(port);
if (mos7840_port == NULL) {
dbg("%s \n", "mos7840_break:leaving ...........");
- return -1;
+ return 0;
}
- spin_lock_irqsave(&mos7840_port->pool_lock,flags);
- for (i = 0; i < NUM_URBS; ++i) {
- if (mos7840_port->busy[i]) {
+ spin_lock_irqsave(&mos7840_port->pool_lock, flags);
+ for (i = 0; i < NUM_URBS; ++i)
+ if (mos7840_port->busy[i])
chars += URB_TRANSFER_BUFFER_SIZE;
- }
- }
- spin_unlock_irqrestore(&mos7840_port->pool_lock,flags);
+ spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
dbg("%s - returns %d", __func__, chars);
return chars;
* 3. A timeout of 3 seconds without activity has expired
*
************************************************************************/
-static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port)
+static void mos7840_block_until_tx_empty(struct tty_struct *tty,
+ struct moschip_port *mos7840_port)
{
int timeout = HZ / 10;
int wait = 30;
while (1) {
- count = mos7840_chars_in_buffer(mos7840_port->port);
+ count = mos7840_chars_in_buffer(tty);
/* Check for Buffer status */
- if (count <= 0) {
+ if (count <= 0)
return;
- }
/* Block the thread for a while */
interruptible_sleep_on_timeout(&mos7840_port->wait_chase,
* this function is called by the tty driver when a port is closed
*****************************************************************************/
-static void mos7840_close(struct usb_serial_port *port, struct file *filp)
+static void mos7840_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial;
struct moschip_port *mos7840_port;
}
}
- if (serial->dev) {
+ if (serial->dev)
/* flush and block until tx is empty */
- mos7840_block_until_tx_empty(mos7840_port);
- }
+ mos7840_block_until_tx_empty(tty, mos7840_port);
/* While closing port, shutdown all bulk read, write *
* and interrupt read if they exists */
if (serial->dev) {
-
if (mos7840_port->write_urb) {
dbg("%s", "Shutdown bulk write\n");
usb_kill_urb(mos7840_port->write_urb);
}
-
if (mos7840_port->read_urb) {
dbg("%s", "Shutdown bulk read\n");
usb_kill_urb(mos7840_port->read_urb);
}
if ((&mos7840_port->control_urb)) {
dbg("%s", "Shutdown control read\n");
- // usb_kill_urb (mos7840_port->control_urb);
-
+ /*/ usb_kill_urb (mos7840_port->control_urb); */
}
}
-// if(mos7840_port->ctrl_buf != NULL)
-// kfree(mos7840_port->ctrl_buf);
+/* if(mos7840_port->ctrl_buf != NULL) */
+/* kfree(mos7840_port->ctrl_buf); */
port0->open_ports--;
dbg("mos7840_num_open_ports in close%d:in port%d\n",
port0->open_ports, port->number);
if (mos7840_port->write_urb) {
/* if this urb had a transfer buffer already (old tx) free it */
-
- if (mos7840_port->write_urb->transfer_buffer != NULL) {
+ if (mos7840_port->write_urb->transfer_buffer != NULL)
kfree(mos7840_port->write_urb->transfer_buffer);
- }
usb_free_urb(mos7840_port->write_urb);
}
*
************************************************************************/
-static void mos7840_block_until_chase_response(struct moschip_port
- *mos7840_port)
+static void mos7840_block_until_chase_response(struct tty_struct *tty,
+ struct moschip_port *mos7840_port)
{
int timeout = 1 * HZ;
int wait = 10;
int count;
while (1) {
- count = mos7840_chars_in_buffer(mos7840_port->port);
+ count = mos7840_chars_in_buffer(tty);
/* Check for Buffer status */
- if (count <= 0) {
+ if (count <= 0)
return;
- }
/* Block the thread for a while */
interruptible_sleep_on_timeout(&mos7840_port->wait_chase,
* mos7840_break
* this function sends a break to the port
*****************************************************************************/
-static void mos7840_break(struct usb_serial_port *port, int break_state)
+static void mos7840_break(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned char data;
struct usb_serial *serial;
struct moschip_port *mos7840_port;
mos7840_port = mos7840_get_port_private(port);
- if (mos7840_port == NULL) {
+ if (mos7840_port == NULL)
return;
- }
-
- if (serial->dev) {
+ if (serial->dev)
/* flush and block until tx is empty */
- mos7840_block_until_chase_response(mos7840_port);
- }
+ mos7840_block_until_chase_response(tty, mos7840_port);
- if (break_state == -1) {
+ if (break_state == -1)
data = mos7840_port->shadowLCR | LCR_SET_BREAK;
- } else {
+ else
data = mos7840_port->shadowLCR & ~LCR_SET_BREAK;
- }
mos7840_port->shadowLCR = data;
dbg("mcs7840_break mos7840_port->shadowLCR is %x\n",
* Otherwise we return a negative error number.
*****************************************************************************/
-static int mos7840_write_room(struct usb_serial_port *port)
+static int mos7840_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
int i;
int room = 0;
unsigned long flags;
spin_lock_irqsave(&mos7840_port->pool_lock, flags);
for (i = 0; i < NUM_URBS; ++i) {
- if (!mos7840_port->busy[i]) {
+ if (!mos7840_port->busy[i])
room += URB_TRANSFER_BUFFER_SIZE;
- }
}
spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
* return a negative error number.
*****************************************************************************/
-static int mos7840_write(struct usb_serial_port *port,
+static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *data, int count)
{
int status;
struct moschip_port *mos7840_port;
struct usb_serial *serial;
struct urb *urb;
- //__u16 Data;
+ /* __u16 Data; */
const unsigned char *current_position = data;
unsigned char *data1;
dbg("%s \n", "entering ...........");
- //dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",mos7840_port->shadowLCR);
+ /* dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",
+ mos7840_port->shadowLCR); */
#ifdef NOTMOS7840
Data = 0x00;
- status = 0;
status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
mos7840_port->shadowLCR = Data;
dbg("mos7840_write: LINE_CONTROL_REGISTER is %x\n", Data);
dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",
mos7840_port->shadowLCR);
- //Data = 0x03;
- //status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data);
- //mos7840_port->shadowLCR=Data;//Need to add later
+ /* Data = 0x03; */
+ /* status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data); */
+ /* mos7840_port->shadowLCR=Data;//Need to add later */
- Data |= SERIAL_LCR_DLAB; //data latch enable in LCR 0x80
- status = 0;
+ Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */
status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
- //Data = 0x0c;
- //status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data);
+ /* Data = 0x0c; */
+ /* status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data); */
Data = 0x00;
- status = 0;
status = mos7840_get_uart_reg(port, DIVISOR_LATCH_LSB, &Data);
dbg("mos7840_write:DLL value is %x\n", Data);
Data = 0x0;
- status = 0;
status = mos7840_get_uart_reg(port, DIVISOR_LATCH_MSB, &Data);
dbg("mos7840_write:DLM value is %x\n", Data);
Data = Data & ~SERIAL_LCR_DLAB;
dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",
mos7840_port->shadowLCR);
- status = 0;
status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
#endif
mos7840_port->icount.tx += transfer_size;
smp_wmb();
dbg("mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx);
- exit:
-
+exit:
return bytes_sent;
}
* being read from the port.
*****************************************************************************/
-static void mos7840_throttle(struct usb_serial_port *port)
+static void mos7840_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7840_port;
- struct tty_struct *tty;
int status;
if (mos7840_port_paranoia_check(port, __func__)) {
dbg("%s", "Entering .......... \n");
- tty = port->tty;
- if (!tty) {
- dbg("%s - no tty available", __func__);
- return;
- }
-
/* if we are implementing XON/XOFF, send the stop character */
if (I_IXOFF(tty)) {
unsigned char stop_char = STOP_CHAR(tty);
- status = mos7840_write(port, &stop_char, 1);
- if (status <= 0) {
+ status = mos7840_write(tty, port, &stop_char, 1);
+ if (status <= 0)
return;
- }
}
-
/* if we are implementing RTS/CTS, toggle that line */
if (tty->termios->c_cflag & CRTSCTS) {
mos7840_port->shadowMCR &= ~MCR_RTS;
- status = 0;
- status =
- mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
+ status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
mos7840_port->shadowMCR);
-
- if (status < 0) {
+ if (status < 0)
return;
- }
}
return;
/*****************************************************************************
* mos7840_unthrottle
- * this function is called by the tty driver when it wants to resume the data
- * being read from the port (called after SerialThrottle is called)
+ * this function is called by the tty driver when it wants to resume
+ * the data being read from the port (called after mos7840_throttle is
+ * called)
*****************************************************************************/
-static void mos7840_unthrottle(struct usb_serial_port *port)
+static void mos7840_unthrottle(struct tty_struct *tty)
{
- struct tty_struct *tty;
+ struct usb_serial_port *port = tty->driver_data;
int status;
struct moschip_port *mos7840_port = mos7840_get_port_private(port);
dbg("%s", "Entering .......... \n");
- tty = port->tty;
- if (!tty) {
- dbg("%s - no tty available", __func__);
- return;
- }
-
/* if we are implementing XON/XOFF, send the start character */
if (I_IXOFF(tty)) {
unsigned char start_char = START_CHAR(tty);
- status = mos7840_write(port, &start_char, 1);
- if (status <= 0) {
+ status = mos7840_write(tty, port, &start_char, 1);
+ if (status <= 0)
return;
- }
}
/* if we are implementing RTS/CTS, toggle that line */
if (tty->termios->c_cflag & CRTSCTS) {
mos7840_port->shadowMCR |= MCR_RTS;
- status = 0;
- status =
- mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
+ status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
mos7840_port->shadowMCR);
- if (status < 0) {
+ if (status < 0)
return;
- }
}
-
- return;
}
-static int mos7840_tiocmget(struct usb_serial_port *port, struct file *file)
+static int mos7840_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7840_port;
unsigned int result;
__u16 msr;
__u16 mcr;
- int status = 0;
+ int status;
mos7840_port = mos7840_get_port_private(port);
dbg("%s - port %d", __func__, port->number);
return result;
}
-static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file,
+static int mos7840_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7840_port;
unsigned int mcr;
int status;
* baud rate.
*****************************************************************************/
static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor,
- __u16 * clk_sel_val)
+ __u16 *clk_sel_val)
{
dbg("%s - %d", __func__, baudRate);
/* Check for round off */
round1 = (__u16) (2304000L / baudrate);
round = (__u16) (round1 - (custom * 10));
- if (round > 4) {
+ if (round > 4)
custom++;
- }
*divisor = custom;
dbg(" Baud %d = %d\n", baudrate, custom);
dbg("%s - port = %d, baud = %d", __func__,
mos7840_port->port->number, baudRate);
- //reset clk_uart_sel in spregOffset
+ /* reset clk_uart_sel in spregOffset */
if (baudRate > 115200) {
#ifdef HW_flow_control
- //NOTE: need to see the pther register to modify
- //setting h/w flow control bit to 1;
- status = 0;
+ /* NOTE: need to see the pther register to modify */
+ /* setting h/w flow control bit to 1 */
Data = 0x2b;
mos7840_port->shadowMCR = Data;
- status =
- mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
+ Data);
if (status < 0) {
dbg("Writing spreg failed in set_serial_baud\n");
return -1;
} else {
#ifdef HW_flow_control
- //setting h/w flow control bit to 0;
- status = 0;
+ / *setting h/w flow control bit to 0 */
Data = 0xb;
mos7840_port->shadowMCR = Data;
- status =
- mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
+ Data);
if (status < 0) {
dbg("Writing spreg failed in set_serial_baud\n");
return -1;
}
- if (1) //baudRate <= 115200)
- {
+ if (1) { /* baudRate <= 115200) */
clk_sel_val = 0x0;
Data = 0x0;
- status = 0;
- status =
- mos7840_calc_baud_rate_divisor(baudRate, &divisor,
+ status = mos7840_calc_baud_rate_divisor(baudRate, &divisor,
&clk_sel_val);
- status =
- mos7840_get_reg_sync(port, mos7840_port->SpRegOffset,
- &Data);
+ status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset,
+ &Data);
if (status < 0) {
dbg("reading spreg failed in set_serial_baud\n");
return -1;
}
Data = (Data & 0x8f) | clk_sel_val;
- status = 0;
- status =
- mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
+ status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset,
+ Data);
if (status < 0) {
dbg("Writing spreg failed in set_serial_baud\n");
return -1;
mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
}
-
return status;
}
* the specified new settings.
*****************************************************************************/
-static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
- struct ktermios *old_termios)
+static void mos7840_change_port_settings(struct tty_struct *tty,
+ struct moschip_port *mos7840_port, struct ktermios *old_termios)
{
- struct tty_struct *tty;
int baud;
unsigned cflag;
unsigned iflag;
return;
}
- tty = mos7840_port->port->tty;
-
dbg("%s", "Entering .......... \n");
lData = LCR_BITS_8;
dbg("%s - parity = none", __func__);
}
- if (cflag & CMSPAR) {
+ if (cflag & CMSPAR)
lParity = lParity | 0x20;
- }
/* Change the Stop bit */
if (cflag & CSTOPB) {
/* set up the MCR register and send it to the mos7840 */
mos7840_port->shadowMCR = MCR_MASTER_IE;
- if (cflag & CBAUD) {
+ if (cflag & CBAUD)
mos7840_port->shadowMCR |= (MCR_DTR | MCR_RTS);
- }
- if (cflag & CRTSCTS) {
+ if (cflag & CRTSCTS)
mos7840_port->shadowMCR |= (MCR_XON_ANY);
-
- } else {
+ else
mos7840_port->shadowMCR &= ~(MCR_XON_ANY);
- }
Data = mos7840_port->shadowMCR;
mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
* the termios structure
*****************************************************************************/
-static void mos7840_set_termios(struct usb_serial_port *port,
+static void mos7840_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
struct ktermios *old_termios)
{
int status;
unsigned int cflag;
struct usb_serial *serial;
struct moschip_port *mos7840_port;
- struct tty_struct *tty;
dbg("mos7840_set_termios: START\n");
if (mos7840_port_paranoia_check(port, __func__)) {
dbg("%s", "Invalid port \n");
if (mos7840_port == NULL)
return;
- tty = port->tty;
-
if (!mos7840_port->open) {
dbg("%s - port not opened", __func__);
return;
/* change the port settings to the new ones specified */
- mos7840_change_port_settings(mos7840_port, old_termios);
+ mos7840_change_port_settings(tty, mos7840_port, old_termios);
if (!mos7840_port->read_urb) {
dbg("%s", "URB KILLED !!!!!\n");
* allows an RS485 driver to be written in user space.
*****************************************************************************/
-static int mos7840_get_lsr_info(struct moschip_port *mos7840_port,
+static int mos7840_get_lsr_info(struct tty_struct *tty,
unsigned int __user *value)
{
int count;
unsigned int result = 0;
- count = mos7840_chars_in_buffer(mos7840_port->port);
+ count = mos7840_chars_in_buffer(tty);
if (count == 0) {
dbg("%s -- Empty", __func__);
result = TIOCSER_TEMT;
* function to set modem info
*****************************************************************************/
+/* FIXME: Should be using the model control hooks */
+
static int mos7840_set_modem_info(struct moschip_port *mos7840_port,
unsigned int cmd, unsigned int __user *value)
{
mos7840_port->shadowMCR = mcr;
Data = mos7840_port->shadowMCR;
- status = 0;
status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
if (status < 0) {
dbg("setting MODEM_CONTROL_REGISTER Failed\n");
unsigned int result = 0;
__u16 msr;
unsigned int mcr = mos7840_port->shadowMCR;
- int status = 0;
- status =
- mos7840_get_uart_reg(mos7840_port->port, MODEM_STATUS_REGISTER,
- &msr);
+ mos7840_get_uart_reg(mos7840_port->port,
+ MODEM_STATUS_REGISTER, &msr);
result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) /* 0x002 */
|((mcr & MCR_RTS) ? TIOCM_RTS : 0) /* 0x004 */
|((msr & MOS7840_MSR_CTS) ? TIOCM_CTS : 0) /* 0x020 */
* this function handles any ioctl calls to the driver
*****************************************************************************/
-static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
+static int mos7840_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
void __user *argp = (void __user *)arg;
struct moschip_port *mos7840_port;
- struct tty_struct *tty;
struct async_icount cnow;
struct async_icount cprev;
if (mos7840_port == NULL)
return -1;
- tty = mos7840_port->port->tty;
-
dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
switch (cmd) {
case TIOCSERGETLSR:
dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
- return mos7840_get_lsr_info(mos7840_port, argp);
+ return mos7840_get_lsr_info(tty, argp);
return 0;
+ /* FIXME: use the modem hooks and remove this */
case TIOCMBIS:
case TIOCMBIC:
case TIOCMSET:
dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
cprev = mos7840_port->icount;
while (1) {
- //interruptible_sleep_on(&mos7840_port->delta_msr_wait);
+ /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
mos7840_port->delta_msr_cond = 0;
wait_event_interruptible(mos7840_port->delta_msr_wait,
(mos7840_port->
if (copy_to_user(argp, &icount, sizeof(icount)))
return -EFAULT;
return 0;
-
- case TIOCEXBAUD:
- return 0;
default:
break;
}
-
return -ENOIOCTLCMD;
}
goto error;
}
- /* Initialize all port interrupt end point to port 0 int endpoint *
- * Our device has only one interrupt end point comman to all port */
+ /* Initialize all port interrupt end point to port 0 int
+ * endpoint. Our device has only one interrupt end point
+ * common to all port */
mos7840_port->port = serial->port[i];
mos7840_set_port_private(serial->port[i], mos7840_port);
mos7840_port->DcrRegOffset = 0x1c;
}
mos7840_dump_serial_port(mos7840_port);
-
mos7840_set_port_private(serial->port[i], mos7840_port);
- //enable rx_disable bit in control register
-
- status =
- mos7840_get_reg_sync(serial->port[i],
- mos7840_port->ControlRegOffset, &Data);
+ /* enable rx_disable bit in control register */
+ status = mos7840_get_reg_sync(serial->port[i],
+ mos7840_port->ControlRegOffset, &Data);
if (status < 0) {
dbg("Reading ControlReg failed status-0x%x\n", status);
break;
} else
dbg("ControlReg Reading success val is %x, status%d\n",
Data, status);
- Data |= 0x08; //setting driver done bit
- Data |= 0x04; //sp1_bit to have cts change reflect in modem status reg
+ Data |= 0x08; /* setting driver done bit */
+ Data |= 0x04; /* sp1_bit to have cts change reflect in
+ modem status reg */
- //Data |= 0x20; //rx_disable bit
- status = 0;
- status =
- mos7840_set_reg_sync(serial->port[i],
+ /* Data |= 0x20; //rx_disable bit */
+ status = mos7840_set_reg_sync(serial->port[i],
mos7840_port->ControlRegOffset, Data);
if (status < 0) {
dbg("Writing ControlReg failed(rx_disable) status-0x%x\n", status);
dbg("ControlReg Writing success(rx_disable) status%d\n",
status);
- //Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 and 0x24 in DCR3
+ /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
+ and 0x24 in DCR3 */
Data = 0x01;
- status = 0;
- status =
- mos7840_set_reg_sync(serial->port[i],
- (__u16) (mos7840_port->DcrRegOffset +
- 0), Data);
+ status = mos7840_set_reg_sync(serial->port[i],
+ (__u16) (mos7840_port->DcrRegOffset + 0), Data);
if (status < 0) {
dbg("Writing DCR0 failed status-0x%x\n", status);
break;
dbg("DCR0 Writing success status%d\n", status);
Data = 0x05;
- status = 0;
- status =
- mos7840_set_reg_sync(serial->port[i],
- (__u16) (mos7840_port->DcrRegOffset +
- 1), Data);
+ status = mos7840_set_reg_sync(serial->port[i],
+ (__u16) (mos7840_port->DcrRegOffset + 1), Data);
if (status < 0) {
dbg("Writing DCR1 failed status-0x%x\n", status);
break;
dbg("DCR1 Writing success status%d\n", status);
Data = 0x24;
- status = 0;
- status =
- mos7840_set_reg_sync(serial->port[i],
- (__u16) (mos7840_port->DcrRegOffset +
- 2), Data);
+ status = mos7840_set_reg_sync(serial->port[i],
+ (__u16) (mos7840_port->DcrRegOffset + 2), Data);
if (status < 0) {
dbg("Writing DCR2 failed status-0x%x\n", status);
break;
} else
dbg("DCR2 Writing success status%d\n", status);
- // write values in clkstart0x0 and clkmulti 0x20
+ /* write values in clkstart0x0 and clkmulti 0x20 */
Data = 0x0;
- status = 0;
- status =
- mos7840_set_reg_sync(serial->port[i],
+ status = mos7840_set_reg_sync(serial->port[i],
CLK_START_VALUE_REGISTER, Data);
if (status < 0) {
dbg("Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status);
dbg("CLK_START_VALUE_REGISTER Writing success status%d\n", status);
Data = 0x20;
- status =
- mos7840_set_reg_sync(serial->port[i], CLK_MULTI_REGISTER,
- Data);
+ status = mos7840_set_reg_sync(serial->port[i],
+ CLK_MULTI_REGISTER, Data);
if (status < 0) {
dbg("Writing CLK_MULTI_REGISTER failed status-0x%x\n",
status);
dbg("CLK_MULTI_REGISTER Writing success status%d\n",
status);
- //write value 0x0 to scratchpad register
+ /* write value 0x0 to scratchpad register */
Data = 0x00;
- status =
- mos7840_set_uart_reg(serial->port[i], SCRATCH_PAD_REGISTER,
- Data);
+ status = mos7840_set_uart_reg(serial->port[i],
+ SCRATCH_PAD_REGISTER, Data);
if (status < 0) {
dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x\n",
status);
dbg("SCRATCH_PAD_REGISTER Writing success status%d\n",
status);
- //Zero Length flag register
+ /* Zero Length flag register */
if ((mos7840_port->port_num != 1)
&& (serial->num_ports == 2)) {
Data = 0xff;
- status = 0;
status = mos7840_set_reg_sync(serial->port[i],
- (__u16) (ZLP_REG1 +
- ((__u16)
- mos7840_port->
- port_num)),
- Data);
+ (__u16) (ZLP_REG1 +
+ ((__u16)mos7840_port->port_num)), Data);
dbg("ZLIP offset%x\n",
(__u16) (ZLP_REG1 +
- ((__u16) mos7840_port->port_num)));
+ ((__u16) mos7840_port->port_num)));
if (status < 0) {
dbg("Writing ZLP_REG%d failed status-0x%x\n",
i + 2, status);
i + 2, status);
} else {
Data = 0xff;
- status = 0;
status = mos7840_set_reg_sync(serial->port[i],
- (__u16) (ZLP_REG1 +
- ((__u16)
- mos7840_port->
- port_num) -
- 0x1), Data);
+ (__u16) (ZLP_REG1 +
+ ((__u16)mos7840_port->port_num) - 0x1), Data);
dbg("ZLIP offset%x\n",
(__u16) (ZLP_REG1 +
((__u16) mos7840_port->port_num) - 0x1));
}
mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
- mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
- if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || !mos7840_port->dr) {
+ mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
+ GFP_KERNEL);
+ if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
+ !mos7840_port->dr) {
status = -ENOMEM;
goto error;
}
}
- //Zero Length flag enable
+ /* Zero Length flag enable */
Data = 0x0f;
status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
if (status < 0) {
return;
}
- /* check for the ports to be closed,close the ports and disconnect */
+ /* check for the ports to be closed,close the ports and disconnect */
/* free private structure allocated for serial port *
* stop reads and writes on all ports */
/* Register with the usb */
retval = usb_register(&io_driver);
-
- if (retval)
- goto failed_usb_register;
-
if (retval == 0) {
dbg("%s\n", "Leaving...");
return 0;
}
-
- failed_usb_register:
usb_serial_deregister(&moschip7840_4port_device);
-
- failed_port_device_register:
-
+failed_port_device_register:
return retval;
}
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, data);
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
__func__, result);
}
-static int navman_open(struct usb_serial_port *port, struct file *filp)
+static int navman_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
int result = 0;
return result;
}
-static void navman_close(struct usb_serial_port *port, struct file *filp)
+static void navman_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
dbg("%s - port %d", __func__, port->number);
usb_kill_urb(port->interrupt_in_urb);
}
-static int navman_write(struct usb_serial_port *port,
+static int navman_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count)
{
dbg("%s - port %d", __func__, port->number);
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
* Please report both successes and troubles to the author at omninet@kroah.com
- *
+ *
* (05/30/2001) gkh
- * switched from using spinlock to a semaphore, which fixes lots of problems.
+ * switched from using spinlock to a semaphore, which fixes lots of
+ * problems.
*
* (04/08/2001) gb
* Identify version on module load.
*
* (11/01/2000) Adam J. Richter
* usb_device_id table support
- *
+ *
* (10/05/2000) gkh
* Fixed bug with urb->dev not being set properly, now that the usb
* core needs it.
- *
+ *
* (08/28/2000) gkh
* Added locks for SMP safeness.
- * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
+ * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
* than once.
* Fixed potential race in omninet_write_bulk_callback
*
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#define ZYXEL_VENDOR_ID 0x0586
#define ZYXEL_OMNINET_ID 0x1000
-#define BT_IGNITIONPRO_ID 0x2000 /* This one seems to be a re-branded ZyXEL device */
+/* This one seems to be a re-branded ZyXEL device */
+#define BT_IGNITIONPRO_ID 0x2000
/* function prototypes */
-static int omninet_open (struct usb_serial_port *port, struct file *filp);
-static void omninet_close (struct usb_serial_port *port, struct file *filp);
-static void omninet_read_bulk_callback (struct urb *urb);
-static void omninet_write_bulk_callback (struct urb *urb);
-static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int omninet_write_room (struct usb_serial_port *port);
-static void omninet_shutdown (struct usb_serial *serial);
-static int omninet_attach (struct usb_serial *serial);
-
-static struct usb_device_id id_table [] = {
+static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static void omninet_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static void omninet_read_bulk_callback(struct urb *urb);
+static void omninet_write_bulk_callback(struct urb *urb);
+static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+static int omninet_write_room(struct tty_struct *tty);
+static void omninet_shutdown(struct usb_serial *serial);
+static int omninet_attach(struct usb_serial *serial);
+
+static struct usb_device_id id_table[] = {
{ USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) },
{ USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) },
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver omninet_driver = {
.name = "omninet",
*
*/
-struct omninet_header
-{
+struct omninet_header {
__u8 oh_seq;
__u8 oh_len;
__u8 oh_xxx;
__u8 oh_pad;
};
-struct omninet_data
-{
- __u8 od_outseq; // Sequence number for bulk_out URBs
+struct omninet_data {
+ __u8 od_outseq; /* Sequence number for bulk_out URBs */
};
-static int omninet_attach (struct usb_serial *serial)
+static int omninet_attach(struct usb_serial *serial)
{
struct omninet_data *od;
struct usb_serial_port *port = serial->port[0];
- od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL );
- if( !od ) {
- err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct omninet_data));
+ od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL);
+ if (!od) {
+ err("%s- kmalloc(%Zd) failed.",
+ __func__, sizeof(struct omninet_data));
return -ENOMEM;
}
usb_set_serial_port_data(port, od);
return 0;
}
-static int omninet_open (struct usb_serial_port *port, struct file *filp)
+static int omninet_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
struct usb_serial_port *wport;
dbg("%s - port %d", __func__, port->number);
wport = serial->port[1];
- wport->tty = port->tty;
+ wport->port.tty = tty; /* FIXME */
/* Start reading from the device */
- usb_fill_bulk_urb(port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
- omninet_read_bulk_callback, port);
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ omninet_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
- if (result) {
- err("%s - failed submitting read urb, error %d", __func__, result);
- }
-
+ if (result)
+ err("%s - failed submitting read urb, error %d",
+ __func__, result);
return result;
}
-static void omninet_close (struct usb_serial_port *port, struct file * filp)
+static void omninet_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
dbg("%s - port %d", __func__, port->number);
usb_kill_urb(port->read_urb);
#define OMNINET_HEADERLEN sizeof(struct omninet_header)
#define OMNINET_BULKOUTSIZE (64 - OMNINET_HEADERLEN)
-static void omninet_read_bulk_callback (struct urb *urb)
+static void omninet_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
unsigned char *data = urb->transfer_buffer;
struct omninet_header *header = (struct omninet_header *) &data[0];
int status = urb->status;
- int i;
int result;
+ int i;
dbg("%s - port %d", __func__, port->number);
return;
}
- if ((debug) && (header->oh_xxx != 0x30)) {
+ if (debug && header->oh_xxx != 0x30) {
if (urb->actual_length) {
- printk (KERN_DEBUG __FILE__ ": omninet_read %d: ", header->oh_len);
- for (i = 0; i < (header->oh_len + OMNINET_HEADERLEN); i++) {
- printk ("%.2x ", data[i]);
- }
- printk ("\n");
+ printk(KERN_DEBUG __FILE__
+ ": omninet_read %d: ", header->oh_len);
+ for (i = 0; i < (header->oh_len +
+ OMNINET_HEADERLEN); i++)
+ printk("%.2x ", data[i]);
+ printk("\n");
}
}
if (urb->actual_length && header->oh_len) {
- for (i = 0; i < header->oh_len; i++) {
- tty_insert_flip_char(port->tty, data[OMNINET_DATAOFFSET + i], 0);
- }
- tty_flip_buffer_push(port->tty);
+ tty_insert_flip_string(port->port.tty,
+ data + OMNINET_DATAOFFSET, header->oh_len);
+ tty_flip_buffer_push(port->port.tty);
}
/* Continue trying to always read */
- usb_fill_bulk_urb(urb, port->serial->dev,
- usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
- urb->transfer_buffer, urb->transfer_buffer_length,
- omninet_read_bulk_callback, port);
+ usb_fill_bulk_urb(urb, port->serial->dev,
+ usb_rcvbulkpipe(port->serial->dev,
+ port->bulk_in_endpointAddress),
+ urb->transfer_buffer, urb->transfer_buffer_length,
+ omninet_read_bulk_callback, port);
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d", __func__, result);
+ err("%s - failed resubmitting read urb, error %d",
+ __func__, result);
return;
}
-static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
- struct usb_serial *serial = port->serial;
- struct usb_serial_port *wport = serial->port[1];
+ struct usb_serial *serial = port->serial;
+ struct usb_serial_port *wport = serial->port[1];
- struct omninet_data *od = usb_get_serial_port_data(port);
- struct omninet_header *header = (struct omninet_header *) wport->write_urb->transfer_buffer;
+ struct omninet_data *od = usb_get_serial_port_data(port);
+ struct omninet_header *header = (struct omninet_header *)
+ wport->write_urb->transfer_buffer;
int result;
if (count == 0) {
dbg("%s - write request of 0 bytes", __func__);
- return (0);
+ return 0;
}
spin_lock_bh(&wport->lock);
count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count;
- memcpy (wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count);
+ memcpy(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET,
+ buf, count);
- usb_serial_debug_data(debug, &port->dev, __func__, count, wport->write_urb->transfer_buffer);
+ usb_serial_debug_data(debug, &port->dev, __func__, count,
+ wport->write_urb->transfer_buffer);
header->oh_seq = od->od_outseq++;
header->oh_len = count;
result = usb_submit_urb(wport->write_urb, GFP_ATOMIC);
if (result) {
wport->write_urb_busy = 0;
- err("%s - failed submitting write urb, error %d", __func__, result);
+ err("%s - failed submitting write urb, error %d",
+ __func__, result);
} else
result = count;
}
-static int omninet_write_room (struct usb_serial_port *port)
+static int omninet_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
struct usb_serial_port *wport = serial->port[1];
dbg("%s - returns %d", __func__, room);
- return (room);
+ return room;
}
-static void omninet_write_bulk_callback (struct urb *urb)
+static void omninet_write_bulk_callback(struct urb *urb)
{
-/* struct omninet_header *header = (struct omninet_header *) urb->transfer_buffer; */
+/* struct omninet_header *header = (struct omninet_header *)
+ urb->transfer_buffer; */
struct usb_serial_port *port = urb->context;
int status = urb->status;
}
-static void omninet_shutdown (struct usb_serial *serial)
+static void omninet_shutdown(struct usb_serial *serial)
{
struct usb_serial_port *wport = serial->port[1];
struct usb_serial_port *port = serial->port[0];
- dbg ("%s", __func__);
+ dbg("%s", __func__);
usb_kill_urb(wport->write_urb);
kfree(usb_get_serial_port_data(port));
}
-static int __init omninet_init (void)
+static int __init omninet_init(void)
{
int retval;
retval = usb_serial_register(&zyxel_omninet_device);
}
-static void __exit omninet_exit (void)
+static void __exit omninet_exit(void)
{
- usb_deregister (&omninet_driver);
- usb_serial_deregister (&zyxel_omninet_device);
+ usb_deregister(&omninet_driver);
+ usb_serial_deregister(&zyxel_omninet_device);
}
module_init(omninet_init);
module_exit(omninet_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
#include <linux/usb/serial.h>
/* Function prototypes */
-static int option_open(struct usb_serial_port *port, struct file *filp);
-static void option_close(struct usb_serial_port *port, struct file *filp);
+static int option_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static void option_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
static int option_startup(struct usb_serial *serial);
static void option_shutdown(struct usb_serial *serial);
-static void option_rx_throttle(struct usb_serial_port *port);
-static void option_rx_unthrottle(struct usb_serial_port *port);
-static int option_write_room(struct usb_serial_port *port);
+static int option_write_room(struct tty_struct *tty);
static void option_instat_callback(struct urb *urb);
-static int option_write(struct usb_serial_port *port,
+static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
-
-static int option_chars_in_buffer(struct usb_serial_port *port);
-static int option_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg);
-static void option_set_termios(struct usb_serial_port *port,
- struct ktermios *old);
-static void option_break_ctl(struct usb_serial_port *port, int break_state);
-static int option_tiocmget(struct usb_serial_port *port, struct file *file);
-static int option_tiocmset(struct usb_serial_port *port, struct file *file,
+static int option_chars_in_buffer(struct tty_struct *tty);
+static void option_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
+static int option_tiocmget(struct tty_struct *tty, struct file *file);
+static int option_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
-static int option_send_setup(struct usb_serial_port *port);
+static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port);
/* Vendor and product IDs */
#define OPTION_VENDOR_ID 0x0AF0
.write = option_write,
.write_room = option_write_room,
.chars_in_buffer = option_chars_in_buffer,
- .throttle = option_rx_throttle,
- .unthrottle = option_rx_unthrottle,
- .ioctl = option_ioctl,
.set_termios = option_set_termios,
- .break_ctl = option_break_ctl,
.tiocmget = option_tiocmget,
.tiocmset = option_tiocmset,
.attach = option_startup,
return 0;
failed_driver_register:
- usb_serial_deregister (&option_1port_device);
+ usb_serial_deregister(&option_1port_device);
failed_1port_device_register:
return retval;
}
static void __exit option_exit(void)
{
- usb_deregister (&option_driver);
- usb_serial_deregister (&option_1port_device);
+ usb_deregister(&option_driver);
+ usb_serial_deregister(&option_1port_device);
}
module_init(option_init);
module_exit(option_exit);
-static void option_rx_throttle(struct usb_serial_port *port)
-{
- dbg("%s", __func__);
-}
-
-static void option_rx_unthrottle(struct usb_serial_port *port)
-{
- dbg("%s", __func__);
-}
-
-static void option_break_ctl(struct usb_serial_port *port, int break_state)
-{
- /* Unfortunately, I don't know how to send a break */
- dbg("%s", __func__);
-}
-
-static void option_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void option_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
dbg("%s", __func__);
/* Doesn't support option setting */
- tty_termios_copy_hw(port->tty->termios, old_termios);
- option_send_setup(port);
+ tty_termios_copy_hw(tty->termios, old_termios);
+ option_send_setup(tty, port);
}
-static int option_tiocmget(struct usb_serial_port *port, struct file *file)
+static int option_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned int value;
struct option_port_private *portdata;
return value;
}
-static int option_tiocmset(struct usb_serial_port *port, struct file *file,
+static int option_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct option_port_private *portdata;
portdata = usb_get_serial_port_data(port);
portdata->rts_state = 0;
if (clear & TIOCM_DTR)
portdata->dtr_state = 0;
- return option_send_setup(port);
-}
-
-static int option_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- return -ENOIOCTLCMD;
+ return option_send_setup(tty, port);
}
/* Write */
-static int option_write(struct usb_serial_port *port,
+static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count)
{
struct option_port_private *portdata;
i = 0;
left = count;
- for (i=0; left > 0 && i < N_OUT_URB; i++) {
+ for (i = 0; left > 0 && i < N_OUT_URB; i++) {
todo = left;
if (todo > OUT_BUFLEN)
todo = OUT_BUFLEN;
usb_pipeendpoint(this_urb->pipe), i);
/* send the data */
- memcpy (this_urb->transfer_buffer, buf, todo);
+ memcpy(this_urb->transfer_buffer, buf, todo);
this_urb->transfer_buffer_length = todo;
this_urb->dev = port->serial->dev;
dbg("%s: nonzero status: %d on endpoint %02x.",
__func__, status, endpoint);
} else {
- tty = port->tty;
+ tty = port->port.tty;
if (urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
}
/* Resubmit urb so we continue receiving */
- if (port->open_count && status != -ESHUTDOWN) {
+ if (port->port.count && status != -ESHUTDOWN) {
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err)
printk(KERN_ERR "%s: resubmit read urb failed. "
struct usb_serial *serial = port->serial;
dbg("%s", __func__);
- dbg("%s: urb %p port %p has data %p", __func__,urb,port,portdata);
+ dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata);
if (status == 0) {
struct usb_ctrlrequest *req_pkt =
portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
portdata->ri_state = ((signals & 0x08) ? 1 : 0);
- if (port->tty && !C_CLOCAL(port->tty) &&
+ if (port->port.tty && !C_CLOCAL(port->port.tty) &&
old_dcd_state && !portdata->dcd_state)
- tty_hangup(port->tty);
+ tty_hangup(port->port.tty);
} else {
dbg("%s: type %x req %x", __func__,
- req_pkt->bRequestType,req_pkt->bRequest);
+ req_pkt->bRequestType, req_pkt->bRequest);
}
} else
dbg("%s: error %d", __func__, status);
}
}
-static int option_write_room(struct usb_serial_port *port)
+static int option_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct option_port_private *portdata;
int i;
int data_len = 0;
portdata = usb_get_serial_port_data(port);
- for (i=0; i < N_OUT_URB; i++) {
+ for (i = 0; i < N_OUT_URB; i++) {
this_urb = portdata->out_urbs[i];
if (this_urb && !test_bit(i, &portdata->out_busy))
data_len += OUT_BUFLEN;
return data_len;
}
-static int option_chars_in_buffer(struct usb_serial_port *port)
+static int option_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct option_port_private *portdata;
int i;
int data_len = 0;
portdata = usb_get_serial_port_data(port);
- for (i=0; i < N_OUT_URB; i++) {
+ for (i = 0; i < N_OUT_URB; i++) {
this_urb = portdata->out_urbs[i];
/* FIXME: This locking is insufficient as this_urb may
go unused during the test */
return data_len;
}
-static int option_open(struct usb_serial_port *port, struct file *filp)
+static int option_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct option_port_private *portdata;
struct usb_serial *serial = port->serial;
/* Reset low level data toggle and start reading from endpoints */
for (i = 0; i < N_IN_URB; i++) {
urb = portdata->in_urbs[i];
- if (! urb)
+ if (!urb)
continue;
if (urb->dev != serial->dev) {
dbg("%s: dev %p != %p", __func__,
/* Reset low level data toggle on out endpoints */
for (i = 0; i < N_OUT_URB; i++) {
urb = portdata->out_urbs[i];
- if (! urb)
+ if (!urb)
continue;
urb->dev = serial->dev;
/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
usb_pipeout(urb->pipe), 0); */
}
- port->tty->low_latency = 1;
+ if (tty)
+ tty->low_latency = 1;
- option_send_setup(port);
+ option_send_setup(tty, port);
- return (0);
+ return 0;
}
-static void option_close(struct usb_serial_port *port, struct file *filp)
+static void option_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
int i;
struct usb_serial *serial = port->serial;
if (serial->dev) {
mutex_lock(&serial->disc_mutex);
if (!serial->disconnected)
- option_send_setup(port);
+ option_send_setup(tty, port);
mutex_unlock(&serial->disc_mutex);
/* Stop reading/writing urbs */
for (i = 0; i < N_OUT_URB; i++)
usb_kill_urb(portdata->out_urbs[i]);
}
- port->tty = NULL;
+ port->port.tty = NULL; /* FIXME */
}
/* Helper functions used by option_setup_urbs */
/* Setup urbs */
static void option_setup_urbs(struct usb_serial *serial)
{
- int i,j;
+ int i, j;
struct usb_serial_port *port;
struct option_port_private *portdata;
port = serial->port[i];
portdata = usb_get_serial_port_data(port);
- /* Do indat endpoints first */
+ /* Do indat endpoints first */
for (j = 0; j < N_IN_URB; ++j) {
- portdata->in_urbs[j] = option_setup_urb (serial,
- port->bulk_in_endpointAddress, USB_DIR_IN, port,
- portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
+ portdata->in_urbs[j] = option_setup_urb(serial,
+ port->bulk_in_endpointAddress,
+ USB_DIR_IN, port,
+ portdata->in_buffer[j],
+ IN_BUFLEN, option_indat_callback);
}
/* outdat endpoints */
for (j = 0; j < N_OUT_URB; ++j) {
- portdata->out_urbs[j] = option_setup_urb (serial,
- port->bulk_out_endpointAddress, USB_DIR_OUT, port,
- portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
+ portdata->out_urbs[j] = option_setup_urb(serial,
+ port->bulk_out_endpointAddress,
+ USB_DIR_OUT, port,
+ portdata->out_buffer[j],
+ OUT_BUFLEN, option_outdat_callback);
}
}
}
* This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN
* CDC.
*/
-static int option_send_setup(struct usb_serial_port *port)
+static int option_send_setup(struct tty_struct *tty,
+ struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct option_port_private *portdata;
portdata = usb_get_serial_port_data(port);
- if (port->tty) {
+ if (tty) {
int val = 0;
if (portdata->dtr_state)
val |= 0x01;
val |= 0x02;
return usb_control_msg(serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
- 0x22,0x21,val,ifNum,NULL,0,USB_CTRL_SET_TIMEOUT);
+ usb_rcvctrlpipe(serial->dev, 0),
+ 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT);
}
-
return 0;
}
if (!portdata) {
dbg("%s: kmalloc for option_port_private (%d) failed!.",
__func__, i);
- return (1);
+ return 1;
}
for (j = 0; j < N_IN_URB; j++) {
usb_set_serial_port_data(port, portdata);
- if (! port->interrupt_in_urb)
+ if (!port->interrupt_in_urb)
continue;
err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (err)
dbg("%s: submit irq_in urb failed %d",
__func__, err);
}
-
option_setup_urbs(serial);
-
- return (0);
+ return 0;
bail_out_error2:
for (j = 0; j < N_OUT_URB; j++)
for (j = 0; j < N_IN_URB; j++) {
if (portdata->in_urbs[j]) {
usb_free_urb(portdata->in_urbs[j]);
- free_page((unsigned long)portdata->in_buffer[j]);
+ free_page((unsigned long)
+ portdata->in_buffer[j]);
portdata->in_urbs[j] = NULL;
}
}
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
* TODO:
* - implement correct flushing for ioctls and oti6858_close()
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "oti6858.h"
#define OTI6858_DESCRIPTION \
#define OTI6858_CTRL_PKT_SIZE sizeof(struct oti6858_control_pkt)
#define OTI6858_CTRL_EQUALS_PENDING(a, priv) \
- ( ((a)->divisor == (priv)->pending_setup.divisor) \
+ (((a)->divisor == (priv)->pending_setup.divisor) \
&& ((a)->control == (priv)->pending_setup.control) \
- && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt) )
+ && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt))
/* function prototypes */
-static int oti6858_open(struct usb_serial_port *port, struct file *filp);
-static void oti6858_close(struct usb_serial_port *port, struct file *filp);
-static void oti6858_set_termios(struct usb_serial_port *port,
- struct ktermios *old);
-static int oti6858_ioctl(struct usb_serial_port *port, struct file *file,
+static int oti6858_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void oti6858_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void oti6858_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
+static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg);
static void oti6858_read_int_callback(struct urb *urb);
static void oti6858_read_bulk_callback(struct urb *urb);
static void oti6858_write_bulk_callback(struct urb *urb);
-static int oti6858_write(struct usb_serial_port *port,
+static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
-static int oti6858_write_room(struct usb_serial_port *port);
-static void oti6858_break_ctl(struct usb_serial_port *port, int break_state);
-static int oti6858_chars_in_buffer(struct usb_serial_port *port);
-static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file);
-static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file,
+static int oti6858_write_room(struct tty_struct *tty);
+static int oti6858_chars_in_buffer(struct tty_struct *tty);
+static int oti6858_tiocmget(struct tty_struct *tty, struct file *file);
+static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static int oti6858_startup(struct usb_serial *serial);
static void oti6858_shutdown(struct usb_serial *serial);
.close = oti6858_close,
.write = oti6858_write,
.ioctl = oti6858_ioctl,
- .break_ctl = oti6858_break_ctl,
.set_termios = oti6858_set_termios,
.tiocmget = oti6858_tiocmget,
.tiocmset = oti6858_tiocmset,
struct delayed_work delayed_setup_work;
wait_queue_head_t intr_wait;
- struct usb_serial_port *port; /* USB port with which associated */
+ struct usb_serial_port *port; /* USB port with which associated */
};
#undef dbg
static void setup_line(struct work_struct *work)
{
- struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_setup_work.work);
+ struct oti6858_private *priv = container_of(work,
+ struct oti6858_private, delayed_setup_work.work);
struct usb_serial_port *port = priv->port;
struct oti6858_control_pkt *new_setup;
unsigned long flags;
dbg("%s(port = %d)", __func__, port->number);
- if ((new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) {
+ new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
+ if (new_setup == NULL) {
dev_err(&port->dev, "%s(): out of memory!\n", __func__);
/* we will try again */
- schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
+ schedule_delayed_work(&priv->delayed_setup_work,
+ msecs_to_jiffies(2));
return;
}
dev_err(&port->dev, "%s(): error reading status\n", __func__);
kfree(new_setup);
/* we will try again */
- schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
+ schedule_delayed_work(&priv->delayed_setup_work,
+ msecs_to_jiffies(2));
return;
}
void send_data(struct work_struct *work)
{
- struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_write_work.work);
+ struct oti6858_private *priv = container_of(work,
+ struct oti6858_private, delayed_write_work.work);
struct usb_serial_port *port = priv->port;
int count = 0, result;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
if (priv->flags.write_urb_in_use) {
spin_unlock_irqrestore(&priv->lock, flags);
- schedule_delayed_work(&priv->delayed_write_work, msecs_to_jiffies(2));
+ schedule_delayed_work(&priv->delayed_write_work,
+ msecs_to_jiffies(2));
return;
}
priv->flags.write_urb_in_use = 1;
static int oti6858_startup(struct usb_serial *serial)
{
- struct usb_serial_port *port = serial->port[0];
- struct oti6858_private *priv;
+ struct usb_serial_port *port = serial->port[0];
+ struct oti6858_private *priv;
int i;
for (i = 0; i < serial->num_ports; ++i) {
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->intr_wait);
-// INIT_WORK(&priv->setup_work, setup_line, serial->port[i]);
-// INIT_WORK(&priv->write_work, send_data, serial->port[i]);
+/* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */
+/* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */
priv->port = port;
INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
return -ENOMEM;
}
-static int oti6858_write(struct usb_serial_port *port,
+static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count)
{
struct oti6858_private *priv = usb_get_serial_port_data(port);
return count;
}
-static int oti6858_write_room(struct usb_serial_port *port)
+static int oti6858_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct oti6858_private *priv = usb_get_serial_port_data(port);
int room = 0;
unsigned long flags;
return room;
}
-static int oti6858_chars_in_buffer(struct usb_serial_port *port)
+static int oti6858_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct oti6858_private *priv = usb_get_serial_port_data(port);
int chars = 0;
unsigned long flags;
return chars;
}
-static void oti6858_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void oti6858_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct oti6858_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
dbg("%s(port = %d)", __func__, port->number);
- if (!port->tty || !port->tty->termios) {
+ if (!tty) {
dbg("%s(): no tty structures", __func__);
return;
}
spin_lock_irqsave(&priv->lock, flags);
if (!priv->flags.termios_initialized) {
- *(port->tty->termios) = tty_std_termios;
- port->tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
+ *(tty->termios) = tty_std_termios;
+ tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
+ tty->termios->c_ispeed = 38400;
+ tty->termios->c_ospeed = 38400;
priv->flags.termios_initialized = 1;
- port->tty->termios->c_ispeed = 38400;
- port->tty->termios->c_ospeed = 38400;
}
spin_unlock_irqrestore(&priv->lock, flags);
- cflag = port->tty->termios->c_cflag;
+ cflag = tty->termios->c_cflag;
spin_lock_irqsave(&priv->lock, flags);
divisor = priv->pending_setup.divisor;
frame_fmt &= ~FMT_DATA_BITS_MASK;
switch (cflag & CSIZE) {
- case CS5:
- frame_fmt |= FMT_DATA_BITS_5;
- break;
- case CS6:
- frame_fmt |= FMT_DATA_BITS_6;
- break;
- case CS7:
- frame_fmt |= FMT_DATA_BITS_7;
- break;
- default:
- case CS8:
- frame_fmt |= FMT_DATA_BITS_8;
- break;
+ case CS5:
+ frame_fmt |= FMT_DATA_BITS_5;
+ break;
+ case CS6:
+ frame_fmt |= FMT_DATA_BITS_6;
+ break;
+ case CS7:
+ frame_fmt |= FMT_DATA_BITS_7;
+ break;
+ default:
+ case CS8:
+ frame_fmt |= FMT_DATA_BITS_8;
+ break;
}
/* manufacturer claims that this device can work with baud rates
* guarantee that any other baud rate will work (especially
* the higher ones)
*/
- br = tty_get_baud_rate(port->tty);
+ br = tty_get_baud_rate(tty);
if (br == 0) {
divisor = 0;
} else {
new_divisor = (96000000 + 8 * br) / (16 * br);
real_br = 96000000 / (16 * new_divisor);
divisor = cpu_to_le16(new_divisor);
- tty_encode_baud_rate(port->tty, real_br, real_br);
+ tty_encode_baud_rate(tty, real_br, real_br);
}
frame_fmt &= ~FMT_STOP_BITS_MASK;
- if ((cflag & CSTOPB) != 0) {
+ if ((cflag & CSTOPB) != 0)
frame_fmt |= FMT_STOP_BITS_2;
- } else {
+ else
frame_fmt |= FMT_STOP_BITS_1;
- }
frame_fmt &= ~FMT_PARITY_MASK;
if ((cflag & PARENB) != 0) {
- if ((cflag & PARODD) != 0) {
+ if ((cflag & PARODD) != 0)
frame_fmt |= FMT_PARITY_ODD;
- } else {
+ else
frame_fmt |= FMT_PARITY_EVEN;
- }
} else {
frame_fmt |= FMT_PARITY_NONE;
}
spin_unlock_irqrestore(&priv->lock, flags);
}
-static int oti6858_open(struct usb_serial_port *port, struct file *filp)
+static int oti6858_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct oti6858_private *priv = usb_get_serial_port_data(port);
struct ktermios tmp_termios;
usb_clear_halt(serial->dev, port->write_urb->pipe);
usb_clear_halt(serial->dev, port->read_urb->pipe);
- if (port->open_count != 1)
+ if (port->port.count != 1)
return 0;
- if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) {
+ buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
+ if (buf == NULL) {
dev_err(&port->dev, "%s(): out of memory!\n", __func__);
return -ENOMEM;
}
if (result != 0) {
dev_err(&port->dev, "%s(): usb_submit_urb() failed"
" with error %d\n", __func__, result);
- oti6858_close(port, NULL);
+ oti6858_close(tty, port, NULL);
return -EPROTO;
}
/* setup termios */
- if (port->tty)
- oti6858_set_termios(port, &tmp_termios);
+ if (tty)
+ oti6858_set_termios(tty, port, &tmp_termios);
return 0;
}
-static void oti6858_close(struct usb_serial_port *port, struct file *filp)
+static void oti6858_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct oti6858_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
timeout = 30 * HZ; /* PL2303_CLOSING_WAIT */
init_waitqueue_entry(&wait, current);
- add_wait_queue(&port->tty->write_wait, &wait);
+ add_wait_queue(&tty->write_wait, &wait);
dbg("%s(): entering wait loop", __func__);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irqsave(&priv->lock, flags);
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->tty->write_wait, &wait);
+ remove_wait_queue(&tty->write_wait, &wait);
dbg("%s(): after wait loop", __func__);
/* clear out any remaining data in the buffer */
/* data is in the buffer to compute a delay */
/* that is not unnecessarily long) */
/* FIXME
- bps = tty_get_baud_rate(port->tty);
+ bps = tty_get_baud_rate(tty);
if (bps > 1200)
timeout = max((HZ*2560)/bps,HZ/10);
else
usb_kill_urb(port->interrupt_in_urb);
/*
- if (port->tty && (port->tty->termios->c_cflag) & HUPCL) {
+ if (tty && (tty->termios->c_cflag) & HUPCL) {
// drop DTR and RTS
spin_lock_irqsave(&priv->lock, flags);
priv->pending_setup.control &= ~CONTROL_MASK;
*/
}
-static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file,
+static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct oti6858_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
u8 control;
if ((clear & TIOCM_DTR) != 0)
control &= ~CONTROL_DTR_HIGH;
- if (control != priv->pending_setup.control) {
+ if (control != priv->pending_setup.control)
priv->pending_setup.control = control;
- }
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file)
+static int oti6858_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct oti6858_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
unsigned pin_state;
spin_unlock_irqrestore(&priv->lock, flags);
while (1) {
- wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev);
+ wait_event_interruptible(priv->intr_wait,
+ priv->status.pin_state != prev);
if (signal_pending(current))
return -ERESTARTSYS;
changed = prev ^ status;
/* FIXME: check if this is correct (active high/low) */
- if ( ((arg & TIOCM_RNG) && (changed & PIN_RI)) ||
- ((arg & TIOCM_DSR) && (changed & PIN_DSR)) ||
- ((arg & TIOCM_CD) && (changed & PIN_DCD)) ||
- ((arg & TIOCM_CTS) && (changed & PIN_CTS))) {
- return 0;
- }
+ if (((arg & TIOCM_RNG) && (changed & PIN_RI)) ||
+ ((arg & TIOCM_DSR) && (changed & PIN_DSR)) ||
+ ((arg & TIOCM_CD) && (changed & PIN_DCD)) ||
+ ((arg & TIOCM_CTS) && (changed & PIN_CTS)))
+ return 0;
prev = status;
}
return 0;
}
-static int oti6858_ioctl(struct usb_serial_port *port, struct file *file,
+static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
- void __user *user_arg = (void __user *) arg;
- unsigned int x;
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)",
__func__, port->number, cmd, arg);
switch (cmd) {
- case TIOCMBIS:
- if (copy_from_user(&x, user_arg, sizeof(x)))
- return -EFAULT;
- return oti6858_tiocmset(port, NULL, x, 0);
-
- case TIOCMBIC:
- if (copy_from_user(&x, user_arg, sizeof(x)))
- return -EFAULT;
- return oti6858_tiocmset(port, NULL, 0, x);
-
- case TIOCMIWAIT:
- dbg("%s(): TIOCMIWAIT", __func__);
- return wait_modem_info(port, arg);
-
- default:
- dbg("%s(): 0x%04x not supported", __func__, cmd);
- break;
+ case TIOCMIWAIT:
+ dbg("%s(): TIOCMIWAIT", __func__);
+ return wait_modem_info(port, arg);
+ default:
+ dbg("%s(): 0x%04x not supported", __func__, cmd);
+ break;
}
-
return -ENOIOCTLCMD;
}
-static void oti6858_break_ctl(struct usb_serial_port *port, int break_state)
-{
- int state;
-
- dbg("%s(port = %d)", __func__, port->number);
-
- state = (break_state == 0) ? 0 : 1;
- dbg("%s(): turning break %s", __func__, state ? "on" : "off");
-
- /* FIXME */
-/*
- result = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
- BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
- 0, NULL, 0, 100);
- if (result != 0)
- dbg("%s(): error sending break", __func__);
- */
-}
static void oti6858_shutdown(struct usb_serial *serial)
{
spin_lock_irqsave(&priv->lock, flags);
if (priv->flags.write_urb_in_use == 0
&& oti6858_buf_data_avail(priv->buf) != 0) {
- schedule_delayed_work(&priv->delayed_write_work,0);
+ schedule_delayed_work(&priv->delayed_write_work, 0);
resubmit = 0;
}
spin_unlock_irqrestore(&priv->lock, flags);
if (resubmit) {
int result;
-// dbg("%s(): submitting interrupt urb", __func__);
+/* dbg("%s(): submitting interrupt urb", __func__); */
urb->dev = port->serial->dev;
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result != 0) {
spin_unlock_irqrestore(&priv->lock, flags);
if (status != 0) {
- if (!port->open_count) {
+ if (!port->port.count) {
dbg("%s(): port is closed, exiting", __func__);
return;
}
/*
if (status == -EPROTO) {
- // PL2303 mysteriously fails with -EPROTO reschedule the read
- dbg("%s - caught -EPROTO, resubmitting the urb", __func__);
+ * PL2303 mysteriously fails with -EPROTO reschedule
+ the read *
+ dbg("%s - caught -EPROTO, resubmitting the urb",
+ __func__);
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result)
dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
return;
}
- tty = port->tty;
+ tty = port->port.tty;
if (tty != NULL && urb->actual_length > 0) {
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
- // schedule the interrupt urb if we are still open */
- if (port->open_count != 0) {
+ /* schedule the interrupt urb if we are still open */
+ if (port->port.count != 0) {
port->interrupt_in_urb->dev = port->serial->dev;
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result != 0) {
priv->flags.write_urb_in_use = 0;
- // schedule the interrupt urb if we are still open */
+ /* schedule the interrupt urb if we are still open */
port->interrupt_in_urb->dev = port->serial->dev;
dbg("%s(): submitting interrupt urb", __func__);
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
{
if (pb == NULL)
return 0;
- return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size);
+ return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size;
}
/*
{
if (pb == NULL)
return 0;
- return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size);
+ return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size;
}
/*
{
int retval;
- if ((retval = usb_serial_register(&oti6858_device)) == 0) {
- if ((retval = usb_register(&oti6858_driver)) != 0)
+ retval = usb_serial_register(&oti6858_device);
+ if (retval == 0) {
+ retval = usb_register(&oti6858_driver);
+ if (retval)
usb_serial_deregister(&oti6858_device);
- else
- return 0;
}
-
return retval;
}
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "pl2303.h"
#define CONTROL_RTS 0x02
#define BREAK_REQUEST_TYPE 0x21
-#define BREAK_REQUEST 0x23
+#define BREAK_REQUEST 0x23
#define BREAK_ON 0xffff
#define BREAK_OFF 0x0000
if (pb == NULL)
return 0;
- return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size);
+ return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size;
}
/*
if (pb == NULL)
return 0;
- return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size);
+ return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size;
}
/*
cleanup:
kfree(buf);
- for (--i; i>=0; --i) {
+ for (--i; i >= 0; --i) {
priv = usb_get_serial_port_data(serial->port[i]);
pl2303_buf_free(priv->buf);
kfree(priv);
static int set_control_lines(struct usb_device *dev, u8 value)
{
int retval;
-
+
retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
value, 0, NULL, 0, 100);
dev_err(&port->dev, "%s - failed submitting write urb,"
" error %d\n", __func__, result);
priv->write_urb_in_use = 0;
- // TODO: reschedule pl2303_send
+ /* TODO: reschedule pl2303_send */
}
usb_serial_port_softint(port);
}
-static int pl2303_write(struct usb_serial_port *port, const unsigned char *buf,
- int count)
+static int pl2303_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
struct pl2303_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
return count;
}
-static int pl2303_write_room(struct usb_serial_port *port)
+static int pl2303_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct pl2303_private *priv = usb_get_serial_port_data(port);
int room = 0;
unsigned long flags;
return room;
}
-static int pl2303_chars_in_buffer(struct usb_serial_port *port)
+static int pl2303_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct pl2303_private *priv = usb_get_serial_port_data(port);
int chars = 0;
unsigned long flags;
return chars;
}
-static void pl2303_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void pl2303_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
struct pl2303_private *priv = usb_get_serial_port_data(port);
spin_lock_irqsave(&priv->lock, flags);
if (!priv->termios_initialized) {
- *(port->tty->termios) = tty_std_termios;
- port->tty->termios->c_cflag = B9600 | CS8 | CREAD |
- HUPCL | CLOCAL;
- port->tty->termios->c_ispeed = 9600;
- port->tty->termios->c_ospeed = 9600;
+ *(tty->termios) = tty_std_termios;
+ tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ tty->termios->c_ispeed = 9600;
+ tty->termios->c_ospeed = 9600;
priv->termios_initialized = 1;
}
spin_unlock_irqrestore(&priv->lock, flags);
serial settings even to the same values as before. Thus
we actually need to filter in this specific case */
- if (!tty_termios_hw_change(port->tty->termios, old_termios))
+ if (!tty_termios_hw_change(tty->termios, old_termios))
return;
- cflag = port->tty->termios->c_cflag;
+ cflag = tty->termios->c_cflag;
buf = kzalloc(7, GFP_KERNEL);
if (!buf) {
dev_err(&port->dev, "%s - out of memory.\n", __func__);
/* Report back no change occurred */
- *port->tty->termios = *old_termios;
+ *tty->termios = *old_termios;
return;
}
if (cflag & CSIZE) {
switch (cflag & CSIZE) {
- case CS5: buf[6] = 5; break;
- case CS6: buf[6] = 6; break;
- case CS7: buf[6] = 7; break;
- default:
- case CS8: buf[6] = 8; break;
+ case CS5:
+ buf[6] = 5;
+ break;
+ case CS6:
+ buf[6] = 6;
+ break;
+ case CS7:
+ buf[6] = 7;
+ break;
+ default:
+ case CS8:
+ buf[6] = 8;
+ break;
}
dbg("%s - data bits = %d", __func__, buf[6]);
}
- baud = tty_get_baud_rate(port->tty);;
+ baud = tty_get_baud_rate(tty);
dbg("%s - baud = %d", __func__, baud);
if (baud) {
buf[0] = baud & 0xff;
/* FIXME: Need to read back resulting baud rate */
if (baud)
- tty_encode_baud_rate(port->tty, baud, baud);
+ tty_encode_baud_rate(tty, baud, baud);
kfree(buf);
}
-static void pl2303_close(struct usb_serial_port *port, struct file *filp)
+static void pl2303_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct pl2303_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
timeout = PL2303_CLOSING_WAIT;
init_waitqueue_entry(&wait, current);
- add_wait_queue(&port->tty->write_wait, &wait);
+ add_wait_queue(&tty->write_wait, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (pl2303_buf_data_avail(priv->buf) == 0 ||
spin_lock_irqsave(&priv->lock, flags);
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->tty->write_wait, &wait);
+ remove_wait_queue(&tty->write_wait, &wait);
/* clear out any remaining data in the buffer */
pl2303_buf_clear(priv->buf);
spin_unlock_irqrestore(&priv->lock, flags);
/* for lower rates we should really know how much */
/* data is in the buffer to compute a delay */
/* that is not unnecessarily long) */
- bps = tty_get_baud_rate(port->tty);
+ bps = tty_get_baud_rate(tty);
if (bps > 1200)
- timeout = max((HZ*2560)/bps,HZ/10);
+ timeout = max((HZ*2560)/bps, HZ/10);
else
timeout = 2*HZ;
schedule_timeout_interruptible(timeout);
usb_kill_urb(port->read_urb);
usb_kill_urb(port->interrupt_in_urb);
- if (port->tty) {
- c_cflag = port->tty->termios->c_cflag;
+ if (tty) {
+ c_cflag = tty->termios->c_cflag;
if (c_cflag & HUPCL) {
/* drop DTR and RTS */
spin_lock_irqsave(&priv->lock, flags);
}
}
-static int pl2303_open(struct usb_serial_port *port, struct file *filp)
+static int pl2303_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct ktermios tmp_termios;
struct usb_serial *serial = port->serial;
}
/* Setup termios */
- if (port->tty) {
- pl2303_set_termios(port, &tmp_termios);
- }
+ if (tty)
+ pl2303_set_termios(tty, port, &tmp_termios);
- //FIXME: need to assert RTS and DTR if CRTSCTS off
+ /* FIXME: need to assert RTS and DTR if CRTSCTS off */
dbg("%s - submitting read urb", __func__);
port->read_urb->dev = serial->dev;
if (result) {
dev_err(&port->dev, "%s - failed submitting read urb,"
" error %d\n", __func__, result);
- pl2303_close(port, NULL);
+ pl2303_close(tty, port, NULL);
return -EPROTO;
}
if (result) {
dev_err(&port->dev, "%s - failed submitting interrupt urb,"
" error %d\n", __func__, result);
- pl2303_close(port, NULL);
+ pl2303_close(tty, port, NULL);
return -EPROTO;
}
return 0;
}
-static int pl2303_tiocmset(struct usb_serial_port *port, struct file *file,
+static int pl2303_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct pl2303_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
u8 control;
return set_control_lines(port->serial->dev, control);
}
-static int pl2303_tiocmget(struct usb_serial_port *port, struct file *file)
+static int pl2303_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct pl2303_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
unsigned int mcr;
status = priv->line_status;
spin_unlock_irqrestore(&priv->lock, flags);
- changed=prevstatus^status;
+ changed = prevstatus ^ status;
if (((arg & TIOCM_RNG) && (changed & UART_RING)) ||
((arg & TIOCM_DSR) && (changed & UART_DSR)) ||
((arg & TIOCM_CD) && (changed & UART_DCD)) ||
- ((arg & TIOCM_CTS) && (changed & UART_CTS)) ) {
+ ((arg & TIOCM_CTS) && (changed & UART_CTS))) {
return 0;
}
prevstatus = status;
return 0;
}
-static int pl2303_ioctl(struct usb_serial_port *port, struct file *file,
+static int pl2303_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
switch (cmd) {
- case TIOCMIWAIT:
- dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
- return wait_modem_info(port, arg);
-
- default:
- dbg("%s not supported = 0x%04x", __func__, cmd);
- break;
+ case TIOCMIWAIT:
+ dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
+ return wait_modem_info(port, arg);
+ default:
+ dbg("%s not supported = 0x%04x", __func__, cmd);
+ break;
}
-
return -ENOIOCTLCMD;
}
-static void pl2303_break_ctl(struct usb_serial_port *port, int break_state)
+static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
u16 state;
int result;
state = BREAK_OFF;
else
state = BREAK_ON;
- dbg("%s - turning break %s", __func__, state==BREAK_OFF ? "off" : "on");
+ dbg("%s - turning break %s", __func__,
+ state == BREAK_OFF ? "off" : "on");
result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
if (actual_length < length)
return;
- /* Save off the uart status for others to look at */
+ /* Save off the uart status for others to look at */
spin_lock_irqsave(&priv->lock, flags);
priv->line_status = data[status_idx];
spin_unlock_irqrestore(&priv->lock, flags);
if (status) {
dbg("%s - urb status = %d", __func__, status);
- if (!port->open_count) {
+ if (!port->port.count) {
dbg("%s - port is closed, exiting.", __func__);
return;
}
/* break takes precedence over parity, */
/* which takes precedence over framing errors */
- if (line_status & UART_BREAK_ERROR )
+ if (line_status & UART_BREAK_ERROR)
tty_flag = TTY_BREAK;
else if (line_status & UART_PARITY_ERROR)
tty_flag = TTY_PARITY;
tty_flag = TTY_FRAME;
dbg("%s - tty_flag = %d", __func__, tty_flag);
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length + 1);
/* overrun is special, not associated with a char */
}
/* Schedule the next read _if_ we are still open */
- if (port->open_count) {
+ if (port->port.count) {
urb->dev = port->serial->dev;
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result)
* Stuart Lynne <sl@lineo.com>, Tom Rushworth <tbr@lineo.com>
*/
-/*
- * The encapsultaion is designed to overcome difficulties with some USB hardware.
+/*
+ * The encapsultaion is designed to overcome difficulties with some USB
+ * hardware.
*
* While the USB protocol has a CRC over the data while in transit, i.e. while
- * being carried over the bus, there is no end to end protection. If the hardware
- * has any problems getting the data into or out of the USB transmit and receive
- * FIFO's then data can be lost.
+ * being carried over the bus, there is no end to end protection. If the
+ * hardware has any problems getting the data into or out of the USB transmit
+ * and receive FIFO's then data can be lost.
*
- * This protocol adds a two byte trailer to each USB packet to specify the number
- * of bytes of valid data and a 10 bit CRC that will allow the receiver to verify
- * that the entire USB packet was received without error.
+ * This protocol adds a two byte trailer to each USB packet to specify the
+ * number of bytes of valid data and a 10 bit CRC that will allow the receiver
+ * to verify that the entire USB packet was received without error.
*
- * Because in this case the sender and receiver are the class and function drivers
- * there is now end to end protection.
+ * Because in this case the sender and receiver are the class and function
+ * drivers there is now end to end protection.
*
- * There is an additional option that can be used to force all transmitted packets
- * to be padded to the maximum packet size. This provides a work around for some
- * devices which have problems with small USB packets.
+ * There is an additional option that can be used to force all transmitted
+ * packets to be padded to the maximum packet size. This provides a work
+ * around for some devices which have problems with small USB packets.
*
* Assuming a packetsize of N:
*
* | Data Length | 10 bit CRC |
* + 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 | 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 +
*
- * The 10 bit CRC is computed across the sent data, followed by the trailer with
- * the length set and the CRC set to zero. The CRC is then OR'd into the trailer.
+ * The 10 bit CRC is computed across the sent data, followed by the trailer
+ * with the length set and the CRC set to zero. The CRC is then OR'd into
+ * the trailer.
*
- * When received a 10 bit CRC is computed over the entire frame including the trailer
- * and should be equal to zero.
+ * When received a 10 bit CRC is computed over the entire frame including
+ * the trailer and should be equal to zero.
*
* Two module parameters are used to control the encapsulation, if both are
* turned of the module works as a simple serial device with NO
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com"
#define DRIVER_DESC "USB Safe Encapsulated Serial"
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-static __u16 vendor; // no default
-static __u16 product; // no default
+static __u16 vendor; /* no default */
+static __u16 product; /* no default */
module_param(vendor, ushort, 0);
MODULE_PARM_DESC(vendor, "User specified USB idVendor (required)");
module_param(product, ushort, 0);
#define LINEO_SAFESERIAL_CRC_PADDED 0x02
-#define MY_USB_DEVICE(vend,prod,dc,ic,isc) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS | \
- USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS, \
- .idVendor = (vend), \
- .idProduct = (prod),\
- .bDeviceClass = (dc),\
- .bInterfaceClass = (ic), \
- .bInterfaceSubClass = (isc),
+#define MY_USB_DEVICE(vend, prod, dc, ic, isc) \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+ USB_DEVICE_ID_MATCH_DEV_CLASS | \
+ USB_DEVICE_ID_MATCH_INT_CLASS | \
+ USB_DEVICE_ID_MATCH_INT_SUBCLASS, \
+ .idVendor = (vend), \
+ .idProduct = (prod),\
+ .bDeviceClass = (dc),\
+ .bInterfaceClass = (ic), \
+ .bInterfaceSubClass = (isc),
static struct usb_device_id id_table[] = {
- {MY_USB_DEVICE (0x49f, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Itsy
- {MY_USB_DEVICE (0x3f0, 0x2101, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Calypso
- {MY_USB_DEVICE (0x4dd, 0x8001, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Iris
- {MY_USB_DEVICE (0x4dd, 0x8002, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie
- {MY_USB_DEVICE (0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie
- {MY_USB_DEVICE (0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie
- {MY_USB_DEVICE (0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Sharp tmp
- // extra null entry for module
- // vendor/produc parameters
- {MY_USB_DEVICE (0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},
- {} // terminating entry
+ {MY_USB_DEVICE(0x49f, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Itsy */
+ {MY_USB_DEVICE(0x3f0, 0x2101, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Calypso */
+ {MY_USB_DEVICE(0x4dd, 0x8001, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Iris */
+ {MY_USB_DEVICE(0x4dd, 0x8002, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Collie */
+ {MY_USB_DEVICE(0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Collie */
+ {MY_USB_DEVICE(0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Collie */
+ {MY_USB_DEVICE(0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Sharp tmp */
+ /* extra null entry for module vendor/produc parameters */
+ {MY_USB_DEVICE(0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},
+ {} /* terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver safe_driver = {
.name = "safe_serial",
};
static const __u16 crc10_table[256] = {
- 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
- 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
- 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c,
- 0x053, 0x260, 0x206, 0x035, 0x2ca, 0x0f9, 0x09f, 0x2ac, 0x352, 0x161, 0x107, 0x334, 0x1cb, 0x3f8, 0x39e, 0x1ad,
- 0x0c4, 0x2f7, 0x291, 0x0a2, 0x25d, 0x06e, 0x008, 0x23b, 0x3c5, 0x1f6, 0x190, 0x3a3, 0x15c, 0x36f, 0x309, 0x13a,
- 0x0f5, 0x2c6, 0x2a0, 0x093, 0x26c, 0x05f, 0x039, 0x20a, 0x3f4, 0x1c7, 0x1a1, 0x392, 0x16d, 0x35e, 0x338, 0x10b,
- 0x0a6, 0x295, 0x2f3, 0x0c0, 0x23f, 0x00c, 0x06a, 0x259, 0x3a7, 0x194, 0x1f2, 0x3c1, 0x13e, 0x30d, 0x36b, 0x158,
- 0x097, 0x2a4, 0x2c2, 0x0f1, 0x20e, 0x03d, 0x05b, 0x268, 0x396, 0x1a5, 0x1c3, 0x3f0, 0x10f, 0x33c, 0x35a, 0x169,
- 0x188, 0x3bb, 0x3dd, 0x1ee, 0x311, 0x122, 0x144, 0x377, 0x289, 0x0ba, 0x0dc, 0x2ef, 0x010, 0x223, 0x245, 0x076,
- 0x1b9, 0x38a, 0x3ec, 0x1df, 0x320, 0x113, 0x175, 0x346, 0x2b8, 0x08b, 0x0ed, 0x2de, 0x021, 0x212, 0x274, 0x047,
- 0x1ea, 0x3d9, 0x3bf, 0x18c, 0x373, 0x140, 0x126, 0x315, 0x2eb, 0x0d8, 0x0be, 0x28d, 0x072, 0x241, 0x227, 0x014,
- 0x1db, 0x3e8, 0x38e, 0x1bd, 0x342, 0x171, 0x117, 0x324, 0x2da, 0x0e9, 0x08f, 0x2bc, 0x043, 0x270, 0x216, 0x025,
- 0x14c, 0x37f, 0x319, 0x12a, 0x3d5, 0x1e6, 0x180, 0x3b3, 0x24d, 0x07e, 0x018, 0x22b, 0x0d4, 0x2e7, 0x281, 0x0b2,
- 0x17d, 0x34e, 0x328, 0x11b, 0x3e4, 0x1d7, 0x1b1, 0x382, 0x27c, 0x04f, 0x029, 0x21a, 0x0e5, 0x2d6, 0x2b0, 0x083,
- 0x12e, 0x31d, 0x37b, 0x148, 0x3b7, 0x184, 0x1e2, 0x3d1, 0x22f, 0x01c, 0x07a, 0x249, 0x0b6, 0x285, 0x2e3, 0x0d0,
- 0x11f, 0x32c, 0x34a, 0x179, 0x386, 0x1b5, 0x1d3, 0x3e0, 0x21e, 0x02d, 0x04b, 0x278, 0x087, 0x2b4, 0x2d2, 0x0e1,
+ 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff,
+ 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
+ 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce,
+ 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
+ 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d,
+ 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c,
+ 0x053, 0x260, 0x206, 0x035, 0x2ca, 0x0f9, 0x09f, 0x2ac,
+ 0x352, 0x161, 0x107, 0x334, 0x1cb, 0x3f8, 0x39e, 0x1ad,
+ 0x0c4, 0x2f7, 0x291, 0x0a2, 0x25d, 0x06e, 0x008, 0x23b,
+ 0x3c5, 0x1f6, 0x190, 0x3a3, 0x15c, 0x36f, 0x309, 0x13a,
+ 0x0f5, 0x2c6, 0x2a0, 0x093, 0x26c, 0x05f, 0x039, 0x20a,
+ 0x3f4, 0x1c7, 0x1a1, 0x392, 0x16d, 0x35e, 0x338, 0x10b,
+ 0x0a6, 0x295, 0x2f3, 0x0c0, 0x23f, 0x00c, 0x06a, 0x259,
+ 0x3a7, 0x194, 0x1f2, 0x3c1, 0x13e, 0x30d, 0x36b, 0x158,
+ 0x097, 0x2a4, 0x2c2, 0x0f1, 0x20e, 0x03d, 0x05b, 0x268,
+ 0x396, 0x1a5, 0x1c3, 0x3f0, 0x10f, 0x33c, 0x35a, 0x169,
+ 0x188, 0x3bb, 0x3dd, 0x1ee, 0x311, 0x122, 0x144, 0x377,
+ 0x289, 0x0ba, 0x0dc, 0x2ef, 0x010, 0x223, 0x245, 0x076,
+ 0x1b9, 0x38a, 0x3ec, 0x1df, 0x320, 0x113, 0x175, 0x346,
+ 0x2b8, 0x08b, 0x0ed, 0x2de, 0x021, 0x212, 0x274, 0x047,
+ 0x1ea, 0x3d9, 0x3bf, 0x18c, 0x373, 0x140, 0x126, 0x315,
+ 0x2eb, 0x0d8, 0x0be, 0x28d, 0x072, 0x241, 0x227, 0x014,
+ 0x1db, 0x3e8, 0x38e, 0x1bd, 0x342, 0x171, 0x117, 0x324,
+ 0x2da, 0x0e9, 0x08f, 0x2bc, 0x043, 0x270, 0x216, 0x025,
+ 0x14c, 0x37f, 0x319, 0x12a, 0x3d5, 0x1e6, 0x180, 0x3b3,
+ 0x24d, 0x07e, 0x018, 0x22b, 0x0d4, 0x2e7, 0x281, 0x0b2,
+ 0x17d, 0x34e, 0x328, 0x11b, 0x3e4, 0x1d7, 0x1b1, 0x382,
+ 0x27c, 0x04f, 0x029, 0x21a, 0x0e5, 0x2d6, 0x2b0, 0x083,
+ 0x12e, 0x31d, 0x37b, 0x148, 0x3b7, 0x184, 0x1e2, 0x3d1,
+ 0x22f, 0x01c, 0x07a, 0x249, 0x0b6, 0x285, 0x2e3, 0x0d0,
+ 0x11f, 0x32c, 0x34a, 0x179, 0x386, 0x1b5, 0x1d3, 0x3e0,
+ 0x21e, 0x02d, 0x04b, 0x278, 0x087, 0x2b4, 0x2d2, 0x0e1,
};
-#define CRC10_INITFCS 0x000 // Initial FCS value
-#define CRC10_GOODFCS 0x000 // Good final FCS value
-#define CRC10_FCS(fcs, c) ( (((fcs) << 8) & 0x3ff) ^ crc10_table[((fcs) >> 2) & 0xff] ^ (c))
+#define CRC10_INITFCS 0x000 /* Initial FCS value */
+#define CRC10_GOODFCS 0x000 /* Good final FCS value */
+#define CRC10_FCS(fcs, c) ((((fcs) << 8) & 0x3ff) ^ crc10_table[((fcs) >> 2) & 0xff] ^ (c))
-/**
+/**
* fcs_compute10 - memcpy and calculate 10 bit CRC across buffer
* @sp: pointer to buffer
* @len: number of bytes
* Perform a memcpy and calculate fcs using ppp 10bit CRC algorithm. Return
* new 10 bit FCS.
*/
-static __u16 __inline__ fcs_compute10 (unsigned char *sp, int len, __u16 fcs)
+static __u16 __inline__ fcs_compute10(unsigned char *sp, int len, __u16 fcs)
{
- for (; len-- > 0; fcs = CRC10_FCS (fcs, *sp++));
+ for (; len-- > 0; fcs = CRC10_FCS(fcs, *sp++));
return fcs;
}
-static void safe_read_bulk_callback (struct urb *urb)
+static void safe_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
unsigned char *data = urb->transfer_buffer;
int result;
int status = urb->status;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
if (status) {
dbg("%s - nonzero read bulk status received: %d",
return;
}
- dbg ("safe_read_bulk_callback length: %d", port->read_urb->actual_length);
+ dbg("safe_read_bulk_callback length: %d",
+ port->read_urb->actual_length);
#ifdef ECHO_RCV
{
int i;
unsigned char *cp = port->read_urb->transfer_buffer;
for (i = 0; i < port->read_urb->actual_length; i++) {
- if ((i % 32) == 0) {
- printk ("\nru[%02x] ", i);
- }
- printk ("%02x ", *cp++);
+ if ((i % 32) == 0)
+ printk("\nru[%02x] ", i);
+ printk("%02x ", *cp++);
}
- printk ("\n");
+ printk("\n");
}
#endif
if (safe) {
__u16 fcs;
- if (!(fcs = fcs_compute10 (data, length, CRC10_INITFCS))) {
+ fcs = fcs_compute10(data, length, CRC10_INITFCS);
+ if (!fcs) {
int actual_length = data[length - 2] >> 2;
if (actual_length <= (length - 2)) {
- info ("%s - actual: %d", __func__, actual_length);
- tty_insert_flip_string(port->tty, data, actual_length);
- tty_flip_buffer_push (port->tty);
+ info("%s - actual: %d", __func__,
+ actual_length);
+ tty_insert_flip_string(port->port.tty,
+ data, actual_length);
+ tty_flip_buffer_push(port->port.tty);
} else {
- err ("%s - inconsistent lengths %d:%d", __func__,
- actual_length, length);
+ err("%s - inconsistent lengths %d:%d",
+ __func__, actual_length, length);
}
} else {
- err ("%s - bad CRC %x", __func__, fcs);
+ err("%s - bad CRC %x", __func__, fcs);
}
} else {
- tty_insert_flip_string(port->tty, data, length);
- tty_flip_buffer_push (port->tty);
+ tty_insert_flip_string(port->port.tty, data, length);
+ tty_flip_buffer_push(port->port.tty);
}
/* Continue trying to always read */
- usb_fill_bulk_urb (urb, port->serial->dev,
- usb_rcvbulkpipe (port->serial->dev, port->bulk_in_endpointAddress),
- urb->transfer_buffer, urb->transfer_buffer_length,
- safe_read_bulk_callback, port);
-
- if ((result = usb_submit_urb (urb, GFP_ATOMIC))) {
- err ("%s - failed resubmitting read urb, error %d", __func__, result);
+ usb_fill_bulk_urb(urb, port->serial->dev,
+ usb_rcvbulkpipe(port->serial->dev,
+ port->bulk_in_endpointAddress),
+ urb->transfer_buffer, urb->transfer_buffer_length,
+ safe_read_bulk_callback, port);
+
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result)
+ err("%s - failed resubmitting read urb, error %d",
+ __func__, result);
/* FIXME: Need a mechanism to retry later if this happens */
- }
}
-static int safe_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int safe_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
unsigned char *data;
int result;
int i;
int packet_length;
- dbg ("safe_write port: %p %d urb: %p count: %d", port, port->number, port->write_urb,
- count);
+ dbg("safe_write port: %p %d urb: %p count: %d",
+ port, port->number, port->write_urb, count);
if (!port->write_urb) {
- dbg ("%s - write urb NULL", __func__);
+ dbg("%s - write urb NULL", __func__);
return 0;
}
- dbg ("safe_write write_urb: %d transfer_buffer_length",
+ dbg("safe_write write_urb: %d transfer_buffer_length",
port->write_urb->transfer_buffer_length);
if (!port->write_urb->transfer_buffer_length) {
- dbg ("%s - write urb transfer_buffer_length zero", __func__);
+ dbg("%s - write urb transfer_buffer_length zero", __func__);
return 0;
}
if (count == 0) {
- dbg ("%s - write request of 0 bytes", __func__);
+ dbg("%s - write request of 0 bytes", __func__);
return 0;
}
spin_lock_bh(&port->lock);
port->write_urb_busy = 1;
spin_unlock_bh(&port->lock);
- packet_length = port->bulk_out_size; // get max packetsize
+ packet_length = port->bulk_out_size; /* get max packetsize */
- i = packet_length - (safe ? 2 : 0); // get bytes to send
+ i = packet_length - (safe ? 2 : 0); /* get bytes to send */
count = (count > i) ? i : count;
- // get the data into the transfer buffer
+ /* get the data into the transfer buffer */
data = port->write_urb->transfer_buffer;
- memset (data, '0', packet_length);
+ memset(data, '0', packet_length);
- memcpy (data, buf, count);
+ memcpy(data, buf, count);
if (safe) {
__u16 fcs;
- // pad if necessary
- if (!padded) {
+ /* pad if necessary */
+ if (!padded)
packet_length = count + 2;
- }
- // set count
+ /* set count */
data[packet_length - 2] = count << 2;
data[packet_length - 1] = 0;
- // compute fcs and insert into trailer
- fcs = fcs_compute10 (data, packet_length, CRC10_INITFCS);
+ /* compute fcs and insert into trailer */
+ fcs = fcs_compute10(data, packet_length, CRC10_INITFCS);
data[packet_length - 2] |= fcs >> 8;
data[packet_length - 1] |= fcs & 0xff;
- // set length to send
+ /* set length to send */
port->write_urb->transfer_buffer_length = packet_length;
} else {
port->write_urb->transfer_buffer_length = count;
}
- usb_serial_debug_data(debug, &port->dev, __func__, count, port->write_urb->transfer_buffer);
+ usb_serial_debug_data(debug, &port->dev, __func__, count,
+ port->write_urb->transfer_buffer);
#ifdef ECHO_TX
{
int i;
unsigned char *cp = port->write_urb->transfer_buffer;
for (i = 0; i < port->write_urb->transfer_buffer_length; i++) {
- if ((i % 32) == 0) {
- printk ("\nsu[%02x] ", i);
- }
- printk ("%02x ", *cp++);
+ if ((i % 32) == 0)
+ printk("\nsu[%02x] ", i);
+ printk("%02x ", *cp++);
}
- printk ("\n");
+ printk("\n");
}
#endif
port->write_urb->dev = port->serial->dev;
- if ((result = usb_submit_urb (port->write_urb, GFP_KERNEL))) {
+ result = usb_submit_urb(port->write_urb, GFP_KERNEL);
+ if (result) {
port->write_urb_busy = 0;
- err ("%s - failed submitting write urb, error %d", __func__, result);
+ err("%s - failed submitting write urb, error %d",
+ __func__, result);
return 0;
}
- dbg ("%s urb: %p submitted", __func__, port->write_urb);
+ dbg("%s urb: %p submitted", __func__, port->write_urb);
- return (count);
+ return count;
}
-static int safe_write_room (struct usb_serial_port *port)
+static int safe_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
int room = 0; /* Default: no room */
unsigned long flags;
- dbg ("%s", __func__);
+ dbg("%s", __func__);
spin_lock_irqsave(&port->lock, flags);
if (port->write_urb_busy)
room = port->bulk_out_size - (safe ? 2 : 0);
spin_unlock_irqrestore(&port->lock, flags);
- if (room) {
- dbg ("safe_write_room returns %d", room);
- }
-
+ if (room)
+ dbg("safe_write_room returns %d", room);
return room;
}
-static int safe_startup (struct usb_serial *serial)
+static int safe_startup(struct usb_serial *serial)
{
switch (serial->interface->cur_altsetting->desc.bInterfaceProtocol) {
case LINEO_SAFESERIAL_CRC:
.attach = safe_startup,
};
-static int __init safe_init (void)
+static int __init safe_init(void)
{
int i, retval;
- info (DRIVER_VERSION " " DRIVER_AUTHOR);
- info (DRIVER_DESC);
- info ("vendor: %x product: %x safe: %d padded: %d\n", vendor, product, safe, padded);
+ info(DRIVER_VERSION " " DRIVER_AUTHOR);
+ info(DRIVER_DESC);
+ info("vendor: %x product: %x safe: %d padded: %d\n",
+ vendor, product, safe, padded);
- // if we have vendor / product parameters patch them into id list
+ /* if we have vendor / product parameters patch them into id list */
if (vendor || product) {
- info ("vendor: %x product: %x\n", vendor, product);
+ info("vendor: %x product: %x\n", vendor, product);
for (i = 0; i < ARRAY_SIZE(id_table); i++) {
if (!id_table[i].idVendor && !id_table[i].idProduct) {
return retval;
}
-static void __exit safe_exit (void)
+static void __exit safe_exit(void)
{
- usb_deregister (&safe_driver);
- usb_serial_deregister (&safe_device);
+ usb_deregister(&safe_driver);
+ usb_serial_deregister(&safe_device);
}
-module_init (safe_init);
-module_exit (safe_exit);
+module_init(safe_init);
+module_exit(safe_exit);
int ri_state;
};
-static int sierra_send_setup(struct usb_serial_port *port)
+static int sierra_send_setup(struct tty_struct *tty,
+ struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct sierra_port_private *portdata;
portdata = usb_get_serial_port_data(port);
- if (port->tty) {
+ if (tty) {
int val = 0;
if (portdata->dtr_state)
val |= 0x01;
return 0;
}
-static void sierra_rx_throttle(struct usb_serial_port *port)
+static void sierra_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
dbg("%s", __func__);
+ tty_termios_copy_hw(tty->termios, old_termios);
+ sierra_send_setup(tty, port);
}
-static void sierra_rx_unthrottle(struct usb_serial_port *port)
-{
- dbg("%s", __func__);
-}
-
-static void sierra_break_ctl(struct usb_serial_port *port, int break_state)
-{
- /* Unfortunately, I don't know how to send a break */
- dbg("%s", __func__);
-}
-
-static void sierra_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
-{
- dbg("%s", __func__);
- tty_termios_copy_hw(port->tty->termios, old_termios);
- sierra_send_setup(port);
-}
-
-static int sierra_tiocmget(struct usb_serial_port *port, struct file *file)
+static int sierra_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
unsigned int value;
struct sierra_port_private *portdata;
return value;
}
-static int sierra_tiocmset(struct usb_serial_port *port, struct file *file,
+static int sierra_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct sierra_port_private *portdata;
portdata = usb_get_serial_port_data(port);
portdata->rts_state = 0;
if (clear & TIOCM_DTR)
portdata->dtr_state = 0;
- return sierra_send_setup(port);
-}
-
-static int sierra_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- return -ENOIOCTLCMD;
+ return sierra_send_setup(tty, port);
}
static void sierra_outdat_callback(struct urb *urb)
}
/* Write */
-static int sierra_write(struct usb_serial_port *port,
- const unsigned char *buf, int count)
+static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
struct sierra_port_private *portdata = usb_get_serial_port_data(port);
struct usb_serial *serial = port->serial;
dbg("%s: nonzero status: %d on endpoint %02x.",
__func__, status, endpoint);
} else {
- tty = port->tty;
+ tty = port->port.tty;
if (urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
}
/* Resubmit urb so we continue receiving */
- if (port->open_count && status != -ESHUTDOWN) {
+ if (port->port.count && status != -ESHUTDOWN) {
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err)
dev_err(&port->dev, "resubmit read urb failed."
portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
portdata->ri_state = ((signals & 0x08) ? 1 : 0);
- if (port->tty && !C_CLOCAL(port->tty) &&
+ if (port->port.tty && !C_CLOCAL(port->port.tty) &&
old_dcd_state && !portdata->dcd_state)
- tty_hangup(port->tty);
+ tty_hangup(port->port.tty);
} else {
dbg("%s: type %x req %x", __func__,
req_pkt->bRequestType, req_pkt->bRequest);
}
}
-static int sierra_write_room(struct usb_serial_port *port)
+static int sierra_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct sierra_port_private *portdata = usb_get_serial_port_data(port);
unsigned long flags;
return 2048;
}
-static int sierra_chars_in_buffer(struct usb_serial_port *port)
-{
- dbg("%s - port %d", __func__, port->number);
-
- /*
- * We can't really account for how much data we
- * have sent out, but hasn't made it through to the
- * device as we can't see the backend here, so just
- * tell the tty layer that everything is flushed.
- *
- * FIXME: should walk the outstanding urbs info
- */
- return 0;
-}
-
-static int sierra_open(struct usb_serial_port *port, struct file *filp)
+static int sierra_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct sierra_port_private *portdata;
struct usb_serial *serial = port->serial;
}
}
- port->tty->low_latency = 1;
+ if (tty)
+ tty->low_latency = 1;
- sierra_send_setup(port);
+ sierra_send_setup(tty, port);
/* start up the interrupt endpoint if we have one */
if (port->interrupt_in_urb) {
return 0;
}
-static void sierra_close(struct usb_serial_port *port, struct file *filp)
+static void sierra_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
int i;
struct usb_serial *serial = port->serial;
if (serial->dev) {
mutex_lock(&serial->disc_mutex);
if (!serial->disconnected)
- sierra_send_setup(port);
+ sierra_send_setup(tty, port);
mutex_unlock(&serial->disc_mutex);
/* Stop reading/writing urbs */
usb_kill_urb(port->interrupt_in_urb);
- port->tty = NULL;
+ port->port.tty = NULL; /* FIXME */
}
static int sierra_startup(struct usb_serial *serial)
.close = sierra_close,
.write = sierra_write,
.write_room = sierra_write_room,
- .chars_in_buffer = sierra_chars_in_buffer,
- .throttle = sierra_rx_throttle,
- .unthrottle = sierra_rx_unthrottle,
- .ioctl = sierra_ioctl,
.set_termios = sierra_set_termios,
- .break_ctl = sierra_break_ctl,
.tiocmget = sierra_tiocmget,
.tiocmset = sierra_tiocmset,
.attach = sierra_startup,
static void __exit sierra_exit(void)
{
- usb_deregister (&sierra_driver);
+ usb_deregister(&sierra_driver);
usb_serial_deregister(&sierra_device);
}
{
if (pb == NULL)
return 0;
- return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size);
+ return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size;
}
/* get the number of space in the pipo */
{
if (pb == NULL)
return 0;
- return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size);
+ return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size;
}
/* put count data into pipo */
/* close the serial port. We should wait for data sending to device 1st and
* then kill all urb. */
-static void spcp8x5_close(struct usb_serial_port *port, struct file *filp)
+static void spcp8x5_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
timeout = SPCP8x5_CLOSING_WAIT;
init_waitqueue_entry(&wait, current);
- add_wait_queue(&port->tty->write_wait, &wait);
+ add_wait_queue(&tty->write_wait, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (ringbuf_avail_data(priv->buf) == 0 ||
spin_lock_irqsave(&priv->lock, flags);
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->tty->write_wait, &wait);
+ remove_wait_queue(&tty->write_wait, &wait);
/* clear out any remaining data in the buffer */
clear_ringbuf(priv->buf);
* flow control for data rates of 1200 bps or more, for lower rates we
* should really know how much data is in the buffer to compute a delay
* that is not unnecessarily long) */
- bps = tty_get_baud_rate(port->tty);
+ bps = tty_get_baud_rate(tty);
if (bps > 1200)
timeout = max((HZ*2560) / bps, HZ/10);
else
schedule_timeout(timeout);
/* clear control lines */
- if (port->tty) {
- c_cflag = port->tty->termios->c_cflag;
+ if (tty) {
+ c_cflag = tty->termios->c_cflag;
if (c_cflag & HUPCL) {
spin_lock_irqsave(&priv->lock, flags);
priv->line_control = 0;
}
/* set the serial param for transfer. we should check if we really need to
- * transfer. then if be set flow contorl we should do this too. */
-static void spcp8x5_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+ * transfer. if we set flow control we should do this too. */
+static void spcp8x5_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
- unsigned int cflag = port->tty->termios->c_cflag;
+ unsigned int cflag = tty->termios->c_cflag;
unsigned int old_cflag = old_termios->c_cflag;
unsigned short uartdata;
unsigned char buf[2] = {0, 0};
int i;
u8 control;
- if ((!port->tty) || (!port->tty->termios))
- return;
-
/* for the 1st time call this function */
spin_lock_irqsave(&priv->lock, flags);
if (!priv->termios_initialized) {
- *(port->tty->termios) = tty_std_termios;
- port->tty->termios->c_cflag = B115200 | CS8 | CREAD |
- HUPCL | CLOCAL;
+ *(tty->termios) = tty_std_termios;
+ tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+ tty->termios->c_ispeed = 115200;
+ tty->termios->c_ospeed = 115200;
priv->termios_initialized = 1;
}
spin_unlock_irqrestore(&priv->lock, flags);
/* check that they really want us to change something */
- if (!tty_termios_hw_change(port->tty->termios, old_termios))
+ if (!tty_termios_hw_change(tty->termios, old_termios))
return;
/* set DTR/RTS active */
}
/* Set Baud Rate */
- baud = tty_get_baud_rate(port->tty);;
+ baud = tty_get_baud_rate(tty);;
switch (baud) {
case 300: buf[0] = 0x00; break;
case 600: buf[0] = 0x01; break;
/* open the serial port. do some usb system call. set termios and get the line
* status of the device. then submit the read urb */
-static int spcp8x5_open(struct usb_serial_port *port, struct file *filp)
+static int spcp8x5_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct ktermios tmp_termios;
struct usb_serial *serial = port->serial;
return ret;
spin_lock_irqsave(&priv->lock, flags);
- if (port->tty->termios->c_cflag & CBAUD)
+ if (tty && (tty->termios->c_cflag & CBAUD))
priv->line_control = MCR_DTR | MCR_RTS;
else
priv->line_control = 0;
spcp8x5_set_ctrlLine(serial->dev, priv->line_control , priv->type);
/* Setup termios */
- if (port->tty)
- spcp8x5_set_termios(port, &tmp_termios);
+ if (tty)
+ spcp8x5_set_termios(tty, port, &tmp_termios);
spcp8x5_get_msr(serial->dev, &status, priv->type);
port->read_urb->dev = serial->dev;
ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (ret) {
- spcp8x5_close(port, NULL);
+ spcp8x5_close(tty, port, NULL);
return -EPROTO;
}
return 0;
/* check the urb status */
if (urb->status) {
- if (!port->open_count)
+ if (!port->port.count)
return;
if (urb->status == -EPROTO) {
/* spcp8x5 mysteriously fails with -EPROTO */
tty_flag = TTY_FRAME;
dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag);
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length + 1);
/* overrun is special, not associated with a char */
}
/* Schedule the next read _if_ we are still open */
- if (port->open_count) {
+ if (port->port.count) {
urb->dev = port->serial->dev;
result = usb_submit_urb(urb , GFP_ATOMIC);
if (result)
}
/* write data to ring buffer. and then start the write transfer */
-static int spcp8x5_write(struct usb_serial_port *port,
+static int spcp8x5_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count)
{
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
return 0;
}
-static int spcp8x5_ioctl(struct usb_serial_port *port, struct file *file,
+static int spcp8x5_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
switch (cmd) {
return -ENOIOCTLCMD;
}
-static int spcp8x5_tiocmset(struct usb_serial_port *port, struct file *file,
+static int spcp8x5_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
u8 control;
return spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type);
}
-static int spcp8x5_tiocmget(struct usb_serial_port *port, struct file *file)
+static int spcp8x5_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
unsigned int mcr;
}
/* get the avail space room in ring buffer */
-static int spcp8x5_write_room(struct usb_serial_port *port)
+static int spcp8x5_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
int room = 0;
unsigned long flags;
}
/* get the number of avail data in write ring buffer */
-static int spcp8x5_chars_in_buffer(struct usb_serial_port *port)
+static int spcp8x5_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
int chars = 0;
unsigned long flags;
* For questions or problems with this driver, contact Texas Instruments
* technical support, or Al Borchers <alborchers@steinerpoint.com>, or
* Peter Berger <pberger@brimson.com>.
- *
+ *
* This driver needs this hotplug script in /etc/hotplug/usb/ti_usb_3410_5052
* or in /etc/hotplug.d/usb/ti_usb_3410_5052.hotplug to set the device
* configuration.
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/firmware.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/circ_buf.h>
#include <linux/mutex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <linux/firmware.h>
static int ti_startup(struct usb_serial *serial);
static void ti_shutdown(struct usb_serial *serial);
-static int ti_open(struct usb_serial_port *port, struct file *file);
-static void ti_close(struct usb_serial_port *port, struct file *file);
-static int ti_write(struct usb_serial_port *port, const unsigned char *data,
- int count);
-static int ti_write_room(struct usb_serial_port *port);
-static int ti_chars_in_buffer(struct usb_serial_port *port);
-static void ti_throttle(struct usb_serial_port *port);
-static void ti_unthrottle(struct usb_serial_port *port);
-static int ti_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
-static void ti_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios);
-static int ti_tiocmget(struct usb_serial_port *port, struct file *file);
-static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
- unsigned int set, unsigned int clear);
-static void ti_break(struct usb_serial_port *port, int break_state);
+static int ti_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *file);
+static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *file);
+static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *data, int count);
+static int ti_write_room(struct tty_struct *tty);
+static int ti_chars_in_buffer(struct tty_struct *tty);
+static void ti_throttle(struct tty_struct *tty);
+static void ti_unthrottle(struct tty_struct *tty);
+static int ti_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void ti_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios);
+static int ti_tiocmget(struct tty_struct *tty, struct file *file);
+static int ti_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static void ti_break(struct tty_struct *tty, int break_state);
static void ti_interrupt_callback(struct urb *urb);
static void ti_bulk_in_callback(struct urb *urb);
static void ti_bulk_out_callback(struct urb *urb);
static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
__u8 mask, __u8 byte);
-static int ti_download_firmware(struct ti_device *tdev, char *fw_name);
-
+static int ti_download_firmware(struct ti_device *tdev, int type);
/* circular buffer */
static struct circ_buf *ti_buf_alloc(void);
MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
module_param(low_latency, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(low_latency, "TTY low_latency flag, 0=off, 1=on, default is off");
+MODULE_PARM_DESC(low_latency,
+ "TTY low_latency flag, 0=off, 1=on, default is off");
module_param(closing_wait, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain in close, in .01 secs, default is 4000");
+MODULE_PARM_DESC(closing_wait,
+ "Maximum wait for data to drain in close, in .01 secs, default is 4000");
module_param_array(vendor_3410, ushort, &vendor_3410_count, S_IRUGO);
-MODULE_PARM_DESC(vendor_3410, "Vendor ids for 3410 based devices, 1-5 short integers");
+MODULE_PARM_DESC(vendor_3410,
+ "Vendor ids for 3410 based devices, 1-5 short integers");
module_param_array(product_3410, ushort, &product_3410_count, S_IRUGO);
-MODULE_PARM_DESC(product_3410, "Product ids for 3410 based devices, 1-5 short integers");
+MODULE_PARM_DESC(product_3410,
+ "Product ids for 3410 based devices, 1-5 short integers");
module_param_array(vendor_5052, ushort, &vendor_5052_count, S_IRUGO);
-MODULE_PARM_DESC(vendor_5052, "Vendor ids for 5052 based devices, 1-5 short integers");
+MODULE_PARM_DESC(vendor_5052,
+ "Vendor ids for 5052 based devices, 1-5 short integers");
module_param_array(product_5052, ushort, &product_5052_count, S_IRUGO);
-MODULE_PARM_DESC(product_5052, "Product ids for 5052 based devices, 1-5 short integers");
+MODULE_PARM_DESC(product_5052,
+ "Product ids for 5052 based devices, 1-5 short integers");
MODULE_DEVICE_TABLE(usb, ti_id_table_combined);
static int __init ti_init(void)
{
- int i,j;
+ int i, j;
int ret;
/* insert extra vendor and product ids */
j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1;
- for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) {
+ for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++) {
ti_id_table_3410[j].idVendor = vendor_3410[i];
ti_id_table_3410[j].idProduct = product_3410[i];
ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
}
j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1;
- for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) {
+ for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++) {
ti_id_table_5052[j].idVendor = vendor_5052[i];
ti_id_table_5052[j].idProduct = product_5052[i];
ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
/* determine device type */
if (usb_match_id(serial->interface, ti_id_table_3410))
tdev->td_is_3410 = 1;
- dbg("%s - device type is %s", __func__, tdev->td_is_3410 ? "3410" : "5052");
+ dbg("%s - device type is %s", __func__,
+ tdev->td_is_3410 ? "3410" : "5052");
/* if we have only 1 configuration, download firmware */
if (dev->descriptor.bNumConfigurations == 1) {
-
if (tdev->td_is_3410)
- status = ti_download_firmware(tdev, "ti_3410.fw");
+ status = ti_download_firmware(tdev, 3410);
else
- status = ti_download_firmware(tdev, "ti_5052.fw");
+ status = ti_download_firmware(tdev, 5052);
if (status)
goto free_tdev;
status = -ENODEV;
goto free_tdev;
- }
+ }
/* the second configuration must be set (in sysfs by hotplug script) */
if (dev->actconfig->desc.bConfigurationValue == TI_BOOT_CONFIG) {
goto free_tports;
}
spin_lock_init(&tport->tp_lock);
- tport->tp_uart_base_addr = (i == 0 ? TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
+ tport->tp_uart_base_addr = (i == 0 ?
+ TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
tport->tp_closing_wait = closing_wait;
init_waitqueue_head(&tport->tp_msr_wait);
usb_set_serial_port_data(serial->port[i], tport);
tport->tp_uart_mode = 0; /* default is RS232 */
}
-
+
return 0;
free_tports:
- for (--i; i>=0; --i) {
+ for (--i; i >= 0; --i) {
tport = usb_get_serial_port_data(serial->port[i]);
ti_buf_free(tport->tp_write_buf);
kfree(tport);
dbg("%s", __func__);
- for (i=0; i < serial->num_ports; ++i) {
+ for (i = 0; i < serial->num_ports; ++i) {
tport = usb_get_serial_port_data(serial->port[i]);
if (tport) {
ti_buf_free(tport->tp_write_buf);
}
-static int ti_open(struct usb_serial_port *port, struct file *file)
+static int ti_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *file)
{
struct ti_port *tport = usb_get_serial_port_data(port);
struct ti_device *tdev;
struct urb *urb;
int port_number;
int status;
- __u16 open_settings = (__u8)(TI_PIPE_MODE_CONTINOUS |
- TI_PIPE_TIMEOUT_ENABLE |
+ __u16 open_settings = (__u8)(TI_PIPE_MODE_CONTINOUS |
+ TI_PIPE_TIMEOUT_ENABLE |
(TI_TRANSFER_TIMEOUT << 2));
dbg("%s - port %d", __func__, port->number);
if (mutex_lock_interruptible(&tdev->td_open_close_lock))
return -ERESTARTSYS;
- if (port->tty)
- port->tty->low_latency =
- (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ if (tty)
+ tty->low_latency =
+ (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
port_number = port->number - port->serial->minor;
dbg("%s - start interrupt in urb", __func__);
urb = tdev->td_serial->port[0]->interrupt_in_urb;
if (!urb) {
- dev_err(&port->dev, "%s - no interrupt urb\n", __func__);
+ dev_err(&port->dev, "%s - no interrupt urb\n",
+ __func__);
status = -EINVAL;
goto release_lock;
}
urb->dev = dev;
status = usb_submit_urb(urb, GFP_KERNEL);
if (status) {
- dev_err(&port->dev, "%s - submit interrupt urb failed, %d\n", __func__, status);
+ dev_err(&port->dev,
+ "%s - submit interrupt urb failed, %d\n",
+ __func__, status);
goto release_lock;
}
}
- ti_set_termios(port, port->tty->termios);
+ if (tty)
+ ti_set_termios(tty, port, tty->termios);
dbg("%s - sending TI_OPEN_PORT", __func__);
status = ti_command_out_sync(tdev, TI_OPEN_PORT,
(__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0);
if (status) {
- dev_err(&port->dev, "%s - cannot send open command, %d\n", __func__, status);
+ dev_err(&port->dev, "%s - cannot send open command, %d\n",
+ __func__, status);
goto unlink_int_urb;
}
status = ti_command_out_sync(tdev, TI_START_PORT,
(__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
if (status) {
- dev_err(&port->dev, "%s - cannot send start command, %d\n", __func__, status);
+ dev_err(&port->dev, "%s - cannot send start command, %d\n",
+ __func__, status);
goto unlink_int_urb;
}
status = ti_command_out_sync(tdev, TI_PURGE_PORT,
(__u8)(TI_UART1_PORT + port_number), TI_PURGE_INPUT, NULL, 0);
if (status) {
- dev_err(&port->dev, "%s - cannot clear input buffers, %d\n", __func__, status);
+ dev_err(&port->dev, "%s - cannot clear input buffers, %d\n",
+ __func__, status);
goto unlink_int_urb;
}
status = ti_command_out_sync(tdev, TI_PURGE_PORT,
(__u8)(TI_UART1_PORT + port_number), TI_PURGE_OUTPUT, NULL, 0);
if (status) {
- dev_err(&port->dev, "%s - cannot clear output buffers, %d\n", __func__, status);
+ dev_err(&port->dev, "%s - cannot clear output buffers, %d\n",
+ __func__, status);
goto unlink_int_urb;
}
usb_clear_halt(dev, port->write_urb->pipe);
usb_clear_halt(dev, port->read_urb->pipe);
- ti_set_termios(port, port->tty->termios);
+ if (tty)
+ ti_set_termios(tty, port, tty->termios);
dbg("%s - sending TI_OPEN_PORT (2)", __func__);
status = ti_command_out_sync(tdev, TI_OPEN_PORT,
(__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0);
if (status) {
- dev_err(&port->dev, "%s - cannot send open command (2), %d\n", __func__, status);
+ dev_err(&port->dev, "%s - cannot send open command (2), %d\n",
+ __func__, status);
goto unlink_int_urb;
}
status = ti_command_out_sync(tdev, TI_START_PORT,
(__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
if (status) {
- dev_err(&port->dev, "%s - cannot send start command (2), %d\n", __func__, status);
+ dev_err(&port->dev, "%s - cannot send start command (2), %d\n",
+ __func__, status);
goto unlink_int_urb;
}
urb->dev = dev;
status = usb_submit_urb(urb, GFP_KERNEL);
if (status) {
- dev_err(&port->dev, "%s - submit read urb failed, %d\n", __func__, status);
+ dev_err(&port->dev, "%s - submit read urb failed, %d\n",
+ __func__, status);
goto unlink_int_urb;
}
}
-static void ti_close(struct usb_serial_port *port, struct file *file)
+static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *file)
{
struct ti_device *tdev;
struct ti_port *tport;
int do_unlock;
dbg("%s - port %d", __func__, port->number);
-
+
tdev = usb_get_serial_data(port->serial);
tport = usb_get_serial_port_data(port);
if (tdev == NULL || tport == NULL)
status = ti_command_out_sync(tdev, TI_CLOSE_PORT,
(__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
if (status)
- dev_err(&port->dev, "%s - cannot send close port command, %d\n" , __func__, status);
+ dev_err(&port->dev,
+ "%s - cannot send close port command, %d\n"
+ , __func__, status);
/* if mutex_lock is interrupted, continue anyway */
do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock);
}
-static int ti_write(struct usb_serial_port *port, const unsigned char *data,
- int count)
+static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *data, int count)
{
struct ti_port *tport = usb_get_serial_port_data(port);
unsigned long flags;
}
-static int ti_write_room(struct usb_serial_port *port)
+static int ti_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ti_port *tport = usb_get_serial_port_data(port);
int room = 0;
unsigned long flags;
if (tport == NULL)
return -ENODEV;
-
+
spin_lock_irqsave(&tport->tp_lock, flags);
room = ti_buf_space_avail(tport->tp_write_buf);
spin_unlock_irqrestore(&tport->tp_lock, flags);
}
-static int ti_chars_in_buffer(struct usb_serial_port *port)
+static int ti_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ti_port *tport = usb_get_serial_port_data(port);
int chars = 0;
unsigned long flags;
}
-static void ti_throttle(struct usb_serial_port *port)
+static void ti_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ti_port *tport = usb_get_serial_port_data(port);
- struct tty_struct *tty;
dbg("%s - port %d", __func__, port->number);
if (tport == NULL)
return;
- tty = port->tty;
- if (!tty) {
- dbg("%s - no tty", __func__);
- return;
- }
-
if (I_IXOFF(tty) || C_CRTSCTS(tty))
ti_stop_read(tport, tty);
}
-static void ti_unthrottle(struct usb_serial_port *port)
+static void ti_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ti_port *tport = usb_get_serial_port_data(port);
- struct tty_struct *tty;
int status;
dbg("%s - port %d", __func__, port->number);
if (tport == NULL)
return;
- tty = port->tty;
- if (!tty) {
- dbg("%s - no tty", __func__);
- return;
- }
-
if (I_IXOFF(tty) || C_CRTSCTS(tty)) {
status = ti_restart_read(tport, tty);
if (status)
- dev_err(&port->dev, "%s - cannot restart read, %d\n", __func__, status);
+ dev_err(&port->dev, "%s - cannot restart read, %d\n",
+ __func__, status);
}
}
-static int ti_ioctl(struct usb_serial_port *port, struct file *file,
+static int ti_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ti_port *tport = usb_get_serial_port_data(port);
struct async_icount cnow;
struct async_icount cprev;
return -ENODEV;
switch (cmd) {
- case TIOCGSERIAL:
- dbg("%s - (%d) TIOCGSERIAL", __func__, port->number);
- return ti_get_serial_info(tport, (struct serial_struct __user *)arg);
- break;
-
- case TIOCSSERIAL:
- dbg("%s - (%d) TIOCSSERIAL", __func__, port->number);
- return ti_set_serial_info(tport, (struct serial_struct __user *)arg);
- break;
-
- case TIOCMIWAIT:
- dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
- cprev = tport->tp_icount;
- while (1) {
- interruptible_sleep_on(&tport->tp_msr_wait);
- if (signal_pending(current))
- return -ERESTARTSYS;
- cnow = tport->tp_icount;
- if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
- cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
- return -EIO; /* no change => error */
- if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
- return 0;
- }
- cprev = cnow;
- }
- break;
-
- case TIOCGICOUNT:
- dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, port->number, tport->tp_icount.rx, tport->tp_icount.tx);
- if (copy_to_user((void __user *)arg, &tport->tp_icount, sizeof(tport->tp_icount)))
- return -EFAULT;
- return 0;
+ case TIOCGSERIAL:
+ dbg("%s - (%d) TIOCGSERIAL", __func__, port->number);
+ return ti_get_serial_info(tport,
+ (struct serial_struct __user *)arg);
+ case TIOCSSERIAL:
+ dbg("%s - (%d) TIOCSSERIAL", __func__, port->number);
+ return ti_set_serial_info(tport,
+ (struct serial_struct __user *)arg);
+ case TIOCMIWAIT:
+ dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
+ cprev = tport->tp_icount;
+ while (1) {
+ interruptible_sleep_on(&tport->tp_msr_wait);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ cnow = tport->tp_icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+ return -EIO; /* no change => error */
+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)))
+ return 0;
+ cprev = cnow;
+ }
+ break;
+ case TIOCGICOUNT:
+ dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d",
+ __func__, port->number,
+ tport->tp_icount.rx, tport->tp_icount.tx);
+ if (copy_to_user((void __user *)arg, &tport->tp_icount,
+ sizeof(tport->tp_icount)))
+ return -EFAULT;
+ return 0;
}
-
return -ENOIOCTLCMD;
}
-static void ti_set_termios(struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void ti_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct ti_port *tport = usb_get_serial_port_data(port);
- struct tty_struct *tty = port->tty;
struct ti_uart_config *config;
- tcflag_t cflag,iflag;
+ tcflag_t cflag, iflag;
int baud;
int status;
int port_number = port->number - port->serial->minor;
iflag = tty->termios->c_iflag;
dbg("%s - cflag %08x, iflag %08x", __func__, cflag, iflag);
- dbg("%s - old clfag %08x, old iflag %08x", __func__, old_termios->c_cflag, old_termios->c_iflag);
+ dbg("%s - old clfag %08x, old iflag %08x", __func__,
+ old_termios->c_cflag, old_termios->c_iflag);
if (tport == NULL)
return;
config->bUartMode = (__u8)(tport->tp_uart_mode);
switch (cflag & CSIZE) {
- case CS5:
- config->bDataBits = TI_UART_5_DATA_BITS;
- break;
- case CS6:
- config->bDataBits = TI_UART_6_DATA_BITS;
- break;
- case CS7:
- config->bDataBits = TI_UART_7_DATA_BITS;
- break;
- default:
- case CS8:
- config->bDataBits = TI_UART_8_DATA_BITS;
- break;
+ case CS5:
+ config->bDataBits = TI_UART_5_DATA_BITS;
+ break;
+ case CS6:
+ config->bDataBits = TI_UART_6_DATA_BITS;
+ break;
+ case CS7:
+ config->bDataBits = TI_UART_7_DATA_BITS;
+ break;
+ default:
+ case CS8:
+ config->bDataBits = TI_UART_8_DATA_BITS;
+ break;
}
/* CMSPAR isn't supported by this driver */
}
} else {
config->wFlags &= ~TI_UART_ENABLE_PARITY_CHECKING;
- config->bParity = TI_UART_NO_PARITY;
+ config->bParity = TI_UART_NO_PARITY;
}
if (cflag & CSTOPB)
(__u8)(TI_UART1_PORT + port_number), 0, (__u8 *)config,
sizeof(*config));
if (status)
- dev_err(&port->dev, "%s - cannot set config on port %d, %d\n", __func__, port_number, status);
+ dev_err(&port->dev, "%s - cannot set config on port %d, %d\n",
+ __func__, port_number, status);
/* SET_CONFIG asserts RTS and DTR, reset them correctly */
mcr = tport->tp_shadow_mcr;
mcr &= ~(TI_MCR_DTR | TI_MCR_RTS);
status = ti_set_mcr(tport, mcr);
if (status)
- dev_err(&port->dev, "%s - cannot set modem control on port %d, %d\n", __func__, port_number, status);
+ dev_err(&port->dev,
+ "%s - cannot set modem control on port %d, %d\n",
+ __func__, port_number, status);
kfree(config);
}
-static int ti_tiocmget(struct usb_serial_port *port, struct file *file)
+static int ti_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ti_port *tport = usb_get_serial_port_data(port);
unsigned int result;
unsigned int msr;
}
-static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
+static int ti_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ti_port *tport = usb_get_serial_port_data(port);
unsigned int mcr;
unsigned long flags;
}
-static void ti_break(struct usb_serial_port *port, int break_state)
+static void ti_break(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct ti_port *tport = usb_get_serial_port_data(port);
int status;
port_number = TI_GET_PORT_FROM_CODE(data[0]);
function = TI_GET_FUNC_FROM_CODE(data[0]);
- dbg("%s - port_number %d, function %d, data 0x%02X", __func__, port_number, function, data[1]);
+ dbg("%s - port_number %d, function %d, data 0x%02X",
+ __func__, port_number, function, data[1]);
if (port_number >= serial->num_ports) {
- dev_err(dev, "%s - bad port number, %d\n", __func__, port_number);
+ dev_err(dev, "%s - bad port number, %d\n",
+ __func__, port_number);
goto exit;
}
switch (function) {
case TI_CODE_DATA_ERROR:
- dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n", __func__, port_number, data[1]);
+ dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n",
+ __func__, port_number, data[1]);
break;
case TI_CODE_MODEM_STATUS:
break;
default:
- dev_err(dev, "%s - unknown interrupt code, 0x%02X\n", __func__, data[1]);
+ dev_err(dev, "%s - unknown interrupt code, 0x%02X\n",
+ __func__, data[1]);
break;
}
return;
default:
dev_err(dev, "%s - nonzero urb status, %d\n",
- __func__, status );
+ __func__, status);
tport->tp_tdev->td_urb_error = 1;
wake_up_interruptible(&tport->tp_write_wait);
}
return;
}
- if (port->tty && urb->actual_length) {
+ if (port->port.tty && urb->actual_length) {
usb_serial_debug_data(debug, dev, __func__,
urb->actual_length, urb->transfer_buffer);
if (!tport->tp_is_open)
dbg("%s - port closed, dropping data", __func__);
else
- ti_recv(&urb->dev->dev, port->tty, urb->transfer_buffer,
- urb->actual_length);
+ ti_recv(&urb->dev->dev, port->port.tty,
+ urb->transfer_buffer,
+ urb->actual_length);
spin_lock(&tport->tp_lock);
tport->tp_icount.rx += urb->actual_length;
do {
cnt = tty_buffer_request_room(tty, length);
if (cnt < length) {
- dev_err(dev, "%s - dropping data, %d bytes lost\n", __func__, length - cnt);
- if(cnt == 0)
+ dev_err(dev, "%s - dropping data, %d bytes lost\n",
+ __func__, length - cnt);
+ if (cnt == 0)
break;
}
tty_insert_flip_string(tty, data, cnt);
{
int count, result;
struct usb_serial_port *port = tport->tp_port;
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty; /* FIXME */
unsigned long flags;
spin_unlock_irqrestore(&tport->tp_lock, flags);
- usb_serial_debug_data(debug, &port->dev, __func__, count, port->write_urb->transfer_buffer);
+ usb_serial_debug_data(debug, &port->dev, __func__, count,
+ port->write_urb->transfer_buffer);
usb_fill_bulk_urb(port->write_urb, port->serial->dev,
usb_sndbulkpipe(port->serial->dev,
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (result) {
- dev_err(&port->dev, "%s - submit write urb failed, %d\n", __func__, result);
- tport->tp_write_urb_in_use = 0;
+ dev_err(&port->dev, "%s - submit write urb failed, %d\n",
+ __func__, result);
+ tport->tp_write_urb_in_use = 0;
/* TODO: reschedule ti_send */
} else {
spin_lock_irqsave(&tport->tp_lock, flags);
static int ti_get_lsr(struct ti_port *tport)
{
- int size,status;
+ int size, status;
struct ti_device *tdev = tport->tp_tdev;
struct usb_serial_port *port = tport->tp_port;
int port_number = port->number - port->serial->minor;
status = ti_command_in_sync(tdev, TI_GET_PORT_STATUS,
(__u8)(TI_UART1_PORT+port_number), 0, (__u8 *)data, size);
if (status) {
- dev_err(&port->dev, "%s - get port status command failed, %d\n", __func__, status);
+ dev_err(&port->dev,
+ "%s - get port status command failed, %d\n",
+ __func__, status);
goto free_data;
}
return -EFAULT;
tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
- if (port->tty)
- port->tty->low_latency =
+ /* FIXME */
+ if (port->port.tty)
+ port->port.tty->low_latency =
(tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
tport->tp_closing_wait = new_serial.closing_wait;
tport->tp_msr = msr & TI_MSR_MASK;
/* handle CTS flow control */
- tty = tport->tp_port->tty;
+ tty = tport->tp_port->port.tty;
if (tty && C_CRTSCTS(tty)) {
if (msr & TI_MSR_CTS) {
tty->hw_stopped = 0;
struct ti_write_data_bytes *data;
struct device *dev = &tdev->td_serial->dev->dev;
- dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X", __func__, addr, mask, byte);
+ dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X",
+ __func__, addr, mask, byte);
size = sizeof(struct ti_write_data_bytes) + 2;
data = kmalloc(size, GFP_KERNEL);
return status;
}
-
-static int ti_download_firmware(struct ti_device *tdev,
- char *fw_name)
+static int ti_do_download(struct usb_device *dev, int pipe,
+ u8 *buffer, int size)
{
- const struct firmware *fw;
- int status = 0;
- int buffer_size;
int pos;
- int len;
+ u8 cs = 0;
int done;
- __u8 cs = 0;
- __u8 *buffer;
- struct usb_device *dev = tdev->td_serial->dev;
struct ti_firmware_header *header;
- unsigned int pipe = usb_sndbulkpipe(dev,
- tdev->td_serial->port[0]->bulk_out_endpointAddress);
-
- buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header);
-
- if (request_firmware(&fw, fw_name, &dev->dev)) {
- dev_err(&dev->dev, "%s - failed to load firmware \"%s\"\n",
- __func__, fw_name);
- return -ENOENT;
- }
- if (fw->size > buffer_size) {
- dev_err(&dev->dev, "%s - firmware \"%s\" is too large\n",
- __func__, fw_name);
- release_firmware(fw);
- return -EINVAL;
- }
-
- buffer = kmalloc(buffer_size, GFP_KERNEL);
- if (!buffer) {
- dev_err(&dev->dev, "%s - out of memory\n", __func__);
- release_firmware(fw);
- return -ENOMEM;
- }
-
- memcpy(buffer, fw->data, fw->size);
- memset(buffer+fw->size, 0xff, buffer_size-fw->size);
+ int status;
+ int len;
- for(pos = sizeof(struct ti_firmware_header); pos < buffer_size; pos++)
+ for (pos = sizeof(struct ti_firmware_header); pos < size; pos++)
cs = (__u8)(cs + buffer[pos]);
header = (struct ti_firmware_header *)buffer;
- header->wLength = cpu_to_le16((__u16)(buffer_size - sizeof(struct ti_firmware_header)));
+ header->wLength = cpu_to_le16((__u16)(size
+ - sizeof(struct ti_firmware_header)));
header->bCheckSum = cs;
dbg("%s - downloading firmware", __func__);
- for (pos = 0; pos < buffer_size; pos += done) {
- len = min(buffer_size - pos, TI_DOWNLOAD_MAX_PACKET_SIZE);
- status = usb_bulk_msg(dev, pipe, buffer+pos, len, &done, 1000);
+ for (pos = 0; pos < size; pos += done) {
+ len = min(size - pos, TI_DOWNLOAD_MAX_PACKET_SIZE);
+ status = usb_bulk_msg(dev, pipe, buffer + pos, len,
+ &done, 1000);
if (status)
break;
}
+ return status;
+}
- kfree(buffer);
- release_firmware(fw);
+static int ti_download_firmware(struct ti_device *tdev, int type)
+{
+ int status = -ENOMEM;
+ int buffer_size;
+ __u8 *buffer;
+ struct usb_device *dev = tdev->td_serial->dev;
+ unsigned int pipe = usb_sndbulkpipe(dev,
+ tdev->td_serial->port[0]->bulk_out_endpointAddress);
+ const struct firmware *fw_p;
+ char buf[32];
+ sprintf(buf, "ti_usb-%d.bin", type);
+ if (request_firmware(&fw_p, buf, &dev->dev)) {
+ dev_err(&dev->dev, "%s - firmware not found\n", __func__);
+ return -ENOENT;
+ }
+ if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
+ dev_err(&dev->dev, "%s - firmware too large\n", __func__);
+ return -ENOENT;
+ }
+
+ buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header);
+ buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (buffer) {
+ memcpy(buffer, fw_p->data, fw_p->size);
+ memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size);
+ ti_do_download(dev, pipe, buffer, fw_p->size);
+ kfree(buffer);
+ }
+ release_firmware(fw_p);
if (status) {
- dev_err(&dev->dev, "%s - error downloading firmware, %d\n", __func__, status);
+ dev_err(&dev->dev, "%s - error downloading firmware, %d\n",
+ __func__, status);
return status;
}
static int ti_buf_data_avail(struct circ_buf *cb)
{
- return CIRC_CNT(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
+ return CIRC_CNT(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
}
static int ti_buf_space_avail(struct circ_buf *cb)
{
- return CIRC_SPACE(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
+ return CIRC_SPACE(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
}
* This driver was originally based on the ACM driver by Armin Fuerst (which was
* based on a driver by Brad Keryan)
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
*/
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/list.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "pl2303.h"
*/
static int debug;
-static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
+/* initially all NULL */
+static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
static DEFINE_MUTEX(table_lock);
static LIST_HEAD(usb_serial_driver_list);
return serial;
}
-static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_ports, unsigned int *minor)
+static struct usb_serial *get_free_serial(struct usb_serial *serial,
+ int num_ports, unsigned int *minor)
{
unsigned int i, j;
int good_spot;
if (serial == NULL)
return;
- for (i = 0; i < serial->num_ports; ++i) {
+ for (i = 0; i < serial->num_ports; ++i)
serial_table[serial->minor + i] = NULL;
- }
}
static void destroy_serial(struct kref *kref)
return_serial(serial);
for (i = 0; i < serial->num_ports; ++i)
- serial->port[i]->open_count = 0;
+ serial->port[i]->port.count = 0;
/* the ports are cleaned up and released in port_release() */
for (i = 0; i < serial->num_ports; ++i)
* not get cleaned up in port_release() as it was never registered with
* the driver core */
if (serial->num_ports < serial->num_port_pointers) {
- for (i = serial->num_ports; i < serial->num_port_pointers; ++i) {
+ for (i = serial->num_ports;
+ i < serial->num_port_pointers; ++i) {
port = serial->port[i];
if (!port)
continue;
usb_put_dev(serial->dev);
/* free up any memory that we allocated */
- kfree (serial);
+ kfree(serial);
}
void usb_serial_put(struct usb_serial *serial)
/*****************************************************************************
* Driver tty interface functions
*****************************************************************************/
-static int serial_open (struct tty_struct *tty, struct file * filp)
+static int serial_open (struct tty_struct *tty, struct file *filp)
{
struct usb_serial *serial;
struct usb_serial_port *port;
unsigned int portNumber;
int retval;
-
+
dbg("%s", __func__);
/* get the serial object associated with this tty pointer */
retval = -ERESTARTSYS;
goto bailout_kref_put;
}
-
- ++port->open_count;
+
+ ++port->port.count;
/* set up our port structure making the tty driver
* remember our port object, and us it */
tty->driver_data = port;
- port->tty = tty;
+ port->port.tty = tty;
- if (port->open_count == 1) {
+ if (port->port.count == 1) {
/* lock this module before we call it
* this may fail, which means we must bail out,
retval = usb_autopm_get_interface(serial->interface);
if (retval)
goto bailout_module_put;
- /* only call the device specific open if this
+ /* only call the device specific open if this
* is the first time the port is opened */
- retval = serial->type->open(port, filp);
+ retval = serial->type->open(tty, port, filp);
if (retval)
goto bailout_interface_put;
}
bailout_module_put:
module_put(serial->type->driver.owner);
bailout_mutex_unlock:
- port->open_count = 0;
+ port->port.count = 0;
tty->driver_data = NULL;
- port->tty = NULL;
+ port->port.tty = NULL;
mutex_unlock(&port->mutex);
bailout_kref_put:
usb_serial_put(serial);
return retval;
}
-static void serial_close(struct tty_struct *tty, struct file * filp)
+static void serial_close(struct tty_struct *tty, struct file *filp)
{
struct usb_serial_port *port = tty->driver_data;
mutex_lock(&port->mutex);
- if (port->open_count == 0) {
+ if (port->port.count == 0) {
mutex_unlock(&port->mutex);
return;
}
- --port->open_count;
- if (port->open_count == 0)
- /* only call the device specific close if this
+ --port->port.count;
+ if (port->port.count == 0)
+ /* only call the device specific close if this
* port is being closed by the last owner */
- port->serial->type->close(port, filp);
+ port->serial->type->close(tty, port, filp);
- if (port->open_count == (port->console? 1 : 0)) {
- if (port->tty) {
- if (port->tty->driver_data)
- port->tty->driver_data = NULL;
- port->tty = NULL;
+ if (port->port.count == (port->console? 1 : 0)) {
+ if (port->port.tty) {
+ if (port->port.tty->driver_data)
+ port->port.tty->driver_data = NULL;
+ port->port.tty = NULL;
}
}
- if (port->open_count == 0) {
+ if (port->port.count == 0) {
mutex_lock(&port->serial->disc_mutex);
if (!port->serial->disconnected)
usb_autopm_put_interface(port->serial->interface);
usb_serial_put(port->serial);
}
-static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+ int count)
{
struct usb_serial_port *port = tty->driver_data;
int retval = -ENODEV;
dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
- /* open_count is managed under the mutex lock for the tty so cannot
- drop to zero until after the last close completes */
- WARN_ON(!port->open_count);
+ /* count is managed under the mutex lock for the tty so cannot
+ drop to zero until after the last close completes */
+ WARN_ON(!port->port.count);
/* pass on to the driver specific version of this function */
- retval = port->serial->type->write(port, buf, count);
+ retval = port->serial->type->write(tty, port, buf, count);
exit:
return retval;
}
-static int serial_write_room (struct tty_struct *tty)
+static int serial_write_room(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __func__, port->number);
- WARN_ON(!port->open_count);
+ WARN_ON(!port->port.count);
/* pass on to the driver specific version of this function */
- return port->serial->type->write_room(port);
+ return port->serial->type->write_room(tty);
}
-static int serial_chars_in_buffer (struct tty_struct *tty)
+static int serial_chars_in_buffer(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
dbg("%s = port %d", __func__, port->number);
- WARN_ON(!port->open_count);
+ WARN_ON(!port->port.count);
/* pass on to the driver specific version of this function */
- return port->serial->type->chars_in_buffer(port);
+ return port->serial->type->chars_in_buffer(tty);
}
-static void serial_throttle (struct tty_struct * tty)
+static void serial_throttle(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __func__, port->number);
- WARN_ON(!port->open_count);
+ WARN_ON(!port->port.count);
/* pass on to the driver specific version of this function */
if (port->serial->type->throttle)
- port->serial->type->throttle(port);
+ port->serial->type->throttle(tty);
}
-static void serial_unthrottle (struct tty_struct * tty)
+static void serial_unthrottle(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __func__, port->number);
- WARN_ON(!port->open_count);
+ WARN_ON(!port->port.count);
/* pass on to the driver specific version of this function */
if (port->serial->type->unthrottle)
- port->serial->type->unthrottle(port);
+ port->serial->type->unthrottle(tty);
}
-static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
struct usb_serial_port *port = tty->driver_data;
int retval = -ENODEV;
dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
- WARN_ON(!port->open_count);
+ WARN_ON(!port->port.count);
- /* pass on to the driver specific version of this function if it is available */
+ /* pass on to the driver specific version of this function
+ if it is available */
if (port->serial->type->ioctl) {
lock_kernel();
- retval = port->serial->type->ioctl(port, file, cmd, arg);
+ retval = port->serial->type->ioctl(tty, file, cmd, arg);
unlock_kernel();
- }
- else
+ } else
retval = -ENOIOCTLCMD;
return retval;
}
-static void serial_set_termios (struct tty_struct *tty, struct ktermios * old)
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
{
struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __func__, port->number);
- WARN_ON(!port->open_count);
- /* pass on to the driver specific version of this function if it is available */
+ WARN_ON(!port->port.count);
+ /* pass on to the driver specific version of this function
+ if it is available */
if (port->serial->type->set_termios)
- port->serial->type->set_termios(port, old);
+ port->serial->type->set_termios(tty, port, old);
else
tty_termios_copy_hw(tty->termios, old);
}
-static void serial_break (struct tty_struct *tty, int break_state)
+static int serial_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __func__, port->number);
- WARN_ON(!port->open_count);
- /* pass on to the driver specific version of this function if it is available */
+ WARN_ON(!port->port.count);
+ /* pass on to the driver specific version of this function
+ if it is available */
if (port->serial->type->break_ctl) {
lock_kernel();
- port->serial->type->break_ctl(port, break_state);
+ port->serial->type->break_ctl(tty, break_state);
unlock_kernel();
}
+ return 0;
}
-static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int serial_read_proc(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
{
struct usb_serial *serial;
int length = 0;
char tmp[40];
dbg("%s", __func__);
- length += sprintf (page, "usbserinfo:1.0 driver:2.0\n");
+ length += sprintf(page, "usbserinfo:1.0 driver:2.0\n");
for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
serial = usb_serial_get_by_index(i);
if (serial == NULL)
continue;
- length += sprintf (page+length, "%d:", i);
+ length += sprintf(page+length, "%d:", i);
if (serial->type->driver.owner)
- length += sprintf (page+length, " module:%s", module_name(serial->type->driver.owner));
- length += sprintf (page+length, " name:\"%s\"", serial->type->description);
- length += sprintf (page+length, " vendor:%04x product:%04x",
- le16_to_cpu(serial->dev->descriptor.idVendor),
- le16_to_cpu(serial->dev->descriptor.idProduct));
- length += sprintf (page+length, " num_ports:%d", serial->num_ports);
- length += sprintf (page+length, " port:%d", i - serial->minor + 1);
-
+ length += sprintf(page+length, " module:%s",
+ module_name(serial->type->driver.owner));
+ length += sprintf(page+length, " name:\"%s\"",
+ serial->type->description);
+ length += sprintf(page+length, " vendor:%04x product:%04x",
+ le16_to_cpu(serial->dev->descriptor.idVendor),
+ le16_to_cpu(serial->dev->descriptor.idProduct));
+ length += sprintf(page+length, " num_ports:%d",
+ serial->num_ports);
+ length += sprintf(page+length, " port:%d",
+ i - serial->minor + 1);
usb_make_path(serial->dev, tmp, sizeof(tmp));
- length += sprintf (page+length, " path:%s", tmp);
-
- length += sprintf (page+length, "\n");
+ length += sprintf(page+length, " path:%s", tmp);
+
+ length += sprintf(page+length, "\n");
if ((length + begin) > (off + count)) {
usb_serial_put(serial);
goto done;
if (off >= (length + begin))
return 0;
*start = page + (off-begin);
- return ((count < begin+length-off) ? count : begin+length-off);
+ return (count < begin+length-off) ? count : begin+length-off;
}
-static int serial_tiocmget (struct tty_struct *tty, struct file *file)
+static int serial_tiocmget(struct tty_struct *tty, struct file *file)
{
struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __func__, port->number);
- WARN_ON(!port->open_count);
+ WARN_ON(!port->port.count);
if (port->serial->type->tiocmget)
- return port->serial->type->tiocmget(port, file);
+ return port->serial->type->tiocmget(tty, file);
return -EINVAL;
}
-static int serial_tiocmset (struct tty_struct *tty, struct file *file,
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __func__, port->number);
- WARN_ON(!port->open_count);
+ WARN_ON(!port->port.count);
if (port->serial->type->tiocmset)
- return port->serial->type->tiocmset(port, file, set, clear);
+ return port->serial->type->tiocmset(tty, file, set, clear);
return -EINVAL;
}
{
schedule_work(&port->work);
}
+EXPORT_SYMBOL_GPL(usb_serial_port_softint);
static void usb_serial_port_work(struct work_struct *work)
{
struct tty_struct *tty;
dbg("%s - port %d", __func__, port->number);
-
+
if (!port)
return;
- tty = port->tty;
+ tty = port->port.tty;
if (!tty)
return;
kfree(port);
}
-static struct usb_serial * create_serial (struct usb_device *dev,
- struct usb_interface *interface,
- struct usb_serial_driver *driver)
+static struct usb_serial *create_serial(struct usb_device *dev,
+ struct usb_interface *interface,
+ struct usb_serial_driver *driver)
{
struct usb_serial *serial;
}
static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
- struct usb_serial_driver *drv)
+ struct usb_serial_driver *drv)
{
struct usb_dynid *dynid;
return id;
}
-static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
+static struct usb_serial_driver *search_serial_device(
+ struct usb_interface *iface)
{
const struct usb_device_id *id;
struct usb_serial_driver *drv;
int usb_serial_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
- struct usb_device *dev = interface_to_usbdev (interface);
+ struct usb_device *dev = interface_to_usbdev(interface);
struct usb_serial *serial = NULL;
struct usb_serial_port *port;
struct usb_host_interface *iface_desc;
return -ENODEV;
}
- serial = create_serial (dev, interface, type);
+ serial = create_serial(dev, interface, type);
if (!serial) {
unlock_kernel();
dev_err(&interface->dev, "%s - out of memory\n", __func__);
if (!try_module_get(type->driver.owner)) {
unlock_kernel();
- dev_err(&interface->dev, "module get failed, exiting\n");
- kfree (serial);
+ dev_err(&interface->dev,
+ "module get failed, exiting\n");
+ kfree(serial);
return -EIO;
}
if (retval) {
unlock_kernel();
- dbg ("sub driver rejected device");
- kfree (serial);
+ dbg("sub driver rejected device");
+ kfree(serial);
return retval;
}
}
}
#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
- /* BEGIN HORRIBLE HACK FOR PL2303 */
+ /* BEGIN HORRIBLE HACK FOR PL2303 */
/* this is needed due to the looney way its endpoints are set up */
if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&
(le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) ||
if (num_bulk_in == 0 || num_bulk_out == 0) {
unlock_kernel();
dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
- kfree (serial);
+ kfree(serial);
return -ENODEV;
}
}
num_ports = num_bulk_out;
if (num_ports == 0) {
unlock_kernel();
- dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n");
- kfree (serial);
+ dev_err(&interface->dev,
+ "Generic device with no bulk out, not allowed.\n");
+ kfree(serial);
return -EIO;
}
}
if (type->calc_num_ports) {
if (!try_module_get(type->driver.owner)) {
unlock_kernel();
- dev_err(&interface->dev, "module get failed, exiting\n");
- kfree (serial);
+ dev_err(&interface->dev,
+ "module get failed, exiting\n");
+ kfree(serial);
return -EIO;
}
- num_ports = type->calc_num_ports (serial);
+ num_ports = type->calc_num_ports(serial);
module_put(type->driver.owner);
}
if (!num_ports)
type->description);
/* create our ports, we need as many as the max endpoints */
- /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */
+ /* we don't use num_ports here because some devices have more
+ endpoint pairs than ports */
max_endpoints = max(num_bulk_in, num_bulk_out);
max_endpoints = max(max_endpoints, num_interrupt_in);
max_endpoints = max(max_endpoints, num_interrupt_out);
serial->num_port_pointers = max_endpoints;
unlock_kernel();
- dbg("%s - setting up %d port structures for this device", __func__, max_endpoints);
+ dbg("%s - setting up %d port structures for this device",
+ __func__, max_endpoints);
for (i = 0; i < max_endpoints; ++i) {
port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
if (!port)
for (i = 0; i < num_bulk_in; ++i) {
endpoint = bulk_in_endpoint[i];
port = serial->port[i];
- port->read_urb = usb_alloc_urb (0, GFP_KERNEL);
+ port->read_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!port->read_urb) {
dev_err(&interface->dev, "No free urbs available\n");
goto probe_error;
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
port->bulk_in_size = buffer_size;
port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
- port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+ port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!port->bulk_in_buffer) {
- dev_err(&interface->dev, "Couldn't allocate bulk_in_buffer\n");
+ dev_err(&interface->dev,
+ "Couldn't allocate bulk_in_buffer\n");
goto probe_error;
}
- usb_fill_bulk_urb (port->read_urb, dev,
- usb_rcvbulkpipe (dev,
- endpoint->bEndpointAddress),
- port->bulk_in_buffer, buffer_size,
- serial->type->read_bulk_callback,
- port);
+ usb_fill_bulk_urb(port->read_urb, dev,
+ usb_rcvbulkpipe(dev,
+ endpoint->bEndpointAddress),
+ port->bulk_in_buffer, buffer_size,
+ serial->type->read_bulk_callback, port);
}
for (i = 0; i < num_bulk_out; ++i) {
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
port->bulk_out_size = buffer_size;
port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
- port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
+ port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!port->bulk_out_buffer) {
- dev_err(&interface->dev, "Couldn't allocate bulk_out_buffer\n");
+ dev_err(&interface->dev,
+ "Couldn't allocate bulk_out_buffer\n");
goto probe_error;
}
- usb_fill_bulk_urb (port->write_urb, dev,
- usb_sndbulkpipe (dev,
- endpoint->bEndpointAddress),
- port->bulk_out_buffer, buffer_size,
- serial->type->write_bulk_callback,
- port);
+ usb_fill_bulk_urb(port->write_urb, dev,
+ usb_sndbulkpipe(dev,
+ endpoint->bEndpointAddress),
+ port->bulk_out_buffer, buffer_size,
+ serial->type->write_bulk_callback, port);
}
if (serial->type->read_int_callback) {
port = serial->port[i];
port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!port->interrupt_in_urb) {
- dev_err(&interface->dev, "No free urbs available\n");
+ dev_err(&interface->dev,
+ "No free urbs available\n");
goto probe_error;
}
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
- port->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
- port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+ port->interrupt_in_endpointAddress =
+ endpoint->bEndpointAddress;
+ port->interrupt_in_buffer = kmalloc(buffer_size,
+ GFP_KERNEL);
if (!port->interrupt_in_buffer) {
- dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n");
+ dev_err(&interface->dev,
+ "Couldn't allocate interrupt_in_buffer\n");
goto probe_error;
}
- usb_fill_int_urb (port->interrupt_in_urb, dev,
- usb_rcvintpipe (dev,
- endpoint->bEndpointAddress),
- port->interrupt_in_buffer, buffer_size,
- serial->type->read_int_callback, port,
- endpoint->bInterval);
+ usb_fill_int_urb(port->interrupt_in_urb, dev,
+ usb_rcvintpipe(dev,
+ endpoint->bEndpointAddress),
+ port->interrupt_in_buffer, buffer_size,
+ serial->type->read_int_callback, port,
+ endpoint->bInterval);
}
} else if (num_interrupt_in) {
dbg("the device claims to support interrupt in transfers, but read_int_callback is not defined");
}
-
+
if (serial->type->write_int_callback) {
for (i = 0; i < num_interrupt_out; ++i) {
endpoint = interrupt_out_endpoint[i];
port = serial->port[i];
port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!port->interrupt_out_urb) {
- dev_err(&interface->dev, "No free urbs available\n");
+ dev_err(&interface->dev,
+ "No free urbs available\n");
goto probe_error;
}
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
port->interrupt_out_size = buffer_size;
- port->interrupt_out_endpointAddress = endpoint->bEndpointAddress;
- port->interrupt_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
+ port->interrupt_out_endpointAddress =
+ endpoint->bEndpointAddress;
+ port->interrupt_out_buffer = kmalloc(buffer_size,
+ GFP_KERNEL);
if (!port->interrupt_out_buffer) {
- dev_err(&interface->dev, "Couldn't allocate interrupt_out_buffer\n");
+ dev_err(&interface->dev,
+ "Couldn't allocate interrupt_out_buffer\n");
goto probe_error;
}
- usb_fill_int_urb (port->interrupt_out_urb, dev,
- usb_sndintpipe (dev,
- endpoint->bEndpointAddress),
- port->interrupt_out_buffer, buffer_size,
- serial->type->write_int_callback, port,
- endpoint->bInterval);
+ usb_fill_int_urb(port->interrupt_out_urb, dev,
+ usb_sndintpipe(dev,
+ endpoint->bEndpointAddress),
+ port->interrupt_out_buffer, buffer_size,
+ serial->type->write_int_callback, port,
+ endpoint->bInterval);
}
} else if (num_interrupt_out) {
dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined");
}
-
+
/* if this device type has an attach function, call it */
if (type->attach) {
if (!try_module_get(type->driver.owner)) {
- dev_err(&interface->dev, "module get failed, exiting\n");
+ dev_err(&interface->dev,
+ "module get failed, exiting\n");
goto probe_error;
}
- retval = type->attach (serial);
+ retval = type->attach(serial);
module_put(type->driver.owner);
if (retval < 0)
goto probe_error;
if (retval > 0) {
- /* quietly accept this device, but don't bind to a serial port
- * as it's about to disappear */
+ /* quietly accept this device, but don't bind to a
+ serial port as it's about to disappear */
goto exit;
}
}
- if (get_free_serial (serial, num_ports, &minor) == NULL) {
+ if (get_free_serial(serial, num_ports, &minor) == NULL) {
dev_err(&interface->dev, "No more free serial devices\n");
goto probe_error;
}
"continuing\n");
}
- usb_serial_console_init (debug, minor);
+ usb_serial_console_init(debug, minor);
exit:
/* success */
- usb_set_intfdata (interface, serial);
+ usb_set_intfdata(interface, serial);
return 0;
probe_error:
/* free up any memory that we allocated */
for (i = 0; i < serial->num_port_pointers; ++i)
kfree(serial->port[i]);
- kfree (serial);
+ kfree(serial);
return -EIO;
}
+EXPORT_SYMBOL_GPL(usb_serial_probe);
void usb_serial_disconnect(struct usb_interface *interface)
{
int i;
- struct usb_serial *serial = usb_get_intfdata (interface);
+ struct usb_serial *serial = usb_get_intfdata(interface);
struct device *dev = &interface->dev;
struct usb_serial_port *port;
usb_serial_console_disconnect(serial);
- dbg ("%s", __func__);
+ dbg("%s", __func__);
mutex_lock(&serial->disc_mutex);
- usb_set_intfdata (interface, NULL);
+ usb_set_intfdata(interface, NULL);
/* must set a flag, to signal subdrivers */
serial->disconnected = 1;
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port) {
- if (port->tty)
- tty_hangup(port->tty);
+ if (port->port.tty)
+ tty_hangup(port->port.tty);
kill_traffic(port);
}
}
usb_serial_put(serial);
dev_info(dev, "device disconnected\n");
}
+EXPORT_SYMBOL_GPL(usb_serial_disconnect);
int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
{
return -ENOMEM;
/* Initialize our global data */
- for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
+ for (i = 0; i < SERIAL_TTY_MINORS; ++i)
serial_table[i] = NULL;
- }
result = bus_register(&usb_serial_bus_type);
if (result) {
usb_serial_tty_driver->minor_start = 0;
usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
- usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW |
+ TTY_DRIVER_DYNAMIC_DEV;
usb_serial_tty_driver->init_termios = tty_std_termios;
- usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD
+ | HUPCL | CLOCAL;
usb_serial_tty_driver->init_termios.c_ispeed = 9600;
usb_serial_tty_driver->init_termios.c_ospeed = 9600;
tty_set_operations(usb_serial_tty_driver, &serial_ops);
bus_unregister(&usb_serial_bus_type);
exit_bus:
- err ("%s - returning with error %d", __func__, result);
+ err("%s - returning with error %d", __func__, result);
put_tty_driver(usb_serial_tty_driver);
return result;
}
if (!type->function) { \
type->function = usb_serial_generic_##function; \
dbg("Had to override the " #function \
- " usb serial operation with the generic one.");\
+ " usb serial operation with the generic one.");\
} \
} while (0)
set_to_generic_if_null(device, resume);
}
-int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */
+int usb_serial_register(struct usb_serial_driver *driver)
{
+ /* must be called with BKL held */
int retval;
fixup_generic(driver);
retval = usb_serial_bus_register(driver);
if (retval) {
- err("problem %d when registering driver %s", retval, driver->description);
+ err("problem %d when registering driver %s",
+ retval, driver->description);
list_del(&driver->driver_list);
- }
- else
- info("USB Serial support registered for %s", driver->description);
+ } else
+ info("USB Serial support registered for %s",
+ driver->description);
return retval;
}
+EXPORT_SYMBOL_GPL(usb_serial_register);
-void usb_serial_deregister(struct usb_serial_driver *device) /* must be called with BKL held */
+void usb_serial_deregister(struct usb_serial_driver *device)
{
+ /* must be called with BKL held */
info("USB Serial deregistering driver %s", device->description);
list_del(&device->driver_list);
usb_serial_bus_deregister(device);
}
-
-
-
-/* If the usb-serial core is built into the core, the usb-serial drivers
- need these symbols to load properly as modules. */
-EXPORT_SYMBOL_GPL(usb_serial_register);
EXPORT_SYMBOL_GPL(usb_serial_deregister);
-EXPORT_SYMBOL_GPL(usb_serial_probe);
-EXPORT_SYMBOL_GPL(usb_serial_disconnect);
-EXPORT_SYMBOL_GPL(usb_serial_port_softint);
-
/* Module information */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
.no_dynamic_id = 1,
};
-int usb_debug_open(struct usb_serial_port *port, struct file *filp)
+int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
port->bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE;
- return usb_serial_generic_open(port, filp);
+ return usb_serial_generic_open(tty, port, filp);
}
static struct usb_serial_driver debug_device = {
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "visor.h"
#define DRIVER_DESC "USB HandSpring Visor / Palm OS driver"
/* function prototypes for a handspring visor */
-static int visor_open (struct usb_serial_port *port, struct file *filp);
-static void visor_close (struct usb_serial_port *port, struct file *filp);
-static int visor_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int visor_write_room (struct usb_serial_port *port);
-static int visor_chars_in_buffer (struct usb_serial_port *port);
-static void visor_throttle (struct usb_serial_port *port);
-static void visor_unthrottle (struct usb_serial_port *port);
-static int visor_probe (struct usb_serial *serial, const struct usb_device_id *id);
+static int visor_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static void visor_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static int visor_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+static int visor_write_room(struct tty_struct *tty);
+static void visor_throttle(struct tty_struct *tty);
+static void visor_unthrottle(struct tty_struct *tty);
+static int visor_probe(struct usb_serial *serial,
+ const struct usb_device_id *id);
static int visor_calc_num_ports(struct usb_serial *serial);
-static void visor_shutdown (struct usb_serial *serial);
-static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void visor_write_bulk_callback (struct urb *urb);
-static void visor_read_bulk_callback (struct urb *urb);
-static void visor_read_int_callback (struct urb *urb);
-static int clie_3_5_startup (struct usb_serial *serial);
-static int treo_attach (struct usb_serial *serial);
-static int clie_5_attach (struct usb_serial *serial);
-static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id);
-static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id);
+static void visor_shutdown(struct usb_serial *serial);
+static void visor_write_bulk_callback(struct urb *urb);
+static void visor_read_bulk_callback(struct urb *urb);
+static void visor_read_int_callback(struct urb *urb);
+static int clie_3_5_startup(struct usb_serial *serial);
+static int treo_attach(struct usb_serial *serial);
+static int clie_5_attach(struct usb_serial *serial);
+static int palm_os_3_probe(struct usb_serial *serial,
+ const struct usb_device_id *id);
+static int palm_os_4_probe(struct usb_serial *serial,
+ const struct usb_device_id *id);
/* Parameters that may be passed into the module. */
static int debug;
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
- { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID),
+ { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
- { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID),
+ { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
- { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID),
+ { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver visor_driver = {
.name = "visor",
.no_dynamic_id = 1,
};
-/* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
+/* All of the device info needed for the Handspring Visor,
+ and Palm 4.0 devices */
static struct usb_serial_driver handspring_device = {
.driver = {
.owner = THIS_MODULE,
.probe = visor_probe,
.calc_num_ports = visor_calc_num_ports,
.shutdown = visor_shutdown,
- .ioctl = visor_ioctl,
.write = visor_write,
.write_room = visor_write_room,
- .chars_in_buffer = visor_chars_in_buffer,
.write_bulk_callback = visor_write_bulk_callback,
.read_bulk_callback = visor_read_bulk_callback,
.read_int_callback = visor_read_int_callback,
.probe = visor_probe,
.calc_num_ports = visor_calc_num_ports,
.shutdown = visor_shutdown,
- .ioctl = visor_ioctl,
.write = visor_write,
.write_room = visor_write_room,
- .chars_in_buffer = visor_chars_in_buffer,
.write_bulk_callback = visor_write_bulk_callback,
.read_bulk_callback = visor_read_bulk_callback,
.read_int_callback = visor_read_int_callback,
.throttle = visor_throttle,
.unthrottle = visor_unthrottle,
.attach = clie_3_5_startup,
- .ioctl = visor_ioctl,
.write = visor_write,
.write_room = visor_write_room,
- .chars_in_buffer = visor_chars_in_buffer,
.write_bulk_callback = visor_write_bulk_callback,
.read_bulk_callback = visor_read_bulk_callback,
};
/******************************************************************************
* Handspring Visor specific driver functions
******************************************************************************/
-static int visor_open (struct usb_serial_port *port, struct file *filp)
+static int visor_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
{
struct usb_serial *serial = port->serial;
struct visor_private *priv = usb_get_serial_port_data(port);
* through, otherwise it is scheduled, and with high data rates (like
* with OHCI) data can get lost.
*/
- if (port->tty)
- port->tty->low_latency = 1;
+ if (tty)
+ tty->low_latency = 1;
/* Start reading from the device */
- usb_fill_bulk_urb (port->read_urb, serial->dev,
- usb_rcvbulkpipe (serial->dev,
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
visor_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result) {
- dev_err(&port->dev, "%s - failed submitting read urb, error %d\n",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
goto exit;
}
-
+
if (port->interrupt_in_urb) {
dbg("%s - adding interrupt input for treo", __func__);
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result)
- dev_err(&port->dev, "%s - failed submitting interrupt urb, error %d\n",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting interrupt urb, error %d\n",
+ __func__, result);
}
-exit:
+exit:
return result;
}
-static void visor_close (struct usb_serial_port *port, struct file * filp)
+static void visor_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned char *transfer_buffer;
dbg("%s - port %d", __func__, port->number);
-
+
/* shutdown our urbs */
usb_kill_urb(port->read_urb);
usb_kill_urb(port->interrupt_in_urb);
mutex_lock(&port->serial->disc_mutex);
if (!port->serial->disconnected) {
/* Try to send shutdown message, unless the device is gone */
- transfer_buffer = kmalloc (0x12, GFP_KERNEL);
+ transfer_buffer = kmalloc(0x12, GFP_KERNEL);
if (transfer_buffer) {
- usb_control_msg (port->serial->dev,
+ usb_control_msg(port->serial->dev,
usb_rcvctrlpipe(port->serial->dev, 0),
VISOR_CLOSE_NOTIFICATION, 0xc2,
0x0000, 0x0000,
transfer_buffer, 0x12, 300);
- kfree (transfer_buffer);
+ kfree(transfer_buffer);
}
}
mutex_unlock(&port->serial->disc_mutex);
}
-static int visor_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int visor_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
struct visor_private *priv = usb_get_serial_port_data(port);
struct usb_serial *serial = port->serial;
priv->outstanding_urbs++;
spin_unlock_irqrestore(&priv->lock, flags);
- buffer = kmalloc (count, GFP_ATOMIC);
+ buffer = kmalloc(count, GFP_ATOMIC);
if (!buffer) {
dev_err(&port->dev, "out of memory\n");
count = -ENOMEM;
goto error_no_urb;
}
- memcpy (buffer, buf, count);
+ memcpy(buffer, buf, count);
usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
- usb_fill_bulk_urb (urb, serial->dev,
- usb_sndbulkpipe (serial->dev,
+ usb_fill_bulk_urb(urb, serial->dev,
+ usb_sndbulkpipe(serial->dev,
port->bulk_out_endpointAddress),
- buffer, count,
+ buffer, count,
visor_write_bulk_callback, port);
/* send it down the pipe */
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
- dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n",
- __func__, status);
+ dev_err(&port->dev,
+ "%s - usb_submit_urb(write bulk) failed with status = %d\n",
+ __func__, status);
count = status;
goto error;
} else {
}
-static int visor_write_room (struct usb_serial_port *port)
+static int visor_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
}
-static int visor_chars_in_buffer (struct usb_serial_port *port)
-{
- dbg("%s - port %d", __func__, port->number);
-
- /*
- * We can't really account for how much data we
- * have sent out, but hasn't made it through to the
- * device, so just tell the tty layer that everything
- * is flushed.
- *
- * FIXME: Should walk outstanding_urbs
- */
- return 0;
-}
-
-
-static void visor_write_bulk_callback (struct urb *urb)
+static void visor_write_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
/* free up the transfer buffer, as usb_free_urb() does not do this */
- kfree (urb->transfer_buffer);
+ kfree(urb->transfer_buffer);
dbg("%s - port %d", __func__, port->number);
}
-static void visor_read_bulk_callback (struct urb *urb)
+static void visor_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct visor_private *priv = usb_get_serial_port_data(port);
return;
}
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, data);
- tty = port->tty;
+ tty = port->port.tty;
if (tty && urb->actual_length) {
- available_room = tty_buffer_request_room(tty, urb->actual_length);
+ available_room = tty_buffer_request_room(tty,
+ urb->actual_length);
if (available_room) {
tty_insert_flip_string(tty, data, available_room);
tty_flip_buffer_push(tty);
/* Continue trying to always read if we should */
if (!priv->throttled) {
- usb_fill_bulk_urb (port->read_urb, port->serial->dev,
+ usb_fill_bulk_urb(port->read_urb, port->serial->dev,
usb_rcvbulkpipe(port->serial->dev,
- port->bulk_in_endpointAddress),
+ port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
visor_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
- } else {
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
+ } else
priv->actually_throttled = 1;
- }
spin_unlock(&priv->lock);
}
-static void visor_read_int_callback (struct urb *urb)
+static void visor_read_int_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
int status = urb->status;
urb->actual_length, urb->transfer_buffer);
exit:
- result = usb_submit_urb (urb, GFP_ATOMIC);
+ result = usb_submit_urb(urb, GFP_ATOMIC);
if (result)
- dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n",
- __func__, result);
+ dev_err(&urb->dev->dev,
+ "%s - Error %d submitting interrupt urb\n",
+ __func__, result);
}
-static void visor_throttle (struct usb_serial_port *port)
+static void visor_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
}
-static void visor_unthrottle (struct usb_serial_port *port)
+static void visor_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
int result;
port->read_urb->dev = port->serial->dev;
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
}
-static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id)
+static int palm_os_3_probe(struct usb_serial *serial,
+ const struct usb_device_id *id)
{
struct device *dev = &serial->dev->dev;
struct visor_connection_info *connection_info;
dbg("%s", __func__);
- transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL);
+ transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL);
if (!transfer_buffer) {
dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__,
sizeof(*connection_info));
}
/* send a get connection info request */
- retval = usb_control_msg (serial->dev,
+ retval = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
VISOR_GET_CONNECTION_INFORMATION,
0xc2, 0x0000, 0x0000, transfer_buffer,
}
if (retval == sizeof(*connection_info)) {
- connection_info = (struct visor_connection_info *)transfer_buffer;
+ connection_info = (struct visor_connection_info *)
+ transfer_buffer;
num_ports = le16_to_cpu(connection_info->num_ports);
for (i = 0; i < num_ports; ++i) {
- switch (connection_info->connections[i].port_function_id) {
- case VISOR_FUNCTION_GENERIC:
- string = "Generic";
- break;
- case VISOR_FUNCTION_DEBUGGER:
- string = "Debugger";
- break;
- case VISOR_FUNCTION_HOTSYNC:
- string = "HotSync";
- break;
- case VISOR_FUNCTION_CONSOLE:
- string = "Console";
- break;
- case VISOR_FUNCTION_REMOTE_FILE_SYS:
- string = "Remote File System";
- break;
- default:
- string = "unknown";
- break;
+ switch (
+ connection_info->connections[i].port_function_id) {
+ case VISOR_FUNCTION_GENERIC:
+ string = "Generic";
+ break;
+ case VISOR_FUNCTION_DEBUGGER:
+ string = "Debugger";
+ break;
+ case VISOR_FUNCTION_HOTSYNC:
+ string = "HotSync";
+ break;
+ case VISOR_FUNCTION_CONSOLE:
+ string = "Console";
+ break;
+ case VISOR_FUNCTION_REMOTE_FILE_SYS:
+ string = "Remote File System";
+ break;
+ default:
+ string = "unknown";
+ break;
}
dev_info(dev, "%s: port %d, is for %s use\n",
serial->type->description,
* Handle devices that report invalid stuff here.
*/
if (num_ports == 0 || num_ports > 2) {
- dev_warn (dev, "%s: No valid connect info available\n",
+ dev_warn(dev, "%s: No valid connect info available\n",
serial->type->description);
num_ports = 2;
}
-
+
dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,
num_ports);
*/
usb_set_serial_data(serial, (void *)(long)num_ports);
- /* ask for the number of bytes available, but ignore the response as it is broken */
- retval = usb_control_msg (serial->dev,
+ /* ask for the number of bytes available, but ignore the
+ response as it is broken */
+ retval = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
VISOR_REQUEST_BYTES_AVAILABLE,
0xc2, 0x0000, 0x0005, transfer_buffer,
retval = 0;
exit:
- kfree (transfer_buffer);
+ kfree(transfer_buffer);
return retval;
}
-static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id)
+static int palm_os_4_probe(struct usb_serial *serial,
+ const struct usb_device_id *id)
{
struct device *dev = &serial->dev->dev;
struct palm_ext_connection_info *connection_info;
dbg("%s", __func__);
- transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL);
+ transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL);
if (!transfer_buffer) {
dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__,
sizeof(*connection_info));
return -ENOMEM;
}
- retval = usb_control_msg (serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
+ retval = usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
PALM_GET_EXT_CONNECTION_INFORMATION,
0xc2, 0x0000, 0x0000, transfer_buffer,
- sizeof (*connection_info), 300);
+ sizeof(*connection_info), 300);
if (retval < 0)
dev_err(dev, "%s - error %d getting connection info\n",
__func__, retval);
usb_serial_debug_data(debug, &serial->dev->dev, __func__,
retval, transfer_buffer);
- kfree (transfer_buffer);
+ kfree(transfer_buffer);
return 0;
}
-static int visor_probe (struct usb_serial *serial, const struct usb_device_id *id)
+static int visor_probe(struct usb_serial *serial,
+ const struct usb_device_id *id)
{
int retval = 0;
- int (*startup) (struct usb_serial *serial, const struct usb_device_id *id);
+ int (*startup)(struct usb_serial *serial,
+ const struct usb_device_id *id);
dbg("%s", __func__);
return retval;
}
-static int visor_calc_num_ports (struct usb_serial *serial)
+static int visor_calc_num_ports(struct usb_serial *serial)
{
int num_ports = (int)(long)(usb_get_serial_data(serial));
int i;
for (i = 0; i < serial->num_ports; ++i) {
- priv = kzalloc (sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
while (i-- != 0) {
priv = usb_get_serial_port_data(ports[i]);
return 0;
}
-static int clie_3_5_startup (struct usb_serial *serial)
+static int clie_3_5_startup(struct usb_serial *serial)
{
struct device *dev = &serial->dev->dev;
int result;
*/
/* get the config number */
- result = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
USB_REQ_GET_CONFIGURATION, USB_DIR_IN,
0, 0, &data, 1, 3000);
if (result < 0) {
- dev_err(dev, "%s: get config number failed: %d\n", __func__, result);
+ dev_err(dev, "%s: get config number failed: %d\n",
+ __func__, result);
return result;
}
if (result != 1) {
- dev_err(dev, "%s: get config number bad return length: %d\n", __func__, result);
+ dev_err(dev, "%s: get config number bad return length: %d\n",
+ __func__, result);
return -EIO;
}
/* get the interface number */
- result = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- USB_REQ_GET_INTERFACE,
+ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ USB_REQ_GET_INTERFACE,
USB_DIR_IN | USB_RECIP_INTERFACE,
0, 0, &data, 1, 3000);
if (result < 0) {
- dev_err(dev, "%s: get interface number failed: %d\n", __func__, result);
+ dev_err(dev, "%s: get interface number failed: %d\n",
+ __func__, result);
return result;
}
if (result != 1) {
- dev_err(dev, "%s: get interface number bad return length: %d\n", __func__, result);
+ dev_err(dev,
+ "%s: get interface number bad return length: %d\n",
+ __func__, result);
return -EIO;
}
return generic_startup(serial);
}
-
-static int treo_attach (struct usb_serial *serial)
+
+static int treo_attach(struct usb_serial *serial)
{
struct usb_serial_port *swap_port;
/* Only do this endpoint hack for the Handspring devices with
* interrupt in endpoints, which for now are the Treo devices. */
- if (!((le16_to_cpu(serial->dev->descriptor.idVendor) == HANDSPRING_VENDOR_ID) ||
- (le16_to_cpu(serial->dev->descriptor.idVendor) == KYOCERA_VENDOR_ID)) ||
- (serial->num_interrupt_in == 0))
+ if (!((le16_to_cpu(serial->dev->descriptor.idVendor)
+ == HANDSPRING_VENDOR_ID) ||
+ (le16_to_cpu(serial->dev->descriptor.idVendor)
+ == KYOCERA_VENDOR_ID)) ||
+ (serial->num_interrupt_in == 0))
goto generic_startup;
dbg("%s", __func__);
/*
- * It appears that Treos and Kyoceras want to use the
- * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
- * so let's swap the 1st and 2nd bulk in and interrupt endpoints.
- * Note that swapping the bulk out endpoints would break lots of
+ * It appears that Treos and Kyoceras want to use the
+ * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
+ * so let's swap the 1st and 2nd bulk in and interrupt endpoints.
+ * Note that swapping the bulk out endpoints would break lots of
* apps that want to communicate on the second port.
*/
#define COPY_PORT(dest, src) \
- dest->read_urb = src->read_urb; \
- dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress; \
- dest->bulk_in_buffer = src->bulk_in_buffer; \
- dest->interrupt_in_urb = src->interrupt_in_urb; \
- dest->interrupt_in_endpointAddress = src->interrupt_in_endpointAddress; \
- dest->interrupt_in_buffer = src->interrupt_in_buffer;
+ do { \
+ dest->read_urb = src->read_urb; \
+ dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
+ dest->bulk_in_buffer = src->bulk_in_buffer; \
+ dest->interrupt_in_urb = src->interrupt_in_urb; \
+ dest->interrupt_in_endpointAddress = \
+ src->interrupt_in_endpointAddress;\
+ dest->interrupt_in_buffer = src->interrupt_in_buffer; \
+ } while (0);
swap_port = kmalloc(sizeof(*swap_port), GFP_KERNEL);
if (!swap_port)
return generic_startup(serial);
}
-static int clie_5_attach (struct usb_serial *serial)
+static int clie_5_attach(struct usb_serial *serial)
{
dbg("%s", __func__);
- /* TH55 registers 2 ports.
- Communication in from the UX50/TH55 uses bulk_in_endpointAddress from port 0
- Communication out to the UX50/TH55 uses bulk_out_endpointAddress from port 1
-
+ /* TH55 registers 2 ports.
+ Communication in from the UX50/TH55 uses bulk_in_endpointAddress
+ from port 0. Communication out to the UX50/TH55 uses
+ bulk_out_endpointAddress from port 1
+
Lets do a quick and dirty mapping
*/
-
+
/* some sanity check */
if (serial->num_ports < 2)
return -1;
-
+
/* port 0 now uses the modified endpoint Address */
- serial->port[0]->bulk_out_endpointAddress = serial->port[1]->bulk_out_endpointAddress;
+ serial->port[0]->bulk_out_endpointAddress =
+ serial->port[1]->bulk_out_endpointAddress;
return generic_startup(serial);
}
-static void visor_shutdown (struct usb_serial *serial)
+static void visor_shutdown(struct usb_serial *serial)
{
struct visor_private *priv;
int i;
}
}
-static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
-{
- dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
-
- return -ENOIOCTLCMD;
-}
-
-static int __init visor_init (void)
+static int __init visor_init(void)
{
int i, retval;
/* Only if parameters were passed to us */
- if ((vendor>0) && (product>0)) {
- struct usb_device_id usb_dev_temp[]=
- {{USB_DEVICE(vendor, product),
- .driver_info = (kernel_ulong_t)&palm_os_4_probe }};
+ if (vendor > 0 && product > 0) {
+ struct usb_device_id usb_dev_temp[] = {
+ {
+ USB_DEVICE(vendor, product),
+ .driver_info =
+ (kernel_ulong_t) &palm_os_4_probe
+ }
+ };
/* Find the last entry in id_table */
- for (i=0; ; i++) {
- if (id_table[i].idVendor==0) {
+ for (i = 0;; i++) {
+ if (id_table[i].idVendor == 0) {
id_table[i] = usb_dev_temp[0];
break;
}
}
/* Find the last entry in id_table_combined */
- for (i=0; ; i++) {
- if (id_table_combined[i].idVendor==0) {
+ for (i = 0;; i++) {
+ if (id_table_combined[i].idVendor == 0) {
id_table_combined[i] = usb_dev_temp[0];
break;
}
}
- info("Untested USB device specified at time of module insertion");
+ info(
+ "Untested USB device specified at time of module insertion");
info("Warning: This is not guaranteed to work");
info("Using a newer kernel is preferred to this method");
info("Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x",
if (retval)
goto failed_clie_5_register;
retval = usb_register(&visor_driver);
- if (retval)
+ if (retval)
goto failed_usb_register;
info(DRIVER_DESC);
static void __exit visor_exit (void)
{
- usb_deregister (&visor_driver);
- usb_serial_deregister (&handspring_device);
- usb_serial_deregister (&clie_3_5_device);
- usb_serial_deregister (&clie_5_device);
+ usb_deregister(&visor_driver);
+ usb_serial_deregister(&handspring_device);
+ usb_serial_deregister(&clie_3_5_device);
+ usb_serial_deregister(&clie_5_device);
}
module_init(visor_init);
module_exit(visor_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
* (10/09/2002) Stuart MacDonald (stuartm@connecttech.com)
* Upgrade to full working driver
*
* (05/30/2001) gkh
- * switched from using spinlock to a semaphore, which fixes lots of problems.
+ * switched from using spinlock to a semaphore, which fixes lots of
+ * problems.
*
* (04/08/2001) gb
* Identify version on module load.
- *
+ *
* 2001_Mar_19 gkh
- * Fixed MOD_INC and MOD_DEC logic, the ability to open a port more
+ * Fixed MOD_INC and MOD_DEC logic, the ability to open a port more
* than once, and the got the proper usb_device_id table entries so
* the driver works again.
*
* (11/01/2000) Adam J. Richter
* usb_device_id table support
- *
+ *
* (10/05/2000) gkh
* Fixed bug with urb->dev not being set properly, now that the usb
* core needs it.
- *
+ *
* (10/03/2000) smd
* firmware is improved to guard against crap sent to device
* firmware now replies CMD_FAILURE on bad things
* Fixed bug with port->minor that was found by Al Borchers
*
* (07/04/2000) gkh
- * Added support for port settings. Baud rate can now be changed. Line signals
- * are not transferred to and from the tty layer yet, but things seem to be
- * working well now.
+ * Added support for port settings. Baud rate can now be changed. Line
+ * signals are not transferred to and from the tty layer yet, but things
+ * seem to be working well now.
*
* (05/04/2000) gkh
* First cut at open and close commands. Data can flow through the ports at
*
* (03/26/2000) gkh
* Split driver up into device specific pieces.
- *
+ *
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/termbits.h>
#include <linux/usb.h>
#include <linux/serial_reg.h>
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver whiteheat_driver = {
.name = "whiteheat",
};
/* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */
-static int whiteheat_firmware_download (struct usb_serial *serial, const struct usb_device_id *id);
-static int whiteheat_firmware_attach (struct usb_serial *serial);
+static int whiteheat_firmware_download(struct usb_serial *serial,
+ const struct usb_device_id *id);
+static int whiteheat_firmware_attach(struct usb_serial *serial);
/* function prototypes for the Connect Tech WhiteHEAT serial converter */
-static int whiteheat_attach (struct usb_serial *serial);
-static void whiteheat_shutdown (struct usb_serial *serial);
-static int whiteheat_open (struct usb_serial_port *port, struct file *filp);
-static void whiteheat_close (struct usb_serial_port *port, struct file *filp);
-static int whiteheat_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int whiteheat_write_room (struct usb_serial_port *port);
-static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void whiteheat_set_termios (struct usb_serial_port *port, struct ktermios * old);
-static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file);
-static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
-static void whiteheat_break_ctl (struct usb_serial_port *port, int break_state);
-static int whiteheat_chars_in_buffer (struct usb_serial_port *port);
-static void whiteheat_throttle (struct usb_serial_port *port);
-static void whiteheat_unthrottle (struct usb_serial_port *port);
-static void whiteheat_read_callback (struct urb *urb);
-static void whiteheat_write_callback (struct urb *urb);
+static int whiteheat_attach(struct usb_serial *serial);
+static void whiteheat_shutdown(struct usb_serial *serial);
+static int whiteheat_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static void whiteheat_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+static int whiteheat_write(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+static int whiteheat_write_room(struct tty_struct *tty);
+static int whiteheat_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void whiteheat_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
+static int whiteheat_tiocmget(struct tty_struct *tty, struct file *file);
+static int whiteheat_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static void whiteheat_break_ctl(struct tty_struct *tty, int break_state);
+static int whiteheat_chars_in_buffer(struct tty_struct *tty);
+static void whiteheat_throttle(struct tty_struct *tty);
+static void whiteheat_unthrottle(struct tty_struct *tty);
+static void whiteheat_read_callback(struct urb *urb);
+static void whiteheat_write_callback(struct urb *urb);
static struct usb_serial_driver whiteheat_fake_device = {
.driver = {
struct mutex mutex;
__u8 port_running;
__u8 command_finished;
- wait_queue_head_t wait_command; /* for handling sleeping while waiting for a command to finish */
+ wait_queue_head_t wait_command; /* for handling sleeping whilst
+ waiting for a command to
+ finish */
__u8 result_buffer[64];
};
static void command_port_read_callback(struct urb *urb);
static int start_port_read(struct usb_serial_port *port);
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head);
+static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
+ struct list_head *head);
static struct list_head *list_first(struct list_head *head);
static void rx_data_softint(struct work_struct *work);
-static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize);
+static int firm_send_command(struct usb_serial_port *port, __u8 command,
+ __u8 *data, __u8 datasize);
static int firm_open(struct usb_serial_port *port);
static int firm_close(struct usb_serial_port *port);
-static int firm_setup_port(struct usb_serial_port *port);
+static int firm_setup_port(struct tty_struct *tty);
static int firm_set_rts(struct usb_serial_port *port, __u8 onoff);
static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff);
static int firm_set_break(struct usb_serial_port *port, __u8 onoff);
- device renumerated itself and comes up as new device id with all
firmware download completed.
*/
-static int whiteheat_firmware_download (struct usb_serial *serial, const struct usb_device_id *id)
+static int whiteheat_firmware_download(struct usb_serial *serial,
+ const struct usb_device_id *id)
{
int response, ret = -ENOENT;
const struct firmware *loader_fw = NULL, *firmware_fw = NULL;
record = ihex_next_binrec(record);
}
- response = ezusb_set_reset (serial, 0);
+ response = ezusb_set_reset(serial, 0);
record = (const struct ihex_binrec *)firmware_fw->data;
while (record && be32_to_cpu(record->addr) < 0x1b40)
}
++record;
}
-
- response = ezusb_set_reset (serial, 1);
+
+ response = ezusb_set_reset(serial, 1);
record = (const struct ihex_binrec *)firmware_fw->data;
while (record && be32_to_cpu(record->addr) < 0x1b40) {
}
-static int whiteheat_firmware_attach (struct usb_serial *serial)
+static int whiteheat_firmware_attach(struct usb_serial *serial)
{
/* We want this device to fail to have a driver assigned to it */
return 1;
/*****************************************************************************
* Connect Tech's White Heat serial driver functions
*****************************************************************************/
-static int whiteheat_attach (struct usb_serial *serial)
+static int whiteheat_attach(struct usb_serial *serial)
{
struct usb_serial_port *command_port;
struct whiteheat_command_private *command_info;
command_port = serial->port[COMMAND_PORT];
- pipe = usb_sndbulkpipe (serial->dev, command_port->bulk_out_endpointAddress);
+ pipe = usb_sndbulkpipe(serial->dev,
+ command_port->bulk_out_endpointAddress);
command = kmalloc(2, GFP_KERNEL);
if (!command)
goto no_command_buffer;
command[0] = WHITEHEAT_GET_HW_INFO;
command[1] = 0;
-
+
result = kmalloc(sizeof(*hw_info) + 1, GFP_KERNEL);
if (!result)
goto no_result_buffer;
/*
* When the module is reloaded the firmware is still there and
* the endpoints are still in the usb core unchanged. This is the
- * unlinking bug in disguise. Same for the call below.
- */
+ * unlinking bug in disguise. Same for the call below.
+ */
usb_clear_halt(serial->dev, pipe);
- ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS);
+ ret = usb_bulk_msg(serial->dev, pipe, command, 2,
+ &alen, COMMAND_TIMEOUT_MS);
if (ret) {
- err("%s: Couldn't send command [%d]", serial->type->description, ret);
+ err("%s: Couldn't send command [%d]",
+ serial->type->description, ret);
goto no_firmware;
} else if (alen != 2) {
- err("%s: Send command incomplete [%d]", serial->type->description, alen);
+ err("%s: Send command incomplete [%d]",
+ serial->type->description, alen);
goto no_firmware;
}
- pipe = usb_rcvbulkpipe (serial->dev, command_port->bulk_in_endpointAddress);
+ pipe = usb_rcvbulkpipe(serial->dev,
+ command_port->bulk_in_endpointAddress);
/* See the comment on the usb_clear_halt() above */
usb_clear_halt(serial->dev, pipe);
- ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
+ ret = usb_bulk_msg(serial->dev, pipe, result,
+ sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
if (ret) {
- err("%s: Couldn't get results [%d]", serial->type->description, ret);
+ err("%s: Couldn't get results [%d]",
+ serial->type->description, ret);
goto no_firmware;
} else if (alen != sizeof(*hw_info) + 1) {
- err("%s: Get results incomplete [%d]", serial->type->description, alen);
+ err("%s: Get results incomplete [%d]",
+ serial->type->description, alen);
goto no_firmware;
} else if (result[0] != command[0]) {
- err("%s: Command failed [%d]", serial->type->description, result[0]);
+ err("%s: Command failed [%d]",
+ serial->type->description, result[0]);
goto no_firmware;
}
info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
if (info == NULL) {
- err("%s: Out of memory for port structures\n", serial->type->description);
+ err("%s: Out of memory for port structures\n",
+ serial->type->description);
goto no_private;
}
usb_set_serial_port_data(port, info);
}
- command_info = kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
+ command_info = kmalloc(sizeof(struct whiteheat_command_private),
+ GFP_KERNEL);
if (command_info == NULL) {
- err("%s: Out of memory for port structures\n", serial->type->description);
+ err("%s: Out of memory for port structures\n",
+ serial->type->description);
goto no_command_private;
}
no_firmware:
/* Firmware likely not running */
- err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->description);
- err("%s: If the firmware is not running (status led not blinking)\n", serial->type->description);
- err("%s: please contact support@connecttech.com\n", serial->type->description);
+ err("%s: Unable to retrieve firmware version, try replugging\n",
+ serial->type->description);
+ err("%s: If the firmware is not running (status led not blinking)\n",
+ serial->type->description);
+ err("%s: please contact support@connecttech.com\n",
+ serial->type->description);
kfree(result);
return -ENODEV;
}
-static void whiteheat_shutdown (struct usb_serial *serial)
+static void whiteheat_shutdown(struct usb_serial *serial)
{
struct usb_serial_port *command_port;
struct usb_serial_port *port;
/* free up our private data for our command port */
command_port = serial->port[COMMAND_PORT];
- kfree (usb_get_serial_port_data(command_port));
+ kfree(usb_get_serial_port_data(command_port));
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
return;
}
-
-static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
+static int whiteheat_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
int retval = 0;
- struct ktermios old_term;
dbg("%s - port %d", __func__, port->number);
if (retval)
goto exit;
- port->tty->low_latency = 1;
+ if (tty)
+ tty->low_latency = 1;
/* send an open port command */
retval = firm_open(port);
goto exit;
}
- old_term.c_cflag = ~port->tty->termios->c_cflag;
- old_term.c_iflag = ~port->tty->termios->c_iflag;
- whiteheat_set_termios(port, &old_term);
+ if (tty)
+ firm_setup_port(tty);
/* Work around HCD bugs */
usb_clear_halt(port->serial->dev, port->read_urb->pipe);
/* Start reading from the device */
retval = start_port_read(port);
if (retval) {
- err("%s - failed submitting read urb, error %d", __func__, retval);
+ err("%s - failed submitting read urb, error %d",
+ __func__, retval);
firm_close(port);
stop_command_port(port->serial);
goto exit;
}
-static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
+static void whiteheat_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct whiteheat_urb_wrap *wrap;
}
mutex_unlock(&port->serial->disc_mutex);
- port->tty->closing = 1;
+ tty->closing = 1;
/*
* Not currently in use; tty_wait_until_sent() calls
* acquisition. This should be fixed at some point. Greg's been
* notified.
if ((filp->f_flags & (O_NDELAY | O_NONBLOCK)) == 0) {
- tty_wait_until_sent(port->tty, CLOSING_DELAY);
+ tty_wait_until_sent(tty, CLOSING_DELAY);
}
*/
- tty_driver_flush_buffer(port->tty);
- tty_ldisc_flush(port->tty);
+ tty_driver_flush_buffer(tty);
+ tty_ldisc_flush(tty);
firm_report_tx_done(port);
stop_command_port(port->serial);
- port->tty->closing = 0;
+ tty->closing = 0;
}
-static int whiteheat_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+static int whiteheat_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct usb_serial *serial = port->serial;
struct whiteheat_private *info = usb_get_serial_port_data(port);
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
- bytes = (count > port->bulk_out_size) ? port->bulk_out_size : count;
- memcpy (urb->transfer_buffer, buf + sent, bytes);
+ bytes = (count > port->bulk_out_size) ?
+ port->bulk_out_size : count;
+ memcpy(urb->transfer_buffer, buf + sent, bytes);
- usb_serial_debug_data(debug, &port->dev, __func__, bytes, urb->transfer_buffer);
+ usb_serial_debug_data(debug, &port->dev,
+ __func__, bytes, urb->transfer_buffer);
urb->dev = serial->dev;
urb->transfer_buffer_length = bytes;
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result) {
- err("%s - failed submitting write urb, error %d", __func__, result);
+ err("%s - failed submitting write urb, error %d",
+ __func__, result);
sent = result;
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->tx_urbs_free);
return sent;
}
-
-static int whiteheat_write_room(struct usb_serial_port *port)
+static int whiteheat_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct list_head *tmp;
int room = 0;
unsigned long flags;
dbg("%s - port %d", __func__, port->number);
-
+
spin_lock_irqsave(&info->lock, flags);
list_for_each(tmp, &info->tx_urbs_free)
room++;
return (room);
}
-
-static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file)
+static int whiteheat_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
unsigned int modem_signals = 0;
return modem_signals;
}
-
-static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file,
+static int whiteheat_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
dbg("%s - port %d", __func__, port->number);
}
-static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+static int whiteheat_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
+ struct usb_serial_port *port = tty->driver_data;
struct serial_struct serstruct;
void __user *user_arg = (void __user *)arg;
dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
switch (cmd) {
- case TIOCGSERIAL:
- memset(&serstruct, 0, sizeof(serstruct));
- serstruct.type = PORT_16654;
- serstruct.line = port->serial->minor;
- serstruct.port = port->number;
- serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
- serstruct.xmit_fifo_size = port->bulk_out_size;
- serstruct.custom_divisor = 0;
- serstruct.baud_base = 460800;
- serstruct.close_delay = CLOSING_DELAY;
- serstruct.closing_wait = CLOSING_DELAY;
-
- if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
- return -EFAULT;
-
- break;
-
- case TIOCSSERIAL:
- if (copy_from_user(&serstruct, user_arg, sizeof(serstruct)))
- return -EFAULT;
-
- /*
- * For now this is ignored. dip sets the ASYNC_[V]HI flags
- * but this isn't used by us at all. Maybe someone somewhere
- * will need the custom_divisor setting.
- */
-
- break;
-
- default:
- break;
+ case TIOCGSERIAL:
+ memset(&serstruct, 0, sizeof(serstruct));
+ serstruct.type = PORT_16654;
+ serstruct.line = port->serial->minor;
+ serstruct.port = port->number;
+ serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+ serstruct.xmit_fifo_size = port->bulk_out_size;
+ serstruct.custom_divisor = 0;
+ serstruct.baud_base = 460800;
+ serstruct.close_delay = CLOSING_DELAY;
+ serstruct.closing_wait = CLOSING_DELAY;
+
+ if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
+ return -EFAULT;
+ break;
+ default:
+ break;
}
return -ENOIOCTLCMD;
}
-static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
+static void whiteheat_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
- dbg("%s -port %d", __func__, port->number);
- firm_setup_port(port);
+ firm_setup_port(tty);
}
-
-static void whiteheat_break_ctl(struct usb_serial_port *port, int break_state) {
+static void whiteheat_break_ctl(struct tty_struct *tty, int break_state)
+{
+ struct usb_serial_port *port = tty->driver_data;
firm_set_break(port, break_state);
}
-static int whiteheat_chars_in_buffer(struct usb_serial_port *port)
+static int whiteheat_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct list_head *tmp;
struct whiteheat_urb_wrap *wrap;
}
spin_unlock_irqrestore(&info->lock, flags);
- dbg ("%s - returns %d", __func__, chars);
+ dbg("%s - returns %d", __func__, chars);
return chars;
}
-static void whiteheat_throttle (struct usb_serial_port *port)
+static void whiteheat_throttle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
unsigned long flags;
}
-static void whiteheat_unthrottle (struct usb_serial_port *port)
+static void whiteheat_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
int actually_throttled;
unsigned long flags;
command_info = usb_get_serial_port_data(command_port);
if (!command_info) {
- dbg ("%s - command_info is NULL, exiting.", __func__);
+ dbg("%s - command_info is NULL, exiting.", __func__);
return;
}
if (status) {
return;
}
- usb_serial_debug_data(debug, &command_port->dev, __func__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &command_port->dev,
+ __func__, urb->actual_length, data);
if (data[0] == WHITEHEAT_CMD_COMPLETE) {
command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
command_info->command_finished = WHITEHEAT_CMD_FAILURE;
wake_up(&command_info->wait_command);
} else if (data[0] == WHITEHEAT_EVENT) {
- /* These are unsolicited reports from the firmware, hence no waiting command to wakeup */
+ /* These are unsolicited reports from the firmware, hence no
+ waiting command to wakeup */
dbg("%s - event received", __func__);
} else if (data[0] == WHITEHEAT_GET_DTR_RTS) {
- memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1);
+ memcpy(command_info->result_buffer, &data[1],
+ urb->actual_length - 1);
command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
wake_up(&command_info->wait_command);
- } else {
+ } else
dbg("%s - bad reply from firmware", __func__);
- }
-
+
/* Continue trying to always read */
command_port->read_urb->dev = command_port->serial->dev;
result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC);
if (result)
- dbg("%s - failed resubmitting read urb, error %d", __func__, result);
+ dbg("%s - failed resubmitting read urb, error %d",
+ __func__, result);
}
return;
}
- usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev,
+ __func__, urb->actual_length, data);
spin_lock(&info->lock);
list_add_tail(&wrap->list, &info->rx_urb_q);
/*****************************************************************************
* Connect Tech's White Heat firmware interface
*****************************************************************************/
-static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize)
+static int firm_send_command(struct usb_serial_port *port, __u8 command,
+ __u8 *data, __u8 datasize)
{
struct usb_serial_port *command_port;
struct whiteheat_command_private *command_info;
command_info = usb_get_serial_port_data(command_port);
mutex_lock(&command_info->mutex);
command_info->command_finished = false;
-
+
transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer;
transfer_buffer[0] = command;
- memcpy (&transfer_buffer[1], data, datasize);
+ memcpy(&transfer_buffer[1], data, datasize);
command_port->write_urb->transfer_buffer_length = datasize + 1;
command_port->write_urb->dev = port->serial->dev;
- retval = usb_submit_urb (command_port->write_urb, GFP_NOIO);
+ retval = usb_submit_urb(command_port->write_urb, GFP_NOIO);
if (retval) {
dbg("%s - submit urb failed", __func__);
goto exit;
if (command_info->command_finished == WHITEHEAT_CMD_COMPLETE) {
dbg("%s - command completed.", __func__);
switch (command) {
- case WHITEHEAT_GET_DTR_RTS:
- info = usb_get_serial_port_data(port);
- memcpy(&info->mcr, command_info->result_buffer, sizeof(struct whiteheat_dr_info));
+ case WHITEHEAT_GET_DTR_RTS:
+ info = usb_get_serial_port_data(port);
+ memcpy(&info->mcr, command_info->result_buffer,
+ sizeof(struct whiteheat_dr_info));
break;
}
}
-
exit:
mutex_unlock(&command_info->mutex);
return retval;
}
-static int firm_open(struct usb_serial_port *port) {
+static int firm_open(struct usb_serial_port *port)
+{
struct whiteheat_simple open_command;
open_command.port = port->number - port->serial->minor + 1;
- return firm_send_command(port, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
+ return firm_send_command(port, WHITEHEAT_OPEN,
+ (__u8 *)&open_command, sizeof(open_command));
}
-static int firm_close(struct usb_serial_port *port) {
+static int firm_close(struct usb_serial_port *port)
+{
struct whiteheat_simple close_command;
close_command.port = port->number - port->serial->minor + 1;
- return firm_send_command(port, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command));
+ return firm_send_command(port, WHITEHEAT_CLOSE,
+ (__u8 *)&close_command, sizeof(close_command));
}
-static int firm_setup_port(struct usb_serial_port *port) {
+static int firm_setup_port(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
struct whiteheat_port_settings port_settings;
- unsigned int cflag = port->tty->termios->c_cflag;
+ unsigned int cflag = tty->termios->c_cflag;
port_settings.port = port->number + 1;
/* get the byte size */
switch (cflag & CSIZE) {
- case CS5: port_settings.bits = 5; break;
- case CS6: port_settings.bits = 6; break;
- case CS7: port_settings.bits = 7; break;
- default:
- case CS8: port_settings.bits = 8; break;
+ case CS5: port_settings.bits = 5; break;
+ case CS6: port_settings.bits = 6; break;
+ case CS7: port_settings.bits = 7; break;
+ default:
+ case CS8: port_settings.bits = 8; break;
}
dbg("%s - data bits = %d", __func__, port_settings.bits);
-
+
/* determine the parity */
if (cflag & PARENB)
if (cflag & CMSPAR)
/* figure out the flow control settings */
if (cflag & CRTSCTS)
- port_settings.hflow = (WHITEHEAT_HFLOW_CTS | WHITEHEAT_HFLOW_RTS);
+ port_settings.hflow = (WHITEHEAT_HFLOW_CTS |
+ WHITEHEAT_HFLOW_RTS);
else
port_settings.hflow = WHITEHEAT_HFLOW_NONE;
dbg("%s - hardware flow control = %s %s %s %s", __func__,
(port_settings.hflow & WHITEHEAT_HFLOW_RTS) ? "RTS" : "",
(port_settings.hflow & WHITEHEAT_HFLOW_DSR) ? "DSR" : "",
(port_settings.hflow & WHITEHEAT_HFLOW_DTR) ? "DTR" : "");
-
+
/* determine software flow control */
- if (I_IXOFF(port->tty))
+ if (I_IXOFF(tty))
port_settings.sflow = WHITEHEAT_SFLOW_RXTX;
else
port_settings.sflow = WHITEHEAT_SFLOW_NONE;
dbg("%s - software flow control = %c", __func__, port_settings.sflow);
-
- port_settings.xon = START_CHAR(port->tty);
- port_settings.xoff = STOP_CHAR(port->tty);
- dbg("%s - XON = %2x, XOFF = %2x", __func__, port_settings.xon, port_settings.xoff);
+
+ port_settings.xon = START_CHAR(tty);
+ port_settings.xoff = STOP_CHAR(tty);
+ dbg("%s - XON = %2x, XOFF = %2x",
+ __func__, port_settings.xon, port_settings.xoff);
/* get the baud rate wanted */
- port_settings.baud = tty_get_baud_rate(port->tty);
+ port_settings.baud = tty_get_baud_rate(tty);
dbg("%s - baud rate = %d", __func__, port_settings.baud);
/* fixme: should set validated settings */
- tty_encode_baud_rate(port->tty, port_settings.baud, port_settings.baud);
+ tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud);
/* handle any settings that aren't specified in the tty structure */
port_settings.lloop = 0;
-
+
/* now send the message to the device */
- return firm_send_command(port, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));
+ return firm_send_command(port, WHITEHEAT_SETUP_PORT,
+ (__u8 *)&port_settings, sizeof(port_settings));
}
-static int firm_set_rts(struct usb_serial_port *port, __u8 onoff) {
+static int firm_set_rts(struct usb_serial_port *port, __u8 onoff)
+{
struct whiteheat_set_rdb rts_command;
rts_command.port = port->number - port->serial->minor + 1;
rts_command.state = onoff;
- return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&rts_command, sizeof(rts_command));
+ return firm_send_command(port, WHITEHEAT_SET_RTS,
+ (__u8 *)&rts_command, sizeof(rts_command));
}
-static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff) {
+static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff)
+{
struct whiteheat_set_rdb dtr_command;
dtr_command.port = port->number - port->serial->minor + 1;
dtr_command.state = onoff;
- return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&dtr_command, sizeof(dtr_command));
+ return firm_send_command(port, WHITEHEAT_SET_DTR,
+ (__u8 *)&dtr_command, sizeof(dtr_command));
}
-static int firm_set_break(struct usb_serial_port *port, __u8 onoff) {
+static int firm_set_break(struct usb_serial_port *port, __u8 onoff)
+{
struct whiteheat_set_rdb break_command;
break_command.port = port->number - port->serial->minor + 1;
break_command.state = onoff;
- return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&break_command, sizeof(break_command));
+ return firm_send_command(port, WHITEHEAT_SET_BREAK,
+ (__u8 *)&break_command, sizeof(break_command));
}
-static int firm_purge(struct usb_serial_port *port, __u8 rxtx) {
+static int firm_purge(struct usb_serial_port *port, __u8 rxtx)
+{
struct whiteheat_purge purge_command;
purge_command.port = port->number - port->serial->minor + 1;
purge_command.what = rxtx;
- return firm_send_command(port, WHITEHEAT_PURGE, (__u8 *)&purge_command, sizeof(purge_command));
+ return firm_send_command(port, WHITEHEAT_PURGE,
+ (__u8 *)&purge_command, sizeof(purge_command));
}
-static int firm_get_dtr_rts(struct usb_serial_port *port) {
+static int firm_get_dtr_rts(struct usb_serial_port *port)
+{
struct whiteheat_simple get_dr_command;
get_dr_command.port = port->number - port->serial->minor + 1;
- return firm_send_command(port, WHITEHEAT_GET_DTR_RTS, (__u8 *)&get_dr_command, sizeof(get_dr_command));
+ return firm_send_command(port, WHITEHEAT_GET_DTR_RTS,
+ (__u8 *)&get_dr_command, sizeof(get_dr_command));
}
-static int firm_report_tx_done(struct usb_serial_port *port) {
+static int firm_report_tx_done(struct usb_serial_port *port)
+{
struct whiteheat_simple close_command;
close_command.port = port->number - port->serial->minor + 1;
- return firm_send_command(port, WHITEHEAT_REPORT_TX_DONE, (__u8 *)&close_command, sizeof(close_command));
+ return firm_send_command(port, WHITEHEAT_REPORT_TX_DONE,
+ (__u8 *)&close_command, sizeof(close_command));
}
struct usb_serial_port *command_port;
struct whiteheat_command_private *command_info;
int retval = 0;
-
+
command_port = serial->port[COMMAND_PORT];
command_info = usb_get_serial_port_data(command_port);
mutex_lock(&command_info->mutex);
command_port->read_urb->dev = serial->dev;
retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL);
if (retval) {
- err("%s - failed submitting read urb, error %d", __func__, retval);
+ err("%s - failed submitting read urb, error %d",
+ __func__, retval);
goto exit;
}
}
}
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb* urb, struct list_head *head)
+static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
+ struct list_head *head)
{
struct whiteheat_urb_wrap *wrap;
struct list_head *tmp;
struct whiteheat_private *info =
container_of(work, struct whiteheat_private, rx_work);
struct usb_serial_port *port = info->port;
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
struct whiteheat_urb_wrap *wrap;
struct urb *urb;
unsigned long flags;
urb = wrap->urb;
if (tty && urb->actual_length) {
- int len = tty_buffer_request_room(tty, urb->actual_length);
+ int len = tty_buffer_request_room(tty,
+ urb->actual_length);
/* This stuff can go away now I suspect */
if (unlikely(len < urb->actual_length)) {
spin_lock_irqsave(&info->lock, flags);
urb->dev = port->serial->dev;
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result) {
- err("%s - failed resubmitting read urb, error %d", __func__, result);
+ err("%s - failed resubmitting read urb, error %d",
+ __func__, result);
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->rx_urbs_free);
continue;
/*****************************************************************************
* Connect Tech's White Heat module functions
*****************************************************************************/
-static int __init whiteheat_init (void)
+static int __init whiteheat_init(void)
{
int retval;
retval = usb_serial_register(&whiteheat_fake_device);
}
-static void __exit whiteheat_exit (void)
+static void __exit whiteheat_exit(void)
{
- usb_deregister (&whiteheat_driver);
- usb_serial_deregister (&whiteheat_fake_device);
- usb_serial_deregister (&whiteheat_device);
+ usb_deregister(&whiteheat_driver);
+ usb_serial_deregister(&whiteheat_fake_device);
+ usb_serial_deregister(&whiteheat_device);
}
module_init(whiteheat_init);
module_exit(whiteheat_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("whiteheat.fw");
* USB ConnectTech WhiteHEAT driver
*
* Copyright (C) 2002
- * Connect Tech Inc.
+ * Connect Tech Inc.
*
* Copyright (C) 1999, 2000
* Greg Kroah-Hartman (greg@kroah.com)
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
*
*/
#define WHITEHEAT_DUMP 7 /* dump memory */
#define WHITEHEAT_STATUS 8 /* get status */
#define WHITEHEAT_PURGE 9 /* clear the UART fifos */
-#define WHITEHEAT_GET_DTR_RTS 10 /* get the state of DTR and RTS for a port */
-#define WHITEHEAT_GET_HW_INFO 11 /* get EEPROM info and hardware ID */
+#define WHITEHEAT_GET_DTR_RTS 10 /* get the state of DTR and RTS
+ for a port */
+#define WHITEHEAT_GET_HW_INFO 11 /* get EEPROM info and
+ hardware ID */
#define WHITEHEAT_REPORT_TX_DONE 12 /* get the next TX done */
#define WHITEHEAT_EVENT 13 /* unsolicited status events */
-#define WHITEHEAT_ECHO 14 /* send data to the indicated IN endpoint */
-#define WHITEHEAT_DO_TEST 15 /* perform the specified test */
-#define WHITEHEAT_CMD_COMPLETE 16 /* reply for certain commands */
+#define WHITEHEAT_ECHO 14 /* send data to the indicated
+ IN endpoint */
+#define WHITEHEAT_DO_TEST 15 /* perform specified test */
+#define WHITEHEAT_CMD_COMPLETE 16 /* reply for some commands */
#define WHITEHEAT_CMD_FAILURE 17 /* reply for failed commands */
#define WHITEHEAT_PAR_MARK '1' /* mark (force 1) parity */
#define WHITEHEAT_SFLOW_NONE 'n' /* no software flow control */
-#define WHITEHEAT_SFLOW_RX 'r' /* XOFF/ON is sent when RX fills/empties */
-#define WHITEHEAT_SFLOW_TX 't' /* when received XOFF/ON will stop/start TX */
+#define WHITEHEAT_SFLOW_RX 'r' /* XOFF/ON is sent when RX
+ fills/empties */
+#define WHITEHEAT_SFLOW_TX 't' /* when received XOFF/ON will
+ stop/start TX */
#define WHITEHEAT_SFLOW_RXTX 'b' /* both SFLOW_RX and SFLOW_TX */
#define WHITEHEAT_HFLOW_NONE 0x00 /* no hardware flow control */
-#define WHITEHEAT_HFLOW_RTS_TOGGLE 0x01 /* RTS is on during transmit, off otherwise */
-#define WHITEHEAT_HFLOW_DTR 0x02 /* DTR is off/on when RX fills/empties */
-#define WHITEHEAT_HFLOW_CTS 0x08 /* when received CTS off/on will stop/start TX */
-#define WHITEHEAT_HFLOW_DSR 0x10 /* when received DSR off/on will stop/start TX */
-#define WHITEHEAT_HFLOW_RTS 0x80 /* RTS is off/on when RX fills/empties */
+#define WHITEHEAT_HFLOW_RTS_TOGGLE 0x01 /* RTS is on during transmit,
+ off otherwise */
+#define WHITEHEAT_HFLOW_DTR 0x02 /* DTR is off/on when RX
+ fills/empties */
+#define WHITEHEAT_HFLOW_CTS 0x08 /* when received CTS off/on
+ will stop/start TX */
+#define WHITEHEAT_HFLOW_DSR 0x10 /* when received DSR off/on
+ will stop/start TX */
+#define WHITEHEAT_HFLOW_RTS 0x80 /* RTS is off/on when RX
+ fills/empties */
struct whiteheat_port_settings {
__u8 port; /* port number (1 to N) */
- __u32 baud; /* any value 7 - 460800, firmware calculates best fit; arrives little endian */
+ __u32 baud; /* any value 7 - 460800, firmware calculates
+ best fit; arrives little endian */
__u8 bits; /* 5, 6, 7, or 8 */
__u8 stop; /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */
__u8 parity; /* see WHITEHEAT_PAR_* above */
*/
#define WHITEHEAT_TEST_UART_RW 0x01 /* read/write uart registers */
#define WHITEHEAT_TEST_UART_INTR 0x02 /* uart interrupt */
-#define WHITEHEAT_TEST_SETUP_CONT 0x03 /* setup for PORT_CONT/PORT_DISCONT */
+#define WHITEHEAT_TEST_SETUP_CONT 0x03 /* setup for
+ PORT_CONT/PORT_DISCONT */
#define WHITEHEAT_TEST_PORT_CONT 0x04 /* port connect */
#define WHITEHEAT_TEST_PORT_DISCONT 0x05 /* port disconnect */
#define WHITEHEAT_TEST_UART_CLK_START 0x06 /* uart clock test start */
#define WHITEHEAT_TEST_UART_CLK_STOP 0x07 /* uart clock test stop */
-#define WHITEHEAT_TEST_MODEM_FT 0x08 /* modem signals, requires a loopback cable/connector */
+#define WHITEHEAT_TEST_MODEM_FT 0x08 /* modem signals, requires a
+ loopback cable/connector */
#define WHITEHEAT_TEST_ERASE_EEPROM 0x09 /* erase eeprom */
#define WHITEHEAT_TEST_READ_EEPROM 0x0a /* read eeprom */
#define WHITEHEAT_TEST_PROGRAM_EEPROM 0x0b /* program eeprom */
#define WHITEHEAT_EVENT_CONNECT 0x08 /* connect field is valid */
#define WHITEHEAT_FLOW_NONE 0x00 /* no flow control active */
-#define WHITEHEAT_FLOW_HARD_OUT 0x01 /* TX is stopped by CTS (waiting for CTS to go on) */
-#define WHITEHEAT_FLOW_HARD_IN 0x02 /* remote TX is stopped by RTS */
-#define WHITEHEAT_FLOW_SOFT_OUT 0x04 /* TX is stopped by XOFF received (waiting for XON) */
-#define WHITEHEAT_FLOW_SOFT_IN 0x08 /* remote TX is stopped by XOFF transmitted */
+#define WHITEHEAT_FLOW_HARD_OUT 0x01 /* TX is stopped by CTS
+ (waiting for CTS to go on) */
+#define WHITEHEAT_FLOW_HARD_IN 0x02 /* remote TX is stopped
+ by RTS */
+#define WHITEHEAT_FLOW_SOFT_OUT 0x04 /* TX is stopped by XOFF
+ received (waiting for XON) */
+#define WHITEHEAT_FLOW_SOFT_IN 0x08 /* remote TX is stopped by XOFF
+ transmitted */
#define WHITEHEAT_FLOW_TX_DONE 0x80 /* TX has completed */
struct whiteheat_status_info {
__u8 port; /* port number (1 to N) */
- __u8 event; /* indicates what the current event is, see WHITEHEAT_EVENT_* above */
- __u8 modem; /* modem signal status (copy of uart's MSR register) */
+ __u8 event; /* indicates what the current event is,
+ see WHITEHEAT_EVENT_* above */
+ __u8 modem; /* modem signal status (copy of uart's
+ MSR register) */
__u8 error; /* line status (copy of uart's LSR register) */
- __u8 flow; /* flow control state, see WHITEHEAT_FLOW_* above */
- __u8 connect; /* 0 means not connected, non-zero means connected */
+ __u8 flow; /* flow control state, see WHITEHEAT_FLOW_*
+ above */
+ __u8 connect; /* 0 means not connected, non-zero means
+ connected */
};
struct whiteheat_event_info {
__u8 port; /* port number (1 to N) */
__u8 event; /* see whiteheat_status_info.event */
- __u8 info; /* see whiteheat_status_info.modem, .error, .flow, .connect */
+ __u8 info; /* see whiteheat_status_info.modem, .error,
+ .flow, .connect */
};
struct whiteheat_test_info {
__u8 port; /* port number (1 to N) */
- __u8 test; /* indicates which test this is a response for, see WHITEHEAT_DO_TEST above */
+ __u8 test; /* indicates which test this is a response for,
+ see WHITEHEAT_DO_TEST above */
__u8 status; /* see WHITEHEAT_TEST_* above */
__u8 results[32]; /* test-dependent results */
};
NEW_AUX_ENT(AT_GID, tsk->gid);
NEW_AUX_ENT(AT_EGID, tsk->egid);
NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
+ NEW_AUX_ENT(AT_EXECFN, bprm->exec);
if (k_platform) {
NEW_AUX_ENT(AT_PLATFORM,
(elf_addr_t)(unsigned long)u_platform);
struct pagemapread pm;
int pagecount;
int ret = -ESRCH;
- struct mm_walk pagemap_walk;
+ struct mm_walk pagemap_walk = {};
unsigned long src;
unsigned long svpfn;
unsigned long start_vaddr;
#define AT_SECURE 23 /* secure mode boolean */
+#define AT_EXECFN 31 /* filename of program */
#ifdef __KERNEL__
-#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */
+#define AT_VECTOR_SIZE_BASE 17 /* NEW_AUX_ENT entries in auxiliary table */
+ /* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */
#endif
#endif /* _LINUX_AUXVEC_H */
--- /dev/null
+#ifndef LINUX_SPI_MAX7301_H
+#define LINUX_SPI_MAX7301_H
+
+struct max7301_platform_data {
+ /* number assigned to the first GPIO */
+ unsigned base;
+};
+
+#endif
#define MGSL_INTERFACE_RTS_EN 0x10
#define MGSL_INTERFACE_LL 0x20
#define MGSL_INTERFACE_RL 0x40
+#define MGSL_INTERFACE_MSB_FIRST 0x80
typedef struct _MGSL_PARAMS
{
extern int tty_check_change(struct tty_struct *tty);
extern void stop_tty(struct tty_struct *tty);
extern void start_tty(struct tty_struct *tty);
-extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
-extern int tty_unregister_ldisc(int disc);
extern int tty_register_driver(struct tty_driver *driver);
extern int tty_unregister_driver(struct tty_driver *driver);
extern struct device *tty_register_device(struct tty_driver *driver,
extern int tty_port_alloc_xmit_buf(struct tty_port *port);
extern void tty_port_free_xmit_buf(struct tty_port *port);
+extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
+extern int tty_unregister_ldisc(int disc);
+extern int tty_set_ldisc(struct tty_struct *tty, int ldisc);
+extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty);
+extern void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty);
+extern void tty_ldisc_init(struct tty_struct *tty);
+extern void tty_ldisc_begin(void);
+/* This last one is just for the tty layer internals and shouldn't be used elsewhere */
+extern void tty_ldisc_enable(struct tty_struct *tty);
/* n_tty.c */
*
* Optional:
*
- * void (*break_ctl)(struct tty_stuct *tty, int state);
+ * int (*break_ctl)(struct tty_stuct *tty, int state);
*
* This optional routine requests the tty driver to turn on or
* off BREAK status on the RS-232 port. If state is -1,
* handle the following ioctls: TCSBRK, TCSBRKP, TIOCSBRK,
* TIOCCBRK.
*
+ * If the driver sets TTY_DRIVER_HARDWARE_BREAK then the interface
+ * will also be called with actual times and the hardware is expected
+ * to do the delay work itself. 0 and -1 are still used for on/off.
+ *
* Optional: Required for TCSBRK/BRKP/etc handling.
*
* void (*wait_until_sent)(struct tty_struct *tty, int timeout);
void (*stop)(struct tty_struct *tty);
void (*start)(struct tty_struct *tty);
void (*hangup)(struct tty_struct *tty);
- void (*break_ctl)(struct tty_struct *tty, int state);
+ int (*break_ctl)(struct tty_struct *tty, int state);
void (*flush_buffer)(struct tty_struct *tty);
void (*set_ldisc)(struct tty_struct *tty);
void (*wait_until_sent)(struct tty_struct *tty, int timeout);
* TTY_DRIVER_DEVPTS_MEM -- don't use the standard arrays, instead
* use dynamic memory keyed through the devpts filesystem. This
* is only applicable to the pty driver.
+ *
+ * TTY_DRIVER_HARDWARE_BREAK -- hardware handles break signals. Pass
+ * the requested timeout to the caller instead of using a simple
+ * on/off interface.
+ *
*/
#define TTY_DRIVER_INSTALLED 0x0001
#define TTY_DRIVER_RESET_TERMIOS 0x0002
#define TTY_DRIVER_REAL_RAW 0x0004
#define TTY_DRIVER_DYNAMIC_DEV 0x0008
#define TTY_DRIVER_DEVPTS_MEM 0x0010
+#define TTY_DRIVER_HARDWARE_BREAK 0x0020
/* tty driver types */
#define TTY_DRIVER_TYPE_SYSTEM 0x0001
*/
struct usb_serial_port {
struct usb_serial *serial;
- struct tty_struct *tty;
+ struct tty_port port;
spinlock_t lock;
struct mutex mutex;
unsigned char number;
wait_queue_head_t write_wait;
struct work_struct work;
- int open_count;
char throttled;
char throttle_req;
char console;
int (*resume)(struct usb_serial *serial);
/* serial function calls */
- int (*open)(struct usb_serial_port *port, struct file *filp);
- void (*close)(struct usb_serial_port *port, struct file *filp);
- int (*write)(struct usb_serial_port *port, const unsigned char *buf,
- int count);
- int (*write_room)(struct usb_serial_port *port);
- int (*ioctl)(struct usb_serial_port *port, struct file *file,
+ /* Called by console with tty = NULL and by tty */
+ int (*open)(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+ void (*close)(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+ int (*write)(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+ /* Called only by the tty layer */
+ int (*write_room)(struct tty_struct *tty);
+ int (*ioctl)(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg);
- void (*set_termios)(struct usb_serial_port *port, struct ktermios *old);
- void (*break_ctl)(struct usb_serial_port *port, int break_state);
- int (*chars_in_buffer)(struct usb_serial_port *port);
- void (*throttle)(struct usb_serial_port *port);
- void (*unthrottle)(struct usb_serial_port *port);
- int (*tiocmget)(struct usb_serial_port *port, struct file *file);
- int (*tiocmset)(struct usb_serial_port *port, struct file *file,
+ void (*set_termios)(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
+ void (*break_ctl)(struct tty_struct *tty, int break_state);
+ int (*chars_in_buffer)(struct tty_struct *tty);
+ void (*throttle)(struct tty_struct *tty);
+ void (*unthrottle)(struct tty_struct *tty);
+ int (*tiocmget)(struct tty_struct *tty, struct file *file);
+ int (*tiocmset)(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
-
+ /* USB events */
void (*read_int_callback)(struct urb *urb);
void (*write_int_callback)(struct urb *urb);
void (*read_bulk_callback)(struct urb *urb);
/* Functions needed by other parts of the usbserial core */
extern struct usb_serial *usb_serial_get_by_index(unsigned int minor);
extern void usb_serial_put(struct usb_serial *serial);
-extern int usb_serial_generic_open(struct usb_serial_port *port,
- struct file *filp);
-extern int usb_serial_generic_write(struct usb_serial_port *port,
- const unsigned char *buf, int count);
-extern void usb_serial_generic_close(struct usb_serial_port *port,
- struct file *filp);
+extern int usb_serial_generic_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
+extern int usb_serial_generic_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count);
+extern void usb_serial_generic_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp);
extern int usb_serial_generic_resume(struct usb_serial *serial);
-extern int usb_serial_generic_write_room(struct usb_serial_port *port);
-extern int usb_serial_generic_chars_in_buffer(struct usb_serial_port *port);
+extern int usb_serial_generic_write_room(struct tty_struct *tty);
+extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);
extern void usb_serial_generic_read_bulk_callback(struct urb *urb);
extern void usb_serial_generic_write_bulk_callback(struct urb *urb);
-extern void usb_serial_generic_throttle(struct usb_serial_port *port);
-extern void usb_serial_generic_unthrottle(struct usb_serial_port *port);
+extern void usb_serial_generic_throttle(struct tty_struct *tty);
+extern void usb_serial_generic_unthrottle(struct tty_struct *tty);
extern void usb_serial_generic_shutdown(struct usb_serial *serial);
extern int usb_serial_generic_register(int debug);
extern void usb_serial_generic_deregister(void);
if (apn == b->pn) {
cpus_or(*dp, *dp, b->cpus_allowed);
b->pn = -1;
- update_domain_attr(dattr, b);
+ if (dattr)
+ update_domain_attr(dattr
+ + nslot, b);
}
}
nslot++;
cond_syscall(sys_epoll_ctl);
cond_syscall(sys_epoll_wait);
cond_syscall(sys_epoll_pwait);
+cond_syscall(compat_sys_epoll_pwait);
cond_syscall(sys_semget);
cond_syscall(sys_semop);
cond_syscall(sys_semtimedop);
cmd_kernel-mod = $(modpost) $@
vmlinux.o: FORCE
+ @rm -fr $(kernelmarkersfile)
$(call cmd,kernel-mod)
# Declare generated files as targets for modpost
mod->skip = 1;
}
- add_marker(mod, marker, fmt);
+ if (!mod->skip)
+ add_marker(mod, marker, fmt);
}
return;
fail: