From 4504b5a0b22e26a7213d9e08706303a790f5a400 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:13 +0100 Subject: [PATCH] usb: gadget: printer: move function-related bind code to function's bind 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 Signed-off-by: Felipe Balbi --- 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 494cd8a5aca4..c8570441a303 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) -- 2.39.2