linux/drivers/char/ipmi/ipmi_dmi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * A hack to create a platform device from a DMI entry.  This will
   4 * allow autoloading of the IPMI drive based on SMBIOS entries.
   5 */
   6
   7#include <linux/ipmi.h>
   8#include <linux/init.h>
   9#include <linux/dmi.h>
  10#include <linux/platform_device.h>
  11#include <linux/property.h>
  12#include "ipmi_si_sm.h"
  13#include "ipmi_dmi.h"
  14
  15#define IPMI_DMI_TYPE_KCS       0x01
  16#define IPMI_DMI_TYPE_SMIC      0x02
  17#define IPMI_DMI_TYPE_BT        0x03
  18#define IPMI_DMI_TYPE_SSIF      0x04
  19
  20struct ipmi_dmi_info {
  21        enum si_type si_type;
  22        u32 flags;
  23        unsigned long addr;
  24        u8 slave_addr;
  25        struct ipmi_dmi_info *next;
  26};
  27
  28static struct ipmi_dmi_info *ipmi_dmi_infos;
  29
  30static int ipmi_dmi_nr __initdata;
  31
  32static void __init dmi_add_platform_ipmi(unsigned long base_addr,
  33                                         u32 flags,
  34                                         u8 slave_addr,
  35                                         int irq,
  36                                         int offset,
  37                                         int type)
  38{
  39        struct platform_device *pdev;
  40        struct resource r[4];
  41        unsigned int num_r = 1, size;
  42        struct property_entry p[5];
  43        unsigned int pidx = 0;
  44        char *name, *override;
  45        int rv;
  46        enum si_type si_type;
  47        struct ipmi_dmi_info *info;
  48
  49        memset(p, 0, sizeof(p));
  50
  51        name = "dmi-ipmi-si";
  52        override = "ipmi_si";
  53        switch (type) {
  54        case IPMI_DMI_TYPE_SSIF:
  55                name = "dmi-ipmi-ssif";
  56                override = "ipmi_ssif";
  57                offset = 1;
  58                size = 1;
  59                si_type = SI_TYPE_INVALID;
  60                break;
  61        case IPMI_DMI_TYPE_BT:
  62                size = 3;
  63                si_type = SI_BT;
  64                break;
  65        case IPMI_DMI_TYPE_KCS:
  66                size = 2;
  67                si_type = SI_KCS;
  68                break;
  69        case IPMI_DMI_TYPE_SMIC:
  70                size = 2;
  71                si_type = SI_SMIC;
  72                break;
  73        default:
  74                pr_err("ipmi:dmi: Invalid IPMI type: %d\n", type);
  75                return;
  76        }
  77
  78        if (si_type != SI_TYPE_INVALID)
  79                p[pidx++] = PROPERTY_ENTRY_U8("ipmi-type", si_type);
  80
  81        p[pidx++] = PROPERTY_ENTRY_U8("slave-addr", slave_addr);
  82        p[pidx++] = PROPERTY_ENTRY_U8("addr-source", SI_SMBIOS);
  83
  84        info = kmalloc(sizeof(*info), GFP_KERNEL);
  85        if (!info) {
  86                pr_warn("ipmi:dmi: Could not allocate dmi info\n");
  87        } else {
  88                info->si_type = si_type;
  89                info->flags = flags;
  90                info->addr = base_addr;
  91                info->slave_addr = slave_addr;
  92                info->next = ipmi_dmi_infos;
  93                ipmi_dmi_infos = info;
  94        }
  95
  96        pdev = platform_device_alloc(name, ipmi_dmi_nr);
  97        if (!pdev) {
  98                pr_err("ipmi:dmi: Error allocation IPMI platform device\n");
  99                return;
 100        }
 101        pdev->driver_override = kasprintf(GFP_KERNEL, "%s",
 102                                          override);
 103        if (!pdev->driver_override)
 104                goto err;
 105
 106        if (type == IPMI_DMI_TYPE_SSIF) {
 107                p[pidx++] = PROPERTY_ENTRY_U16("i2c-addr", base_addr);
 108                goto add_properties;
 109        }
 110
 111        memset(r, 0, sizeof(r));
 112
 113        r[0].start = base_addr;
 114        r[0].end = r[0].start + offset - 1;
 115        r[0].name = "IPMI Address 1";
 116        r[0].flags = flags;
 117
 118        if (size > 1) {
 119                r[1].start = r[0].start + offset;
 120                r[1].end = r[1].start + offset - 1;
 121                r[1].name = "IPMI Address 2";
 122                r[1].flags = flags;
 123                num_r++;
 124        }
 125
 126        if (size > 2) {
 127                r[2].start = r[1].start + offset;
 128                r[2].end = r[2].start + offset - 1;
 129                r[2].name = "IPMI Address 3";
 130                r[2].flags = flags;
 131                num_r++;
 132        }
 133
 134        if (irq) {
 135                r[num_r].start = irq;
 136                r[num_r].end = irq;
 137                r[num_r].name = "IPMI IRQ";
 138                r[num_r].flags = IORESOURCE_IRQ;
 139                num_r++;
 140        }
 141
 142        rv = platform_device_add_resources(pdev, r, num_r);
 143        if (rv) {
 144                dev_err(&pdev->dev,
 145                        "ipmi:dmi: Unable to add resources: %d\n", rv);
 146                goto err;
 147        }
 148
 149add_properties:
 150        rv = platform_device_add_properties(pdev, p);
 151        if (rv) {
 152                dev_err(&pdev->dev,
 153                        "ipmi:dmi: Unable to add properties: %d\n", rv);
 154                goto err;
 155        }
 156
 157        rv = platform_device_add(pdev);
 158        if (rv) {
 159                dev_err(&pdev->dev, "ipmi:dmi: Unable to add device: %d\n", rv);
 160                goto err;
 161        }
 162
 163        ipmi_dmi_nr++;
 164        return;
 165
 166err:
 167        platform_device_put(pdev);
 168}
 169
 170/*
 171 * Look up the slave address for a given interface.  This is here
 172 * because ACPI doesn't have a slave address while SMBIOS does, but we
 173 * prefer using ACPI so the ACPI code can use the IPMI namespace.
 174 * This function allows an ACPI-specified IPMI device to look up the
 175 * slave address from the DMI table.
 176 */
 177int ipmi_dmi_get_slave_addr(enum si_type si_type, u32 flags,
 178                            unsigned long base_addr)
 179{
 180        struct ipmi_dmi_info *info = ipmi_dmi_infos;
 181
 182        while (info) {
 183                if (info->si_type == si_type &&
 184                    info->flags == flags &&
 185                    info->addr == base_addr)
 186                        return info->slave_addr;
 187                info = info->next;
 188        }
 189
 190        return 0;
 191}
 192EXPORT_SYMBOL(ipmi_dmi_get_slave_addr);
 193
 194#define DMI_IPMI_MIN_LENGTH     0x10
 195#define DMI_IPMI_VER2_LENGTH    0x12
 196#define DMI_IPMI_TYPE           4
 197#define DMI_IPMI_SLAVEADDR      6
 198#define DMI_IPMI_ADDR           8
 199#define DMI_IPMI_ACCESS         0x10
 200#define DMI_IPMI_IRQ            0x11
 201#define DMI_IPMI_IO_MASK        0xfffe
 202
 203static void __init dmi_decode_ipmi(const struct dmi_header *dm)
 204{
 205        const u8        *data = (const u8 *) dm;
 206        u32             flags = IORESOURCE_IO;
 207        unsigned long   base_addr;
 208        u8              len = dm->length;
 209        u8              slave_addr;
 210        int             irq = 0, offset;
 211        int             type;
 212
 213        if (len < DMI_IPMI_MIN_LENGTH)
 214                return;
 215
 216        type = data[DMI_IPMI_TYPE];
 217        slave_addr = data[DMI_IPMI_SLAVEADDR];
 218
 219        memcpy(&base_addr, data + DMI_IPMI_ADDR, sizeof(unsigned long));
 220        if (len >= DMI_IPMI_VER2_LENGTH) {
 221                if (type == IPMI_DMI_TYPE_SSIF) {
 222                        offset = 0;
 223                        flags = 0;
 224                        base_addr = data[DMI_IPMI_ADDR] >> 1;
 225                        if (base_addr == 0) {
 226                                /*
 227                                 * Some broken systems put the I2C address in
 228                                 * the slave address field.  We try to
 229                                 * accommodate them here.
 230                                 */
 231                                base_addr = data[DMI_IPMI_SLAVEADDR] >> 1;
 232                                slave_addr = 0;
 233                        }
 234                } else {
 235                        if (base_addr & 1) {
 236                                /* I/O */
 237                                base_addr &= DMI_IPMI_IO_MASK;
 238                        } else {
 239                                /* Memory */
 240                                flags = IORESOURCE_MEM;
 241                        }
 242
 243                        /*
 244                         * If bit 4 of byte 0x10 is set, then the lsb
 245                         * for the address is odd.
 246                         */
 247                        base_addr |= (data[DMI_IPMI_ACCESS] >> 4) & 1;
 248
 249                        irq = data[DMI_IPMI_IRQ];
 250
 251                        /*
 252                         * The top two bits of byte 0x10 hold the
 253                         * register spacing.
 254                         */
 255                        switch ((data[DMI_IPMI_ACCESS] >> 6) & 3) {
 256                        case 0: /* Byte boundaries */
 257                                offset = 1;
 258                                break;
 259                        case 1: /* 32-bit boundaries */
 260                                offset = 4;
 261                                break;
 262                        case 2: /* 16-byte boundaries */
 263                                offset = 16;
 264                                break;
 265                        default:
 266                                pr_err("ipmi:dmi: Invalid offset: 0\n");
 267                                return;
 268                        }
 269                }
 270        } else {
 271                /* Old DMI spec. */
 272                /*
 273                 * Note that technically, the lower bit of the base
 274                 * address should be 1 if the address is I/O and 0 if
 275                 * the address is in memory.  So many systems get that
 276                 * wrong (and all that I have seen are I/O) so we just
 277                 * ignore that bit and assume I/O.  Systems that use
 278                 * memory should use the newer spec, anyway.
 279                 */
 280                base_addr = base_addr & DMI_IPMI_IO_MASK;
 281                offset = 1;
 282        }
 283
 284        dmi_add_platform_ipmi(base_addr, flags, slave_addr, irq,
 285                              offset, type);
 286}
 287
 288static int __init scan_for_dmi_ipmi(void)
 289{
 290        const struct dmi_device *dev = NULL;
 291
 292#ifdef CONFIG_ARM64
 293        /* RHEL-only
 294         * If this is ARM-based HPE m400, return now, because that platform
 295         * reports the host-side ipmi address as intel port-io space, which
 296         * does not exist in the ARM architecture.
 297         */
 298        const char *dmistr = dmi_get_system_info(DMI_PRODUCT_NAME);
 299
 300        if (dmistr && (strcmp("ProLiant m400 Server", dmistr) == 0)) {
 301                pr_debug("%s does not support host ipmi\n", dmistr);
 302                return 0;
 303        }
 304        /* END RHEL-only */
 305#endif
 306
 307        while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev)))
 308                dmi_decode_ipmi((const struct dmi_header *) dev->device_data);
 309
 310        return 0;
 311}
 312subsys_initcall(scan_for_dmi_ipmi);
 313