usb: gadget: printer: move function-related bind code to function's bind
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>
Tue, 3 Mar 2015 09:52:13 +0000 (10:52 +0100)
committerFelipe Balbi <balbi@ti.com>
Tue, 10 Mar 2015 20:33:36 +0000 (15:33 -0500)
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@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/legacy/printer.c

index 494cd8a5aca4e9c3bf61618e8e21ec37c3be3f71..c8570441a303680eb33aff081c8c9d051da5a2ba 100644 (file)
@@ -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)