summaryrefslogtreecommitdiff
path: root/drivers/usb/serial/ti_usb_3410_5052.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/ti_usb_3410_5052.c')
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c205
1 files changed, 36 insertions, 169 deletions
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 0afe5c71c17e..90979a1f5311 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -30,7 +30,7 @@
#include <linux/spinlock.h>
#include <linux/ioctl.h>
#include <linux/serial.h>
-#include <linux/circ_buf.h>
+#include <linux/kfifo.h>
#include <linux/mutex.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
@@ -40,7 +40,7 @@
/* Defines */
-#define TI_DRIVER_VERSION "v0.9"
+#define TI_DRIVER_VERSION "v0.10"
#define TI_DRIVER_AUTHOR "Al Borchers <alborchers@steinerpoint.com>"
#define TI_DRIVER_DESC "TI USB 3410/5052 Serial Driver"
@@ -82,7 +82,7 @@ struct ti_port {
spinlock_t tp_lock;
int tp_read_urb_state;
int tp_write_urb_in_use;
- struct circ_buf *tp_write_buf;
+ struct kfifo write_fifo;
};
struct ti_device {
@@ -144,15 +144,6 @@ static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
static int ti_download_firmware(struct ti_device *tdev);
-/* circular buffer */
-static struct circ_buf *ti_buf_alloc(void);
-static void ti_buf_free(struct circ_buf *cb);
-static void ti_buf_clear(struct circ_buf *cb);
-static int ti_buf_data_avail(struct circ_buf *cb);
-static int ti_buf_space_avail(struct circ_buf *cb);
-static int ti_buf_put(struct circ_buf *cb, const char *buf, int count);
-static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
-
/* Data */
@@ -172,7 +163,7 @@ static unsigned int product_5052_count;
/* the array dimension is the number of default entries plus */
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
/* null entry */
-static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -180,6 +171,9 @@ static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
@@ -192,7 +186,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -200,6 +194,9 @@ static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1]
{ USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
@@ -287,6 +284,8 @@ MODULE_FIRMWARE("ti_5052.fw");
MODULE_FIRMWARE("mts_cdma.fw");
MODULE_FIRMWARE("mts_gsm.fw");
MODULE_FIRMWARE("mts_edge.fw");
+MODULE_FIRMWARE("mts_mt9234mu.fw");
+MODULE_FIRMWARE("mts_mt9234zba.fw");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
@@ -442,8 +441,8 @@ static int ti_startup(struct usb_serial *serial)
tport->tp_closing_wait = closing_wait;
init_waitqueue_head(&tport->tp_msr_wait);
init_waitqueue_head(&tport->tp_write_wait);
- tport->tp_write_buf = ti_buf_alloc();
- if (tport->tp_write_buf == NULL) {
+ if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE,
+ GFP_KERNEL)) {
dev_err(&dev->dev, "%s - out of memory\n", __func__);
kfree(tport);
status = -ENOMEM;
@@ -460,7 +459,7 @@ static int ti_startup(struct usb_serial *serial)
free_tports:
for (--i; i >= 0; --i) {
tport = usb_get_serial_port_data(serial->port[i]);
- ti_buf_free(tport->tp_write_buf);
+ kfifo_free(&tport->write_fifo);
kfree(tport);
usb_set_serial_port_data(serial->port[i], NULL);
}
@@ -482,7 +481,7 @@ static void ti_release(struct usb_serial *serial)
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);
+ kfifo_free(&tport->write_fifo);
kfree(tport);
}
}
@@ -693,7 +692,6 @@ 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;
dbg("%s - port %d", __func__, port->number);
@@ -705,10 +703,8 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
if (tport == NULL || !tport->tp_is_open)
return -ENODEV;
- spin_lock_irqsave(&tport->tp_lock, flags);
- count = ti_buf_put(tport->tp_write_buf, data, count);
- spin_unlock_irqrestore(&tport->tp_lock, flags);
-
+ count = kfifo_in_locked(&tport->write_fifo, data, count,
+ &tport->tp_lock);
ti_send(tport);
return count;
@@ -728,7 +724,7 @@ static int ti_write_room(struct tty_struct *tty)
return 0;
spin_lock_irqsave(&tport->tp_lock, flags);
- room = ti_buf_space_avail(tport->tp_write_buf);
+ room = kfifo_avail(&tport->write_fifo);
spin_unlock_irqrestore(&tport->tp_lock, flags);
dbg("%s - returns %d", __func__, room);
@@ -749,7 +745,7 @@ static int ti_chars_in_buffer(struct tty_struct *tty)
return 0;
spin_lock_irqsave(&tport->tp_lock, flags);
- chars = ti_buf_data_avail(tport->tp_write_buf);
+ chars = kfifo_len(&tport->write_fifo);
spin_unlock_irqrestore(&tport->tp_lock, flags);
dbg("%s - returns %d", __func__, chars);
@@ -1301,7 +1297,7 @@ static void ti_send(struct ti_port *tport)
if (tport->tp_write_urb_in_use)
goto unlock;
- count = ti_buf_get(tport->tp_write_buf,
+ count = kfifo_out(&tport->write_fifo,
port->write_urb->transfer_buffer,
port->bulk_out_size);
@@ -1496,7 +1492,7 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush)
add_wait_queue(&tport->tp_write_wait, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
- if (ti_buf_data_avail(tport->tp_write_buf) == 0
+ if (kfifo_len(&tport->write_fifo) == 0
|| timeout == 0 || signal_pending(current)
|| tdev->td_urb_error
|| port->serial->disconnected) /* disconnect */
@@ -1510,7 +1506,7 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush)
/* flush any remaining data in the buffer */
if (flush)
- ti_buf_clear(tport->tp_write_buf);
+ kfifo_reset_out(&tport->write_fifo);
spin_unlock_irq(&tport->tp_lock);
@@ -1687,6 +1683,7 @@ static int ti_download_firmware(struct ti_device *tdev)
const struct firmware *fw_p;
char buf[32];
+ dbg("%s\n", __func__);
/* try ID specific firmware first, then try generic firmware */
sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
dev->descriptor.idProduct);
@@ -1703,7 +1700,15 @@ static int ti_download_firmware(struct ti_device *tdev)
case MTS_EDGE_PRODUCT_ID:
strcpy(buf, "mts_edge.fw");
break;
- }
+ case MTS_MT9234MU_PRODUCT_ID:
+ strcpy(buf, "mts_mt9234mu.fw");
+ break;
+ case MTS_MT9234ZBA_PRODUCT_ID:
+ strcpy(buf, "mts_mt9234zba.fw");
+ break;
+ case MTS_MT9234ZBAOLD_PRODUCT_ID:
+ strcpy(buf, "mts_mt9234zba.fw");
+ break; }
}
if (buf[0] == '\0') {
if (tdev->td_is_3410)
@@ -1718,7 +1723,7 @@ static int ti_download_firmware(struct ti_device *tdev)
return -ENOENT;
}
if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
- dev_err(&dev->dev, "%s - firmware too large\n", __func__);
+ dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
return -ENOENT;
}
@@ -1730,6 +1735,7 @@ static int ti_download_firmware(struct ti_device *tdev)
status = ti_do_download(dev, pipe, buffer, fw_p->size);
kfree(buffer);
} else {
+ dbg("%s ENOMEM\n", __func__);
status = -ENOMEM;
}
release_firmware(fw_p);
@@ -1743,142 +1749,3 @@ static int ti_download_firmware(struct ti_device *tdev)
return 0;
}
-
-
-/* Circular Buffer Functions */
-
-/*
- * ti_buf_alloc
- *
- * Allocate a circular buffer and all associated memory.
- */
-
-static struct circ_buf *ti_buf_alloc(void)
-{
- struct circ_buf *cb;
-
- cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
- if (cb == NULL)
- return NULL;
-
- cb->buf = kmalloc(TI_WRITE_BUF_SIZE, GFP_KERNEL);
- if (cb->buf == NULL) {
- kfree(cb);
- return NULL;
- }
-
- ti_buf_clear(cb);
-
- return cb;
-}
-
-
-/*
- * ti_buf_free
- *
- * Free the buffer and all associated memory.
- */
-
-static void ti_buf_free(struct circ_buf *cb)
-{
- kfree(cb->buf);
- kfree(cb);
-}
-
-
-/*
- * ti_buf_clear
- *
- * Clear out all data in the circular buffer.
- */
-
-static void ti_buf_clear(struct circ_buf *cb)
-{
- cb->head = cb->tail = 0;
-}
-
-
-/*
- * ti_buf_data_avail
- *
- * Return the number of bytes of data available in the circular
- * buffer.
- */
-
-static int ti_buf_data_avail(struct circ_buf *cb)
-{
- return CIRC_CNT(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
-}
-
-
-/*
- * ti_buf_space_avail
- *
- * Return the number of bytes of space available in the circular
- * buffer.
- */
-
-static int ti_buf_space_avail(struct circ_buf *cb)
-{
- return CIRC_SPACE(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
-}
-
-
-/*
- * ti_buf_put
- *
- * Copy data data from a user buffer and put it into the circular buffer.
- * Restrict to the amount of space available.
- *
- * Return the number of bytes copied.
- */
-
-static int ti_buf_put(struct circ_buf *cb, const char *buf, int count)
-{
- int c, ret = 0;
-
- while (1) {
- c = CIRC_SPACE_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
- if (count < c)
- c = count;
- if (c <= 0)
- break;
- memcpy(cb->buf + cb->head, buf, c);
- cb->head = (cb->head + c) & (TI_WRITE_BUF_SIZE-1);
- buf += c;
- count -= c;
- ret += c;
- }
-
- return ret;
-}
-
-
-/*
- * ti_buf_get
- *
- * Get data from the circular buffer and copy to the given buffer.
- * Restrict to the amount of data available.
- *
- * Return the number of bytes copied.
- */
-
-static int ti_buf_get(struct circ_buf *cb, char *buf, int count)
-{
- int c, ret = 0;
-
- while (1) {
- c = CIRC_CNT_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
- if (count < c)
- c = count;
- if (c <= 0)
- break;
- memcpy(buf, cb->buf + cb->tail, c);
- cb->tail = (cb->tail + c) & (TI_WRITE_BUF_SIZE-1);
- buf += c;
- count -= c;
- ret += c;
- }
-
- return ret;
-}