RE: [PATCH] vfio/pci: Fix SR-IOV VF handling with MMIO blocking

2020-06-27 Thread Wang, Haiyue
> -Original Message-
> From: Alex Williamson 
> Sent: Sunday, June 28, 2020 12:09
> To: Wang, Haiyue 
> Cc: k...@vger.kernel.org; linux-kernel@vger.kernel.org; 
> maxime.coque...@redhat.com; David Marchand
> ; Kevin Traynor 
> Subject: Re: [PATCH] vfio/pci: Fix SR-IOV VF handling with MMIO blocking
> 
> On Sun, 28 Jun 2020 03:12:12 +
> "Wang, Haiyue"  wrote:
> 
> > > -Original Message-
> > > From: kvm-ow...@vger.kernel.org  On Behalf Of 
> > > Alex Williamson
> > > Sent: Friday, June 26, 2020 00:57
> > > To: alex.william...@redhat.com
> > > Cc: k...@vger.kernel.org; linux-kernel@vger.kernel.org; 
> > > maxime.coque...@redhat.com
> > > Subject: [PATCH] vfio/pci: Fix SR-IOV VF handling with MMIO blocking
> > >
> > > SR-IOV VFs do not implement the memory enable bit of the command
> > > register, therefore this bit is not set in config space after
> > > pci_enable_device().  This leads to an unintended difference
> > > between PF and VF in hand-off state to the user.  We can correct
> > > this by setting the initial value of the memory enable bit in our
> > > virtualized config space.  There's really no need however to
> > > ever fault a user on a VF though as this would only indicate an
> > > error in the user's management of the enable bit, versus a PF
> > > where the same access could trigger hardware faults.
> > >
> > > Fixes: abafbc551fdd ("vfio-pci: Invalidate mmaps and block MMIO access on 
> > > disabled memory")
> > > Signed-off-by: Alex Williamson 
> > > ---
> > >  drivers/vfio/pci/vfio_pci_config.c |   17 -
> > >  1 file changed, 16 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/vfio/pci/vfio_pci_config.c 
> > > b/drivers/vfio/pci/vfio_pci_config.c
> > > index 8746c943247a..d98843feddce 100644
> > > --- a/drivers/vfio/pci/vfio_pci_config.c
> > > +++ b/drivers/vfio/pci/vfio_pci_config.c
> > > @@ -398,9 +398,15 @@ static inline void p_setd(struct perm_bits *p, int 
> > > off, u32 virt, u32 write)
> > >  /* Caller should hold memory_lock semaphore */
> > >  bool __vfio_pci_memory_enabled(struct vfio_pci_device *vdev)
> > >  {
> > > + struct pci_dev *pdev = vdev->pdev;
> > >   u16 cmd = le16_to_cpu(*(__le16 *)>vconfig[PCI_COMMAND]);
> > >
> > > - return cmd & PCI_COMMAND_MEMORY;
> > > + /*
> > > +  * SR-IOV VF memory enable is handled by the MSE bit in the
> > > +  * PF SR-IOV capability, there's therefore no need to trigger
> > > +  * faults based on the virtual value.
> > > +  */
> > > + return pdev->is_virtfn || (cmd & PCI_COMMAND_MEMORY);
> >
> > Hi Alex,
> >
> > After set up the initial copy of config space for memory enable bit for VF, 
> > is it worth
> > to trigger SIGBUS into the bad user space process which intentionally try 
> > to disable the
> > memory access command (even it is VF) then access the memory to trigger 
> > CVE-2020-12888 ?
> 
> We're essentially only trying to catch the user in mismanaging the
> enable bit if we trigger a fault based on the virtualized enabled bit,
> right?  There's no risk that the VF would trigger a UR based on the
> state of our virtual enable bit.  So is it worth triggering a user
> fault when, for instance, the user might be aware that the device is a
> VF and know that the memory enable bit is not relative to the physical

Emm .. I read the CVE attack description from: 
https://bugzilla.redhat.com/show_bug.cgi?id=1836244,
I thought it should also prevent the bad Guest VM, thanks for sharing the 
background more.

BR,
Haiyue

> device?  Thanks,
> 
> Alex
> 
> > >  }
> > >
> > >  /*
> > > @@ -1728,6 +1734,15 @@ int vfio_config_init(struct vfio_pci_device *vdev)
> > >vconfig[PCI_INTERRUPT_PIN]);
> > >
> > >   vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */
> > > +
> > > + /*
> > > +  * VFs do no implement the memory enable bit of the COMMAND
> > > +  * register therefore we'll not have it set in our initial
> > > +  * copy of config space after pci_enable_device().  For
> > > +  * consistency with PFs, set the virtual enable bit here.
> > > +  */
> > > + *(__le16 *)[PCI_COMMAND] |=
> > > + cpu_to_le16(PCI_COMMAND_MEMORY);
> > >   }
> > >
> > >   if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx)
> >



RE: [PATCH] vfio/pci: Fix SR-IOV VF handling with MMIO blocking

2020-06-27 Thread Wang, Haiyue
> -Original Message-
> From: kvm-ow...@vger.kernel.org  On Behalf Of Alex 
> Williamson
> Sent: Friday, June 26, 2020 00:57
> To: alex.william...@redhat.com
> Cc: k...@vger.kernel.org; linux-kernel@vger.kernel.org; 
> maxime.coque...@redhat.com
> Subject: [PATCH] vfio/pci: Fix SR-IOV VF handling with MMIO blocking
> 
> SR-IOV VFs do not implement the memory enable bit of the command
> register, therefore this bit is not set in config space after
> pci_enable_device().  This leads to an unintended difference
> between PF and VF in hand-off state to the user.  We can correct
> this by setting the initial value of the memory enable bit in our
> virtualized config space.  There's really no need however to
> ever fault a user on a VF though as this would only indicate an
> error in the user's management of the enable bit, versus a PF
> where the same access could trigger hardware faults.
> 
> Fixes: abafbc551fdd ("vfio-pci: Invalidate mmaps and block MMIO access on 
> disabled memory")
> Signed-off-by: Alex Williamson 
> ---
>  drivers/vfio/pci/vfio_pci_config.c |   17 -
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_config.c 
> b/drivers/vfio/pci/vfio_pci_config.c
> index 8746c943247a..d98843feddce 100644
> --- a/drivers/vfio/pci/vfio_pci_config.c
> +++ b/drivers/vfio/pci/vfio_pci_config.c
> @@ -398,9 +398,15 @@ static inline void p_setd(struct perm_bits *p, int off, 
> u32 virt, u32 write)
>  /* Caller should hold memory_lock semaphore */
>  bool __vfio_pci_memory_enabled(struct vfio_pci_device *vdev)
>  {
> + struct pci_dev *pdev = vdev->pdev;
>   u16 cmd = le16_to_cpu(*(__le16 *)>vconfig[PCI_COMMAND]);
> 
> - return cmd & PCI_COMMAND_MEMORY;
> + /*
> +  * SR-IOV VF memory enable is handled by the MSE bit in the
> +  * PF SR-IOV capability, there's therefore no need to trigger
> +  * faults based on the virtual value.
> +  */
> + return pdev->is_virtfn || (cmd & PCI_COMMAND_MEMORY);

Hi Alex,

After set up the initial copy of config space for memory enable bit for VF, is 
it worth
to trigger SIGBUS into the bad user space process which intentionally try to 
disable the
memory access command (even it is VF) then access the memory to trigger 
CVE-2020-12888 ?

BR,
Haiyue

>  }
> 
>  /*
> @@ -1728,6 +1734,15 @@ int vfio_config_init(struct vfio_pci_device *vdev)
>vconfig[PCI_INTERRUPT_PIN]);
> 
>   vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */
> +
> + /*
> +  * VFs do no implement the memory enable bit of the COMMAND
> +  * register therefore we'll not have it set in our initial
> +  * copy of config space after pci_enable_device().  For
> +  * consistency with PFs, set the virtual enable bit here.
> +  */
> + *(__le16 *)[PCI_COMMAND] |=
> + cpu_to_le16(PCI_COMMAND_MEMORY);
>   }
> 
>   if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx)



Re: [RFC PATCH 15/17] ipmi: kcs: aspeed: Implement v2 bindings

2019-07-26 Thread Wang, Haiyue



在 2019-07-26 13:39, Andrew Jeffery 写道:

The v2 bindings allow us to extract the resources from the devicetree.
The table in the driver is retained to derive the channel index, which
removes the need for kcs_chan property from the v1 bindings. The v2
bindings allow us to reduce the number of warnings generated by the
existing devicetree nodes.

Cc: Haiyue Wang
Cc: Corey Minyard
Cc: Arnd Bergmann
Cc: Greg Kroah-Hartman
Cc:openipmi-develo...@lists.sourceforge.net
Signed-off-by: Andrew Jeffery
---
  drivers/char/ipmi/kcs_bmc_aspeed.c | 156 +++--
  1 file changed, 127 insertions(+), 29 deletions(-)


Looks good, thanks for the hard work, the code is more clean! :)

Reviewed-by: Haiyue Wang 



Re: [PATCHv7 1/3] dt-bindings: i2c: document bindings for i2c-slave-mqueue

2019-06-11 Thread Wang, Haiyue



在 2019-06-12 07:14, Rob Herring 写道:

On Wed, Jun 05, 2019 at 09:46:49AM -0700, Eduardo Valentin wrote:

Document the i2c-slave-mqueue binding by adding
descriptor, required properties, and example.

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: Wolfram Sang 
Cc: linux-...@vger.kernel.org
Cc: devicet...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Eduardo Valentin 
---

Changes from V6 to V7:
- none

  .../bindings/i2c/i2c-slave-mqueue.txt | 34 +++
  1 file changed, 34 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/i2c/i2c-slave-mqueue.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-slave-mqueue.txt 
b/Documentation/devicetree/bindings/i2c/i2c-slave-mqueue.txt
new file mode 100644
index ..eb1881a4fc0e
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-slave-mqueue.txt
@@ -0,0 +1,34 @@
+===
+Device Tree for I2C slave message queue backend
+===
+
+Some protocols over I2C/SMBus are designed for bi-directional transferring
+messages by using I2C Master Write protocol. This requires that both sides
+of the communication have slave addresses.

So the address 0x10 in the example below is the address of the I2C
controller?


+
+This I2C slave mqueue (message queue) is used to receive and queue

Hi Rob, This is mqueue comes from, not from specs directly.

+messages from the remote i2c intelligent device; and it will add the target
+slave address (with R/W# bit is always 0) into the message at the first byte.
+
+Links
+
+`Intelligent Platform Management Bus
+Communications Protocol Specification
+`_
+
+`Management Component Transport Protocol (MCTP)
+SMBus/I2C Transport Binding Specification
+`_
+
+Required Properties:
+- compatible   : should be "i2c-slave-mqueue"

There is no mention of mqueue (or queue) in these specs. Where does that
come from? Perhaps something more closely matching the protocol would be
better name.


+- reg  : slave address
+
+Example:
+
+i2c {

Would there be other slaves?

The common binding states 'multi-master' property should be present.

I need a more complete example.


+   slave_mqueue: i2c-slave-mqueue {
+   compatible = "i2c-slave-mqueue";
+   reg = <0x10>;


Hi Eduardo,

Looks like the slave reg missed the key value bit:


https://elinux.org/images/f/f6/ELCE15-WolframSang-ShinyNewI2CSlaveFramework.pdf

Example: reg = <(I2C_OWN_SLAVE_ADDRESS | 0x42)>;



+   };
+};
--
2.21.0



Re: [PATCH i2c/slave-mqueue v5] i2c: slave-mqueue: add a slave backend to receive and queue messages

2019-05-29 Thread Wang, Haiyue



在 2019-05-30 07:11, Eduardo Valentin 写道:

this code goes access and modify data here, e.g. msg->len and msg->buf.

On this case (I2C_SLAVE_WRITE_RECEIVED), this code wont protect access.

This can cause concurrence issues if you receive an IRQ when the user
is on your bin_read().

User will not touch 'msg = mq->curr;', just touch 'msg =
>queue[mq->out];'

What happens if mq->curr == mq->queue[mq->out]?


1. The Read will check.

+   spin_lock_irqsave(>lock, flags);
+   if (mq->out != mq->in) {
+   msg = >queue[mq->out];

2. Flush the oldeast message. ^_^

+   case I2C_SLAVE_STOP:
+   if (unlikely(mq->truncated || msg->len < 2))
+   break;
+
+   spin_lock(>lock);
+   mq->in = MQ_QUEUE_NEXT(mq->in);
+   mq->curr = >queue[mq->in];
+   mq->curr->len = 0;
+
+   /* Flush the oldest message */
+   if (mq->out == mq->in)
+   mq->out = MQ_QUEUE_NEXT(mq->out);
+   spin_unlock(>lock);




Re: [PATCH i2c/slave-mqueue v5] i2c: slave-mqueue: add a slave backend to receive and queue messages

2019-05-24 Thread Wang, Haiyue



在 2019-05-25 01:33, Eduardo Valentin 写道:

Hey,

On Fri, May 24, 2019 at 10:43:16AM +0800, Wang, Haiyue wrote:

Thanks for interest, the design idea is from:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/i2c/i2c-slave-eeprom.c?h=v5.2-rc1

and

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c/slave-interface

Then you will get the answer. ;-)

Well, maybe :-) see further comments inline..
Please see in line. And how about the test result in your real system ? 
It works as expected ?

BR,

Haiyue


在 2019-05-24 06:03, Eduardo Valentin 写道:

Hey Wang,

On Tue, Apr 24, 2018 at 01:06:32AM +0800, Haiyue Wang wrote:

Some protocols over I2C are designed for bi-directional transferring
messages by using I2C Master Write protocol. Like the MCTP (Management
Component Transport Protocol) and IPMB (Intelligent Platform Management
Bus), they both require that the userspace can receive messages from
I2C dirvers under slave mode.

This new slave mqueue backend is used to receive and queue messages, it
will exposes these messages to userspace by sysfs bin file.

Signed-off-by: Haiyue Wang 
---
v4 -> v5:
  - Typo: bellowing -> the below

v3 -> v4:
  - Drop the small message after receiving I2C STOP.

v2 -> v3:
  - Just remove the ';' after the end '}' of i2c_slave_mqueue_probe().

v1 -> v2:
  - Change MQ_MSGBUF_SIZE and MQ_QUEUE_SIZE to be configurable by Kconfig.
---
  Documentation/i2c/slave-mqueue-backend.rst | 125 ++
  drivers/i2c/Kconfig|  25 
  drivers/i2c/Makefile   |   1 +
  drivers/i2c/i2c-slave-mqueue.c | 203 +
  4 files changed, 354 insertions(+)
  create mode 100644 Documentation/i2c/slave-mqueue-backend.rst
  create mode 100644 drivers/i2c/i2c-slave-mqueue.c

diff --git a/Documentation/i2c/slave-mqueue-backend.rst 
b/Documentation/i2c/slave-mqueue-backend.rst
new file mode 100644
index 000..3966cf0
--- /dev/null
+++ b/Documentation/i2c/slave-mqueue-backend.rst
@@ -0,0 +1,125 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=
+Linux I2C slave message queue backend
+=
+
+:Author: Haiyue Wang 
+
+Some protocols over I2C/SMBus are designed for bi-directional transferring
+messages by using I2C Master Write protocol. This requires that both sides
+of the communication have slave addresses.
+
+Like MCTP (Management Component Transport Protocol) and IPMB (Intelligent
+Platform Management Bus), they both require that the userspace can receive
+messages from i2c dirvers under slave mode.
+
+This I2C slave mqueue (message queue) backend is used to receive and queue
+messages from the remote i2c intelligent device; and it will add the target
+slave address (with R/W# bit is always 0) into the message at the first byte,
+so that userspace can use this byte to dispatch the messages into different
+handling modules. Also, like IPMB, the address byte is in its message format,
+it needs it to do checksum.
+
+For messages are time related, so this backend will flush the oldest message
+to queue the newest one.
+
+Link
+
+`Intelligent Platform Management Bus
+Communications Protocol Specification
+<https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmp-spec-v1.0.pdf>`_
+
+`Management Component Transport Protocol (MCTP)
+SMBus/I2C Transport Binding Specification
+<https://www.dmtf.org/sites/default/files/standards/documents/DSP0237_1.1.0.pdf>`_
+
+How to use
+--
+For example, the I2C5 bus has slave address 0x10, the below command will create
+the related message queue interface:
+
+echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-5/new_device
+
+Then you can dump the messages like this:
+
+hexdump -C /sys/bus/i2c/devices/5-1010/slave-mqueue
+
+Code Example
+
+*Note: call 'lseek' before 'read', this is a requirement from kernfs' design.*
+
+::
+
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+
+  int main(int argc, char *argv[])
+  {
+  int i, r;
+  struct pollfd pfd;
+  struct timespec ts;
+  unsigned char data[256];
+
+  pfd.fd = open(argv[1], O_RDONLY | O_NONBLOCK);
+  if (pfd.fd < 0)
+  return -1;
+
+  pfd.events = POLLPRI;
+
+  while (1) {
+  r = poll(, 1, 5000);
+
+  if (r < 0)
+  break;
+
+  if (r == 0 || !(pfd.revents & POLLPRI))
+  continue;
+
+  lseek(pfd.fd, 0, SEEK_SET);
+  r = read(pfd.fd, data, sizeof(data));
+  if (r <= 0)
+  continue;
+
+  clock_gettime(CLOCK_MONOTONIC, );
+  printf("[%ld.%.9ld] :", ts.tv_sec,

Re: [PATCH i2c/slave-mqueue v5] i2c: slave-mqueue: add a slave backend to receive and queue messages

2019-05-23 Thread Wang, Haiyue

Thanks for interest, the design idea is from:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/i2c/i2c-slave-eeprom.c?h=v5.2-rc1

and

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c/slave-interface

Then you will get the answer. ;-)

BR,

Haiyue


在 2019-05-24 06:03, Eduardo Valentin 写道:

Hey Wang,

On Tue, Apr 24, 2018 at 01:06:32AM +0800, Haiyue Wang wrote:

Some protocols over I2C are designed for bi-directional transferring
messages by using I2C Master Write protocol. Like the MCTP (Management
Component Transport Protocol) and IPMB (Intelligent Platform Management
Bus), they both require that the userspace can receive messages from
I2C dirvers under slave mode.

This new slave mqueue backend is used to receive and queue messages, it
will exposes these messages to userspace by sysfs bin file.

Signed-off-by: Haiyue Wang 
---
v4 -> v5:
  - Typo: bellowing -> the below

v3 -> v4:
  - Drop the small message after receiving I2C STOP.

v2 -> v3:
  - Just remove the ';' after the end '}' of i2c_slave_mqueue_probe().

v1 -> v2:
  - Change MQ_MSGBUF_SIZE and MQ_QUEUE_SIZE to be configurable by Kconfig.
---
  Documentation/i2c/slave-mqueue-backend.rst | 125 ++
  drivers/i2c/Kconfig|  25 
  drivers/i2c/Makefile   |   1 +
  drivers/i2c/i2c-slave-mqueue.c | 203 +
  4 files changed, 354 insertions(+)
  create mode 100644 Documentation/i2c/slave-mqueue-backend.rst
  create mode 100644 drivers/i2c/i2c-slave-mqueue.c

diff --git a/Documentation/i2c/slave-mqueue-backend.rst 
b/Documentation/i2c/slave-mqueue-backend.rst
new file mode 100644
index 000..3966cf0
--- /dev/null
+++ b/Documentation/i2c/slave-mqueue-backend.rst
@@ -0,0 +1,125 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=
+Linux I2C slave message queue backend
+=
+
+:Author: Haiyue Wang 
+
+Some protocols over I2C/SMBus are designed for bi-directional transferring
+messages by using I2C Master Write protocol. This requires that both sides
+of the communication have slave addresses.
+
+Like MCTP (Management Component Transport Protocol) and IPMB (Intelligent
+Platform Management Bus), they both require that the userspace can receive
+messages from i2c dirvers under slave mode.
+
+This I2C slave mqueue (message queue) backend is used to receive and queue
+messages from the remote i2c intelligent device; and it will add the target
+slave address (with R/W# bit is always 0) into the message at the first byte,
+so that userspace can use this byte to dispatch the messages into different
+handling modules. Also, like IPMB, the address byte is in its message format,
+it needs it to do checksum.
+
+For messages are time related, so this backend will flush the oldest message
+to queue the newest one.
+
+Link
+
+`Intelligent Platform Management Bus
+Communications Protocol Specification
+`_
+
+`Management Component Transport Protocol (MCTP)
+SMBus/I2C Transport Binding Specification
+`_
+
+How to use
+--
+For example, the I2C5 bus has slave address 0x10, the below command will create
+the related message queue interface:
+
+echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-5/new_device
+
+Then you can dump the messages like this:
+
+hexdump -C /sys/bus/i2c/devices/5-1010/slave-mqueue
+
+Code Example
+
+*Note: call 'lseek' before 'read', this is a requirement from kernfs' design.*
+
+::
+
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+
+  int main(int argc, char *argv[])
+  {
+  int i, r;
+  struct pollfd pfd;
+  struct timespec ts;
+  unsigned char data[256];
+
+  pfd.fd = open(argv[1], O_RDONLY | O_NONBLOCK);
+  if (pfd.fd < 0)
+  return -1;
+
+  pfd.events = POLLPRI;
+
+  while (1) {
+  r = poll(, 1, 5000);
+
+  if (r < 0)
+  break;
+
+  if (r == 0 || !(pfd.revents & POLLPRI))
+  continue;
+
+  lseek(pfd.fd, 0, SEEK_SET);
+  r = read(pfd.fd, data, sizeof(data));
+  if (r <= 0)
+  continue;
+
+  clock_gettime(CLOCK_MONOTONIC, );
+  printf("[%ld.%.9ld] :", ts.tv_sec, ts.tv_nsec);
+  for (i = 0; i < r; i++)
+  printf(" %02x", data[i]);
+  printf("\n");
+  }
+
+  close(pfd.fd);
+
+  return 0;
+  }
+
+Result
+--
+*./a.out "/sys/bus/i2c/devices/5-1010/slave-mqueue"*
+
+::
+
+  [10183.232500449] : 20 18 c8 2c 78 01 5b
+ 

Re: [PATCH] ipmi: kcs_bmc: handle devm_kasprintf() failure case

2018-11-27 Thread Wang, Haiyue

[Resend for wrong reply HTML format mail]

Great check for making kcs_bmc module be more stable and handle things 
gracefully.

My tag if needed.
 Reviewed-by: Haiyue Wang

在 2018-11-27 21:36, Corey Minyard 写道:

On 11/21/18 9:08 AM, Nicholas Mc Guire wrote:

devm_kasprintf() may return NULL if internal allocation failed so this
assignment is not safe. Moved the error exit path and added the !NULL
which then allows the devres manager to take care of cleanup.



Added the original author.  This looks correct to me, I've included 
it, but I would

like Haiyue to comment, if possible.

Thanks,

-corey



Signed-off-by: Nicholas Mc Guire 
Fixes: cd2315d471f4 ("ipmi: kcs_bmc: don't change device name") 


Re: [PATCH] ipmi: kcs_bmc: handle devm_kasprintf() failure case

2018-11-27 Thread Wang, Haiyue

[Resend for wrong reply HTML format mail]

Great check for making kcs_bmc module be more stable and handle things 
gracefully.

My tag if needed.
 Reviewed-by: Haiyue Wang

在 2018-11-27 21:36, Corey Minyard 写道:

On 11/21/18 9:08 AM, Nicholas Mc Guire wrote:

devm_kasprintf() may return NULL if internal allocation failed so this
assignment is not safe. Moved the error exit path and added the !NULL
which then allows the devres manager to take care of cleanup.



Added the original author.  This looks correct to me, I've included 
it, but I would

like Haiyue to comment, if possible.

Thanks,

-corey



Signed-off-by: Nicholas Mc Guire 
Fixes: cd2315d471f4 ("ipmi: kcs_bmc: don't change device name") 


Re: [PATCH dts/arm/aspeed-g5 v1] ARM: dts: aspeed-g5: Add IPMI KCS node

2018-05-25 Thread Wang, Haiyue

Hi Joel & Andrew

This patch is out of date. ;-)

New: https://patchwork.ozlabs.org/patch/893720/


On 2018-05-25 12:34, Joel Stanley wrote:

Hello Andrew,

On 16 March 2018 at 11:17, Wang, Haiyue <haiyue.w...@linux.intel.com> wrote:

Hi Joel and Andrew,

Have time to review this patch ? Hope for your comments. :-)

BR,
Haiyue


On 2018-03-07 13:04, Haiyue Wang wrote:

The IPMI KCS device part of the LPC interface and is used for
communication with the host processor.

Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>

Do you have time to take a look at these? The device tree doesn't make
sense to me.

Cheers,

Joel


---
   arch/arm/boot/dts/aspeed-g5.dtsi | 43
+++-
   1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi
b/arch/arm/boot/dts/aspeed-g5.dtsi
index 8eac57c..f443169 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -267,8 +267,40 @@
 ranges = <0x0 0x1e789000 0x1000>;
 lpc_bmc: lpc-bmc@0 {
-   compatible =
"aspeed,ast2500-lpc-bmc";
+   compatible =
"aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon";
 reg = <0x0 0x80>;
+   reg-io-width = <4>;
+
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges = <0x0 0x0 0x80>;
+
+   kcs1: kcs1@0 {
+   compatible =
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <1>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
+   kcs2: kcs2@0 {
+   compatible =
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <2>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
+   kcs3: kcs3@0 {
+   compatible =
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <3>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
 };
 lpc_host: lpc-host@80 {
@@ -294,6 +326,15 @@
 status = "disabled";
 };
   + kcs4: kcs4@0 {
+   compatible =
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0xa0>;
+   interrupts = <8>;
+   kcs_chan = <4>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
 lhc: lhc@20 {
 compatible =
"aspeed,ast2500-lhc";
 reg = <0x20 0x24 0x48
0x8>;






Re: [PATCH dts/arm/aspeed-g5 v1] ARM: dts: aspeed-g5: Add IPMI KCS node

2018-05-25 Thread Wang, Haiyue

Hi Joel & Andrew

This patch is out of date. ;-)

New: https://patchwork.ozlabs.org/patch/893720/


On 2018-05-25 12:34, Joel Stanley wrote:

Hello Andrew,

On 16 March 2018 at 11:17, Wang, Haiyue  wrote:

Hi Joel and Andrew,

Have time to review this patch ? Hope for your comments. :-)

BR,
Haiyue


On 2018-03-07 13:04, Haiyue Wang wrote:

The IPMI KCS device part of the LPC interface and is used for
communication with the host processor.

Signed-off-by: Haiyue Wang 

Do you have time to take a look at these? The device tree doesn't make
sense to me.

Cheers,

Joel


---
   arch/arm/boot/dts/aspeed-g5.dtsi | 43
+++-
   1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi
b/arch/arm/boot/dts/aspeed-g5.dtsi
index 8eac57c..f443169 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -267,8 +267,40 @@
 ranges = <0x0 0x1e789000 0x1000>;
 lpc_bmc: lpc-bmc@0 {
-   compatible =
"aspeed,ast2500-lpc-bmc";
+   compatible =
"aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon";
 reg = <0x0 0x80>;
+   reg-io-width = <4>;
+
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges = <0x0 0x0 0x80>;
+
+   kcs1: kcs1@0 {
+   compatible =
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <1>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
+   kcs2: kcs2@0 {
+   compatible =
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <2>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
+   kcs3: kcs3@0 {
+   compatible =
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <3>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
 };
 lpc_host: lpc-host@80 {
@@ -294,6 +326,15 @@
 status = "disabled";
 };
   + kcs4: kcs4@0 {
+   compatible =
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0xa0>;
+   interrupts = <8>;
+   kcs_chan = <4>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
 lhc: lhc@20 {
 compatible =
"aspeed,ast2500-lhc";
 reg = <0x20 0x24 0x48
0x8>;






Re: [PATCH ipmi/kcs_bmc v1] ipmi: add an NPCM7xx KCS BMC driver

2018-04-13 Thread Wang, Haiyue

Thanks, Corey.

BR,

Haiyue


On 2018-04-13 23:56, Corey Minyard wrote:

On 03/22/2018 07:50 AM, Haiyue Wang wrote:

This driver exposes the Keyboard Controller Style (KCS) interface on
Novoton NPCM7xx SoCs as a character device. Such SOCs are commonly used
as a BaseBoard Management Controller (BMC) on a server board, and KCS
interface is commonly used to perform the in-band IPMI communication
between the server and its BMC.


Sorry, I missed this.  It is queued for the next kernel release.

Thanks,

-corey 




Re: [PATCH ipmi/kcs_bmc v1] ipmi: add an NPCM7xx KCS BMC driver

2018-04-13 Thread Wang, Haiyue

Thanks, Corey.

BR,

Haiyue


On 2018-04-13 23:56, Corey Minyard wrote:

On 03/22/2018 07:50 AM, Haiyue Wang wrote:

This driver exposes the Keyboard Controller Style (KCS) interface on
Novoton NPCM7xx SoCs as a character device. Such SOCs are commonly used
as a BaseBoard Management Controller (BMC) on a server board, and KCS
interface is commonly used to perform the in-band IPMI communication
between the server and its BMC.


Sorry, I missed this.  It is queued for the next kernel release.

Thanks,

-corey 




Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-13 Thread Wang, Haiyue



On 2018-04-13 21:50, Corey Minyard wrote:

On 04/07/2018 02:54 AM, Wang, Haiyue wrote:

Hi Corey,

Since IPMI 2.0 just defined minimum, no maximum:



KCS/SMIC Input : Required: 40 bytes IPMI Message, minimum

KCS/SMIC Output : Required: 38 bytes IPMI Message, minimum



Yes, though there are practical maximums that are much smaller than 
1000 bytes.






We can enlarge the block size for avoiding waste, and make our driver

support most worst message size case. And I think this patch make 
checking


simple (from 3 to 1), and the code clean, this is the biggest reason 
I want to


change. The TLB is just memory management study from book, no data to

support access improvement. :)


I would argue that the way it is now expresses the intent of the code 
better
than one allocation split into three parts.  Expressing your intent is 
more

important than the number of checks and a minuscule performance
improvement.  For me it makes the code easier to understand.  If you had
a tool that checked for out-of-bounds memory access, then a single 
allocation

might not find an overrun between the parts.  Smaller allocations tend
to result in less memory fragmentation.


When I wrote the commit, I felt that the message was not so professional,
and the reason sounded weak. The driver development is a complex work,
needs considering more things, not just one. Thanks for your patience.

My preference is to leave it as it is.  However, it's not that 
important, and

if you really want this patch, I can include it.


So leave it as it is, abandon this patch. :-)

BTW, another patch about KCS BMC chip support:
https://lkml.org/lkml/2018/3/22/284
Look forward your reviewing, I've tried my best to make it better.


Thanks,

-corey



BR,

Haiyue


On 2018-04-07 10:37, Wang, Haiyue wrote:



On 2018-04-07 05:47, Corey Minyard wrote:

On 03/15/2018 07:20 AM, Haiyue Wang wrote:
Allocate a continuous memory block for the three KCS data buffers 
with

related index assignment.


I'm finally getting to this.

Is there a reason you want to do this?  In general, it's better to 
not try to

outsmart your base system.  Depending on the memory allocator, in this
case, you might actually use more memory.  You probably won't use any
less.

I got this idea from another code review, but that patch allocates 
30 more
the same size memory block, reducing the devm_kmalloc call will be 
better.

For KCS only have 3, may be the key point is memory waste.

In the original case, you allocate three 1000 byte buffers, 
resulting in 3

1024 byte slab allocated.

In the changed case, you will allocate a 3000 byte buffer, 
resulting in

a single 4096 byte slab allocation, wasting 1024 more bytes of memory.


As the kcs has memory copy between in/out/kbuffer, put them in the same
page will be better ? Such as the same TLB ? (Well, I just got this 
from book,
no real experience of memory accessing performance. And also, I was 
told

that using space to save the time. :-)).

Just my stupid thinking. I'm OK to drop this patch if it doesn't 
help with

performance, or something else.

BR.
Haiyue


-corey


Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c 
b/drivers/char/ipmi/kcs_bmc.c

index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations 
kcs_bmc_fops = {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int 
sizeof_priv, u32 channel)

  {
  struct kcs_bmc *kcs_bmc;
+    void *buf;
    kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + 
sizeof_priv, GFP_KERNEL);

  if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device 
*dev, int sizeof_priv, u32 channel)

  mutex_init(_bmc->mutex);
  init_waitqueue_head(_bmc->queue);
  -    kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);
-    kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);
-    kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);
-    if (!kcs_bmc->data_in || !kcs_bmc->data_out || 
!kcs_bmc->kbuffer)

+    buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+    if (!buf)
  return NULL;
+    kcs_bmc->data_in  = buf;
+    kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+    kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
    kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
  kcs_bmc->miscdev.name = dev_name(dev);













Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-13 Thread Wang, Haiyue



On 2018-04-13 21:50, Corey Minyard wrote:

On 04/07/2018 02:54 AM, Wang, Haiyue wrote:

Hi Corey,

Since IPMI 2.0 just defined minimum, no maximum:



KCS/SMIC Input : Required: 40 bytes IPMI Message, minimum

KCS/SMIC Output : Required: 38 bytes IPMI Message, minimum



Yes, though there are practical maximums that are much smaller than 
1000 bytes.






We can enlarge the block size for avoiding waste, and make our driver

support most worst message size case. And I think this patch make 
checking


simple (from 3 to 1), and the code clean, this is the biggest reason 
I want to


change. The TLB is just memory management study from book, no data to

support access improvement. :)


I would argue that the way it is now expresses the intent of the code 
better
than one allocation split into three parts.  Expressing your intent is 
more

important than the number of checks and a minuscule performance
improvement.  For me it makes the code easier to understand.  If you had
a tool that checked for out-of-bounds memory access, then a single 
allocation

might not find an overrun between the parts.  Smaller allocations tend
to result in less memory fragmentation.


When I wrote the commit, I felt that the message was not so professional,
and the reason sounded weak. The driver development is a complex work,
needs considering more things, not just one. Thanks for your patience.

My preference is to leave it as it is.  However, it's not that 
important, and

if you really want this patch, I can include it.


So leave it as it is, abandon this patch. :-)

BTW, another patch about KCS BMC chip support:
https://lkml.org/lkml/2018/3/22/284
Look forward your reviewing, I've tried my best to make it better.


Thanks,

-corey



BR,

Haiyue


On 2018-04-07 10:37, Wang, Haiyue wrote:



On 2018-04-07 05:47, Corey Minyard wrote:

On 03/15/2018 07:20 AM, Haiyue Wang wrote:
Allocate a continuous memory block for the three KCS data buffers 
with

related index assignment.


I'm finally getting to this.

Is there a reason you want to do this?  In general, it's better to 
not try to

outsmart your base system.  Depending on the memory allocator, in this
case, you might actually use more memory.  You probably won't use any
less.

I got this idea from another code review, but that patch allocates 
30 more
the same size memory block, reducing the devm_kmalloc call will be 
better.

For KCS only have 3, may be the key point is memory waste.

In the original case, you allocate three 1000 byte buffers, 
resulting in 3

1024 byte slab allocated.

In the changed case, you will allocate a 3000 byte buffer, 
resulting in

a single 4096 byte slab allocation, wasting 1024 more bytes of memory.


As the kcs has memory copy between in/out/kbuffer, put them in the same
page will be better ? Such as the same TLB ? (Well, I just got this 
from book,
no real experience of memory accessing performance. And also, I was 
told

that using space to save the time. :-)).

