public inbox for linux-i2c@vger.kernel.org
 help / color / mirror / Atom feed
From: Wolfram Sang <w.sang-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
To: Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
Cc: David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>,
	i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
Subject: Re: [PATCH] Add a new-style driver for most I2C EEPROMs
Date: Mon, 2 Jun 2008 18:21:54 +0200	[thread overview]
Message-ID: <20080602162154.GA11141@pengutronix.de> (raw)
In-Reply-To: <20080522222022.68d65cd7-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>


[-- Attachment #1.1: Type: text/plain, Size: 6047 bytes --]

Hi Jean,

some more comments while working on the driver:

> > +static struct i2c_client *at24_ee_address(struct at24_data *at24, u16 *addr,
> > +		unsigned *offset)
> > +{
> > +	struct at24_platform_data *chip = &at24->chip;
> > +	unsigned i;
> > +
> > +	if (*offset >= chip->byte_len)
> > +		return NULL;
> > +
> > +	if (chip->flags & AT24_EE_ADDR2) {
> > +		i = *offset >> 16;
> > +		*offset &= 0xffff;
> > +	} else {
> > +		i = *offset >> 8;
> > +		*offset &= 0xff;
> > +	}
> > +
> > +	if (unlikely(i > chip->i2c_addr_mask)) {
> > +		dev_err(&at24->client[0]->dev,
> > +			"requested client %u not available!\n", i);
> > +		return NULL;
> > +	}
> 
> That's not just unlikely... that would be a bug in the driver, right?
> This could be protected by #ifdef DEBUG, to not slow down the driver
> uselessly.
This error case can happen, if the supplied 'byte_len' and
'i2c_addr_mask' don't fit. I will put this check to the probe-function,
this should also do. Calculating i2c_addr_mask from byte_len still gives
me headaches, although I'd also like this to happen (see later).

> > +	/*
> > +	 * When we have a better choice than SMBus calls, use a combined
> > +	 * I2C message.  Write address; then read up to io_limit data bytes.
> > +	 * Note that read page rollover helps us here (unlike writes).
> > +	 */
> > +	msg[0].buf = addr;
> > +	addr[1] = (u8) offset;
> 
> Please use a proper mask instead of a cast, it's clearer what you're
> doing.
> 
> > +	addr[0] = (u8) (offset >> 8);
> 
> Cast is not needed.

I tend to change it like this:

	offset_be = cpu_to_be16(offset);
        msg[0].buf = (u8 *) &offset_be;

> > +static ssize_t at24_ee_write(struct at24_data *at24, char *buf,
> > loff_t off, +		size_t count) +{ +	struct
> > i2c_client *client; +	struct i2c_msg  msg;
> 
> Doubled space.
> 
> > +	unsigned offset = (unsigned) off;
> 
> Why don't you simply make the offset parameter an unsigned int, if
> that's what you want?
I changed the parameter to unsigned. But I think I need to have another
look, not that we are bitten by some cast-sideeffects.

> > +	/* buffer big enough to stick the address at the beginning */
> > +	at24->writebuf = kmalloc(at24->write_max + 2, GFP_KERNEL);
> > +	if (!at24->writebuf) {
> > +		retval = -ENOMEM;
> > +		count = 0;
> > +	}
> 
> You could move this to before taking the mutex (using a temporary
> pointer), so that you can return with an error immediately if
> allocation fails. But more importantly: do you really need to allocate
> and free a new buffer for each write? You serialize the writes, and the
> size of the buffer doesn't depend on the actual write operation, so you
> might as well allocate the buffer as part of at24_probe(), this will
> make write operations faster and will avoid useless memory
> fragmentation.
> 
> If you are really worried about the memory waste in case the user
> doesn't actually write to the EEPROM, you could alternatively allocate
> the buffer on the first write, and free it in the .remove() method.
Now, I allocate it in probe when the EEPROM is selected to be writable.

> > +	/* Use I2C operations unless we're stuck with SMBus extensions. */
> > +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> > +		if (chip->flags & AT24_EE_ADDR2) {
> > +			err = -ECOMM;
> > +			goto fail;
> > +		}
> > +		if (!i2c_check_functionality(client->adapter,
> > +				I2C_FUNC_SMBUS_I2C_BLOCK)) {
> > +			err = -EBADMSG;
> > +			goto fail;
> > +		}
> 
> These are definitely not the correct error values. I also see no
> reason to return different error values for the two cases as the
> problem is exactly the same: underlying adapter doesn't support the
> transaction types needed to talk to the EEPROM. What about -EOPNOTSUPP?
> Or -ENODEV.
Ah, errno-fun. -EPFNOSUPPORT?

> > +	/* use dummy devices for multiple-address chips */
> > +	if (chip->i2c_addr_mask) {
> > +		for (i = 1; i <= chip->i2c_addr_mask; i++) {
> > +			c = i2c_new_dummy(client->adapter, client->addr + i);
> > +			if (!c) {
> > +				dev_err(&client->dev, "addr %d unavail\n",
> 
> Please spell words in error messages completely. Address should be
> printed in hexadecimal, that's what developers and users are used to.
> 
> > +						client->addr + i);
> > +				err = -ENOCSI;
> 
> Again a funky error value, completely unrelated with the error that
> occurred. -EBUSY?
-EADDRINUSE?

> > +cleanup:
> > +	if (chip->i2c_addr_mask) {
> 
> Note that this test is not needed: the for loop below won't do anything
> if i2c_addr_mask == 0.
I thought it would be cleaner to skip the for-loop if it is not needed.
Otherwise it may look like a bug easily. Then again, a comment would
also help.

> 
> > +		for (i = 1; i <= chip->i2c_addr_mask; i++) {
> > +			c = at24->client[i];
> > +			if (c)
> > +				i2c_unregister_device(c);
> > + *	- What write page size does it support?
> > + */
> > +
> > +struct at24_platform_data {
> > +	u32		byte_len;		/* size (sum of all addr) */
> > +	u16		page_size;		/* for writes */
> > +	u8		i2c_addr_mask;		/* for multi-addr chips */
> 
> This notion of i2c_addr_mask seems more restrictive and easy to get
> wrong than it needs to be. What you really have is a number of slave
> I2C addresses, that's more intuitive IMHO, and using this would save a
> couple "+ 1" in the code. As a matter of fact, that's what you
> described in the comment above.
> 
> Oh, BTW, can't you compute this value yourself from byte_len and (flags
> & AT24_EE_ADDR2)? I think so...
There is at least one exception already (24c00) which covers eight
addresses but actually just needs one. This spoils the calculation of
i2c_addr_mask (and if there is one case, there will be others) :( I
agree, that num_addresses might be more apropriate than i2c_addr_mask.

Kind regards,

   Wolfram

-- 
  Dipl.-Ing. Wolfram Sang | http://www.pengutronix.de
 Pengutronix - Linux Solutions for Science and Industry

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
i2c mailing list
i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
http://lists.lm-sensors.org/mailman/listinfo/i2c

  parent reply	other threads:[~2008-06-02 16:21 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-15 20:36 [PATCH] Add a new-style driver for most I2C EEPROMs Wolfram Sang
     [not found] ` <1210883799-25188-1-git-send-email-w.sang-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2008-05-22 20:20   ` Jean Delvare
     [not found]     ` <20080522222022.68d65cd7-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-05-22 21:35       ` David Brownell
     [not found]         ` <200805221435.36829.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-05-23  7:17           ` Jean Delvare
     [not found]             ` <20080523091703.2ba86bb1-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-05-24 21:11               ` David Brownell
2008-05-30  9:15       ` Wolfram Sang
     [not found]         ` <20080530091534.GB727-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2008-05-30  9:51           ` Jean Delvare
     [not found]             ` <20080530115131.0e111fdb-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-05-30 10:45               ` Wolfram Sang
2008-06-02 16:21       ` Wolfram Sang [this message]
     [not found]         ` <20080602162154.GA11141-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2008-06-02 18:50           ` Jean Delvare
     [not found]             ` <20080602205034.3e2b392b-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-06-02 19:33               ` David Brownell
     [not found]                 ` <200806021233.46781.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-06-02 19:48                   ` Jean Delvare
     [not found]                     ` <20080602214823.15ca190b-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-06-03 20:36                       ` David Brownell
     [not found]                         ` <200806031336.35678.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-06-03 21:19                           ` Jean Delvare
     [not found]                             ` <20080603231927.61f9eb61-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-06-04 11:51                               ` Wolfram Sang
2008-06-08  8:40                           ` Jean Delvare
     [not found]                             ` <20080608104038.006be072-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-06-08 20:26                               ` David Brownell
2008-05-23  7:21   ` Jean Delvare
  -- strict thread matches above, loose matches on Subject: below --
2008-04-11 11:43 Wolfram Sang
     [not found] ` <1207914198-8561-1-git-send-email-w.sang-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2008-04-11 12:24   ` Wolfram Sang
2008-04-14  7:22     ` Robert Schwebel
     [not found]       ` <20080414072227.GU13814-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2008-04-14 12:39         ` Jean Delvare
     [not found]           ` <20080414143925.31b55b39-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-04-14 15:57             ` David Brownell
     [not found]               ` <200804140857.33732.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-04-17 21:17                 ` David Brownell
     [not found]                   ` <200804171417.23753.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-04-18  8:07                     ` Trent Piepho
     [not found]                       ` <Pine.LNX.4.58.0804172346580.10592-nuiHJn5p267P3RPoUHIrnuTW4wlIGRCZ@public.gmane.org>
2008-04-18 10:31                         ` Wolfram Sang
     [not found]                           ` <20080418103149.GA4245-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2008-04-18 23:06                             ` Trent Piepho
     [not found]                               ` <Pine.LNX.4.58.0804181555560.15372-13q4cmjDBaTP3RPoUHIrnuTW4wlIGRCZ@public.gmane.org>
2008-04-21  9:17                                 ` Wolfram Sang
2008-04-21 17:20                                   ` Trent Piepho
     [not found]                                     ` <Pine.LNX.4.58.0804211005410.15697-nuiHJn5p267P3RPoUHIrnuTW4wlIGRCZ@public.gmane.org>
2008-04-24 10:47                                       ` Wolfram Sang
     [not found]                                         ` <20080424104740.GB4201-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2008-04-27  1:28                                           ` Trent Piepho
2008-04-18 16:48                         ` David Brownell
     [not found]                           ` <200804180948.15298.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-04-18 23:26                             ` Trent Piepho
2008-04-18  8:59                     ` Wolfram Sang
2008-04-15 10:13             ` Wolfram Sang
2008-04-17 16:05   ` Wolfram Sang
2008-04-17 16:24     ` Jean Delvare

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=20080602162154.GA11141@pengutronix.de \
    --to=w.sang-bicnvbalz9megne8c9+irq@public.gmane.org \
    --cc=david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org \
    --cc=i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org \
    --cc=khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org \
    /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