summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/baseband_usb_chr.c511
1 files changed, 262 insertions, 249 deletions
diff --git a/drivers/usb/serial/baseband_usb_chr.c b/drivers/usb/serial/baseband_usb_chr.c
index c0f45dafd4c8..bb2649dc4c36 100644
--- a/drivers/usb/serial/baseband_usb_chr.c
+++ b/drivers/usb/serial/baseband_usb_chr.c
@@ -34,7 +34,7 @@
#include <linux/usb.h>
#include <linux/workqueue.h>
#include <asm/ioctls.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "baseband_usb_chr.h"
MODULE_LICENSE("GPL");
@@ -52,6 +52,8 @@ MODULE_PARM_DESC(baseband_usb_chr_intf, "baseband (usb chr) - USB interface");
static struct baseband_usb *baseband_usb_chr;
+static atomic_t g_rx_count = ATOMIC_INIT(0);
+
/* baseband ipc functions */
static void baseband_ipc_dump(const char *prefix, unsigned long int offset,
@@ -59,8 +61,7 @@ static void baseband_ipc_dump(const char *prefix, unsigned long int offset,
{
size_t i;
- for (i = 0; i < bufsiz; i += 16)
- {
+ for (i = 0; i < bufsiz; i += 16) {
pr_debug("%s"
"[%lx+%x] %p "
"%02x %02x %02x %02x "
@@ -71,22 +72,38 @@ static void baseband_ipc_dump(const char *prefix, unsigned long int offset,
offset,
i,
((const unsigned char *) buf) + i,
- (i + 0 < bufsiz) ? ((const unsigned char *) buf)[i+0] : 0xff,
- (i + 1 < bufsiz) ? ((const unsigned char *) buf)[i+1] : 0xff,
- (i + 2 < bufsiz) ? ((const unsigned char *) buf)[i+2] : 0xff,
- (i + 3 < bufsiz) ? ((const unsigned char *) buf)[i+3] : 0xff,
- (i + 4 < bufsiz) ? ((const unsigned char *) buf)[i+4] : 0xff,
- (i + 5 < bufsiz) ? ((const unsigned char *) buf)[i+5] : 0xff,
- (i + 6 < bufsiz) ? ((const unsigned char *) buf)[i+6] : 0xff,
- (i + 7 < bufsiz) ? ((const unsigned char *) buf)[i+7] : 0xff,
- (i + 8 < bufsiz) ? ((const unsigned char *) buf)[i+8] : 0xff,
- (i + 9 < bufsiz) ? ((const unsigned char *) buf)[i+9] : 0xff,
- (i + 10 < bufsiz) ? ((const unsigned char *) buf)[i+10] : 0xff,
- (i + 11 < bufsiz) ? ((const unsigned char *) buf)[i+11] : 0xff,
- (i + 12 < bufsiz) ? ((const unsigned char *) buf)[i+12] : 0xff,
- (i + 13 < bufsiz) ? ((const unsigned char *) buf)[i+13] : 0xff,
- (i + 14 < bufsiz) ? ((const unsigned char *) buf)[i+14] : 0xff,
- (i + 15 < bufsiz) ? ((const unsigned char *) buf)[i+15] : 0xff);
+ (i + 0 < bufsiz) ? ((const unsigned char *) buf)[i+0]
+ : 0xff,
+ (i + 1 < bufsiz) ? ((const unsigned char *) buf)[i+1]
+ : 0xff,
+ (i + 2 < bufsiz) ? ((const unsigned char *) buf)[i+2]
+ : 0xff,
+ (i + 3 < bufsiz) ? ((const unsigned char *) buf)[i+3]
+ : 0xff,
+ (i + 4 < bufsiz) ? ((const unsigned char *) buf)[i+4]
+ : 0xff,
+ (i + 5 < bufsiz) ? ((const unsigned char *) buf)[i+5]
+ : 0xff,
+ (i + 6 < bufsiz) ? ((const unsigned char *) buf)[i+6]
+ : 0xff,
+ (i + 7 < bufsiz) ? ((const unsigned char *) buf)[i+7]
+ : 0xff,
+ (i + 8 < bufsiz) ? ((const unsigned char *) buf)[i+8]
+ : 0xff,
+ (i + 9 < bufsiz) ? ((const unsigned char *) buf)[i+9]
+ : 0xff,
+ (i + 10 < bufsiz) ? ((const unsigned char *) buf)[i+10]
+ : 0xff,
+ (i + 11 < bufsiz) ? ((const unsigned char *) buf)[i+11]
+ : 0xff,
+ (i + 12 < bufsiz) ? ((const unsigned char *) buf)[i+12]
+ : 0xff,
+ (i + 13 < bufsiz) ? ((const unsigned char *) buf)[i+13]
+ : 0xff,
+ (i + 14 < bufsiz) ? ((const unsigned char *) buf)[i+14]
+ : 0xff,
+ (i + 15 < bufsiz) ? ((const unsigned char *) buf)[i+15]
+ : 0xff);
}
}
@@ -119,11 +136,10 @@ static size_t peek_ipc_tx_bufsiz(struct baseband_ipc *ipc,
pr_debug("peek_ipc_tx_bufsiz - "
"ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
ipc_buf, ipc_buf->offset, ipc_buf->count);
- if (ipc_buf->count > bufsiz - tx_bufsiz) {
+ if (ipc_buf->count > bufsiz - tx_bufsiz)
break;
- } else {
+ else
tx_bufsiz += ipc_buf->count;
- }
}
/* release tx buffer semaphores */
@@ -145,9 +161,8 @@ static size_t get_ipc_tx_buf(struct baseband_ipc *ipc,
pr_err("!ipc || !buf\n");
return 0;
}
- if (!bufsiz) {
+ if (!bufsiz)
return 0;
- }
/* acquire tx buffer semaphores */
if (down_interruptible(&ipc->buf_sem)) {
@@ -213,9 +228,8 @@ static size_t put_ipc_rx_buf(struct baseband_ipc *ipc,
pr_err("!ipc || !buf\n");
return 0;
}
- if (!bufsiz) {
+ if (!bufsiz)
return 0;
- }
/* acquire rx buffer semaphores */
retry:
@@ -474,14 +488,10 @@ static void baseband_ipc_close(struct baseband_ipc *ipc)
memset(&ipc->rx.wait, 0, sizeof(ipc->rx.wait));
/* destroy data buffers */
- if (ipc->ipc_tx) {
- kfree(ipc->ipc_tx);
- ipc->ipc_tx = (unsigned char *) 0;
- }
- if (ipc->ipc_rx) {
- kfree(ipc->ipc_rx);
- ipc->ipc_rx = (unsigned char *) 0;
- }
+ kfree(ipc->ipc_tx);
+ ipc->ipc_tx = (unsigned char *) 0;
+ kfree(ipc->ipc_rx);
+ ipc->ipc_rx = (unsigned char *) 0;
list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx_free.buf, list)
{
kfree(ipc_buf);
@@ -514,16 +524,14 @@ static struct baseband_ipc *baseband_ipc_open(work_func_t work_func,
{
struct baseband_ipc *ipc;
struct baseband_ipc_buf *ipc_buf;
- int err;
int i;
pr_debug("baseband_ipc_open {\n");
/* allocate baseband ipc structure */
- ipc = (struct baseband_ipc *) kzalloc(sizeof(struct baseband_ipc),
- GFP_KERNEL);
+ ipc = kzalloc(sizeof(struct baseband_ipc), GFP_KERNEL);
if (!ipc)
- return ((struct baseband_ipc *) 0);
+ return (struct baseband_ipc *) 0;
/* create semaphores */
sema_init(&ipc->buf_sem, 1);
@@ -537,7 +545,8 @@ static struct baseband_ipc *baseband_ipc_open(work_func_t work_func,
ipc_buf = (struct baseband_ipc_buf *)
kzalloc(sizeof(struct baseband_ipc_buf), GFP_KERNEL);
if (!ipc_buf) {
- pr_err("cannot allocate baseband ipc rx buffer #%d\n", i);
+ pr_err("cannot allocate baseband ipc rx buffer #%d\n",
+ i);
goto error_exit;
}
pr_debug("baseband_ipc_open - "
@@ -549,7 +558,8 @@ static struct baseband_ipc *baseband_ipc_open(work_func_t work_func,
ipc_buf = (struct baseband_ipc_buf *)
kzalloc(sizeof(struct baseband_ipc_buf), GFP_KERNEL);
if (!ipc_buf) {
- pr_err("cannot allocate baseband ipc tx buffer #%d\n", i);
+ pr_err("cannot allocate baseband ipc tx buffer #%d\n",
+ i);
goto error_exit;
}
pr_debug("baseband_ipc_open - "
@@ -573,77 +583,121 @@ static struct baseband_ipc *baseband_ipc_open(work_func_t work_func,
pr_err("cannot create workqueue\n");
goto error_exit;
}
- if (work_func) {
+ if (work_func)
INIT_WORK(&ipc->work, work_func);
- }
- if (rx_work_func) {
+ if (rx_work_func)
INIT_WORK(&ipc->rx_work, rx_work_func);
- }
- if (tx_work_func) {
+ if (tx_work_func)
INIT_WORK(&ipc->tx_work, tx_work_func);
- }
pr_debug("baseband_ipc_open }\n");
return ipc;
error_exit:
baseband_ipc_close(ipc);
- return ((struct baseband_ipc *) 0);
+ return (struct baseband_ipc *) 0;
}
-/* usb functions */
+/* usb rx */
-static unsigned int g_usb_interface_index;
-static struct usb_interface *g_usb_interface;
+static void baseband_usb_chr_rx_urb_comp(struct urb *urb)
+{
+ struct baseband_usb *usb = (struct baseband_usb *) urb->context;
-static int baseband_usb_driver_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+ pr_debug("baseband_usb_chr_rx_urb_comp { urb %p\n", urb);
+
+ /* queue rx urb completion work */
+ queue_work(usb->ipc->workqueue, &usb->ipc->rx_work);
+
+ pr_debug("baseband_usb_chr_rx_urb_comp }\n");
+}
+
+static int baseband_usb_chr_rx_urb_submit(struct baseband_usb *usb)
{
- pr_debug("%s(%d) { intf %p id %p\n", __func__, __LINE__, intf, id);
+ struct urb *urb;
+ void *buf;
+ int err;
- pr_debug("intf->cur_altsetting->desc.bInterfaceNumber %02x\n",
- intf->cur_altsetting->desc.bInterfaceNumber);
- pr_debug("intf->cur_altsetting->desc.bAlternateSetting %02x\n",
- intf->cur_altsetting->desc.bAlternateSetting);
- pr_debug("intf->cur_altsetting->desc.bNumEndpoints %02x\n",
- intf->cur_altsetting->desc.bNumEndpoints);
- pr_debug("intf->cur_altsetting->desc.bInterfaceClass %02x\n",
- intf->cur_altsetting->desc.bInterfaceClass);
- pr_debug("intf->cur_altsetting->desc.bInterfaceSubClass %02x\n",
- intf->cur_altsetting->desc.bInterfaceSubClass);
- pr_debug("intf->cur_altsetting->desc.bInterfaceProtocol %02x\n",
- intf->cur_altsetting->desc.bInterfaceProtocol);
- pr_debug("intf->cur_altsetting->desc.iInterface %02x\n",
- intf->cur_altsetting->desc.iInterface);
+ pr_debug("baseband_usb_chr_rx_urb_submit { usb %p\n", usb);
- if (g_usb_interface_index !=
- intf->cur_altsetting->desc.bInterfaceNumber) {
- pr_debug("%s(%d) } -ENODEV\n", __func__, __LINE__);
- return -ENODEV;
- } else {
- g_usb_interface = intf;
+ /* check input */
+ if (usb->usb.rx_urb) {
+ pr_err("previous urb still active\n");
+ return -1;
}
- pr_debug("%s(%d) }\n", __func__, __LINE__);
- return 0;
+ /* allocate rx urb */
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ pr_err("usb_alloc_urb() failed\n");
+ return -ENOMEM;
+ }
+ buf = kzalloc(USB_CHR_RX_BUFSIZ, GFP_ATOMIC);
+ if (!buf) {
+ pr_err("usb buffer kzalloc() failed\n");
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+ usb_fill_bulk_urb(urb, usb->usb.device, usb->usb.pipe.bulk.in,
+ buf, USB_CHR_RX_BUFSIZ,
+ baseband_usb_chr_rx_urb_comp,
+ usb);
+ urb->transfer_flags = 0;
+
+ /* submit rx urb */
+ usb->usb.rx_urb = urb;
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+ pr_err("usb_submit_urb() failed - err %d\n", err);
+ usb->usb.rx_urb = (struct urb *) 0;
+ kfree(urb->transfer_buffer);
+ usb_free_urb(urb);
+ return err;
+ }
+
+ pr_debug("baseband_usb_chr_rx_urb_submit }\n");
+ return err;
}
-static void baseband_usb_driver_disconnect(struct usb_interface *intf)
+static void baseband_usb_chr_rx_urb_comp_work(struct work_struct *work)
{
- pr_debug("%s(%d) { intf %p\n", __func__, __LINE__, intf);
- pr_debug("%s(%d) }\n", __func__, __LINE__);
-}
+ struct baseband_usb *usb = baseband_usb_chr;
+ struct urb *urb = usb->usb.rx_urb;
+ size_t len;
-static char baseband_usb_driver_name[32];
+ pr_debug("baseband_usb_chr_rx_urb_comp_work { work %p\n", work);
-static struct usb_device_id baseband_usb_driver_id_table[2];
+ /* put rx urb data in rx buffer */
+ if (urb->actual_length) {
+ pr_debug("baseband_usb_chr_rx_urb_comp_work - "
+ "urb->actual_length %d\n", urb->actual_length);
+ len = put_ipc_rx_buf(usb->ipc,
+ urb->transfer_buffer, urb->actual_length);
+ baseband_ipc_dump("baseband_usb_chr_rx_urb_comp_work"
+ " - rx buf ", 0,
+ urb->transfer_buffer, len > 16 ? 16 : len);
+ if (len != urb->actual_length) {
+ pr_err("baseband_usb_chr_rx_urb_comp_work - "
+ "put_ipx_rx_buf() only put %d/%d bytes\n",
+ len, urb->actual_length);
+ }
+ /* increment count of available rx bytes */
+ atomic_add(len, &g_rx_count);
+ }
-static struct usb_driver baseband_usb_driver = {
- .name = baseband_usb_driver_name,
- .probe = baseband_usb_driver_probe,
- .disconnect = baseband_usb_driver_disconnect,
- .id_table = baseband_usb_driver_id_table,
-};
+ /* free rx urb */
+ kfree(urb->transfer_buffer);
+ urb->transfer_buffer = (void *) 0;
+ usb_free_urb(urb);
+ usb->usb.rx_urb = (struct urb *) 0;
+
+ /* submit next rx urb */
+ baseband_usb_chr_rx_urb_submit(usb);
+
+ pr_debug("baseband_usb_chr_rx_urb_comp_work }\n");
+}
+
+/* usb functions */
static void find_usb_pipe(struct baseband_usb *usb)
{
@@ -684,6 +738,88 @@ static void find_usb_pipe(struct baseband_usb *usb)
}
}
+static int baseband_usb_driver_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int err;
+
+ pr_debug("%s(%d) { intf %p id %p\n", __func__, __LINE__, intf, id);
+
+ pr_debug("intf->cur_altsetting->desc.bInterfaceNumber %02x\n",
+ intf->cur_altsetting->desc.bInterfaceNumber);
+ pr_debug("intf->cur_altsetting->desc.bAlternateSetting %02x\n",
+ intf->cur_altsetting->desc.bAlternateSetting);
+ pr_debug("intf->cur_altsetting->desc.bNumEndpoints %02x\n",
+ intf->cur_altsetting->desc.bNumEndpoints);
+ pr_debug("intf->cur_altsetting->desc.bInterfaceClass %02x\n",
+ intf->cur_altsetting->desc.bInterfaceClass);
+ pr_debug("intf->cur_altsetting->desc.bInterfaceSubClass %02x\n",
+ intf->cur_altsetting->desc.bInterfaceSubClass);
+ pr_debug("intf->cur_altsetting->desc.bInterfaceProtocol %02x\n",
+ intf->cur_altsetting->desc.bInterfaceProtocol);
+ pr_debug("intf->cur_altsetting->desc.iInterface %02x\n",
+ intf->cur_altsetting->desc.iInterface);
+
+ /* usb interface mismatch */
+ if (baseband_usb_chr_intf !=
+ intf->cur_altsetting->desc.bInterfaceNumber) {
+ pr_debug("%s(%d) } -ENODEV\n", __func__, __LINE__);
+ return -ENODEV;
+ }
+
+ /* usb interface match */
+ baseband_usb_chr->usb.device = interface_to_usbdev(intf);
+ baseband_usb_chr->usb.interface = intf;
+ find_usb_pipe(baseband_usb_chr);
+ baseband_usb_chr->usb.rx_urb = (struct urb *) 0;
+ baseband_usb_chr->usb.tx_urb = (struct urb *) 0;
+ pr_debug("baseband_usb_chr->usb.driver->name %s\n",
+ baseband_usb_chr->usb.driver->name);
+ pr_debug("baseband_usb_chr->usb.device %p\n",
+ baseband_usb_chr->usb.device);
+ pr_debug("baseband_usb_chr->usb.interface %p\n",
+ baseband_usb_chr->usb.interface);
+ pr_debug("baseband_usb_chr->usb.pipe.isoch.in %x\n",
+ baseband_usb_chr->usb.pipe.isoch.in);
+ pr_debug("baseband_usb_chr->usb.pipe.isoch.out %x\n",
+ baseband_usb_chr->usb.pipe.isoch.out);
+ pr_debug("baseband_usb_chr->usb.pipe.bulk.in %x\n",
+ baseband_usb_chr->usb.pipe.bulk.in);
+ pr_debug("baseband_usb_chr->usb.pipe.bulk.out %x\n",
+ baseband_usb_chr->usb.pipe.bulk.out);
+ pr_debug("baseband_usb_chr->usb.pipe.interrupt.in %x\n",
+ baseband_usb_chr->usb.pipe.interrupt.in);
+ pr_debug("baseband_usb_chr->usb.pipe.interrupt.out %x\n",
+ baseband_usb_chr->usb.pipe.interrupt.out);
+
+ /* start usb rx */
+ err = baseband_usb_chr_rx_urb_submit(baseband_usb_chr);
+ if (err < 0) {
+ pr_err("submit rx failed - err %d\n", err);
+ return -ENODEV;
+ }
+
+ pr_debug("%s(%d) }\n", __func__, __LINE__);
+ return 0;
+}
+
+static void baseband_usb_driver_disconnect(struct usb_interface *intf)
+{
+ pr_debug("%s(%d) { intf %p\n", __func__, __LINE__, intf);
+ pr_debug("%s(%d) }\n", __func__, __LINE__);
+}
+
+static char baseband_usb_driver_name[32];
+
+static struct usb_device_id baseband_usb_driver_id_table[2];
+
+static struct usb_driver baseband_usb_driver = {
+ .name = baseband_usb_driver_name,
+ .probe = baseband_usb_driver_probe,
+ .disconnect = baseband_usb_driver_disconnect,
+ .id_table = baseband_usb_driver_id_table,
+};
+
static void baseband_usb_chr_work(struct work_struct *work)
{
struct baseband_usb *usb = baseband_usb_chr;
@@ -702,10 +838,17 @@ static void baseband_usb_chr_work(struct work_struct *work)
"usb not open\n");
return;
}
+ if (!usb->usb.device) {
+ pr_err("baseband_usb_chr_work - "
+ "usb device not probed yet\n");
+ mdelay(10);
+ queue_work(usb->ipc->workqueue, &usb->ipc->work);
+ return;
+ }
/* allocate buffers on first transaction (will be freed on close) */
if (!usb->ipc->ipc_rx) {
- usb->ipc->ipc_rx = (unsigned char *) kzalloc(USB_CHR_RX_BUFSIZ, GFP_KERNEL);
+ usb->ipc->ipc_rx = kzalloc(USB_CHR_RX_BUFSIZ, GFP_KERNEL);
if (!usb->ipc->ipc_rx) {
pr_err("baseband_usb_chr_work - "
"cannot allocate usb->ipc->ipc_rx\n");
@@ -713,7 +856,7 @@ static void baseband_usb_chr_work(struct work_struct *work)
}
}
if (!usb->ipc->ipc_tx) {
- usb->ipc->ipc_tx = (unsigned char *) kzalloc(USB_CHR_TX_BUFSIZ, GFP_KERNEL);
+ usb->ipc->ipc_tx = kzalloc(USB_CHR_TX_BUFSIZ, GFP_KERNEL);
if (!usb->ipc->ipc_tx) {
pr_err("baseband_usb_chr_work - "
"cannot allocate usb->ipc->ipc_tx\n");
@@ -724,9 +867,8 @@ static void baseband_usb_chr_work(struct work_struct *work)
/* usb transaction loop */
rx.buf = usb->ipc->ipc_rx;
tx.buf = usb->ipc->ipc_tx;
- while ((tx.bufsiz_byte = peek_ipc_tx_bufsiz(usb->ipc, USB_CHR_TX_BUFSIZ))
- != 0)
- {
+ while ((tx.bufsiz_byte = peek_ipc_tx_bufsiz(usb->ipc,
+ USB_CHR_TX_BUFSIZ)) != 0) {
get_ipc_tx_buf(usb->ipc, tx.buf, tx.bufsiz_byte);
err = usb_bulk_msg(usb->usb.device, usb->usb.pipe.bulk.out,
tx.buf, tx.bufsiz_byte, &ipc_tx_byte, USB_CHR_TIMEOUT);
@@ -736,7 +878,8 @@ static void baseband_usb_chr_work(struct work_struct *work)
continue;
}
if (tx.bufsiz_byte != ipc_tx_byte) {
- pr_err("tx.bufsiz_byte %d != ipc_tx_byte %d\n", tx.bufsiz_byte, ipc_tx_byte);
+ pr_err("tx.bufsiz_byte %d != ipc_tx_byte %d\n",
+ tx.bufsiz_byte, ipc_tx_byte);
continue;
}
}
@@ -746,8 +889,6 @@ static void baseband_usb_chr_work(struct work_struct *work)
/* usb character file operations */
-static atomic_t g_rx_count = ATOMIC_INIT(0);
-
static int baseband_usb_chr_open(struct inode *inode, struct file *file)
{
pr_debug("baseband_usb_chr_open\n");
@@ -760,29 +901,35 @@ static int baseband_usb_chr_release(struct inode *inode, struct file *file)
return 0;
}
-static ssize_t baseband_usb_chr_read(struct file *file, char *buf, size_t count, loff_t *pos)
+static ssize_t baseband_usb_chr_read(struct file *file, char *buf,
+ size_t count, loff_t *pos)
{
ssize_t ret;
pr_debug("baseband_usb_chr_read\n");
- ret = baseband_ipc_file_read(baseband_usb_chr->ipc, file, buf, count, pos);
+ ret = baseband_ipc_file_read(baseband_usb_chr->ipc,
+ file, buf, count, pos);
if (ret > 0) {
/* decrement count of available rx bytes */
int val = atomic_read(&g_rx_count);
- pr_debug("baseband_usb_chr_read - read %d unread %d\n", ret, val - ret);
+ pr_debug("baseband_usb_chr_read - read %d unread %d\n",
+ ret, val - ret);
atomic_sub(ret, &g_rx_count);
}
return ret;
}
-static ssize_t baseband_usb_chr_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+static ssize_t baseband_usb_chr_write(struct file *file, const char *buf,
+ size_t count, loff_t *pos)
{
pr_debug("baseband_usb_chr_write\n");
- return baseband_ipc_file_write(baseband_usb_chr->ipc, file, buf, count, pos);
+ return baseband_ipc_file_write(baseband_usb_chr->ipc,
+ file, buf, count, pos);
}
-static long baseband_usb_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long baseband_usb_chr_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
pr_debug("baseband_usb_chr_ioctl\n");
switch (cmd) {
@@ -807,12 +954,12 @@ static long baseband_usb_chr_ioctl(struct file *file, unsigned int cmd, unsigned
return -ENODEV;
}
-static struct file_operations baseband_usb_chr_fops = {
- open: baseband_usb_chr_open,
- release: baseband_usb_chr_release,
- read: baseband_usb_chr_read,
- write: baseband_usb_chr_write,
- unlocked_ioctl: baseband_usb_chr_ioctl,
+static const struct file_operations baseband_usb_chr_fops = {
+ .open = baseband_usb_chr_open,
+ .release = baseband_usb_chr_release,
+ .read = baseband_usb_chr_read,
+ .write = baseband_usb_chr_write,
+ .unlocked_ioctl = baseband_usb_chr_ioctl,
};
/* usb device driver functions */
@@ -858,10 +1005,10 @@ static struct baseband_usb *baseband_usb_open(unsigned int vid,
pr_debug("baseband_usb_open {\n");
/* allocate baseband usb structure */
- usb = (struct baseband_usb *) kzalloc(sizeof(struct baseband_usb),
- GFP_KERNEL);
+ usb = kzalloc(sizeof(struct baseband_usb), GFP_KERNEL);
if (!usb)
- return ((struct baseband_usb *) 0);
+ return (struct baseband_usb *) 0;
+ baseband_usb_chr = usb;
/* open baseband ipc */
usb->ipc = baseband_ipc_open(work_func,
@@ -876,149 +1023,24 @@ static struct baseband_usb *baseband_usb_open(unsigned int vid,
sprintf(baseband_usb_driver_name,
"baseband_usb_%x_%x_%x",
vid, pid, intf);
- baseband_usb_driver_id_table[0].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+ baseband_usb_driver_id_table[0].match_flags
+ = USB_DEVICE_ID_MATCH_DEVICE;
baseband_usb_driver_id_table[0].idVendor = vid;
baseband_usb_driver_id_table[0].idProduct = pid;
- g_usb_interface_index = intf;
- g_usb_interface = (struct usb_interface *) 0;
+ usb->usb.driver = &baseband_usb_driver;
err = usb_register(&baseband_usb_driver);
if (err < 0) {
pr_err("cannot open usb driver - err %d\n", err);
goto error_exit;
}
- usb->usb.driver = &baseband_usb_driver;
- if (!g_usb_interface) {
- pr_err("cannot open usb driver - !g_usb_interface\n");
- goto error_exit;
- }
- usb->usb.device = interface_to_usbdev(g_usb_interface);
- usb->usb.interface = g_usb_interface;
- find_usb_pipe(usb);
- usb->usb.rx_urb = (struct urb *) 0;
- usb->usb.tx_urb = (struct urb *) 0;
- g_usb_interface_index = ~0U;
- g_usb_interface = (struct usb_interface *) 0;
- pr_debug("usb->usb.driver->name %s\n", usb->usb.driver->name);
- pr_debug("usb->usb.device %p\n", usb->usb.device);
- pr_debug("usb->usb.interface %p\n", usb->usb.interface);
- pr_debug("usb->usb.pipe.isoch.in %x\n", usb->usb.pipe.isoch.in);
- pr_debug("usb->usb.pipe.isoch.out %x\n", usb->usb.pipe.isoch.out);
- pr_debug("usb->usb.pipe.bulk.in %x\n", usb->usb.pipe.bulk.in);
- pr_debug("usb->usb.pipe.bulk.out %x\n", usb->usb.pipe.bulk.out);
- pr_debug("usb->usb.pipe.interrupt.in %x\n", usb->usb.pipe.interrupt.in);
- pr_debug("usb->usb.pipe.interrupt.out %x\n", usb->usb.pipe.interrupt.out);
pr_debug("baseband_usb_open }\n");
return usb;
error_exit:
baseband_usb_close(usb);
- return ((struct baseband_usb *) 0);
-}
-
-/* usb rx */
-
-static int baseband_usb_chr_rx_urb_submit(struct baseband_usb *usb);
-static void baseband_usb_chr_rx_urb_comp(struct urb *urb);
-static void baseband_usb_chr_rx_urb_comp_work(struct work_struct *work);
-
-static int baseband_usb_chr_rx_urb_submit(struct baseband_usb *usb)
-{
- struct urb *urb;
- void *buf;
- int err;
-
- pr_debug("baseband_usb_chr_rx_urb_submit { usb %p\n", usb);
-
- /* check input */
- if (usb->usb.rx_urb) {
- pr_err("previous urb still active\n");
- return -1;
- }
-
- /* allocate rx urb */
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb) {
- pr_err("usb_alloc_urb() failed\n");
- return -ENOMEM;
- }
- buf = kzalloc(USB_CHR_RX_BUFSIZ, GFP_ATOMIC);
- if (!buf) {
- pr_err("usb buffer kzalloc() failed\n");
- usb_free_urb(urb);
- return -ENOMEM;
- }
- usb_fill_bulk_urb(urb, usb->usb.device, usb->usb.pipe.bulk.in,
- buf, USB_CHR_RX_BUFSIZ,
- baseband_usb_chr_rx_urb_comp,
- usb);
- urb->transfer_flags = 0;
-
- /* submit rx urb */
- usb->usb.rx_urb = urb;
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err < 0) {
- pr_err("usb_submit_urb() failed - err %d\n", err);
- usb->usb.rx_urb = (struct urb *) 0;
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- return err;
- }
-
- pr_debug("baseband_usb_chr_rx_urb_submit }\n");
- return err;
-}
-
-static void baseband_usb_chr_rx_urb_comp(struct urb *urb)
-{
- struct baseband_usb *usb = (struct baseband_usb *) urb->context;
-
- pr_debug("baseband_usb_chr_rx_urb_comp { urb %p\n", urb);
-
- /* queue rx urb completion work */
- queue_work(usb->ipc->workqueue, &usb->ipc->rx_work);
-
- pr_debug("baseband_usb_chr_rx_urb_comp }\n");
-}
-
-static void baseband_usb_chr_rx_urb_comp_work(struct work_struct *work)
-{
- struct baseband_usb *usb = baseband_usb_chr;
- struct urb *urb = usb->usb.rx_urb;
- size_t len;
-
- pr_debug("baseband_usb_chr_rx_urb_comp_work { work %p\n", work);
-
- /* put rx urb data in rx buffer */
- if (urb->actual_length) {
- pr_debug("baseband_usb_chr_rx_urb_comp_work - "
- "urb->actual_length %d\n", urb->actual_length);
- len = put_ipc_rx_buf(usb->ipc,
- urb->transfer_buffer, urb->actual_length);
- baseband_ipc_dump("baseband_usb_chr_rx_urb_comp_work"
- " - rx buf ", 0,
- urb->transfer_buffer, len > 16 ? 16 : len);
- if (len != urb->actual_length) {
- pr_err("baseband_usb_chr_rx_urb_comp_work - "
- "put_ipx_rx_buf() only put %d/%d bytes\n",
- len, urb->actual_length);
- }
- /* increment count of available rx bytes */
- atomic_add(len, &g_rx_count);
- }
-
- /* free rx urb */
- if (urb->transfer_buffer) {
- kfree(urb->transfer_buffer);
- urb->transfer_buffer = (void *) 0;
- }
- usb_free_urb(urb);
- usb->usb.rx_urb = (struct urb *) 0;
-
- /* submit next rx urb */
- baseband_usb_chr_rx_urb_submit(usb);
-
- pr_debug("baseband_usb_chr_rx_urb_comp_work }\n");
+ baseband_usb_chr = (struct baseband_usb *) 0;
+ return (struct baseband_usb *) 0;
}
/* module init / exit functions */
@@ -1054,17 +1076,8 @@ static int baseband_usb_chr_init(void)
pr_debug("registered baseband usb character device - major %d\n",
BASEBAND_USB_CHR_DEV_MAJOR);
- /* start usb rx */
- err = baseband_usb_chr_rx_urb_submit(baseband_usb_chr);
- if (err < 0) {
- pr_err("submit rx failed - err %d\n", err);
- goto err3;
- }
-
pr_debug("baseband_usb_chr_init }\n");
return 0;
-err3: unregister_chrdev(BASEBAND_USB_CHR_DEV_MAJOR,
- BASEBAND_USB_CHR_DEV_NAME);
err2: baseband_usb_close(baseband_usb_chr);
baseband_usb_chr = (struct baseband_usb *) 0;
err1: return err;