[RFC] usb: gadget: libcomposite: provide usb_get_cdesc()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We have global descriptors. This is okay as long as we use them
read-only. Writting the endpoint address is not *that* bad as long as
two functions of the same kind are not used in parallel.

The bad part starts when sourcesink NULLs parts of the descriptor
because it could allocate an ISOC or INT endpoint. If that happens then
once then it won't be able to assign ISOC/INT again. One might think
that if it happens once then it will happen again but then it might be
rejected because it run out of endpoints and smaller endpoints would be
possible. If we null it once, then it won't happen again.

This patch solves it by returning the "correct" copied member which then
can be used for modification. That means something like this could be
done:

	ss->int_out_ep = usb_ep_autoconfig(cdev->gadget,
				   &fs_int_sink_desc);
	usb_assign_descriptors(f, fs_source_sink_descs,
			       hs_source_sink_descs,
			       ss_source_sink_descs);
	d = usb_get_cdesc(fs_source_sink_descs, &fs_int_sink_desc,
			  f->fs_descriptors)
	d->wMaxPacketSize = 64;

The alternative would be to hold a mutex while the original is modified
and reverted back to the original state before the lock is dropped.

Any suggestions, ideas?

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
---
 drivers/usb/gadget/config.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index 34e12fc52c23..f17d060df4f8 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -159,6 +159,22 @@ usb_copy_descriptors(struct usb_descriptor_header **src)
 }
 EXPORT_SYMBOL_GPL(usb_copy_descriptors);
 
+struct usb_descriptor_header *usb_get_cdesc(struct usb_descriptor_header **hdr,
+					     struct usb_descriptor_header *desc,
+					     struct usb_descriptor_header **c)
+{
+	unsigned off;
+
+	for (off = 0; hdr[off] && c[off]; off++) {
+		if (hdr[off] == desc)
+			break;
+	}
+	if (!hdr[off] || !c[off])
+		return NULL;
+	return c[off];
+}
+EXPORT_SYMBOL_GPL(usb_get_cdesc);
+
 int usb_assign_descriptors(struct usb_function *f,
 		struct usb_descriptor_header **fs,
 		struct usb_descriptor_header **hs,
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux