qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: minyard@acm.org
To: qemu-devel@nongnu.org, "Dr . David Alan Gilbert" <dgilbert@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	Corey Minyard <minyard@acm.org>,
	Peter Maydell <peter.maydell@linaro.org>,
	Corey Minyard <cminyard@mvista.com>
Subject: [Qemu-devel] [PATCH v4 06/19] i2c:smbus: Simplify write operation
Date: Mon, 28 Jan 2019 11:54:45 -0600	[thread overview]
Message-ID: <20190128175458.27255-7-minyard@acm.org> (raw)
In-Reply-To: <20190128175458.27255-1-minyard@acm.org>

From: Corey Minyard <cminyard@mvista.com>

There were two different write functions and the SMBus code kept
track of the command.

Keeping track of the command wasn't useful, in fact it wasn't quite
correct for the eeprom_smbus code.  And there is no need for two write
functions.  Just have one write function and the first byte in the
buffer is the command.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
 hw/i2c/smbus_eeprom.c        | 47 ++++++++++++------------------------
 hw/i2c/smbus_slave.c         | 25 ++++---------------
 include/hw/i2c/smbus_slave.h | 21 ++++++++++------
 3 files changed, 34 insertions(+), 59 deletions(-)

diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index d82423aa7e..3f9ed266f8 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -43,16 +43,6 @@ static void eeprom_quick_cmd(SMBusDevice *dev, uint8_t read)
 #endif
 }
 
-static void eeprom_send_byte(SMBusDevice *dev, uint8_t val)
-{
-    SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
-#ifdef DEBUG
-    printf("eeprom_send_byte: addr=0x%02x val=0x%02x\n",
-           dev->i2c.address, val);
-#endif
-    eeprom->offset = val;
-}
-
 static uint8_t eeprom_receive_byte(SMBusDevice *dev)
 {
     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
@@ -65,34 +55,30 @@ static uint8_t eeprom_receive_byte(SMBusDevice *dev)
     return val;
 }
 
-static void eeprom_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len)
+static int eeprom_write_data(SMBusDevice *dev, uint8_t *buf, uint8_t len)
 {
     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
-    int n;
+    uint8_t *data = eeprom->data;
+
 #ifdef DEBUG
     printf("eeprom_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n",
-           dev->i2c.address, cmd, buf[0]);
+           dev->i2c.address, buf[0], buf[1]);
 #endif
-    /* A page write operation is not a valid SMBus command.
-       It is a block write without a length byte.  Fortunately we
-       get the full block anyway.  */
-    /* TODO: Should this set the current location?  */
-    if (cmd + len > 256)
-        n = 256 - cmd;
-    else
-        n = len;
-    memcpy(eeprom->data + cmd, buf, n);
-    len -= n;
-    if (len)
-        memcpy(eeprom->data, buf + n, len);
+    /* len is guaranteed to be > 0 */
+    eeprom->offset = buf[0];
+    buf++;
+    len--;
+
+    for (; len > 0; len--) {
+        data[eeprom->offset] = *buf++;
+        eeprom->offset = (eeprom->offset + 1) % 256;
+    }
+
+    return 0;
 }
 
