Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a5923340 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Felipe Balbi
Browse files

usb: gadget: factor out two helper functions from composite_bind()



This patch factors out two helper functions from composite_bind()
that is composite_dev_prepare() and its counterpart
composite_dev_cleanup().

This will be used by the configfs which requries a slightly different
bind/setup code because part of its configurations (i.e. config
descripts, cdev, …) are setup in advance and VID/PID and so one should
not be overwritten. Also the setup of ep0 endpoint can be delayed until
the UDC is assigned.

Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 4c49a5f0
Loading
Loading
Loading
Loading
+51 −31
Original line number Diff line number Diff line
@@ -1394,11 +1394,8 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
	if (cdev->driver->unbind && unbind_driver)
		cdev->driver->unbind(cdev);

	if (cdev->req) {
		kfree(cdev->req->buf);
		usb_ep_free_request(gadget->ep0, cdev->req);
	}
	device_remove_file(&gadget->dev, &dev_attr_suspended);
	composite_dev_cleanup(cdev);

	kfree(cdev->def_manufacturer);
	kfree(cdev);
	set_gadget_data(gadget, NULL);
@@ -1447,34 +1444,25 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new,
		new->iProduct = iProduct;
}

static struct usb_composite_driver *to_cdriver(struct usb_gadget_driver *gdrv)
{
	return container_of(gdrv, struct usb_composite_driver, gadget_driver);
}

static int composite_bind(struct usb_gadget *gadget,
		struct usb_gadget_driver *gdriver)
int composite_dev_prepare(struct usb_composite_driver *composite,
		struct usb_composite_dev *cdev)
{
	struct usb_composite_dev	*cdev;
	struct usb_composite_driver	*composite = to_cdriver(gdriver);
	int				status = -ENOMEM;

	cdev = kzalloc(sizeof *cdev, GFP_KERNEL);
	if (!cdev)
		return status;

	spin_lock_init(&cdev->lock);
	cdev->gadget = gadget;
	set_gadget_data(gadget, cdev);
	INIT_LIST_HEAD(&cdev->configs);
	struct usb_gadget *gadget = cdev->gadget;
	int ret = -ENOMEM;

	/* preallocate control response and buffer */
	cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
	if (!cdev->req)
		goto fail;
		return -ENOMEM;

	cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL);
	if (!cdev->req->buf)
		goto fail;

	ret = device_create_file(&gadget->dev, &dev_attr_suspended);
	if (ret)
		goto fail_dev;

	cdev->req->complete = composite_setup_complete;
	gadget->ep0->driver_data = cdev;

@@ -1492,7 +1480,44 @@ static int composite_bind(struct usb_gadget *gadget,
	 * we force endpoints to start unassigned; few controller
	 * drivers will zero ep->driver_data.
	 */
	usb_ep_autoconfig_reset(cdev->gadget);
	usb_ep_autoconfig_reset(gadget);
	return 0;
fail_dev:
	kfree(cdev->req->buf);
fail:
	usb_ep_free_request(gadget->ep0, cdev->req);
	cdev->req = NULL;
	return ret;
}

void composite_dev_cleanup(struct usb_composite_dev *cdev)
{
	if (cdev->req) {
		kfree(cdev->req->buf);
		usb_ep_free_request(cdev->gadget->ep0, cdev->req);
	}
	device_remove_file(&cdev->gadget->dev, &dev_attr_suspended);
}

static int composite_bind(struct usb_gadget *gadget,
		struct usb_gadget_driver *gdriver)
{
	struct usb_composite_dev	*cdev;
	struct usb_composite_driver	*composite = to_cdriver(gdriver);
	int				status = -ENOMEM;

	cdev = kzalloc(sizeof *cdev, GFP_KERNEL);
	if (!cdev)
		return status;

	spin_lock_init(&cdev->lock);
	cdev->gadget = gadget;
	set_gadget_data(gadget, cdev);
	INIT_LIST_HEAD(&cdev->configs);

	status = composite_dev_prepare(composite, cdev);
	if (status)
		goto fail;

	/* composite gadget needs to assign strings for whole device (like
	 * serial number), register function drivers, potentially update
@@ -1508,11 +1533,6 @@ static int composite_bind(struct usb_gadget *gadget,
	if (composite->needs_serial && !cdev->desc.iSerialNumber)
		WARNING(cdev, "userspace failed to provide iSerialNumber\n");

	/* finish up */
	status = device_create_file(&gadget->dev, &dev_attr_suspended);
	if (status)
		goto fail;

	INFO(cdev, "%s ready\n", composite->name);
	return 0;

+8 −0
Original line number Diff line number Diff line
@@ -323,7 +323,15 @@ struct usb_composite_driver {
extern int usb_composite_probe(struct usb_composite_driver *driver);
extern void usb_composite_unregister(struct usb_composite_driver *driver);
extern void usb_composite_setup_continue(struct usb_composite_dev *cdev);
extern int composite_dev_prepare(struct usb_composite_driver *composite,
		struct usb_composite_dev *cdev);
void composite_dev_cleanup(struct usb_composite_dev *cdev);

static inline struct usb_composite_driver *to_cdriver(
		struct usb_gadget_driver *gdrv)
{
	return container_of(gdrv, struct usb_composite_driver, gadget_driver);
}

/**
 * struct usb_composite_device - represents one composite usb gadget