From: Felipe Balbi <balbi@kernel.org>
To: "Noralf Trønnes" <noralf@tronnes.org>, dri-devel@lists.freedesktop.org
Cc: linux-usb@vger.kernel.org, sam@ravnborg.org,
"Noralf Trønnes" <noralf@tronnes.org>
Subject: Re: [PATCH v3 6/6] usb: gadget: function: Add Generic USB Display support
Date: Tue, 02 Jun 2020 20:05:01 +0300 [thread overview]
Message-ID: <87k10p1jr6.fsf@kernel.org> (raw)
In-Reply-To: <20200529175643.46094-7-noralf@tronnes.org>
[-- Attachment #1: Type: text/plain, Size: 4315 bytes --]
Hi,
I missed this completely until now.
Noralf Trønnes <noralf@tronnes.org> writes:
> This adds the gadget side support for the Generic USB Display. It presents
> a DRM display device as a USB Display configured through configfs.
>
> The display is implemented as a vendor type USB interface with one bulk
> out endpoint. The protocol is implemented using control requests.
> lz4 compressed framebuffer data/pixels are sent over the bulk endpoint.
>
> The DRM part of the gadget is placed in the DRM subsystem since it reaches
> into the DRM internals.
First and foremost, could this be done in userspace using the raw gadget
or f_fs?
> diff --git a/drivers/usb/gadget/function/f_gud_drm.c b/drivers/usb/gadget/function/f_gud_drm.c
> new file mode 100644
> index 000000000000..9a2d6bb9739f
> --- /dev/null
> +++ b/drivers/usb/gadget/function/f_gud_drm.c
> @@ -0,0 +1,678 @@
> +struct f_gud_drm {
> + struct usb_function func;
> + struct work_struct worker;
why do you need a worker?
> + size_t max_buffer_size;
> + void *ctrl_req_buf;
> +
> + u8 interface_id;
> + struct usb_request *ctrl_req;
> +
> + struct usb_ep *bulk_ep;
> + struct usb_request *bulk_req;
single request? Don't you want to amortize the latency of
queue->complete by using a series of requests?
> + struct gud_drm_gadget *gdg;
> +
> + spinlock_t lock; /* Protects the following members: */
> + bool ctrl_pending;
> + bool status_pending;
> + bool bulk_pending;
> + bool disable_pending;
could this be a single u32 with #define'd flags? That would be atomic,
right?
> + u8 errno;
a global per-function error? Why?
> + u16 request;
> + u16 value;
also why? Looks odd
> +};
> +
> +static inline struct f_gud_drm *func_to_f_gud_drm(struct usb_function *f)
let the compiler inline for you
> +{
> + return container_of(f, struct f_gud_drm, func);
could be a macro, but okay.
> +static inline struct f_gud_drm_opts *fi_to_f_gud_drm_opts(const struct usb_function_instance *fi)
ditto
> +{
> + return container_of(fi, struct f_gud_drm_opts, func_inst);
ditto
> +}
> +
> +static inline struct f_gud_drm_opts *ci_to_f_gud_drm_opts(struct config_item *item)
ditto
> +{
> + return container_of(to_config_group(item), struct f_gud_drm_opts,
> + func_inst.group);
ditto
> +}
> +
> +#define F_MUD_DEFINE_BULK_ENDPOINT_DESCRIPTOR(name, addr, size) \
> + static struct usb_endpoint_descriptor name = { \
const? Also, please check all the others
> +static void f_gud_drm_bulk_complete(struct usb_ep *ep, struct usb_request *req)
> +{
> + struct f_gud_drm *fgd = req->context;
> + unsigned long flags;
> +
> + if (req->status || req->actual != req->length)
> + return;
so, if we complete with an erroneous status or a short packet, you'll
ignore it?
> + spin_lock_irqsave(&fgd->lock, flags);
> + fgd->bulk_pending = true;
> + spin_unlock_irqrestore(&fgd->lock, flags);
> +
> + queue_work(system_long_wq, &fgd->worker);
Do you need to offset this to a worker?
> +static int f_gud_drm_ctrl_req_set_buffer(struct f_gud_drm *fgd, void *buf, size_t len)
> +{
> + int ret;
> +
> + if (len != sizeof(struct gud_drm_req_set_buffer))
> + return -EINVAL;
> +
> + ret = gud_drm_gadget_set_buffer(fgd->gdg, buf);
> + if (ret < 0)
> + return ret;
> +
> + if (ret > fgd->max_buffer_size)
> + return -EOVERFLOW;
> +
> + fgd->bulk_req->length = ret;
> +
> + return usb_ep_queue(fgd->bulk_ep, fgd->bulk_req, GFP_KERNEL);
> +}
> +
> +static void f_gud_drm_worker(struct work_struct *work)
> +{
> + struct f_gud_drm *fgd = container_of(work, struct f_gud_drm, worker);
> + bool ctrl_pending, bulk_pending, disable_pending;
> + struct gud_drm_gadget *gdg = fgd->gdg;
> + unsigned long flags;
> + u16 request, value;
> + int ret;
> +
> + spin_lock_irqsave(&fgd->lock, flags);
> + request = fgd->request;
> + value = fgd->value;
> + ctrl_pending = fgd->ctrl_pending;
> + bulk_pending = fgd->bulk_pending;
> + disable_pending = fgd->disable_pending;
> + spin_unlock_irqrestore(&fgd->lock, flags);
> +
> + pr_debug("%s: bulk_pending=%u ctrl_pending=%u disable_pending=%u\n",
> + __func__, bulk_pending, ctrl_pending, disable_pending);
could we use dev_dbg() at least?
--
balbi
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: Felipe Balbi <balbi@kernel.org>
To: "Noralf Trønnes" <noralf@tronnes.org>, dri-devel@lists.freedesktop.org
Cc: linux-usb@vger.kernel.org, sam@ravnborg.org
Subject: Re: [PATCH v3 6/6] usb: gadget: function: Add Generic USB Display support
Date: Tue, 02 Jun 2020 20:05:01 +0300 [thread overview]
Message-ID: <87k10p1jr6.fsf@kernel.org> (raw)
In-Reply-To: <20200529175643.46094-7-noralf@tronnes.org>
[-- Attachment #1.1: Type: text/plain, Size: 4315 bytes --]
Hi,
I missed this completely until now.
Noralf Trønnes <noralf@tronnes.org> writes:
> This adds the gadget side support for the Generic USB Display. It presents
> a DRM display device as a USB Display configured through configfs.
>
> The display is implemented as a vendor type USB interface with one bulk
> out endpoint. The protocol is implemented using control requests.
> lz4 compressed framebuffer data/pixels are sent over the bulk endpoint.
>
> The DRM part of the gadget is placed in the DRM subsystem since it reaches
> into the DRM internals.
First and foremost, could this be done in userspace using the raw gadget
or f_fs?
> diff --git a/drivers/usb/gadget/function/f_gud_drm.c b/drivers/usb/gadget/function/f_gud_drm.c
> new file mode 100644
> index 000000000000..9a2d6bb9739f
> --- /dev/null
> +++ b/drivers/usb/gadget/function/f_gud_drm.c
> @@ -0,0 +1,678 @@
> +struct f_gud_drm {
> + struct usb_function func;
> + struct work_struct worker;
why do you need a worker?
> + size_t max_buffer_size;
> + void *ctrl_req_buf;
> +
> + u8 interface_id;
> + struct usb_request *ctrl_req;
> +
> + struct usb_ep *bulk_ep;
> + struct usb_request *bulk_req;
single request? Don't you want to amortize the latency of
queue->complete by using a series of requests?
> + struct gud_drm_gadget *gdg;
> +
> + spinlock_t lock; /* Protects the following members: */
> + bool ctrl_pending;
> + bool status_pending;
> + bool bulk_pending;
> + bool disable_pending;
could this be a single u32 with #define'd flags? That would be atomic,
right?
> + u8 errno;
a global per-function error? Why?
> + u16 request;
> + u16 value;
also why? Looks odd
> +};
> +
> +static inline struct f_gud_drm *func_to_f_gud_drm(struct usb_function *f)
let the compiler inline for you
> +{
> + return container_of(f, struct f_gud_drm, func);
could be a macro, but okay.
> +static inline struct f_gud_drm_opts *fi_to_f_gud_drm_opts(const struct usb_function_instance *fi)
ditto
> +{
> + return container_of(fi, struct f_gud_drm_opts, func_inst);
ditto
> +}
> +
> +static inline struct f_gud_drm_opts *ci_to_f_gud_drm_opts(struct config_item *item)
ditto
> +{
> + return container_of(to_config_group(item), struct f_gud_drm_opts,
> + func_inst.group);
ditto
> +}
> +
> +#define F_MUD_DEFINE_BULK_ENDPOINT_DESCRIPTOR(name, addr, size) \
> + static struct usb_endpoint_descriptor name = { \
const? Also, please check all the others
> +static void f_gud_drm_bulk_complete(struct usb_ep *ep, struct usb_request *req)
> +{
> + struct f_gud_drm *fgd = req->context;
> + unsigned long flags;
> +
> + if (req->status || req->actual != req->length)
> + return;
so, if we complete with an erroneous status or a short packet, you'll
ignore it?
> + spin_lock_irqsave(&fgd->lock, flags);
> + fgd->bulk_pending = true;
> + spin_unlock_irqrestore(&fgd->lock, flags);
> +
> + queue_work(system_long_wq, &fgd->worker);
Do you need to offset this to a worker?
> +static int f_gud_drm_ctrl_req_set_buffer(struct f_gud_drm *fgd, void *buf, size_t len)
> +{
> + int ret;
> +
> + if (len != sizeof(struct gud_drm_req_set_buffer))
> + return -EINVAL;
> +
> + ret = gud_drm_gadget_set_buffer(fgd->gdg, buf);
> + if (ret < 0)
> + return ret;
> +
> + if (ret > fgd->max_buffer_size)
> + return -EOVERFLOW;
> +
> + fgd->bulk_req->length = ret;
> +
> + return usb_ep_queue(fgd->bulk_ep, fgd->bulk_req, GFP_KERNEL);
> +}
> +
> +static void f_gud_drm_worker(struct work_struct *work)
> +{
> + struct f_gud_drm *fgd = container_of(work, struct f_gud_drm, worker);
> + bool ctrl_pending, bulk_pending, disable_pending;
> + struct gud_drm_gadget *gdg = fgd->gdg;
> + unsigned long flags;
> + u16 request, value;
> + int ret;
> +
> + spin_lock_irqsave(&fgd->lock, flags);
> + request = fgd->request;
> + value = fgd->value;
> + ctrl_pending = fgd->ctrl_pending;
> + bulk_pending = fgd->bulk_pending;
> + disable_pending = fgd->disable_pending;
> + spin_unlock_irqrestore(&fgd->lock, flags);
> +
> + pr_debug("%s: bulk_pending=%u ctrl_pending=%u disable_pending=%u\n",
> + __func__, bulk_pending, ctrl_pending, disable_pending);
could we use dev_dbg() at least?
--
balbi
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
[-- Attachment #2: Type: text/plain, Size: 160 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2020-06-02 17:05 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-29 17:56 [PATCH v3 0/6] Generic USB Display driver Noralf Trønnes
2020-05-29 17:56 ` Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 1/6] drm/client: Add drm_client_init_from_id() Noralf Trønnes
2020-05-29 17:56 ` Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 2/6] drm/client: Add drm_client_modeset_disable() Noralf Trønnes
2020-05-29 17:56 ` Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 3/6] drm/client: Add a way to set modeset, properties and rotation Noralf Trønnes
2020-05-29 17:56 ` Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 4/6] drm: Add Generic USB Display driver Noralf Trønnes
2020-05-29 17:56 ` Noralf Trønnes
2020-05-29 22:45 ` Peter Stuge
2020-05-29 22:45 ` Peter Stuge
2020-06-01 16:57 ` Noralf Trønnes
2020-06-01 16:57 ` Noralf Trønnes
2020-06-02 0:12 ` Peter Stuge
2020-06-02 0:12 ` Peter Stuge
2020-06-02 2:32 ` Alan Stern
2020-06-02 2:32 ` Alan Stern
2020-06-02 5:21 ` Peter Stuge
2020-06-02 5:21 ` Peter Stuge
2020-06-02 15:27 ` Alan Stern
2020-06-02 15:27 ` Alan Stern
2020-06-02 18:38 ` Peter Stuge
2020-06-02 18:38 ` Peter Stuge
2020-06-05 12:03 ` Noralf Trønnes
2020-06-05 12:03 ` Noralf Trønnes
2020-06-02 11:46 ` Noralf Trønnes
2020-06-02 11:46 ` Noralf Trønnes
2020-07-14 15:30 ` Noralf Trønnes
2020-07-14 15:30 ` Noralf Trønnes
2020-06-03 19:17 ` Noralf Trønnes
2020-06-03 19:17 ` Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 5/6] drm/gud: Add functionality for the USB gadget side Noralf Trønnes
2020-05-29 17:56 ` Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 6/6] usb: gadget: function: Add Generic USB Display support Noralf Trønnes
2020-05-29 17:56 ` Noralf Trønnes
2020-06-02 17:05 ` Felipe Balbi [this message]
2020-06-02 17:05 ` Felipe Balbi
2020-06-02 19:14 ` Noralf Trønnes
2020-06-02 19:14 ` Noralf Trønnes
2020-06-03 7:10 ` Felipe Balbi
2020-06-03 7:10 ` Felipe Balbi
2020-07-09 16:32 ` [PATCH v3 0/6] Generic USB Display driver Lubomir Rintel
2020-07-09 16:32 ` Lubomir Rintel
2020-07-14 13:33 ` Noralf Trønnes
2020-07-14 13:33 ` Noralf Trønnes
2020-07-14 17:40 ` Peter Stuge
2020-07-14 17:40 ` Peter Stuge
2020-07-14 19:03 ` Noralf Trønnes
2020-07-14 19:03 ` Noralf Trønnes
2020-07-14 19:38 ` Peter Stuge
2020-07-14 19:38 ` Peter Stuge
2020-07-16 17:43 ` Noralf Trønnes
2020-07-16 17:43 ` Noralf Trønnes
2020-07-15 7:30 ` Lubomir Rintel
2020-07-15 7:30 ` Lubomir Rintel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87k10p1jr6.fsf@kernel.org \
--to=balbi@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-usb@vger.kernel.org \
--cc=noralf@tronnes.org \
--cc=sam@ravnborg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.