Just my stupid thinking. I'm OK to drop this patch if it doesn't 
help with

performance, or something else.

BR.
Haiyue


-corey


Signed-off-by: Haiyue Wang 
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c 
b/drivers/char/ipmi/kcs_bmc.c

index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations 
kcs_bmc_fops = {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int 
sizeof_priv, u32 channel)

  {
  struct kcs_bmc *kcs_bmc;
+    void *buf;
    kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + 
sizeof_priv, GFP_KERNEL);

  if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device 
*dev, int sizeof_priv, u32 channel)

  mutex_init(_bmc->mutex);
  init_waitqueue_head(_bmc->queue);
  -    kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);
-    kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);
-    kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);
-    if (!kcs_bmc->data_in || !kcs_bmc->data_out || 
!kcs_bmc->kbuffer)

+    buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+    if (!buf)
  return NULL;
+    kcs_bmc->data_in  = buf;
+    kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+    kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
    kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
  kcs_bmc->miscdev.name = dev_name(dev);













Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-07 Thread Wang, Haiyue

Hi Corey,

Since IPMI 2.0 just defined minimum, no maximum:



KCS/SMIC Input : Required: 40 bytes IPMI Message, minimum

KCS/SMIC Output : Required: 38 bytes IPMI Message, minimum



We can enlarge the block size for avoiding waste, and make our driver

support most worst message size case. And I think this patch make checking

simple (from 3 to 1), and the code clean, this is the biggest reason I 
want to


change. The TLB is just memory management study from book, no data to

support access improvement. :)

BR,

Haiyue


On 2018-04-07 10:37, Wang, Haiyue wrote:



On 2018-04-07 05:47, Corey Minyard wrote:

On 03/15/2018 07:20 AM, Haiyue Wang wrote:

Allocate a continuous memory block for the three KCS data buffers with
related index assignment.


I'm finally getting to this.

Is there a reason you want to do this?  In general, it's better to 
not try to

outsmart your base system.  Depending on the memory allocator, in this
case, you might actually use more memory.  You probably won't use any
less.

I got this idea from another code review, but that patch allocates 30 
more
the same size memory block, reducing the devm_kmalloc call will be 
better.

For KCS only have 3, may be the key point is memory waste.

In the original case, you allocate three 1000 byte buffers, resulting 
in 3

1024 byte slab allocated.

In the changed case, you will allocate a 3000 byte buffer, resulting in
a single 4096 byte slab allocation, wasting 1024 more bytes of memory.


As the kcs has memory copy between in/out/kbuffer, put them in the same
page will be better ? Such as the same TLB ? (Well, I just got this 
from book,

no real experience of memory accessing performance. And also, I was told
that using space to save the time. :-)).

Just my stupid thinking. I'm OK to drop this patch if it doesn't help 
with

performance, or something else.

BR.
Haiyue


-corey


Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations kcs_bmc_fops 
= {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, 
u32 channel)

  {
  struct kcs_bmc *kcs_bmc;
+    void *buf;
    kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, 
GFP_KERNEL);

  if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device 
*dev, int sizeof_priv, u32 channel)

  mutex_init(_bmc->mutex);
  init_waitqueue_head(_bmc->queue);
  -    kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);

-    kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer)
+    buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+    if (!buf)
  return NULL;
+    kcs_bmc->data_in  = buf;
+    kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+    kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
    kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
  kcs_bmc->miscdev.name = dev_name(dev);









Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-07 Thread Wang, Haiyue

Hi Corey,

Since IPMI 2.0 just defined minimum, no maximum:



KCS/SMIC Input : Required: 40 bytes IPMI Message, minimum

KCS/SMIC Output : Required: 38 bytes IPMI Message, minimum



We can enlarge the block size for avoiding waste, and make our driver

support most worst message size case. And I think this patch make checking

simple (from 3 to 1), and the code clean, this is the biggest reason I 
want to


change. The TLB is just memory management study from book, no data to

support access improvement. :)

BR,

Haiyue


On 2018-04-07 10:37, Wang, Haiyue wrote:



On 2018-04-07 05:47, Corey Minyard wrote:

On 03/15/2018 07:20 AM, Haiyue Wang wrote:

Allocate a continuous memory block for the three KCS data buffers with
related index assignment.


I'm finally getting to this.

Is there a reason you want to do this?  In general, it's better to 
not try to

outsmart your base system.  Depending on the memory allocator, in this
case, you might actually use more memory.  You probably won't use any
less.

I got this idea from another code review, but that patch allocates 30 
more
the same size memory block, reducing the devm_kmalloc call will be 
better.

For KCS only have 3, may be the key point is memory waste.

In the original case, you allocate three 1000 byte buffers, resulting 
in 3

1024 byte slab allocated.

In the changed case, you will allocate a 3000 byte buffer, resulting in
a single 4096 byte slab allocation, wasting 1024 more bytes of memory.


As the kcs has memory copy between in/out/kbuffer, put them in the same
page will be better ? Such as the same TLB ? (Well, I just got this 
from book,

no real experience of memory accessing performance. And also, I was told
that using space to save the time. :-)).

Just my stupid thinking. I'm OK to drop this patch if it doesn't help 
with

performance, or something else.

BR.
Haiyue


-corey


Signed-off-by: Haiyue Wang 
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations kcs_bmc_fops 
= {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, 
u32 channel)

  {
  struct kcs_bmc *kcs_bmc;
+    void *buf;
    kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, 
GFP_KERNEL);

  if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device 
*dev, int sizeof_priv, u32 channel)

  mutex_init(_bmc->mutex);
  init_waitqueue_head(_bmc->queue);
  -    kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);

-    kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer)
+    buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+    if (!buf)
  return NULL;
+    kcs_bmc->data_in  = buf;
+    kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+    kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
    kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
  kcs_bmc->miscdev.name = dev_name(dev);









Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-06 Thread Wang, Haiyue



On 2018-04-07 05:47, Corey Minyard wrote:

On 03/15/2018 07:20 AM, Haiyue Wang wrote:

Allocate a continuous memory block for the three KCS data buffers with
related index assignment.


I'm finally getting to this.

Is there a reason you want to do this?  In general, it's better to not 
try to

outsmart your base system.  Depending on the memory allocator, in this
case, you might actually use more memory.  You probably won't use any
less.


I got this idea from another code review, but that patch allocates 30 more
the same size memory block, reducing the devm_kmalloc call will be better.
For KCS only have 3, may be the key point is memory waste.

In the original case, you allocate three 1000 byte buffers, resulting 
in 3

1024 byte slab allocated.

In the changed case, you will allocate a 3000 byte buffer, resulting in
a single 4096 byte slab allocation, wasting 1024 more bytes of memory.


As the kcs has memory copy between in/out/kbuffer, put them in the same
page will be better ? Such as the same TLB ? (Well, I just got this from 
book,

no real experience of memory accessing performance. And also, I was told
that using space to save the time. :-)).

Just my stupid thinking. I'm OK to drop this patch if it doesn't help with
performance, or something else.

BR.
Haiyue


-corey


Signed-off-by: Haiyue Wang 
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations kcs_bmc_fops = {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, 
u32 channel)

  {
  struct kcs_bmc *kcs_bmc;
+    void *buf;
    kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, 
GFP_KERNEL);

  if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device 
*dev, int sizeof_priv, u32 channel)

  mutex_init(_bmc->mutex);
  init_waitqueue_head(_bmc->queue);
  -    kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer)
+    buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+    if (!buf)
  return NULL;
+    kcs_bmc->data_in  = buf;
+    kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+    kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
    kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
  kcs_bmc->miscdev.name = dev_name(dev);







Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-06 Thread Wang, Haiyue



On 2018-04-07 05:47, Corey Minyard wrote:

On 03/15/2018 07:20 AM, Haiyue Wang wrote:

Allocate a continuous memory block for the three KCS data buffers with
related index assignment.


I'm finally getting to this.

Is there a reason you want to do this?  In general, it's better to not 
try to

outsmart your base system.  Depending on the memory allocator, in this
case, you might actually use more memory.  You probably won't use any
less.


I got this idea from another code review, but that patch allocates 30 more
the same size memory block, reducing the devm_kmalloc call will be better.
For KCS only have 3, may be the key point is memory waste.

In the original case, you allocate three 1000 byte buffers, resulting 
in 3

1024 byte slab allocated.

In the changed case, you will allocate a 3000 byte buffer, resulting in
a single 4096 byte slab allocation, wasting 1024 more bytes of memory.


As the kcs has memory copy between in/out/kbuffer, put them in the same
page will be better ? Such as the same TLB ? (Well, I just got this from 
book,

no real experience of memory accessing performance. And also, I was told
that using space to save the time. :-)).

Just my stupid thinking. I'm OK to drop this patch if it doesn't help with
performance, or something else.

BR.
Haiyue


-corey


Signed-off-by: Haiyue Wang 
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations kcs_bmc_fops = {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, 
u32 channel)

  {
  struct kcs_bmc *kcs_bmc;
+    void *buf;
    kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, 
GFP_KERNEL);

  if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device 
*dev, int sizeof_priv, u32 channel)

  mutex_init(_bmc->mutex);
  init_waitqueue_head(_bmc->queue);
  -    kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer)
+    buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+    if (!buf)
  return NULL;
+    kcs_bmc->data_in  = buf;
+    kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+    kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
    kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
  kcs_bmc->miscdev.name = dev_name(dev);







Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-03 Thread Wang, Haiyue

Just a small piece of cake, not so urgent. I just try to understand

the code commitment process, such as time etc. :)

Thanks!

BR,
Haiyue

On 2018-04-04 02:45, Corey Minyard wrote:

On 04/03/2018 01:00 AM, Wang, Haiyue wrote:

Hi Corey,

The 4.17 merge window is opened now, this patch is not yet in 
linux-next tree,


so it will be merged into 4.18 ?



Yeah, this came in kind of late, and I had some other critical
things I was having to focus on, so I've been kind of out of the loop.

If it's urgent, I can work on getting it into 4.17 later, but I'd rather
wait on 4.18.

-corey


Thanks & Regards,

Haiyue

On 2018-03-15 20:20, Haiyue Wang wrote:

Allocate a continuous memory block for the three KCS data buffers with
related index assignment.

Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations kcs_bmc_fops 
= {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, 
u32 channel)

  {
  struct kcs_bmc *kcs_bmc;
+    void *buf;
    kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, 
GFP_KERNEL);

  if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device 
*dev, int sizeof_priv, u32 channel)

  mutex_init(_bmc->mutex);
  init_waitqueue_head(_bmc->queue);
  -    kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);

-    kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer)
+    buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+    if (!buf)
  return NULL;
+    kcs_bmc->data_in  = buf;
+    kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+    kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
    kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
  kcs_bmc->miscdev.name = dev_name(dev);








Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-03 Thread Wang, Haiyue

Just a small piece of cake, not so urgent. I just try to understand

the code commitment process, such as time etc. :)

Thanks!

BR,
Haiyue

On 2018-04-04 02:45, Corey Minyard wrote:

On 04/03/2018 01:00 AM, Wang, Haiyue wrote:

Hi Corey,

The 4.17 merge window is opened now, this patch is not yet in 
linux-next tree,


so it will be merged into 4.18 ?



Yeah, this came in kind of late, and I had some other critical
things I was having to focus on, so I've been kind of out of the loop.

If it's urgent, I can work on getting it into 4.17 later, but I'd rather
wait on 4.18.

-corey


Thanks & Regards,

Haiyue

On 2018-03-15 20:20, Haiyue Wang wrote:

Allocate a continuous memory block for the three KCS data buffers with
related index assignment.

Signed-off-by: Haiyue Wang 
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations kcs_bmc_fops 
= {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, 
u32 channel)

  {
  struct kcs_bmc *kcs_bmc;
+    void *buf;
    kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, 
GFP_KERNEL);

  if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device 
*dev, int sizeof_priv, u32 channel)

  mutex_init(_bmc->mutex);
  init_waitqueue_head(_bmc->queue);
  -    kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, 
GFP_KERNEL);

-    kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-    if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer)
+    buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+    if (!buf)
  return NULL;
+    kcs_bmc->data_in  = buf;
+    kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+    kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
    kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
  kcs_bmc->miscdev.name = dev_name(dev);








Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-03 Thread Wang, Haiyue

Hi Corey,

The 4.17 merge window is opened now, this patch is not yet in linux-next 
tree,


so it will be merged into 4.18 ?

Thanks & Regards,

Haiyue

On 2018-03-15 20:20, Haiyue Wang wrote:

Allocate a continuous memory block for the three KCS data buffers with
related index assignment.

Signed-off-by: Haiyue Wang 
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations kcs_bmc_fops = {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 
channel)
  {
struct kcs_bmc *kcs_bmc;
+   void *buf;
  
  	kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, GFP_KERNEL);

if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int 
sizeof_priv, u32 channel)
mutex_init(_bmc->mutex);
init_waitqueue_head(_bmc->queue);
  
-	kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);

-   kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-   kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-   if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer)
+   buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+   if (!buf)
return NULL;
+   kcs_bmc->data_in  = buf;
+   kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+   kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
  
  	kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;

kcs_bmc->miscdev.name = dev_name(dev);




Re: [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation

2018-04-03 Thread Wang, Haiyue

Hi Corey,

The 4.17 merge window is opened now, this patch is not yet in linux-next 
tree,


so it will be merged into 4.18 ?

Thanks & Regards,

Haiyue

On 2018-03-15 20:20, Haiyue Wang wrote:

Allocate a continuous memory block for the three KCS data buffers with
related index assignment.

Signed-off-by: Haiyue Wang 
---
  drivers/char/ipmi/kcs_bmc.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index fbfc05e..dc19c0d 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -435,6 +435,7 @@ static const struct file_operations kcs_bmc_fops = {
  struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 
channel)
  {
struct kcs_bmc *kcs_bmc;
+   void *buf;
  
  	kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, GFP_KERNEL);

if (!kcs_bmc)
@@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int 
sizeof_priv, u32 channel)
mutex_init(_bmc->mutex);
init_waitqueue_head(_bmc->queue);
  
-	kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);

-   kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-   kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
-   if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer)
+   buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL);
+   if (!buf)
return NULL;
+   kcs_bmc->data_in  = buf;
+   kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ;
+   kcs_bmc->kbuffer  = buf + KCS_MSG_BUFSIZ * 2;
  
  	kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;

kcs_bmc->miscdev.name = dev_name(dev);




Re: [PATCH i2c/slave-mqueue v1] i2c: slave-mqueue: add a slave backend to receive and queue messages

2018-03-19 Thread Wang, Haiyue

Thanks, Andy.


Hi Wolfram,

Let me introduce some development background, it is used for OpenBMC 
project,


