123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * USB Keyspan PDA / Xircom / Entrega Converter driver
- *
- * Copyright (C) 1999 - 2001 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 1999, 2000 Brian Warner <warner@lothar.com>
- * Copyright (C) 2000 Al Borchers <borchers@steinerpoint.com>
- *
- * See Documentation/usb/usb-serial.rst for more information on using this
- * driver
- */
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
- #include <linux/tty.h>
- #include <linux/tty_driver.h>
- #include <linux/tty_flip.h>
- #include <linux/module.h>
- #include <linux/spinlock.h>
- #include <linux/workqueue.h>
- #include <linux/uaccess.h>
- #include <linux/usb.h>
- #include <linux/usb/serial.h>
- #include <linux/usb/ezusb.h>
- /* make a simple define to handle if we are compiling keyspan_pda or xircom support */
- #if IS_ENABLED(CONFIG_USB_SERIAL_KEYSPAN_PDA)
- #define KEYSPAN
- #else
- #undef KEYSPAN
- #endif
- #if IS_ENABLED(CONFIG_USB_SERIAL_XIRCOM)
- #define XIRCOM
- #else
- #undef XIRCOM
- #endif
- #define DRIVER_AUTHOR "Brian Warner <warner@lothar.com>"
- #define DRIVER_DESC "USB Keyspan PDA Converter driver"
- #define KEYSPAN_TX_THRESHOLD 16
- struct keyspan_pda_private {
- int tx_room;
- int tx_throttled;
- struct work_struct unthrottle_work;
- struct usb_serial *serial;
- struct usb_serial_port *port;
- };
- #define KEYSPAN_VENDOR_ID 0x06cd
- #define KEYSPAN_PDA_FAKE_ID 0x0103
- #define KEYSPAN_PDA_ID 0x0104 /* no clue */
- /* For Xircom PGSDB9 and older Entrega version of the same device */
- #define XIRCOM_VENDOR_ID 0x085a
- #define XIRCOM_FAKE_ID 0x8027
- #define XIRCOM_FAKE_ID_2 0x8025 /* "PGMFHUB" serial */
- #define ENTREGA_VENDOR_ID 0x1645
- #define ENTREGA_FAKE_ID 0x8093
- static const struct usb_device_id id_table_combined[] = {
- #ifdef KEYSPAN
- { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
- #endif
- #ifdef XIRCOM
- { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
- { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID_2) },
- { USB_DEVICE(ENTREGA_VENDOR_ID, ENTREGA_FAKE_ID) },
- #endif
- { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
- { } /* Terminating entry */
- };
- MODULE_DEVICE_TABLE(usb, id_table_combined);
- static const struct usb_device_id id_table_std[] = {
- { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
- { } /* Terminating entry */
- };
- #ifdef KEYSPAN
- static const struct usb_device_id id_table_fake[] = {
- { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
- { } /* Terminating entry */
- };
- #endif
- #ifdef XIRCOM
- static const struct usb_device_id id_table_fake_xircom[] = {
- { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
- { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID_2) },
- { USB_DEVICE(ENTREGA_VENDOR_ID, ENTREGA_FAKE_ID) },
- { }
- };
- #endif
- static void keyspan_pda_request_unthrottle(struct work_struct *work)
- {
- struct keyspan_pda_private *priv =
- container_of(work, struct keyspan_pda_private, unthrottle_work);
- struct usb_serial *serial = priv->serial;
- int result;
- /* ask the device to tell us when the tx buffer becomes
- sufficiently empty */
- result = usb_control_msg(serial->dev,
- usb_sndctrlpipe(serial->dev, 0),
- 7, /* request_unthrottle */
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE
- | USB_DIR_OUT,
- KEYSPAN_TX_THRESHOLD,
- 0, /* index */
- NULL,
- 0,
- 2000);
- if (result < 0)
- dev_dbg(&serial->dev->dev, "%s - error %d from usb_control_msg\n",
- __func__, result);
- }
- static void keyspan_pda_rx_interrupt(struct urb *urb)
- {
- struct usb_serial_port *port = urb->context;
- unsigned char *data = urb->transfer_buffer;
- unsigned int len = urb->actual_length;
- int retval;
- int status = urb->status;
- struct keyspan_pda_private *priv;
- unsigned long flags;
- priv = usb_get_serial_port_data(port);
- switch (status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dev_dbg(&urb->dev->dev, "%s - urb shutting down with status: %d\n", __func__, status);
- return;
- default:
- dev_dbg(&urb->dev->dev, "%s - nonzero urb status received: %d\n", __func__, status);
- goto exit;
- }
- if (len < 1) {
- dev_warn(&port->dev, "short message received\n");
- goto exit;
- }
- /* see if the message is data or a status interrupt */
- switch (data[0]) {
- case 0:
- /* rest of message is rx data */
- if (len < 2)
- break;
- tty_insert_flip_string(&port->port, data + 1, len - 1);
- tty_flip_buffer_push(&port->port);
- break;
- case 1:
- /* status interrupt */
- if (len < 2) {
- dev_warn(&port->dev, "short interrupt message received\n");
- break;
- }
- dev_dbg(&port->dev, "rx int, d1=%d\n", data[1]);
- switch (data[1]) {
- case 1: /* modemline change */
- break;
- case 2: /* tx unthrottle interrupt */
- spin_lock_irqsave(&port->lock, flags);
- priv->tx_throttled = 0;
- priv->tx_room = max(priv->tx_room, KEYSPAN_TX_THRESHOLD);
- spin_unlock_irqrestore(&port->lock, flags);
- /* queue up a wakeup at scheduler time */
- usb_serial_port_softint(port);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- exit:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
- dev_err(&port->dev,
- "%s - usb_submit_urb failed with result %d\n",
- __func__, retval);
- }
- 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
- flowcontrol, the device will signal the other end when its buffer
- fills up. If we're doing XON/XOFF, this would be a good time to
- send an XOFF, although it might make sense to foist that off
- upon the device too. */
- struct usb_serial_port *port = tty->driver_data;
- usb_kill_urb(port->interrupt_in_urb);
- }
- static void keyspan_pda_rx_unthrottle(struct tty_struct *tty)
- {
- struct usb_serial_port *port = tty->driver_data;
- /* just restart the receive interrupt URB */
- if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL))
- dev_dbg(&port->dev, "usb_submit_urb(read urb) failed\n");
- }
- 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;
- }
- /* 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_RECIP_INTERFACE
- | USB_DIR_OUT, /* type */
- bindex, /* value */
- 0, /* index */
- NULL, /* &data */
- 0, /* size */
- 2000); /* timeout */
- if (rc < 0)
- return 0;
- return baud;
- }
- 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;
- if (break_state == -1)
- value = 1; /* start break */
- 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);
- if (result < 0)
- dev_dbg(&port->dev, "%s - error %d from usb_control_msg\n",
- __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
- seconds apart, but it feels like the break sent isn't as long as it
- is on /dev/ttyS0 */
- }
- 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;
- /* cflag specifies lots of stuff: number of stop bits, parity, number
- of data bits, baud. What can the device actually handle?:
- CSTOPB (1 stop bit or 2)
- PARENB (parity)
- CSIZE (5bit .. 8bit)
- There is minimal hw support for parity (a PSW bit seems to hold the
- parity of whatever is in the accumulator). The UART either deals
- with 10 bits (start, 8 data, stop) or 11 bits (start, 8 data,
- 1 special, stop). So, with firmware changes, we could do:
- 8N1: 10 bit
- 8N2: 11 bit, extra bit always (mark?)
- 8[EOMS]1: 11 bit, extra bit is parity
- 7[EOMS]1: 10 bit, b0/b7 is parity
- 7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?)
- HW flow control is dictated by the tty->termios.c_cflags & CRTSCTS
- bit.
- For now, just do baud. */
- speed = tty_get_baud_rate(tty);
- speed = keyspan_pda_setbaud(serial, speed);
- if (speed == 0) {
- dev_dbg(&port->dev, "can't handle requested baud rate\n");
- /* It hasn't changed so.. */
- speed = tty_termios_baud_rate(old_termios);
- }
- /* Only speed can change so copy the old h/w parameters
- then encode the new speed */
- tty_termios_copy_hw(&tty->termios, old_termios);
- tty_encode_baud_rate(tty, speed, speed);
- }
- /* modem control pins: DTR and RTS are outputs and can be controlled.
- DCD, RI, DSR, CTS are inputs and can be read. All outputs can also be
- read. The byte passed is: DTR(b7) DCD RI DSR CTS RTS(b2) unused unused */
- static int keyspan_pda_get_modem_info(struct usb_serial *serial,
- unsigned char *value)
- {
- int rc;
- u8 *data;
- data = kmalloc(1, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
- rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- 3, /* get pins */
- USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
- 0, 0, data, 1, 2000);
- if (rc == 1)
- *value = *data;
- else if (rc >= 0)
- rc = -EIO;
- kfree(data);
- return rc;
- }
- static int keyspan_pda_set_modem_info(struct usb_serial *serial,
- unsigned char value)
- {
- int rc;
- rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- 3, /* set pins */
- USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_OUT,
- value, 0, NULL, 0, 2000);
- return rc;
- }
- static int keyspan_pda_tiocmget(struct tty_struct *tty)
- {
- struct usb_serial_port *port = tty->driver_data;
- struct usb_serial *serial = port->serial;
- int rc;
- unsigned char status;
- int value;
- rc = keyspan_pda_get_modem_info(serial, &status);
- if (rc < 0)
- return rc;
- value =
- ((status & (1<<7)) ? TIOCM_DTR : 0) |
- ((status & (1<<6)) ? TIOCM_CAR : 0) |
- ((status & (1<<5)) ? TIOCM_RNG : 0) |
- ((status & (1<<4)) ? TIOCM_DSR : 0) |
- ((status & (1<<3)) ? TIOCM_CTS : 0) |
- ((status & (1<<2)) ? TIOCM_RTS : 0);
- return value;
- }
- static int keyspan_pda_tiocmset(struct tty_struct *tty,
- 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;
- rc = keyspan_pda_get_modem_info(serial, &status);
- if (rc < 0)
- return rc;
- if (set & TIOCM_RTS)
- status |= (1<<2);
- if (set & TIOCM_DTR)
- status |= (1<<7);
- if (clear & TIOCM_RTS)
- status &= ~(1<<2);
- if (clear & TIOCM_DTR)
- status &= ~(1<<7);
- rc = keyspan_pda_set_modem_info(serial, status);
- return rc;
- }
- 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;
- int rc = 0;
- struct keyspan_pda_private *priv;
- unsigned long flags;
- priv = usb_get_serial_port_data(port);
- /* guess how much room is left in the device's ring buffer, and if we
- want to send more than that, check first, updating our notion of
- what is left. If our write will result in no room left, ask the
- device to give us an interrupt when the room available rises above
- a threshold, and hold off all writers (eventually, those using
- select() or poll() too) until we receive that unthrottle interrupt.
- Block if we can't write anything at all, otherwise write as much as
- we can. */
- if (count == 0) {
- dev_dbg(&port->dev, "write request of 0 bytes\n");
- return 0;
- }
- /* we might block because of:
- the TX urb is in-flight (wait until it completes)
- the device is full (wait until it says there is room)
- */
- spin_lock_irqsave(&port->lock, flags);
- if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled) {
- spin_unlock_irqrestore(&port->lock, flags);
- return 0;
- }
- clear_bit(0, &port->write_urbs_free);
- spin_unlock_irqrestore(&port->lock, flags);
- /* At this point the URB is in our control, nobody else can submit it
- again (the only sudden transition was the one from EINPROGRESS to
- finished). Also, the tx process is not throttled. So we are
- ready to write. */
- count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
- /* Check if we might overrun the Tx buffer. If so, ask the
- device how much room it really has. This is done only on
- scheduler time, since usb_control_msg() sleeps. */
- if (count > priv->tx_room && !in_interrupt()) {
- u8 *room;
- room = kmalloc(1, GFP_KERNEL);
- if (!room) {
- rc = -ENOMEM;
- goto exit;
- }
- rc = usb_control_msg(serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
- 6, /* write_room */
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE
- | USB_DIR_IN,
- 0, /* value: 0 means "remaining room" */
- 0, /* index */
- room,
- 1,
- 2000);
- if (rc > 0) {
- dev_dbg(&port->dev, "roomquery says %d\n", *room);
- priv->tx_room = *room;
- }
- kfree(room);
- if (rc < 0) {
- dev_dbg(&port->dev, "roomquery failed\n");
- goto exit;
- }
- if (rc == 0) {
- dev_dbg(&port->dev, "roomquery returned 0 bytes\n");
- rc = -EIO; /* device didn't return any data */
- goto exit;
- }
- }
- if (count >= priv->tx_room) {
- /* we're about to completely fill the Tx buffer, so
- we'll be throttled afterwards. */
- count = priv->tx_room;
- request_unthrottle = 1;
- }
- if (count) {
- /* now transfer data */
- memcpy(port->write_urb->transfer_buffer, buf, count);
- /* send the data out the bulk port */
- port->write_urb->transfer_buffer_length = count;
- priv->tx_room -= count;
- rc = usb_submit_urb(port->write_urb, GFP_ATOMIC);
- if (rc) {
- dev_dbg(&port->dev, "usb_submit_urb(write bulk) failed\n");
- goto exit;
- }
- } else {
- /* There wasn't any room left, so we are throttled until
- the buffer empties a bit */
- request_unthrottle = 1;
- }
- if (request_unthrottle) {
- priv->tx_throttled = 1; /* block writers */
- schedule_work(&priv->unthrottle_work);
- }
- rc = count;
- exit:
- if (rc <= 0)
- set_bit(0, &port->write_urbs_free);
- return rc;
- }
- static void keyspan_pda_write_bulk_callback(struct urb *urb)
- {
- struct usb_serial_port *port = urb->context;
- set_bit(0, &port->write_urbs_free);
- /* queue up a wakeup at scheduler time */
- usb_serial_port_softint(port);
- }
- static int keyspan_pda_write_room(struct tty_struct *tty)
- {
- struct usb_serial_port *port = tty->driver_data;
- struct keyspan_pda_private *priv = usb_get_serial_port_data(port);
- unsigned long flags;
- int room = 0;
- spin_lock_irqsave(&port->lock, flags);
- if (test_bit(0, &port->write_urbs_free) && !priv->tx_throttled)
- room = priv->tx_room;
- spin_unlock_irqrestore(&port->lock, flags);
- return room;
- }
- 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;
- priv = usb_get_serial_port_data(port);
- /* when throttled, return at least WAKEUP_CHARS to tell select() (via
- n_tty.c:normal_poll() ) that we're not writeable. */
- spin_lock_irqsave(&port->lock, flags);
- if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled)
- ret = 256;
- spin_unlock_irqrestore(&port->lock, flags);
- return ret;
- }
- static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on)
- {
- struct usb_serial *serial = port->serial;
- if (on)
- keyspan_pda_set_modem_info(serial, (1 << 7) | (1 << 2));
- else
- keyspan_pda_set_modem_info(serial, 0);
- }
- static int keyspan_pda_open(struct tty_struct *tty,
- struct usb_serial_port *port)
- {
- struct usb_serial *serial = port->serial;
- u8 *room;
- int rc = 0;
- struct keyspan_pda_private *priv;
- /* find out how much room is in the Tx ring */
- room = kmalloc(1, GFP_KERNEL);
- if (!room)
- return -ENOMEM;
- rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- 6, /* write_room */
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE
- | USB_DIR_IN,
- 0, /* value */
- 0, /* index */
- room,
- 1,
- 2000);
- if (rc < 0) {
- dev_dbg(&port->dev, "%s - roomquery failed\n", __func__);
- goto error;
- }
- if (rc == 0) {
- dev_dbg(&port->dev, "%s - roomquery returned 0 bytes\n", __func__);
- rc = -EIO;
- goto error;
- }
- priv = usb_get_serial_port_data(port);
- priv->tx_room = *room;
- priv->tx_throttled = *room ? 0 : 1;
- /*Start reading from the device*/
- rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
- if (rc) {
- dev_dbg(&port->dev, "%s - usb_submit_urb(read int) failed\n", __func__);
- goto error;
- }
- error:
- kfree(room);
- return rc;
- }
- static void keyspan_pda_close(struct usb_serial_port *port)
- {
- struct keyspan_pda_private *priv = usb_get_serial_port_data(port);
- usb_kill_urb(port->write_urb);
- usb_kill_urb(port->interrupt_in_urb);
- cancel_work_sync(&priv->unthrottle_work);
- }
- /* download the firmware to a "fake" device (pre-renumeration) */
- static int keyspan_pda_fake_startup(struct usb_serial *serial)
- {
- int response;
- const char *fw_name;
- /* download the firmware here ... */
- response = ezusb_fx1_set_reset(serial->dev, 1);
- if (0) { ; }
- #ifdef KEYSPAN
- else if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID)
- fw_name = "keyspan_pda/keyspan_pda.fw";
- #endif
- #ifdef XIRCOM
- else if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) ||
- (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGA_VENDOR_ID))
- fw_name = "keyspan_pda/xircom_pgs.fw";
- #endif
- else {
- dev_err(&serial->dev->dev, "%s: unknown vendor, aborting.\n",
- __func__);
- return -ENODEV;
- }
- if (ezusb_fx1_ihex_firmware_download(serial->dev, fw_name) < 0) {
- dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n",
- fw_name);
- return -ENOENT;
- }
- /* after downloading firmware Renumeration will occur in a
- moment and the new device will bind to the real driver */
- /* we want this device to fail to have a driver assigned to it. */
- return 1;
- }
- #ifdef KEYSPAN
- MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
- #endif
- #ifdef XIRCOM
- MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
- #endif
- static int keyspan_pda_port_probe(struct usb_serial_port *port)
- {
- struct keyspan_pda_private *priv;
- priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
- priv->serial = port->serial;
- priv->port = port;
- usb_set_serial_port_data(port, priv);
- return 0;
- }
- static int keyspan_pda_port_remove(struct usb_serial_port *port)
- {
- struct keyspan_pda_private *priv;
- priv = usb_get_serial_port_data(port);
- kfree(priv);
- return 0;
- }
- #ifdef KEYSPAN
- static struct usb_serial_driver keyspan_pda_fake_device = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "keyspan_pda_pre",
- },
- .description = "Keyspan PDA - (prerenumeration)",
- .id_table = id_table_fake,
- .num_ports = 1,
- .attach = keyspan_pda_fake_startup,
- };
- #endif
- #ifdef XIRCOM
- static struct usb_serial_driver xircom_pgs_fake_device = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "xircom_no_firm",
- },
- .description = "Xircom / Entrega PGS - (prerenumeration)",
- .id_table = id_table_fake_xircom,
- .num_ports = 1,
- .attach = keyspan_pda_fake_startup,
- };
- #endif
- static struct usb_serial_driver keyspan_pda_device = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "keyspan_pda",
- },
- .description = "Keyspan PDA",
- .id_table = id_table_std,
- .num_ports = 1,
- .num_bulk_out = 1,
- .num_interrupt_in = 1,
- .dtr_rts = keyspan_pda_dtr_rts,
- .open = keyspan_pda_open,
- .close = keyspan_pda_close,
- .write = keyspan_pda_write,
- .write_room = keyspan_pda_write_room,
- .write_bulk_callback = keyspan_pda_write_bulk_callback,
- .read_int_callback = keyspan_pda_rx_interrupt,
- .chars_in_buffer = keyspan_pda_chars_in_buffer,
- .throttle = keyspan_pda_rx_throttle,
- .unthrottle = keyspan_pda_rx_unthrottle,
- .set_termios = keyspan_pda_set_termios,
- .break_ctl = keyspan_pda_break_ctl,
- .tiocmget = keyspan_pda_tiocmget,
- .tiocmset = keyspan_pda_tiocmset,
- .port_probe = keyspan_pda_port_probe,
- .port_remove = keyspan_pda_port_remove,
- };
- static struct usb_serial_driver * const serial_drivers[] = {
- &keyspan_pda_device,
- #ifdef KEYSPAN
- &keyspan_pda_fake_device,
- #endif
- #ifdef XIRCOM
- &xircom_pgs_fake_device,
- #endif
- NULL
- };
- module_usb_serial_driver(serial_drivers, id_table_combined);
- MODULE_AUTHOR(DRIVER_AUTHOR);
- MODULE_DESCRIPTION(DRIVER_DESC);
- MODULE_LICENSE("GPL");
|