aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2008-05-07 17:25:24 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-05-14 13:00:28 -0400
commit734d37c654569f03156f8603a9761c402a73aa20 (patch)
tree880694ade8bc79bd45425ec108e002776cea1628 /drivers
parent2c2d28a015f0dd36c5d1a06e16923e3142574066 (diff)
USB: serial gadget: simplify endpoint handling
Switch serial gadget away from a *very* old idiom: just remember the endpoints we'll be using, instead of looking them up by name each time. This is a net code and data (globals) shrink. Also fix a small memory leak in the rmmod path, by working the same as the disconnect code. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: Al Borchers <alborchers@steinerpoint.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/serial.c146
1 files changed, 57 insertions, 89 deletions
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b0c32c73aeb6..0829027d9296 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -198,10 +198,6 @@ static unsigned int gs_buf_get(struct gs_buf *gb, char *buf,
198 198
199static struct gs_dev *gs_device; 199static struct gs_dev *gs_device;
200 200
201static const char *EP_IN_NAME;
202static const char *EP_OUT_NAME;
203static const char *EP_NOTIFY_NAME;
204
205static struct mutex gs_open_close_lock[GS_NUM_PORTS]; 201static struct mutex gs_open_close_lock[GS_NUM_PORTS];
206 202
207 203
@@ -1217,13 +1213,8 @@ static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
1217 gs_free_req(gadget->ep0, dev->dev_ctrl_req); 1213 gs_free_req(gadget->ep0, dev->dev_ctrl_req);
1218 dev->dev_ctrl_req = NULL; 1214 dev->dev_ctrl_req = NULL;
1219 } 1215 }
1216 gs_reset_config(dev);
1220 gs_free_ports(dev); 1217 gs_free_ports(dev);
1221 if (dev->dev_notify_ep)
1222 usb_ep_disable(dev->dev_notify_ep);
1223 if (dev->dev_in_ep)
1224 usb_ep_disable(dev->dev_in_ep);
1225 if (dev->dev_out_ep)
1226 usb_ep_disable(dev->dev_out_ep);
1227 kfree(dev); 1218 kfree(dev);
1228 set_gadget_data(gadget, NULL); 1219 set_gadget_data(gadget, NULL);
1229 } 1220 }
@@ -1264,19 +1255,23 @@ static int __init gs_bind(struct usb_gadget *gadget)
1264 __constant_cpu_to_le16(GS_VERSION_NUM|0x0099); 1255 __constant_cpu_to_le16(GS_VERSION_NUM|0x0099);
1265 } 1256 }
1266 1257
1258 dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL);
1259 if (dev == NULL)
1260 return -ENOMEM;
1261
1267 usb_ep_autoconfig_reset(gadget); 1262 usb_ep_autoconfig_reset(gadget);
1268 1263
1269 ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc); 1264 ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc);
1270 if (!ep) 1265 if (!ep)
1271 goto autoconf_fail; 1266 goto autoconf_fail;
1272 EP_IN_NAME = ep->name; 1267 dev->dev_in_ep = ep;
1273 ep->driver_data = ep; /* claim the endpoint */ 1268 ep->driver_data = dev; /* claim the endpoint */
1274 1269
1275 ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc); 1270 ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc);
1276 if (!ep) 1271 if (!ep)
1277 goto autoconf_fail; 1272 goto autoconf_fail;
1278 EP_OUT_NAME = ep->name; 1273 dev->dev_out_ep = ep;
1279 ep->driver_data = ep; /* claim the endpoint */ 1274 ep->driver_data = dev; /* claim the endpoint */
1280 1275
1281 if (use_acm) { 1276 if (use_acm) {
1282 ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); 1277 ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc);
@@ -1286,8 +1281,8 @@ static int __init gs_bind(struct usb_gadget *gadget)
1286 } 1281 }
1287 gs_device_desc.idProduct = __constant_cpu_to_le16( 1282 gs_device_desc.idProduct = __constant_cpu_to_le16(
1288 GS_CDC_PRODUCT_ID), 1283 GS_CDC_PRODUCT_ID),
1289 EP_NOTIFY_NAME = ep->name; 1284 dev->dev_notify_ep = ep;
1290 ep->driver_data = ep; /* claim the endpoint */ 1285 ep->driver_data = dev; /* claim the endpoint */
1291 } 1286 }
1292 1287
1293 gs_device_desc.bDeviceClass = use_acm 1288 gs_device_desc.bDeviceClass = use_acm
@@ -1317,9 +1312,7 @@ static int __init gs_bind(struct usb_gadget *gadget)
1317 gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; 1312 gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
1318 } 1313 }
1319 1314
1320 gs_device = dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL); 1315 gs_device = dev;
1321 if (dev == NULL)
1322 return -ENOMEM;
1323 1316
1324 snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", 1317 snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
1325 init_utsname()->sysname, init_utsname()->release, 1318 init_utsname()->sysname, init_utsname()->release,
@@ -1351,6 +1344,7 @@ static int __init gs_bind(struct usb_gadget *gadget)
1351 return 0; 1344 return 0;
1352 1345
1353autoconf_fail: 1346autoconf_fail:
1347 kfree(dev);
1354 pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name); 1348 pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name);
1355 return -ENODEV; 1349 return -ENODEV;
1356} 1350}
@@ -1710,7 +1704,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config)
1710 int ret = 0; 1704 int ret = 0;
1711 struct usb_gadget *gadget = dev->dev_gadget; 1705 struct usb_gadget *gadget = dev->dev_gadget;
1712 struct usb_ep *ep; 1706 struct usb_ep *ep;
1713 struct usb_endpoint_descriptor *ep_desc; 1707 struct usb_endpoint_descriptor *out, *in, *notify;
1714 struct usb_request *req; 1708 struct usb_request *req;
1715 1709
1716 if (dev == NULL) { 1710 if (dev == NULL) {
@@ -1738,71 +1732,53 @@ static int gs_set_config(struct gs_dev *dev, unsigned config)
1738 return -EINVAL; 1732 return -EINVAL;
1739 } 1733 }
1740 1734
1741 dev->dev_config = config; 1735 in = choose_ep_desc(gadget,
1742 1736 &gs_highspeed_in_desc,
1743 gadget_for_each_ep(ep, gadget) { 1737 &gs_fullspeed_in_desc);
1744 1738 out = choose_ep_desc(gadget,
1745 if (EP_NOTIFY_NAME 1739 &gs_highspeed_out_desc,
1746 && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { 1740 &gs_fullspeed_out_desc);
1747 ep_desc = choose_ep_desc(gadget, 1741 notify = dev->dev_notify_ep
1742 ? choose_ep_desc(gadget,
1748 &gs_highspeed_notify_desc, 1743 &gs_highspeed_notify_desc,
1749 &gs_fullspeed_notify_desc); 1744 &gs_fullspeed_notify_desc)
1750 ret = usb_ep_enable(ep,ep_desc); 1745 : NULL;
1751 if (ret == 0) {
1752 ep->driver_data = dev;
1753 dev->dev_notify_ep = ep;
1754 dev->dev_notify_ep_desc = ep_desc;
1755 } else {
1756 pr_err("gs_set_config: cannot enable NOTIFY "
1757 "endpoint %s, ret=%d\n",
1758 ep->name, ret);
1759 goto exit_reset_config;
1760 }
1761 }
1762 1746
1763 else if (strcmp(ep->name, EP_IN_NAME) == 0) { 1747 ret = usb_ep_enable(dev->dev_in_ep, in);
1764 ep_desc = choose_ep_desc(gadget, 1748 if (ret == 0) {
1765 &gs_highspeed_in_desc, 1749 dev->dev_in_ep_desc = in;
1766 &gs_fullspeed_in_desc); 1750 } else {
1767 ret = usb_ep_enable(ep,ep_desc); 1751 pr_debug("%s: cannot enable %s %s, ret=%d\n",
1768 if (ret == 0) { 1752 __func__, "IN", dev->dev_in_ep->name, ret);
1769 ep->driver_data = dev; 1753 return ret;
1770 dev->dev_in_ep = ep; 1754 }
1771 dev->dev_in_ep_desc = ep_desc;
1772 } else {
1773 pr_err("gs_set_config: cannot enable IN "
1774 "endpoint %s, ret=%d\n",
1775 ep->name, ret);
1776 goto exit_reset_config;
1777 }
1778 }
1779
1780 else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
1781 ep_desc = choose_ep_desc(gadget,
1782 &gs_highspeed_out_desc,
1783 &gs_fullspeed_out_desc);
1784 ret = usb_ep_enable(ep,ep_desc);
1785 if (ret == 0) {
1786 ep->driver_data = dev;
1787 dev->dev_out_ep = ep;
1788 dev->dev_out_ep_desc = ep_desc;
1789 } else {
1790 pr_err("gs_set_config: cannot enable OUT "
1791 "endpoint %s, ret=%d\n",
1792 ep->name, ret);
1793 goto exit_reset_config;
1794 }
1795 }
1796 1755
1756 ret = usb_ep_enable(dev->dev_out_ep, out);
1757 if (ret == 0) {
1758 dev->dev_out_ep_desc = out;
1759 } else {
1760 pr_debug("%s: cannot enable %s %s, ret=%d\n",
1761 __func__, "OUT", dev->dev_out_ep->name, ret);
1762fail0:
1763 usb_ep_disable(dev->dev_in_ep);
1764 return ret;
1797 } 1765 }
1798 1766
1799 if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL 1767 if (notify) {
1800 || (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) { 1768 ret = usb_ep_enable(dev->dev_notify_ep, notify);
1801 pr_err("gs_set_config: cannot find endpoints\n"); 1769 if (ret == 0) {
1802 ret = -ENODEV; 1770 dev->dev_notify_ep_desc = notify;
1803 goto exit_reset_config; 1771 } else {
1772 pr_debug("%s: cannot enable %s %s, ret=%d\n",
1773 __func__, "NOTIFY",
1774 dev->dev_notify_ep->name, ret);
1775 usb_ep_disable(dev->dev_out_ep);
1776 goto fail0;
1777 }
1804 } 1778 }
1805 1779
1780 dev->dev_config = config;
1781
1806 /* allocate and queue read requests */ 1782 /* allocate and queue read requests */
1807 ep = dev->dev_out_ep; 1783 ep = dev->dev_out_ep;
1808 for (i=0; i<read_q_size && ret == 0; i++) { 1784 for (i=0; i<read_q_size && ret == 0; i++) {
@@ -1886,18 +1862,10 @@ static void gs_reset_config(struct gs_dev *dev)
1886 1862
1887 /* disable endpoints, forcing completion of pending i/o; */ 1863 /* disable endpoints, forcing completion of pending i/o; */
1888 /* completion handlers free their requests in this case */ 1864 /* completion handlers free their requests in this case */
1889 if (dev->dev_notify_ep) { 1865 if (dev->dev_notify_ep)
1890 usb_ep_disable(dev->dev_notify_ep); 1866 usb_ep_disable(dev->dev_notify_ep);
1891 dev->dev_notify_ep = NULL; 1867 usb_ep_disable(dev->dev_in_ep);
1892 } 1868 usb_ep_disable(dev->dev_out_ep);
1893 if (dev->dev_in_ep) {
1894 usb_ep_disable(dev->dev_in_ep);
1895 dev->dev_in_ep = NULL;
1896 }
1897 if (dev->dev_out_ep) {
1898 usb_ep_disable(dev->dev_out_ep);
1899 dev->dev_out_ep = NULL;
1900 }
1901} 1869}
1902 1870
1903/* 1871/*