which belongs to the Linux Foundation now 
(https://www.linuxfoundation.org/blog/openbmc-project-community-comes-together-at-the-linux-foundation-to-define-open-source-implementation-of-bmc-firmware-stack/).


1. *https://goo.gl/WgvPFi*

*** 
***https://lists.ozlabs.org/pipermail/openbmc/2018-January/010493.html* 
*


**

*IPMI is embedded within IPMB (similar to KCS, BT?)*

*

 *

   Who started, who responded to messages

 *

   We need a kernel interface for handling a multi-master slave

 *

   Dell has a non-standard i2c IPMB interface

 o

   Kernel maintains table of outstanding commands

 *

   Brendan suggests we need a kernel driver for doing both MCTP and IPMB

 *

   We can’t do them both in usersland as MCTP makes extensions to SMBUS
   in order to allow arbitration. Problematic extension is the “MCTP
   fairness arbitration”. Requires the i2c controllers on the bus
   (masters/slaves) to observe the line for a certain period of time in
   order to see who is using the line. There’s no userspace API for
   this, and it the timing requirements are tight

 *

   Slave mode is not yet exposed to the user

 *

   As we don’t have a userspace interface, it makes sense to add a new one

*

BR,
Haiyue

On 2018-03-20 03:32, Andy Shevchenko wrote:

On Sat, 2018-03-17 at 11:48 +0800, Haiyue Wang wrote:

Some protocols over I2C are designed for bi-directional transferring
messages by using I2C Master Write protocol. Like the MCTP (Management
Component Transport Protocol) and IPMB (Intelligent Platform
Management
Bus), they both require that the userspace can receive messages from
I2C dirvers under slave mode.

This new slave mqueue backend is used to receive and queue messages,
it
will exposes these messages to userspace by sysfs bin file.


Wolfram, I'm not sure this is the best approach, though I can't propose
anything else right now.

If you are satisfied with it, I give a formal

Reviewed-by: Andy Shevchenko 


Signed-off-by: Haiyue Wang 
---
  Documentation/i2c/slave-mqueue-backend.rst | 125 ++
  drivers/i2c/Kconfig|  13 ++
  drivers/i2c/Makefile   |   1 +
  drivers/i2c/i2c-slave-mqueue.c | 202
+
  4 files changed, 341 insertions(+)
  create mode 100644 Documentation/i2c/slave-mqueue-backend.rst
  create mode 100644 drivers/i2c/i2c-slave-mqueue.c

diff --git a/Documentation/i2c/slave-mqueue-backend.rst
b/Documentation/i2c/slave-mqueue-backend.rst
new file mode 100644
index 000..69d6437
--- /dev/null
+++ b/Documentation/i2c/slave-mqueue-backend.rst
@@ -0,0 +1,125 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=
+Linux I2C slave message queue backend
+=
+
+:Author: Haiyue Wang 
+
+Some protocols over I2C/SMBus are designed for bi-directional
transferring
+messages by using I2C Master Write protocol. This requires that both
sides
+of the communication have slave addresses.
+
+Like MCTP (Management Component Transport Protocol) and IPMB
(Intelligent
+Platform Management Bus), they both require that the userspace can
receive
+messages from i2c dirvers under slave mode.
+
+This I2C slave mqueue (message queue) backend is used to receive and
queue
+messages from the remote i2c intelligent device; and it will add the
target
+slave address (with R/W# bit is always 0) into the message at the
first byte,
+so that userspace can use this byte to dispatch the messages into
different
+handling modules. Also, like IPMB, the address byte is in its message
format,
+it needs it to do checksum.
+
+For messages are time related, so this backend will flush the oldest
message
+to queue the newest one.
+
+Link
+
+`Intelligent Platform Management Bus
+Communications Protocol Specification
+`_
+
+`Management Component Transport Protocol (MCTP)
+SMBus/I2C Transport Binding Specification
+`_
+
+How to use
+--
+For example, the I2C5 bus has slave address 0x10, bellowing command
will create
+the related message queue interface:
+
+echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-5/new_device
+
+Then you can dump the messages like this:
+
+hexdump -C /sys/bus/i2c/devices/5-1010/slave-mqueue
+
+Code Example
+
+*Note: call 'lseek' before 'read', this is a requirement from kernfs'
design.*
+
+::
+
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+
+  int main(int argc, char *argv[])
+  {
+  int i, r;
+  struct pollfd pfd;
+  struct 

Re: [PATCH i2c/slave-mqueue v1] i2c: slave-mqueue: add a slave backend to receive and queue messages

2018-03-19 Thread Wang, Haiyue

Thanks, Andy.


Hi Wolfram,

Let me introduce some development background, it is used for OpenBMC 
project,


which belongs to the Linux Foundation now 
(https://www.linuxfoundation.org/blog/openbmc-project-community-comes-together-at-the-linux-foundation-to-define-open-source-implementation-of-bmc-firmware-stack/).


1. *https://goo.gl/WgvPFi*

*** 
***https://lists.ozlabs.org/pipermail/openbmc/2018-January/010493.html* 
*


**

*IPMI is embedded within IPMB (similar to KCS, BT?)*

*

 *

   Who started, who responded to messages

 *

   We need a kernel interface for handling a multi-master slave

 *

   Dell has a non-standard i2c IPMB interface

 o

   Kernel maintains table of outstanding commands

 *

   Brendan suggests we need a kernel driver for doing both MCTP and IPMB

 *

   We can’t do them both in usersland as MCTP makes extensions to SMBUS
   in order to allow arbitration. Problematic extension is the “MCTP
   fairness arbitration”. Requires the i2c controllers on the bus
   (masters/slaves) to observe the line for a certain period of time in
   order to see who is using the line. There’s no userspace API for
   this, and it the timing requirements are tight

 *

   Slave mode is not yet exposed to the user

 *

   As we don’t have a userspace interface, it makes sense to add a new one

*

BR,
Haiyue

On 2018-03-20 03:32, Andy Shevchenko wrote:

On Sat, 2018-03-17 at 11:48 +0800, Haiyue Wang wrote:

Some protocols over I2C are designed for bi-directional transferring
messages by using I2C Master Write protocol. Like the MCTP (Management
Component Transport Protocol) and IPMB (Intelligent Platform
Management
Bus), they both require that the userspace can receive messages from
I2C dirvers under slave mode.

This new slave mqueue backend is used to receive and queue messages,
it
will exposes these messages to userspace by sysfs bin file.


Wolfram, I'm not sure this is the best approach, though I can't propose
anything else right now.

If you are satisfied with it, I give a formal

Reviewed-by: Andy Shevchenko 


Signed-off-by: Haiyue Wang 
---
  Documentation/i2c/slave-mqueue-backend.rst | 125 ++
  drivers/i2c/Kconfig|  13 ++
  drivers/i2c/Makefile   |   1 +
  drivers/i2c/i2c-slave-mqueue.c | 202
+
  4 files changed, 341 insertions(+)
  create mode 100644 Documentation/i2c/slave-mqueue-backend.rst
  create mode 100644 drivers/i2c/i2c-slave-mqueue.c

diff --git a/Documentation/i2c/slave-mqueue-backend.rst
b/Documentation/i2c/slave-mqueue-backend.rst
new file mode 100644
index 000..69d6437
--- /dev/null
+++ b/Documentation/i2c/slave-mqueue-backend.rst
@@ -0,0 +1,125 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=
+Linux I2C slave message queue backend
+=
+
+:Author: Haiyue Wang 
+
+Some protocols over I2C/SMBus are designed for bi-directional
transferring
+messages by using I2C Master Write protocol. This requires that both
sides
+of the communication have slave addresses.
+
+Like MCTP (Management Component Transport Protocol) and IPMB
(Intelligent
+Platform Management Bus), they both require that the userspace can
receive
+messages from i2c dirvers under slave mode.
+
+This I2C slave mqueue (message queue) backend is used to receive and
queue
+messages from the remote i2c intelligent device; and it will add the
target
+slave address (with R/W# bit is always 0) into the message at the
first byte,
+so that userspace can use this byte to dispatch the messages into
different
+handling modules. Also, like IPMB, the address byte is in its message
format,
+it needs it to do checksum.
+
+For messages are time related, so this backend will flush the oldest
message
+to queue the newest one.
+
+Link
+
+`Intelligent Platform Management Bus
+Communications Protocol Specification
+`_
+
+`Management Component Transport Protocol (MCTP)
+SMBus/I2C Transport Binding Specification
+`_
+
+How to use
+--
+For example, the I2C5 bus has slave address 0x10, bellowing command
will create
+the related message queue interface:
+
+echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-5/new_device
+
+Then you can dump the messages like this:
+
+hexdump -C /sys/bus/i2c/devices/5-1010/slave-mqueue
+
+Code Example
+
+*Note: call 'lseek' before 'read', this is a requirement from kernfs'
design.*
+
+::
+
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+  #include 
+
+  int main(int argc, char *argv[])
+  {
+  int i, r;
+  struct pollfd pfd;
+  struct timespec ts;
+  unsigned char data[256];
+
+  pfd.fd = open(argv[1], O_RDONLY | 

Re: [PATCH dts/arm/aspeed-g5 v1] ARM: dts: aspeed-g5: Add IPMI KCS node

2018-03-15 Thread Wang, Haiyue

Hi Joel and Andrew,

Have time to review this patch ? Hope for your comments. :-)

BR,
Haiyue

On 2018-03-07 13:04, Haiyue Wang wrote:

The IPMI KCS device part of the LPC interface and is used for
communication with the host processor.

Signed-off-by: Haiyue Wang 
---
  arch/arm/boot/dts/aspeed-g5.dtsi | 43 +++-
  1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 8eac57c..f443169 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -267,8 +267,40 @@
ranges = <0x0 0x1e789000 0x1000>;
  
  lpc_bmc: lpc-bmc@0 {

-   compatible = "aspeed,ast2500-lpc-bmc";
+   compatible = "aspeed,ast2500-lpc-bmc", 
"simple-mfd", "syscon";
reg = <0x0 0x80>;
+   reg-io-width = <4>;
+
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges = <0x0 0x0 0x80>;
+
+   kcs1: kcs1@0 {
+   compatible = 
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <1>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
+   kcs2: kcs2@0 {
+   compatible = 
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <2>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
+   kcs3: kcs3@0 {
+   compatible = 
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <3>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
};
  
  lpc_host: lpc-host@80 {

@@ -294,6 +326,15 @@
status = "disabled";
};
  
+	kcs4: kcs4@0 {

+   compatible = 
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0xa0>;
+   interrupts = <8>;
+   kcs_chan = <4>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
lhc: lhc@20 {
compatible = 
"aspeed,ast2500-lhc";
reg = <0x20 0x24 0x48 0x8>;




Re: [PATCH dts/arm/aspeed-g5 v1] ARM: dts: aspeed-g5: Add IPMI KCS node

2018-03-15 Thread Wang, Haiyue

Hi Joel and Andrew,

Have time to review this patch ? Hope for your comments. :-)

BR,
Haiyue

On 2018-03-07 13:04, Haiyue Wang wrote:

The IPMI KCS device part of the LPC interface and is used for
communication with the host processor.

Signed-off-by: Haiyue Wang 
---
  arch/arm/boot/dts/aspeed-g5.dtsi | 43 +++-
  1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 8eac57c..f443169 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -267,8 +267,40 @@
ranges = <0x0 0x1e789000 0x1000>;
  
  lpc_bmc: lpc-bmc@0 {

-   compatible = "aspeed,ast2500-lpc-bmc";
+   compatible = "aspeed,ast2500-lpc-bmc", 
"simple-mfd", "syscon";
reg = <0x0 0x80>;
+   reg-io-width = <4>;
+
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges = <0x0 0x0 0x80>;
+
+   kcs1: kcs1@0 {
+   compatible = 
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <1>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
+   kcs2: kcs2@0 {
+   compatible = 
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <2>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
+   kcs3: kcs3@0 {
+   compatible = 
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0x80>;
+   interrupts = <8>;
+   kcs_chan = <3>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
};
  
  lpc_host: lpc-host@80 {

@@ -294,6 +326,15 @@
status = "disabled";
};
  
+	kcs4: kcs4@0 {

+   compatible = 
"aspeed,ast2500-kcs-bmc";
+   reg = <0x0 0xa0>;
+   interrupts = <8>;
+   kcs_chan = <4>;
+   kcs_addr = <0x0>;
+   status = "disabled";
+   };
+
lhc: lhc@20 {
compatible = 
"aspeed,ast2500-lhc";
reg = <0x20 0x24 0x48 0x8>;




Re: [PATCH dts/arm/aspeed-g5 v1] ARM: dts: aspeed-g5: Add IPMI KCS node

2018-03-06 Thread Wang, Haiyue

On 2018-03-07 11:56, Joel Stanley wrote:

And the patch is generated by rebasing on:
https://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git
Please help to review.

Thanks for the patch. I suggest you submit this patch for inclusion in
the upstream kernel. To do this, send it to:
Joel Stanley
Andrew Jeffery
linux-arm-ker...@lists.infradead.org
linux-asp...@lists.ozlabs.org
linux-kernel@vger.kernel.org

Got it.

And I will consider it for merging.

 From there I can backport it into the dev-4.13 tree.

Cheers,

Joel





Re: [PATCH dts/arm/aspeed-g5 v1] ARM: dts: aspeed-g5: Add IPMI KCS node

2018-03-06 Thread Wang, Haiyue

On 2018-03-07 11:56, Joel Stanley wrote:

And the patch is generated by rebasing on:
https://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git
Please help to review.

Thanks for the patch. I suggest you submit this patch for inclusion in
the upstream kernel. To do this, send it to:
Joel Stanley
Andrew Jeffery
linux-arm-ker...@lists.infradead.org
linux-asp...@lists.ozlabs.org
linux-kernel@vger.kernel.org

Got it.

And I will consider it for merging.

 From there I can backport it into the dev-4.13 tree.

Cheers,

Joel





Re: [PATCH ipmi/kcs_bmc v6] ipmi: kcs_bmc: coding-style fixes and use new poll type

2018-02-26 Thread Wang, Haiyue



On 2018-02-26 23:50, Corey Minyard wrote:

On 02/26/2018 09:48 AM, Haiyue Wang wrote:

Many for coding-style fixes, and update the poll API with the new
type '__poll_t', this is new commit from linux-4.16-rc1.

Signed-off-by: Haiyue Wang 


Sorry for the delay, I was on jury duty last week.  But it looks like 
you got

some useful changes in.

I'm hoping you are done with this patch :-).  I've included in my 
tree, but

I can replace if necessary.

Thanks,


Thanks for your time, my mistake, this one should be last one. :-)

BR,
Haiyue


-corey


---
v5 -> v6:
  - Add the missed change to EPOLLIN.




Re: [PATCH ipmi/kcs_bmc v6] ipmi: kcs_bmc: coding-style fixes and use new poll type

2018-02-26 Thread Wang, Haiyue



On 2018-02-26 23:50, Corey Minyard wrote:

On 02/26/2018 09:48 AM, Haiyue Wang wrote:

Many for coding-style fixes, and update the poll API with the new
type '__poll_t', this is new commit from linux-4.16-rc1.

Signed-off-by: Haiyue Wang 


Sorry for the delay, I was on jury duty last week.  But it looks like 
you got

some useful changes in.

I'm hoping you are done with this patch :-).  I've included in my 
tree, but

I can replace if necessary.

Thanks,


Thanks for your time, my mistake, this one should be last one. :-)

BR,
Haiyue


-corey


---
v5 -> v6:
  - Add the missed change to EPOLLIN.




Re: [PATCH arm/aspeed/ast2500 v2] eSPI: add ASPEED AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-02-23 Thread Wang, Haiyue

On 2018-02-23 18:25, Andy Shevchenko wrote:

On Fri, 2018-02-23 at 15:04 +0800, Haiyue Wang wrote:

When PCH works under eSPI mode, the PMC (Power Management Controller)
in
PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in
dead loop if no SUS_ACK assert. This is the basic requirement for the
BMC
works as eSPI slave.

So, do we have an agreement that the driver should go in this shape w/o
interacting with SPI subsystem?
Not sure, I've added the specification of eSPI, hope people don't feel 
confused with SPI. :-)

Also few comments below.


+config ASPEED_ESPI_SLAVE
+   depends on (ARCH_ASPEED || COMPILE_TEST) && REGMAP_MMIO

I would rather split this to two
depends on REGMAP_MMIO
depends on ARCH_ASPEED || COMPILE_TEST

OK, it looks clean. I referred to:
config ASPEED_LPC_CTRL
    depends on (ARCH_ASPEED || COMPILE_TEST) && REGMAP && MFD_SYSCON


+   tristate "Aspeed ast2500 eSPI slave device driver"
+   ---help---
+ Control Aspeed ast2500 eSPI slave controller to handle
event
+ which needs the firmware's processing.
+#include 

What exactly requires this header?

Oh, I ctrl+c / ctrl+v from other device tree usage module. :-(
Remove it now. Thanks for making the code more clean.

+static int aspeed_espi_slave_probe(struct platform_device *pdev)
+{
+   struct aspeed_espi_slave_data *priv;
+   struct device *dev = >dev;
+   struct resource *res;
+   void __iomem *regs;
+   int rc;
+
+   dev_set_name(dev, DEVICE_NAME);

Do this after checks and memory allocations.

Fixed!

+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   regs = devm_ioremap_resource(dev, res);
+   if (IS_ERR(regs))
+   return PTR_ERR(regs);
+
+   priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+   if (!priv)
+   return -ENOMEM;
+
+   priv->map = devm_regmap_init_mmio(dev, regs,
_slave_regmap_cfg);
+   if (IS_ERR(priv->map))
+   return PTR_ERR(priv->map);
+
+static const struct of_device_id of_espi_slave_match_table[] = {
+   { .compatible = "aspeed,ast2500-espi-slave" },
+   { }
+};
+MODULE_DEVICE_TABLE(of, of_espi_slave_match_table);

This one should be closer to the struct of_device_id.

Fixed.



Re: [PATCH arm/aspeed/ast2500 v2] eSPI: add ASPEED AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-02-23 Thread Wang, Haiyue

On 2018-02-23 18:25, Andy Shevchenko wrote:

On Fri, 2018-02-23 at 15:04 +0800, Haiyue Wang wrote:

When PCH works under eSPI mode, the PMC (Power Management Controller)
in
PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in
dead loop if no SUS_ACK assert. This is the basic requirement for the
BMC
works as eSPI slave.

So, do we have an agreement that the driver should go in this shape w/o
interacting with SPI subsystem?
Not sure, I've added the specification of eSPI, hope people don't feel 
confused with SPI. :-)

Also few comments below.


+config ASPEED_ESPI_SLAVE
+   depends on (ARCH_ASPEED || COMPILE_TEST) && REGMAP_MMIO

I would rather split this to two
depends on REGMAP_MMIO
depends on ARCH_ASPEED || COMPILE_TEST

OK, it looks clean. I referred to:
config ASPEED_LPC_CTRL
    depends on (ARCH_ASPEED || COMPILE_TEST) && REGMAP && MFD_SYSCON


+   tristate "Aspeed ast2500 eSPI slave device driver"
+   ---help---
+ Control Aspeed ast2500 eSPI slave controller to handle
event
+ which needs the firmware's processing.
+#include 

What exactly requires this header?

Oh, I ctrl+c / ctrl+v from other device tree usage module. :-(
Remove it now. Thanks for making the code more clean.

+static int aspeed_espi_slave_probe(struct platform_device *pdev)
+{
+   struct aspeed_espi_slave_data *priv;
+   struct device *dev = >dev;
+   struct resource *res;
+   void __iomem *regs;
+   int rc;
+
+   dev_set_name(dev, DEVICE_NAME);

Do this after checks and memory allocations.

Fixed!

+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   regs = devm_ioremap_resource(dev, res);
+   if (IS_ERR(regs))
+   return PTR_ERR(regs);
+
+   priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+   if (!priv)
+   return -ENOMEM;
+
+   priv->map = devm_regmap_init_mmio(dev, regs,
_slave_regmap_cfg);
+   if (IS_ERR(priv->map))
+   return PTR_ERR(priv->map);
+
+static const struct of_device_id of_espi_slave_match_table[] = {
+   { .compatible = "aspeed,ast2500-espi-slave" },
+   { }
+};
+MODULE_DEVICE_TABLE(of, of_espi_slave_match_table);

This one should be closer to the struct of_device_id.

Fixed.



Re: [PATCH] MAINTAINERS: Update ASPEED entry with details

2018-02-22 Thread Wang, Haiyue



On 2018-02-23 08:11, Andrew Jeffery wrote:

Hi Haiyue,

On Thu, 22 Feb 2018, at 19:20, Wang, Haiyue wrote:

Dear Andrew & Joel,

Since you are ASPEED BMC experts, any time and interest in eSPI code
review ? I've sent

it before, but no more response. Intel recommends eSPI bus than LPC as I
know. I just kept

the minimal eSPI code which is approved to work well in our real server
boards for two more

years. Other part of eSPI driver from ASPEED's SDK  has been removed,
because ePSI is a new

thing, we only use a small feature set like booting host.

We Intel submit this eSPI patch for openbmc upstreaming, hope for your
response. :-)

https://patchwork.kernel.org/patch/10166577/


There are some comments against the v1 that you linked to above, is there a v2 
on the lists?

A long holiday back, will send v2 patch soon.

Separately it's better to ping us by replying to the patch itself and putting 
us in To/Cc, that way we keep discussions focused on the patch at hand here.

Got it. Thanks for your reply.


Cheers,

Andrew




Re: [PATCH] MAINTAINERS: Update ASPEED entry with details

2018-02-22 Thread Wang, Haiyue



On 2018-02-23 08:11, Andrew Jeffery wrote:

Hi Haiyue,

On Thu, 22 Feb 2018, at 19:20, Wang, Haiyue wrote:

Dear Andrew & Joel,

Since you are ASPEED BMC experts, any time and interest in eSPI code
review ? I've sent

it before, but no more response. Intel recommends eSPI bus than LPC as I
know. I just kept

the minimal eSPI code which is approved to work well in our real server
boards for two more

years. Other part of eSPI driver from ASPEED's SDK  has been removed,
because ePSI is a new

thing, we only use a small feature set like booting host.

We Intel submit this eSPI patch for openbmc upstreaming, hope for your
response. :-)

https://patchwork.kernel.org/patch/10166577/


There are some comments against the v1 that you linked to above, is there a v2 
on the lists?

A long holiday back, will send v2 patch soon.

Separately it's better to ping us by replying to the patch itself and putting 
us in To/Cc, that way we keep discussions focused on the patch at hand here.

Got it. Thanks for your reply.


Cheers,

Andrew




Re: [PATCH] MAINTAINERS: Update ASPEED entry with details

2018-02-22 Thread Wang, Haiyue

Dear Andrew & Joel,

Since you are ASPEED BMC experts, any time and interest in eSPI code 
review ? I've sent


it before, but no more response. Intel recommends eSPI bus than LPC as I 
know. I just kept


the minimal eSPI code which is approved to work well in our real server 
boards for two more


years. Other part of eSPI driver from ASPEED's SDK  has been removed, 
because ePSI is a new


thing, we only use a small feature set like booting host.

We Intel submit this eSPI patch for openbmc upstreaming, hope for your 
response. :-)


https://patchwork.kernel.org/patch/10166577/



On 2018-02-22 16:39, Andrew Jeffery wrote:


On Thu, 22 Feb 2018, at 15:33, Joel Stanley wrote:

I am interested in all ASPEED drivers, and the previous match wasn't
grabbing files in nested directories. Use N instead.

Add the arm kernel mailing list so that patches get reviewed there, and
the linux-aspeed list which exists only so I can use patchwork to track
patches.

Add Andrew as a reviewer, because he is involved in reviewing ASPEED
stuff.

Signed-off-by: Joel Stanley 

Acked-by: Andrew Jeffery 




Re: [PATCH] MAINTAINERS: Update ASPEED entry with details

2018-02-22 Thread Wang, Haiyue

Dear Andrew & Joel,

Since you are ASPEED BMC experts, any time and interest in eSPI code 
review ? I've sent


it before, but no more response. Intel recommends eSPI bus than LPC as I 
know. I just kept


the minimal eSPI code which is approved to work well in our real server 
boards for two more


years. Other part of eSPI driver from ASPEED's SDK  has been removed, 
because ePSI is a new


thing, we only use a small feature set like booting host.

We Intel submit this eSPI patch for openbmc upstreaming, hope for your 
response. :-)


https://patchwork.kernel.org/patch/10166577/



On 2018-02-22 16:39, Andrew Jeffery wrote:


On Thu, 22 Feb 2018, at 15:33, Joel Stanley wrote:

I am interested in all ASPEED drivers, and the previous match wasn't
grabbing files in nested directories. Use N instead.

Add the arm kernel mailing list so that patches get reviewed there, and
the linux-aspeed list which exists only so I can use patchwork to track
patches.

Add Andrew as a reviewer, because he is involved in reviewing ASPEED
stuff.

Signed-off-by: Joel Stanley 

Acked-by: Andrew Jeffery 




Re: [PATCH ipmi/kcs_bmc v2] ipmi: kcs_bmc: make the code be more clean

2018-02-20 Thread Wang, Haiyue



On 2018-02-20 21:29, Corey Minyard wrote:

On 02/19/2018 09:55 AM, Haiyue Wang wrote:

---
When you use ---, it means everything following is not in the commit 
text,

including your signature.


Got it.

v1 -> v2:


Do you want me to fold this into the previous patch?  That's generally
not how things work, a new patch is fine for this, with a list of things
done like below.


I will submit a new patch.

One comment inline below...



Add 'SPDX-License-Identifier' style for header files modification.
---

1. Add the missed key word '__user' for read / write.
2. Remove the prefix 'file' of 'file_to_kcs_bmc', no need this
duplicated word as its parameter has 'struct file *filp'.
3. Change the 'unsigned int' to '__poll_t' to meet the new 'poll'
definition.
4. Correct the 'SPDX-License-Identifier' style for header files.

Signed-off-by: Haiyue Wang 
---
  drivers/char/ipmi/kcs_bmc.c    | 32 
+---

  drivers/char/ipmi/kcs_bmc.h    |  6 --
  drivers/char/ipmi/kcs_bmc_aspeed.c |  4 +++-
  include/uapi/linux/ipmi_bmc.h  |  6 --
  4 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index 6476bfb..fbfc05e 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -1,5 +1,7 @@
  // SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2015-2018, Intel Corporation.
+/*
+ * Copyright (c) 2015-2018, Intel Corporation.
+ */
    #define pr_fmt(fmt) "kcs-bmc: " fmt
  @@ -242,14 +244,14 @@ int kcs_bmc_handle_event(struct kcs_bmc 
*kcs_bmc)

  }
  EXPORT_SYMBOL(kcs_bmc_handle_event);
  -static inline struct kcs_bmc *file_to_kcs_bmc(struct file *filp)
+static inline struct kcs_bmc *to_kcs_bmc(struct file *filp)
  {
  return container_of(filp->private_data, struct kcs_bmc, miscdev);
  }
    static int kcs_bmc_open(struct inode *inode, struct file *filp)
  {
-    struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp);
+    struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp);
  int ret = 0;
    spin_lock_irq(_bmc->lock);
@@ -262,25 +264,25 @@ static int kcs_bmc_open(struct inode *inode, 
struct file *filp)

  return ret;
  }
  -static unsigned int kcs_bmc_poll(struct file *filp, poll_table *wait)
+static __poll_t kcs_bmc_poll(struct file *filp, poll_table *wait)
  {
-    struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp);
-    unsigned int mask = 0;
+    struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp);
+    __poll_t mask = 0;
    poll_wait(filp, _bmc->queue, wait);
    spin_lock_irq(_bmc->lock);
  if (kcs_bmc->data_in_avail)
-    mask |= POLLIN;
+    mask |= EPOLLIN;


I get this:

  CC [M]  drivers/char/ipmi/kcs_bmc.o
../drivers/char/ipmi/kcs_bmc.c: In function ‘kcs_bmc_poll’:
../drivers/char/ipmi/kcs_bmc.c:276:11: error: ‘EPOLLIN’ undeclared 
(first use in this function)

   mask |= EPOLLIN;
   ^
../drivers/char/ipmi/kcs_bmc.c:276:11: note: each undeclared 
identifier is reported only once for each function it appears in


probably need to include linux/eventpoll.h

I forgot to tell you that you need update the git tree, it is merged in 
from 'Linux 4.16-rc1'. Like bt-bmc.c. :)


git log -p drivers/char/ipmi/bt-bmc.c
commit a9a08845e9acbd224e4ee466f5c1275ed50054e8
Author: Linus Torvalds 
Date:   Sun Feb 11 14:34:03 2018 -0800

    vfs: do bulk POLL* -> EPOLL* replacement

    This is the mindless scripted replacement of kernel use of POLL*
    variables as described by Al, done by this script:

    for V in IN OUT PRI ERR RDNORM RDBAND WRNORM WRBAND HUP RDHUP 
NVAL MSG; do
    L=`git grep -l -w POLL$V | grep -v '^t' | grep -v /um/ | 
grep -v '^sa' | grep -v '/poll.h$'|grep -v '^D'`
    for f in $L; do sed -i 
"-es/^\([^\"]*\)\(\\)/\\1E\\2/" $f; done

    done

    with de-mangling cleanups yet to come.

    NOTE! On almost all architectures, the EPOLL* constants have the same
    values as the POLL* constants do.  But they keyword here is "almost".
    For various bad reasons they aren't the same, and epoll() doesn't
    actually work quite correctly in some cases due to this on Sparc et al.

    The next patch from Al will sort out the final differences, and we
    should be all done.

    Scripted-by: Al Viro 
    Signed-off-by: Linus Torvalds 

diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index 7992c87..c95b93b 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -349,10 +349,10 @@ static __poll_t bt_bmc_poll(struct file *file, 
poll_table *wait)

    ctrl = bt_inb(bt_bmc, BT_CTRL);

    if (ctrl & BT_CTRL_H2B_ATN)
-   mask |= POLLIN;
+   mask |= EPOLLIN;

    if (!(ctrl & (BT_CTRL_H_BUSY | BT_CTRL_B2H_ATN)))
-   mask |= POLLOUT;
+   mask |= EPOLLOUT;

    return mask;


-corey


spin_unlock_irq(_bmc->lock);
     

Re: [PATCH ipmi/kcs_bmc v2] ipmi: kcs_bmc: make the code be more clean

2018-02-20 Thread Wang, Haiyue



On 2018-02-20 21:29, Corey Minyard wrote:

On 02/19/2018 09:55 AM, Haiyue Wang wrote:

---
When you use ---, it means everything following is not in the commit 
text,

including your signature.


Got it.

v1 -> v2:


Do you want me to fold this into the previous patch?  That's generally
not how things work, a new patch is fine for this, with a list of things
done like below.


I will submit a new patch.

One comment inline below...



Add 'SPDX-License-Identifier' style for header files modification.
---

1. Add the missed key word '__user' for read / write.
2. Remove the prefix 'file' of 'file_to_kcs_bmc', no need this
duplicated word as its parameter has 'struct file *filp'.
3. Change the 'unsigned int' to '__poll_t' to meet the new 'poll'
definition.
4. Correct the 'SPDX-License-Identifier' style for header files.

Signed-off-by: Haiyue Wang 
---
  drivers/char/ipmi/kcs_bmc.c    | 32 
+---

  drivers/char/ipmi/kcs_bmc.h    |  6 --
  drivers/char/ipmi/kcs_bmc_aspeed.c |  4 +++-
  include/uapi/linux/ipmi_bmc.h  |  6 --
  4 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index 6476bfb..fbfc05e 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -1,5 +1,7 @@
  // SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2015-2018, Intel Corporation.
+/*
+ * Copyright (c) 2015-2018, Intel Corporation.
+ */
    #define pr_fmt(fmt) "kcs-bmc: " fmt
  @@ -242,14 +244,14 @@ int kcs_bmc_handle_event(struct kcs_bmc 
*kcs_bmc)

  }
  EXPORT_SYMBOL(kcs_bmc_handle_event);
  -static inline struct kcs_bmc *file_to_kcs_bmc(struct file *filp)
+static inline struct kcs_bmc *to_kcs_bmc(struct file *filp)
  {
  return container_of(filp->private_data, struct kcs_bmc, miscdev);
  }
    static int kcs_bmc_open(struct inode *inode, struct file *filp)
  {
-    struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp);
+    struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp);
  int ret = 0;
    spin_lock_irq(_bmc->lock);
@@ -262,25 +264,25 @@ static int kcs_bmc_open(struct inode *inode, 
struct file *filp)

  return ret;
  }
  -static unsigned int kcs_bmc_poll(struct file *filp, poll_table *wait)
+static __poll_t kcs_bmc_poll(struct file *filp, poll_table *wait)
  {
-    struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp);
-    unsigned int mask = 0;
+    struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp);
+    __poll_t mask = 0;
    poll_wait(filp, _bmc->queue, wait);
    spin_lock_irq(_bmc->lock);
  if (kcs_bmc->data_in_avail)
-    mask |= POLLIN;
+    mask |= EPOLLIN;


I get this:

  CC [M]  drivers/char/ipmi/kcs_bmc.o
../drivers/char/ipmi/kcs_bmc.c: In function ‘kcs_bmc_poll’:
../drivers/char/ipmi/kcs_bmc.c:276:11: error: ‘EPOLLIN’ undeclared 
(first use in this function)

   mask |= EPOLLIN;
   ^
../drivers/char/ipmi/kcs_bmc.c:276:11: note: each undeclared 
identifier is reported only once for each function it appears in


probably need to include linux/eventpoll.h

I forgot to tell you that you need update the git tree, it is merged in 
from 'Linux 4.16-rc1'. Like bt-bmc.c. :)


git log -p drivers/char/ipmi/bt-bmc.c
commit a9a08845e9acbd224e4ee466f5c1275ed50054e8
Author: Linus Torvalds 
Date:   Sun Feb 11 14:34:03 2018 -0800

    vfs: do bulk POLL* -> EPOLL* replacement

    This is the mindless scripted replacement of kernel use of POLL*
    variables as described by Al, done by this script:

    for V in IN OUT PRI ERR RDNORM RDBAND WRNORM WRBAND HUP RDHUP 
NVAL MSG; do
    L=`git grep -l -w POLL$V | grep -v '^t' | grep -v /um/ | 
grep -v '^sa' | grep -v '/poll.h$'|grep -v '^D'`
    for f in $L; do sed -i 
"-es/^\([^\"]*\)\(\\)/\\1E\\2/" $f; done

    done

    with de-mangling cleanups yet to come.

    NOTE! On almost all architectures, the EPOLL* constants have the same
    values as the POLL* constants do.  But they keyword here is "almost".
    For various bad reasons they aren't the same, and epoll() doesn't
    actually work quite correctly in some cases due to this on Sparc et al.

    The next patch from Al will sort out the final differences, and we
    should be all done.

    Scripted-by: Al Viro 
    Signed-off-by: Linus Torvalds 

diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index 7992c87..c95b93b 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -349,10 +349,10 @@ static __poll_t bt_bmc_poll(struct file *file, 
poll_table *wait)

    ctrl = bt_inb(bt_bmc, BT_CTRL);

    if (ctrl & BT_CTRL_H2B_ATN)
-   mask |= POLLIN;
+   mask |= EPOLLIN;

    if (!(ctrl & (BT_CTRL_H_BUSY | BT_CTRL_B2H_ATN)))
-   mask |= POLLOUT;
+   mask |= EPOLLOUT;

    return mask;


-corey


spin_unlock_irq(_bmc->lock);
    return mask;
  }
  -static ssize_t kcs_bmc_read(struct file *filp, char *buf,
-    size_t count, loff_t 

Re: [PATCH] ipmi: kcs_bmc: mark expected switch fall-through in kcs_bmc_handle_data

2018-02-16 Thread Wang, Haiyue



On 2018-02-15 05:46, Corey Minyard wrote:

On 02/14/2018 11:30 AM, Gustavo A. R. Silva wrote:

In preparation to enabling -Wimplicit-fallthrough, mark switch cases
where we are expecting to fall through.


Thanks, queued for next release.

-corey


Addresses-Coverity-ID: 1465255 ("Missing break in switch")
Signed-off-by: Gustavo A. R. Silva 
---
This code was compiled with GCC 7.3.0

  drivers/char/ipmi/kcs_bmc.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index 3a3498a..6476bfb 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -95,6 +95,7 @@ static void kcs_bmc_handle_data(struct kcs_bmc 
*kcs_bmc)

  switch (kcs_bmc->phase) {
  case KCS_PHASE_WRITE_START:
  kcs_bmc->phase = KCS_PHASE_WRITE_DATA;
+    /* fall through */
Thanks, Gustavo. I see many modules have '/* fall through */', but I 
thought it was a just C comment, I didn't

add it for making code clean. Learned it, thank you! :-)

    case KCS_PHASE_WRITE_DATA:
  if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) {







Re: [PATCH] ipmi: kcs_bmc: mark expected switch fall-through in kcs_bmc_handle_data

2018-02-16 Thread Wang, Haiyue



On 2018-02-15 05:46, Corey Minyard wrote:

On 02/14/2018 11:30 AM, Gustavo A. R. Silva wrote:

In preparation to enabling -Wimplicit-fallthrough, mark switch cases
where we are expecting to fall through.


Thanks, queued for next release.

-corey


Addresses-Coverity-ID: 1465255 ("Missing break in switch")
Signed-off-by: Gustavo A. R. Silva 
---
This code was compiled with GCC 7.3.0

  drivers/char/ipmi/kcs_bmc.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c
index 3a3498a..6476bfb 100644
--- a/drivers/char/ipmi/kcs_bmc.c
+++ b/drivers/char/ipmi/kcs_bmc.c
@@ -95,6 +95,7 @@ static void kcs_bmc_handle_data(struct kcs_bmc 
*kcs_bmc)

  switch (kcs_bmc->phase) {
  case KCS_PHASE_WRITE_START:
  kcs_bmc->phase = KCS_PHASE_WRITE_DATA;
+    /* fall through */
Thanks, Gustavo. I see many modules have '/* fall through */', but I 
thought it was a just C comment, I didn't

add it for making code clean. Learned it, thank you! :-)

    case KCS_PHASE_WRITE_DATA:
  if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) {







Re: [PATCH arm/aspeed/ast2500 v5 1/2] ipmi: add a KCS IPMI BMC driver

2018-02-02 Thread Wang, Haiyue

On 2018-02-02 21:52, Corey Minyard wrote:

On 02/01/2018 08:16 PM, Haiyue Wang wrote:

---
v4->v5
- Fix -Wdiscarded-qualifiers 'const' compile warning.
- Fix size_t printk compile error.

v3->v4
- Change to accept WRITE_START any time.

v2->v3

- Update the KCS phase state machine.
- Fix the race condition of read/write.

v1->v2

- Divide the driver into two parts, one handles the BMC KCS IPMI 2.0 
state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations and BMC 
chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by KCS 
and BT.



Provides a device driver for the KCS (Keyboard Controller Style)
IPMI interface which meets the requirement of the BMC (Baseboard
Management Controllers) side for handling the IPMI request from
host system software.


Ok, this is in my queue, it will go into next once 4.16-rc1 comes out, 
then into

4.16 if all goes well.

Thanks, for your patience and work on this.

*Really appreciate your time on the code review, I really learned more, 
thank you.  :-)


-- Haiyue
*
-corey 




Re: [PATCH arm/aspeed/ast2500 v5 1/2] ipmi: add a KCS IPMI BMC driver

2018-02-02 Thread Wang, Haiyue

On 2018-02-02 21:52, Corey Minyard wrote:

On 02/01/2018 08:16 PM, Haiyue Wang wrote:

---
v4->v5
- Fix -Wdiscarded-qualifiers 'const' compile warning.
- Fix size_t printk compile error.

v3->v4
- Change to accept WRITE_START any time.

v2->v3

- Update the KCS phase state machine.
- Fix the race condition of read/write.

v1->v2

- Divide the driver into two parts, one handles the BMC KCS IPMI 2.0 
state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations and BMC 
chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by KCS 
and BT.



Provides a device driver for the KCS (Keyboard Controller Style)
IPMI interface which meets the requirement of the BMC (Baseboard
Management Controllers) side for handling the IPMI request from
host system software.


Ok, this is in my queue, it will go into next once 4.16-rc1 comes out, 
then into

4.16 if all goes well.

Thanks, for your patience and work on this.

*Really appreciate your time on the code review, I really learned more, 
thank you.  :-)


-- Haiyue
*
-corey 




Re: [PATCH arm/aspeed/ast2500 v4 1/2] ipmi: add a KCS IPMI BMC driver

2018-02-01 Thread Wang, Haiyue



On 2018-02-02 09:10, Corey Minyard wrote:


I loaded this in, tried a compile on x86_64, and got the following:

In file included from ../drivers/char/ipmi/kcs_bmc.c:15:0:
../drivers/char/ipmi/kcs_bmc.h: In function ‘kcs_bmc_priv’:
../drivers/char/ipmi/kcs_bmc.h:100:9: warning: return discards ‘const’ 
qualifier from pointer target type [-Wdiscarded-qualifiers]

  return kcs_bmc->priv;
 ^

-static inline void *kcs_bmc_priv(const struct kcs_bmc *kcs_bmc)
+static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc)  <-- Can this 
fix error on x86_64 ?

{
    return kcs_bmc->priv;
}

In file included from ../include/linux/printk.h:7:0,
 from ../include/linux/kernel.h:14,
 from ../include/asm-generic/bug.h:18,
 from ../arch/x86/include/asm/bug.h:82,
 from ../include/linux/bug.h:5,
 from ../include/linux/io.h:23,
 from ../drivers/char/ipmi/kcs_bmc.c:7:
../drivers/char/ipmi/kcs_bmc.c: In function ‘kcs_bmc_read’:
../include/linux/kern_levels.h:5:18: warning: format ‘%u’ expects 
argument of type ‘unsigned int’, but argument 3 has type ‘size_t {aka 
long unsigned int}’ [-Wformat=]

 #define KERN_SOH "\001"  /* ASCII Start Of Header */
  ^
../include/linux/kern_levels.h:11:18: note: in expansion of macro 
‘KERN_SOH’

 #define KERN_ERR KERN_SOH "3" /* error conditions */
  ^
../include/linux/printk.h:301:9: note: in expansion of macro ‘KERN_ERR’
  printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
 ^
