1 2 /* 3 * IBM ASM Service Processor Device Driver 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 * 19 * Copyright (C) IBM Corporation, 2004 20 * 21 * Author: Max Asb�ck <amax@us.ibm.com> 22 * 23 */ 24 25 #include <linux/kernel.h> 26 #include <linux/types.h> 27 #include <linux/errno.h> 28 #include <linux/list.h> 29 #include <linux/wait.h> 30 #include <linux/spinlock.h> 31 #include <linux/slab.h> 32 #include <linux/config.h> 33 #include <linux/module.h> 34 #include <linux/version.h> 35 #include <linux/interrupt.h> 36 #include <linux/device.h> 37 38 /* Driver identification */ 39 #define DRIVER_NAME "ibmasm" 40 #define DRIVER_VERSION "0.4" 41 #define DRIVER_AUTHOR "Max Asbock" 42 #define DRIVER_DESC "IBM ASM Service Processor Driver" 43 44 #define err(msg) printk(KERN_ERR "%s: " msg "\n", DRIVER_NAME) 45 #define info(msg) printk(KERN_INFO "%s: " msg "\n", DRIVER_NAME) 46 47 48 #define IBMASM_CMD_PENDING 0 49 #define IBMASM_CMD_COMPLETE 1 50 #define IBMASM_CMD_FAILED 2 51 52 #define IBMASM_CMD_TIMEOUT_NORMAL 45 53 #define IBMASM_CMD_TIMEOUT_EXTRA 240 54 55 #define IBMASM_CMD_MAX_BUFFER_SIZE 0x4000 56 57 #define REVERSE_HEARTBEAT_TIMEOUT 120 58 59 #define HEARTBEAT_BUFFER_SIZE 0x400 60 61 #ifdef IA64 62 #define IBMASM_DRIVER_VPD "Lin64 6.08 " 63 #else 64 #define IBMASM_DRIVER_VPD "Lin32 6.08 " 65 #endif 66 67 #define SYSTEM_STATE_OS_UP 5 68 #define SYSTEM_STATE_OS_DOWN 4 69 70 #define IBMASM_NAME_SIZE 16 71 72 #define IBMASM_NUM_EVENTS 10 73 #define IBMASM_EVENT_MAX_SIZE 2048u 74 75 76 struct command { 77 struct list_head queue_node; 78 wait_queue_head_t wait; 79 unsigned char *buffer; 80 size_t buffer_size; 81 int status; 82 struct kobject kobj; 83 }; 84 #define to_command(c) container_of(c, struct command, kobj) 85 86 static inline void command_put(struct command *cmd) 87 { 88 kobject_put(&cmd->kobj); 89 } 90 91 static inline void command_get(struct command *cmd) 92 { 93 kobject_get(&cmd->kobj); 94 } 95 96 97 struct ibmasm_event { 98 unsigned int serial_number; 99 unsigned int data_size; 100 unsigned char data[IBMASM_EVENT_MAX_SIZE]; 101 }; 102 103 struct event_buffer { 104 struct ibmasm_event events[IBMASM_NUM_EVENTS]; 105 unsigned int next_serial_number; 106 unsigned int next_index; 107 struct list_head readers; 108 }; 109 110 struct event_reader { 111 unsigned int next_serial_number; 112 wait_queue_head_t wait; 113 struct list_head node; 114 unsigned int data_size; 115 unsigned char data[IBMASM_EVENT_MAX_SIZE]; 116 }; 117 118 struct reverse_heartbeat { 119 wait_queue_head_t wait; 120 unsigned int stopped; 121 }; 122 123 124 /* remote console events */ 125 struct mouse_event { 126 long x; 127 long y; 128 unsigned char buttons; 129 unsigned char transitions; 130 }; 131 132 struct keyboard_event { 133 unsigned long key_code; 134 unsigned char key_down; 135 }; 136 137 struct remote_event { 138 unsigned long type; 139 union { 140 struct mouse_event mouse; 141 struct keyboard_event keyboard; 142 } data; 143 }; 144 145 #define DRIVER_REMOTE_QUEUE_SIZE 240 146 147 struct remote_queue { 148 struct remote_event *start; 149 struct remote_event *end; 150 struct remote_event *reader; 151 struct remote_event *writer; 152 unsigned int size; 153 int open; 154 wait_queue_head_t wait; 155 }; 156 157 158 struct service_processor { 159 struct list_head node; 160 spinlock_t lock; 161 void __iomem *base_address; 162 unsigned int irq; 163 struct command *current_command; 164 struct command *heartbeat; 165 struct list_head command_queue; 166 struct event_buffer *event_buffer; 167 char dirname[IBMASM_NAME_SIZE]; 168 char devname[IBMASM_NAME_SIZE]; 169 unsigned int number; 170 struct remote_queue remote_queue; 171 int serial_line; 172 struct device *dev; 173 }; 174 175 /* command processing */ 176 extern struct command *ibmasm_new_command(size_t buffer_size); 177 extern void ibmasm_exec_command(struct service_processor *sp, struct command *cmd); 178 extern void ibmasm_wait_for_response(struct command *cmd, int timeout); 179 extern void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size); 180 181 /* event processing */ 182 extern int ibmasm_event_buffer_init(struct service_processor *sp); 183 extern void ibmasm_event_buffer_exit(struct service_processor *sp); 184 extern void ibmasm_receive_event(struct service_processor *sp, void *data, unsigned int data_size); 185 extern void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader); 186 extern void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader); 187 extern int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader); 188 189 /* heartbeat - from SP to OS */ 190 extern void ibmasm_register_panic_notifier(void); 191 extern void ibmasm_unregister_panic_notifier(void); 192 extern int ibmasm_heartbeat_init(struct service_processor *sp); 193 extern void ibmasm_heartbeat_exit(struct service_processor *sp); 194 extern void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size_t size); 195 196 /* reverse heartbeat - from OS to SP */ 197 extern void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb); 198 extern int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb); 199 extern void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb); 200 201 /* dot commands */ 202 extern void ibmasm_receive_message(struct service_processor *sp, void *data, int data_size); 203 extern int ibmasm_send_driver_vpd(struct service_processor *sp); 204 extern int ibmasm_send_os_state(struct service_processor *sp, int os_state); 205 206 /* low level message processing */ 207 extern int ibmasm_send_i2o_message(struct service_processor *sp); 208 extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs); 209 210 /* remote console */ 211 extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp); 212 extern int ibmasm_init_remote_queue(struct service_processor *sp); 213 extern void ibmasm_free_remote_queue(struct service_processor *sp); 214 extern void ibmasm_advance_reader(struct remote_queue *q, unsigned int n); 215 extern size_t ibmasm_events_available(struct remote_queue *q); 216 217 /* file system */ 218 extern int ibmasmfs_register(void); 219 extern void ibmasmfs_unregister(void); 220 extern void ibmasmfs_add_sp(struct service_processor *sp); 221 222 /* uart */ 223 #ifdef CONFIG_SERIAL_8250 224 extern void ibmasm_register_uart(struct service_processor *sp); 225 extern void ibmasm_unregister_uart(struct service_processor *sp); 226 #else 227 #define ibmasm_register_uart(sp) do { } while(0) 228 #define ibmasm_unregister_uart(sp) do { } while(0) 229 #endif 230