summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/function
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/function')
-rw-r--r--drivers/usb/gadget/function/u_data_bridge.c77
1 files changed, 25 insertions, 52 deletions
diff --git a/drivers/usb/gadget/function/u_data_bridge.c b/drivers/usb/gadget/function/u_data_bridge.c
index 944b770fa6c4..c4ef3e84edea 100644
--- a/drivers/usb/gadget/function/u_data_bridge.c
+++ b/drivers/usb/gadget/function/u_data_bridge.c
@@ -39,9 +39,9 @@
#define num_of_instance 2
#define BRIDGE_RX_QUEUE_SIZE 8
-#define BRIDGE_RX_BUF_SIZE PAGE_SIZE
+#define BRIDGE_RX_BUF_SIZE 2048
#define BRIDGE_TX_QUEUE_SIZE 8
-#define BRIDGE_TX_BUF_SIZE PAGE_SIZE
+#define BRIDGE_TX_BUF_SIZE 2048
struct gbridge_port {
struct cdev gbridge_cdev;
@@ -62,7 +62,6 @@ struct gbridge_port {
unsigned cbits_to_modem;
bool cbits_updated;
- unsigned cbits_to_host;
bool is_connected;
bool port_open;
@@ -78,6 +77,7 @@ struct class *gbridge_classp;
static dev_t gbridge_number;
static struct workqueue_struct *gbridge_wq;
static unsigned n_bridge_ports;
+static void gbridge_read_complete(struct usb_ep *ep, struct usb_request *req);
static void gbridge_free_req(struct usb_ep *ep, struct usb_request *req)
{
kfree(req->buf);
@@ -90,7 +90,7 @@ static void gbridge_free_requests(struct usb_ep *ep, struct list_head *head)
while (!list_empty(head)) {
req = list_entry(head->next, struct usb_request, list);
- list_del(&req->list);
+ list_del_init(&req->list);
gbridge_free_req(ep, req);
}
}
@@ -154,9 +154,9 @@ static void gbridge_start_rx(struct gbridge_port *port)
}
spin_lock_irqsave(&port->port_lock, flags);
- if (!port->port_usb) {
+ if (!(port->is_connected && port->port_open)) {
spin_unlock_irqrestore(&port->port_lock, flags);
- pr_err("Err as USB is disconnected.\n");
+ pr_debug("can't start rx.\n");
return;
}
@@ -167,7 +167,9 @@ static void gbridge_start_rx(struct gbridge_port *port)
struct usb_request *req;
req = list_entry(pool->next, struct usb_request, list);
- list_del(&req->list);
+ list_del_init(&req->list);
+ req->length = BRIDGE_RX_BUF_SIZE;
+ req->complete = gbridge_read_complete;
spin_unlock_irqrestore(&port->port_lock, flags);
ret = usb_ep_queue(ep, req, GFP_KERNEL);
spin_lock_irqsave(&port->port_lock, flags);
@@ -195,17 +197,13 @@ static void gbridge_read_complete(struct usb_ep *ep, struct usb_request *req)
}
spin_lock_irqsave(&port->port_lock, flags);
- if (!port->port_open) {
+ if (!port->port_open || req->status || !req->actual) {
list_add_tail(&req->list, &port->read_pool);
spin_unlock_irqrestore(&port->port_lock, flags);
return;
}
- if (!req->status)
- port->nbytes_from_host += req->actual;
- else
- pr_warn("read_complete with status:%d\n", req->status);
-
+ port->nbytes_from_host += req->actual;
list_add_tail(&req->list, &port->read_queued);
spin_unlock_irqrestore(&port->port_lock, flags);
@@ -303,20 +301,16 @@ static void gbridge_stop_io(struct gbridge_port *port)
out = port->port_usb->out;
spin_unlock_irqrestore(&port->port_lock, flags);
- usb_ep_fifo_flush(in);
- usb_ep_fifo_flush(out);
+ /* disable endpoints, aborting down any active I/O */
+ usb_ep_disable(out);
+ out->driver_data = NULL;
+ usb_ep_disable(in);
+ in->driver_data = NULL;
spin_lock_irqsave(&port->port_lock, flags);
- if (port->port_usb) {
- gbridge_free_requests(out, &port->read_pool);
- gbridge_free_requests(in, &port->write_pool);
- port->cbits_to_host = 0;
- }
-
- if (port->port_usb->send_modem_ctrl_bits)
- port->port_usb->send_modem_ctrl_bits(
- port->port_usb,
- port->cbits_to_host);
+ gbridge_free_requests(out, &port->read_queued);
+ gbridge_free_requests(out, &port->read_pool);
+ gbridge_free_requests(in, &port->write_pool);
spin_unlock_irqrestore(&port->port_lock, flags);
}
@@ -325,7 +319,6 @@ int gbridge_port_open(struct inode *inode, struct file *file)
int ret;
unsigned long flags;
struct gbridge_port *port;
- struct gserial *gser;
port = container_of(inode->i_cdev, struct gbridge_port,
gbridge_cdev);
@@ -350,11 +343,8 @@ int gbridge_port_open(struct inode *inode, struct file *file)
spin_lock_irqsave(&port->port_lock, flags);
port->port_open = true;
- gser = port->port_usb;
spin_unlock_irqrestore(&port->port_lock, flags);
- gbridge_start_io(port);
- if (gser && gser->connect)
- gser->connect(gser);
+ gbridge_start_rx(port);
pr_debug("port(%p) open is success\n", port);
@@ -365,7 +355,6 @@ int gbridge_port_release(struct inode *inode, struct file *file)
{
unsigned long flags;
struct gbridge_port *port;
- struct gserial *gser;
port = file->private_data;
if (!port) {
@@ -375,14 +364,10 @@ int gbridge_port_release(struct inode *inode, struct file *file)
pr_debug("closing port(%p)\n", port);
spin_lock_irqsave(&port->port_lock, flags);
- gser = port->port_usb;
- if (gser && gser->disconnect)
- gser->disconnect(gser);
port->port_open = false;
port->cbits_updated = false;
spin_unlock_irqrestore(&port->port_lock, flags);
- gbridge_stop_io(port);
pr_debug("port(%p) is closed.\n", port);
return 0;
@@ -471,7 +456,7 @@ ssize_t gbridge_port_write(struct file *file,
}
pool = &port->write_pool;
req = list_first_entry(pool, struct usb_request, list);
- list_del(&req->list);
+ list_del_init(&req->list);
spin_unlock_irqrestore(&port->port_lock, flags);
pr_debug("%s: write buf size:%zu\n", __func__, count);
@@ -710,13 +695,12 @@ static ssize_t debug_gbridge_read_stats(struct file *file, char __user *ubuf,
"nbytes_to_port_bridge: %lu\n"
"nbytes_from_port_bridge: %lu\n"
"cbits_to_modem: %u\n"
- "cbits_to_host: %u\n"
"Port Opened: %s\n",
i, port->nbytes_to_host,
port->nbytes_from_host,
port->nbytes_to_port_bridge,
port->nbytes_from_port_bridge,
- port->cbits_to_modem, port->cbits_to_host,
+ port->cbits_to_modem,
(port->port_open ? "Opened" : "Closed"));
spin_unlock_irqrestore(&port->port_lock, flags);
}
@@ -828,6 +812,7 @@ int gbridge_connect(void *gptr, u8 portno)
port->is_connected = true;
spin_unlock_irqrestore(&port->port_lock, flags);
+ gbridge_start_io(port);
wake_up(&port->open_wq);
return 0;
}
@@ -852,25 +837,13 @@ void gbridge_disconnect(void *gptr, u8 portno)
port = ports[portno];
gser = gptr;
+ gbridge_stop_io(port);
spin_lock_irqsave(&port->port_lock, flags);
port->is_connected = false;
- port->port_usb = 0;
- spin_unlock_irqrestore(&port->port_lock, flags);
-
- /* disable endpoints, aborting down any active I/O */
- usb_ep_disable(gser->out);
- gser->out->driver_data = NULL;
- usb_ep_disable(gser->in);
- gser->in->driver_data = NULL;
-
- spin_lock_irqsave(&port->port_lock, flags);
- gbridge_free_requests(gser->out, &port->read_pool);
- gbridge_free_requests(gser->in, &port->write_pool);
-
+ port->port_usb = NULL;
port->nbytes_from_host = port->nbytes_to_host = 0;
port->nbytes_to_port_bridge = 0;
spin_unlock_irqrestore(&port->port_lock, flags);
-
}
static void gbridge_port_free(int portno)