../drivers/char/ipmi/kcs_bmc.c:307:3: note: in expansion of macro 
‘pr_err’

   pr_err("channel=%u with too large data : %u\n",
   ^

https://elinux.org/Debugging_by_printing
However please*note*: always use/%zu/,/%zd/or/%zx/for 
printing/size_t/and/ssize_t/values. ssize_t and size_t are quite common 
values in the kernel, so please use the/%z/to avoid annoying compile 
warnings.
So I change it from "%u" to "%zu", it is passed on my arm-32 compile, is 
it OK on your X64 ?

pr_err("channel=%u with too large data : %zu\n",

In file included from ../drivers/char/ipmi/kcs_bmc_aspeed.c:20:0:
../drivers/char/ipmi/kcs_bmc.h: In function ‘kcs_bmc_priv’:
../drivers/char/ipmi/kcs_bmc.h:100:9: warning: return discards ‘const’ 
qualifier from pointer target type [-Wdiscarded-qualifiers]

  return kcs_bmc->priv;
 ^

So that needs to be fixed before it goes in.

Also, since you are respinning, can you make ASPEED_KCS_IPMI_BMC 
select IPMI_KCS_BMC, like:


diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index bc2568a..d34f40e 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -99,16 +99,11 @@ config IPMI_POWEROFF
 endif # IPMI_HANDLER

 config IPMI_KCS_BMC
-   tristate 'IPMI KCS BMC Interface'
-   help
- Provides a device driver for the KCS (Keyboard Controller 
Style)
- IPMI interface which meets the requirement of the BMC 
(Baseboard

- Management Controllers) side for handling the IPMI request from
- host system software.
+   tristate

 config ASPEED_KCS_IPMI_BMC
    depends on ARCH_ASPEED || COMPILE_TEST
-   depends on IPMI_KCS_BMC
+   select IPMI_KCS_BMC
    select REGMAP_MMIO
    tristate "Aspeed KCS IPMI BMC driver"
    help

It doesn't make much sense to have IPMI_KCS_BMC on its own.  I was 
going to do this till I saw the compiler error.



Got it, will change it to 'select'
-corey 




Re: [PATCH arm/aspeed/ast2500 v4 1/2] ipmi: add a KCS IPMI BMC driver

2018-02-01 Thread Wang, Haiyue



On 2018-02-02 09:10, Corey Minyard wrote:


I loaded this in, tried a compile on x86_64, and got the following:

In file included from ../drivers/char/ipmi/kcs_bmc.c:15:0:
../drivers/char/ipmi/kcs_bmc.h: In function ‘kcs_bmc_priv’:
../drivers/char/ipmi/kcs_bmc.h:100:9: warning: return discards ‘const’ 
qualifier from pointer target type [-Wdiscarded-qualifiers]

  return kcs_bmc->priv;
 ^

-static inline void *kcs_bmc_priv(const struct kcs_bmc *kcs_bmc)
+static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc)  <-- Can this 
fix error on x86_64 ?

{
    return kcs_bmc->priv;
}

In file included from ../include/linux/printk.h:7:0,
 from ../include/linux/kernel.h:14,
 from ../include/asm-generic/bug.h:18,
 from ../arch/x86/include/asm/bug.h:82,
 from ../include/linux/bug.h:5,
 from ../include/linux/io.h:23,
 from ../drivers/char/ipmi/kcs_bmc.c:7:
../drivers/char/ipmi/kcs_bmc.c: In function ‘kcs_bmc_read’:
../include/linux/kern_levels.h:5:18: warning: format ‘%u’ expects 
argument of type ‘unsigned int’, but argument 3 has type ‘size_t {aka 
long unsigned int}’ [-Wformat=]

 #define KERN_SOH "\001"  /* ASCII Start Of Header */
  ^
../include/linux/kern_levels.h:11:18: note: in expansion of macro 
‘KERN_SOH’

 #define KERN_ERR KERN_SOH "3" /* error conditions */
  ^
../include/linux/printk.h:301:9: note: in expansion of macro ‘KERN_ERR’
  printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
 ^
../drivers/char/ipmi/kcs_bmc.c:307:3: note: in expansion of macro 
‘pr_err’

   pr_err("channel=%u with too large data : %u\n",
   ^

https://elinux.org/Debugging_by_printing
However please*note*: always use/%zu/,/%zd/or/%zx/for 
printing/size_t/and/ssize_t/values. ssize_t and size_t are quite common 
values in the kernel, so please use the/%z/to avoid annoying compile 
warnings.
So I change it from "%u" to "%zu", it is passed on my arm-32 compile, is 
it OK on your X64 ?

pr_err("channel=%u with too large data : %zu\n",

In file included from ../drivers/char/ipmi/kcs_bmc_aspeed.c:20:0:
../drivers/char/ipmi/kcs_bmc.h: In function ‘kcs_bmc_priv’:
../drivers/char/ipmi/kcs_bmc.h:100:9: warning: return discards ‘const’ 
qualifier from pointer target type [-Wdiscarded-qualifiers]

  return kcs_bmc->priv;
 ^

So that needs to be fixed before it goes in.

Also, since you are respinning, can you make ASPEED_KCS_IPMI_BMC 
select IPMI_KCS_BMC, like:


diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index bc2568a..d34f40e 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -99,16 +99,11 @@ config IPMI_POWEROFF
 endif # IPMI_HANDLER

 config IPMI_KCS_BMC
-   tristate 'IPMI KCS BMC Interface'
-   help
- Provides a device driver for the KCS (Keyboard Controller 
Style)
- IPMI interface which meets the requirement of the BMC 
(Baseboard

- Management Controllers) side for handling the IPMI request from
- host system software.
+   tristate

 config ASPEED_KCS_IPMI_BMC
    depends on ARCH_ASPEED || COMPILE_TEST
-   depends on IPMI_KCS_BMC
+   select IPMI_KCS_BMC
    select REGMAP_MMIO
    tristate "Aspeed KCS IPMI BMC driver"
    help

It doesn't make much sense to have IPMI_KCS_BMC on its own.  I was 
going to do this till I saw the compiler error.



Got it, will change it to 'select'
-corey 




Re: [PATCH arm/aspeed/ast2500 v3 1/2] ipmi: add a KCS IPMI BMC driver

2018-02-01 Thread Wang, Haiyue



On 2018-02-02 04:32, Corey Minyard wrote:

+static void kcs_bmc_handle_cmd(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);
+    switch (cmd) {
+    case KCS_CMD_WRITE_START:
+    if (kcs_bmc->phase != KCS_PHASE_IDLE &&
+    kcs_bmc->phase != KCS_PHASE_ERROR) {
+    kcs_force_abort(kcs_bmc);
+    break;
+    }
+


The spec says you can do a write start basically any time and the 
state machine starts over. I know I kind of went back and forth on 
this in my previous email, but what you had before is correct, I think.



So change it to the bellowing code is OK now? :-)

+   case KCS_CMD_WRITE_START:
+   kcs_bmc->data_in_avail = false;
+   kcs_bmc->data_in_idx   = 0;
+   kcs_bmc->phase = KCS_PHASE_WRITE;
+   kcs_bmc->error = KCS_NO_ERROR;
+   break;

-corey 




Re: [PATCH arm/aspeed/ast2500 v3 1/2] ipmi: add a KCS IPMI BMC driver

2018-02-01 Thread Wang, Haiyue



On 2018-02-02 04:32, Corey Minyard wrote:

+static void kcs_bmc_handle_cmd(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);
+    switch (cmd) {
+    case KCS_CMD_WRITE_START:
+    if (kcs_bmc->phase != KCS_PHASE_IDLE &&
+    kcs_bmc->phase != KCS_PHASE_ERROR) {
+    kcs_force_abort(kcs_bmc);
+    break;
+    }
+


The spec says you can do a write start basically any time and the 
state machine starts over. I know I kind of went back and forth on 
this in my previous email, but what you had before is correct, I think.



So change it to the bellowing code is OK now? :-)

+   case KCS_CMD_WRITE_START:
+   kcs_bmc->data_in_avail = false;
+   kcs_bmc->data_in_idx   = 0;
+   kcs_bmc->phase = KCS_PHASE_WRITE;
+   kcs_bmc->error = KCS_NO_ERROR;
+   break;

-corey 




Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-30 Thread Wang, Haiyue



On 2018-01-31 09:52, Corey Minyard wrote:

On 01/30/2018 07:37 PM, Wang, Haiyue wrote:



On 2018-01-31 09:25, Corey Minyard wrote:

On 01/30/2018 07:02 PM, Wang, Haiyue wrote:



On 2018-01-31 08:52, Corey Minyard wrote:

On 01/30/2018 06:02 PM, Wang, Haiyue wrote:



On 2018-01-30 21:49, Corey Minyard wrote:

On 01/29/2018 07:57 AM, Wang, Haiyue wrote:



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to 
perform in-band
IPMI communication between a server host and its BMC 
(BaseBoard Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs 
(AST2400 and AST2500)
as a character device. Such SOCs are commonly used as BMCs 
and this driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS 
IPMI 2.0 state;
   the other handles the BMC KCS controller such as AST2500 
IO accessing.
- Use the spin lock APIs to handle the device file 
operations and BMC chip
   IRQ inferface for accessing the same KCS BMC data 
structure.

- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be 
used by KCS and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the 
data is too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set? It won't hurt 
anything if it's not
set.  As it is, you have a race if something opens the 
device while this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+ kcs_bmc->data_in_avail = true;
+ wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do 
error

handling if the phase isn't correct?

Similar thing if the device here isn't open. You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx 
setting from

here, for reasons I will explain later.

If host software sends the data twice such as a retry before 
the BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not 
clear data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host 
software (SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END 
while this driver is in read
state?  The spec is unclear on this, but it really

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-30 Thread Wang, Haiyue



On 2018-01-31 09:52, Corey Minyard wrote:

On 01/30/2018 07:37 PM, Wang, Haiyue wrote:



On 2018-01-31 09:25, Corey Minyard wrote:

On 01/30/2018 07:02 PM, Wang, Haiyue wrote:



On 2018-01-31 08:52, Corey Minyard wrote:

On 01/30/2018 06:02 PM, Wang, Haiyue wrote:



On 2018-01-30 21:49, Corey Minyard wrote:

On 01/29/2018 07:57 AM, Wang, Haiyue wrote:



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to 
perform in-band
IPMI communication between a server host and its BMC 
(BaseBoard Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs 
(AST2400 and AST2500)
as a character device. Such SOCs are commonly used as BMCs 
and this driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang 

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS 
IPMI 2.0 state;
   the other handles the BMC KCS controller such as AST2500 
IO accessing.
- Use the spin lock APIs to handle the device file 
operations and BMC chip
   IRQ inferface for accessing the same KCS BMC data 
structure.

- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be 
used by KCS and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the 
data is too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set? It won't hurt 
anything if it's not
set.  As it is, you have a race if something opens the 
device while this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+ kcs_bmc->data_in_avail = true;
+ wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do 
error

handling if the phase isn't correct?

Similar thing if the device here isn't open. You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx 
setting from

here, for reasons I will explain later.

If host software sends the data twice such as a retry before 
the BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not 
clear data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host 
software (SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END 
while this driver is in read
state?  The spec is unclear on this, but it really only makes 
sense for the host 

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-30 Thread Wang, Haiyue



On 2018-01-31 09:25, Corey Minyard wrote:

On 01/30/2018 07:02 PM, Wang, Haiyue wrote:



On 2018-01-31 08:52, Corey Minyard wrote:

On 01/30/2018 06:02 PM, Wang, Haiyue wrote:



On 2018-01-30 21:49, Corey Minyard wrote:

On 01/29/2018 07:57 AM, Wang, Haiyue wrote:



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to 
perform in-band
IPMI communication between a server host and its BMC 
(BaseBoard Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 
and AST2500)
as a character device. Such SOCs are commonly used as BMCs 
and this driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS 
IPMI 2.0 state;
   the other handles the BMC KCS controller such as AST2500 
IO accessing.
- Use the spin lock APIs to handle the device file operations 
and BMC chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used 
by KCS and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the 
data is too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt 
anything if it's not
set.  As it is, you have a race if something opens the device 
while this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+ kcs_bmc->data_in_avail = true;
+ wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting 
from

here, for reasons I will explain later.

If host software sends the data twice such as a retry before 
the BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not 
clear data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host 
software (SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END 
while this driver is in read
state?  The spec is unclear on this, but it really only makes 
sense for the host to issue
WRITE_START in idle stat and WRITE_END in wri

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-30 Thread Wang, Haiyue



On 2018-01-31 09:25, Corey Minyard wrote:

On 01/30/2018 07:02 PM, Wang, Haiyue wrote:



On 2018-01-31 08:52, Corey Minyard wrote:

On 01/30/2018 06:02 PM, Wang, Haiyue wrote:



On 2018-01-30 21:49, Corey Minyard wrote:

On 01/29/2018 07:57 AM, Wang, Haiyue wrote:



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to 
perform in-band
IPMI communication between a server host and its BMC 
(BaseBoard Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 
and AST2500)
as a character device. Such SOCs are commonly used as BMCs 
and this driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang 

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS 
IPMI 2.0 state;
   the other handles the BMC KCS controller such as AST2500 
IO accessing.
- Use the spin lock APIs to handle the device file operations 
and BMC chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used 
by KCS and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the 
data is too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt 
anything if it's not
set.  As it is, you have a race if something opens the device 
while this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+ kcs_bmc->data_in_avail = true;
+ wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting 
from

here, for reasons I will explain later.

If host software sends the data twice such as a retry before 
the BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not 
clear data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host 
software (SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END 
while this driver is in read
state?  The spec is unclear on this, but it really only makes 
sense for the host to issue
WRITE_START in idle stat and WRITE_END in write state. IMHO it 
should

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-30 Thread Wang, Haiyue



On 2018-01-31 08:52, Corey Minyard wrote:

On 01/30/2018 06:02 PM, Wang, Haiyue wrote:



On 2018-01-30 21:49, Corey Minyard wrote:

On 01/29/2018 07:57 AM, Wang, Haiyue wrote:



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to 
perform in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 
and AST2500)
as a character device. Such SOCs are commonly used as BMCs and 
this driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS 
IPMI 2.0 state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations 
and BMC chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by 
KCS and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the 
data is too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt 
anything if it's not
set.  As it is, you have a race if something opens the device 
while this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+ kcs_bmc->data_in_avail = true;
+ wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting from
here, for reasons I will explain later.

If host software sends the data twice such as a retry before the 
BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not clear 
data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host 
software (SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END while 
this driver is in read
state?  The spec is unclear on this, but it really only makes 
sense for the host to issue
WRITE_START in idle stat and WRITE_END in write state. IMHO it 
should go to error
state.  You might make the case that a WRITE_START anywhere

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-30 Thread Wang, Haiyue



On 2018-01-31 08:52, Corey Minyard wrote:

On 01/30/2018 06:02 PM, Wang, Haiyue wrote:



On 2018-01-30 21:49, Corey Minyard wrote:

On 01/29/2018 07:57 AM, Wang, Haiyue wrote:



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to 
perform in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 
and AST2500)
as a character device. Such SOCs are commonly used as BMCs and 
this driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang 

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS 
IPMI 2.0 state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations 
and BMC chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by 
KCS and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the 
data is too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt 
anything if it's not
set.  As it is, you have a race if something opens the device 
while this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+ kcs_bmc->data_in_avail = true;
+ wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting from
here, for reasons I will explain later.

If host software sends the data twice such as a retry before the 
BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not clear 
data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host 
software (SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END while 
this driver is in read
state?  The spec is unclear on this, but it really only makes 
sense for the host to issue
WRITE_START in idle stat and WRITE_END in write state. IMHO it 
should go to error
state.  You might make the case that a WRITE_START anywhere 
restarts the transact

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-30 Thread Wang, Haiyue



On 2018-01-30 21:49, Corey Minyard wrote:

On 01/29/2018 07:57 AM, Wang, Haiyue wrote:



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and 
this driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS IPMI 
2.0 state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations and 
BMC chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by 
KCS and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the data 
is too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt 
anything if it's not
set.  As it is, you have a race if something opens the device 
while this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+ kcs_bmc->data_in_avail = true;
+ wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting from
here, for reasons I will explain later.

If host software sends the data twice such as a retry before the 
BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not clear 
data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host software 
(SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END while 
this driver is in read
state?  The spec is unclear on this, but it really only makes sense 
for the host to issue
WRITE_START in idle stat and WRITE_END in write state.  IMHO it 
should go to error
state.  You might make the case that a WRITE_START anywhere restarts 
the transaction,
but the feel of the error state machine kind of go

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-30 Thread Wang, Haiyue



On 2018-01-30 21:49, Corey Minyard wrote:

On 01/29/2018 07:57 AM, Wang, Haiyue wrote:



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and 
this driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang 

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS IPMI 
2.0 state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations and 
BMC chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by 
KCS and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the data 
is too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+ kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt 
anything if it's not
set.  As it is, you have a race if something opens the device 
while this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+ kcs_bmc->data_in_avail = true;
+ wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting from
here, for reasons I will explain later.

If host software sends the data twice such as a retry before the 
BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not clear 
data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host software 
(SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END while 
this driver is in read
state?  The spec is unclear on this, but it really only makes sense 
for the host to issue
WRITE_START in idle stat and WRITE_END in write state.  IMHO it 
should go to error
state.  You might make the case that a WRITE_START anywhere restarts 
the transaction,
but the feel of the error state machine kind of goes against that. 
WRITE_END is definitely

wro

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-29 Thread Wang, Haiyue



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this 
driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS IPMI 
2.0 state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations and 
BMC chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by KCS 
and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+    kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the data is 
too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+    kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt anything 
if it's not
set.  As it is, you have a race if something opens the device while 
this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+    kcs_bmc->data_in_avail = true;
+    wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting from
here, for reasons I will explain later.

If host software sends the data twice such as a retry before the 
BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not clear 
data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host software 
(SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END while 
this driver is in read
state?  The spec is unclear on this, but it really only makes sense 
for the host to issue
WRITE_START in idle stat and WRITE_END in write state.  IMHO it should 
go to error
state.  You might make the case that a WRITE_START anywhere restarts 
the transaction,
but the feel of the error state machine kind of goes against that. 
WRITE_END is definitely

wrong an

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-29 Thread Wang, Haiyue



On 2018-01-26 22:48, Corey Minyard wrote:

On 01/26/2018 12:08 AM, Wang, Haiyue wrote:



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this 
driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang 

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS IPMI 
2.0 state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations and 
BMC chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by KCS 
and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+    kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);


I missed this earlier, you need to issue a length error if the data is 
too large.



+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+    kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt anything 
if it's not
set.  As it is, you have a race if something opens the device while 
this code

runs.

Also, don't set the state to wait read until the "write" has 
finished (userland has

read the data out of the buffer.  More on that later.


Understood.

+    kcs_bmc->data_in_avail = true;
+    wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+ kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting from
here, for reasons I will explain later.

If host software sends the data twice such as a retry before the 
BMC's IPMI service starts,
then the two IPMI requests will be merged into one, if not clear 
data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host software 
(SMS). :(


True, but what if the host issues WRITE_START or a WRITE_END while 
this driver is in read
state?  The spec is unclear on this, but it really only makes sense 
for the host to issue
WRITE_START in idle stat and WRITE_END in write state.  IMHO it should 
go to error
state.  You might make the case that a WRITE_START anywhere restarts 
the transaction,
but the feel of the error state machine kind of goes against that. 
WRITE_END is definitely

wrong anywhere but write state.

I just found 

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-25 Thread Wang, Haiyue



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this 
driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang 

---



+
+static ssize_t kcs_bmc_read(struct file *filp, char *buf,
+    size_t count, loff_t *offset)
+{
+    struct kcs_bmc *kcs_bmc = file_kcs_bmc(filp);
+    ssize_t ret = -EAGAIN;
+


This function still has some issues.

You can't call copy_to_user() with a spinlock held or interrupts 
disabled.

To handle readers, you probably need a separate mutex.

Also, this function can return -EAGAIN even if O_NONBLOCK is not set if
kcs_bmc->data_in_avail changes between when you wait on the event
and when you check it under the lock.

You also clear data_in_avail even if the copy_to_user() fails, which is
wrong.

I believe the best way to handle this would be to have the spinlock
protect the inner workings of the state machine and a mutex handle
copying data out, setting/clearing the running flag (thus a mutex
instead of spinlock in open and release) and the ioctl settings (except
for abort where you will need to grab the spinlock).

After the wait event below, grab the mutex.  If data is not available
and O_NONBLOCK is not set, drop the mutex and retry.  Otherwise
this is the only place (besides release) that sets data_in_avail to 
false.

Do the copy_to_user(), grab the spinlock, clear data_in_avail and
data_in_idx, then release the lock and mutex.  If you are really
adventurous you can do this without grabbing the lock using
barriers, but it's probably not necessary here.

The main race is data_in and data_out memory copy from & to between one 
user-land (ipmid) and
the irq handler. If separates the copy_to_user into two parts: check the 
'access_ok(VERIFY_WRITE, to, n)',
if no errors, then grap the spinlock and irq disabled, then 
'memcpy((void __force *)to, from, n);' It it right

calling ?

I will add a mutex to avoid spinlcok using as possible.

+    if (!(filp->f_flags & O_NONBLOCK))
+    wait_event_interruptible(kcs_bmc->queue,
+ kcs_bmc->data_in_avail);
+
+    spin_lock_irq(_bmc->lock);
+
+    if (kcs_bmc->data_in_avail) {
+    kcs_bmc->data_in_avail = false;
+
+    if (count > kcs_bmc->data_in_idx)
+    count = kcs_bmc->data_in_idx;
+
+    if (!copy_to_user(buf, kcs_bmc->data_in, count))
+    ret = count;
+    else
+    ret = -EFAULT;
+    }
+
+    spin_unlock_irq(_bmc->lock);
+
+    return ret;
+}
+



+    }
+
+    spin_unlock_irq(_bmc->lock);
+
+    return ret;
+}






Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-25 Thread Wang, Haiyue



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this 
driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang 

---



+
+static ssize_t kcs_bmc_read(struct file *filp, char *buf,
+    size_t count, loff_t *offset)
+{
+    struct kcs_bmc *kcs_bmc = file_kcs_bmc(filp);
+    ssize_t ret = -EAGAIN;
+


This function still has some issues.

You can't call copy_to_user() with a spinlock held or interrupts 
disabled.

To handle readers, you probably need a separate mutex.

Also, this function can return -EAGAIN even if O_NONBLOCK is not set if
kcs_bmc->data_in_avail changes between when you wait on the event
and when you check it under the lock.

You also clear data_in_avail even if the copy_to_user() fails, which is
wrong.

I believe the best way to handle this would be to have the spinlock
protect the inner workings of the state machine and a mutex handle
copying data out, setting/clearing the running flag (thus a mutex
instead of spinlock in open and release) and the ioctl settings (except
for abort where you will need to grab the spinlock).

After the wait event below, grab the mutex.  If data is not available
and O_NONBLOCK is not set, drop the mutex and retry.  Otherwise
this is the only place (besides release) that sets data_in_avail to 
false.

Do the copy_to_user(), grab the spinlock, clear data_in_avail and
data_in_idx, then release the lock and mutex.  If you are really
adventurous you can do this without grabbing the lock using
barriers, but it's probably not necessary here.

The main race is data_in and data_out memory copy from & to between one 
user-land (ipmid) and
the irq handler. If separates the copy_to_user into two parts: check the 
'access_ok(VERIFY_WRITE, to, n)',
if no errors, then grap the spinlock and irq disabled, then 
'memcpy((void __force *)to, from, n);' It it right

calling ?

I will add a mutex to avoid spinlcok using as possible.

+    if (!(filp->f_flags & O_NONBLOCK))
+    wait_event_interruptible(kcs_bmc->queue,
+ kcs_bmc->data_in_avail);
+
+    spin_lock_irq(_bmc->lock);
+
+    if (kcs_bmc->data_in_avail) {
+    kcs_bmc->data_in_avail = false;
+
+    if (count > kcs_bmc->data_in_idx)
+    count = kcs_bmc->data_in_idx;
+
+    if (!copy_to_user(buf, kcs_bmc->data_in, count))
+    ret = count;
+    else
+    ret = -EFAULT;
+    }
+
+    spin_unlock_irq(_bmc->lock);
+
+    return ret;
+}
+



+    }
+
+    spin_unlock_irq(_bmc->lock);
+
+    return ret;
+}






Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-25 Thread Wang, Haiyue



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this 
driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang 

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS IPMI 2.0 
state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations and BMC 
chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by KCS 
and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+    kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+    kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt anything 
if it's not
set.  As it is, you have a race if something opens the device while 
this code

runs.

Also, don't set the state to wait read until the "write" has finished 
(userland has

read the data out of the buffer.  More on that later.


Understood.

+    kcs_bmc->data_in_avail = true;
+    wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+    kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting from
here, for reasons I will explain later.

If host software sends the data twice such as a retry before the BMC's 
IPMI service starts,
then the two IPMI requests will be merged into one, if not clear 
data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host software 
(SMS). :(

+    switch (cmd) {
+    case KCS_CMD_WRITE_START:
+    kcs_bmc->data_in_avail = false;
+    kcs_bmc->data_in_idx   = 0;
+    kcs_bmc->phase = KCS_PHASE_WRITE;
+    kcs_bmc->error = KCS_NO_ERROR;
+    break;
+
+    case KCS_CMD_WRITE_END:
+    kcs_bmc->phase = KCS_PHASE_WRITE_END;
+    break;
+
+    case KCS_CMD_ABORT:
+    if (kcs_bmc->error == KCS_NO_ERROR)
+    kcs_bmc->error = KCS_ABORTED_BY_COMMAND;
+
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR1;
+    break;
+
+    default:
+    kcs_bmc->error = KCS_ILLEGAL_CONTROL_CODE;
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = 

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-25 Thread Wang, Haiyue



On 2018-01-25 01:48, Corey Minyard wrote:

On 01/24/2018 10:06 AM, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this 
driver

implements the BMC side of the KCS interface.

Signed-off-by: Haiyue Wang 

---
v1->v2

- Divide the driver into two parts, one handles the BMC KCS IPMI 2.0 
state;
   the other handles the BMC KCS controller such as AST2500 IO 
accessing.
- Use the spin lock APIs to handle the device file operations and BMC 
chip

   IRQ inferface for accessing the same KCS BMC data structure.
- Enhanced the phases handling of the KCS BMC.
- Unified the IOCTL definition for IPMI BMC, it will be used by KCS 
and BT.


---

+
+static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc)
+{
+    u8 data;
+
+    switch (kcs_bmc->phase) {
+    case KCS_PHASE_WRITE:
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* set OBF before reading data */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+    kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+    break;
+
+    case KCS_PHASE_WRITE_END:
+    set_state(kcs_bmc, READ_STATE);
+
+    if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ)
+    kcs_bmc->data_in[kcs_bmc->data_in_idx++] =
+    read_data(kcs_bmc);
+
+    kcs_bmc->phase = KCS_PHASE_WAIT_READ;
+    if (kcs_bmc->running) {


Why do you only do this when running is set?  It won't hurt anything 
if it's not
set.  As it is, you have a race if something opens the device while 
this code

runs.

Also, don't set the state to wait read until the "write" has finished 
(userland has

read the data out of the buffer.  More on that later.


Understood.

+    kcs_bmc->data_in_avail = true;
+    wake_up_interruptible(_bmc->queue);
+    }
+    break;
+
+    case KCS_PHASE_READ:
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len)
+    set_state(kcs_bmc, IDLE_STATE);
+
+    data = read_data(kcs_bmc);
+    if (data != KCS_CMD_READ_BYTE) {
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+
+    if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) {
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+    break;
+    }
+
+    write_data(kcs_bmc,
+    kcs_bmc->data_out[kcs_bmc->data_out_idx++]);
+    break;
+
+    case KCS_PHASE_ABORT_ERROR1:
+    set_state(kcs_bmc, READ_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2;
+    break;
+
+    case KCS_PHASE_ABORT_ERROR2:
+    set_state(kcs_bmc, IDLE_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    kcs_bmc->phase = KCS_PHASE_IDLE;
+
+    break;
+
+    default:
+    set_state(kcs_bmc, ERROR_STATE);
+
+    /* Read the Dummy byte */
+    read_data(kcs_bmc);
+
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+    break;
+    }
+}
+
+static void kcs_bmc_handle_command(struct kcs_bmc *kcs_bmc)
+{
+    u8 cmd;
+
+    set_state(kcs_bmc, WRITE_STATE);
+
+    /* Dummy data to generate OBF */
+    write_data(kcs_bmc, KCS_ZERO_DATA);
+
+    cmd = read_data(kcs_bmc);


Shouldn't you check the phase in all the cases below and do error
handling if the phase isn't correct?

Similar thing if the device here isn't open.  You need to handle
that gracefully.

Also, you should remove data_in_avail and data_in_idx setting from
here, for reasons I will explain later.

If host software sends the data twice such as a retry before the BMC's 
IPMI service starts,
then the two IPMI requests will be merged into one, if not clear 
data_in_idx after receving
KCS_CMD_WRITE_START. Most of the states are driven by host software 
(SMS). :(

+    switch (cmd) {
+    case KCS_CMD_WRITE_START:
+    kcs_bmc->data_in_avail = false;
+    kcs_bmc->data_in_idx   = 0;
+    kcs_bmc->phase = KCS_PHASE_WRITE;
+    kcs_bmc->error = KCS_NO_ERROR;
+    break;
+
+    case KCS_CMD_WRITE_END:
+    kcs_bmc->phase = KCS_PHASE_WRITE_END;
+    break;
+
+    case KCS_CMD_ABORT:
+    if (kcs_bmc->error == KCS_NO_ERROR)
+    kcs_bmc->error = KCS_ABORTED_BY_COMMAND;
+
+    kcs_bmc->phase = KCS_PHASE_ABORT_ERROR1;
+    break;
+
+    default:
+    kcs_bmc->error = KCS_ILLEGAL_CONTROL_CODE;
+    set_state(kcs_bmc, ERROR_STATE);
+    write_data(kcs_bmc, kcs_bmc->error);
+    kcs_bmc->phase = KCS_PHASE_ERROR;
+    

Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-25 Thread Wang, Haiyue



On 2018-01-25 01:05, Andy Shevchenko wrote:

On Thu, 2018-01-25 at 00:06 +0800, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-
band
IPMI communication between a server host and its BMC (BaseBoard
Management
Controllers).


+config ASPEED_KCS_IPMI_BMC
+   depends on ARCH_ASPEED || COMPILE_TEST
+   depends on IPMI_KCS_BMC
+   select REGMAP_MMIO
+   tristate "Aspeed KCS IPMI BMC driver"
+   help
+ Provides a driver for the KCS (Keyboard Controller Style)
IPMI
+ interface found on Aspeed SOCs (AST2400 and AST2500).
+
+ The driver implements the BMC side of the KCS contorller,
it
+ provides the access of KCS IO space for BMC side.
+static inline u8 read_data(struct kcs_bmc *kcs_bmc)
+{
+   return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.idr);
+}
+
+static inline void write_data(struct kcs_bmc *kcs_bmc, u8 data)
+{
+   kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.odr, data);
+}
+
+static inline u8 read_status(struct kcs_bmc *kcs_bmc)
+{
+   return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.str);
+}
+
+static inline void write_status(struct kcs_bmc *kcs_bmc, u8 data)
+{
+   kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.str, data);
+}
+
+static void update_status_bits(struct kcs_bmc *kcs_bmc, u8 mask, u8
val)
+{
+   u8 tmp;
+
+   tmp = read_status(kcs_bmc);
+
+   tmp &= ~mask;
+   tmp |= val & mask;
+
+   write_status(kcs_bmc, tmp);
+}

Shouldn't be above some kind of regmap API?
It is KCS spec defined IO access for hidden the low level, if the low 
level supports regmap, such as in kcs_bmc_aspeed.c,

aspeed_kcs_inb & aspeed_kcs_outb.



+/* Different phases of the KCS BMC module */
+enum kcs_phases {
+   /* BMC should not be expecting nor sending any data. */
+   KCS_PHASE_IDLE,

Perhaps kernel-doc?
Code + inline comments should be better than kernel-doc ? Or move it out 
like :


/* The interface for checksum offload between the stack and networking 
drivers

 * is as follows...
 *
 * A. IP checksum related features
 *
 * Drivers advertise checksum offload capabilities in the features of a 
device.
 * From the stack's point of view these are capabilities offered by the 
driver,
 * a driver typically only advertises features that it is capable of 
offloading

 * to its device.
 *
 * The checksum related features are:
 *
 *    NETIF_F_HW_CSUM    - The driver (or its device) is able to 
compute one

 *              IP (one's complement) checksum for any combination
 *              of protocols or protocol layering. The checksum is
 *              computed and set in a packet per the CHECKSUM_PARTIAL
 *              interface (see below).
 *
 *    NETIF_F_IP_CSUM - Driver (device) is only able to checksum plain
 *              TCP or UDP packets over IPv4. These are specifically
 *              unencapsulated packets of the form IPv4|TCP or
 *              IPv4|UDP where the Protocol field in the IPv4 header
 *              is TCP or UDP. The IPv4 header may contain IP options
 *              This feature cannot be set in features for a device
 *              with NETIF_F_HW_CSUM also set. This feature is being
 *              DEPRECATED (see below).

+};



+/* IPMI 2.0 - 9.5, KCS Interface Registers */
+struct kcs_ioreg {
+   u32 idr; /* Input Data Register */
+   u32 odr; /* Output Data Register */
+   u32 str; /* Status Register */

kernel-doc

+};
+
+static inline void *kcs_bmc_priv(const struct kcs_bmc *kcs_bmc)
+{
+   return kcs_bmc->priv;
+}
+
+extern int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc);
+extern struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int
sizeof_priv,
+   u32 channel);

Drop extern.
After dropping extern, it truly passed compilation, have any special 
reason to drop 'extern' ?

I saw in kernel still use extern like : extern void printk_nmi_init(void);

+#endif

Next one could be reviewed when you split this patch to two.

Got it!



Re: [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-25 Thread Wang, Haiyue



On 2018-01-25 01:05, Andy Shevchenko wrote:

On Thu, 2018-01-25 at 00:06 +0800, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-
band
IPMI communication between a server host and its BMC (BaseBoard
Management
Controllers).


+config ASPEED_KCS_IPMI_BMC
+   depends on ARCH_ASPEED || COMPILE_TEST
+   depends on IPMI_KCS_BMC
+   select REGMAP_MMIO
+   tristate "Aspeed KCS IPMI BMC driver"
+   help
+ Provides a driver for the KCS (Keyboard Controller Style)
IPMI
+ interface found on Aspeed SOCs (AST2400 and AST2500).
+
+ The driver implements the BMC side of the KCS contorller,
it
+ provides the access of KCS IO space for BMC side.
+static inline u8 read_data(struct kcs_bmc *kcs_bmc)
+{
+   return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.idr);
+}
+
+static inline void write_data(struct kcs_bmc *kcs_bmc, u8 data)
+{
+   kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.odr, data);
+}
+
+static inline u8 read_status(struct kcs_bmc *kcs_bmc)
+{
+   return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.str);
+}
+
+static inline void write_status(struct kcs_bmc *kcs_bmc, u8 data)
+{
+   kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.str, data);
+}
+
+static void update_status_bits(struct kcs_bmc *kcs_bmc, u8 mask, u8
val)
+{
+   u8 tmp;
+
+   tmp = read_status(kcs_bmc);
+
+   tmp &= ~mask;
+   tmp |= val & mask;
+
+   write_status(kcs_bmc, tmp);
+}

Shouldn't be above some kind of regmap API?
It is KCS spec defined IO access for hidden the low level, if the low 
level supports regmap, such as in kcs_bmc_aspeed.c,

aspeed_kcs_inb & aspeed_kcs_outb.



+/* Different phases of the KCS BMC module */
+enum kcs_phases {
+   /* BMC should not be expecting nor sending any data. */
+   KCS_PHASE_IDLE,

Perhaps kernel-doc?
Code + inline comments should be better than kernel-doc ? Or move it out 
like :


/* The interface for checksum offload between the stack and networking 
drivers

 * is as follows...
 *
 * A. IP checksum related features
 *
 * Drivers advertise checksum offload capabilities in the features of a 
device.
 * From the stack's point of view these are capabilities offered by the 
driver,
 * a driver typically only advertises features that it is capable of 
offloading

 * to its device.
 *
 * The checksum related features are:
 *
 *    NETIF_F_HW_CSUM    - The driver (or its device) is able to 
compute one

 *              IP (one's complement) checksum for any combination
 *              of protocols or protocol layering. The checksum is
 *              computed and set in a packet per the CHECKSUM_PARTIAL
 *              interface (see below).
 *
 *    NETIF_F_IP_CSUM - Driver (device) is only able to checksum plain
 *              TCP or UDP packets over IPv4. These are specifically
 *              unencapsulated packets of the form IPv4|TCP or
 *              IPv4|UDP where the Protocol field in the IPv4 header
 *              is TCP or UDP. The IPv4 header may contain IP options
 *              This feature cannot be set in features for a device
 *              with NETIF_F_HW_CSUM also set. This feature is being
 *              DEPRECATED (see below).

+};



+/* IPMI 2.0 - 9.5, KCS Interface Registers */
+struct kcs_ioreg {
+   u32 idr; /* Input Data Register */
+   u32 odr; /* Output Data Register */
+   u32 str; /* Status Register */

kernel-doc

+};
+
+static inline void *kcs_bmc_priv(const struct kcs_bmc *kcs_bmc)
+{
+   return kcs_bmc->priv;
+}
+
+extern int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc);
+extern struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int
sizeof_priv,
+   u32 channel);

Drop extern.
After dropping extern, it truly passed compilation, have any special 
reason to drop 'extern' ?

I saw in kernel still use extern like : extern void printk_nmi_init(void);

+#endif

Next one could be reviewed when you split this patch to two.

Got it!



Re: [PATCH arm/aspeed/ast2500 v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-24 Thread Wang, Haiyue



On 2018-01-23 16:44, Greg KH wrote:

On Tue, Jan 16, 2018 at 07:52:32PM +0800, Haiyue Wang wrote:

When PCH works under eSPI mode, the PMC (Power Management Controller) in
PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in
dead loop if no SUS_ACK assert. This is the basic requirement for the BMC
works as eSPI slave.

Also for the host power on / off actions, from BMC side, the following VW
(Virtual Wire) messages are done in firmware:
1. SLAVE_BOOT_LOAD_DONE / SLAVE_BOOT_LOAD_STATUS
2. SUS_ACK
3. OOB_RESET_ACK
4. HOST_RESET_ACK

Signed-off-by: Haiyue Wang 
---
  .../devicetree/bindings/misc/aspeed-espi-slave.txt |  20 ++
  Documentation/misc-devices/espi-slave.rst  | 114 +

DT files need to be split out into a separate patch so that the DT
maintainers can properly review them.


--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -471,6 +471,17 @@ config VEXPRESS_SYSCFG
  ARM Ltd. Versatile Express uses specialised platform configuration
  bus. System Configuration interface is one of the possible means
  of generating transactions on this bus.
+config ASPEED_ESPI_SLAVE

You need a blank line above this one please.

Fixed.

+   depends on ARCH_ASPEED || COMPILE_TEST
+   select REGMAP_MMIO

Select or depend?
Before, I used "depends on". I was told to to change "select". I'm not 
sure which is more better by practice ?

+   tristate "Aspeed ast2500 eSPI slave device"
+   ---help---
+ This allows host to access Baseboard Management Controller (BMC) over 
the
+ Enhanced Serial Peripheral Interface (eSPI) bus, which replaces the 
Low Pin
+ Count (LPC) bus.
+
+ Its interface supports peripheral, virtual wire, out-of-band, and 
flash
+ sharing channels.

What is the module name?

You means the --help-- description is not clear and specific ?
  
  config ASPEED_LPC_CTRL

depends on (ARCH_ASPEED || COMPILE_TEST) && REGMAP && MFD_SYSCON
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 5ca5f64..a1081f4 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_GENWQE)  += genwqe/
  obj-$(CONFIG_ECHO)+= echo/
  obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
  obj-$(CONFIG_CXL_BASE)+= cxl/
+obj-$(CONFIG_ASPEED_ESPI_SLAVE) += aspeed-espi-slave.o

Why no tab?

Fixed, thanks.

thanks,

greg k-h




Re: [PATCH arm/aspeed/ast2500 v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-24 Thread Wang, Haiyue



On 2018-01-23 16:44, Greg KH wrote:

On Tue, Jan 16, 2018 at 07:52:32PM +0800, Haiyue Wang wrote:

When PCH works under eSPI mode, the PMC (Power Management Controller) in
PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in
dead loop if no SUS_ACK assert. This is the basic requirement for the BMC
works as eSPI slave.

Also for the host power on / off actions, from BMC side, the following VW
(Virtual Wire) messages are done in firmware:
1. SLAVE_BOOT_LOAD_DONE / SLAVE_BOOT_LOAD_STATUS
2. SUS_ACK
3. OOB_RESET_ACK
4. HOST_RESET_ACK

Signed-off-by: Haiyue Wang 
---
  .../devicetree/bindings/misc/aspeed-espi-slave.txt |  20 ++
  Documentation/misc-devices/espi-slave.rst  | 114 +

DT files need to be split out into a separate patch so that the DT
maintainers can properly review them.


--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -471,6 +471,17 @@ config VEXPRESS_SYSCFG
  ARM Ltd. Versatile Express uses specialised platform configuration
  bus. System Configuration interface is one of the possible means
  of generating transactions on this bus.
+config ASPEED_ESPI_SLAVE

You need a blank line above this one please.

Fixed.

+   depends on ARCH_ASPEED || COMPILE_TEST
+   select REGMAP_MMIO

Select or depend?
Before, I used "depends on". I was told to to change "select". I'm not 
sure which is more better by practice ?

+   tristate "Aspeed ast2500 eSPI slave device"
+   ---help---
+ This allows host to access Baseboard Management Controller (BMC) over 
the
+ Enhanced Serial Peripheral Interface (eSPI) bus, which replaces the 
Low Pin
+ Count (LPC) bus.
+
+ Its interface supports peripheral, virtual wire, out-of-band, and 
flash
+ sharing channels.

What is the module name?

You means the --help-- description is not clear and specific ?
  
  config ASPEED_LPC_CTRL

depends on (ARCH_ASPEED || COMPILE_TEST) && REGMAP && MFD_SYSCON
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 5ca5f64..a1081f4 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_GENWQE)  += genwqe/
  obj-$(CONFIG_ECHO)+= echo/
  obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
  obj-$(CONFIG_CXL_BASE)+= cxl/
+obj-$(CONFIG_ASPEED_ESPI_SLAVE) += aspeed-espi-slave.o

Why no tab?

Fixed, thanks.

thanks,

greg k-h




Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue



On 2018-01-18 10:58, Corey Minyard wrote:

On 01/17/2018 06:16 PM, Wang, Haiyue wrote:



On 2018-01-17 23:59, Corey Minyard wrote:

On 01/17/2018 08:31 AM, Wang, Haiyue wrote:



On 2018-01-17 06:12, Corey Minyard wrote:

On 01/16/2018 02:59 PM, Corey Minyard wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 
and AST2500)
as a character device. Such SOCs are commonly used as BMCs and 
this driver

implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface? My 
preference would be to
create a file named include/uapi/linux/ipmi-bmc.h and add the 
following:


#define __IPMI_BMC_IOCTL_MAGIC    0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set 
BT_BMC_IOCTL_SMS_ATN to
IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in 
ipmi-bmc.h and

use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name 
more
specific?  (I made this same error on bt-bmc,c, it should 
probably be renamed.)



How about these IOCTL definitions ? Is it more specific ?

#define IPMI_BMC_IOCTL_SET_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)
#define IPMI_BMC_IOCTL_CLEAR_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x01)
#define IPMI_BMC_IOCTL_FORCE_ABORT _IO(__IPMI_BMC_IOCTL_MAGIC, 0x02)



Those look good to me.  If you could do the switchover to ipmi-bmc.h 
in a separate
patch, that would be cleaner.  Then add the clear atn and force 
abort ioctls in the

patch to add the new driver.

Sound good?

-corey

If I understood correctly, still use KCS_BMC_IOCTL_xxx in kcs_bmc.h 
currently, then add a

patch for ipmi-bmc.h, and modify the bt_bmc.h together. Right ?



No, not exactly.  Just add ipmi-bmc.h and put the ioctls you define 
above in it.  No need for
kcs_bmc.h at all.  We can then switch bt-bmc.c over to use the new 
ioctls later and remove

bt_bmc.h when all the software gets switched over.


Understood. Will use the new ioctls for kcs_bmc firstly.

-corey


Haiyue







Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue



On 2018-01-18 10:58, Corey Minyard wrote:

On 01/17/2018 06:16 PM, Wang, Haiyue wrote:



On 2018-01-17 23:59, Corey Minyard wrote:

On 01/17/2018 08:31 AM, Wang, Haiyue wrote:



On 2018-01-17 06:12, Corey Minyard wrote:

On 01/16/2018 02:59 PM, Corey Minyard wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 
and AST2500)
as a character device. Such SOCs are commonly used as BMCs and 
this driver

implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface? My 
preference would be to
create a file named include/uapi/linux/ipmi-bmc.h and add the 
following:


#define __IPMI_BMC_IOCTL_MAGIC    0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set 
BT_BMC_IOCTL_SMS_ATN to
IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in 
ipmi-bmc.h and

use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name 
more
specific?  (I made this same error on bt-bmc,c, it should 
probably be renamed.)



How about these IOCTL definitions ? Is it more specific ?

#define IPMI_BMC_IOCTL_SET_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)
#define IPMI_BMC_IOCTL_CLEAR_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x01)
#define IPMI_BMC_IOCTL_FORCE_ABORT _IO(__IPMI_BMC_IOCTL_MAGIC, 0x02)



Those look good to me.  If you could do the switchover to ipmi-bmc.h 
in a separate
patch, that would be cleaner.  Then add the clear atn and force 
abort ioctls in the

patch to add the new driver.

Sound good?

-corey

If I understood correctly, still use KCS_BMC_IOCTL_xxx in kcs_bmc.h 
currently, then add a

patch for ipmi-bmc.h, and modify the bt_bmc.h together. Right ?



No, not exactly.  Just add ipmi-bmc.h and put the ioctls you define 
above in it.  No need for
kcs_bmc.h at all.  We can then switch bt-bmc.c over to use the new 
ioctls later and remove

bt_bmc.h when all the software gets switched over.


Understood. Will use the new ioctls for kcs_bmc firstly.

-corey


Haiyue







Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue



On 2018-01-18 00:31, Corey Minyard wrote:

On 01/17/2018 08:31 AM, Wang, Haiyue wrote:





Snip...



+
+struct kcs_bmc {
+    struct regmap *map;
+    spinlock_t lock;


This lock is only used in threads, as far as I can tell. Couldn't 
it just be a normal mutex?

But more on this later.

I missed this lock using in KCS ISR function, for AST2500 is single 
core CPU. The critical data such as
data_in_avail is shared between ISR and user thread, spinlock_t 
related API should be the right one ?

especially for SMP ?



Sort of.  In the case below, you need to use spin_lock_irqsave(), you 
don't necessarily get

here with interrupts disabled.

In the ones called from user context, you should really use 
spin_lock_irq().  Interrupts

should always be on at that point, so it's better.


Understood, will change it with the right API call.

static irqreturn_t kcs_bmc_irq(int irq, void *arg)
{
    
    spin_lock(_bmc->lock);  // <-- MISSED

    switch (sts) {
    case KCS_STR_IBF | KCS_STR_CMD_DAT:
        kcs_rx_cmd(kcs_bmc);
        break;

    case KCS_STR_IBF:
        kcs_rx_data(kcs_bmc);
        break;

    default:
        ret = IRQ_NONE;
        break;
    }

    spin_unlock(_bmc->lock); // <-- MISSED

    return ret;
}





+ spin_lock_irqsave(_bmc->lock, flags);
+    if (kcs_bmc->kcs_phase == KCS_PHASE_READ) {


If you don't modify kcs_phase here, you have a race condition. You 
probably
need a KCS_WAIT_READ condition.  Also, the nomenclature of "read" 
and "write"
here is a little confusing, since your phases are from the host's 
point of view,
not this driver's point of view.  You might want to document that 
explicitly.


The race condition means that the user MAY write the duplicated 
response ?


Not exactly.  Two threads can call this, and if it hasn't transitions 
from the read phase,

the data out will be overwritten.


OK, will add new state KCS_WAIT_READ handling.



Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue



On 2018-01-18 00:31, Corey Minyard wrote:

On 01/17/2018 08:31 AM, Wang, Haiyue wrote:





Snip...



+
+struct kcs_bmc {
+    struct regmap *map;
+    spinlock_t lock;


This lock is only used in threads, as far as I can tell. Couldn't 
it just be a normal mutex?

But more on this later.

I missed this lock using in KCS ISR function, for AST2500 is single 
core CPU. The critical data such as
data_in_avail is shared between ISR and user thread, spinlock_t 
related API should be the right one ?

especially for SMP ?



Sort of.  In the case below, you need to use spin_lock_irqsave(), you 
don't necessarily get

here with interrupts disabled.

In the ones called from user context, you should really use 
spin_lock_irq().  Interrupts

should always be on at that point, so it's better.


Understood, will change it with the right API call.

static irqreturn_t kcs_bmc_irq(int irq, void *arg)
{
    
    spin_lock(_bmc->lock);  // <-- MISSED

    switch (sts) {
    case KCS_STR_IBF | KCS_STR_CMD_DAT:
        kcs_rx_cmd(kcs_bmc);
        break;

    case KCS_STR_IBF:
        kcs_rx_data(kcs_bmc);
        break;

    default:
        ret = IRQ_NONE;
        break;
    }

    spin_unlock(_bmc->lock); // <-- MISSED

    return ret;
}





+ spin_lock_irqsave(_bmc->lock, flags);
+    if (kcs_bmc->kcs_phase == KCS_PHASE_READ) {


If you don't modify kcs_phase here, you have a race condition. You 
probably
need a KCS_WAIT_READ condition.  Also, the nomenclature of "read" 
and "write"
here is a little confusing, since your phases are from the host's 
point of view,
not this driver's point of view.  You might want to document that 
explicitly.


The race condition means that the user MAY write the duplicated 
response ?


Not exactly.  Two threads can call this, and if it hasn't transitions 
from the read phase,

the data out will be overwritten.


OK, will add new state KCS_WAIT_READ handling.



Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue



On 2018-01-17 23:59, Corey Minyard wrote:

On 01/17/2018 08:31 AM, Wang, Haiyue wrote:



On 2018-01-17 06:12, Corey Minyard wrote:

On 01/16/2018 02:59 PM, Corey Minyard wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and 
this driver

implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface? My 
preference would be to
create a file named include/uapi/linux/ipmi-bmc.h and add the 
following:


#define __IPMI_BMC_IOCTL_MAGIC    0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set 
BT_BMC_IOCTL_SMS_ATN to

IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in ipmi-bmc.h and
use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name more
specific?  (I made this same error on bt-bmc,c, it should probably 
be renamed.)



How about these IOCTL definitions ? Is it more specific ?

#define IPMI_BMC_IOCTL_SET_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)
#define IPMI_BMC_IOCTL_CLEAR_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x01)
#define IPMI_BMC_IOCTL_FORCE_ABORT _IO(__IPMI_BMC_IOCTL_MAGIC, 0x02)



Those look good to me.  If you could do the switchover to ipmi-bmc.h 
in a separate
patch, that would be cleaner.  Then add the clear atn and force abort 
ioctls in the

patch to add the new driver.

Sound good?

-corey

If I understood correctly, still use KCS_BMC_IOCTL_xxx in kcs_bmc.h 
currently, then add a

patch for ipmi-bmc.h, and modify the bt_bmc.h together. Right ?

Haiyue


Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue



On 2018-01-17 23:59, Corey Minyard wrote:

On 01/17/2018 08:31 AM, Wang, Haiyue wrote:



On 2018-01-17 06:12, Corey Minyard wrote:

On 01/16/2018 02:59 PM, Corey Minyard wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and 
this driver

implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface? My 
preference would be to
create a file named include/uapi/linux/ipmi-bmc.h and add the 
following:


#define __IPMI_BMC_IOCTL_MAGIC    0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set 
BT_BMC_IOCTL_SMS_ATN to

IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in ipmi-bmc.h and
use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name more
specific?  (I made this same error on bt-bmc,c, it should probably 
be renamed.)



How about these IOCTL definitions ? Is it more specific ?

#define IPMI_BMC_IOCTL_SET_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)
#define IPMI_BMC_IOCTL_CLEAR_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x01)
#define IPMI_BMC_IOCTL_FORCE_ABORT _IO(__IPMI_BMC_IOCTL_MAGIC, 0x02)



Those look good to me.  If you could do the switchover to ipmi-bmc.h 
in a separate
patch, that would be cleaner.  Then add the clear atn and force abort 
ioctls in the

patch to add the new driver.

Sound good?

-corey

If I understood correctly, still use KCS_BMC_IOCTL_xxx in kcs_bmc.h 
currently, then add a

patch for ipmi-bmc.h, and modify the bt_bmc.h together. Right ?

Haiyue


Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue

Thanks Avi, wait for your response when new patch is ready. :-)

BR,
Haiyue


On 2018-01-17 20:54, Avi Fishman wrote:

Sounds great for us (Nuvoton).

Avi.
On Wed, Jan 17, 2018 at 8:32 AM, Wang, Haiyue
<haiyue.w...@linux.intel.com> wrote:


On 2018-01-17 07:06, Joel Stanley wrote:

On Tue, Jan 16, 2018 at 2:59 PM, Corey Minyard <miny...@acm.org> wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a server host and its BMC (BaseBoard
Management
Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this
driver
implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface?  My preference
would be to
create a file named include/uapi/linux/ipmi-bmc.h and add the following:

#define __IPMI_BMC_IOCTL_MAGIC0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN_IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set BT_BMC_IOCTL_SMS_ATN to
IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in ipmi-bmc.h and
use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name more
specific?  (I made this same error on bt-bmc,c, it should probably be
renamed.)

Yes, we had a group of openbmc people get together recently and spoke
about this. Unfortunately Haiyue wasn't there (but other Intel BMC
people were).

We've got code coming from another BMC vendor who will use the same
userspace API. The intention is to unify ASPEED's KCS and BT, along
with Nuvoton's KCS and BT, as you outlined above.

Great design for common BMC code, thanks Joel & Corey.

Then we need to divide the kcs-bmc.c into two files, one (still kcs-bmc.c)
is for handling IPMI KCS state
according to IPMI 2.0 specification, and also handing device misc
operations; another file is called such
as aspeed-kcs-bmc.c which handles ast2500 kcs controller. So that Nuvoton
can define nvvoton-kcs-bmc.c
low level API, and call the IPMI KCS function in kcs-bmc.c ?

How about this idea ? If it makes sense, I will change the code for review
in patch v2.


Cheers,

Joel






Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue

Thanks Avi, wait for your response when new patch is ready. :-)

BR,
Haiyue


On 2018-01-17 20:54, Avi Fishman wrote:

Sounds great for us (Nuvoton).

Avi.
On Wed, Jan 17, 2018 at 8:32 AM, Wang, Haiyue
 wrote:


On 2018-01-17 07:06, Joel Stanley wrote:

On Tue, Jan 16, 2018 at 2:59 PM, Corey Minyard  wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a server host and its BMC (BaseBoard
Management
Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this
driver
implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface?  My preference
would be to
create a file named include/uapi/linux/ipmi-bmc.h and add the following:

#define __IPMI_BMC_IOCTL_MAGIC0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN_IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set BT_BMC_IOCTL_SMS_ATN to
IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in ipmi-bmc.h and
use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name more
specific?  (I made this same error on bt-bmc,c, it should probably be
renamed.)

Yes, we had a group of openbmc people get together recently and spoke
about this. Unfortunately Haiyue wasn't there (but other Intel BMC
people were).

We've got code coming from another BMC vendor who will use the same
userspace API. The intention is to unify ASPEED's KCS and BT, along
with Nuvoton's KCS and BT, as you outlined above.

Great design for common BMC code, thanks Joel & Corey.

Then we need to divide the kcs-bmc.c into two files, one (still kcs-bmc.c)
is for handling IPMI KCS state
according to IPMI 2.0 specification, and also handing device misc
operations; another file is called such
as aspeed-kcs-bmc.c which handles ast2500 kcs controller. So that Nuvoton
can define nvvoton-kcs-bmc.c
low level API, and call the IPMI KCS function in kcs-bmc.c ?

How about this idea ? If it makes sense, I will change the code for review
in patch v2.


Cheers,

Joel






Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue



On 2018-01-17 06:12, Corey Minyard wrote:

On 01/16/2018 02:59 PM, Corey Minyard wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this 
driver

implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface?  My 
preference would be to

create a file named include/uapi/linux/ipmi-bmc.h and add the following:

#define __IPMI_BMC_IOCTL_MAGIC    0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set 
BT_BMC_IOCTL_SMS_ATN to

IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in ipmi-bmc.h and
use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name more
specific?  (I made this same error on bt-bmc,c, it should probably be 
renamed.)



How about these IOCTL definitions ? Is it more specific ?

#define IPMI_BMC_IOCTL_SET_SMS_ATN    _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)
#define IPMI_BMC_IOCTL_CLEAR_SMS_ATN  _IO(__IPMI_BMC_IOCTL_MAGIC, 0x01)
#define IPMI_BMC_IOCTL_FORCE_ABORT    _IO(__IPMI_BMC_IOCTL_MAGIC, 0x02)


More comments inline, as I'll go ahead and review this.


Signed-off-by: Haiyue Wang 
---
  .../devicetree/bindings/ipmi/aspeed-kcs-bmc.txt    |  26 +
  drivers/char/ipmi/Kconfig  |   9 +
  drivers/char/ipmi/Makefile |   1 +
  drivers/char/ipmi/kcs-bmc.c    | 744 
+

  include/uapi/linux/kcs-bmc.h   |  14 +
  5 files changed, 794 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt

  create mode 100644 drivers/char/ipmi/kcs-bmc.c
  create mode 100644 include/uapi/linux/kcs-bmc.h

diff --git 
a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt 
b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt

new file mode 100644
index 000..dd0c73d
--- /dev/null
+++ b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt
@@ -0,0 +1,26 @@
+* Aspeed KCS (Keyboard Controller Style) IPMI interface
+
+The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs
+(BaseBoard Management Controllers) and the KCS interface can be
+used to perform in-band IPMI communication with their host.
+
+Required properties:
+- compatible : should be one of
+    "aspeed,ast2400-kcs-bmc"
+    "aspeed,ast2500-kcs-bmc"
+- interrupts : interrupt generated by the controller
+- kcs_chan : The LPC channel number in the controller
+- kcs_addr : The host CPU IO map address
+
+
+Example:
+
+    kcs3: kcs3@0 {
+    compatible = "aspeed,ast2500-kcs-bmc";
+    reg = <0x0 0x80>;
+    interrupts = <8>;
+    kcs_chan = <3>;
+    kcs_addr = <0xCA2>;
+    status = "okay";
+    };
+
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 3544abc..36132f8 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -104,3 +104,12 @@ config ASPEED_BT_IPMI_BMC
    Provides a driver for the BT (Block Transfer) IPMI interface
    found on Aspeed SOCs (AST2400 and AST2500). The driver
    implements the BMC side of the BT interface.
+
+config ASPEED_KCS_IPMI_BMC
+    depends on ARCH_ASPEED || COMPILE_TEST
+    select REGMAP_MMIO
+    tristate "KCS IPMI bmc driver"
+    help
+  Provides a driver for the KCS (Keyboard Controller Style) IPMI
+  interface found on Aspeed SOCs (AST2400 and AST2500). The driver
+  implements the BMC side of the KCS interface.
\ No newline at end of file
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
index 33b899f..f217bae 100644
--- a/drivers/char/ipmi/Makefile
+++ b/drivers/char/ipmi/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
  obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
  obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
  obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o
+obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs-bmc.o
\ No newline at end of file
diff --git a/drivers/char/ipmi/kcs-bmc.c b/drivers/char/ipmi/kcs-bmc.c
new file mode 100644
index 000..d6eab0b
--- /dev/null
+++ b/drivers/char/ipmi/kcs-bmc.c
@@ -0,0 +1,744 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2015-2018, Intel Corporation.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define KCS_MSG_BUFSIZ  1024
+#define KCS_CHANNEL_MAX 4
+
+/*
+ * This is a BMC device used to communicate to the host
+ */
+#define DEVICE_NAME "ipmi-kcs-host"
+
+
+/* Different Phases of the KCS Module */
+#define KCS_PHASE_IDLE  

Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-17 Thread Wang, Haiyue



On 2018-01-17 06:12, Corey Minyard wrote:

On 01/16/2018 02:59 PM, Corey Minyard wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:
The KCS (Keyboard Controller Style) interface is used to perform 
in-band
IPMI communication between a server host and its BMC (BaseBoard 
Management

Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and 
AST2500)
as a character device. Such SOCs are commonly used as BMCs and this 
driver

implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface?  My 
preference would be to

create a file named include/uapi/linux/ipmi-bmc.h and add the following:

#define __IPMI_BMC_IOCTL_MAGIC    0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set 
BT_BMC_IOCTL_SMS_ATN to

IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in ipmi-bmc.h and
use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name more
specific?  (I made this same error on bt-bmc,c, it should probably be 
renamed.)



How about these IOCTL definitions ? Is it more specific ?

#define IPMI_BMC_IOCTL_SET_SMS_ATN    _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)
#define IPMI_BMC_IOCTL_CLEAR_SMS_ATN  _IO(__IPMI_BMC_IOCTL_MAGIC, 0x01)
#define IPMI_BMC_IOCTL_FORCE_ABORT    _IO(__IPMI_BMC_IOCTL_MAGIC, 0x02)


More comments inline, as I'll go ahead and review this.


Signed-off-by: Haiyue Wang 
---
  .../devicetree/bindings/ipmi/aspeed-kcs-bmc.txt    |  26 +
  drivers/char/ipmi/Kconfig  |   9 +
  drivers/char/ipmi/Makefile |   1 +
  drivers/char/ipmi/kcs-bmc.c    | 744 
+

  include/uapi/linux/kcs-bmc.h   |  14 +
  5 files changed, 794 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt

  create mode 100644 drivers/char/ipmi/kcs-bmc.c
  create mode 100644 include/uapi/linux/kcs-bmc.h

diff --git 
a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt 
b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt

new file mode 100644
index 000..dd0c73d
--- /dev/null
+++ b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt
@@ -0,0 +1,26 @@
+* Aspeed KCS (Keyboard Controller Style) IPMI interface
+
+The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs
+(BaseBoard Management Controllers) and the KCS interface can be
+used to perform in-band IPMI communication with their host.
+
+Required properties:
+- compatible : should be one of
+    "aspeed,ast2400-kcs-bmc"
+    "aspeed,ast2500-kcs-bmc"
+- interrupts : interrupt generated by the controller
+- kcs_chan : The LPC channel number in the controller
+- kcs_addr : The host CPU IO map address
+
+
+Example:
+
+    kcs3: kcs3@0 {
+    compatible = "aspeed,ast2500-kcs-bmc";
+    reg = <0x0 0x80>;
+    interrupts = <8>;
+    kcs_chan = <3>;
+    kcs_addr = <0xCA2>;
+    status = "okay";
+    };
+
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 3544abc..36132f8 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -104,3 +104,12 @@ config ASPEED_BT_IPMI_BMC
    Provides a driver for the BT (Block Transfer) IPMI interface
    found on Aspeed SOCs (AST2400 and AST2500). The driver
    implements the BMC side of the BT interface.
+
+config ASPEED_KCS_IPMI_BMC
+    depends on ARCH_ASPEED || COMPILE_TEST
+    select REGMAP_MMIO
+    tristate "KCS IPMI bmc driver"
+    help
+  Provides a driver for the KCS (Keyboard Controller Style) IPMI
+  interface found on Aspeed SOCs (AST2400 and AST2500). The driver
+  implements the BMC side of the KCS interface.
\ No newline at end of file
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
index 33b899f..f217bae 100644
--- a/drivers/char/ipmi/Makefile
+++ b/drivers/char/ipmi/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
  obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
  obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
  obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o
+obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs-bmc.o
\ No newline at end of file
diff --git a/drivers/char/ipmi/kcs-bmc.c b/drivers/char/ipmi/kcs-bmc.c
new file mode 100644
index 000..d6eab0b
--- /dev/null
+++ b/drivers/char/ipmi/kcs-bmc.c
@@ -0,0 +1,744 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2015-2018, Intel Corporation.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define KCS_MSG_BUFSIZ  1024
+#define KCS_CHANNEL_MAX 4
+
+/*
+ * This is a BMC device used to communicate to the host
+ */
+#define DEVICE_NAME "ipmi-kcs-host"
+
+
+/* Different Phases of the KCS Module */
+#define KCS_PHASE_IDLE  0x00
+#define 

Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-16 Thread Wang, Haiyue



On 2018-01-17 07:06, Joel Stanley wrote:

On Tue, Jan 16, 2018 at 2:59 PM, Corey Minyard  wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a server host and its BMC (BaseBoard Management
Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and AST2500)
as a character device. Such SOCs are commonly used as BMCs and this driver
implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface?  My preference
would be to
create a file named include/uapi/linux/ipmi-bmc.h and add the following:

#define __IPMI_BMC_IOCTL_MAGIC0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN_IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set BT_BMC_IOCTL_SMS_ATN to
IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in ipmi-bmc.h and
use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name more
specific?  (I made this same error on bt-bmc,c, it should probably be
renamed.)

Yes, we had a group of openbmc people get together recently and spoke
about this. Unfortunately Haiyue wasn't there (but other Intel BMC
people were).

We've got code coming from another BMC vendor who will use the same
userspace API. The intention is to unify ASPEED's KCS and BT, along
with Nuvoton's KCS and BT, as you outlined above.

Great design for common BMC code, thanks Joel & Corey.

Then we need to divide the kcs-bmc.c into two files, one (still 
kcs-bmc.c) is for handling IPMI KCS state
according to IPMI 2.0 specification, and also handing device misc 
operations; another file is called such
as aspeed-kcs-bmc.c which handles ast2500 kcs controller. So that 
Nuvoton can define nvvoton-kcs-bmc.c

low level API, and call the IPMI KCS function in kcs-bmc.c ?

How about this idea ? If it makes sense, I will change the code for 
review in patch v2.



Cheers,

Joel




Re: [PATCH arm/aspeed/ast2500 v1] ipmi: add an Aspeed KCS IPMI BMC driver

2018-01-16 Thread Wang, Haiyue



On 2018-01-17 07:06, Joel Stanley wrote:

On Tue, Jan 16, 2018 at 2:59 PM, Corey Minyard  wrote:

On 01/16/2018 05:43 AM, Haiyue Wang wrote:

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a server host and its BMC (BaseBoard Management
Controllers).

This driver exposes the KCS interface on ASpeed SOCs (AST2400 and AST2500)
as a character device. Such SOCs are commonly used as BMCs and this driver
implements the BMC side of the KCS interface.


I thought we were going to unify the BMC ioctl interface?  My preference
would be to
create a file named include/uapi/linux/ipmi-bmc.h and add the following:

#define __IPMI_BMC_IOCTL_MAGIC0xb1
#define IPMI_BMC_IOCTL_SMS_SET_ATN_IO(__IPMI_BMC_IOCTL_MAGIC, 0x00)

to make it the same as BT.  Then in bt-bmc.h, set BT_BMC_IOCTL_SMS_ATN to
IPMI_BMC_IOCTL_SMS_SET_ATN.  Then add the KCS ioctls in ipmi-bmc.h and
use that.  That way we stay backward compatible but we are unified.

Since more KCS interfaces may come around, can you make the name more
specific?  (I made this same error on bt-bmc,c, it should probably be
renamed.)

Yes, we had a group of openbmc people get together recently and spoke
about this. Unfortunately Haiyue wasn't there (but other Intel BMC
people were).

We've got code coming from another BMC vendor who will use the same
userspace API. The intention is to unify ASPEED's KCS and BT, along
with Nuvoton's KCS and BT, as you outlined above.

Great design for common BMC code, thanks Joel & Corey.

Then we need to divide the kcs-bmc.c into two files, one (still 
kcs-bmc.c) is for handling IPMI KCS state
according to IPMI 2.0 specification, and also handing device misc 
operations; another file is called such
as aspeed-kcs-bmc.c which handles ast2500 kcs controller. So that 
Nuvoton can define nvvoton-kcs-bmc.c

low level API, and call the IPMI KCS function in kcs-bmc.c ?

How about this idea ? If it makes sense, I will change the code for 
review in patch v2.



Cheers,

Joel




Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-03 Thread Wang, Haiyue

On 2018-01-04 01:08, Wang, Haiyue wrote:




On 2018-01-04 00:43, Wang, Haiyue wrote:

On 2018-01-03 23:17, Arnd Bergmann wrote:

On Wed, Jan 3, 2018 at 3:21 AM, Wang, Haiyue
<haiyue.w...@linux.intel.com>  wrote:

On 2018-01-03 00:23, Arnd Bergmann wrote:

On Tue, Jan 2, 2018 at 4:36 PM, Wang, Haiyue<haiyue.w...@linux.intel.com>  
wrote:

On 2018-01-02 23:13, Arnd Bergmann wrote:

On 2017-12-31 07:10, Arnd Bergmann wrote:

On the slave side, it seems that aspeed have implemented the
virtual wires partially in hardware and require a driver like the one
you wrote to reply to some of the wires being accessed by the host,
but again it seems plausible that this could be implemented in another
BMC using a generic SPI slave and a transaction layer written
entirely in software.

Yes, you are right, Aspeed have implemented the virtual wires partially.
Tthat's why I named it
as aspeed-espi-slave driver.

Maybe the name should be more specific and refer to only virtual-wire
rather than espi-slave?

We changed Aspeed's reference code about virtual-wire to production code,
which meets the upstream code style. If other people used new features in eSPI
slave, they can add into this place one by one, which is proved to work. This is
a eSPI slave start point for Aspeed, not just virtual wires.

I fear this could tie the application-level protocol too closely to the aspeed
hardware driver. More on that below.


Looks like yes, for eSPI is new thing, not sure other BMC chip 
company how to design the eSPI slave.



You can image bellowing work path:

   KCSMailbox  Snoop (Port 80)  UART 
 ^^ ^  ^
 | ||   |
 | ||   |
  \|/  /
   { LPC IP }< { eSPI IP to
decode
the mmio address }

This is all handled by the drivers/misc/aspeed-lpc-snoop.c driver, right?

This driver just handle port 80. And later may have kcs-bmc.c upstream from
openbmc
project:https://github.com/openbmc/docs/blob/master/kernel-development.md

Ok.


And in our first generation eSPI x86 server, we  just use the eSPI new
function to decode the VW to boot the PCH (eSPI master).

Other functions such as GPIO SMBus, we didn't use it. So for making
things clean, we just keep the basic code, which is verified and tested
well.

For the upstream submission, having the code verified and tested
is secondary, it most of all must be maintainable in the future ;-)

Your current driver is very simple, which is good: it shouldn't try to be
overly generic and do things we won't ever need, but I want to be
sure that I understand the bigger picture well enough and ensure
that the code is generic enough to do the things we know we will
need.

Sure, people should easily add new features into this file. They just need
add other interrupt
handling here. Currently, we handle the basic interrupt bits.

Can you list what other interrupts there are in this hardware block,
and what they relate to? You already said that the MMIO/PIO support
is a separate hardware block that is shared with the LPC slave,
and I guess there is no block for a flash protocol, so is this
VW and SMBUS combined, or does it do more than those two?


Such as:
Flash Channel Tx Error
  OOB Channel Tx Error
  Flash Channel Tx Abort
  OOB Channel Tx Abort
  Peripheral Channel Non-Posted Tx Abort
  Peripheral Channel Posted Tx Abort
  Virtual Wire GPIO Event
  ...


I see that your documentation only refers to the generic principle of
eSPI, while the driver deals mostly with the aspeed specifics. If we
get a generic virtual-wire implementation based on the spi-slave
framework, the documentation would be the same, and part
of the driver would also be the same. OTOH, if one were to use
the SMBUS over eSPI, the high-level interaction with the vw
would have to be different, and at that point, we'd probably want
an abstraction that can deal with both the aspeed hardware and
a simple spi-slave based implementation.

Superficially, the virtual wires closely resemble GPIOs both on
the host and the slave side, so I wonder if your driver could be
rewritten into a gpiochip driver that implements the slave side of
the eSPI VW on ast2500: make it export a set of GPIO lines,
I suppose you'd need 64 GPIOs to cover all possible
bits in ESPI_SYS_ISR and ESPI_SYS1_ISR, plus an irqchip
to handle the virtual events (ESPI_SYSEVT_HOST_RST_WARN
etc). That would let you separate the simple logic (ack after
warn, boot-done after boot, ...) into one driver or even
user space, and keep the low-level driver specific to ast2500
but otherwise independent of the host side. Do you think that
makes sense?

Currently, these virtual wires side-band signals between PCH and BMC
(AST2500) needs to be
handled in time. So we did it in ISR by reading and writing registers. When
this d

Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-03 Thread Wang, Haiyue

On 2018-01-04 01:08, Wang, Haiyue wrote:




On 2018-01-04 00:43, Wang, Haiyue wrote:

On 2018-01-03 23:17, Arnd Bergmann wrote:

On Wed, Jan 3, 2018 at 3:21 AM, Wang, Haiyue
  wrote:

On 2018-01-03 00:23, Arnd Bergmann wrote:

On Tue, Jan 2, 2018 at 4:36 PM, Wang, Haiyue  
wrote:

On 2018-01-02 23:13, Arnd Bergmann wrote:

On 2017-12-31 07:10, Arnd Bergmann wrote:

On the slave side, it seems that aspeed have implemented the
virtual wires partially in hardware and require a driver like the one
you wrote to reply to some of the wires being accessed by the host,
but again it seems plausible that this could be implemented in another
BMC using a generic SPI slave and a transaction layer written
entirely in software.

Yes, you are right, Aspeed have implemented the virtual wires partially.
Tthat's why I named it
as aspeed-espi-slave driver.

Maybe the name should be more specific and refer to only virtual-wire
rather than espi-slave?

We changed Aspeed's reference code about virtual-wire to production code,
which meets the upstream code style. If other people used new features in eSPI
slave, they can add into this place one by one, which is proved to work. This is
a eSPI slave start point for Aspeed, not just virtual wires.

I fear this could tie the application-level protocol too closely to the aspeed
hardware driver. More on that below.


Looks like yes, for eSPI is new thing, not sure other BMC chip 
company how to design the eSPI slave.



You can image bellowing work path:

   KCSMailbox  Snoop (Port 80)  UART 
 ^^ ^  ^
 | ||   |
 | ||   |
  \|/  /
   { LPC IP }< { eSPI IP to
decode
the mmio address }

This is all handled by the drivers/misc/aspeed-lpc-snoop.c driver, right?

This driver just handle port 80. And later may have kcs-bmc.c upstream from
openbmc
project:https://github.com/openbmc/docs/blob/master/kernel-development.md

Ok.


And in our first generation eSPI x86 server, we  just use the eSPI new
function to decode the VW to boot the PCH (eSPI master).

Other functions such as GPIO SMBus, we didn't use it. So for making
things clean, we just keep the basic code, which is verified and tested
well.

For the upstream submission, having the code verified and tested
is secondary, it most of all must be maintainable in the future ;-)

Your current driver is very simple, which is good: it shouldn't try to be
overly generic and do things we won't ever need, but I want to be
sure that I understand the bigger picture well enough and ensure
that the code is generic enough to do the things we know we will
need.

Sure, people should easily add new features into this file. They just need
add other interrupt
handling here. Currently, we handle the basic interrupt bits.

Can you list what other interrupts there are in this hardware block,
and what they relate to? You already said that the MMIO/PIO support
is a separate hardware block that is shared with the LPC slave,
and I guess there is no block for a flash protocol, so is this
VW and SMBUS combined, or does it do more than those two?


Such as:
Flash Channel Tx Error
  OOB Channel Tx Error
  Flash Channel Tx Abort
  OOB Channel Tx Abort
  Peripheral Channel Non-Posted Tx Abort
  Peripheral Channel Posted Tx Abort
  Virtual Wire GPIO Event
  ...


I see that your documentation only refers to the generic principle of
eSPI, while the driver deals mostly with the aspeed specifics. If we
get a generic virtual-wire implementation based on the spi-slave
framework, the documentation would be the same, and part
of the driver would also be the same. OTOH, if one were to use
the SMBUS over eSPI, the high-level interaction with the vw
would have to be different, and at that point, we'd probably want
an abstraction that can deal with both the aspeed hardware and
a simple spi-slave based implementation.

Superficially, the virtual wires closely resemble GPIOs both on
the host and the slave side, so I wonder if your driver could be
rewritten into a gpiochip driver that implements the slave side of
the eSPI VW on ast2500: make it export a set of GPIO lines,
I suppose you'd need 64 GPIOs to cover all possible
bits in ESPI_SYS_ISR and ESPI_SYS1_ISR, plus an irqchip
to handle the virtual events (ESPI_SYSEVT_HOST_RST_WARN
etc). That would let you separate the simple logic (ack after
warn, boot-done after boot, ...) into one driver or even
user space, and keep the low-level driver specific to ast2500
but otherwise independent of the host side. Do you think that
makes sense?

Currently, these virtual wires side-band signals between PCH and BMC
(AST2500) needs to be
handled in time. So we did it in ISR by reading and writing registers. When
this driver is loaded,
then it can handle just in kernel mode, no need a u

Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-03 Thread Wang, Haiyue



On 2018-01-03 22:32, Mark Brown wrote:

On Wed, Jan 03, 2018 at 10:28:22PM +0800, Wang, Haiyue wrote:


Should send to like this ? Because I add patch for Aspeed chip:
./scripts/get_maintainer.pl drivers/misc/aspeed-lpc-snoop.c
Joel Stanley <j...@jms.id.au> (maintainer:ARM/ASPEED MACHINE SUPPORT)
Arnd Bergmann <a...@arndb.de> (supporter:CHAR and MISC DRIVERS)
Greg Kroah-Hartman <gre...@linuxfoundation.org> (supporter:CHAR and MISC
DRIVERS)
linux-kernel@vger.kernel.org (open list)

So it's not actually doing anything at all with the SPI subsystem?  I
lacked any context for the discussion having been copied in part way
through.  If it is a SPI controller it ought to have been in
drivers/spi.

Yes, eSPI just uses the SPI pin definition, but it replaces LPC interface.


Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-03 Thread Wang, Haiyue



On 2018-01-03 22:32, Mark Brown wrote:

On Wed, Jan 03, 2018 at 10:28:22PM +0800, Wang, Haiyue wrote:


Should send to like this ? Because I add patch for Aspeed chip:
./scripts/get_maintainer.pl drivers/misc/aspeed-lpc-snoop.c
Joel Stanley  (maintainer:ARM/ASPEED MACHINE SUPPORT)
Arnd Bergmann  (supporter:CHAR and MISC DRIVERS)
Greg Kroah-Hartman  (supporter:CHAR and MISC
DRIVERS)
linux-kernel@vger.kernel.org (open list)

So it's not actually doing anything at all with the SPI subsystem?  I
lacked any context for the discussion having been copied in part way
through.  If it is a SPI controller it ought to have been in
drivers/spi.

Yes, eSPI just uses the SPI pin definition, but it replaces LPC interface.


Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-03 Thread Wang, Haiyue



On 2018-01-03 19:38, Mark Brown wrote:

On Sun, Dec 31, 2017 at 12:10:51AM +0100, Arnd Bergmann wrote:

On Fri, Dec 29, 2017 at 2:53 AM, Haiyue Wang
 wrote:

When PCH works under eSPI mode, the PMC (Power Management Controller) in
PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in
dead loop if no SUS_ACK assert. This is the basic requirement for the BMC
works as eSPI slave.

Also for the host power on / off actions, from BMC side, the following VW
(Virtual Wire) messages are done in firmware:
1. SLAVE_BOOT_LOAD_DONE / SLAVE_BOOT_LOAD_STATUS
2. SUS_ACK
3. OOB_RESET_ACK
4. HOST_RESET_ACK

I have not looked at the driver contents yet, but I'm adding the SPI
maintainer and
mailing list to Cc here for further discussion. Can you clarify how

More generally:

As documented in SubmittingPatches please send patches to the
maintainers for the code you would like to change.  The normal kernel
workflow is that people apply patches from their inboxes, if they aren't
copied they are likely to not see the patch at all and it is much more
difficult to apply patches.

Should send to like this ? Because I add patch for Aspeed chip:

./scripts/get_maintainer.pl drivers/misc/aspeed-lpc-snoop.c
Joel Stanley  (maintainer:ARM/ASPEED MACHINE SUPPORT)
Arnd Bergmann  (supporter:CHAR and MISC DRIVERS)
Greg Kroah-Hartman  (supporter:CHAR and MISC 
DRIVERS)

linux-kernel@vger.kernel.org (open list)



Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-03 Thread Wang, Haiyue



On 2018-01-03 19:38, Mark Brown wrote:

On Sun, Dec 31, 2017 at 12:10:51AM +0100, Arnd Bergmann wrote:

On Fri, Dec 29, 2017 at 2:53 AM, Haiyue Wang
 wrote:

When PCH works under eSPI mode, the PMC (Power Management Controller) in
PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in
dead loop if no SUS_ACK assert. This is the basic requirement for the BMC
works as eSPI slave.

Also for the host power on / off actions, from BMC side, the following VW
(Virtual Wire) messages are done in firmware:
1. SLAVE_BOOT_LOAD_DONE / SLAVE_BOOT_LOAD_STATUS
2. SUS_ACK
3. OOB_RESET_ACK
4. HOST_RESET_ACK

I have not looked at the driver contents yet, but I'm adding the SPI
maintainer and
mailing list to Cc here for further discussion. Can you clarify how

More generally:

As documented in SubmittingPatches please send patches to the
maintainers for the code you would like to change.  The normal kernel
workflow is that people apply patches from their inboxes, if they aren't
copied they are likely to not see the patch at all and it is much more
difficult to apply patches.

Should send to like this ? Because I add patch for Aspeed chip:

./scripts/get_maintainer.pl drivers/misc/aspeed-lpc-snoop.c
Joel Stanley  (maintainer:ARM/ASPEED MACHINE SUPPORT)
Arnd Bergmann  (supporter:CHAR and MISC DRIVERS)
Greg Kroah-Hartman  (supporter:CHAR and MISC 
DRIVERS)

linux-kernel@vger.kernel.org (open list)



Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-02 Thread Wang, Haiyue



On 2018-01-03 00:23, Arnd Bergmann wrote:

On Tue, Jan 2, 2018 at 4:36 PM, Wang, Haiyue
<haiyue.w...@linux.intel.com> wrote:

On 2018-01-02 23:13, Arnd Bergmann wrote:

On 2017-12-31 07:10, Arnd Bergmann wrote:

It also seems rather inflexible to have a single driver that is
responsible both
for the transport (eSPI register level interface for ASPEED) and the
high-level
protocol (talking to an Intel PCH), since either half of the work could
be
done elsewhere, using either a different eSPI slave implementation, or
a different
host architecture)

Yes, eSPI has the architecture such as transaction layer, link Layer;
all of it is about the **silicon**
design. That's why I put the driver under /misc directory, not /spi
directory.

I don't see any requirement in the eSPI spec for the upper layers to
be implemented in hardware. Obviously an x86 host such as Intel's
PCH would implement the host interface using PIO,  and MMIO
accesses that are compatible with ISA and LPC, as this is the motivation
behind the specification, but an ARM server that wants to use eSPI
based peripherals could choose to implement it just as well using
a traditional SPI master hardware, some GPIOs (reset and alert)
and a (driver independent) software implementation of the transaction
and link layers.

On the slave side, it seems that aspeed have implemented the
virtual wires partially in hardware and require a driver like the one
you wrote to reply to some of the wires being accessed by the host,
but again it seems plausible that this could be implemented in another
BMC using a generic SPI slave and a transaction layer written
entirely in software.

Yes, you are right, Aspeed have implemented the virtual wires partially.
Tthat's why I named it
as aspeed-espi-slave driver.

Maybe the name should be more specific and refer to only virtual-wire
rather than espi-slave?
We changed Aspeed's reference code about virtual-wire to production 
code, which meets
the upstream code style. If other people used new features in eSPI 
slave, they can add into
this place one by one, which is proved to work. This is a eSPI slave 
start point for Aspeed,

not just virtual wires.

Your driver does not handle the other channels (smbus, mmio, spinor)
at the moment at all, can you provide some information how they
are implemented in the ast2500? Are those handled completely
in hardware (I assume this is the case for spinor at least), or do they
require help from a driver, either this one or a separate one?

I can't send the AST2500 datasheet to you directly, but you can contact
Aspeed firstly.
https://www.aspeedtech.com/products.php?fPath=20=440

These functions are handled in hardware, the original SDK just provides some
ioctl API for user
application to access them. The mmio function such as KCS / Port 80, these
controllers will get
data from eSPI IP in silicon, but their drivers do not need to be changed,
run the same as LPC
mode.

You can image bellowing work path:

  KCSMailbox  Snoop (Port 80)  UART 
^^ ^  ^
| ||   |
| ||   |
 \|/  /
  { LPC IP }< { eSPI IP to decode
the mmio address }

This is all handled by the drivers/misc/aspeed-lpc-snoop.c driver, right?
This driver just handle port 80. And later may have kcs-bmc.c upstream 
from openbmc

project: https://github.com/openbmc/docs/blob/master/kernel-development.md

And in our first generation eSPI x86 server, we  just use the eSPI new
function to decode the VW to boot the PCH (eSPI master).

Other functions such as GPIO SMBus, we didn't use it. So for making
things clean, we just keep the basic code, which is verified and tested
well.

For the upstream submission, having the code verified and tested
is secondary, it most of all must be maintainable in the future ;-)

Your current driver is very simple, which is good: it shouldn't try to be
overly generic and do things we won't ever need, but I want to be
sure that I understand the bigger picture well enough and ensure
that the code is generic enough to do the things we know we will
need.
Sure, people should easily add new features into this file. They just 
need add other interrupt

handling here. Currently, we handle the basic interrupt bits.

I see that your documentation only refers to the generic principle of
eSPI, while the driver deals mostly with the aspeed specifics. If we
get a generic virtual-wire implementation based on the spi-slave
framework, the documentation would be the same, and part
of the driver would also be the same. OTOH, if one were to use
the SMBUS over eSPI, the high-level interaction with the vw
would have to be different, and at that point, we'd probably want
an abstraction that can deal with both the aspeed hardware and
a simple spi-slave based imple

Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-02 Thread Wang, Haiyue



On 2018-01-03 00:23, Arnd Bergmann wrote:

On Tue, Jan 2, 2018 at 4:36 PM, Wang, Haiyue
 wrote:

On 2018-01-02 23:13, Arnd Bergmann wrote:

On 2017-12-31 07:10, Arnd Bergmann wrote:

It also seems rather inflexible to have a single driver that is
responsible both
for the transport (eSPI register level interface for ASPEED) and the
high-level
protocol (talking to an Intel PCH), since either half of the work could
be
done elsewhere, using either a different eSPI slave implementation, or
a different
host architecture)

Yes, eSPI has the architecture such as transaction layer, link Layer;
all of it is about the **silicon**
design. That's why I put the driver under /misc directory, not /spi
directory.

I don't see any requirement in the eSPI spec for the upper layers to
be implemented in hardware. Obviously an x86 host such as Intel's
PCH would implement the host interface using PIO,  and MMIO
accesses that are compatible with ISA and LPC, as this is the motivation
behind the specification, but an ARM server that wants to use eSPI
based peripherals could choose to implement it just as well using
a traditional SPI master hardware, some GPIOs (reset and alert)
and a (driver independent) software implementation of the transaction
and link layers.

On the slave side, it seems that aspeed have implemented the
virtual wires partially in hardware and require a driver like the one
you wrote to reply to some of the wires being accessed by the host,
but again it seems plausible that this could be implemented in another
BMC using a generic SPI slave and a transaction layer written
entirely in software.

Yes, you are right, Aspeed have implemented the virtual wires partially.
Tthat's why I named it
as aspeed-espi-slave driver.

Maybe the name should be more specific and refer to only virtual-wire
rather than espi-slave?
We changed Aspeed's reference code about virtual-wire to production 
code, which meets
the upstream code style. If other people used new features in eSPI 
slave, they can add into
this place one by one, which is proved to work. This is a eSPI slave 
start point for Aspeed,

not just virtual wires.

Your driver does not handle the other channels (smbus, mmio, spinor)
at the moment at all, can you provide some information how they
are implemented in the ast2500? Are those handled completely
in hardware (I assume this is the case for spinor at least), or do they
require help from a driver, either this one or a separate one?

I can't send the AST2500 datasheet to you directly, but you can contact
Aspeed firstly.
https://www.aspeedtech.com/products.php?fPath=20=440

These functions are handled in hardware, the original SDK just provides some
ioctl API for user
application to access them. The mmio function such as KCS / Port 80, these
controllers will get
data from eSPI IP in silicon, but their drivers do not need to be changed,
run the same as LPC
mode.

You can image bellowing work path:

  KCSMailbox  Snoop (Port 80)  UART 
^^ ^  ^
| ||   |
| ||   |
 \|/  /
  { LPC IP }< { eSPI IP to decode
the mmio address }

This is all handled by the drivers/misc/aspeed-lpc-snoop.c driver, right?
This driver just handle port 80. And later may have kcs-bmc.c upstream 
from openbmc

project: https://github.com/openbmc/docs/blob/master/kernel-development.md

And in our first generation eSPI x86 server, we  just use the eSPI new
function to decode the VW to boot the PCH (eSPI master).

Other functions such as GPIO SMBus, we didn't use it. So for making
things clean, we just keep the basic code, which is verified and tested
well.

For the upstream submission, having the code verified and tested
is secondary, it most of all must be maintainable in the future ;-)

Your current driver is very simple, which is good: it shouldn't try to be
overly generic and do things we won't ever need, but I want to be
sure that I understand the bigger picture well enough and ensure
that the code is generic enough to do the things we know we will
need.
Sure, people should easily add new features into this file. They just 
need add other interrupt

handling here. Currently, we handle the basic interrupt bits.

I see that your documentation only refers to the generic principle of
eSPI, while the driver deals mostly with the aspeed specifics. If we
get a generic virtual-wire implementation based on the spi-slave
framework, the documentation would be the same, and part
of the driver would also be the same. OTOH, if one were to use
the SMBUS over eSPI, the high-level interaction with the vw
would have to be different, and at that point, we'd probably want
an abstraction that can deal with both the aspeed hardware and
a simple spi-slave based implementation.

Superficially, the virtual wi

Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-02 Thread Wang, Haiyue



On 2018-01-02 23:13, Arnd Bergmann wrote:

On 2017-12-31 07:10, Arnd Bergmann wrote:

On Fri, Dec 29, 2017 at 2:53 AM, Haiyue Wang
 wrote:

When PCH works under eSPI mode, the PMC (Power Management Controller) in
PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in
dead loop if no SUS_ACK assert. This is the basic requirement for the BMC
works as eSPI slave.

Also for the host power on / off actions, from BMC side, the following VW
(Virtual Wire) messages are done in firmware:
1. SLAVE_BOOT_LOAD_DONE / SLAVE_BOOT_LOAD_STATUS
2. SUS_ACK
3. OOB_RESET_ACK
4. HOST_RESET_ACK

I have not looked at the driver contents yet, but I'm adding the SPI
maintainer and
mailing list to Cc here for further discussion. Can you clarify how
the eSPI slave
mode relates to SPI slaves that we already support? I was under the impression
that the difference between SPI and eSPI is mainly on the master side, but that
any SPI slave can also act as an eSPI slave. Would this driver fit into the SPI
slave framework, possibly with some extensions to the generic abstraction?

In simple word, the eSPI uses the SPI interface pin definition, but it
will replace Low Pin Count (LPC)
interface. From its name, sure, it will confuse you! ;-)

I know what eSPI is meant for, and understand the basic idea of the
protocol, but I'm not familiar with the Apeed slave hardware
implementation.

I see! ;-)

It also seems rather inflexible to have a single driver that is responsible both
for the transport (eSPI register level interface for ASPEED) and the high-level
protocol (talking to an Intel PCH), since either half of the work could be
done elsewhere, using either a different eSPI slave implementation, or
a different
host architecture)

Yes, eSPI has the architecture such as transaction layer, link Layer;
all of it is about the **silicon**
design. That's why I put the driver under /misc directory, not /spi
directory.

I don't see any requirement in the eSPI spec for the upper layers to
be implemented in hardware. Obviously an x86 host such as Intel's
PCH would implement the host interface using PIO,  and MMIO
accesses that are compatible with ISA and LPC, as this is the motivation
behind the specification, but an ARM server that wants to use eSPI
based peripherals could choose to implement it just as well using
a traditional SPI master hardware, some GPIOs (reset and alert)
and a (driver independent) software implementation of the transaction
and link layers.

On the slave side, it seems that aspeed have implemented the
virtual wires partially in hardware and require a driver like the one
you wrote to reply to some of the wires being accessed by the host,
but again it seems plausible that this could be implemented in another
BMC using a generic SPI slave and a transaction layer written
entirely in software.
Yes, you are right, Aspeed have implemented the virtual wires partially. 
Tthat's why I named it

as aspeed-espi-slave driver.

Your driver does not handle the other channels (smbus, mmio, spinor)
at the moment at all, can you provide some information how they
are implemented in the ast2500? Are those handled completely
in hardware (I assume this is the case for spinor at least), or do they
require help from a driver, either this one or a separate one?
I can't send the AST2500 datasheet to you directly, but you can contact 
Aspeed firstly.

https://www.aspeedtech.com/products.php?fPath=20=440

These functions are handled in hardware, the original SDK just provides 
some ioctl API for user
application to access them. The mmio function such as KCS / Port 80, 
these controllers will get
data from eSPI IP in silicon, but their drivers do not need to be 
changed, run the same as LPC

mode.

You can image bellowing work path:

 KCS    Mailbox  Snoop (Port 80)  UART 
   ^    ^ ^  ^
   | |    |   |
   | |    |   |
    \    |    /  /
 { LPC IP }    < { eSPI IP to 
decode the mmio address }


And in our first generation eSPI x86 server, we  just use the eSPI new 
function to decode the VW to
boot the PCH (eSPI master). Other functions such as GPIO SMBus, we 
didn't use it. So for making
things clean, we just keep the basic code, which is verified and tested 
well.

Arnd

---
BR,
Haiyue


Re: [PATCH v1] eSPI: add Aspeed AST2500 eSPI driver to boot a host with PCH runs on eSPI

2018-01-02 Thread Wang, Haiyue



On 2018-01-02 23:13, Arnd Bergmann wrote:

On 2017-12-31 07:10, Arnd Bergmann wrote:

On Fri, Dec 29, 2017 at 2:53 AM, Haiyue Wang
 wrote:

When PCH works under eSPI mode, the PMC (Power Management Controller) in
PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in
dead loop if no SUS_ACK assert. This is the basic requirement for the BMC
works as eSPI slave.

Also for the host power on / off actions, from BMC side, the following VW
(Virtual Wire) messages are done in firmware:
1. SLAVE_BOOT_LOAD_DONE / SLAVE_BOOT_LOAD_STATUS
2. SUS_ACK
3. OOB_RESET_ACK
4. HOST_RESET_ACK

I have not looked at the driver contents yet, but I'm adding the SPI
maintainer and
mailing list to Cc here for further discussion. Can you clarify how
the eSPI slave
mode relates to SPI slaves that we already support? I was under the impression
that the difference between SPI and eSPI is mainly on the master side, but that
any SPI slave can also act as an eSPI slave. Would this driver fit into the SPI
slave framework, possibly with some extensions to the generic abstraction?

In simple word, the eSPI uses the SPI interface pin definition, but it
will replace Low Pin Count (LPC)
interface. From its name, sure, it will confuse you! ;-)

I know what eSPI is meant for, and understand the basic idea of the
protocol, but I'm not familiar with the Apeed slave hardware
implementation.

I see! ;-)

It also seems rather inflexible to have a single driver that is responsible both
for the transport (eSPI register level interface for ASPEED) and the high-level
protocol (talking to an Intel PCH), since either half of the work could be
done elsewhere, using either a different eSPI slave implementation, or
a different
host architecture)

Yes, eSPI has the architecture such as transaction layer, link Layer;
all of it is about the **silicon**
design. That's why I put the driver under /misc directory, not /spi
directory.

I don't see any requirement in the eSPI spec for the upper layers to
be implemented in hardware. Obviously an x86 host such as Intel's
PCH would implement the host interface using PIO,  and MMIO
accesses that are compatible with ISA and LPC, as this is the motivation
behind the specification, but an ARM server that wants to use eSPI
based peripherals could choose to implement it just as well using
a traditional SPI master hardware, some GPIOs (reset and alert)
and a (driver independent) software implementation of the transaction
and link layers.

On the slave side, it seems that aspeed have implemented the
virtual wires partially in hardware and require a driver like the one
you wrote to reply to some of the wires being accessed by the host,
but again it seems plausible that this could be implemented in another
BMC using a generic SPI slave and a transaction layer written
entirely in software.
Yes, you are right, Aspeed have implemented the virtual wires partially. 
Tthat's why I named it

as aspeed-espi-slave driver.

Your driver does not handle the other channels (smbus, mmio, spinor)
at the moment at all, can you provide some information how they
are implemented in the ast2500? Are those handled completely
in hardware (I assume this is the case for spinor at least), or do they
require help from a driver, either this one or a separate one?
I can't send the AST2500 datasheet to you directly, but you can contact 
Aspeed firstly.

https://www.aspeedtech.com/products.php?fPath=20=440

These functions are handled in hardware, the original SDK just provides 
some ioctl API for user
application to access them. The mmio function such as KCS / Port 80, 
these controllers will get
data from eSPI IP in silicon, but their drivers do not need to be 
changed, run the same as LPC

mode.

You can image bellowing work path:

 KCS    Mailbox  Snoop (Port 80)  UART 
   ^    ^ ^  ^
   | |    |   |
   | |    |   |
    \    |    /  /
 { LPC IP }    < { eSPI IP to 
decode the mmio address }


And in our first generation eSPI x86 server, we  just use the eSPI new 
function to decode the VW to
boot the PCH (eSPI master). Other functions such as GPIO SMBus, we 
didn't use it. So for making
things clean, we just keep the basic code, which is verified and tested 
well.

Arnd

---
BR,
Haiyue


Re: [PATCH linux ipmi for BMC v2] ipmi: add an Aspeed KCS IPMI BMC driver

2017-12-20 Thread Wang, Haiyue



On 2017-12-21 09:07, Joel Stanley wrote:

On Thu, Dec 21, 2017 at 6:41 AM, Corey Minyard  wrote:

On 12/14/2017 10:34 PM, Haiyue Wang wrote:

This patch adds a simple device driver to expose the KCS interface on
Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are
commonly used as BMCs (BaseBoard Management Controllers) and this driver
implements the BMC side of the KCS interface.

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a host and its BMC.

The device name defaults to '/dev/ipmi-kcsX', X=1,2,3,4.


Looking through this, I have no objections.  I didn't do an analysis of the
state machine.  Have you tested it through the various error states?  You'd
have to hack the IPMI driver on the host side to be able to do that, but
it's not too hard.

