From: Daniel Mack <daniel@zonque.org>
To: Damien Zammit <damien.zammit@gmail.com>
Cc: alsa-devel@alsa-project.org, Clemens Ladisch <clemens@ladisch.de>
Subject: Re: [PATCH] ALSA: usb-audio - Capture and duplex support for Digidesign Mbox 1 sound card.
Date: Mon, 31 Mar 2014 19:58:44 +0200 [thread overview]
Message-ID: <5339ACD4.5010208@zonque.org> (raw)
In-Reply-To: <53365B9B.2050402@gmail.com>
Hi Damien,
On 03/29/2014 06:35 AM, Damien Zammit wrote:
> A few revisions of this patch have been made. This patch provides support for usb cards
> which have their streams on multiple endpoints within the same interface.
> In particular, it provides duplex mode support for Digidesign Mbox 1.
>
> I followed ALSA dev team's suggestion of making it work for N endpoints
> rather than hardcoding it to two, and improved error handling has been provided.
> An extra parameter has been added as requested to the usbaudio quirk struct 'epmulti'
> to give the number of endpoints within a multi interface.
>
A few style nits below, which you can fix for the next version. Most
important, the error unwinder should be more in-line with other code in
the kernel.
> diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
> index 7c57f22..affbced 100644
> --- a/sound/usb/quirks.c
> +++ b/sound/usb/quirks.c
> @@ -180,6 +180,84 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
> return 0;
> }
>
> +/*
> + * create N streams for an interface without proper descriptors but with multiple endpoints
> + */
> +static int create_fixed_multi_stream_quirk(struct snd_usb_audio *chip,
> + struct usb_interface *iface,
> + struct usb_driver *driver,
> + const struct snd_usb_audio_quirk *quirk)
> +{
> + struct audioformat **fp;
> + struct usb_host_interface *alts = NULL;
> + int *stream;
> + int err, i;
> + unsigned *rate_table = NULL;
> + int rates_found;
> + rates_found = 0;
> +
> + stream = (int*) kmalloc(sizeof(int) * quirk->epmulti, GFP_KERNEL);
No need to cast the result of k[mzc]alloc. Same for other locations below.
> + if (!stream)
> + goto err_mem;
err = -ENOMEM;
goto exit_err;
> + fp = (struct audioformat**) kmalloc(sizeof((const struct audioformat*)quirk->data) * quirk->epmulti, GFP_KERNEL);
> + if (!(fp))
Extra parenthesis not needed.
> + goto err_mem;
> +
> + for (i = 0; i < quirk->epmulti; ++i) {
i++ is prefered if the operation order doesn't matter. It's not
important but a little more common in the kernel.
> + fp[i] = kmemdup((const struct audioformat*)(quirk->data + i*sizeof(const struct audioformat)), sizeof(*fp[i]), GFP_KERNEL);
You need to do something about these overlong lines, as they're also
quite unparsable for humans. One solution is to pre-calculate the size
into a temporary variable.
> + if (!(fp[i])) {
Extra parenthesis not needed.
> + usb_audio_err(chip, "cannot memdup %d\n", i);
err = -ENOMEM;
goto exit_err;
> + goto err_mem;
> + }
> + if (fp[i]->nr_rates > MAX_NR_RATES) {
> + err = -EINVAL;
> + goto err_rates;
> + }
> + if (fp[i]->nr_rates > 0 && !rates_found) {
> + rate_table = kmemdup(fp[i]->rate_table,
> + sizeof(int) * fp[i]->nr_rates, GFP_KERNEL);
> + rates_found = 1;
Not sure if I overlook anything, but isn't the extra variable
rates_found redundant here, as can derive the same information by
checking for (rate_table != NULL)?
> + }
> + if (!rate_table) {
> + err = -ENOMEM;
> + goto err_rates;
> + }
This check makes more sense directly underneath the kmemdup().
> + fp[i]->rate_table = rate_table;
> +
> + stream[i] = (fp[i]->endpoint & USB_DIR_IN)
> + ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
> +
> + err = snd_usb_add_audio_stream(chip, stream[i], fp[i]);
> + if (err < 0)
> + goto err_ratetable;
> +
> + if (fp[i]->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
> + fp[i]->altset_idx >= iface->num_altsetting) {
> + err = -EINVAL;
> + goto err_ratetable;
> + }
> + alts = &iface->altsetting[fp[0]->altset_idx];
> + fp[i]->datainterval = snd_usb_parse_datainterval(chip, alts);
> + fp[i]->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
> + }
> + usb_set_interface(chip->dev, fp[0]->iface, 0);
> + snd_usb_init_pitch(chip, fp[0]->iface, alts, fp[0]);
> + snd_usb_init_sample_rate(chip, fp[0]->iface, alts, fp[0], fp[0]->rate_max);
> + return 0;
> +
> +err_mem:
> + return -ENOMEM;
You can drop this ...
> +err_ratetable:
> + kfree(rate_table);
> +err_rates:
> + for (i = 0; i < quirk->epmulti; ++i)
> + if(fp[i])
> + kfree(fp[i]);
> + kfree(fp);
> + kfree(stream);
... and place another label here:
exit_err:
> + return err;
> +}
> +
Thanks,
Daniel
prev parent reply other threads:[~2014-03-31 17:58 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-26 15:10 [PATCH] ALSA: usb-audio - Capture and duplex support for Digidesign Mbox 1 sound card Damien Zammit
2014-01-26 15:30 ` Damien Zammit
2014-01-26 16:52 ` Clemens Ladisch
2014-01-27 3:02 ` Damien Zammit
2014-03-01 7:40 ` Damien Zammit
2014-03-03 21:01 ` Daniel Mack
2014-03-29 5:01 ` Mark Hills
2014-03-29 12:27 ` [alsa-devel] " Damien Zammit
2014-03-29 22:57 ` Mark Hills
2014-03-30 3:21 ` Damien Zammit
2014-03-31 17:47 ` Daniel Mack
2014-04-01 2:41 ` Damien Zammit
2014-03-29 5:35 ` Damien Zammit
2014-03-31 17:58 ` Daniel Mack [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5339ACD4.5010208@zonque.org \
--to=daniel@zonque.org \
--cc=alsa-devel@alsa-project.org \
--cc=clemens@ladisch.de \
--cc=damien.zammit@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox