[PATCH 10/29] usb: gadget: printer: move function-related bind code to function's bind

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

 



In order to factor out a reusable f_printer.c, the code related to the
function should be placed in functions related to the function.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx>
---
 drivers/usb/gadget/legacy/printer.c | 114 +++++++++++++++++++++---------------
 1 file changed, 66 insertions(+), 48 deletions(-)

diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c
index 494cd8a..c857044 100644
--- a/drivers/usb/gadget/legacy/printer.c
+++ b/drivers/usb/gadget/legacy/printer.c
@@ -85,6 +85,7 @@ struct printer_dev {
 	struct cdev		printer_cdev;
 	u8			printer_cdev_open;
 	wait_queue_head_t	wait;
+	unsigned		q_len;
 	struct usb_function	function;
 };
 
@@ -1045,18 +1046,25 @@ unknown:
 static int __init printer_func_bind(struct usb_configuration *c,
 		struct usb_function *f)
 {
+	struct usb_gadget *gadget = c->cdev->gadget;
 	struct printer_dev *dev = container_of(f, struct printer_dev, function);
+	struct device *pdev;
 	struct usb_composite_dev *cdev = c->cdev;
 	struct usb_ep *in_ep;
 	struct usb_ep *out_ep = NULL;
+	struct usb_request *req;
 	int id;
 	int ret;
+	u32 i;
 
 	id = usb_interface_id(c, f);
 	if (id < 0)
 		return id;
 	intf_desc.bInterfaceNumber = id;
 
+	/* finish hookup to lower layer ... */
+	dev->gadget = gadget;
+
 	/* all we really need is bulk IN/OUT */
 	in_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_in_desc);
 	if (!in_ep) {
@@ -1085,7 +1093,64 @@ autoconf_fail:
 
 	dev->in_ep = in_ep;
 	dev->out_ep = out_ep;
+
+	ret = -ENOMEM;
+	for (i = 0; i < dev->q_len; i++) {
+		req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL);
+		if (!req)
+			goto fail_tx_reqs;
+		list_add(&req->list, &dev->tx_reqs);
+	}
+
+	for (i = 0; i < dev->q_len; i++) {
+		req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL);
+		if (!req)
+			goto fail_rx_reqs;
+		list_add(&req->list, &dev->rx_reqs);
+	}
+
+	/* Setup the sysfs files for the printer gadget. */
+	pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
+				  NULL, "g_printer");
+	if (IS_ERR(pdev)) {
+		ERROR(dev, "Failed to create device: g_printer\n");
+		ret = PTR_ERR(pdev);
+		goto fail_rx_reqs;
+	}
+
+	/*
+	 * Register a character device as an interface to a user mode
+	 * program that handles the printer specific functionality.
+	 */
+	cdev_init(&dev->printer_cdev, &printer_io_operations);
+	dev->printer_cdev.owner = THIS_MODULE;
+	ret = cdev_add(&dev->printer_cdev, g_printer_devno, 1);
+	if (ret) {
+		ERROR(dev, "Failed to open char device\n");
+		goto fail_cdev_add;
+	}
+
 	return 0;
+
+fail_cdev_add:
+	device_destroy(usb_gadget_class, g_printer_devno);
+
+fail_rx_reqs:
+	while (!list_empty(&dev->rx_reqs)) {
+		req = container_of(dev->rx_reqs.next, struct usb_request, list);
+		list_del(&req->list);
+		printer_req_free(dev->out_ep, req);
+	}
+
+fail_tx_reqs:
+	while (!list_empty(&dev->tx_reqs)) {
+		req = container_of(dev->tx_reqs.next, struct usb_request, list);
+		list_del(&req->list);
+		printer_req_free(dev->in_ep, req);
+	}
+
+	return ret;
+
 }
 
 static void printer_func_unbind(struct usb_configuration *c,
@@ -1173,13 +1238,9 @@ static struct usb_configuration printer_cfg_driver = {
 static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str,
 				 unsigned q_len)
 {
-	struct usb_gadget	*gadget = c->cdev->gadget;
 	struct printer_dev	*dev;
-	struct device		*pdev;
 	int			status = -ENOMEM;
 	size_t			len;
-	u32			i;
-	struct usb_request	*req;
 
 	dev = &usb_printer_gadget;
 
@@ -1193,31 +1254,11 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str,
 	INIT_LIST_HEAD(&dev->rx_reqs);
 	INIT_LIST_HEAD(&dev->rx_buffers);
 
+	dev->q_len = q_len;
 	status = usb_add_function(c, &dev->function);
 	if (status)
 		return status;
 
-	/* Setup the sysfs files for the printer gadget. */
-	pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
-				  NULL, "g_printer");
-	if (IS_ERR(pdev)) {
-		ERROR(dev, "Failed to create device: g_printer\n");
-		status = PTR_ERR(pdev);
-		goto fail;
-	}
-
-	/*
-	 * Register a character device as an interface to a user mode
-	 * program that handles the printer specific functionality.
-	 */
-	cdev_init(&dev->printer_cdev, &printer_io_operations);
-	dev->printer_cdev.owner = THIS_MODULE;
-	status = cdev_add(&dev->printer_cdev, g_printer_devno, 1);
-	if (status) {
-		ERROR(dev, "Failed to open char device\n");
-		goto fail;
-	}
-
 	if (pnp_str)
 		strlcpy(&pnp_string[2], pnp_str, sizeof(pnp_string) - 2);
 
@@ -1240,31 +1281,8 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str,
 	dev->current_rx_bytes = 0;
 	dev->current_rx_buf = NULL;
 
-	status = -ENOMEM;
-	for (i = 0; i < q_len; i++) {
-		req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL);
-		if (!req)
-			goto fail;
-		list_add(&req->list, &dev->tx_reqs);
-	}
-
-	for (i = 0; i < q_len; i++) {
-		req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL);
-		if (!req)
-			goto fail;
-		list_add(&req->list, &dev->rx_reqs);
-	}
-
-	/* finish hookup to lower layer ... */
-	dev->gadget = gadget;
-
 	INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
 	return 0;
-
-fail:
-	printer_cfg_unbind(c);
-	usb_remove_function(c, &dev->function);
-	return status;
 }
 
 static int __init printer_do_config(struct usb_configuration *c)
-- 
1.9.1

--
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