summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-09-25 08:06:22 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-09-25 08:06:22 +0200
commitfaddac631a0e521780854ecf9a53f96481a32716 (patch)
tree292c866315fd161df41d90f4bbde1572b14415d1 /drivers/usb
parent1ab2e649dc0ccef7ee990b999e1d8f8c32e7cd24 (diff)
parent0d4d157cf0d42206491b7a1b417c9904a9abd553 (diff)
downloadbarebox-faddac631a0e521780854ecf9a53f96481a32716.tar.gz
barebox-faddac631a0e521780854ecf9a53f96481a32716.tar.xz
Merge branch 'for-next/net' into master
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/usb.c12
-rw-r--r--drivers/usb/gadget/f_fastboot.c54
2 files changed, 52 insertions, 14 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 30c251f405..c068c64c6b 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -75,28 +75,30 @@ static int host_busnum = 1;
static inline int usb_host_acquire(struct usb_host *host)
{
- if (host->sem)
+ if (slice_acquired(&host->slice))
return -EAGAIN;
- host->sem++;
+
+ slice_acquire(&host->slice);
+
return 0;
}
static inline void usb_host_release(struct usb_host *host)
{
- if (host->sem > 0)
- host->sem--;
+ slice_release(&host->slice);
}
int usb_register_host(struct usb_host *host)
{
list_add_tail(&host->list, &host_list);
host->busnum = host_busnum++;
- host->sem = 0;
+ slice_init(&host->slice, dev_name(host->hw_dev));
return 0;
}
void usb_unregister_host(struct usb_host *host)
{
+ slice_exit(&host->slice);
list_del(&host->list);
}
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index f8a9c32530..da3e0c7a8f 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -21,6 +21,7 @@
#define pr_fmt(fmt) "fastboot: " fmt
#include <dma.h>
+#include <work.h>
#include <unistd.h>
#include <progress.h>
#include <fastboot.h>
@@ -39,6 +40,7 @@ struct f_fastboot {
/* IN/OUT EP's and corresponding requests */
struct usb_ep *in_ep, *out_ep;
struct usb_request *in_req, *out_req;
+ struct work_queue wq;
};
static inline struct f_fastboot *func_to_fastboot(struct usb_function *f)
@@ -136,6 +138,32 @@ static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
{
}
+struct fastboot_work {
+ struct work_struct work;
+ struct f_fastboot *f_fb;
+ char command[FASTBOOT_MAX_CMD_LEN + 1];
+};
+
+static void fastboot_do_work(struct work_struct *w)
+{
+ struct fastboot_work *fw = container_of(w, struct fastboot_work, work);
+ struct f_fastboot *f_fb = fw->f_fb;
+
+ fastboot_exec_cmd(&f_fb->fastboot, fw->command);
+
+ memset(f_fb->out_req->buf, 0, EP_BUFFER_SIZE);
+ usb_ep_queue(f_fb->out_ep, f_fb->out_req);
+
+ free(fw);
+}
+
+static void fastboot_work_cancel(struct work_struct *w)
+{
+ struct fastboot_work *fw = container_of(w, struct fastboot_work, work);
+
+ free(fw);
+}
+
static struct usb_request *fastboot_alloc_request(struct usb_ep *ep)
{
struct usb_request *req;
@@ -172,6 +200,11 @@ static int fastboot_bind(struct usb_configuration *c, struct usb_function *f)
f_fb->fastboot.cmd_exec = opts->common.cmd_exec;
f_fb->fastboot.cmd_flash = opts->common.cmd_flash;
+ f_fb->wq.fn = fastboot_do_work;
+ f_fb->wq.cancel = fastboot_work_cancel;
+
+ wq_register(&f_fb->wq);
+
ret = fastboot_generic_init(&f_fb->fastboot, opts->common.export_bbu);
if (ret)
return ret;
@@ -246,6 +279,8 @@ static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f)
usb_ep_free_request(f_fb->out_ep, f_fb->out_req);
f_fb->out_req = NULL;
+ wq_unregister(&f_fb->wq);
+
fastboot_generic_free(&f_fb->fastboot);
}
@@ -313,8 +348,6 @@ static struct usb_function *fastboot_alloc_func(struct usb_function_instance *fi
f_fb = xzalloc(sizeof(*f_fb));
- INIT_LIST_HEAD(&f_fb->fastboot.variables);
-
f_fb->func.name = "fastboot";
f_fb->func.strings = fastboot_strings;
f_fb->func.bind = fastboot_bind;
@@ -430,16 +463,19 @@ static void fastboot_start_download_usb(struct fastboot *fb)
static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
{
- char *cmdbuf = req->buf;
struct f_fastboot *f_fb = req->context;
+ struct fastboot_work *w;
+ int len;
if (req->status != 0)
return;
- *(cmdbuf + req->actual) = 0;
- fastboot_exec_cmd(&f_fb->fastboot, cmdbuf);
- *cmdbuf = '\0';
- req->actual = 0;
- memset(req->buf, 0, EP_BUFFER_SIZE);
- usb_ep_queue(ep, req);
+ w = xzalloc(sizeof(*w));
+ w->f_fb = f_fb;
+
+ len = min_t(unsigned int, req->actual, FASTBOOT_MAX_CMD_LEN);
+
+ memcpy(w->command, req->buf, len);
+
+ wq_queue_work(&f_fb->wq, &w->work);
}