aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2012-12-23 15:10:20 -0500
committerFelipe Balbi <balbi@ti.com>2013-01-21 13:52:47 -0500
commita59233407aed54b8a9121cea75d9c6a2a470d8d3 (patch)
treef073dd5e345f1ba8e1a23480e418cee608dc825e
parent4c49a5f0ef1bc61395329ea7a9fce2893e97eaa6 (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>
-rw-r--r--drivers/usb/gadget/composite.c82
-rw-r--r--include/linux/usb/composite.h8
2 files changed, 59 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
1450static struct usb_composite_driver *to_cdriver(struct usb_gadget_driver *gdrv) 1447int 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
1455static 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;
1485fail_dev:
1486 kfree(cdev->req->buf);
1487fail:
1488 usb_ep_free_request(gadget->ep0, cdev->req);
1489 cdev->req = NULL;
1490 return ret;
1491}
1492
1493void 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
1502static 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
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 771de7acf8dd..bd6d857c12f4 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -323,7 +323,15 @@ struct usb_composite_driver {
323extern int usb_composite_probe(struct usb_composite_driver *driver); 323extern int usb_composite_probe(struct usb_composite_driver *driver);
324extern void usb_composite_unregister(struct usb_composite_driver *driver); 324extern void usb_composite_unregister(struct usb_composite_driver *driver);
325extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); 325extern void usb_composite_setup_continue(struct usb_composite_dev *cdev);
326extern int composite_dev_prepare(struct usb_composite_driver *composite,
327 struct usb_composite_dev *cdev);
328void composite_dev_cleanup(struct usb_composite_dev *cdev);
326 329
330static inline struct usb_composite_driver *to_cdriver(
331 struct usb_gadget_driver *gdrv)
332{
333 return container_of(gdrv, struct usb_composite_driver, gadget_driver);
334}
327 335
328/** 336/**
329 * struct usb_composite_device - represents one composite usb gadget 337 * struct usb_composite_device - represents one composite usb gadget