| .. | .. |
|---|
| 19 | 19 | * and drives the real SMI state machine. |
|---|
| 20 | 20 | */ |
|---|
| 21 | 21 | |
|---|
| 22 | +#define pr_fmt(fmt) "ipmi_si: " fmt |
|---|
| 23 | + |
|---|
| 22 | 24 | #include <linux/module.h> |
|---|
| 23 | 25 | #include <linux/moduleparam.h> |
|---|
| 24 | 26 | #include <linux/sched.h> |
|---|
| .. | .. |
|---|
| 38 | 40 | #include <linux/ipmi.h> |
|---|
| 39 | 41 | #include <linux/ipmi_smi.h> |
|---|
| 40 | 42 | #include "ipmi_si.h" |
|---|
| 43 | +#include "ipmi_si_sm.h" |
|---|
| 41 | 44 | #include <linux/string.h> |
|---|
| 42 | 45 | #include <linux/ctype.h> |
|---|
| 43 | | - |
|---|
| 44 | | -#define PFX "ipmi_si: " |
|---|
| 45 | 46 | |
|---|
| 46 | 47 | /* Measure times between events in the driver. */ |
|---|
| 47 | 48 | #undef DEBUG_TIMING |
|---|
| .. | .. |
|---|
| 71 | 72 | |
|---|
| 72 | 73 | static const char * const si_to_str[] = { "invalid", "kcs", "smic", "bt" }; |
|---|
| 73 | 74 | |
|---|
| 74 | | -static int initialized; |
|---|
| 75 | +static bool initialized; |
|---|
| 75 | 76 | |
|---|
| 76 | 77 | /* |
|---|
| 77 | 78 | * Indexes into stats[] in smi_info below. |
|---|
| .. | .. |
|---|
| 232 | 233 | /* From the get device id response... */ |
|---|
| 233 | 234 | struct ipmi_device_id device_id; |
|---|
| 234 | 235 | |
|---|
| 235 | | - /* Default driver model device. */ |
|---|
| 236 | | - struct platform_device *pdev; |
|---|
| 237 | | - |
|---|
| 238 | 236 | /* Have we added the device group to the device? */ |
|---|
| 239 | 237 | bool dev_group_added; |
|---|
| 240 | | - |
|---|
| 241 | | - /* Have we added the platform device? */ |
|---|
| 242 | | - bool pdev_registered; |
|---|
| 243 | 238 | |
|---|
| 244 | 239 | /* Counters and things for the proc filesystem. */ |
|---|
| 245 | 240 | atomic_t stats[SI_NUM_STATS]; |
|---|
| .. | .. |
|---|
| 272 | 267 | { |
|---|
| 273 | 268 | struct timespec64 t; |
|---|
| 274 | 269 | |
|---|
| 275 | | - getnstimeofday64(&t); |
|---|
| 276 | | - pr_debug("**%s: %lld.%9.9ld\n", msg, (long long) t.tv_sec, t.tv_nsec); |
|---|
| 270 | + ktime_get_ts64(&t); |
|---|
| 271 | + pr_debug("**%s: %lld.%9.9ld\n", msg, t.tv_sec, t.tv_nsec); |
|---|
| 277 | 272 | } |
|---|
| 278 | 273 | #else |
|---|
| 279 | 274 | #define debug_timestamp(x) |
|---|
| .. | .. |
|---|
| 940 | 935 | } |
|---|
| 941 | 936 | |
|---|
| 942 | 937 | /* |
|---|
| 943 | | - * Use -1 in the nsec value of the busy waiting timespec to tell that |
|---|
| 944 | | - * we are spinning in kipmid looking for something and not delaying |
|---|
| 945 | | - * between checks |
|---|
| 938 | + * Use -1 as a special constant to tell that we are spinning in kipmid |
|---|
| 939 | + * looking for something and not delaying between checks |
|---|
| 946 | 940 | */ |
|---|
| 947 | | -static inline void ipmi_si_set_not_busy(struct timespec64 *ts) |
|---|
| 948 | | -{ |
|---|
| 949 | | - ts->tv_nsec = -1; |
|---|
| 950 | | -} |
|---|
| 951 | | -static inline int ipmi_si_is_busy(struct timespec64 *ts) |
|---|
| 952 | | -{ |
|---|
| 953 | | - return ts->tv_nsec != -1; |
|---|
| 954 | | -} |
|---|
| 955 | | - |
|---|
| 956 | | -static inline int ipmi_thread_busy_wait(enum si_sm_result smi_result, |
|---|
| 957 | | - const struct smi_info *smi_info, |
|---|
| 958 | | - struct timespec64 *busy_until) |
|---|
| 941 | +#define IPMI_TIME_NOT_BUSY ns_to_ktime(-1ull) |
|---|
| 942 | +static inline bool ipmi_thread_busy_wait(enum si_sm_result smi_result, |
|---|
| 943 | + const struct smi_info *smi_info, |
|---|
| 944 | + ktime_t *busy_until) |
|---|
| 959 | 945 | { |
|---|
| 960 | 946 | unsigned int max_busy_us = 0; |
|---|
| 961 | 947 | |
|---|
| 962 | 948 | if (smi_info->si_num < num_max_busy_us) |
|---|
| 963 | 949 | max_busy_us = kipmid_max_busy_us[smi_info->si_num]; |
|---|
| 964 | 950 | if (max_busy_us == 0 || smi_result != SI_SM_CALL_WITH_DELAY) |
|---|
| 965 | | - ipmi_si_set_not_busy(busy_until); |
|---|
| 966 | | - else if (!ipmi_si_is_busy(busy_until)) { |
|---|
| 967 | | - getnstimeofday64(busy_until); |
|---|
| 968 | | - timespec64_add_ns(busy_until, max_busy_us*NSEC_PER_USEC); |
|---|
| 951 | + *busy_until = IPMI_TIME_NOT_BUSY; |
|---|
| 952 | + else if (*busy_until == IPMI_TIME_NOT_BUSY) { |
|---|
| 953 | + *busy_until = ktime_get() + max_busy_us * NSEC_PER_USEC; |
|---|
| 969 | 954 | } else { |
|---|
| 970 | | - struct timespec64 now; |
|---|
| 971 | | - |
|---|
| 972 | | - getnstimeofday64(&now); |
|---|
| 973 | | - if (unlikely(timespec64_compare(&now, busy_until) > 0)) { |
|---|
| 974 | | - ipmi_si_set_not_busy(busy_until); |
|---|
| 975 | | - return 0; |
|---|
| 955 | + if (unlikely(ktime_get() > *busy_until)) { |
|---|
| 956 | + *busy_until = IPMI_TIME_NOT_BUSY; |
|---|
| 957 | + return false; |
|---|
| 976 | 958 | } |
|---|
| 977 | 959 | } |
|---|
| 978 | | - return 1; |
|---|
| 960 | + return true; |
|---|
| 979 | 961 | } |
|---|
| 980 | 962 | |
|---|
| 981 | 963 | |
|---|
| .. | .. |
|---|
| 986 | 968 | * that are not BT and do not have interrupts. It starts spinning |
|---|
| 987 | 969 | * when an operation is complete or until max_busy tells it to stop |
|---|
| 988 | 970 | * (if that is enabled). See the paragraph on kimid_max_busy_us in |
|---|
| 989 | | - * Documentation/IPMI.txt for details. |
|---|
| 971 | + * Documentation/driver-api/ipmi.rst for details. |
|---|
| 990 | 972 | */ |
|---|
| 991 | 973 | static int ipmi_thread(void *data) |
|---|
| 992 | 974 | { |
|---|
| 993 | 975 | struct smi_info *smi_info = data; |
|---|
| 994 | 976 | unsigned long flags; |
|---|
| 995 | 977 | enum si_sm_result smi_result; |
|---|
| 996 | | - struct timespec64 busy_until; |
|---|
| 978 | + ktime_t busy_until = IPMI_TIME_NOT_BUSY; |
|---|
| 997 | 979 | |
|---|
| 998 | | - ipmi_si_set_not_busy(&busy_until); |
|---|
| 999 | 980 | set_user_nice(current, MAX_NICE); |
|---|
| 1000 | 981 | while (!kthread_should_stop()) { |
|---|
| 1001 | 982 | int busy_wait; |
|---|
| .. | .. |
|---|
| 1073 | 1054 | atomic_set(&smi_info->req_events, 1); |
|---|
| 1074 | 1055 | } |
|---|
| 1075 | 1056 | |
|---|
| 1076 | | -static void set_need_watch(void *send_info, bool enable) |
|---|
| 1057 | +static void set_need_watch(void *send_info, unsigned int watch_mask) |
|---|
| 1077 | 1058 | { |
|---|
| 1078 | 1059 | struct smi_info *smi_info = send_info; |
|---|
| 1079 | 1060 | unsigned long flags; |
|---|
| 1061 | + int enable; |
|---|
| 1062 | + |
|---|
| 1063 | + enable = !!watch_mask; |
|---|
| 1080 | 1064 | |
|---|
| 1081 | 1065 | atomic_set(&smi_info->need_watch, enable); |
|---|
| 1082 | 1066 | spin_lock_irqsave(&smi_info->si_lock, flags); |
|---|
| .. | .. |
|---|
| 1283 | 1267 | rv = request_irq(io->irq, |
|---|
| 1284 | 1268 | ipmi_si_irq_handler, |
|---|
| 1285 | 1269 | IRQF_SHARED, |
|---|
| 1286 | | - DEVICE_NAME, |
|---|
| 1270 | + SI_DEVICE_NAME, |
|---|
| 1287 | 1271 | io->irq_handler_data); |
|---|
| 1288 | 1272 | if (rv) { |
|---|
| 1289 | 1273 | dev_warn(io->dev, "%s unable to claim interrupt %d," |
|---|
| 1290 | 1274 | " running polled\n", |
|---|
| 1291 | | - DEVICE_NAME, io->irq); |
|---|
| 1275 | + SI_DEVICE_NAME, io->irq); |
|---|
| 1292 | 1276 | io->irq = 0; |
|---|
| 1293 | 1277 | } else { |
|---|
| 1294 | 1278 | io->irq_cleanup = std_irq_cleanup; |
|---|
| .. | .. |
|---|
| 1332 | 1316 | unsigned char *resp; |
|---|
| 1333 | 1317 | unsigned long resp_len; |
|---|
| 1334 | 1318 | int rv = 0; |
|---|
| 1319 | + unsigned int retry_count = 0; |
|---|
| 1335 | 1320 | |
|---|
| 1336 | 1321 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); |
|---|
| 1337 | 1322 | if (!resp) |
|---|
| .. | .. |
|---|
| 1343 | 1328 | */ |
|---|
| 1344 | 1329 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; |
|---|
| 1345 | 1330 | msg[1] = IPMI_GET_DEVICE_ID_CMD; |
|---|
| 1331 | + |
|---|
| 1332 | +retry: |
|---|
| 1346 | 1333 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); |
|---|
| 1347 | 1334 | |
|---|
| 1348 | 1335 | rv = wait_for_msg_done(smi_info); |
|---|
| .. | .. |
|---|
| 1355 | 1342 | /* Check and record info from the get device id, in case we need it. */ |
|---|
| 1356 | 1343 | rv = ipmi_demangle_device_id(resp[0] >> 2, resp[1], |
|---|
| 1357 | 1344 | resp + 2, resp_len - 2, &smi_info->device_id); |
|---|
| 1345 | + if (rv) { |
|---|
| 1346 | + /* record completion code */ |
|---|
| 1347 | + unsigned char cc = *(resp + 2); |
|---|
| 1348 | + |
|---|
| 1349 | + if ((cc == IPMI_DEVICE_IN_FW_UPDATE_ERR |
|---|
| 1350 | + || cc == IPMI_DEVICE_IN_INIT_ERR |
|---|
| 1351 | + || cc == IPMI_NOT_IN_MY_STATE_ERR) |
|---|
| 1352 | + && ++retry_count <= GET_DEVICE_ID_MAX_RETRY) { |
|---|
| 1353 | + dev_warn(smi_info->io.dev, |
|---|
| 1354 | + "BMC returned 0x%2.2x, retry get bmc device id\n", |
|---|
| 1355 | + cc); |
|---|
| 1356 | + goto retry; |
|---|
| 1357 | + } |
|---|
| 1358 | + } |
|---|
| 1358 | 1359 | |
|---|
| 1359 | 1360 | out: |
|---|
| 1360 | 1361 | kfree(resp); |
|---|
| .. | .. |
|---|
| 1544 | 1545 | |
|---|
| 1545 | 1546 | rv = wait_for_msg_done(smi_info); |
|---|
| 1546 | 1547 | if (rv) { |
|---|
| 1547 | | - pr_warn(PFX "Error getting response from get global enables command, the event buffer is not enabled.\n"); |
|---|
| 1548 | + pr_warn("Error getting response from get global enables command, the event buffer is not enabled\n"); |
|---|
| 1548 | 1549 | goto out; |
|---|
| 1549 | 1550 | } |
|---|
| 1550 | 1551 | |
|---|
| .. | .. |
|---|
| 1555 | 1556 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || |
|---|
| 1556 | 1557 | resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD || |
|---|
| 1557 | 1558 | resp[2] != 0) { |
|---|
| 1558 | | - pr_warn(PFX "Invalid return from get global enables command, cannot enable the event buffer.\n"); |
|---|
| 1559 | + pr_warn("Invalid return from get global enables command, cannot enable the event buffer\n"); |
|---|
| 1559 | 1560 | rv = -EINVAL; |
|---|
| 1560 | 1561 | goto out; |
|---|
| 1561 | 1562 | } |
|---|
| .. | .. |
|---|
| 1573 | 1574 | |
|---|
| 1574 | 1575 | rv = wait_for_msg_done(smi_info); |
|---|
| 1575 | 1576 | if (rv) { |
|---|
| 1576 | | - pr_warn(PFX "Error getting response from set global, enables command, the event buffer is not enabled.\n"); |
|---|
| 1577 | + pr_warn("Error getting response from set global, enables command, the event buffer is not enabled\n"); |
|---|
| 1577 | 1578 | goto out; |
|---|
| 1578 | 1579 | } |
|---|
| 1579 | 1580 | |
|---|
| .. | .. |
|---|
| 1583 | 1584 | if (resp_len < 3 || |
|---|
| 1584 | 1585 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || |
|---|
| 1585 | 1586 | resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) { |
|---|
| 1586 | | - pr_warn(PFX "Invalid return from get global, enables command, not enable the event buffer.\n"); |
|---|
| 1587 | + pr_warn("Invalid return from get global, enables command, not enable the event buffer\n"); |
|---|
| 1587 | 1588 | rv = -EINVAL; |
|---|
| 1588 | 1589 | goto out; |
|---|
| 1589 | 1590 | } |
|---|
| .. | .. |
|---|
| 1603 | 1604 | } |
|---|
| 1604 | 1605 | |
|---|
| 1605 | 1606 | #define IPMI_SI_ATTR(name) \ |
|---|
| 1606 | | -static ssize_t ipmi_##name##_show(struct device *dev, \ |
|---|
| 1607 | | - struct device_attribute *attr, \ |
|---|
| 1608 | | - char *buf) \ |
|---|
| 1607 | +static ssize_t name##_show(struct device *dev, \ |
|---|
| 1608 | + struct device_attribute *attr, \ |
|---|
| 1609 | + char *buf) \ |
|---|
| 1609 | 1610 | { \ |
|---|
| 1610 | 1611 | struct smi_info *smi_info = dev_get_drvdata(dev); \ |
|---|
| 1611 | 1612 | \ |
|---|
| 1612 | 1613 | return snprintf(buf, 10, "%u\n", smi_get_stat(smi_info, name)); \ |
|---|
| 1613 | 1614 | } \ |
|---|
| 1614 | | -static DEVICE_ATTR(name, S_IRUGO, ipmi_##name##_show, NULL) |
|---|
| 1615 | +static DEVICE_ATTR(name, 0444, name##_show, NULL) |
|---|
| 1615 | 1616 | |
|---|
| 1616 | | -static ssize_t ipmi_type_show(struct device *dev, |
|---|
| 1617 | | - struct device_attribute *attr, |
|---|
| 1618 | | - char *buf) |
|---|
| 1617 | +static ssize_t type_show(struct device *dev, |
|---|
| 1618 | + struct device_attribute *attr, |
|---|
| 1619 | + char *buf) |
|---|
| 1619 | 1620 | { |
|---|
| 1620 | 1621 | struct smi_info *smi_info = dev_get_drvdata(dev); |
|---|
| 1621 | 1622 | |
|---|
| 1622 | 1623 | return snprintf(buf, 10, "%s\n", si_to_str[smi_info->io.si_type]); |
|---|
| 1623 | 1624 | } |
|---|
| 1624 | | -static DEVICE_ATTR(type, S_IRUGO, ipmi_type_show, NULL); |
|---|
| 1625 | +static DEVICE_ATTR(type, 0444, type_show, NULL); |
|---|
| 1625 | 1626 | |
|---|
| 1626 | | -static ssize_t ipmi_interrupts_enabled_show(struct device *dev, |
|---|
| 1627 | | - struct device_attribute *attr, |
|---|
| 1628 | | - char *buf) |
|---|
| 1627 | +static ssize_t interrupts_enabled_show(struct device *dev, |
|---|
| 1628 | + struct device_attribute *attr, |
|---|
| 1629 | + char *buf) |
|---|
| 1629 | 1630 | { |
|---|
| 1630 | 1631 | struct smi_info *smi_info = dev_get_drvdata(dev); |
|---|
| 1631 | 1632 | int enabled = smi_info->io.irq && !smi_info->interrupt_disabled; |
|---|
| 1632 | 1633 | |
|---|
| 1633 | 1634 | return snprintf(buf, 10, "%d\n", enabled); |
|---|
| 1634 | 1635 | } |
|---|
| 1635 | | -static DEVICE_ATTR(interrupts_enabled, S_IRUGO, |
|---|
| 1636 | | - ipmi_interrupts_enabled_show, NULL); |
|---|
| 1636 | +static DEVICE_ATTR(interrupts_enabled, 0444, |
|---|
| 1637 | + interrupts_enabled_show, NULL); |
|---|
| 1637 | 1638 | |
|---|
| 1638 | 1639 | IPMI_SI_ATTR(short_timeouts); |
|---|
| 1639 | 1640 | IPMI_SI_ATTR(long_timeouts); |
|---|
| .. | .. |
|---|
| 1647 | 1648 | IPMI_SI_ATTR(watchdog_pretimeouts); |
|---|
| 1648 | 1649 | IPMI_SI_ATTR(incoming_messages); |
|---|
| 1649 | 1650 | |
|---|
| 1650 | | -static ssize_t ipmi_params_show(struct device *dev, |
|---|
| 1651 | | - struct device_attribute *attr, |
|---|
| 1652 | | - char *buf) |
|---|
| 1651 | +static ssize_t params_show(struct device *dev, |
|---|
| 1652 | + struct device_attribute *attr, |
|---|
| 1653 | + char *buf) |
|---|
| 1653 | 1654 | { |
|---|
| 1654 | 1655 | struct smi_info *smi_info = dev_get_drvdata(dev); |
|---|
| 1655 | 1656 | |
|---|
| 1656 | 1657 | return snprintf(buf, 200, |
|---|
| 1657 | 1658 | "%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n", |
|---|
| 1658 | 1659 | si_to_str[smi_info->io.si_type], |
|---|
| 1659 | | - addr_space_to_str[smi_info->io.addr_type], |
|---|
| 1660 | + addr_space_to_str[smi_info->io.addr_space], |
|---|
| 1660 | 1661 | smi_info->io.addr_data, |
|---|
| 1661 | 1662 | smi_info->io.regspacing, |
|---|
| 1662 | 1663 | smi_info->io.regsize, |
|---|
| .. | .. |
|---|
| 1664 | 1665 | smi_info->io.irq, |
|---|
| 1665 | 1666 | smi_info->io.slave_addr); |
|---|
| 1666 | 1667 | } |
|---|
| 1667 | | -static DEVICE_ATTR(params, S_IRUGO, ipmi_params_show, NULL); |
|---|
| 1668 | +static DEVICE_ATTR(params, 0444, params_show, NULL); |
|---|
| 1668 | 1669 | |
|---|
| 1669 | 1670 | static struct attribute *ipmi_si_dev_attrs[] = { |
|---|
| 1670 | 1671 | &dev_attr_type.attr, |
|---|
| .. | .. |
|---|
| 1845 | 1846 | } |
|---|
| 1846 | 1847 | |
|---|
| 1847 | 1848 | smi_info->timer_can_start = false; |
|---|
| 1848 | | - if (smi_info->timer_running) |
|---|
| 1849 | | - del_timer_sync(&smi_info->si_timer); |
|---|
| 1849 | + del_timer_sync(&smi_info->si_timer); |
|---|
| 1850 | 1850 | } |
|---|
| 1851 | 1851 | |
|---|
| 1852 | 1852 | static struct smi_info *find_dup_si(struct smi_info *info) |
|---|
| .. | .. |
|---|
| 1854 | 1854 | struct smi_info *e; |
|---|
| 1855 | 1855 | |
|---|
| 1856 | 1856 | list_for_each_entry(e, &smi_infos, link) { |
|---|
| 1857 | | - if (e->io.addr_type != info->io.addr_type) |
|---|
| 1857 | + if (e->io.addr_space != info->io.addr_space) |
|---|
| 1858 | 1858 | continue; |
|---|
| 1859 | 1859 | if (e->io.addr_data == info->io.addr_data) { |
|---|
| 1860 | 1860 | /* |
|---|
| .. | .. |
|---|
| 1881 | 1881 | * address, they presumably want us to use it and not what is |
|---|
| 1882 | 1882 | * in the firmware. |
|---|
| 1883 | 1883 | */ |
|---|
| 1884 | | - if (io->addr_source != SI_HARDCODED && |
|---|
| 1885 | | - ipmi_si_hardcode_match(io->addr_type, io->addr_data)) { |
|---|
| 1884 | + if (io->addr_source != SI_HARDCODED && io->addr_source != SI_HOTMOD && |
|---|
| 1885 | + ipmi_si_hardcode_match(io->addr_space, io->addr_data)) { |
|---|
| 1886 | 1886 | dev_info(io->dev, |
|---|
| 1887 | 1887 | "Hard-coded device at this address already exists"); |
|---|
| 1888 | 1888 | return -ENODEV; |
|---|
| 1889 | 1889 | } |
|---|
| 1890 | 1890 | |
|---|
| 1891 | 1891 | if (!io->io_setup) { |
|---|
| 1892 | | - if (io->addr_type == IPMI_IO_ADDR_SPACE) { |
|---|
| 1892 | + if (io->addr_space == IPMI_IO_ADDR_SPACE) { |
|---|
| 1893 | 1893 | io->io_setup = ipmi_si_port_setup; |
|---|
| 1894 | | - } else if (io->addr_type == IPMI_MEM_ADDR_SPACE) { |
|---|
| 1894 | + } else if (io->addr_space == IPMI_MEM_ADDR_SPACE) { |
|---|
| 1895 | 1895 | io->io_setup = ipmi_si_mem_setup; |
|---|
| 1896 | 1896 | } else { |
|---|
| 1897 | 1897 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 1926 | 1926 | } |
|---|
| 1927 | 1927 | } |
|---|
| 1928 | 1928 | |
|---|
| 1929 | | - pr_info(PFX "Adding %s-specified %s state machine\n", |
|---|
| 1929 | + pr_info("Adding %s-specified %s state machine\n", |
|---|
| 1930 | 1930 | ipmi_addr_src_to_str(new_smi->io.addr_source), |
|---|
| 1931 | 1931 | si_to_str[new_smi->io.si_type]); |
|---|
| 1932 | 1932 | |
|---|
| .. | .. |
|---|
| 1948 | 1948 | { |
|---|
| 1949 | 1949 | int rv = 0; |
|---|
| 1950 | 1950 | int i; |
|---|
| 1951 | | - char *init_name = NULL; |
|---|
| 1952 | 1951 | |
|---|
| 1953 | | - pr_info(PFX "Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n", |
|---|
| 1952 | + pr_info("Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n", |
|---|
| 1954 | 1953 | ipmi_addr_src_to_str(new_smi->io.addr_source), |
|---|
| 1955 | 1954 | si_to_str[new_smi->io.si_type], |
|---|
| 1956 | | - addr_space_to_str[new_smi->io.addr_type], |
|---|
| 1955 | + addr_space_to_str[new_smi->io.addr_space], |
|---|
| 1957 | 1956 | new_smi->io.addr_data, |
|---|
| 1958 | 1957 | new_smi->io.slave_addr, new_smi->io.irq); |
|---|
| 1959 | 1958 | |
|---|
| .. | .. |
|---|
| 1980 | 1979 | |
|---|
| 1981 | 1980 | /* Do this early so it's available for logs. */ |
|---|
| 1982 | 1981 | if (!new_smi->io.dev) { |
|---|
| 1983 | | - init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d", |
|---|
| 1984 | | - new_smi->si_num); |
|---|
| 1985 | | - |
|---|
| 1986 | | - /* |
|---|
| 1987 | | - * If we don't already have a device from something |
|---|
| 1988 | | - * else (like PCI), then register a new one. |
|---|
| 1989 | | - */ |
|---|
| 1990 | | - new_smi->pdev = platform_device_alloc("ipmi_si", |
|---|
| 1991 | | - new_smi->si_num); |
|---|
| 1992 | | - if (!new_smi->pdev) { |
|---|
| 1993 | | - pr_err(PFX "Unable to allocate platform device\n"); |
|---|
| 1994 | | - rv = -ENOMEM; |
|---|
| 1995 | | - goto out_err; |
|---|
| 1996 | | - } |
|---|
| 1997 | | - new_smi->io.dev = &new_smi->pdev->dev; |
|---|
| 1998 | | - new_smi->io.dev->driver = &ipmi_platform_driver.driver; |
|---|
| 1999 | | - /* Nulled by device_add() */ |
|---|
| 2000 | | - new_smi->io.dev->init_name = init_name; |
|---|
| 1982 | + pr_err("IPMI interface added with no device\n"); |
|---|
| 1983 | + rv = -EIO; |
|---|
| 1984 | + goto out_err; |
|---|
| 2001 | 1985 | } |
|---|
| 2002 | 1986 | |
|---|
| 2003 | 1987 | /* Allocate the state machine's data and initialize it. */ |
|---|
| .. | .. |
|---|
| 2070 | 2054 | atomic_set(&new_smi->req_events, 1); |
|---|
| 2071 | 2055 | } |
|---|
| 2072 | 2056 | |
|---|
| 2073 | | - if (new_smi->pdev && !new_smi->pdev_registered) { |
|---|
| 2074 | | - rv = platform_device_add(new_smi->pdev); |
|---|
| 2075 | | - if (rv) { |
|---|
| 2076 | | - dev_err(new_smi->io.dev, |
|---|
| 2077 | | - "Unable to register system interface device: %d\n", |
|---|
| 2078 | | - rv); |
|---|
| 2079 | | - goto out_err; |
|---|
| 2080 | | - } |
|---|
| 2081 | | - new_smi->pdev_registered = true; |
|---|
| 2082 | | - } |
|---|
| 2083 | | - |
|---|
| 2084 | 2057 | dev_set_drvdata(new_smi->io.dev, new_smi); |
|---|
| 2085 | 2058 | rv = device_add_group(new_smi->io.dev, &ipmi_si_dev_attr_group); |
|---|
| 2086 | 2059 | if (rv) { |
|---|
| .. | .. |
|---|
| 2116 | 2089 | new_smi->io.io_cleanup = NULL; |
|---|
| 2117 | 2090 | } |
|---|
| 2118 | 2091 | |
|---|
| 2119 | | - kfree(init_name); |
|---|
| 2120 | 2092 | return rv; |
|---|
| 2121 | 2093 | } |
|---|
| 2122 | 2094 | |
|---|
| .. | .. |
|---|
| 2129 | 2101 | return 0; |
|---|
| 2130 | 2102 | |
|---|
| 2131 | 2103 | ipmi_hardcode_init(); |
|---|
| 2132 | | - pr_info("IPMI System Interface driver.\n"); |
|---|
| 2104 | + |
|---|
| 2105 | + pr_info("IPMI System Interface driver\n"); |
|---|
| 2133 | 2106 | |
|---|
| 2134 | 2107 | ipmi_si_platform_init(); |
|---|
| 2135 | 2108 | |
|---|
| .. | .. |
|---|
| 2168 | 2141 | } |
|---|
| 2169 | 2142 | |
|---|
| 2170 | 2143 | skip_fallback_noirq: |
|---|
| 2171 | | - initialized = 1; |
|---|
| 2144 | + initialized = true; |
|---|
| 2172 | 2145 | mutex_unlock(&smi_infos_lock); |
|---|
| 2173 | 2146 | |
|---|
| 2174 | 2147 | if (type) |
|---|
| .. | .. |
|---|
| 2178 | 2151 | if (unload_when_empty && list_empty(&smi_infos)) { |
|---|
| 2179 | 2152 | mutex_unlock(&smi_infos_lock); |
|---|
| 2180 | 2153 | cleanup_ipmi_si(); |
|---|
| 2181 | | - pr_warn(PFX "Unable to find any System Interface(s)\n"); |
|---|
| 2154 | + pr_warn("Unable to find any System Interface(s)\n"); |
|---|
| 2182 | 2155 | return -ENODEV; |
|---|
| 2183 | 2156 | } else { |
|---|
| 2184 | 2157 | mutex_unlock(&smi_infos_lock); |
|---|
| .. | .. |
|---|
| 2214 | 2187 | * handlers might have been running before we freed the |
|---|
| 2215 | 2188 | * interrupt. |
|---|
| 2216 | 2189 | */ |
|---|
| 2217 | | - synchronize_sched(); |
|---|
| 2190 | + synchronize_rcu(); |
|---|
| 2218 | 2191 | |
|---|
| 2219 | 2192 | /* |
|---|
| 2220 | 2193 | * Timeouts are stopped, now make sure the interrupts are off |
|---|
| .. | .. |
|---|
| 2263 | 2236 | if (smi_info->intf) |
|---|
| 2264 | 2237 | ipmi_unregister_smi(smi_info->intf); |
|---|
| 2265 | 2238 | |
|---|
| 2266 | | - if (smi_info->pdev) { |
|---|
| 2267 | | - if (smi_info->pdev_registered) |
|---|
| 2268 | | - platform_device_unregister(smi_info->pdev); |
|---|
| 2269 | | - else |
|---|
| 2270 | | - platform_device_put(smi_info->pdev); |
|---|
| 2271 | | - } |
|---|
| 2272 | | - |
|---|
| 2273 | 2239 | kfree(smi_info); |
|---|
| 2274 | 2240 | } |
|---|
| 2275 | 2241 | |
|---|
| .. | .. |
|---|
| 2291 | 2257 | return rv; |
|---|
| 2292 | 2258 | } |
|---|
| 2293 | 2259 | |
|---|
| 2294 | | -void ipmi_si_remove_by_data(int addr_space, enum si_type si_type, |
|---|
| 2295 | | - unsigned long addr) |
|---|
| 2260 | +struct device *ipmi_si_remove_by_data(int addr_space, enum si_type si_type, |
|---|
| 2261 | + unsigned long addr) |
|---|
| 2296 | 2262 | { |
|---|
| 2297 | 2263 | /* remove */ |
|---|
| 2298 | 2264 | struct smi_info *e, *tmp_e; |
|---|
| 2265 | + struct device *dev = NULL; |
|---|
| 2299 | 2266 | |
|---|
| 2300 | 2267 | mutex_lock(&smi_infos_lock); |
|---|
| 2301 | 2268 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) { |
|---|
| 2302 | | - if (e->io.addr_type != addr_space) |
|---|
| 2269 | + if (e->io.addr_space != addr_space) |
|---|
| 2303 | 2270 | continue; |
|---|
| 2304 | 2271 | if (e->io.si_type != si_type) |
|---|
| 2305 | 2272 | continue; |
|---|
| 2306 | | - if (e->io.addr_data == addr) |
|---|
| 2273 | + if (e->io.addr_data == addr) { |
|---|
| 2274 | + dev = get_device(e->io.dev); |
|---|
| 2307 | 2275 | cleanup_one_si(e); |
|---|
| 2276 | + } |
|---|
| 2308 | 2277 | } |
|---|
| 2309 | 2278 | mutex_unlock(&smi_infos_lock); |
|---|
| 2279 | + |
|---|
| 2280 | + return dev; |
|---|
| 2310 | 2281 | } |
|---|
| 2311 | 2282 | |
|---|
| 2312 | 2283 | static void cleanup_ipmi_si(void) |
|---|
| .. | .. |
|---|
| 2328 | 2299 | mutex_unlock(&smi_infos_lock); |
|---|
| 2329 | 2300 | |
|---|
| 2330 | 2301 | ipmi_si_hardcode_exit(); |
|---|
| 2302 | + ipmi_si_hotmod_exit(); |
|---|
| 2331 | 2303 | } |
|---|
| 2332 | 2304 | module_exit(cleanup_ipmi_si); |
|---|
| 2333 | 2305 | |
|---|