Re: [PATCH v4 char-misc-next] misc: microchip: pci1xxxx: Add OTP/EEPROM driver for the pci1xxxx switch

From: Greg KH
Date: Thu Feb 09 2023 - 03:55:15 EST


On Thu, Feb 09, 2023 at 10:12:37AM +0530, Tharun Kumar P wrote:
> +static int e2p_device_write_byte(struct pci1xxxx_otp_e2p_device *priv,
> + unsigned long byte_offset, u8 value)
> +{
> + u32 data;
> +
> + /* Write the value into EEPROM_DATA_REG register */
> + writel(value, priv->reg_base + MMAP_EEPROM_OFFSET(EEPROM_DATA_REG));
> + data = EEPROM_CMD_EPC_TIMEOUT_BIT | EEPROM_CMD_EPC_WRITE | byte_offset;
> +
> + /* Write the data into EEPROM_CMD_REG register */
> + writel(data, priv->reg_base + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
> +
> + /* Set the EPC_BUSY bit of EEPROM_CMD_REG register */
> + writel(EEPROM_CMD_EPC_BUSY_BIT | data, priv->reg_base +
> + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
> +
> + /* Wait for the EPC_BUSY bit to get cleared */
> + do {
> + data = readl(priv->reg_base + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
> + } while (data & EEPROM_CMD_EPC_BUSY_BIT);

That's a very busy "sit and spin" loop here, what happens if the read of
the bit never actually succeeds? You just locked up the system with no
way to interrupt it :(

Please provide some sort of timeout, or way to break out of this.

> +
> + if (data & EEPROM_CMD_EPC_TIMEOUT_BIT) {
> + dev_err(&priv->pdev->dev, "EEPROM write timed out\n");

How can the timeout bit happen if the busy bit was still set?

And what can userspace do about this if it is reported?

> + return -EFAULT;

This return value is ONLY for when we have memory faults from reading
to/from userspace and the kernel. It's not a valid return value for a
device error, sorry. -EIO maybe?

You return this error in a number of other places in the driver that
shouldn't, please fix this up.

Also the loop issue is in your read_byte call and the same review
comments apply there.

thanks,

greg k-h