aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_ncm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 17:48:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 17:48:20 -0500
commit414a6750e59b0b687034764c464e9ddecac0f7a6 (patch)
tree18a5ceb11359cd72fcb2d31b5eabf3e35328697f /drivers/usb/gadget/f_ncm.c
parentc6bd5bcc4983f1a2d2f87a3769bf309482ee8c04 (diff)
parentfb37ef98015f864d22be223a0e0d93547cd1d4ef (diff)
Merge tag 'usb-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg Kroah-Hartman: "Here's the big set of USB patches for 3.8-rc1. Lots of USB host driver cleanups in here, and a bit of a reorg of the EHCI driver to make it easier for the different EHCI platform drivers to all work together nicer, which was a reduction in overall code. We also deleted some unused firmware files, and got rid of the very old file_storage usb gadget driver that had been broken for a long time. This means we ended up removing way more code than added, always a nice thing to see: 310 files changed, 3028 insertions(+), 10754 deletions(-) Other than that, the usual set of new device ids, driver fixes, gadget driver and controller updates and the like. All of these have been in the linux-next tree for a number of weeks. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'usb-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (228 commits) USB: mark uas driver as BROKEN xhci: Add Lynx Point LP to list of Intel switchable hosts uwb: fix uwb_dev_unlock() missed at an error path in uwb_rc_cmd_async() USB: ftdi_sio: Add support for Newport AGILIS motor drivers MAINTAINERS: remove drivers/block/ub.c USB: chipidea: fix use after free bug ezusb: add dependency to USB usb: ftdi_sio: fixup BeagleBone A5+ quirk USB: cp210x: add Virtenio Preon32 device id usb: storage: remove redundant memset() in usb_probe_stor1() USB: option: blacklist network interface on Huawei E173 USB: OHCI: workaround for hardware bug: retired TDs not added to the Done Queue USB: add new zte 3g-dongle's pid to option.c USB: opticon: switch to generic read implementation USB: opticon: refactor reab-urb processing USB: opticon: use usb-serial bulk-in urb USB: opticon: increase bulk-in size USB: opticon: use port as urb context USB: opticon: pass port to get_serial_info USB: opticon: make private data port specific ...
Diffstat (limited to 'drivers/usb/gadget/f_ncm.c')
-rw-r--r--drivers/usb/gadget/f_ncm.c94
1 files changed, 31 insertions, 63 deletions
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
index b651b529c67f..6c8362f937be 100644
--- a/drivers/usb/gadget/f_ncm.c
+++ b/drivers/usb/gadget/f_ncm.c
@@ -102,7 +102,7 @@ static inline unsigned ncm_bitrate(struct usb_gadget *g)
102 USB_CDC_NCM_NTB32_SUPPORTED) 102 USB_CDC_NCM_NTB32_SUPPORTED)
103 103
104static struct usb_cdc_ncm_ntb_parameters ntb_parameters = { 104static struct usb_cdc_ncm_ntb_parameters ntb_parameters = {
105 .wLength = sizeof ntb_parameters, 105 .wLength = cpu_to_le16(sizeof(ntb_parameters)),
106 .bmNtbFormatsSupported = cpu_to_le16(FORMATS_SUPPORTED), 106 .bmNtbFormatsSupported = cpu_to_le16(FORMATS_SUPPORTED),
107 .dwNtbInMaxSize = cpu_to_le32(NTB_DEFAULT_IN_SIZE), 107 .dwNtbInMaxSize = cpu_to_le32(NTB_DEFAULT_IN_SIZE),
108 .wNdpInDivisor = cpu_to_le16(4), 108 .wNdpInDivisor = cpu_to_le16(4),
@@ -121,7 +121,7 @@ static struct usb_cdc_ncm_ntb_parameters ntb_parameters = {
121 * waste less bandwidth. 121 * waste less bandwidth.
122 */ 122 */
123 123
124#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ 124#define NCM_STATUS_INTERVAL_MS 32
125#define NCM_STATUS_BYTECOUNT 16 /* 8 byte header + data */ 125#define NCM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
126 126
127static struct usb_interface_assoc_descriptor ncm_iad_desc __initdata = { 127static struct usb_interface_assoc_descriptor ncm_iad_desc __initdata = {
@@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor fs_ncm_notify_desc __initdata = {
230 .bEndpointAddress = USB_DIR_IN, 230 .bEndpointAddress = USB_DIR_IN,
231 .bmAttributes = USB_ENDPOINT_XFER_INT, 231 .bmAttributes = USB_ENDPOINT_XFER_INT,
232 .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT), 232 .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT),
233 .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, 233 .bInterval = NCM_STATUS_INTERVAL_MS,
234}; 234};
235 235
236static struct usb_endpoint_descriptor fs_ncm_in_desc __initdata = { 236static struct usb_endpoint_descriptor fs_ncm_in_desc __initdata = {
@@ -275,7 +275,7 @@ static struct usb_endpoint_descriptor hs_ncm_notify_desc __initdata = {
275 .bEndpointAddress = USB_DIR_IN, 275 .bEndpointAddress = USB_DIR_IN,
276 .bmAttributes = USB_ENDPOINT_XFER_INT, 276 .bmAttributes = USB_ENDPOINT_XFER_INT,
277 .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT), 277 .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT),
278 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, 278 .bInterval = USB_MS_TO_HS_INTERVAL(NCM_STATUS_INTERVAL_MS),
279}; 279};
280static struct usb_endpoint_descriptor hs_ncm_in_desc __initdata = { 280static struct usb_endpoint_descriptor hs_ncm_in_desc __initdata = {
281 .bLength = USB_DT_ENDPOINT_SIZE, 281 .bLength = USB_DT_ENDPOINT_SIZE,
@@ -321,7 +321,7 @@ static struct usb_descriptor_header *ncm_hs_function[] __initdata = {
321 321
322static struct usb_string ncm_string_defs[] = { 322static struct usb_string ncm_string_defs[] = {
323 [STRING_CTRL_IDX].s = "CDC Network Control Model (NCM)", 323 [STRING_CTRL_IDX].s = "CDC Network Control Model (NCM)",
324 [STRING_MAC_IDX].s = NULL /* DYNAMIC */, 324 [STRING_MAC_IDX].s = "",
325 [STRING_DATA_IDX].s = "CDC Network Data", 325 [STRING_DATA_IDX].s = "CDC Network Data",
326 [STRING_IAD_IDX].s = "CDC NCM", 326 [STRING_IAD_IDX].s = "CDC NCM",
327 { } /* end of list */ 327 { } /* end of list */
@@ -869,15 +869,19 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port,
869 struct sk_buff *skb2; 869 struct sk_buff *skb2;
870 int ncb_len = 0; 870 int ncb_len = 0;
871 __le16 *tmp; 871 __le16 *tmp;
872 int div = ntb_parameters.wNdpInDivisor; 872 int div;
873 int rem = ntb_parameters.wNdpInPayloadRemainder; 873 int rem;
874 int pad; 874 int pad;
875 int ndp_align = ntb_parameters.wNdpInAlignment; 875 int ndp_align;
876 int ndp_pad; 876 int ndp_pad;
877 unsigned max_size = ncm->port.fixed_in_len; 877 unsigned max_size = ncm->port.fixed_in_len;
878 struct ndp_parser_opts *opts = ncm->parser_opts; 878 struct ndp_parser_opts *opts = ncm->parser_opts;
879 unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; 879 unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0;
880 880
881 div = le16_to_cpu(ntb_parameters.wNdpInDivisor);
882 rem = le16_to_cpu(ntb_parameters.wNdpInPayloadRemainder);
883 ndp_align = le16_to_cpu(ntb_parameters.wNdpInAlignment);
884
881 ncb_len += opts->nth_size; 885 ncb_len += opts->nth_size;
882 ndp_pad = ALIGN(ncb_len, ndp_align) - ncb_len; 886 ndp_pad = ALIGN(ncb_len, ndp_align) - ncb_len;
883 ncb_len += ndp_pad; 887 ncb_len += ndp_pad;
@@ -1208,30 +1212,18 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f)
1208 ncm->notify_req->context = ncm; 1212 ncm->notify_req->context = ncm;
1209 ncm->notify_req->complete = ncm_notify_complete; 1213 ncm->notify_req->complete = ncm_notify_complete;
1210 1214
1211 /* copy descriptors, and track endpoint copies */
1212 f->descriptors = usb_copy_descriptors(ncm_fs_function);
1213 if (!f->descriptors)
1214 goto fail;
1215
1216 /* 1215 /*
1217 * support all relevant hardware speeds... we expect that when 1216 * support all relevant hardware speeds... we expect that when
1218 * hardware is dual speed, all bulk-capable endpoints work at 1217 * hardware is dual speed, all bulk-capable endpoints work at
1219 * both speeds 1218 * both speeds
1220 */ 1219 */
1221 if (gadget_is_dualspeed(c->cdev->gadget)) { 1220 hs_ncm_in_desc.bEndpointAddress = fs_ncm_in_desc.bEndpointAddress;
1222 hs_ncm_in_desc.bEndpointAddress = 1221 hs_ncm_out_desc.bEndpointAddress = fs_ncm_out_desc.bEndpointAddress;
1223 fs_ncm_in_desc.bEndpointAddress; 1222 hs_ncm_notify_desc.bEndpointAddress =
1224 hs_ncm_out_desc.bEndpointAddress = 1223 fs_ncm_notify_desc.bEndpointAddress;
1225 fs_ncm_out_desc.bEndpointAddress;
1226 hs_ncm_notify_desc.bEndpointAddress =
1227 fs_ncm_notify_desc.bEndpointAddress;
1228
1229 /* copy descriptors, and track endpoint copies */
1230 f->hs_descriptors = usb_copy_descriptors(ncm_hs_function);
1231 if (!f->hs_descriptors)
1232 goto fail;
1233 }
1234 1224
1225 status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function,
1226 NULL);
1235 /* 1227 /*
1236 * NOTE: all that is done without knowing or caring about 1228 * NOTE: all that is done without knowing or caring about
1237 * the network link ... which is unavailable to this code 1229 * the network link ... which is unavailable to this code
@@ -1248,9 +1240,7 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f)
1248 return 0; 1240 return 0;
1249 1241
1250fail: 1242fail:
1251 if (f->descriptors) 1243 usb_free_all_descriptors(f);
1252 usb_free_descriptors(f->descriptors);
1253
1254 if (ncm->notify_req) { 1244 if (ncm->notify_req) {
1255 kfree(ncm->notify_req->buf); 1245 kfree(ncm->notify_req->buf);
1256 usb_ep_free_request(ncm->notify, ncm->notify_req); 1246 usb_ep_free_request(ncm->notify, ncm->notify_req);
@@ -1259,9 +1249,9 @@ fail:
1259 /* we might as well release our claims on endpoints */ 1249 /* we might as well release our claims on endpoints */
1260 if (ncm->notify) 1250 if (ncm->notify)
1261 ncm->notify->driver_data = NULL; 1251 ncm->notify->driver_data = NULL;
1262 if (ncm->port.out_ep->desc) 1252 if (ncm->port.out_ep)
1263 ncm->port.out_ep->driver_data = NULL; 1253 ncm->port.out_ep->driver_data = NULL;
1264 if (ncm->port.in_ep->desc) 1254 if (ncm->port.in_ep)
1265 ncm->port.in_ep->driver_data = NULL; 1255 ncm->port.in_ep->driver_data = NULL;
1266 1256
1267 ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); 1257 ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
@@ -1276,14 +1266,12 @@ ncm_unbind(struct usb_configuration *c, struct usb_function *f)
1276 1266
1277 DBG(c->cdev, "ncm unbind\n"); 1267 DBG(c->cdev, "ncm unbind\n");
1278 1268
1279 if (gadget_is_dualspeed(c->cdev->gadget)) 1269 ncm_string_defs[0].id = 0;
1280 usb_free_descriptors(f->hs_descriptors); 1270 usb_free_all_descriptors(f);
1281 usb_free_descriptors(f->descriptors);
1282 1271
1283 kfree(ncm->notify_req->buf); 1272 kfree(ncm->notify_req->buf);
1284 usb_ep_free_request(ncm->notify, ncm->notify_req); 1273 usb_ep_free_request(ncm->notify, ncm->notify_req);
1285 1274
1286 ncm_string_defs[1].s = NULL;
1287 kfree(ncm); 1275 kfree(ncm);
1288} 1276}
1289 1277
@@ -1307,37 +1295,19 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
1307 if (!can_support_ecm(c->cdev->gadget) || !ethaddr) 1295 if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
1308 return -EINVAL; 1296 return -EINVAL;
1309 1297
1310 /* maybe allocate device-global string IDs */
1311 if (ncm_string_defs[0].id == 0) { 1298 if (ncm_string_defs[0].id == 0) {
1312 1299 status = usb_string_ids_tab(c->cdev, ncm_string_defs);
1313 /* control interface label */
1314 status = usb_string_id(c->cdev);
1315 if (status < 0) 1300 if (status < 0)
1316 return status; 1301 return status;
1317 ncm_string_defs[STRING_CTRL_IDX].id = status; 1302 ncm_control_intf.iInterface =
1318 ncm_control_intf.iInterface = status; 1303 ncm_string_defs[STRING_CTRL_IDX].id;
1319 1304
1320 /* data interface label */ 1305 status = ncm_string_defs[STRING_DATA_IDX].id;
1321 status = usb_string_id(c->cdev);
1322 if (status < 0)
1323 return status;
1324 ncm_string_defs[STRING_DATA_IDX].id = status;
1325 ncm_data_nop_intf.iInterface = status; 1306 ncm_data_nop_intf.iInterface = status;
1326 ncm_data_intf.iInterface = status; 1307 ncm_data_intf.iInterface = status;
1327 1308
1328 /* MAC address */ 1309 ecm_desc.iMACAddress = ncm_string_defs[STRING_MAC_IDX].id;
1329 status = usb_string_id(c->cdev); 1310 ncm_iad_desc.iFunction = ncm_string_defs[STRING_IAD_IDX].id;
1330 if (status < 0)
1331 return status;
1332 ncm_string_defs[STRING_MAC_IDX].id = status;
1333 ecm_desc.iMACAddress = status;
1334
1335 /* IAD */
1336 status = usb_string_id(c->cdev);
1337 if (status < 0)
1338 return status;
1339 ncm_string_defs[STRING_IAD_IDX].id = status;
1340 ncm_iad_desc.iFunction = status;
1341 } 1311 }
1342 1312
1343 /* allocate and initialize one new instance */ 1313 /* allocate and initialize one new instance */
@@ -1347,7 +1317,7 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
1347 1317
1348 /* export host's Ethernet address in CDC format */ 1318 /* export host's Ethernet address in CDC format */
1349 snprintf(ncm->ethaddr, sizeof ncm->ethaddr, "%pm", ethaddr); 1319 snprintf(ncm->ethaddr, sizeof ncm->ethaddr, "%pm", ethaddr);
1350 ncm_string_defs[1].s = ncm->ethaddr; 1320 ncm_string_defs[STRING_MAC_IDX].s = ncm->ethaddr;
1351 1321
1352 spin_lock_init(&ncm->lock); 1322 spin_lock_init(&ncm->lock);
1353 ncm_reset_values(ncm); 1323 ncm_reset_values(ncm);
@@ -1367,9 +1337,7 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
1367 ncm->port.unwrap = ncm_unwrap_ntb; 1337 ncm->port.unwrap = ncm_unwrap_ntb;
1368 1338
1369 status = usb_add_function(c, &ncm->port.func); 1339 status = usb_add_function(c, &ncm->port.func);
1370 if (status) { 1340 if (status)
1371 ncm_string_defs[1].s = NULL;
1372 kfree(ncm); 1341 kfree(ncm);
1373 }
1374 return status; 1342 return status;
1375} 1343}