Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: "Geoffrey D. Bennett" <g@b4.vu>
Cc: Takashi Iwai <tiwai@suse.de>, Takashi Iwai <tiwai@suse.com>,
	linux-sound@vger.kernel.org
Subject: Re: [PATCH 1/2] ALSA: FCP: Add Focusrite Control Protocol driver
Date: Sun, 29 Dec 2024 10:01:14 +0100	[thread overview]
Message-ID: <87jzbidfs5.wl-tiwai@suse.de> (raw)
In-Reply-To: <3bbe9f8ec8664e36ca524649a7ec4c1356df17e9.1735159288.git.g@b4.vu>

On Wed, 25 Dec 2024 22:23:19 +0100,
Geoffrey D. Bennett wrote:
> 
> --- /dev/null
> +++ b/include/uapi/sound/fcp.h
> @@ -0,0 +1,59 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/*
> + * Focusrite Control Protocol Driver for ALSA
> + *
> + * Copyright (c) 2024 by Geoffrey D. Bennett <g at b4.vu>
> + */
> +#ifndef __UAPI_SOUND_FCP_H
> +#define __UAPI_SOUND_FCP_H
> +
> +#ifdef __KERNEL__
> +#include <linux/types.h>
> +#else
> +#include <stdint.h>
> +#endif
> +
> +#include <linux/ioctl.h>
> +
> +#define FCP_HWDEP_MAJOR 2
> +#define FCP_HWDEP_MINOR 0
> +#define FCP_HWDEP_SUBMINOR 0
> +
> +#define FCP_HWDEP_VERSION \
> +	((FCP_HWDEP_MAJOR << 16) | \
> +	 (FCP_HWDEP_MINOR << 8) | \
> +	  FCP_HWDEP_SUBMINOR)
> +
> +#define FCP_HWDEP_VERSION_MAJOR(v) (((v) >> 16) & 0xFF)
> +#define FCP_HWDEP_VERSION_MINOR(v) (((v) >> 8) & 0xFF)
> +#define FCP_HWDEP_VERSION_SUBMINOR(v) ((v) & 0xFF)
> +
> +/* Get protocol version */
> +#define FCP_IOCTL_PVERSION _IOR('S', 0x60, int)
> +
> +/* Do FCP step 0 */
> +struct fcp_step0 {
> +	void     *data;
> +	uint16_t  size;
> +};
> +#define FCP_IOCTL_INIT _IOWR('S', 0x64, struct fcp_step0)

An ioctl with a pointer has to be handled carefully because you must
convert it for 32bit compat code.  IOW, it's better to be avoided if
possible.

The same is true for other ioctls.


> --- /dev/null
> +++ b/sound/usb/fcp.c
(snip)
> +struct fcp_data {
> +	struct usb_mixer_interface *mixer;
> +
> +	struct mutex mutex;         /* serialise access to the device */
> +	struct completion cmd_done; /* wait for command completion */
> +	struct file *file;          /* hwdep file */
> +
> +	/* notify waiting to send to *file */
> +	struct {
> +		wait_queue_head_t queue;
> +		u32               event;
> +		spinlock_t        lock;
> +	} notify;

Might be better to define outside with an explicit type name in case
of code simplification (e.g. factoring out the struct init code,
etc).

> +	__u8  bInterfaceNumber;
> +	__u8  bEndpointAddress;
> +	__u16 wMaxPacketSize;
> +	__u8  bInterval;

This is an internal struct and should be types without __ prefix.

> +/* Send an FCP command and get the response */
> +static int fcp_usb(struct usb_mixer_interface *mixer, u32 opcode,
> +		   const void *req_data, u16 req_size,
> +		   void *resp_data, u16 resp_size)
> +{
> +	struct fcp_data *private = mixer->private_data;
> +	struct usb_device *dev = mixer->chip->dev;
> +	struct fcp_usb_packet *req, *resp = NULL;
> +	size_t req_buf_size = struct_size(req, data, req_size);
> +	size_t resp_buf_size = struct_size(resp, data, resp_size);
> +	int retries = 0;
> +	const int max_retries = 5;
> +	int err;
> +
> +	req = kmalloc(req_buf_size, GFP_KERNEL);
> +	if (!req) {
> +		err = -ENOMEM;
> +		goto done;

You can use cleanup.h stuff for code simplification.
(Also for other possible functions.)

> +static int fcp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
> +			   unsigned int cmd, unsigned long arg)
> +{
> +	struct usb_mixer_interface *mixer = hw->private_data;
> +	struct fcp_data *private = mixer->private_data;
> +	int err;
> +
> +	mutex_lock(&private->mutex);
> +
> +	switch (cmd) {
> +
> +	case FCP_IOCTL_PVERSION:
> +		err = put_user(FCP_HWDEP_VERSION,
> +			       (int __user *)arg) ? -EFAULT : 0;
> +		break;
> +
> +	case FCP_IOCTL_INIT:
> +		err = fcp_ioctl_init(mixer, arg);
> +		break;
> +
> +	case FCP_IOCTL_CMD:
> +		err = fcp_ioctl_cmd(mixer, arg);
> +		break;
> +
> +	case FCP_IOCTL_SET_METER_MAP:
> +		err = fcp_ioctl_set_meter_map(mixer, arg);
> +		break;
> +
> +	default:
> +		err = -ENOIOCTLCMD;
> +	}
> +
> +	mutex_unlock(&private->mutex);

There seems an implicit ordering of the command -- FCP_IOCTL_INIT must
be called before *_CMD?  If so, do we have a sanity check for that?

Also, the behavior of *_SET_METER_MAP -- it dynamically creates and
deletes the meter kcontrol -- can be a bit dangerous.  Can't it be
without recreating the kcontrol itself?

Last but not least, any need for suspend/resume and disconnect
handling?


thanks,

Takashi

  reply	other threads:[~2024-12-29  9:01 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-25 21:23 [PATCH 0/2] ALSA: Add driver for big Scarlett 4th Gen interfaces Geoffrey D. Bennett
2024-12-25 21:23 ` [PATCH 1/2] ALSA: FCP: Add Focusrite Control Protocol driver Geoffrey D. Bennett
2024-12-29  9:01   ` Takashi Iwai [this message]
2024-12-25 21:23 ` [PATCH 2/2] ALSA: scarlett2: Add device_setup option to use FCP driver Geoffrey D. Bennett
2024-12-29  8:41 ` [PATCH 0/2] ALSA: Add driver for big Scarlett 4th Gen interfaces Takashi Iwai

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=87jzbidfs5.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=g@b4.vu \
    --cc=linux-sound@vger.kernel.org \
    --cc=tiwai@suse.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