ALSA: line6: Claim pod x3 usb data interface
authorAndrej Krutak <dev@andree.sk>
Tue, 29 Nov 2016 21:12:51 +0000 (22:12 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 29 Nov 2016 21:16:14 +0000 (22:16 +0100)
Userspace apps have to claim USB interfaces before using endpoints in
them (drivers/usb/core/devio.c:checkintf()). It's a lock mechanism so
that two "drivers" don't steal data from each other. Kernel drivers don't
have to claim interfaces to work - but they should, to lock out userspace.

While there, fix line6_properties struct to match checkpatch.pl.

Signed-off-by: Andrej Krutak <dev@andree.sk>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/line6/driver.h
sound/usb/line6/podhd.c

index 7e3a3aada22209318f714a6acb3b364eb56245e4..a5c2e9ae5f172732240db27b0140e71385d00a5e 100644 (file)
@@ -98,10 +98,11 @@ struct line6_properties {
 
        int altsetting;
 
-       unsigned ep_ctrl_r;
-       unsigned ep_ctrl_w;
-       unsigned ep_audio_r;
-       unsigned ep_audio_w;
+       unsigned int ctrl_if;
+       unsigned int ep_ctrl_r;
+       unsigned int ep_ctrl_w;
+       unsigned int ep_audio_r;
+       unsigned int ep_audio_w;
 };
 
 /* Capability bits */
index 49cd4a65e390c8b56a0d5986e3d561fe407c6d80..6ab23e5aee71edf7cbd29192a60219a4d65bba4d 100644 (file)
@@ -153,6 +153,7 @@ static struct line6_pcm_properties podx3_pcm_properties = {
                            .rats = &podhd_ratden},
        .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
 };
+static struct usb_driver podhd_driver;
 
 static void podhd_startup_start_workqueue(unsigned long data);
 static void podhd_startup_workqueue(struct work_struct *work);
@@ -291,8 +292,14 @@ static void podhd_disconnect(struct usb_line6 *line6)
        struct usb_line6_podhd *pod = (struct usb_line6_podhd *)line6;
 
        if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
+               struct usb_interface *intf;
+
                del_timer_sync(&pod->startup_timer);
                cancel_work_sync(&pod->startup_work);
+
+               intf = usb_ifnum_to_if(line6->usbdev,
+                                       pod->line6.properties->ctrl_if);
+               usb_driver_release_interface(&podhd_driver, intf);
        }
 }
 
@@ -304,10 +311,27 @@ static int podhd_init(struct usb_line6 *line6,
 {
        int err;
        struct usb_line6_podhd *pod = (struct usb_line6_podhd *) line6;
+       struct usb_interface *intf;
 
        line6->disconnect = podhd_disconnect;
 
        if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
+               /* claim the data interface */
+               intf = usb_ifnum_to_if(line6->usbdev,
+                                       pod->line6.properties->ctrl_if);
+               if (!intf) {
+                       dev_err(pod->line6.ifcdev, "interface %d not found\n",
+                               pod->line6.properties->ctrl_if);
+                       return -ENODEV;
+               }
+
+               err = usb_driver_claim_interface(&podhd_driver, intf, NULL);
+               if (err != 0) {
+                       dev_err(pod->line6.ifcdev, "can't claim interface %d, error %d\n",
+                               pod->line6.properties->ctrl_if, err);
+                       return err;
+               }
+
                /* create sysfs entries: */
                err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group);
                if (err < 0)
@@ -406,6 +430,7 @@ static const struct line6_properties podhd_properties_table[] = {
                .altsetting = 1,
                .ep_ctrl_r = 0x81,
                .ep_ctrl_w = 0x01,
+               .ctrl_if = 1,
                .ep_audio_r = 0x86,
                .ep_audio_w = 0x02,
        },
@@ -417,6 +442,7 @@ static const struct line6_properties podhd_properties_table[] = {
                .altsetting = 1,
                .ep_ctrl_r = 0x81,
                .ep_ctrl_w = 0x01,
+               .ctrl_if = 1,
                .ep_audio_r = 0x86,
                .ep_audio_w = 0x02,
        },