My only comment is that it might be nice to have consistent ioctl numbers
for the operations on a BMC (at least ATN would be common between KCS and
BT).  But that's not a big deal.

Anyone from the openbmc group want to comment on this?

I'd like to get Andrews thoughts on the change to the bindings.

I asked Haiyue in a different thread why the syscon node needed to be
added in that way, but I didn't think we had a good reason for that.

If we decide that is the way to go I will take a close look at the
driver. I had a quick check over it when Haiyue submitted an earlier
version to the openbmc list.

Waiting for your good ideas all the time. :-)

For there is no sample driver to use "aspeed,ast2500-lpc-bmc" node, by 
referring to "aspeed,ast2500-lpc-host",
I changed it to make different 3 KCS devices to work. This is the 
development story.


    arch/arm/boot/dts/aspeed-g5.dtsi
    lpc: lpc@1e789000 {
    compatible = "aspeed,ast2500-lpc", "simple-mfd";
    reg = <0x1e789000 0x1000>;

    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0x0 0x1e789000 0x1000>;

    lpc_bmc: lpc-bmc@0 {
    compatible = "aspeed,ast2500-lpc-bmc";
    reg = <0x0 0x80>;
    };

    lpc_host: lpc-host@80 {
    compatible = "aspeed,ast2500-lpc-host", 
"simple-mfd", "syscon";

    reg = <0x80 0x1e0>;
    reg-io-width = <4>;

    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0x0 0x80 0x1e0>;

    lpc_ctrl: lpc-ctrl@0 {
    compatible = 
"aspeed,ast2500-lpc-ctrl";

    reg = <0x0 0x80>;
    status = "disabled";
    };

    lpc_snoop: lpc-snoop@0 {
    compatible = 
"aspeed,ast2500-lpc-snoop";

    reg = <0x0 0x80>;
    interrupts = <8>;
    status = "disabled";


You raise a good point about unifying the ioctl. I'd like to see what
could be done there.

Cheers,

Joel


-corey



Signed-off-by: Haiyue Wang 
---
   .../devicetree/bindings/mfd/aspeed-lpc.txt |  31 +-
   drivers/char/ipmi/Kconfig  |   9 +
   drivers/char/ipmi/Makefile |   1 +
   drivers/char/ipmi/kcs-bmc.c| 759
+
   include/uapi/linux/kcs-bmc.h   |  13 +
   5 files changed, 810 insertions(+), 3 deletions(-)
   create mode 100644 drivers/char/ipmi/kcs-bmc.c
   create mode 100644 include/uapi/linux/kcs-bmc.h

diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
index 514d82c..e682000 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
+++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
@@ -62,12 +62,24 @@ BMC Node
   
 - compatible:   One of:
-   "aspeed,ast2400-lpc-bmc"
-   "aspeed,ast2500-lpc-bmc"
+   "aspeed,ast2400-lpc-bmc", "simple-mfd", "syscon"
+   "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon"
 - reg:  contains the physical address and length values of
the
   H8S/2168-compatible LPC controller memory region
   +BMC KCS Node
+
+
+- compatible:  One of:
+   "aspeed,ast2400-kcs-bmc"
+   "aspeed,ast2500-kcs-bmc"
+
+- kcs_chan: The LPC channel number
+
+- kcs_addr: The host CPU IO map address
+
+
   Host Node
   -
   @@ -94,8 +106,21 @@ lpc: lpc@1e789000 {
 ranges = <0x0 0x1e789000 0x1000>;
   

Re: [PATCH linux ipmi for BMC v2] ipmi: add an Aspeed KCS IPMI BMC driver

2017-12-20 Thread Wang, Haiyue



On 2017-12-21 09:07, Joel Stanley wrote:

On Thu, Dec 21, 2017 at 6:41 AM, Corey Minyard  wrote:

On 12/14/2017 10:34 PM, Haiyue Wang wrote:

This patch adds a simple device driver to expose the KCS interface on
Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are
commonly used as BMCs (BaseBoard Management Controllers) and this driver
implements the BMC side of the KCS interface.

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a host and its BMC.

The device name defaults to '/dev/ipmi-kcsX', X=1,2,3,4.


Looking through this, I have no objections.  I didn't do an analysis of the
state machine.  Have you tested it through the various error states?  You'd
have to hack the IPMI driver on the host side to be able to do that, but
it's not too hard.

My only comment is that it might be nice to have consistent ioctl numbers
for the operations on a BMC (at least ATN would be common between KCS and
BT).  But that's not a big deal.

Anyone from the openbmc group want to comment on this?

I'd like to get Andrews thoughts on the change to the bindings.

I asked Haiyue in a different thread why the syscon node needed to be
added in that way, but I didn't think we had a good reason for that.

If we decide that is the way to go I will take a close look at the
driver. I had a quick check over it when Haiyue submitted an earlier
version to the openbmc list.

Waiting for your good ideas all the time. :-)

For there is no sample driver to use "aspeed,ast2500-lpc-bmc" node, by 
referring to "aspeed,ast2500-lpc-host",
I changed it to make different 3 KCS devices to work. This is the 
development story.


    arch/arm/boot/dts/aspeed-g5.dtsi
    lpc: lpc@1e789000 {
    compatible = "aspeed,ast2500-lpc", "simple-mfd";
    reg = <0x1e789000 0x1000>;

    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0x0 0x1e789000 0x1000>;

    lpc_bmc: lpc-bmc@0 {
    compatible = "aspeed,ast2500-lpc-bmc";
    reg = <0x0 0x80>;
    };

    lpc_host: lpc-host@80 {
    compatible = "aspeed,ast2500-lpc-host", 
"simple-mfd", "syscon";

    reg = <0x80 0x1e0>;
    reg-io-width = <4>;

    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0x0 0x80 0x1e0>;

    lpc_ctrl: lpc-ctrl@0 {
    compatible = 
"aspeed,ast2500-lpc-ctrl";

    reg = <0x0 0x80>;
    status = "disabled";
    };

    lpc_snoop: lpc-snoop@0 {
    compatible = 
"aspeed,ast2500-lpc-snoop";

    reg = <0x0 0x80>;
    interrupts = <8>;
    status = "disabled";


You raise a good point about unifying the ioctl. I'd like to see what
could be done there.

Cheers,

Joel


-corey



Signed-off-by: Haiyue Wang 
---
   .../devicetree/bindings/mfd/aspeed-lpc.txt |  31 +-
   drivers/char/ipmi/Kconfig  |   9 +
   drivers/char/ipmi/Makefile |   1 +
   drivers/char/ipmi/kcs-bmc.c| 759
+
   include/uapi/linux/kcs-bmc.h   |  13 +
   5 files changed, 810 insertions(+), 3 deletions(-)
   create mode 100644 drivers/char/ipmi/kcs-bmc.c
   create mode 100644 include/uapi/linux/kcs-bmc.h

diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
index 514d82c..e682000 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
+++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
@@ -62,12 +62,24 @@ BMC Node
   
 - compatible:   One of:
-   "aspeed,ast2400-lpc-bmc"
-   "aspeed,ast2500-lpc-bmc"
+   "aspeed,ast2400-lpc-bmc", "simple-mfd", "syscon"
+   "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon"
 - reg:  contains the physical address and length values of
the
   H8S/2168-compatible LPC controller memory region
   +BMC KCS Node
+
+
+- compatible:  One of:
+   "aspeed,ast2400-kcs-bmc"
+   "aspeed,ast2500-kcs-bmc"
+
+- kcs_chan: The LPC channel number
+
+- kcs_addr: The host CPU IO map address
+
+
   Host Node
   -
   @@ -94,8 +106,21 @@ lpc: lpc@1e789000 {
 ranges = <0x0 0x1e789000 0x1000>;
 lpc_bmc: lpc-bmc@0 {
-   compatible 

Re: [PATCH linux ipmi for BMC v2] ipmi: add an Aspeed KCS IPMI BMC driver

2017-12-20 Thread Wang, Haiyue



On 2017-12-21 09:12, Corey Minyard wrote:

On 12/20/2017 06:59 PM, Wang, Haiyue wrote:



On 2017-12-21 04:11, Corey Minyard wrote:

On 12/14/2017 10:34 PM, Haiyue Wang wrote:

This patch adds a simple device driver to expose the KCS interface on
Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are
commonly used as BMCs (BaseBoard Management Controllers) and this 
driver

implements the BMC side of the KCS interface.

The KCS (Keyboard Controller Style) interface is used to perform 
in-band

IPMI communication between a host and its BMC.

The device name defaults to '/dev/ipmi-kcsX', X=1,2,3,4.


Looking through this, I have no objections.  I didn't do an analysis 
of the state machine.  Have you tested it through the various error 
states?  You'd have to hack the IPMI driver on the host side to be 
able to do that, but it's not too hard.


Not hack the IPMI driver, but work well with it in so many stress 
cycle test and long time running well.


That is probably not enough.  Under normal conditions you will never 
see an abort, you generally have to force it.  That's a lot of code 
that is essentially untested.


Got it. The BMC's KCS state machine is controlled by host IPMI driver. 
The code should comply to the IPMI spec for BMC KCS side,

but of course, untested actively by white box test method. :-(


My only comment is that it might be nice to have consistent ioctl 
numbers for the operations on a BMC (at least ATN would be common 
between KCS and BT).  But that's not a big deal.


In KCS, the ATN has the set/clear requirement, BT only has set 
requirement. Or you mean change '1' to ' _IOW(__KCS_BMC_IOCTL_MAGIC, 
0, unsigned long)' as BT ?




I mean "discuss with the BT driver maintainers so that the BT and KCS 
interfaces work essentially the same."  From a user point of view, it 
would be nice to not have to know if it's KCS or BT for the most part.



Understood now, it is cool, user easily using is first choice.

-corey


#define __BT_BMC_IOCTL_MAGIC    0xb1
#define BT_BMC_IOCTL_SMS_ATN    _IO(__BT_BMC_IOCTL_MAGIC, 0x00)

#define __KCS_BMC_IOCTL_MAGIC  'K'
#define KCS_BMC_IOCTL_SMS_ATN  _IOW(__KCS_BMC_IOCTL_MAGIC, 1, 
unsigned long)

#define KCS_BMC_IOCTL_FORCE_ABORT  _IO(__KCS_BMC_IOCTL_MAGIC, 2)

Anyone from the openbmc group want to comment on this?

-corey


Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com>
---
  .../devicetree/bindings/mfd/aspeed-lpc.txt |  31 +-
  drivers/char/ipmi/Kconfig  |   9 +
  drivers/char/ipmi/Makefile |   1 +
  drivers/char/ipmi/kcs-bmc.c    | 759 
+

  include/uapi/linux/kcs-bmc.h   |  13 +
  5 files changed, 810 insertions(+), 3 deletions(-)
  create mode 100644 drivers/char/ipmi/kcs-bmc.c
  create mode 100644 include/uapi/linux/kcs-bmc.h

diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt 
b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt

index 514d82c..e682000 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
+++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
@@ -62,12 +62,24 @@ BMC Node
  
    - compatible:    One of:
-    "aspeed,ast2400-lpc-bmc"
-    "aspeed,ast2500-lpc-bmc"
+    "aspeed,ast2400-lpc-bmc", "simple-mfd", "syscon"
+    "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon"
    - reg:    contains the physical address and length values 
of the

  H8S/2168-compatible LPC controller memory region
  +BMC KCS Node
+
+
+- compatible:    One of:
+    "aspeed,ast2400-kcs-bmc"
+    "aspeed,ast2500-kcs-bmc"
+
+- kcs_chan: The LPC channel number
+
+- kcs_addr: The host CPU IO map address
+
+
  Host Node
  -
  @@ -94,8 +106,21 @@ lpc: lpc@1e789000 {
  ranges = <0x0 0x1e789000 0x1000>;
    lpc_bmc: lpc-bmc@0 {
-    compatible = "aspeed,ast2500-lpc-bmc";
+    compatible = "aspeed,ast2500-lpc-bmc", "simple-mfd", 
"syscon";

  reg = <0x0 0x80>;
+    reg-io-width = <4>;
+
+    #address-cells = <1>;
+    #size-cells = <1>;
+    ranges = <0x0 0x0 0x80>;
+
+    kcs3: kcs3@0 {
+    compatible = "aspeed,ast2500-kcs-bmc";
+    interrupts = <8>;
+    kcs_chan = <3>;
+    kcs_addr = <0xCA2>;
+    status = "okay";
+    };
  };
    lpc_host: lpc-host@80 {
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 3544abc..3a9d29b 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -104,3 +104,12 @@ config ASPEED_BT_IPMI_BMC
    Provides a driver for the BT (Block Transfer) IPMI interface
    found on Aspeed SOCs (AST2400 and AST2500). The drive

Re: [PATCH linux ipmi for BMC v2] ipmi: add an Aspeed KCS IPMI BMC driver

2017-12-20 Thread Wang, Haiyue



On 2017-12-21 09:12, Corey Minyard wrote:

On 12/20/2017 06:59 PM, Wang, Haiyue wrote:



On 2017-12-21 04:11, Corey Minyard wrote:

On 12/14/2017 10:34 PM, Haiyue Wang wrote:

This patch adds a simple device driver to expose the KCS interface on
Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are
commonly used as BMCs (BaseBoard Management Controllers) and this 
driver

implements the BMC side of the KCS interface.

The KCS (Keyboard Controller Style) interface is used to perform 
in-band

IPMI communication between a host and its BMC.

The device name defaults to '/dev/ipmi-kcsX', X=1,2,3,4.


Looking through this, I have no objections.  I didn't do an analysis 
of the state machine.  Have you tested it through the various error 
states?  You'd have to hack the IPMI driver on the host side to be 
able to do that, but it's not too hard.


Not hack the IPMI driver, but work well with it in so many stress 
cycle test and long time running well.


That is probably not enough.  Under normal conditions you will never 
see an abort, you generally have to force it.  That's a lot of code 
that is essentially untested.


Got it. The BMC's KCS state machine is controlled by host IPMI driver. 
The code should comply to the IPMI spec for BMC KCS side,

but of course, untested actively by white box test method. :-(


My only comment is that it might be nice to have consistent ioctl 
numbers for the operations on a BMC (at least ATN would be common 
between KCS and BT).  But that's not a big deal.


In KCS, the ATN has the set/clear requirement, BT only has set 
requirement. Or you mean change '1' to ' _IOW(__KCS_BMC_IOCTL_MAGIC, 
0, unsigned long)' as BT ?




I mean "discuss with the BT driver maintainers so that the BT and KCS 
interfaces work essentially the same."  From a user point of view, it 
would be nice to not have to know if it's KCS or BT for the most part.



Understood now, it is cool, user easily using is first choice.

-corey


#define __BT_BMC_IOCTL_MAGIC    0xb1
#define BT_BMC_IOCTL_SMS_ATN    _IO(__BT_BMC_IOCTL_MAGIC, 0x00)

#define __KCS_BMC_IOCTL_MAGIC  'K'
#define KCS_BMC_IOCTL_SMS_ATN  _IOW(__KCS_BMC_IOCTL_MAGIC, 1, 
unsigned long)

#define KCS_BMC_IOCTL_FORCE_ABORT  _IO(__KCS_BMC_IOCTL_MAGIC, 2)

Anyone from the openbmc group want to comment on this?

-corey


Signed-off-by: Haiyue Wang 
---
  .../devicetree/bindings/mfd/aspeed-lpc.txt |  31 +-
  drivers/char/ipmi/Kconfig  |   9 +
  drivers/char/ipmi/Makefile |   1 +
  drivers/char/ipmi/kcs-bmc.c    | 759 
+

  include/uapi/linux/kcs-bmc.h   |  13 +
  5 files changed, 810 insertions(+), 3 deletions(-)
  create mode 100644 drivers/char/ipmi/kcs-bmc.c
  create mode 100644 include/uapi/linux/kcs-bmc.h

diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt 
b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt

index 514d82c..e682000 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
+++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
@@ -62,12 +62,24 @@ BMC Node
  
    - compatible:    One of:
-    "aspeed,ast2400-lpc-bmc"
-    "aspeed,ast2500-lpc-bmc"
+    "aspeed,ast2400-lpc-bmc", "simple-mfd", "syscon"
+    "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon"
    - reg:    contains the physical address and length values 
of the

  H8S/2168-compatible LPC controller memory region
  +BMC KCS Node
+
+
+- compatible:    One of:
+    "aspeed,ast2400-kcs-bmc"
+    "aspeed,ast2500-kcs-bmc"
+
+- kcs_chan: The LPC channel number
+
+- kcs_addr: The host CPU IO map address
+
+
  Host Node
  -
  @@ -94,8 +106,21 @@ lpc: lpc@1e789000 {
  ranges = <0x0 0x1e789000 0x1000>;
    lpc_bmc: lpc-bmc@0 {
-    compatible = "aspeed,ast2500-lpc-bmc";
+    compatible = "aspeed,ast2500-lpc-bmc", "simple-mfd", 
"syscon";

  reg = <0x0 0x80>;
+    reg-io-width = <4>;
+
+    #address-cells = <1>;
+    #size-cells = <1>;
+    ranges = <0x0 0x0 0x80>;
+
+    kcs3: kcs3@0 {
+    compatible = "aspeed,ast2500-kcs-bmc";
+    interrupts = <8>;
+    kcs_chan = <3>;
+    kcs_addr = <0xCA2>;
+    status = "okay";
+    };
  };
    lpc_host: lpc-host@80 {
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 3544abc..3a9d29b 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -104,3 +104,12 @@ config ASPEED_BT_IPMI_BMC
    Provides a driver for the BT (Block Transfer) IPMI interface
    found on Aspeed SOCs (AST2400 and AST2500). The driver
    implements the BMC si

Re: [PATCH linux ipmi for BMC v2] ipmi: add an Aspeed KCS IPMI BMC driver

2017-12-20 Thread Wang, Haiyue



On 2017-12-21 04:11, Corey Minyard wrote:

On 12/14/2017 10:34 PM, Haiyue Wang wrote:

This patch adds a simple device driver to expose the KCS interface on
Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are
commonly used as BMCs (BaseBoard Management Controllers) and this driver
implements the BMC side of the KCS interface.

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a host and its BMC.

The device name defaults to '/dev/ipmi-kcsX', X=1,2,3,4.


Looking through this, I have no objections.  I didn't do an analysis 
of the state machine.  Have you tested it through the various error 
states?  You'd have to hack the IPMI driver on the host side to be 
able to do that, but it's not too hard.


Not hack the IPMI driver, but work well with it in so many stress cycle 
test and long time running well.


My only comment is that it might be nice to have consistent ioctl 
numbers for the operations on a BMC (at least ATN would be common 
between KCS and BT).  But that's not a big deal.


In KCS, the ATN has the set/clear requirement, BT only has set 
requirement. Or you mean change '1' to ' _IOW(__KCS_BMC_IOCTL_MAGIC, 0, 
unsigned long)' as BT ?


#define __BT_BMC_IOCTL_MAGIC    0xb1
#define BT_BMC_IOCTL_SMS_ATN    _IO(__BT_BMC_IOCTL_MAGIC, 0x00)

#define __KCS_BMC_IOCTL_MAGIC  'K'
#define KCS_BMC_IOCTL_SMS_ATN  _IOW(__KCS_BMC_IOCTL_MAGIC, 1, 
unsigned long)

#define KCS_BMC_IOCTL_FORCE_ABORT  _IO(__KCS_BMC_IOCTL_MAGIC, 2)

Anyone from the openbmc group want to comment on this?

-corey


Signed-off-by: Haiyue Wang 
---
  .../devicetree/bindings/mfd/aspeed-lpc.txt |  31 +-
  drivers/char/ipmi/Kconfig  |   9 +
  drivers/char/ipmi/Makefile |   1 +
  drivers/char/ipmi/kcs-bmc.c    | 759 
+

  include/uapi/linux/kcs-bmc.h   |  13 +
  5 files changed, 810 insertions(+), 3 deletions(-)
  create mode 100644 drivers/char/ipmi/kcs-bmc.c
  create mode 100644 include/uapi/linux/kcs-bmc.h

diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt 
b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt

index 514d82c..e682000 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
+++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
@@ -62,12 +62,24 @@ BMC Node
  
    - compatible:    One of:
-    "aspeed,ast2400-lpc-bmc"
-    "aspeed,ast2500-lpc-bmc"
+    "aspeed,ast2400-lpc-bmc", "simple-mfd", "syscon"
+    "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon"
    - reg:    contains the physical address and length values of the
  H8S/2168-compatible LPC controller memory region
  +BMC KCS Node
+
+
+- compatible:    One of:
+    "aspeed,ast2400-kcs-bmc"
+    "aspeed,ast2500-kcs-bmc"
+
+- kcs_chan: The LPC channel number
+
+- kcs_addr: The host CPU IO map address
+
+
  Host Node
  -
  @@ -94,8 +106,21 @@ lpc: lpc@1e789000 {
  ranges = <0x0 0x1e789000 0x1000>;
    lpc_bmc: lpc-bmc@0 {
-    compatible = "aspeed,ast2500-lpc-bmc";
+    compatible = "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon";
  reg = <0x0 0x80>;
+    reg-io-width = <4>;
+
+    #address-cells = <1>;
+    #size-cells = <1>;
+    ranges = <0x0 0x0 0x80>;
+
+    kcs3: kcs3@0 {
+    compatible = "aspeed,ast2500-kcs-bmc";
+    interrupts = <8>;
+    kcs_chan = <3>;
+    kcs_addr = <0xCA2>;
+    status = "okay";
+    };
  };
    lpc_host: lpc-host@80 {
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 3544abc..3a9d29b 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -104,3 +104,12 @@ config ASPEED_BT_IPMI_BMC
    Provides a driver for the BT (Block Transfer) IPMI interface
    found on Aspeed SOCs (AST2400 and AST2500). The driver
    implements the BMC side of the BT interface.
+
+config ASPEED_KCS_IPMI_BMC
+    depends on ARCH_ASPEED || COMPILE_TEST
+    depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
+    tristate "KCS IPMI bmc driver"
+    help
+  Provides a driver for the KCS (Keyboard Controller Style) IPMI
+  interface found on Aspeed SOCs (AST2400 and AST2500). The driver
+  implements the BMC side of the KCS interface.
\ No newline at end of file
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
index 33b899f..f217bae 100644
--- a/drivers/char/ipmi/Makefile
+++ b/drivers/char/ipmi/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
  obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
  obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
  obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o
+obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs-bmc.o
\ No newline at end of file
diff --git a/drivers/char/ipmi/kcs-bmc.c b/drivers/char/ipmi/kcs-bmc.c
new file mode 

Re: [PATCH linux ipmi for BMC v2] ipmi: add an Aspeed KCS IPMI BMC driver

2017-12-20 Thread Wang, Haiyue



On 2017-12-21 04:11, Corey Minyard wrote:

On 12/14/2017 10:34 PM, Haiyue Wang wrote:

This patch adds a simple device driver to expose the KCS interface on
Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are
commonly used as BMCs (BaseBoard Management Controllers) and this driver
implements the BMC side of the KCS interface.

The KCS (Keyboard Controller Style) interface is used to perform in-band
IPMI communication between a host and its BMC.

The device name defaults to '/dev/ipmi-kcsX', X=1,2,3,4.


Looking through this, I have no objections.  I didn't do an analysis 
of the state machine.  Have you tested it through the various error 
states?  You'd have to hack the IPMI driver on the host side to be 
able to do that, but it's not too hard.


Not hack the IPMI driver, but work well with it in so many stress cycle 
test and long time running well.


My only comment is that it might be nice to have consistent ioctl 
numbers for the operations on a BMC (at least ATN would be common 
between KCS and BT).  But that's not a big deal.


In KCS, the ATN has the set/clear requirement, BT only has set 
requirement. Or you mean change '1' to ' _IOW(__KCS_BMC_IOCTL_MAGIC, 0, 
unsigned long)' as BT ?


#define __BT_BMC_IOCTL_MAGIC    0xb1
#define BT_BMC_IOCTL_SMS_ATN    _IO(__BT_BMC_IOCTL_MAGIC, 0x00)

#define __KCS_BMC_IOCTL_MAGIC  'K'
#define KCS_BMC_IOCTL_SMS_ATN  _IOW(__KCS_BMC_IOCTL_MAGIC, 1, 
unsigned long)

#define KCS_BMC_IOCTL_FORCE_ABORT  _IO(__KCS_BMC_IOCTL_MAGIC, 2)

Anyone from the openbmc group want to comment on this?

-corey


Signed-off-by: Haiyue Wang 
---
  .../devicetree/bindings/mfd/aspeed-lpc.txt |  31 +-
  drivers/char/ipmi/Kconfig  |   9 +
  drivers/char/ipmi/Makefile |   1 +
  drivers/char/ipmi/kcs-bmc.c    | 759 
+

  include/uapi/linux/kcs-bmc.h   |  13 +
  5 files changed, 810 insertions(+), 3 deletions(-)
  create mode 100644 drivers/char/ipmi/kcs-bmc.c
  create mode 100644 include/uapi/linux/kcs-bmc.h

diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt 
b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt

index 514d82c..e682000 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
+++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
@@ -62,12 +62,24 @@ BMC Node
  
    - compatible:    One of:
-    "aspeed,ast2400-lpc-bmc"
-    "aspeed,ast2500-lpc-bmc"
+    "aspeed,ast2400-lpc-bmc", "simple-mfd", "syscon"
+    "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon"
    - reg:    contains the physical address and length values of the
  H8S/2168-compatible LPC controller memory region
  +BMC KCS Node
+
+
+- compatible:    One of:
+    "aspeed,ast2400-kcs-bmc"
+    "aspeed,ast2500-kcs-bmc"
+
+- kcs_chan: The LPC channel number
+
+- kcs_addr: The host CPU IO map address
+
+
  Host Node
  -
  @@ -94,8 +106,21 @@ lpc: lpc@1e789000 {
  ranges = <0x0 0x1e789000 0x1000>;
    lpc_bmc: lpc-bmc@0 {
-    compatible = "aspeed,ast2500-lpc-bmc";
+    compatible = "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon";
  reg = <0x0 0x80>;
+    reg-io-width = <4>;
+
+    #address-cells = <1>;
+    #size-cells = <1>;
+    ranges = <0x0 0x0 0x80>;
+
+    kcs3: kcs3@0 {
+    compatible = "aspeed,ast2500-kcs-bmc";
+    interrupts = <8>;
+    kcs_chan = <3>;
+    kcs_addr = <0xCA2>;
+    status = "okay";
+    };
  };
    lpc_host: lpc-host@80 {
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 3544abc..3a9d29b 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -104,3 +104,12 @@ config ASPEED_BT_IPMI_BMC
    Provides a driver for the BT (Block Transfer) IPMI interface
    found on Aspeed SOCs (AST2400 and AST2500). The driver
    implements the BMC side of the BT interface.
+
+config ASPEED_KCS_IPMI_BMC
+    depends on ARCH_ASPEED || COMPILE_TEST
+    depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
+    tristate "KCS IPMI bmc driver"
+    help
+  Provides a driver for the KCS (Keyboard Controller Style) IPMI
+  interface found on Aspeed SOCs (AST2400 and AST2500). The driver
+  implements the BMC side of the KCS interface.
\ No newline at end of file
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
index 33b899f..f217bae 100644
--- a/drivers/char/ipmi/Makefile
+++ b/drivers/char/ipmi/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
  obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
  obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
  obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o
+obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs-bmc.o
\ No newline at end of file
diff --git a/drivers/char/ipmi/kcs-bmc.c b/drivers/char/ipmi/kcs-bmc.c
new file mode 100644
index 000..256fb00