-static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
+static uint8_t eeprom_read_data(SMBusDevice *dev, int n)
 {
-    SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
-    /* If this is the first byte then set the current position.  */
-    if (n == 0)
-        eeprom->offset = cmd;
     /* As with writes, we implement block reads without the
        SMBus length byte.  */
     return eeprom_receive_byte(dev);
@@ -117,7 +103,6 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
 
     dc->realize = smbus_eeprom_realize;
     sc->quick_cmd = eeprom_quick_cmd;
-    sc->send_byte = eeprom_send_byte;
     sc->receive_byte = eeprom_receive_byte;
     sc->write_data = eeprom_write_data;
     sc->read_data = eeprom_read_data;
diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c
index 6a89a286e3..92c7a5086c 100644
--- a/hw/i2c/smbus_slave.c
+++ b/hw/i2c/smbus_slave.c
@@ -54,18 +54,9 @@ static void smbus_do_write(SMBusDevice *dev)
 {
     SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
 
-    if (dev->data_len == 1) {
-        DPRINTF("Send Byte\n");
-        if (sc->send_byte) {
-            sc->send_byte(dev, dev->data_buf[0]);
-        }
-    } else {
-        dev->command = dev->data_buf[0];
-        DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1);
-        if (sc->write_data) {
-            sc->write_data(dev, dev->command, dev->data_buf + 1,
-                           dev->data_len - 1);
-        }
+    DPRINTF("Command %d len %d\n", dev->data_buf[0], dev->data_len);
+    if (sc->write_data) {
+        sc->write_data(dev, dev->data_buf, dev->data_len);
     }
 }
 
@@ -98,13 +89,7 @@ static int smbus_i2c_event(I2CSlave *s, enum i2c_event event)
                 BADF("Read after write with no data\n");
                 dev->mode = SMBUS_CONFUSED;
             } else {
-                if (dev->data_len > 1) {
-                    smbus_do_write(dev);
-                } else {
-                    dev->command = dev->data_buf[0];
-                    DPRINTF("%02x: Command %d\n", dev->i2c.address,
-                            dev->command);
-                }
+                smbus_do_write(dev);
                 DPRINTF("Read mode\n");
                 dev->data_len = 0;
                 dev->mode = SMBUS_READ_DATA;
@@ -177,7 +162,7 @@ static uint8_t smbus_i2c_recv(I2CSlave *s)
         break;
     case SMBUS_READ_DATA:
         if (sc->read_data) {
-            ret = sc->read_data(dev, dev->command, dev->data_len);
+            ret = sc->read_data(dev, dev->data_len);
             dev->data_len++;
         } else {
             ret = 0;
diff --git a/include/hw/i2c/smbus_slave.h b/include/hw/i2c/smbus_slave.h
index 5ef1c72ad0..fa92201ec6 100644
--- a/include/hw/i2c/smbus_slave.h
+++ b/include/hw/i2c/smbus_slave.h
@@ -46,18 +46,24 @@ typedef struct SMBusDeviceClass
      * This may be NULL, quick commands are ignore in that case.
      */
     void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
-    void (*send_byte)(SMBusDevice *dev, uint8_t val);
+
     uint8_t (*receive_byte)(SMBusDevice *dev);
-    /* We can't distinguish between a word write and a block write with
-       length 1, so pass the whole data block including the length byte
-       (if present).  The device is responsible figuring out what type of
-       command  this is.  */
-    void (*write_data)(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len);
+
+    /*
+     * We can't distinguish between a word write and a block write with
+     * length 1, so pass the whole data block including the length byte
+     * (if present).  The device is responsible figuring out what type of
+     * command this is.
+     * This may be NULL if no data is written to the device.  Writes
+     * will be ignore in that case.
+     */
+    int (*write_data)(SMBusDevice *dev, uint8_t *buf, uint8_t len);
+
     /* Likewise we can't distinguish between different reads, or even know
        the length of the read until the read is complete, so read data a
        byte at a time.  The device is responsible for adding the length
        byte on block reads.  */
-    uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n);
+    uint8_t (*read_data)(SMBusDevice *dev, int n);
 } SMBusDeviceClass;
 
 struct SMBusDevice {
@@ -68,7 +74,6 @@ struct SMBusDevice {
     int mode;
     int data_len;
     uint8_t data_buf[34]; /* command + len + 32 bytes of data.  */
-    uint8_t command;
 };
 
 #endif
-- 
2.17.1

  parent reply	other threads:[~2019-01-28 18:01 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-28 17:54 [Qemu-devel] [PATCH v4 00/19] Fix/add vmstate handling in some I2C code minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 01/19] i2c: Split smbus into parts minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 02/19] i2c: have I2C receive operation return uint8_t minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 03/19] arm:i2c: Don't mask return from i2c_recv() minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 04/19] i2c: Don't check return value " minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 05/19] i2c:smbus: Correct the working of quick commands minyard
2019-01-28 17:54 ` minyard [this message]
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 07/19] i2c:smbus: Simplify read handling minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 08/19] i2c:smbus_eeprom: Get rid of the quick command minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 09/19] i2c:smbus: Make white space in switch statements consistent minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 10/19] boards.h: Ignore migration for SMBus devices on older machines minyard
2019-01-28 18:08   ` Eduardo Habkost
2019-01-28 18:22     ` Corey Minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 11/19] i2c:pm_smbus: Fix pm_smbus handling of I2C block read minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 12/19] migration: Add a VMSTATE_BOOL_TEST() macro minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 13/19] i2c:pm_smbus: Fix state transfer minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 14/19] i2c:smbus_slave: Add an SMBus vmstate structure minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 15/19] i2c:smbus_eeprom: Add normal type name and cast to smbus_eeprom.c minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 16/19] i2c:smbus_eeprom: Add a size constant for the smbus_eeprom size minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 17/19] i2c:smbus_eeprom: Add vmstate handling to the smbus eeprom minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 18/19] i2c:smbus_eeprom: Add a reset function to smbus_eeprom minyard
2019-01-28 17:54 ` [Qemu-devel] [PATCH v4 19/19] i2c: Verify that the count passed in to smbus_eeprom_init() is valid minyard

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=20190128175458.27255-7-minyard@acm.org \
    --to=minyard@acm.org \
    --cc=cminyard@mvista.com \
    --cc=dgilbert@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.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;
as well as URLs for NNTP newsgroup(s).