"openbmc" wrote on
08/07/2017 10:53:01 PM:
> From: Brendan Higgins
> To: miny...@acm.org, benjaminf...@google.com, c...@kaod.org,
> j...@jms.id.au, and...@aj.id.au
> Cc: openipmi-developer@lists.sourceforge.net, Brendan Higgins
> , open...@lists.ozlabs.org, linux-
> ker...@vger.kernel.org
> Date: 08/07/2017 10:55 PM
> Subject: [RFC v1 4/4] ipmi_bmc: bt-aspeed: port driver to IPMI BMC
framework
> Sent by: "openbmc"
>
> From: Benjamin Fair
>
> The driver was handling interaction with userspace on its own. This
> patch changes it to use the functionality of the ipmi_bmc framework
> instead.
>
> Note that this removes the ability for the BMC to set SMS_ATN by making
> an ioctl. If this functionality is required, it can be added back in
> with a later patch.
Isn't SMS_ATN the way a BMC initiates an IPMI message to the OS? Say for
instance a request to shutdown?
>
> Signed-off-by: Benjamin Fair
> Signed-off-by: Brendan Higgins
> ---
> drivers/char/ipmi_bmc/ipmi_bmc_bt_aspeed.c | 258
> +
> include/uapi/linux/bt-bmc.h| 18 --
> 2 files changed, 74 insertions(+), 202 deletions(-)
> delete mode 100644 include/uapi/linux/bt-bmc.h
>
> diff --git a/drivers/char/ipmi_bmc/ipmi_bmc_bt_aspeed.c b/drivers/
> char/ipmi_bmc/ipmi_bmc_bt_aspeed.c
> index 70d434bc1cbf..7c8082c511ee 100644
> --- a/drivers/char/ipmi_bmc/ipmi_bmc_bt_aspeed.c
> +++ b/drivers/char/ipmi_bmc/ipmi_bmc_bt_aspeed.c
> @@ -7,25 +7,19 @@
> * 2 of the License, or (at your option) any later version.
> */
>
> -#include
> -#include
> #include
> #include
> #include
> +#include
> #include
> -#include
> #include
> #include
> #include
> -#include
> #include
> #include
> #include
>
> -/*
> - * This is a BMC device used to communicate to the host
> - */
> -#define DEVICE_NAME "ipmi-bt-host"
> +#define DEVICE_NAME "ipmi-bmc-bt-aspeed"
>
> #define BT_IO_BASE 0xe4
> #define BT_IRQ 10
> @@ -61,18 +55,17 @@
> #define BT_BMC_BUFFER_SIZE 256
>
> struct bt_bmc {
> + struct ipmi_bmc_bus bus;
> struct device dev;
> - struct miscdevice miscdev;
> + struct ipmi_bmc_ctx *bmc_ctx;
> + struct bt_msg request;
> struct regmap *map;
> int offset;
> int irq;
> - wait_queue_head_t queue;
> struct timer_list poll_timer;
> - struct mutex mutex;
> + spinlock_t lock;
> };
>
> -static atomic_t open_count = ATOMIC_INIT(0);
> -
> static const struct regmap_config bt_regmap_cfg = {
> .reg_bits = 32,
> .val_bits = 32,
> @@ -158,27 +151,28 @@ static ssize_t bt_writen(struct bt_bmc
> *bt_bmc, u8 *buf, size_t n)
> return n;
> }
>
> +/* TODO(benjaminfair): support ioctl BT_BMC_IOCTL_SMS_ATN */
> static void set_sms_atn(struct bt_bmc *bt_bmc)
> {
> bt_outb(bt_bmc, BT_CTRL_SMS_ATN, BT_CTRL);
> }
>
> -static struct bt_bmc *file_bt_bmc(struct file *file)
> +/* Called with bt_bmc->lock held */
> +static bool __is_request_avail(struct bt_bmc *bt_bmc)
> {
> - return container_of(file->private_data, struct bt_bmc, miscdev);
> + return bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_H2B_ATN;
> }
>
> -static int bt_bmc_open(struct inode *inode, struct file *file)
> +static bool is_request_avail(struct bt_bmc *bt_bmc)
> {
> - struct bt_bmc *bt_bmc = file_bt_bmc(file);
> + unsigned long flags;
> + bool result;
>
> - if (atomic_inc_return(&open_count) == 1) {
> - clr_b_busy(bt_bmc);
> - return 0;
> - }
> + spin_lock_irqsave(&bt_bmc->lock, flags);
> + result = __is_request_avail(bt_bmc);
> + spin_unlock_irqrestore(&bt_bmc->lock, flags);
>
> - atomic_dec(&open_count);
> - return -EBUSY;
> + return result;
> }
>
> /*
> @@ -194,67 +188,43 @@ static int bt_bmc_open(struct inode *inode,
> struct file *file)
> *Length NetFn/LUN Seq Cmd Data
> *
> */
> -static ssize_t bt_bmc_read(struct file *file, char __user *buf,
> -size_t count, loff_t *ppos)
> +static void get_request(struct bt_bmc *bt_bmc)
> {
> - struct bt_bmc *bt_bmc = file_bt_bmc(file);
> - u8 len;
> - int len_byte = 1;
> - u8 kbuffer[BT_BMC_BUFFER_SIZE];
> - ssize_t ret = 0;
> - ssize_t nread;
> + u8 *request_buf = (u8 *) &bt_bmc->request;
> + unsigned long flags;
>
> - if (!access_ok(VERIFY_WRITE, buf, count))
> - return -EFAULT;
> + spin_lock_irqsave(&bt_bmc->lock, flags);
>
> - WARN_ON(*ppos);
> -
> - if (wait_event_interruptible(bt_bmc->queue,
> - bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_H2B_ATN))
> - return -ERESTARTSYS;
> -
> - mutex_lock(&bt_bmc->mutex);
> -
> - if (unlikely(!(bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_H2B_ATN))) {
> - ret = -EIO;
> - goto out_unlock;
> + if (!__is_request_avail(bt_bmc)) {
> + spin_unlock_irqrestore(&bt_bmc->lock, flags);
> + return;
> }
>
> set_b_busy(bt_bmc);
> clr_h2b_atn(bt_bmc);
> clr_rd_ptr(bt_bmc);
>
> - /*
> -* The BT frames start with the message length, which does