Message ID | 20240605175953.2613260-8-joychakr@google.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers |
Received: from sv.mirrors.kernel.org ([139.178.88.99]) by linuxtv.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from <linux-media+bounces-12608-patchwork=linuxtv.org@vger.kernel.org>) id 1sEuyk-0006tf-1q for patchwork@linuxtv.org; Wed, 05 Jun 2024 18:03:19 +0000 Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id CBA9E28AE9F for <patchwork@linuxtv.org>; Wed, 5 Jun 2024 18:03:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 761D0195F20; Wed, 5 Jun 2024 18:00:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="xh8vf0dA" X-Original-To: linux-media@vger.kernel.org Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73EFF13A87E for <linux-media@vger.kernel.org>; Wed, 5 Jun 2024 18:00:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717610433; cv=none; b=pEVsg80n4ziA0A2g3kNmQfuKF6lXZjnmVSIibWkTN8UQKDSAUR7WFXXZF4e1y0Ychr5iYru8eZw2ydlEH5Zzbi31KyEiCwOVQPYDMgeoJnFcM3kxkD0zPFFzXANVLDLg1ngms1ezYwVa3kAUZR11lbaeC5aLQU0qsvFd+b65m0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717610433; c=relaxed/simple; bh=7YntdTNu7aMZ5zLGGRpR3JsfAB0rBOtanC3KQe4XBYY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=gdJehf0c2kLwYEosKVvKC3M4s1Tv8/e0el3g5YIN8eAayg59qfvK2d4D8y9JvWNltMj3x6mnffS1CieHM5sS8qiQstj+pVAU6PbY5cm5xZ9LU7rVDkW3pM7tfX9zDapMPYtIMV1adAmmSRx/D1g4jit9nD3AVLF0UgZGziVsO08= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--joychakr.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=xh8vf0dA; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--joychakr.bounces.google.com Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-62a1e9807c0so743417b3.0 for <linux-media@vger.kernel.org>; Wed, 05 Jun 2024 11:00:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1717610430; x=1718215230; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=GabZAVwK9FSl0VODpa0rRnhc7Hb5WIAFsUpyNY/Jkgw=; b=xh8vf0dA+TFlUnkkazIa6Em6KzJbbntuGamI4Gn8Wj1jFYYx5ZYFkn2tA0alpWg68u 9jhNXfx2DxL9m7tqmgthqmC1rUSflk24zLEIHrstf3mW39EvFDR2FeelUhLsupY30DEi /gVZrfJA0Slzv9rEogcUVgXiY8hLFc0E46E+FUZ/X8hWU6PYTTTOsgDQPMK44rgcyi4X g7UTGxktSZ/IcwoGFDfvWXQYzCbWyLYks/FVJWCMOKozF5JwJ5koJWgZ7381pzPo2fKz JwnKZftDOTv9WkuxVVV5rBvZHglYy9BQThw/il2JbfCMaxHpHsqQPdwDUsOxRCnGKcAo B5jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717610430; x=1718215230; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=GabZAVwK9FSl0VODpa0rRnhc7Hb5WIAFsUpyNY/Jkgw=; b=JJvfaP34q/dZtxA/8WqDmbDISDSJIq73M50y6rc+9BstOJFBlhIVoCOgRUhxa+Fy9Z 1G0rW9c6DTR5l5bCYyE3+Jg3McDJikRaPNRp1owSq8Icip2huqv7ugZeeknbUo6tAKTC rX8mWOe3U9YbcM3SiQ+60clTQjWRbpRHALOyYFXXsim1FZMosu6zU9ddoS27E++QcHBg iJcqFhe1FA47Vnhn9rn7Hvr1IbEFVaOTZ6vvY80XkvICEWkVSxS3osiln3o6GYPeqkPH SAgqsZUU/2uVMA6wEYsu8fHtyr7i9TzrbDHGBTKQWsJX8R3CLigXSrg7sDYk1/KkmNK8 oaFQ== X-Forwarded-Encrypted: i=1; AJvYcCUUp287qfPPr0ySdiKD+5LcuBtrkMqOjvYYjRz6oE1R2oPc2zUBO/+C+SESTOOKizPkcAtjvW9Kmv2hLQclOezOnMQTJsVOO8lADaY= X-Gm-Message-State: AOJu0Yz5hN30J6oiEayxsAfrw5bZAuPj5ml9F2wnR4nBXHErgB9lz30i rPVuMaTeWTmczcWWJOookV6xvEbSTTsKrBdP+4b3zrhCglV5mDfEu5PDt7F8sYMET6/DlhSoc3A 3Nn3IivyX4A== X-Google-Smtp-Source: AGHT+IEja+GLVOpS7V2U0r8IR9Z9ZB6nAf9rPU6225JSB7wTRYk1qUU4QFIkeBtYF/8VHx1IHDowrDp0WPzcZg== X-Received: from joychakr.c.googlers.com ([fda3:e722:ac3:cc00:4f:4b78:c0a8:6ea]) (user=joychakr job=sendgmr) by 2002:a0d:d952:0:b0:627:de82:8077 with SMTP id 00721157ae682-62cc709af05mr798057b3.2.1717610430440; Wed, 05 Jun 2024 11:00:30 -0700 (PDT) Date: Wed, 5 Jun 2024 17:59:51 +0000 In-Reply-To: <20240605175953.2613260-1-joychakr@google.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: <linux-media.vger.kernel.org> List-Subscribe: <mailto:linux-media+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-media+unsubscribe@vger.kernel.org> Mime-Version: 1.0 References: <20240605175953.2613260-1-joychakr@google.com> X-Mailer: git-send-email 2.45.1.467.gbab1589fc0-goog Message-ID: <20240605175953.2613260-8-joychakr@google.com> Subject: [PATCH v1 07/17] misc: eeprom: at25: Change nvmem reg_read/write return type From: Joy Chakraborty <joychakr@google.com> To: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>, Lars-Peter Clausen <lars@metafoo.de>, Sakari Ailus <sakari.ailus@linux.intel.com>, Bingbu Cao <bingbu.cao@intel.com>, Zhihao Cheng <chengzhihao1@huawei.com>, Jerome Brunet <jbrunet@baylibre.com>, Martin Blumenstingl <martin.blumenstingl@googlemail.com> Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, linux-i2c@vger.kernel.org, linux-gpio@vger.kernel.org, linux-mtd@lists.infradead.org, linux-rtc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-amlogic@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-tegra@vger.kernel.org, linux-usb@vger.kernel.org, manugautam@google.com, Joy Chakraborty <joychakr@google.com> Content-Type: text/plain; charset="UTF-8" X-LSpam-Score: -13.4 (-------------) X-LSpam-Report: No, score=-13.4 required=5.0 tests=ARC_SIGNED=0.001,ARC_VALID=-0.1,BAYES_00=-1.9,DKIMWL_WL_MED=-1,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,DMARC_PASS=-0.001,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1,RCVD_IN_DNSWL_MED=-2.3,SPF_HELO_NONE=0.001,SPF_PASS=-0.001,USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no |
Series |
nvmem: Handle change of return type in reg_read/write() definition
|
|
Commit Message
Joy Chakraborty
June 5, 2024, 5:59 p.m. UTC
Change nvmem read/write function definition return type to ssize_t.
Signed-off-by: Joy Chakraborty <joychakr@google.com>
---
drivers/misc/eeprom/at25.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
Comments
On Wed, Jun 05, 2024 at 05:59:51PM +0000, Joy Chakraborty wrote: > @@ -195,10 +195,11 @@ static struct attribute *sernum_attrs[] = { > }; > ATTRIBUTE_GROUPS(sernum); > > -static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) > +static ssize_t at25_ee_write(void *priv, unsigned int off, void *val, size_t count) > { > struct at25_data *at25 = priv; > size_t maxsz = spi_max_transfer_size(at25->spi); > + size_t bytes_written = count; > const char *buf = val; > int status = 0; > unsigned buf_size; > @@ -313,7 +314,7 @@ static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) > mutex_unlock(&at25->lock); > > kfree(bounce); > - return status; > + return status < 0 ? status : bytes_written; > } So the original bug was that rmem_read() is returning positive values on success instead of zero[1]. That started a discussion about partial reads which resulted in changing the API to support partial reads[2]. That patchset broke the build. This patchset is trying to fix the build breakage. [1] https://lore.kernel.org/all/20240206042408.224138-1-joychakr@google.com/ [2] https://lore.kernel.org/all/20240510082929.3792559-2-joychakr@google.com/ The bug in rmem_read() is still not fixed. That needs to be fixed as a stand alone patch. We can discuss re-writing the API separately. These functions are used internally and exported to the user through sysfs via bin_attr_nvmem_read/write(). For internal users partial reads should be treated as failure. What are we supposed to do with a partial read? I don't think anyone has asked for partial reads to be supported from sysfs either except Greg was wondering about it while reading the code. Currently, a lot of drivers return -EINVAL for partial read/writes but some return success. It is a bit messy. But this patchset doesn't really improve anything. In at24_read() we check if it's going to be a partial read and return -EINVAL. Below we report a partial read as a full read. It's just a more complicated way of doing exactly what we were doing before. drivers/misc/eeprom/at25.c 198 static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) 199 { 200 struct at25_data *at25 = priv; 201 size_t maxsz = spi_max_transfer_size(at25->spi); New: size_t bytes_written = count; ^^^^^^^^^^^^^^^^^^^^^ This is not the number of bytes written. 202 const char *buf = val; 203 int status = 0; 204 unsigned buf_size; 205 u8 *bounce; 206 207 if (unlikely(off >= at25->chip.byte_len)) 208 return -EFBIG; 209 if ((off + count) > at25->chip.byte_len) 210 count = at25->chip.byte_len - off; ^^^^^ This is. 211 if (unlikely(!count)) 212 return -EINVAL; 213 214 /* Temp buffer starts with command and address */ 215 buf_size = at25->chip.page_size; 216 if (buf_size > io_limit) 217 buf_size = io_limit; 218 bounce = kmalloc(buf_size + at25->addrlen + 1, GFP_KERNEL); 219 if (!bounce) 220 return -ENOMEM; 221 regards, dan carpenter
On Thu, Jun 6, 2024 at 2:11 PM Dan Carpenter <dan.carpenter@linaro.org> wrote: > > On Wed, Jun 05, 2024 at 05:59:51PM +0000, Joy Chakraborty wrote: > > @@ -195,10 +195,11 @@ static struct attribute *sernum_attrs[] = { > > }; > > ATTRIBUTE_GROUPS(sernum); > > > > -static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) > > +static ssize_t at25_ee_write(void *priv, unsigned int off, void *val, size_t count) > > { > > struct at25_data *at25 = priv; > > size_t maxsz = spi_max_transfer_size(at25->spi); > > + size_t bytes_written = count; > > const char *buf = val; > > int status = 0; > > unsigned buf_size; > > @@ -313,7 +314,7 @@ static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) > > mutex_unlock(&at25->lock); > > > > kfree(bounce); > > - return status; > > + return status < 0 ? status : bytes_written; > > } > > So the original bug was that rmem_read() is returning positive values > on success instead of zero[1]. That started a discussion about partial > reads which resulted in changing the API to support partial reads[2]. > That patchset broke the build. This patchset is trying to fix the > build breakage. > > [1] https://lore.kernel.org/all/20240206042408.224138-1-joychakr@google.com/ > [2] https://lore.kernel.org/all/20240510082929.3792559-2-joychakr@google.com/ > > The bug in rmem_read() is still not fixed. That needs to be fixed as > a stand alone patch. We can discuss re-writing the API separately. > True, fixing the return type would fix that as well is what I thought but maybe yes we need to fix that separately as well. > These functions are used internally and exported to the user through > sysfs via bin_attr_nvmem_read/write(). For internal users partial reads > should be treated as failure. What are we supposed to do with a partial > read? I don't think anyone has asked for partial reads to be supported > from sysfs either except Greg was wondering about it while reading the > code. > > Currently, a lot of drivers return -EINVAL for partial read/writes but > some return success. It is a bit messy. But this patchset doesn't > really improve anything. In at24_read() we check if it's going to be a > partial read and return -EINVAL. Below we report a partial read as a > full read. It's just a more complicated way of doing exactly what we > were doing before. Currently what drivers return is up to their interpretation of int return type, there are a few drivers which also return the number of bytes written/read already like drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c . The objective of the patch was to handle partial reads and errors at the nvmem core and instead of leaving it up to each nvmem provider by providing a better return value to nvmem providers. Regarding drivers/misc/eeprom/at25.c which you pointed below, that is a problem in my code change. I missed that count was modified later on and should initialize bytes_written to the new value of count, will fix that when I come up with the new patch. I agree that it does not improve anything for a lot of nvmem providers for example the ones which call into other reg_map_read/write apis which do not return the number of bytes read/written but it does help us do better error handling at the nvmem core layer for nvmem providers who can return the valid number of bytes read/written. Please let me know if you have any other suggestions on how to handle this better. Thanks Joy > > drivers/misc/eeprom/at25.c > 198 static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) > 199 { > 200 struct at25_data *at25 = priv; > 201 size_t maxsz = spi_max_transfer_size(at25->spi); > New: size_t bytes_written = count; > ^^^^^^^^^^^^^^^^^^^^^ > This is not the number of bytes written. > > 202 const char *buf = val; > 203 int status = 0; > 204 unsigned buf_size; > 205 u8 *bounce; > 206 > 207 if (unlikely(off >= at25->chip.byte_len)) > 208 return -EFBIG; > 209 if ((off + count) > at25->chip.byte_len) > 210 count = at25->chip.byte_len - off; > ^^^^^ > This is. > > 211 if (unlikely(!count)) > 212 return -EINVAL; > 213 > 214 /* Temp buffer starts with command and address */ > 215 buf_size = at25->chip.page_size; > 216 if (buf_size > io_limit) > 217 buf_size = io_limit; > 218 bounce = kmalloc(buf_size + at25->addrlen + 1, GFP_KERNEL); > 219 if (!bounce) > 220 return -ENOMEM; > 221 > > regards, > dan carpenter
On Thu, Jun 06, 2024 at 03:12:03PM +0530, Joy Chakraborty wrote: > > These functions are used internally and exported to the user through > > sysfs via bin_attr_nvmem_read/write(). For internal users partial reads > > should be treated as failure. What are we supposed to do with a partial > > read? I don't think anyone has asked for partial reads to be supported > > from sysfs either except Greg was wondering about it while reading the > > code. > > > > Currently, a lot of drivers return -EINVAL for partial read/writes but > > some return success. It is a bit messy. But this patchset doesn't > > really improve anything. In at24_read() we check if it's going to be a > > partial read and return -EINVAL. Below we report a partial read as a > > full read. It's just a more complicated way of doing exactly what we > > were doing before. > > Currently what drivers return is up to their interpretation of int > return type, there are a few drivers which also return the number of > bytes written/read already like > drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c . Returning non-zero is a bug. It won't break bin_attr_nvmem_read/write() but it will break other places like nvmem_access_with_keepouts(), __nvmem_cell_read() and nvmem_cell_prepare_write_buffer() where all non-zero returns from nvmem_reg_read() are treated as an error. > The objective of the patch was to handle partial reads and errors at > the nvmem core and instead of leaving it up to each nvmem provider by > providing a better return value to nvmem providers. > > Regarding drivers/misc/eeprom/at25.c which you pointed below, that is > a problem in my code change. I missed that count was modified later on > and should initialize bytes_written to the new value of count, will > fix that when I come up with the new patch. > > I agree that it does not improve anything for a lot of nvmem providers > for example the ones which call into other reg_map_read/write apis > which do not return the number of bytes read/written but it does help > us do better error handling at the nvmem core layer for nvmem > providers who can return the valid number of bytes read/written. If we're going to support partial writes, then it needs to be done all the way. We need to audit functions like at24_read() and remove the -EINVAL lines. 440 if (off + count > at24->byte_len) 441 return -EINVAL; It should be: if (off + count > at24->byte_len) count = at24->byte_len - off; Some drivers handle writing zero bytes as -EINVAL and some return 0. Those changes could be done before we change the API. You updated nvmem_access_with_keepouts() to handle negative returns but not zero returns so it could lead to a forever loop. regards, dan carpenter
On Thu, Jun 6, 2024 at 3:41 PM Dan Carpenter <dan.carpenter@linaro.org> wrote: > > On Thu, Jun 06, 2024 at 03:12:03PM +0530, Joy Chakraborty wrote: > > > These functions are used internally and exported to the user through > > > sysfs via bin_attr_nvmem_read/write(). For internal users partial reads > > > should be treated as failure. What are we supposed to do with a partial > > > read? I don't think anyone has asked for partial reads to be supported > > > from sysfs either except Greg was wondering about it while reading the > > > code. > > > > > > Currently, a lot of drivers return -EINVAL for partial read/writes but > > > some return success. It is a bit messy. But this patchset doesn't > > > really improve anything. In at24_read() we check if it's going to be a > > > partial read and return -EINVAL. Below we report a partial read as a > > > full read. It's just a more complicated way of doing exactly what we > > > were doing before. > > > > Currently what drivers return is up to their interpretation of int > > return type, there are a few drivers which also return the number of > > bytes written/read already like > > drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c . > > Returning non-zero is a bug. It won't break bin_attr_nvmem_read/write() > but it will break other places like nvmem_access_with_keepouts(), > __nvmem_cell_read() and nvmem_cell_prepare_write_buffer() where all > non-zero returns from nvmem_reg_read() are treated as an error. > Yes, I will resend the patch to fix that. > > The objective of the patch was to handle partial reads and errors at > > the nvmem core and instead of leaving it up to each nvmem provider by > > providing a better return value to nvmem providers. > > > > Regarding drivers/misc/eeprom/at25.c which you pointed below, that is > > a problem in my code change. I missed that count was modified later on > > and should initialize bytes_written to the new value of count, will > > fix that when I come up with the new patch. > > > > I agree that it does not improve anything for a lot of nvmem providers > > for example the ones which call into other reg_map_read/write apis > > which do not return the number of bytes read/written but it does help > > us do better error handling at the nvmem core layer for nvmem > > providers who can return the valid number of bytes read/written. > > If we're going to support partial writes, then it needs to be done all > the way. We need to audit functions like at24_read() and remove the > -EINVAL lines. > > 440 if (off + count > at24->byte_len) > 441 return -EINVAL; > > It should be: > > if (off + count > at24->byte_len) > count = at24->byte_len - off; > > Some drivers handle writing zero bytes as -EINVAL and some return 0. > Those changes could be done before we change the API. > Sure, we can do it in a phased manner like you suggested in another reply by creating new pointers and slowly moving each driver to the new pointer and then deprecating the old one. > You updated nvmem_access_with_keepouts() to handle negative returns but > not zero returns so it could lead to a forever loop. > Yes, that is a possible case. Will rework it. > regards, > dan carpenter > Thanks Joy
On 06/06/2024 09:41, Dan Carpenter wrote: > So the original bug was that rmem_read() is returning positive values > on success instead of zero[1]. That started a discussion about partial > reads which resulted in changing the API to support partial reads[2]. > That patchset broke the build. This patchset is trying to fix the > build breakage. > > [1]https://lore.kernel.org/all/20240206042408.224138-1-joychakr@google.com/ > [2]https://lore.kernel.org/all/20240510082929.3792559-2-joychakr@google.com/ > > The bug in rmem_read() is still not fixed. That needs to be fixed as > a stand alone patch. We can discuss re-writing the API separately. I agree with Dan, Lets fix the rmem_read and start working on the API rework in parallel. Am happy to pick the [1]. --srini
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 595ceb9a7126..73d60f80aea8 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -74,8 +74,8 @@ struct at25_data { #define io_limit PAGE_SIZE /* bytes */ -static int at25_ee_read(void *priv, unsigned int offset, - void *val, size_t count) +static ssize_t at25_ee_read(void *priv, unsigned int offset, + void *val, size_t count) { struct at25_data *at25 = priv; char *buf = val; @@ -147,7 +147,7 @@ static int at25_ee_read(void *priv, unsigned int offset, dev_dbg(&at25->spi->dev, "read %zu bytes at %d\n", count, offset); - return 0; + return count; } /* Read extra registers as ID or serial number */ @@ -195,10 +195,11 @@ static struct attribute *sernum_attrs[] = { }; ATTRIBUTE_GROUPS(sernum); -static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) +static ssize_t at25_ee_write(void *priv, unsigned int off, void *val, size_t count) { struct at25_data *at25 = priv; size_t maxsz = spi_max_transfer_size(at25->spi); + size_t bytes_written = count; const char *buf = val; int status = 0; unsigned buf_size; @@ -313,7 +314,7 @@ static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) mutex_unlock(&at25->lock); kfree(bounce); - return status; + return status < 0 ? status : bytes_written; } /*-------------------------------------------------------------------------*/