From: "Geoffrey D. Bennett" <g@b4.vu>
To: Takashi Iwai <tiwai@suse.de>
Cc: Takashi Iwai <tiwai@suse.com>,
alsa-devel@alsa-project.org, linux-sound@vger.kernel.org
Subject: [PATCH v2 11/11] ALSA: scarlett2: Add support for uploading new firmware
Date: Fri, 29 Dec 2023 22:49:23 +1030 [thread overview]
Message-ID: <ZY65S0ojShSNSeRQ@m.b4.vu> (raw)
In-Reply-To: <e295050a79057ee8b7bc555a65e295691abd1ede.1703001053.git.g@b4.vu>
Add ops.write to the hwdep interface. Once the upgrade firmware flash
segment has been erased, writes to the hwdep fd are permitted, and
translated to SCARLETT2_USB_WRITE_SEGMENT commands to the device.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
Hi Takashi,
I noticed that scarlett2_hwdep_write() was returning the wrong value
for errors encountered after the kzalloc(). Since I don't think you've
taken this set of patches yet, can you replace the previous patch 11
with this version two? Sorry, I don't know if you'd prefer I resend
all 11 patches but I erred on the side of fewer emails. Let me know if
you would like me to do different this time or next time.
Thanks,
Geoffrey.
sound/usb/mixer_scarlett2.c | 96 +++++++++++++++++++++++++++++++++++--
1 file changed, 93 insertions(+), 3 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index ca09d0cd0cae..1f3b07bd7b3f 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -266,7 +266,8 @@ enum {
enum {
SCARLETT2_FLASH_WRITE_STATE_IDLE = 0,
SCARLETT2_FLASH_WRITE_STATE_SELECTED = 1,
- SCARLETT2_FLASH_WRITE_STATE_ERASING = 2
+ SCARLETT2_FLASH_WRITE_STATE_ERASING = 2,
+ SCARLETT2_FLASH_WRITE_STATE_WRITE = 3
};
static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = {
@@ -1176,6 +1177,7 @@ static int scarlett2_get_port_start_num(
#define SCARLETT2_USB_METER_LEVELS_GET_MAGIC 1
#define SCARLETT2_FLASH_BLOCK_SIZE 4096
+#define SCARLETT2_FLASH_WRITE_MAX 1024
#define SCARLETT2_SEGMENT_NUM_MIN 1
#define SCARLETT2_SEGMENT_NUM_MAX 4
@@ -5079,10 +5081,10 @@ static int scarlett2_ioctl_get_erase_progress(
return -EFAULT;
/* If the erase is complete, change the state from ERASING to
- * IDLE.
+ * WRITE.
*/
if (progress.progress == 0xff)
- private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_IDLE;
+ private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_WRITE;
return 0;
}
@@ -5135,6 +5137,93 @@ static int scarlett2_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
}
}
+static long scarlett2_hwdep_write(struct snd_hwdep *hw,
+ const char __user *buf,
+ long count, loff_t *offset)
+{
+ struct usb_mixer_interface *mixer = hw->private_data;
+ struct scarlett2_data *private = mixer->private_data;
+ int segment_id, segment_num, err, len;
+ int flash_size;
+
+ /* SCARLETT2_USB_WRITE_SEGMENT request data */
+ struct {
+ __le32 segment_num;
+ __le32 offset;
+ __le32 pad;
+ u8 data[];
+ } __packed *req;
+
+ /* Calculate the maximum permitted in data[] */
+ const size_t max_data_size = SCARLETT2_FLASH_WRITE_MAX -
+ offsetof(typeof(*req), data);
+
+ /* If erasing, wait for it to complete */
+ if (private->flash_write_state ==
+ SCARLETT2_FLASH_WRITE_STATE_ERASING) {
+ err = scarlett2_wait_for_erase(mixer);
+ if (err < 0)
+ return err;
+ private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_WRITE;
+
+ /* Check that an erase has been done & completed */
+ } else if (private->flash_write_state !=
+ SCARLETT2_FLASH_WRITE_STATE_WRITE) {
+ return -EINVAL;
+ }
+
+ /* Check that we're writing to the upgrade firmware */
+ segment_id = private->selected_flash_segment_id;
+ if (segment_id != SCARLETT2_SEGMENT_ID_FIRMWARE)
+ return -EINVAL;
+
+ segment_num = private->flash_segment_nums[segment_id];
+ if (segment_num < SCARLETT2_SEGMENT_NUM_MIN ||
+ segment_num > SCARLETT2_SEGMENT_NUM_MAX)
+ return -EFAULT;
+
+ /* Validate the offset and count */
+ flash_size = private->flash_segment_blocks[segment_id] *
+ SCARLETT2_FLASH_BLOCK_SIZE;
+
+ if (count < 0 || *offset < 0 || *offset + count >= flash_size)
+ return -EINVAL;
+
+ if (!count)
+ return 0;
+
+ /* Limit the *req size to SCARLETT2_FLASH_WRITE_MAX */
+ if (count > max_data_size)
+ count = max_data_size;
+
+ /* Create and send the request */
+ len = struct_size(req, data, count);
+ req = kzalloc(len, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ req->segment_num = cpu_to_le32(segment_num);
+ req->offset = cpu_to_le32(*offset);
+ req->pad = 0;
+
+ if (copy_from_user(req->data, buf, count)) {
+ err = -EFAULT;
+ goto error;
+ }
+
+ err = scarlett2_usb(mixer, SCARLETT2_USB_WRITE_SEGMENT,
+ req, len, NULL, 0);
+ if (err < 0)
+ goto error;
+
+ *offset += count;
+ err = count;
+
+error:
+ kfree(req);
+ return err;
+}
+
static int scarlett2_hwdep_release(struct snd_hwdep *hw, struct file *file)
{
struct usb_mixer_interface *mixer = hw->private_data;
@@ -5164,6 +5253,7 @@ static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer)
hw->exclusive = 1;
hw->ops.open = scarlett2_hwdep_open;
hw->ops.ioctl = scarlett2_hwdep_ioctl;
+ hw->ops.write = scarlett2_hwdep_write;
hw->ops.release = scarlett2_hwdep_release;
return 0;
--
2.43.0
next prev parent reply other threads:[~2023-12-29 12:19 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-19 17:36 [PATCH 00/11] ALSA: scarlett2: Firmware Upgrade and Error Handling Improvements Geoffrey D. Bennett
2023-12-19 17:36 ` [PATCH 01/11] ALSA: scarlett2: Update maintainer info Geoffrey D. Bennett
2023-12-19 17:37 ` [PATCH 02/11] ALSA: scarlett2: Add missing error check to scarlett2_config_save() Geoffrey D. Bennett
2023-12-19 17:37 ` [PATCH 03/11] ALSA: scarlett2: Add missing error check to scarlett2_usb_set_config() Geoffrey D. Bennett
2023-12-19 17:37 ` [PATCH 04/11] ALSA: scarlett2: Add missing error checks to *_ctl_get() Geoffrey D. Bennett
2023-12-19 17:37 ` [PATCH 05/11] ALSA: scarlett2: Add clamp() in scarlett2_mixer_ctl_put() Geoffrey D. Bennett
2023-12-19 17:38 ` [PATCH 06/11] ALSA: scarlett2: Add missing mutex lock around get meter levels Geoffrey D. Bennett
2023-12-19 17:38 ` [PATCH 07/11] ALSA: scarlett2: Add #defines for firmware upgrade Geoffrey D. Bennett
2023-12-19 17:38 ` [PATCH 08/11] ALSA: scarlett2: Retrieve useful flash segment numbers Geoffrey D. Bennett
2023-12-19 17:39 ` [PATCH 09/11] ALSA: scarlett2: Add skeleton hwdep/ioctl interface Geoffrey D. Bennett
2023-12-19 17:50 ` [PATCH 10/11] ALSA: scarlett2: Add ioctl commands to erase flash segments Geoffrey D. Bennett
2023-12-19 17:50 ` [PATCH 11/11] ALSA: scarlett2: Add support for uploading new firmware Geoffrey D. Bennett
2023-12-29 12:19 ` Geoffrey D. Bennett [this message]
2023-12-29 15:08 ` [PATCH 00/11] ALSA: scarlett2: Firmware Upgrade and Error Handling Improvements 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=ZY65S0ojShSNSeRQ@m.b4.vu \
--to=g@b4.vu \
--cc=alsa-devel@alsa-project.org \
--cc=linux-sound@vger.kernel.org \
--cc=tiwai@suse.com \
--cc=tiwai@suse.de \
/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