linux/drivers/misc/ibmasm/ibmasm.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2
   3/*
   4 * IBM ASM Service Processor Device Driver
   5 *
   6 * Copyright (C) IBM Corporation, 2004
   7 *
   8 * Author: Max Asböck <amax@us.ibm.com>
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/types.h>
  13#include <linux/errno.h>
  14#include <linux/list.h>
  15#include <linux/wait.h>
  16#include <linux/spinlock.h>
  17#include <linux/slab.h>
  18#include <linux/module.h>
  19#include <linux/interrupt.h>
  20#include <linux/kref.h>
  21#include <linux/device.h>
  22#include <linux/input.h>
  23#include <linux/time64.h>
  24
  25/* Driver identification */
  26#define DRIVER_NAME     "ibmasm"
  27#define DRIVER_VERSION  "1.0"
  28#define DRIVER_AUTHOR   "Max Asbock <masbock@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"
  29#define DRIVER_DESC     "IBM ASM Service Processor Driver"
  30
  31#define err(msg) printk(KERN_ERR "%s: " msg "\n", DRIVER_NAME)
  32#define info(msg) printk(KERN_INFO "%s: " msg "\n", DRIVER_NAME)
  33
  34extern int ibmasm_debug;
  35#define dbg(STR, ARGS...)                                       \
  36        do {                                                    \
  37                if (ibmasm_debug)                               \
  38                        printk(KERN_DEBUG STR , ##ARGS);        \
  39        } while (0)
  40
  41static inline char *get_timestamp(char *buf)
  42{
  43        struct timespec64 now;
  44
  45        ktime_get_real_ts64(&now);
  46        sprintf(buf, "%llu.%.08lu", (long long)now.tv_sec,
  47                                now.tv_nsec / NSEC_PER_USEC);
  48        return buf;
  49}
  50
  51#define IBMASM_CMD_PENDING      0
  52#define IBMASM_CMD_COMPLETE     1
  53#define IBMASM_CMD_FAILED       2
  54
  55#define IBMASM_CMD_TIMEOUT_NORMAL       45
  56#define IBMASM_CMD_TIMEOUT_EXTRA        240
  57
  58#define IBMASM_CMD_MAX_BUFFER_SIZE      0x8000
  59
  60#define REVERSE_HEARTBEAT_TIMEOUT       120
  61
  62#define HEARTBEAT_BUFFER_SIZE           0x400
  63
  64#ifdef IA64
  65#define IBMASM_DRIVER_VPD "Lin64 6.08      "
  66#else
  67#define IBMASM_DRIVER_VPD "Lin32 6.08      "
  68#endif
  69
  70#define SYSTEM_STATE_OS_UP      5
  71#define SYSTEM_STATE_OS_DOWN    4
  72
  73#define IBMASM_NAME_SIZE        16
  74
  75#define IBMASM_NUM_EVENTS       10
  76#define IBMASM_EVENT_MAX_SIZE   2048u
  77
  78
  79struct command {
  80        struct list_head        queue_node;
  81        wait_queue_head_t       wait;
  82        unsigned char           *buffer;
  83        size_t                  buffer_size;
  84        int                     status;
  85        struct kref             kref;
  86        spinlock_t              *lock;
  87};
  88#define to_command(c) container_of(c, struct command, kref)
  89
  90void ibmasm_free_command(struct kref *kref);
  91static inline void command_put(struct command *cmd)
  92{
  93        unsigned long flags;
  94        spinlock_t *lock = cmd->lock;
  95
  96        spin_lock_irqsave(lock, flags);
  97        kref_put(&cmd->kref, ibmasm_free_command);
  98        spin_unlock_irqrestore(lock, flags);
  99}
 100
 101static inline void command_get(struct command *cmd)
 102{
 103        kref_get(&cmd->kref);
 104}
 105
 106
 107struct ibmasm_event {
 108        unsigned int    serial_number;
 109        unsigned int    data_size;
 110        unsigned char   data[IBMASM_EVENT_MAX_SIZE];
 111};
 112
 113struct event_buffer {
 114        struct ibmasm_event     events[IBMASM_NUM_EVENTS];
 115        unsigned int            next_serial_number;
 116        unsigned int            next_index;
 117        struct list_head        readers;
 118};
 119
 120struct event_reader {
 121        int                     cancelled;
 122        unsigned int            next_serial_number;
 123        wait_queue_head_t       wait;
 124        struct list_head        node;
 125        unsigned int            data_size;
 126        unsigned char           data[IBMASM_EVENT_MAX_SIZE];
 127};
 128
 129struct reverse_heartbeat {
 130        wait_queue_head_t       wait;
 131        unsigned int            stopped;
 132};
 133
 134struct ibmasm_remote {
 135        struct input_dev *keybd_dev;
 136        struct input_dev *mouse_dev;
 137};
 138
 139struct service_processor {
 140        struct list_head        node;
 141        spinlock_t              lock;
 142        void __iomem            *base_address;
 143        unsigned int            irq;
 144        struct command          *current_command;
 145        struct command          *heartbeat;
 146        struct list_head        command_queue;
 147        struct event_buffer     *event_buffer;
 148        char                    dirname[IBMASM_NAME_SIZE];
 149        char                    devname[IBMASM_NAME_SIZE];
 150        unsigned int            number;
 151        struct ibmasm_remote    remote;
 152        int                     serial_line;
 153        struct device           *dev;
 154};
 155
 156/* command processing */
 157struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size);
 158void ibmasm_exec_command(struct service_processor *sp, struct command *cmd);
 159void ibmasm_wait_for_response(struct command *cmd, int timeout);
 160void ibmasm_receive_command_response(struct service_processor *sp, void *response,  size_t size);
 161
 162/* event processing */
 163int ibmasm_event_buffer_init(struct service_processor *sp);
 164void ibmasm_event_buffer_exit(struct service_processor *sp);
 165void ibmasm_receive_event(struct service_processor *sp, void *data,  unsigned int data_size);
 166void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader);
 167void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader);
 168int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader);
 169void ibmasm_cancel_next_event(struct event_reader *reader);
 170
 171/* heartbeat - from SP to OS */
 172void ibmasm_register_panic_notifier(void);
 173void ibmasm_unregister_panic_notifier(void);
 174int ibmasm_heartbeat_init(struct service_processor *sp);
 175void ibmasm_heartbeat_exit(struct service_processor *sp);
 176void ibmasm_receive_heartbeat(struct service_processor *sp,  void *message, size_t size);
 177
 178/* reverse heartbeat - from OS to SP */
 179void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb);
 180int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb);
 181void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb);
 182
 183/* dot commands */
 184void ibmasm_receive_message(struct service_processor *sp, void *data, int data_size);
 185int ibmasm_send_driver_vpd(struct service_processor *sp);
 186int ibmasm_send_os_state(struct service_processor *sp, int os_state);
 187
 188/* low level message processing */
 189int ibmasm_send_i2o_message(struct service_processor *sp);
 190irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id);
 191
 192/* remote console */
 193void ibmasm_handle_mouse_interrupt(struct service_processor *sp);
 194int ibmasm_init_remote_input_dev(struct service_processor *sp);
 195void ibmasm_free_remote_input_dev(struct service_processor *sp);
 196
 197/* file system */
 198int ibmasmfs_register(void);
 199void ibmasmfs_unregister(void);
 200void ibmasmfs_add_sp(struct service_processor *sp);
 201
 202/* uart */
 203#if IS_ENABLED(CONFIG_SERIAL_8250)
 204void ibmasm_register_uart(struct service_processor *sp);
 205void ibmasm_unregister_uart(struct service_processor *sp);
 206#else
 207#define ibmasm_register_uart(sp)        do { } while(0)
 208#define ibmasm_unregister_uart(sp)      do { } while(0)
 209#endif
 210