diff options
Diffstat (limited to 'sound/usb/card.c')
| -rw-r--r-- | sound/usb/card.c | 114 | 
1 files changed, 62 insertions, 52 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c index 64952e2d3ed..a09e5f3519e 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -79,7 +79,6 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card *  /* Vendor/product IDs for this card */  static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };  static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; -static int nrpacks = 8;		/* max. number of packets per urb */  static int device_setup[SNDRV_CARDS]; /* device parameter for this card */  static bool ignore_ctl_error;  static bool autoclock = true; @@ -94,8 +93,6 @@ module_param_array(vid, int, NULL, 0444);  MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");  module_param_array(pid, int, NULL, 0444);  MODULE_PARM_DESC(pid, "Product ID for the USB audio device."); -module_param(nrpacks, int, 0644); -MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");  module_param_array(device_setup, int, NULL, 0444);  MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");  module_param(ignore_ctl_error, bool, 0444); @@ -142,8 +139,8 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int  	struct usb_interface *iface = usb_ifnum_to_if(dev, interface);  	if (!iface) { -		snd_printk(KERN_ERR "%d:%u:%d : does not exist\n", -			   dev->devnum, ctrlif, interface); +		dev_err(&dev->dev, "%u:%d : does not exist\n", +			ctrlif, interface);  		return -EINVAL;  	} @@ -168,8 +165,8 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int  	}  	if (usb_interface_claimed(iface)) { -		snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", -						dev->devnum, ctrlif, interface); +		dev_dbg(&dev->dev, "%d:%d: skipping, already claimed\n", +			ctrlif, interface);  		return -EINVAL;  	} @@ -179,8 +176,9 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int  		int err = snd_usbmidi_create(chip->card, iface,  					     &chip->midi_list, NULL);  		if (err < 0) { -			snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", -						dev->devnum, ctrlif, interface); +			dev_err(&dev->dev, +				"%u:%d: cannot create sequencer device\n", +				ctrlif, interface);  			return -EINVAL;  		}  		usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); @@ -191,14 +189,15 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int  	if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&  	     altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||  	    altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) { -		snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", -					dev->devnum, ctrlif, interface, altsd->bInterfaceClass); +		dev_dbg(&dev->dev, +			"%u:%d: skipping non-supported interface %d\n", +			ctrlif, interface, altsd->bInterfaceClass);  		/* skip non-supported classes */  		return -EINVAL;  	}  	if (snd_usb_get_speed(dev) == USB_SPEED_LOW) { -		snd_printk(KERN_ERR "low speed audio streaming not supported\n"); +		dev_err(&dev->dev, "low speed audio streaming not supported\n");  		return -EINVAL;  	} @@ -231,26 +230,27 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)  	protocol = altsd->bInterfaceProtocol;  	if (!control_header) { -		snd_printk(KERN_ERR "cannot find UAC_HEADER\n"); +		dev_err(&dev->dev, "cannot find UAC_HEADER\n");  		return -EINVAL;  	}  	switch (protocol) {  	default: -		snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1\n", -			    protocol); +		dev_warn(&dev->dev, +			 "unknown interface protocol %#02x, assuming v1\n", +			 protocol);  		/* fall through */  	case UAC_VERSION_1: {  		struct uac1_ac_header_descriptor *h1 = control_header;  		if (!h1->bInCollection) { -			snd_printk(KERN_INFO "skipping empty audio interface (v1)\n"); +			dev_info(&dev->dev, "skipping empty audio interface (v1)\n");  			return -EINVAL;  		}  		if (h1->bLength < sizeof(*h1) + h1->bInCollection) { -			snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n"); +			dev_err(&dev->dev, "invalid UAC_HEADER (v1)\n");  			return -EINVAL;  		} @@ -280,7 +280,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)  		}  		if (!assoc) { -			snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n"); +			dev_err(&dev->dev, "Audio class v2 interfaces need an interface association\n");  			return -EINVAL;  		} @@ -307,6 +307,11 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)  static int snd_usb_audio_free(struct snd_usb_audio *chip)  { +	struct list_head *p, *n; + +	list_for_each_safe(p, n, &chip->ep_list) +		snd_usb_endpoint_free(p); +  	mutex_destroy(&chip->mutex);  	kfree(chip);  	return 0; @@ -331,7 +336,8 @@ static void remove_trailing_spaces(char *str)  /*   * create a chip instance and set its names.   */ -static int snd_usb_audio_create(struct usb_device *dev, int idx, +static int snd_usb_audio_create(struct usb_interface *intf, +				struct usb_device *dev, int idx,  				const struct snd_usb_audio_quirk *quirk,  				struct snd_usb_audio **rchip)  { @@ -349,16 +355,18 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,  	case USB_SPEED_LOW:  	case USB_SPEED_FULL:  	case USB_SPEED_HIGH: +	case USB_SPEED_WIRELESS:  	case USB_SPEED_SUPER:  		break;  	default: -		snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev)); +		dev_err(&dev->dev, "unknown device speed %d\n", snd_usb_get_speed(dev));  		return -ENXIO;  	} -	err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card); +	err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE, +			   0, &card);  	if (err < 0) { -		snd_printk(KERN_ERR "cannot create card instance %d\n", idx); +		dev_err(&dev->dev, "cannot create card instance %d\n", idx);  		return err;  	} @@ -374,7 +382,6 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,  	chip->dev = dev;  	chip->card = card;  	chip->setup = device_setup[idx]; -	chip->nrpacks = nrpacks;  	chip->autoclock = autoclock;  	chip->probing = 1; @@ -500,7 +507,7 @@ snd_usb_audio_probe(struct usb_device *dev,  	for (i = 0; i < SNDRV_CARDS; i++) {  		if (usb_chip[i] && usb_chip[i]->dev == dev) {  			if (usb_chip[i]->shutdown) { -				snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n"); +				dev_err(&dev->dev, "USB device is in the shutdown state, cannot create a card instance\n");  				goto __error;  			}  			chip = usb_chip[i]; @@ -516,15 +523,15 @@ snd_usb_audio_probe(struct usb_device *dev,  			if (enable[i] && ! usb_chip[i] &&  			    (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&  			    (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { -				if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) { +				if (snd_usb_audio_create(intf, dev, i, quirk, +							 &chip) < 0) {  					goto __error;  				} -				snd_card_set_dev(chip->card, &intf->dev);  				chip->pm_intf = intf;  				break;  			}  		if (!chip) { -			printk(KERN_ERR "no available usb audio device\n"); +			dev_err(&dev->dev, "no available usb audio device\n");  			goto __error;  		}  	} @@ -583,7 +590,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,  				     struct snd_usb_audio *chip)  {  	struct snd_card *card; -	struct list_head *p, *n; +	struct list_head *p;  	if (chip == (void *)-1L)  		return; @@ -596,14 +603,16 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,  	mutex_lock(®ister_mutex);  	chip->num_interfaces--;  	if (chip->num_interfaces <= 0) { +		struct snd_usb_endpoint *ep; +  		snd_card_disconnect(card);  		/* release the pcm resources */  		list_for_each(p, &chip->pcm_list) {  			snd_usb_stream_disconnect(p);  		}  		/* release the endpoint resources */ -		list_for_each_safe(p, n, &chip->ep_list) { -			snd_usb_endpoint_free(p); +		list_for_each_entry(ep, &chip->ep_list, list) { +			snd_usb_endpoint_release(ep);  		}  		/* release the midi resources */  		list_for_each(p, &chip->midi_list) { @@ -649,7 +658,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)  	int err = -ENODEV;  	down_read(&chip->shutdown_rwsem); -	if (chip->probing) +	if (chip->probing && chip->in_pm)  		err = 0;  	else if (!chip->shutdown)  		err = usb_autopm_get_interface(chip->pm_intf); @@ -661,7 +670,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)  void snd_usb_autosuspend(struct snd_usb_audio *chip)  {  	down_read(&chip->shutdown_rwsem); -	if (!chip->shutdown && !chip->probing) +	if (!chip->shutdown && !chip->probing && !chip->in_pm)  		usb_autopm_put_interface(chip->pm_intf);  	up_read(&chip->shutdown_rwsem);  } @@ -693,13 +702,14 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)  			chip->autosuspended = 1;  	} -	list_for_each_entry(mixer, &chip->mixer_list, list) -		snd_usb_mixer_inactivate(mixer); +	if (chip->num_suspended_intf == 1) +		list_for_each_entry(mixer, &chip->mixer_list, list) +			snd_usb_mixer_suspend(mixer);  	return 0;  } -static int usb_audio_resume(struct usb_interface *intf) +static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)  {  	struct snd_usb_audio *chip = usb_get_intfdata(intf);  	struct usb_mixer_interface *mixer; @@ -709,12 +719,14 @@ static int usb_audio_resume(struct usb_interface *intf)  		return 0;  	if (--chip->num_suspended_intf)  		return 0; + +	chip->in_pm = 1;  	/*  	 * ALSA leaves material resumption to user space  	 * we just notify and restart the mixers  	 */  	list_for_each_entry(mixer, &chip->mixer_list, list) { -		err = snd_usb_mixer_activate(mixer); +		err = snd_usb_mixer_resume(mixer, reset_resume);  		if (err < 0)  			goto err_out;  	} @@ -724,11 +736,23 @@ static int usb_audio_resume(struct usb_interface *intf)  	chip->autosuspended = 0;  err_out: +	chip->in_pm = 0;  	return err;  } + +static int usb_audio_resume(struct usb_interface *intf) +{ +	return __usb_audio_resume(intf, false); +} + +static int usb_audio_reset_resume(struct usb_interface *intf) +{ +	return __usb_audio_resume(intf, true); +}  #else  #define usb_audio_suspend	NULL  #define usb_audio_resume	NULL +#define usb_audio_reset_resume	NULL  #endif		/* CONFIG_PM */  static struct usb_device_id usb_audio_ids [] = { @@ -750,23 +774,9 @@ static struct usb_driver usb_audio_driver = {  	.disconnect =	usb_audio_disconnect,  	.suspend =	usb_audio_suspend,  	.resume =	usb_audio_resume, +	.reset_resume =	usb_audio_reset_resume,  	.id_table =	usb_audio_ids,  	.supports_autosuspend = 1,  }; -static int __init snd_usb_audio_init(void) -{ -	if (nrpacks < 1 || nrpacks > MAX_PACKS) { -		printk(KERN_WARNING "invalid nrpacks value.\n"); -		return -EINVAL; -	} -	return usb_register(&usb_audio_driver); -} - -static void __exit snd_usb_audio_cleanup(void) -{ -	usb_deregister(&usb_audio_driver); -} - -module_init(snd_usb_audio_init); -module_exit(snd_usb_audio_cleanup); +module_usb_driver(usb_audio_driver);  | 
