On Tue, 2024-02-27 at 18:38 -0800, Kuppuswamy Sathyanarayanan wrote: > > On 2/27/24 4:00 PM, David E. Box wrote: > > The current mailbox commands are either read-only or write-only and the > > flow is different for each. New commands will need to send and receive > > data. In preparation for these commands, create a common polling function > > to handle sending data and receiving in the same transaction. > > > > Signed-off-by: David E. Box <david.e.box@xxxxxxxxxxxxxxx> > > --- > > > > V2 - In sdsi_cmd_read() remove unnecessary check for non-zero packet_size > > in do loop since the loop is exited earlier when packet_size is > > zero. > > > > drivers/platform/x86/intel/sdsi.c | 79 +++++++++++++++++-------------- > > 1 file changed, 44 insertions(+), 35 deletions(-) > > > > diff --git a/drivers/platform/x86/intel/sdsi.c > > b/drivers/platform/x86/intel/sdsi.c > > index a70c071de6e2..d80c2dc0ce71 100644 > > --- a/drivers/platform/x86/intel/sdsi.c > > +++ b/drivers/platform/x86/intel/sdsi.c > > @@ -15,6 +15,7 @@ > > #include <linux/iopoll.h> > > #include <linux/kernel.h> > > #include <linux/module.h> > > +#include <linux/overflow.h> > > #include <linux/pci.h> > > #include <linux/slab.h> > > #include <linux/sysfs.h> > > @@ -156,8 +157,8 @@ static int sdsi_status_to_errno(u32 status) > > } > > } > > > > -static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info > > *info, > > - size_t *data_size) > > +static int sdsi_mbox_poll(struct sdsi_priv *priv, struct sdsi_mbox_info > > *info, > > + size_t *data_size) > > { > > struct device *dev = priv->dev; > > u32 total, loop, eom, status, message_size; > > @@ -166,18 +167,10 @@ static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, > > struct sdsi_mbox_info *inf > > > > lockdep_assert_held(&priv->mb_lock); > > > > - /* Format and send the read command */ > > - control = FIELD_PREP(CTRL_EOM, 1) | > > - FIELD_PREP(CTRL_SOM, 1) | > > - FIELD_PREP(CTRL_RUN_BUSY, 1) | > > - FIELD_PREP(CTRL_PACKET_SIZE, info->size); > > - writeq(control, priv->control_addr); > > - > > /* For reads, data sizes that are larger than the mailbox size are > > read in packets. */ > > total = 0; > > loop = 0; > > do { > > - void *buf = info->buffer + (SDSI_SIZE_MAILBOX * loop); > > u32 packet_size; > > > > /* Poll on ready bit */ > > @@ -195,6 +188,11 @@ static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, > > struct sdsi_mbox_info *inf > > if (ret) > > break; > > > > + if (!packet_size) { > > + sdsi_complete_transaction(priv); > > + break; > > + } > > + > > /* Only the last packet can be less than the mailbox size. > > */ > > if (!eom && packet_size != SDSI_SIZE_MAILBOX) { > > dev_err(dev, "Invalid packet size\n"); > > @@ -208,9 +206,13 @@ static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, > > struct sdsi_mbox_info *inf > > break; > > } > > > > - sdsi_memcpy64_fromio(buf, priv->mbox_addr, > > round_up(packet_size, SDSI_SIZE_CMD)); > > + if (info->buffer) { > > + void *buf = info->buffer + > > array_size(SDSI_SIZE_MAILBOX, loop); > > > > - total += packet_size; > > + sdsi_memcpy64_fromio(buf, priv->mbox_addr, > > + round_up(packet_size, > > SDSI_SIZE_CMD)); > > + total += packet_size; > > + } > > > > sdsi_complete_transaction(priv); > > } while (!eom && ++loop < MBOX_MAX_PACKETS); > > @@ -230,16 +232,33 @@ static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, > > struct sdsi_mbox_info *inf > > dev_warn(dev, "Read count %u differs from expected count > > %u\n", > > total, message_size); > > > > - *data_size = total; > > + if (data_size) > > + *data_size = total; > > > > Is there a chance for it to be NULL with current callers? Yes. Write only callers set this to NULL. David