From: Jakub Kicinski <kuba@kernel.org>
To: ahmadexp@gmail.com
Cc: Jakub Kicinski <kuba@kernel.org>,
netdev@vger.kernel.org, lee@kernel.org, pavel@kernel.org,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
andi.shyti@kernel.org, peda@lysator.liu.se, trannamatk@gmail.com,
vadim.fedorenko@linux.dev, richardcochran@gmail.com,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
pabeni@redhat.com, kees@kernel.org, gustavoars@kernel.org,
linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-hardening@vger.kernel.org
Subject: Re: [PATCH net-next v5 4/7] ptp: ocp: Track EEPROM fields independently
Date: Tue, 18 Aug 2026 09:57:17 -0700 [thread overview]
Message-ID: <20260818165717.4008441-1-kuba@kernel.org> (raw)
In-Reply-To: <3186cc1f1c51b548439fda558e9e4052a481b787.1786747084.git.ahmadexp@gmail.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
ptp: ocp: Track EEPROM fields independently
This replaces the single has_eeprom_data flag with per-field has_board_id
and has_serial flags, serializes EEPROM discovery under a new eeprom_lock
mutex, and makes ptp_ocp_read_eeprom() take a field mask and return an
error. devlink now publishes whichever field is available and
serialnum_show() propagates read errors.
No Link: tags in the commit header.
The commit message describes fixing a user-visible defect:
"Requiring both reads to succeed before publishing either field makes a
missing serial EEPROM block board profile selection and hides an otherwise
valid board ID."
[Severity: Low]
Should this carry a Fixes: tag? The condition described is reachable on
shipping hardware: fb_eeprom_map places board_id on the untagged '24c02'
client and serial on the "mac" tagged '24mac402' client, so one of the two
can be absent while the other works, and the old code gated both
ptp_ocp_devlink_info_get() and serialnum_show() on has_eeprom_data. The
all-or-nothing reader, the two-entry map with the "mac" tag and the devlink
publication all came in with commit 0cfcdd1ebcfe ("ptp: ocp: add nvmem
interface for accessing eeprom"), which would be the Fixes: target.
If this is instead meant as preparatory work and not stable material (the
patch does change sysfs error semantics), could the changelog say so
explicitly?
> diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
> index 3d26ec1f7b9ec..31a4c9dfe391c 100644
> --- a/drivers/ptp/ptp_ocp.c
> +++ b/drivers/ptp/ptp_ocp.c
[ ... ]
> @@ -1969,21 +1977,50 @@ ptp_ocp_nvmem_device_put(struct nvmem_device **nvmemp)
> *nvmemp = NULL;
> }
>
> -static void
> -ptp_ocp_read_eeprom(struct ptp_ocp *bp)
> +static int
> +ptp_ocp_read_eeprom(struct ptp_ocp *bp, unsigned int fields)
> {
> const struct ptp_ocp_eeprom_map *map;
> struct nvmem_device *nvmem;
> + u8 data[OCP_BOARD_ID_LEN];
> + const char *field_name = "data";
> const void *tag;
> - int ret;
> -
> - if (!bp->i2c_ctrl)
> - return;
> + unsigned int field;
> + int ret = 0;
>
> tag = NULL;
> nvmem = NULL;
> + mutex_lock(&bp->eeprom_lock);
> + fields &= OCP_EEPROM_ALL;
> + if (bp->has_board_id)
> + fields &= ~OCP_EEPROM_BOARD_ID;
> + if (bp->has_serial)
> + fields &= ~OCP_EEPROM_SERIAL;
> + if (!fields)
> + goto out;
> + if (!bp->i2c_ctrl || !bp->eeprom_map) {
> + ret = -ENODEV;
> + goto out;
> + }
>
> for (map = bp->eeprom_map; map->len; map++) {
> + if (map->bp_offset == offsetof(struct ptp_ocp, board_id)) {
> + field = OCP_EEPROM_BOARD_ID;
> + field_name = "board ID";
> + if (bp->has_board_id)
> + continue;
> + } else if (map->bp_offset == offsetof(struct ptp_ocp, serial)) {
> + field = OCP_EEPROM_SERIAL;
> + field_name = "serial number";
> + if (bp->has_serial)
> + continue;
> + } else {
> + continue;
> + }
> +
> + if (!(fields & field))
> + continue;
> +
> if (map->tag != tag) {
> tag = map->tag;
> ptp_ocp_nvmem_device_put(&nvmem);
> @@ -1992,24 +2029,34 @@ ptp_ocp_read_eeprom(struct ptp_ocp *bp)
> nvmem = ptp_ocp_nvmem_device_get(bp, tag);
> if (IS_ERR(nvmem)) {
> ret = PTR_ERR(nvmem);
> - goto fail;
> + goto out;
> }
> }
> - ret = nvmem_device_read(nvmem, map->off, map->len,
> - BP_MAP_ENTRY_ADDR(bp, map));
> - if (ret != map->len)
> - goto fail;
> + ret = nvmem_device_read(nvmem, map->off, map->len, data);
> + if (ret < 0)
> + goto out;
[Severity: Medium]
Are the two fields really independent in both directions here? Both failure
paths inside the loop, the ptp_ocp_nvmem_device_get() failure and this
nvmem_device_read() failure, leave the map walk entirely rather than
recording a failure for that one field and moving on to the next requested
entry.
fb_eeprom_map lists the board ID first, and it lives on a different I2C
client than the serial number:
drivers/ptp/ptp_ocp.c:
static struct ptp_ocp_eeprom_map fb_eeprom_map[] = {
{ EEPROM_ENTRY(0x43, board_id) },
{ EEPROM_ENTRY(0x00, serial), .tag = "mac" },
{ }
};
So if the '24c02' board-ID EEPROM is missing or unreadable while the
'24mac402' MAC EEPROM is fine, ptp_ocp_devlink_info_get() calls
ptp_ocp_read_eeprom(bp, OCP_EEPROM_ALL), the walk bails on the first entry
and the serial entry is never attempted. has_serial stays false, so
devlink_info_serial_number_put() is skipped on every subsequent request.
Isn't that the mirror image of the case the changelog says it removes, "Let
devlink report whichever fields are available"? Would a per-field error
that continues to the next map entry be closer to the intent?
The serialnum sysfs path escapes this only because it asks for
OCP_EEPROM_SERIAL and skips the board-ID entry.
> +
> + memcpy(BP_MAP_ENTRY_ADDR(bp, map), data, map->len);
> + if (field == OCP_EEPROM_BOARD_ID) {
> + /* Publish the field before marking it ready. */
> + smp_store_release(&bp->has_board_id, true);
> + } else {
> + /* Publish the field before marking it ready. */
> + smp_store_release(&bp->has_serial, true);
> + }
> }
>
> - bp->has_eeprom_data = true;
> + ret = 0;
>
> out:
> + if (ret && ret != -EPROBE_DEFER && !bp->eeprom_error_reported) {
> + dev_err(&bp->pdev->dev, "failed to read EEPROM %s: %pe\n",
> + field_name, ERR_PTR(ret));
> + bp->eeprom_error_reported = true;
> + }
> ptp_ocp_nvmem_device_put(&nvmem);
> - return;
> -
> -fail:
> - dev_err(&bp->pdev->dev, "could not read eeprom: %d\n", ret);
> - goto out;
> + mutex_unlock(&bp->eeprom_lock);
> + return ret;
> }
[ ... ]
> @@ -2166,24 +2214,24 @@ ptp_ocp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
> if (err)
> return err;
>
> - if (!bp->has_eeprom_data) {
> - ptp_ocp_read_eeprom(bp);
> - if (!bp->has_eeprom_data)
> - return 0;
> - }
> + ptp_ocp_read_eeprom(bp, OCP_EEPROM_ALL);
[ ... ]
> @@ -3757,9 +3805,17 @@ static ssize_t
> serialnum_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct ptp_ocp *bp = dev_get_drvdata(dev);
> + int ret;
>
> - if (!bp->has_eeprom_data)
> - ptp_ocp_read_eeprom(bp);
> + /* Pairs with field publication in ptp_ocp_read_eeprom(). */
> + if (!smp_load_acquire(&bp->has_serial)) {
> + ret = ptp_ocp_read_eeprom(bp, OCP_EEPROM_SERIAL);
> + if (ret)
> + return ret;
[Severity: Medium]
Can this hand -EPROBE_DEFER to userspace? ptp_ocp_read_eeprom() gets the
nvmem device through ptp_ocp_nvmem_device_get() -> nvmem_device_find() ->
__nvmem_device_get(), and when bus_find_device() finds no matching nvmem
device that returns -EPROBE_DEFER:
drivers/nvmem/core.c:__nvmem_device_get() {
...
if (!nvmem)
return ERR_PTR(-EPROBE_DEFER);
...
}
ptp_ocp_read_eeprom() stores that with "ret = PTR_ERR(nvmem); goto out;" and
returns it unchanged; the "ret != -EPROBE_DEFER" test at the out: label only
suppresses the dev_err(), not the return value. serialnum_show() then
returns it directly, so reading
/sys/class/timecard/ocpN/serialnum with the serial EEPROM's nvmem device not
registered (no 24mac402, at24 not bound yet) gives read(2) errno 517.
That is exactly the "serial EEPROM absent" case this patch targets, and the
attribute is world readable. Would translating internal codes to something
like -ENODEV, -EAGAIN or the -ENODATA already used below be preferable
before crossing the syscall boundary?
> + /* Pairs with field publication in ptp_ocp_read_eeprom(). */
> + if (!smp_load_acquire(&bp->has_serial))
> + return -ENODATA;
> + }
>
> return sysfs_emit(buf, "%pM\n", bp->serial);
> }
[ ... ]
next prev parent reply other threads:[~2026-08-18 16:57 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 23:10 [PATCH net-next v5 0/7] ptp: ocp: Add R4006 and V9 I2C peripheral support Ahmad Byagowi
2026-08-14 23:10 ` [PATCH net-next v5 1/7] dt-bindings: leds: Add IS32FL3207 controller Ahmad Byagowi
2026-08-15 23:11 ` sashiko-bot
2026-08-17 6:41 ` Krzysztof Kozlowski
2026-08-17 18:06 ` Ahmad Byagowi
2026-08-18 16:57 ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 2/7] leds: is32fl3207: Add controller driver Ahmad Byagowi
2026-08-15 23:11 ` sashiko-bot
2026-08-18 16:57 ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 3/7] i2c: mux: Propagate software nodes to channel adapters Ahmad Byagowi
2026-08-15 23:11 ` sashiko-bot
2026-08-18 16:57 ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 4/7] ptp: ocp: Track EEPROM fields independently Ahmad Byagowi
2026-08-15 23:11 ` sashiko-bot
2026-08-18 16:57 ` Jakub Kicinski [this message]
2026-08-14 23:10 ` [PATCH net-next v5 5/7] ptp: ocp: Add profile-driven I2C topology support Ahmad Byagowi
2026-08-15 23:11 ` sashiko-bot
2026-08-18 16:57 ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 6/7] ptp: ocp: Add R4006 I2C peripheral topology Ahmad Byagowi
2026-08-15 23:11 ` sashiko-bot
2026-08-18 16:57 ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 7/7] ptp: ocp: Add Time Card V9 " Ahmad Byagowi
2026-08-15 23:11 ` sashiko-bot
2026-08-18 16:57 ` Jakub Kicinski
2026-08-18 16:56 ` [PATCH net-next v5 0/7] ptp: ocp: Add R4006 and V9 I2C peripheral support Jakub Kicinski
2026-08-18 18:12 ` Ahmad Byagowi
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=20260818165717.4008441-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=ahmadexp@gmail.com \
--cc=andi.shyti@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=gustavoars@kernel.org \
--cc=kees@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lee@kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pavel@kernel.org \
--cc=peda@lysator.liu.se \
--cc=richardcochran@gmail.com \
--cc=robh@kernel.org \
--cc=trannamatk@gmail.com \
--cc=vadim.fedorenko@linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.