diff options
Diffstat (limited to 'sound/usb/card.c')
-rw-r--r-- | sound/usb/card.c | 226 |
1 files changed, 126 insertions, 100 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c index 4a1c6bb3dfa0..a1ed798a1c6b 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -86,6 +86,8 @@ static bool ignore_ctl_error; | |||
86 | static bool autoclock = true; | 86 | static bool autoclock = true; |
87 | static char *quirk_alias[SNDRV_CARDS]; | 87 | static char *quirk_alias[SNDRV_CARDS]; |
88 | 88 | ||
89 | bool snd_usb_use_vmalloc = true; | ||
90 | |||
89 | module_param_array(index, int, NULL, 0444); | 91 | module_param_array(index, int, NULL, 0444); |
90 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); | 92 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); |
91 | module_param_array(id, charp, NULL, 0444); | 93 | module_param_array(id, charp, NULL, 0444); |
@@ -105,6 +107,8 @@ module_param(autoclock, bool, 0444); | |||
105 | MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes)."); | 107 | MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes)."); |
106 | module_param_array(quirk_alias, charp, NULL, 0444); | 108 | module_param_array(quirk_alias, charp, NULL, 0444); |
107 | MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef."); | 109 | MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef."); |
110 | module_param_named(use_vmalloc, snd_usb_use_vmalloc, bool, 0444); | ||
111 | MODULE_PARM_DESC(use_vmalloc, "Use vmalloc for PCM intermediate buffers (default: yes)."); | ||
108 | 112 | ||
109 | /* | 113 | /* |
110 | * we keep the snd_usb_audio_t instances by ourselves for merging | 114 | * we keep the snd_usb_audio_t instances by ourselves for merging |
@@ -221,32 +225,13 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
221 | struct usb_device *dev = chip->dev; | 225 | struct usb_device *dev = chip->dev; |
222 | struct usb_host_interface *host_iface; | 226 | struct usb_host_interface *host_iface; |
223 | struct usb_interface_descriptor *altsd; | 227 | struct usb_interface_descriptor *altsd; |
224 | void *control_header; | ||
225 | int i, protocol; | 228 | int i, protocol; |
226 | int rest_bytes; | ||
227 | 229 | ||
228 | /* find audiocontrol interface */ | 230 | /* find audiocontrol interface */ |
229 | host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; | 231 | host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; |
230 | control_header = snd_usb_find_csint_desc(host_iface->extra, | ||
231 | host_iface->extralen, | ||
232 | NULL, UAC_HEADER); | ||
233 | altsd = get_iface_desc(host_iface); | 232 | altsd = get_iface_desc(host_iface); |
234 | protocol = altsd->bInterfaceProtocol; | 233 | protocol = altsd->bInterfaceProtocol; |
235 | 234 | ||
236 | if (!control_header) { | ||
237 | dev_err(&dev->dev, "cannot find UAC_HEADER\n"); | ||
238 | return -EINVAL; | ||
239 | } | ||
240 | |||
241 | rest_bytes = (void *)(host_iface->extra + host_iface->extralen) - | ||
242 | control_header; | ||
243 | |||
244 | /* just to be sure -- this shouldn't hit at all */ | ||
245 | if (rest_bytes <= 0) { | ||
246 | dev_err(&dev->dev, "invalid control header\n"); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | |||
250 | switch (protocol) { | 235 | switch (protocol) { |
251 | default: | 236 | default: |
252 | dev_warn(&dev->dev, | 237 | dev_warn(&dev->dev, |
@@ -255,7 +240,25 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
255 | /* fall through */ | 240 | /* fall through */ |
256 | 241 | ||
257 | case UAC_VERSION_1: { | 242 | case UAC_VERSION_1: { |
258 | struct uac1_ac_header_descriptor *h1 = control_header; | 243 | struct uac1_ac_header_descriptor *h1; |
244 | int rest_bytes; | ||
245 | |||
246 | h1 = snd_usb_find_csint_desc(host_iface->extra, | ||
247 | host_iface->extralen, | ||
248 | NULL, UAC_HEADER); | ||
249 | if (!h1) { | ||
250 | dev_err(&dev->dev, "cannot find UAC_HEADER\n"); | ||
251 | return -EINVAL; | ||
252 | } | ||
253 | |||
254 | rest_bytes = (void *)(host_iface->extra + | ||
255 | host_iface->extralen) - (void *)h1; | ||
256 | |||
257 | /* just to be sure -- this shouldn't hit at all */ | ||
258 | if (rest_bytes <= 0) { | ||
259 | dev_err(&dev->dev, "invalid control header\n"); | ||
260 | return -EINVAL; | ||
261 | } | ||
259 | 262 | ||
260 | if (rest_bytes < sizeof(*h1)) { | 263 | if (rest_bytes < sizeof(*h1)) { |
261 | dev_err(&dev->dev, "too short v1 buffer descriptor\n"); | 264 | dev_err(&dev->dev, "too short v1 buffer descriptor\n"); |
@@ -308,6 +311,20 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
308 | return -EINVAL; | 311 | return -EINVAL; |
309 | } | 312 | } |
310 | 313 | ||
314 | if (protocol == UAC_VERSION_3) { | ||
315 | int badd = assoc->bFunctionSubClass; | ||
316 | |||
317 | if (badd != UAC3_FUNCTION_SUBCLASS_FULL_ADC_3_0 && | ||
318 | (badd < UAC3_FUNCTION_SUBCLASS_GENERIC_IO || | ||
319 | badd > UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE)) { | ||
320 | dev_err(&dev->dev, | ||
321 | "Unsupported UAC3 BADD profile\n"); | ||
322 | return -EINVAL; | ||
323 | } | ||
324 | |||
325 | chip->badd_profile = badd; | ||
326 | } | ||
327 | |||
311 | for (i = 0; i < assoc->bInterfaceCount; i++) { | 328 | for (i = 0; i < assoc->bInterfaceCount; i++) { |
312 | int intf = assoc->bFirstInterface + i; | 329 | int intf = assoc->bFirstInterface + i; |
313 | 330 | ||
@@ -329,8 +346,9 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
329 | * | 346 | * |
330 | */ | 347 | */ |
331 | 348 | ||
332 | static int snd_usb_audio_free(struct snd_usb_audio *chip) | 349 | static void snd_usb_audio_free(struct snd_card *card) |
333 | { | 350 | { |
351 | struct snd_usb_audio *chip = card->private_data; | ||
334 | struct snd_usb_endpoint *ep, *n; | 352 | struct snd_usb_endpoint *ep, *n; |
335 | 353 | ||
336 | list_for_each_entry_safe(ep, n, &chip->ep_list, list) | 354 | list_for_each_entry_safe(ep, n, &chip->ep_list, list) |
@@ -339,14 +357,90 @@ static int snd_usb_audio_free(struct snd_usb_audio *chip) | |||
339 | mutex_destroy(&chip->mutex); | 357 | mutex_destroy(&chip->mutex); |
340 | if (!atomic_read(&chip->shutdown)) | 358 | if (!atomic_read(&chip->shutdown)) |
341 | dev_set_drvdata(&chip->dev->dev, NULL); | 359 | dev_set_drvdata(&chip->dev->dev, NULL); |
342 | kfree(chip); | ||
343 | return 0; | ||
344 | } | 360 | } |
345 | 361 | ||
346 | static int snd_usb_audio_dev_free(struct snd_device *device) | 362 | static void usb_audio_make_shortname(struct usb_device *dev, |
363 | struct snd_usb_audio *chip, | ||
364 | const struct snd_usb_audio_quirk *quirk) | ||
347 | { | 365 | { |
348 | struct snd_usb_audio *chip = device->device_data; | 366 | struct snd_card *card = chip->card; |
349 | return snd_usb_audio_free(chip); | 367 | |
368 | if (quirk && quirk->product_name && *quirk->product_name) { | ||
369 | strlcpy(card->shortname, quirk->product_name, | ||
370 | sizeof(card->shortname)); | ||
371 | return; | ||
372 | } | ||
373 | |||
374 | /* retrieve the device string as shortname */ | ||
375 | if (!dev->descriptor.iProduct || | ||
376 | usb_string(dev, dev->descriptor.iProduct, | ||
377 | card->shortname, sizeof(card->shortname)) <= 0) { | ||
378 | /* no name available from anywhere, so use ID */ | ||
379 | sprintf(card->shortname, "USB Device %#04x:%#04x", | ||
380 | USB_ID_VENDOR(chip->usb_id), | ||
381 | USB_ID_PRODUCT(chip->usb_id)); | ||
382 | } | ||
383 | |||
384 | strim(card->shortname); | ||
385 | } | ||
386 | |||
387 | static void usb_audio_make_longname(struct usb_device *dev, | ||
388 | struct snd_usb_audio *chip, | ||
389 | const struct snd_usb_audio_quirk *quirk) | ||
390 | { | ||
391 | struct snd_card *card = chip->card; | ||
392 | int len; | ||
393 | |||
394 | /* shortcut - if any pre-defined string is given, use it */ | ||
395 | if (quirk && quirk->profile_name && *quirk->profile_name) { | ||
396 | strlcpy(card->longname, quirk->profile_name, | ||
397 | sizeof(card->longname)); | ||
398 | return; | ||
399 | } | ||
400 | |||
401 | if (quirk && quirk->vendor_name && *quirk->vendor_name) { | ||
402 | len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname)); | ||
403 | } else { | ||
404 | /* retrieve the vendor and device strings as longname */ | ||
405 | if (dev->descriptor.iManufacturer) | ||
406 | len = usb_string(dev, dev->descriptor.iManufacturer, | ||
407 | card->longname, sizeof(card->longname)); | ||
408 | else | ||
409 | len = 0; | ||
410 | /* we don't really care if there isn't any vendor string */ | ||
411 | } | ||
412 | if (len > 0) { | ||
413 | strim(card->longname); | ||
414 | if (*card->longname) | ||
415 | strlcat(card->longname, " ", sizeof(card->longname)); | ||
416 | } | ||
417 | |||
418 | strlcat(card->longname, card->shortname, sizeof(card->longname)); | ||
419 | |||
420 | len = strlcat(card->longname, " at ", sizeof(card->longname)); | ||
421 | |||
422 | if (len < sizeof(card->longname)) | ||
423 | usb_make_path(dev, card->longname + len, sizeof(card->longname) - len); | ||
424 | |||
425 | switch (snd_usb_get_speed(dev)) { | ||
426 | case USB_SPEED_LOW: | ||
427 | strlcat(card->longname, ", low speed", sizeof(card->longname)); | ||
428 | break; | ||
429 | case USB_SPEED_FULL: | ||
430 | strlcat(card->longname, ", full speed", sizeof(card->longname)); | ||
431 | break; | ||
432 | case USB_SPEED_HIGH: | ||
433 | strlcat(card->longname, ", high speed", sizeof(card->longname)); | ||
434 | break; | ||
435 | case USB_SPEED_SUPER: | ||
436 | strlcat(card->longname, ", super speed", sizeof(card->longname)); | ||
437 | break; | ||
438 | case USB_SPEED_SUPER_PLUS: | ||
439 | strlcat(card->longname, ", super speed plus", sizeof(card->longname)); | ||
440 | break; | ||
441 | default: | ||
442 | break; | ||
443 | } | ||
350 | } | 444 | } |
351 | 445 | ||
352 | /* | 446 | /* |
@@ -360,11 +454,8 @@ static int snd_usb_audio_create(struct usb_interface *intf, | |||
360 | { | 454 | { |
361 | struct snd_card *card; | 455 | struct snd_card *card; |
362 | struct snd_usb_audio *chip; | 456 | struct snd_usb_audio *chip; |
363 | int err, len; | 457 | int err; |
364 | char component[14]; | 458 | char component[14]; |
365 | static struct snd_device_ops ops = { | ||
366 | .dev_free = snd_usb_audio_dev_free, | ||
367 | }; | ||
368 | 459 | ||
369 | *rchip = NULL; | 460 | *rchip = NULL; |
370 | 461 | ||
@@ -382,18 +473,13 @@ static int snd_usb_audio_create(struct usb_interface *intf, | |||
382 | } | 473 | } |
383 | 474 | ||
384 | err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE, | 475 | err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE, |
385 | 0, &card); | 476 | sizeof(*chip), &card); |
386 | if (err < 0) { | 477 | if (err < 0) { |
387 | dev_err(&dev->dev, "cannot create card instance %d\n", idx); | 478 | dev_err(&dev->dev, "cannot create card instance %d\n", idx); |
388 | return err; | 479 | return err; |
389 | } | 480 | } |
390 | 481 | ||
391 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 482 | chip = card->private_data; |
392 | if (! chip) { | ||
393 | snd_card_free(card); | ||
394 | return -ENOMEM; | ||
395 | } | ||
396 | |||
397 | mutex_init(&chip->mutex); | 483 | mutex_init(&chip->mutex); |
398 | init_waitqueue_head(&chip->shutdown_wait); | 484 | init_waitqueue_head(&chip->shutdown_wait); |
399 | chip->index = idx; | 485 | chip->index = idx; |
@@ -411,75 +497,15 @@ static int snd_usb_audio_create(struct usb_interface *intf, | |||
411 | INIT_LIST_HEAD(&chip->midi_list); | 497 | INIT_LIST_HEAD(&chip->midi_list); |
412 | INIT_LIST_HEAD(&chip->mixer_list); | 498 | INIT_LIST_HEAD(&chip->mixer_list); |
413 | 499 | ||
414 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | 500 | card->private_free = snd_usb_audio_free; |
415 | snd_usb_audio_free(chip); | ||
416 | snd_card_free(card); | ||
417 | return err; | ||
418 | } | ||
419 | 501 | ||
420 | strcpy(card->driver, "USB-Audio"); | 502 | strcpy(card->driver, "USB-Audio"); |
421 | sprintf(component, "USB%04x:%04x", | 503 | sprintf(component, "USB%04x:%04x", |
422 | USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id)); | 504 | USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id)); |
423 | snd_component_add(card, component); | 505 | snd_component_add(card, component); |
424 | 506 | ||
425 | /* retrieve the device string as shortname */ | 507 | usb_audio_make_shortname(dev, chip, quirk); |
426 | if (quirk && quirk->product_name && *quirk->product_name) { | 508 | usb_audio_make_longname(dev, chip, quirk); |
427 | strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname)); | ||
428 | } else { | ||
429 | if (!dev->descriptor.iProduct || | ||
430 | usb_string(dev, dev->descriptor.iProduct, | ||
431 | card->shortname, sizeof(card->shortname)) <= 0) { | ||
432 | /* no name available from anywhere, so use ID */ | ||
433 | sprintf(card->shortname, "USB Device %#04x:%#04x", | ||
434 | USB_ID_VENDOR(chip->usb_id), | ||
435 | USB_ID_PRODUCT(chip->usb_id)); | ||
436 | } | ||
437 | } | ||
438 | strim(card->shortname); | ||
439 | |||
440 | /* retrieve the vendor and device strings as longname */ | ||
441 | if (quirk && quirk->vendor_name && *quirk->vendor_name) { | ||
442 | len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname)); | ||
443 | } else { | ||
444 | if (dev->descriptor.iManufacturer) | ||
445 | len = usb_string(dev, dev->descriptor.iManufacturer, | ||
446 | card->longname, sizeof(card->longname)); | ||
447 | else | ||
448 | len = 0; | ||
449 | /* we don't really care if there isn't any vendor string */ | ||
450 | } | ||
451 | if (len > 0) { | ||
452 | strim(card->longname); | ||
453 | if (*card->longname) | ||
454 | strlcat(card->longname, " ", sizeof(card->longname)); | ||
455 | } | ||
456 | |||
457 | strlcat(card->longname, card->shortname, sizeof(card->longname)); | ||
458 | |||
459 | len = strlcat(card->longname, " at ", sizeof(card->longname)); | ||
460 | |||
461 | if (len < sizeof(card->longname)) | ||
462 | usb_make_path(dev, card->longname + len, sizeof(card->longname) - len); | ||
463 | |||
464 | switch (snd_usb_get_speed(dev)) { | ||
465 | case USB_SPEED_LOW: | ||
466 | strlcat(card->longname, ", low speed", sizeof(card->longname)); | ||
467 | break; | ||
468 | case USB_SPEED_FULL: | ||
469 | strlcat(card->longname, ", full speed", sizeof(card->longname)); | ||
470 | break; | ||
471 | case USB_SPEED_HIGH: | ||
472 | strlcat(card->longname, ", high speed", sizeof(card->longname)); | ||
473 | break; | ||
474 | case USB_SPEED_SUPER: | ||
475 | strlcat(card->longname, ", super speed", sizeof(card->longname)); | ||
476 | break; | ||
477 | case USB_SPEED_SUPER_PLUS: | ||
478 | strlcat(card->longname, ", super speed plus", sizeof(card->longname)); | ||
479 | break; | ||
480 | default: | ||
481 | break; | ||
482 | } | ||
483 | 509 | ||
484 | snd_usb_audio_create_proc(chip); | 510 | snd_usb_audio_create_proc(chip); |
485 | 511 | ||