summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2015-03-03 10:52:13 +0100
committerFelipe Balbi <balbi@ti.com>2015-03-10 15:33:36 -0500
commit4504b5a0b22e26a7213d9e08706303a790f5a400 (patch)
tree7af77a2a5acbe6967eecf6abdfccbcff1d50a9be /drivers/usb/gadget
parentae2dd0de57a3f6b12e30e5552033a492d6d206f7 (diff)
downloadlinux-stable-4504b5a0b22e26a7213d9e08706303a790f5a400.tar.gz
linux-stable-4504b5a0b22e26a7213d9e08706303a790f5a400.tar.bz2
linux-stable-4504b5a0b22e26a7213d9e08706303a790f5a400.zip
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 <andrzej.p@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/legacy/printer.c114
1 files 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)