root/drivers/char/ipmi/ipmi_dmi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dmi_add_platform_ipmi
  2. ipmi_dmi_get_slave_addr
  3. dmi_decode_ipmi
  4. scan_for_dmi_ipmi

   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 #define pr_fmt(fmt) "%s" fmt, "ipmi:dmi: "
   8 #define dev_fmt pr_fmt
   9 
  10 #include <linux/ipmi.h>
  11 #include <linux/init.h>
  12 #include <linux/dmi.h>
  13 #include <linux/platform_device.h>
  14 #include <linux/property.h>
  15 #include "ipmi_dmi.h"
  16 #include "ipmi_plat_data.h"
  17 
  18 #define IPMI_DMI_TYPE_KCS       0x01
  19 #define IPMI_DMI_TYPE_SMIC      0x02
  20 #define IPMI_DMI_TYPE_BT        0x03
  21 #define IPMI_DMI_TYPE_SSIF      0x04
  22 
  23 struct ipmi_dmi_info {
  24         enum si_type si_type;
  25         unsigned int space; /* addr space for si, intf# for ssif */
  26         unsigned long addr;
  27         u8 slave_addr;
  28         struct ipmi_dmi_info *next;
  29 };
  30 
  31 static struct ipmi_dmi_info *ipmi_dmi_infos;
  32 
  33 static int ipmi_dmi_nr __initdata;
  34 
  35 static void __init dmi_add_platform_ipmi(unsigned long base_addr,
  36                                          unsigned int space,
  37                                          u8 slave_addr,
  38                                          int irq,
  39                                          int offset,
  40                                          int type)
  41 {
  42         const char *name;
  43         struct ipmi_dmi_info *info;
  44         struct ipmi_plat_data p;
  45 
  46         memset(&p, 0, sizeof(p));
  47 
  48         name = "dmi-ipmi-si";
  49         p.iftype = IPMI_PLAT_IF_SI;
  50         switch (type) {
  51         case IPMI_DMI_TYPE_SSIF:
  52                 name = "dmi-ipmi-ssif";
  53                 p.iftype = IPMI_PLAT_IF_SSIF;
  54                 p.type = SI_TYPE_INVALID;
  55                 break;
  56         case IPMI_DMI_TYPE_BT:
  57                 p.type = SI_BT;
  58                 break;
  59         case IPMI_DMI_TYPE_KCS:
  60                 p.type = SI_KCS;
  61                 break;
  62         case IPMI_DMI_TYPE_SMIC:
  63                 p.type = SI_SMIC;
  64                 break;
  65         default:
  66                 pr_err("Invalid IPMI type: %d\n", type);
  67                 return;
  68         }
  69 
  70         p.addr = base_addr;
  71         p.space = space;
  72         p.regspacing = offset;
  73         p.irq = irq;
  74         p.slave_addr = slave_addr;
  75         p.addr_source = SI_SMBIOS;
  76 
  77         info = kmalloc(sizeof(*info), GFP_KERNEL);
  78         if (!info) {
  79                 pr_warn("Could not allocate dmi info\n");
  80         } else {
  81                 info->si_type = p.type;
  82                 info->space = space;
  83                 info->addr = base_addr;
  84                 info->slave_addr = slave_addr;
  85                 info->next = ipmi_dmi_infos;
  86                 ipmi_dmi_infos = info;
  87         }
  88 
  89         if (ipmi_platform_add(name, ipmi_dmi_nr, &p))
  90                 ipmi_dmi_nr++;
  91 }
  92 
  93 /*
  94  * Look up the slave address for a given interface.  This is here
  95  * because ACPI doesn't have a slave address while SMBIOS does, but we
  96  * prefer using ACPI so the ACPI code can use the IPMI namespace.
  97  * This function allows an ACPI-specified IPMI device to look up the
  98  * slave address from the DMI table.
  99  */
 100 int ipmi_dmi_get_slave_addr(enum si_type si_type, unsigned int space,
 101                             unsigned long base_addr)
 102 {
 103         struct ipmi_dmi_info *info = ipmi_dmi_infos;
 104 
 105         while (info) {
 106                 if (info->si_type == si_type &&
 107                     info->space == space &&
 108                     info->addr == base_addr)
 109                         return info->slave_addr;
 110                 info = info->next;
 111         }
 112 
 113         return 0;
 114 }
 115 EXPORT_SYMBOL(ipmi_dmi_get_slave_addr);
 116 
 117 #define DMI_IPMI_MIN_LENGTH     0x10
 118 #define DMI_IPMI_VER2_LENGTH    0x12
 119 #define DMI_IPMI_TYPE           4
 120 #define DMI_IPMI_SLAVEADDR      6
 121 #define DMI_IPMI_ADDR           8
 122 #define DMI_IPMI_ACCESS         0x10
 123 #define DMI_IPMI_IRQ            0x11
 124 #define DMI_IPMI_IO_MASK        0xfffe
 125 
 126 static void __init dmi_decode_ipmi(const struct dmi_header *dm)
 127 {
 128         const u8 *data = (const u8 *) dm;
 129         int space = IPMI_IO_ADDR_SPACE;
 130         unsigned long base_addr;
 131         u8 len = dm->length;
 132         u8 slave_addr;
 133         int irq = 0, offset = 0;
 134         int type;
 135 
 136         if (len < DMI_IPMI_MIN_LENGTH)
 137                 return;
 138 
 139         type = data[DMI_IPMI_TYPE];
 140         slave_addr = data[DMI_IPMI_SLAVEADDR];
 141 
 142         memcpy(&base_addr, data + DMI_IPMI_ADDR, sizeof(unsigned long));
 143         if (!base_addr) {
 144                 pr_err("Base address is zero, assuming no IPMI interface\n");
 145                 return;
 146         }
 147         if (len >= DMI_IPMI_VER2_LENGTH) {
 148                 if (type == IPMI_DMI_TYPE_SSIF) {
 149                         space = 0; /* Match I2C interface 0. */
 150                         base_addr = data[DMI_IPMI_ADDR] >> 1;
 151                         if (base_addr == 0) {
 152                                 /*
 153                                  * Some broken systems put the I2C address in
 154                                  * the slave address field.  We try to
 155                                  * accommodate them here.
 156                                  */
 157                                 base_addr = data[DMI_IPMI_SLAVEADDR] >> 1;
 158                                 slave_addr = 0;
 159                         }
 160                 } else {
 161                         if (base_addr & 1) {
 162                                 /* I/O */
 163                                 base_addr &= DMI_IPMI_IO_MASK;
 164                         } else {
 165                                 /* Memory */
 166                                 space = IPMI_MEM_ADDR_SPACE;
 167                         }
 168 
 169                         /*
 170                          * If bit 4 of byte 0x10 is set, then the lsb
 171                          * for the address is odd.
 172                          */
 173                         base_addr |= (data[DMI_IPMI_ACCESS] >> 4) & 1;
 174 
 175                         irq = data[DMI_IPMI_IRQ];
 176 
 177                         /*
 178                          * The top two bits of byte 0x10 hold the
 179                          * register spacing.
 180                          */
 181                         switch ((data[DMI_IPMI_ACCESS] >> 6) & 3) {
 182                         case 0: /* Byte boundaries */
 183                                 offset = 1;
 184                                 break;
 185                         case 1: /* 32-bit boundaries */
 186                                 offset = 4;
 187                                 break;
 188                         case 2: /* 16-byte boundaries */
 189                                 offset = 16;
 190                                 break;
 191                         default:
 192                                 pr_err("Invalid offset: 0\n");
 193                                 return;
 194                         }
 195                 }
 196         } else {
 197                 /* Old DMI spec. */
 198                 /*
 199                  * Note that technically, the lower bit of the base
 200                  * address should be 1 if the address is I/O and 0 if
 201                  * the address is in memory.  So many systems get that
 202                  * wrong (and all that I have seen are I/O) so we just
 203                  * ignore that bit and assume I/O.  Systems that use
 204                  * memory should use the newer spec, anyway.
 205                  */
 206                 base_addr = base_addr & DMI_IPMI_IO_MASK;
 207                 offset = 1;
 208         }
 209 
 210         dmi_add_platform_ipmi(base_addr, space, slave_addr, irq,
 211                               offset, type);
 212 }
 213 
 214 static int __init scan_for_dmi_ipmi(void)
 215 {
 216         const struct dmi_device *dev = NULL;
 217 
 218         while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev)))
 219                 dmi_decode_ipmi((const struct dmi_header *) dev->device_data);
 220 
 221         return 0;
 222 }
 223 subsys_initcall(scan_for_dmi_ipmi);

/* [<][>][^][v][top][bottom][index][help] */