diff options
Diffstat (limited to 'drivers/usb/gadget/f_subset.c')
-rw-r--r-- | drivers/usb/gadget/f_subset.c | 75 |
1 files changed, 20 insertions, 55 deletions
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index 4060c0bd9785..f172bd152fbb 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c | |||
@@ -236,7 +236,7 @@ static struct usb_descriptor_header *ss_eth_function[] = { | |||
236 | 236 | ||
237 | static struct usb_string geth_string_defs[] = { | 237 | static struct usb_string geth_string_defs[] = { |
238 | [0].s = "CDC Ethernet Subset/SAFE", | 238 | [0].s = "CDC Ethernet Subset/SAFE", |
239 | [1].s = NULL /* DYNAMIC */, | 239 | [1].s = "", |
240 | { } /* end of list */ | 240 | { } /* end of list */ |
241 | }; | 241 | }; |
242 | 242 | ||
@@ -319,38 +319,22 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) | |||
319 | geth->port.out_ep = ep; | 319 | geth->port.out_ep = ep; |
320 | ep->driver_data = cdev; /* claim */ | 320 | ep->driver_data = cdev; /* claim */ |
321 | 321 | ||
322 | /* copy descriptors, and track endpoint copies */ | ||
323 | f->descriptors = usb_copy_descriptors(fs_eth_function); | ||
324 | if (!f->descriptors) | ||
325 | goto fail; | ||
326 | |||
327 | /* support all relevant hardware speeds... we expect that when | 322 | /* support all relevant hardware speeds... we expect that when |
328 | * hardware is dual speed, all bulk-capable endpoints work at | 323 | * hardware is dual speed, all bulk-capable endpoints work at |
329 | * both speeds | 324 | * both speeds |
330 | */ | 325 | */ |
331 | if (gadget_is_dualspeed(c->cdev->gadget)) { | 326 | hs_subset_in_desc.bEndpointAddress = fs_subset_in_desc.bEndpointAddress; |
332 | hs_subset_in_desc.bEndpointAddress = | 327 | hs_subset_out_desc.bEndpointAddress = |
333 | fs_subset_in_desc.bEndpointAddress; | 328 | fs_subset_out_desc.bEndpointAddress; |
334 | hs_subset_out_desc.bEndpointAddress = | ||
335 | fs_subset_out_desc.bEndpointAddress; | ||
336 | |||
337 | /* copy descriptors, and track endpoint copies */ | ||
338 | f->hs_descriptors = usb_copy_descriptors(hs_eth_function); | ||
339 | if (!f->hs_descriptors) | ||
340 | goto fail; | ||
341 | } | ||
342 | 329 | ||
343 | if (gadget_is_superspeed(c->cdev->gadget)) { | 330 | ss_subset_in_desc.bEndpointAddress = fs_subset_in_desc.bEndpointAddress; |
344 | ss_subset_in_desc.bEndpointAddress = | 331 | ss_subset_out_desc.bEndpointAddress = |
345 | fs_subset_in_desc.bEndpointAddress; | 332 | fs_subset_out_desc.bEndpointAddress; |
346 | ss_subset_out_desc.bEndpointAddress = | ||
347 | fs_subset_out_desc.bEndpointAddress; | ||
348 | 333 | ||
349 | /* copy descriptors, and track endpoint copies */ | 334 | status = usb_assign_descriptors(f, fs_eth_function, hs_eth_function, |
350 | f->ss_descriptors = usb_copy_descriptors(ss_eth_function); | 335 | ss_eth_function); |
351 | if (!f->ss_descriptors) | 336 | if (status) |
352 | goto fail; | 337 | goto fail; |
353 | } | ||
354 | 338 | ||
355 | /* NOTE: all that is done without knowing or caring about | 339 | /* NOTE: all that is done without knowing or caring about |
356 | * the network link ... which is unavailable to this code | 340 | * the network link ... which is unavailable to this code |
@@ -364,15 +348,11 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) | |||
364 | return 0; | 348 | return 0; |
365 | 349 | ||
366 | fail: | 350 | fail: |
367 | if (f->descriptors) | 351 | usb_free_all_descriptors(f); |
368 | usb_free_descriptors(f->descriptors); | ||
369 | if (f->hs_descriptors) | ||
370 | usb_free_descriptors(f->hs_descriptors); | ||
371 | |||
372 | /* we might as well release our claims on endpoints */ | 352 | /* we might as well release our claims on endpoints */ |
373 | if (geth->port.out_ep->desc) | 353 | if (geth->port.out_ep) |
374 | geth->port.out_ep->driver_data = NULL; | 354 | geth->port.out_ep->driver_data = NULL; |
375 | if (geth->port.in_ep->desc) | 355 | if (geth->port.in_ep) |
376 | geth->port.in_ep->driver_data = NULL; | 356 | geth->port.in_ep->driver_data = NULL; |
377 | 357 | ||
378 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | 358 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); |
@@ -383,12 +363,8 @@ fail: | |||
383 | static void | 363 | static void |
384 | geth_unbind(struct usb_configuration *c, struct usb_function *f) | 364 | geth_unbind(struct usb_configuration *c, struct usb_function *f) |
385 | { | 365 | { |
386 | if (gadget_is_superspeed(c->cdev->gadget)) | 366 | geth_string_defs[0].id = 0; |
387 | usb_free_descriptors(f->ss_descriptors); | 367 | usb_free_all_descriptors(f); |
388 | if (gadget_is_dualspeed(c->cdev->gadget)) | ||
389 | usb_free_descriptors(f->hs_descriptors); | ||
390 | usb_free_descriptors(f->descriptors); | ||
391 | geth_string_defs[1].s = NULL; | ||
392 | kfree(func_to_geth(f)); | 368 | kfree(func_to_geth(f)); |
393 | } | 369 | } |
394 | 370 | ||
@@ -414,20 +390,11 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) | |||
414 | 390 | ||
415 | /* maybe allocate device-global string IDs */ | 391 | /* maybe allocate device-global string IDs */ |
416 | if (geth_string_defs[0].id == 0) { | 392 | if (geth_string_defs[0].id == 0) { |
417 | 393 | status = usb_string_ids_tab(c->cdev, geth_string_defs); | |
418 | /* interface label */ | ||
419 | status = usb_string_id(c->cdev); | ||
420 | if (status < 0) | 394 | if (status < 0) |
421 | return status; | 395 | return status; |
422 | geth_string_defs[0].id = status; | 396 | subset_data_intf.iInterface = geth_string_defs[0].id; |
423 | subset_data_intf.iInterface = status; | 397 | ether_desc.iMACAddress = geth_string_defs[1].id; |
424 | |||
425 | /* MAC address */ | ||
426 | status = usb_string_id(c->cdev); | ||
427 | if (status < 0) | ||
428 | return status; | ||
429 | geth_string_defs[1].id = status; | ||
430 | ether_desc.iMACAddress = status; | ||
431 | } | 398 | } |
432 | 399 | ||
433 | /* allocate and initialize one new instance */ | 400 | /* allocate and initialize one new instance */ |
@@ -449,9 +416,7 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) | |||
449 | geth->port.func.disable = geth_disable; | 416 | geth->port.func.disable = geth_disable; |
450 | 417 | ||
451 | status = usb_add_function(c, &geth->port.func); | 418 | status = usb_add_function(c, &geth->port.func); |
452 | if (status) { | 419 | if (status) |
453 | geth_string_defs[1].s = NULL; | ||
454 | kfree(geth); | 420 | kfree(geth); |
455 | } | ||
456 | return status; | 421 | return status; |
457 | } | 422 | } |