static atomic_t g_rx_count = ATOMIC_INIT(0);
+struct usb_chr_resource {
+ unsigned char *ipc_rx;
+ unsigned char *ipc_tx;
+ unsigned char *rx_buf;
+};
+static struct usb_chr_resource usb_chr_res;
+
/* baseband ipc functions */
static void baseband_ipc_dump(const char *prefix, unsigned long int offset,
memset(&ipc->rx.wait, 0, sizeof(ipc->rx.wait));
/* destroy data buffers */
- 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)
{
ipc_buf);
list_add_tail(&ipc_buf->list, &ipc->tx_free.buf);
}
- ipc->ipc_rx = kmalloc(USB_CHR_RX_BUFSIZ, GFP_KERNEL);
+ ipc->ipc_rx = usb_chr_res.ipc_rx;
if (!ipc->ipc_rx) {
- pr_err("baseband_ipc_open - "
- "cannot allocate ipc->ipc_rx\n");
+ pr_err("%s: cannot find ipc->ipc_rx\n", __func__);
goto error_exit;
}
- ipc->ipc_tx = kmalloc(USB_CHR_TX_BUFSIZ, GFP_KERNEL);
+ ipc->ipc_tx = usb_chr_res.ipc_tx;
if (!ipc->ipc_tx) {
- pr_err("baseband_ipc_open - "
- "cannot allocate ipc->ipc_tx\n");
+ pr_err("%s: cannot find ipc->ipc_tx\n", __func__);
goto error_exit;
}
&& baseband_usb_chr->ipc->workqueue)
flush_workqueue(baseband_usb_chr->ipc->workqueue);
usb_device_connection = false;
+ probe_usb_intf = NULL;
}
pr_debug("%s(%d) }\n", __func__, __LINE__);
}
usb_kill_urb(usb->usb.rx_urb);
if (usb->usb.rx_urb->transfer_buffer) {
pr_debug("%s: free rx urb transfer buffer\n", __func__);
- kfree(usb->usb.rx_urb->transfer_buffer);
usb->usb.rx_urb->transfer_buffer = (void *) 0;
}
}
flush_work_sync(&usb->ipc->rx_work);
}
- /* close usb driver */
- if (usb->usb.driver) {
- pr_debug("close usb driver {\n");
- usb_deregister(usb->usb.driver);
- usb->usb.driver = (struct usb_driver *) 0;
- pr_debug("close usb driver }\n");
- }
/* close baseband ipc */
if (usb->ipc) {
goto error_exit;
}
- /* open usb driver */
- probe_usb_intf = (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;
- }
- /* wait for probe */
- pr_info("%s: waiting for usb probe...\n", __func__);
- for (i = 0; i < 5 * 10; i++) {
+ for (i = 0; i < 5 * 50; i++) {
if (probe_usb_intf && usb_device_connection)
break;
- msleep(100);
+ /* wait for probe */
+ pr_debug("%s: waiting for usb probe...\n", __func__);
+ msleep(20);
}
if (!probe_usb_intf || !usb_device_connection) {
- pr_info("%s: probe timed out!\n", __func__);
+ pr_err("%s: probe timed out!\n", __func__);
goto error_exit;
}
pr_err("usb_alloc_urb() failed\n");
goto error_exit;
}
- buf = kmalloc(USB_CHR_RX_BUFSIZ, GFP_KERNEL);
+ buf = usb_chr_res.rx_buf;
if (!buf) {
- pr_err("%s: usb buffer kmalloc() failed\n", __func__);
+ pr_err("%s: usb rx buffer not found\n", __func__);
usb_free_urb(urb);
goto error_exit;
}
static int baseband_usb_chr_init(void)
{
- int err;
+ int err = -ENOMEM;
pr_debug("baseband_usb_chr_init {\n");
+ usb_chr_res.ipc_rx = kmalloc(USB_CHR_RX_BUFSIZ, GFP_KERNEL);
+ if (!usb_chr_res.ipc_rx) {
+ pr_err("cannot allocate ipc_rx\n");
+ goto error;
+ }
+ usb_chr_res.ipc_tx = kmalloc(USB_CHR_TX_BUFSIZ, GFP_KERNEL);
+ if (!usb_chr_res.ipc_tx) {
+ pr_err("cannot allocate ipc_tx\n");
+ goto error;
+ }
+ usb_chr_res.rx_buf = kmalloc(USB_CHR_RX_BUFSIZ, GFP_KERNEL);
+ if (!usb_chr_res.rx_buf) {
+ pr_err("%s: usb buffer kmalloc() failed\n", __func__);
+ goto error;
+ }
+
/* register character device */
err = register_chrdev(BASEBAND_USB_CHR_DEV_MAJOR,
BASEBAND_USB_CHR_DEV_NAME,
&baseband_usb_chr_fops);
if (err < 0) {
pr_err("cannot register character device - %d\n", err);
- return err;
+ goto error;
}
pr_debug("registered baseband usb character device - major %d\n",
BASEBAND_USB_CHR_DEV_MAJOR);
pr_err("cannot create workqueue\n");
unregister_chrdev(BASEBAND_USB_CHR_DEV_MAJOR,
BASEBAND_USB_CHR_DEV_NAME);
- return -ENODEV;
+ err = -ENODEV;
+ goto error;
+ }
+
+ /* register usb driver */
+ err = usb_register(&baseband_usb_driver);
+ if (err < 0) {
+ pr_err("%s: cannot register usb driver %d\n", __func__, err);
+ goto error2;
}
pr_debug("baseband_usb_chr_init }\n");
return 0;
+
+error2:
+ unregister_chrdev(BASEBAND_USB_CHR_DEV_MAJOR,
+ BASEBAND_USB_CHR_DEV_NAME);
+ destroy_workqueue(chr_ipc_wq);
+ chr_ipc_wq = NULL;
+error:
+ kfree(usb_chr_res.ipc_rx);
+ kfree(usb_chr_res.ipc_tx);
+ kfree(usb_chr_res.rx_buf);
+ return err;
}
static void baseband_usb_chr_exit(void)
destroy_workqueue(chr_ipc_wq);
chr_ipc_wq = NULL;
}
+
+ /* close usb driver */
+ usb_deregister(&baseband_usb_driver);
+
+ kfree(usb_chr_res.ipc_rx);
+ kfree(usb_chr_res.ipc_tx);
+ kfree(usb_chr_res.rx_buf);
+
pr_debug("baseband_usb_chr_exit }\n");
}