diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2012-12-23 15:10:20 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-01-21 13:52:47 -0500 |
commit | a59233407aed54b8a9121cea75d9c6a2a470d8d3 (patch) | |
tree | f073dd5e345f1ba8e1a23480e418cee608dc825e /drivers/usb/gadget/composite.c | |
parent | 4c49a5f0ef1bc61395329ea7a9fce2893e97eaa6 (diff) |
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: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/composite.c')
-rw-r--r-- | drivers/usb/gadget/composite.c | 82 |
1 files changed, 51 insertions, 31 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 366facccf4f6..9083ec93f38e 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -1394,11 +1394,8 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) | |||
1394 | if (cdev->driver->unbind && unbind_driver) | 1394 | if (cdev->driver->unbind && unbind_driver) |
1395 | cdev->driver->unbind(cdev); | 1395 | cdev->driver->unbind(cdev); |
1396 | 1396 | ||
1397 | if (cdev->req) { | 1397 | composite_dev_cleanup(cdev); |
1398 | kfree(cdev->req->buf); | 1398 | |
1399 | usb_ep_free_request(gadget->ep0, cdev->req); | ||
1400 | } | ||
1401 | device_remove_file(&gadget->dev, &dev_attr_suspended); | ||
1402 | kfree(cdev->def_manufacturer); | 1399 | kfree(cdev->def_manufacturer); |
1403 | kfree(cdev); | 1400 | kfree(cdev); |
1404 | set_gadget_data(gadget, NULL); | 1401 | set_gadget_data(gadget, NULL); |
@@ -1447,34 +1444,25 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, | |||
1447 | new->iProduct = iProduct; | 1444 | new->iProduct = iProduct; |
1448 | } | 1445 | } |
1449 | 1446 | ||
1450 | static struct usb_composite_driver *to_cdriver(struct usb_gadget_driver *gdrv) | 1447 | int composite_dev_prepare(struct usb_composite_driver *composite, |
1448 | struct usb_composite_dev *cdev) | ||
1451 | { | 1449 | { |
1452 | return container_of(gdrv, struct usb_composite_driver, gadget_driver); | 1450 | struct usb_gadget *gadget = cdev->gadget; |
1453 | } | 1451 | int ret = -ENOMEM; |
1454 | |||
1455 | static int composite_bind(struct usb_gadget *gadget, | ||
1456 | struct usb_gadget_driver *gdriver) | ||
1457 | { | ||
1458 | struct usb_composite_dev *cdev; | ||
1459 | struct usb_composite_driver *composite = to_cdriver(gdriver); | ||
1460 | int status = -ENOMEM; | ||
1461 | |||
1462 | cdev = kzalloc(sizeof *cdev, GFP_KERNEL); | ||
1463 | if (!cdev) | ||
1464 | return status; | ||
1465 | |||
1466 | spin_lock_init(&cdev->lock); | ||
1467 | cdev->gadget = gadget; | ||
1468 | set_gadget_data(gadget, cdev); | ||
1469 | INIT_LIST_HEAD(&cdev->configs); | ||
1470 | 1452 | ||
1471 | /* preallocate control response and buffer */ | 1453 | /* preallocate control response and buffer */ |
1472 | cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); | 1454 | cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); |
1473 | if (!cdev->req) | 1455 | if (!cdev->req) |
1474 | goto fail; | 1456 | return -ENOMEM; |
1457 | |||
1475 | cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); | 1458 | cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); |
1476 | if (!cdev->req->buf) | 1459 | if (!cdev->req->buf) |
1477 | goto fail; | 1460 | goto fail; |
1461 | |||
1462 | ret = device_create_file(&gadget->dev, &dev_attr_suspended); | ||
1463 | if (ret) | ||
1464 | goto fail_dev; | ||
1465 | |||
1478 | cdev->req->complete = composite_setup_complete; | 1466 | cdev->req->complete = composite_setup_complete; |
1479 | gadget->ep0->driver_data = cdev; | 1467 | gadget->ep0->driver_data = cdev; |
1480 | 1468 | ||
@@ -1492,7 +1480,44 @@ static int composite_bind(struct usb_gadget *gadget, | |||
1492 | * we force endpoints to start unassigned; few controller | 1480 | * we force endpoints to start unassigned; few controller |
1493 | * drivers will zero ep->driver_data. | 1481 | * drivers will zero ep->driver_data. |
1494 | */ | 1482 | */ |
1495 | usb_ep_autoconfig_reset(cdev->gadget); | 1483 | usb_ep_autoconfig_reset(gadget); |
1484 | return 0; | ||
1485 | fail_dev: | ||
1486 | kfree(cdev->req->buf); | ||
1487 | fail: | ||
1488 | usb_ep_free_request(gadget->ep0, cdev->req); | ||
1489 | cdev->req = NULL; | ||
1490 | return ret; | ||
1491 | } | ||
1492 | |||
1493 | void composite_dev_cleanup(struct usb_composite_dev *cdev) | ||
1494 | { | ||
1495 | if (cdev->req) { | ||
1496 | kfree(cdev->req->buf); | ||
1497 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); | ||
1498 | } | ||
1499 | device_remove_file(&cdev->gadget->dev, &dev_attr_suspended); | ||
1500 | } | ||
1501 | |||
1502 | static int composite_bind(struct usb_gadget *gadget, | ||
1503 | struct usb_gadget_driver *gdriver) | ||
1504 | { | ||
1505 | struct usb_composite_dev *cdev; | ||
1506 | struct usb_composite_driver *composite = to_cdriver(gdriver); | ||
1507 | int status = -ENOMEM; | ||
1508 | |||
1509 | cdev = kzalloc(sizeof *cdev, GFP_KERNEL); | ||
1510 | if (!cdev) | ||
1511 | return status; | ||
1512 | |||
1513 | spin_lock_init(&cdev->lock); | ||
1514 | cdev->gadget = gadget; | ||
1515 | set_gadget_data(gadget, cdev); | ||
1516 | INIT_LIST_HEAD(&cdev->configs); | ||
1517 | |||
1518 | status = composite_dev_prepare(composite, cdev); | ||
1519 | if (status) | ||
1520 | goto fail; | ||
1496 | 1521 | ||
1497 | /* composite gadget needs to assign strings for whole device (like | 1522 | /* composite gadget needs to assign strings for whole device (like |
1498 | * serial number), register function drivers, potentially update | 1523 | * serial number), register function drivers, potentially update |
@@ -1508,11 +1533,6 @@ static int composite_bind(struct usb_gadget *gadget, | |||
1508 | if (composite->needs_serial && !cdev->desc.iSerialNumber) | 1533 | if (composite->needs_serial && !cdev->desc.iSerialNumber) |
1509 | WARNING(cdev, "userspace failed to provide iSerialNumber\n"); | 1534 | WARNING(cdev, "userspace failed to provide iSerialNumber\n"); |
1510 | 1535 | ||
1511 | /* finish up */ | ||
1512 | status = device_create_file(&gadget->dev, &dev_attr_suspended); | ||
1513 | if (status) | ||
1514 | goto fail; | ||
1515 | |||
1516 | INFO(cdev, "%s ready\n", composite->name); | 1536 | INFO(cdev, "%s ready\n", composite->name); |
1517 | return 0; | 1537 | return 0; |
1518 | 1538 | ||