aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/ibmasm/command.c30
-rw-r--r--drivers/misc/ibmasm/dot_command.c10
-rw-r--r--drivers/misc/ibmasm/event.c18
-rw-r--r--drivers/misc/ibmasm/heartbeat.c13
-rw-r--r--drivers/misc/ibmasm/ibmasm.h76
-rw-r--r--drivers/misc/ibmasm/ibmasmfs.c125
-rw-r--r--drivers/misc/ibmasm/lowlevel.c18
-rw-r--r--drivers/misc/ibmasm/module.c69
-rw-r--r--drivers/misc/ibmasm/r_heartbeat.c2
-rw-r--r--drivers/misc/ibmasm/remote.c304
-rw-r--r--drivers/misc/ibmasm/remote.h173
11 files changed, 541 insertions, 297 deletions
diff --git a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c
index 245b0058381d..07a085ccbd5b 100644
--- a/drivers/misc/ibmasm/command.c
+++ b/drivers/misc/ibmasm/command.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include "ibmasm.h" 25#include "ibmasm.h"
26#include "lowlevel.h"
26 27
27static void exec_next_command(struct service_processor *sp); 28static void exec_next_command(struct service_processor *sp);
28static void free_command(struct kobject *kobj); 29static void free_command(struct kobject *kobj);
@@ -31,8 +32,9 @@ static struct kobj_type ibmasm_cmd_kobj_type = {
31 .release = free_command, 32 .release = free_command,
32}; 33};
33 34
35static atomic_t command_count = ATOMIC_INIT(0);
34 36
35struct command *ibmasm_new_command(size_t buffer_size) 37struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size)
36{ 38{
37 struct command *cmd; 39 struct command *cmd;
38 40
@@ -55,11 +57,15 @@ struct command *ibmasm_new_command(size_t buffer_size)
55 57
56 kobject_init(&cmd->kobj); 58 kobject_init(&cmd->kobj);
57 cmd->kobj.ktype = &ibmasm_cmd_kobj_type; 59 cmd->kobj.ktype = &ibmasm_cmd_kobj_type;
60 cmd->lock = &sp->lock;
58 61
59 cmd->status = IBMASM_CMD_PENDING; 62 cmd->status = IBMASM_CMD_PENDING;
60 init_waitqueue_head(&cmd->wait); 63 init_waitqueue_head(&cmd->wait);
61 INIT_LIST_HEAD(&cmd->queue_node); 64 INIT_LIST_HEAD(&cmd->queue_node);
62 65
66 atomic_inc(&command_count);
67 dbg("command count: %d\n", atomic_read(&command_count));
68
63 return cmd; 69 return cmd;
64} 70}
65 71
@@ -68,6 +74,8 @@ static void free_command(struct kobject *kobj)
68 struct command *cmd = to_command(kobj); 74 struct command *cmd = to_command(kobj);
69 75
70 list_del(&cmd->queue_node); 76 list_del(&cmd->queue_node);
77 atomic_dec(&command_count);
78 dbg("command count: %d\n", atomic_read(&command_count));
71 kfree(cmd->buffer); 79 kfree(cmd->buffer);
72 kfree(cmd); 80 kfree(cmd);
73} 81}
@@ -94,8 +102,14 @@ static struct command *dequeue_command(struct service_processor *sp)
94 102
95static inline void do_exec_command(struct service_processor *sp) 103static inline void do_exec_command(struct service_processor *sp)
96{ 104{
105 char tsbuf[32];
106
107 dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
108
97 if (ibmasm_send_i2o_message(sp)) { 109 if (ibmasm_send_i2o_message(sp)) {
98 sp->current_command->status = IBMASM_CMD_FAILED; 110 sp->current_command->status = IBMASM_CMD_FAILED;
111 wake_up(&sp->current_command->wait);
112 command_put(sp->current_command);
99 exec_next_command(sp); 113 exec_next_command(sp);
100 } 114 }
101} 115}
@@ -111,14 +125,16 @@ static inline void do_exec_command(struct service_processor *sp)
111void ibmasm_exec_command(struct service_processor *sp, struct command *cmd) 125void ibmasm_exec_command(struct service_processor *sp, struct command *cmd)
112{ 126{
113 unsigned long flags; 127 unsigned long flags;
128 char tsbuf[32];
129
130 dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
114 131
115 spin_lock_irqsave(&sp->lock, flags); 132 spin_lock_irqsave(&sp->lock, flags);
116 133
117 if (!sp->current_command) { 134 if (!sp->current_command) {
118 command_get(cmd);
119 sp->current_command = cmd; 135 sp->current_command = cmd;
136 command_get(sp->current_command);
120 spin_unlock_irqrestore(&sp->lock, flags); 137 spin_unlock_irqrestore(&sp->lock, flags);
121
122 do_exec_command(sp); 138 do_exec_command(sp);
123 } else { 139 } else {
124 enqueue_command(sp, cmd); 140 enqueue_command(sp, cmd);
@@ -129,9 +145,9 @@ void ibmasm_exec_command(struct service_processor *sp, struct command *cmd)
129static void exec_next_command(struct service_processor *sp) 145static void exec_next_command(struct service_processor *sp)
130{ 146{
131 unsigned long flags; 147 unsigned long flags;
148 char tsbuf[32];
132 149
133 wake_up(&sp->current_command->wait); 150 dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
134 command_put(sp->current_command);
135 151
136 spin_lock_irqsave(&sp->lock, flags); 152 spin_lock_irqsave(&sp->lock, flags);
137 sp->current_command = dequeue_command(sp); 153 sp->current_command = dequeue_command(sp);
@@ -169,7 +185,9 @@ void ibmasm_receive_command_response(struct service_processor *sp, void *respons
169 if (!sp->current_command) 185 if (!sp->current_command)
170 return; 186 return;
171 187
172 memcpy(cmd->buffer, response, min(size, cmd->buffer_size)); 188 memcpy_fromio(cmd->buffer, response, min(size, cmd->buffer_size));
173 cmd->status = IBMASM_CMD_COMPLETE; 189 cmd->status = IBMASM_CMD_COMPLETE;
190 wake_up(&sp->current_command->wait);
191 command_put(sp->current_command);
174 exec_next_command(sp); 192 exec_next_command(sp);
175} 193}
diff --git a/drivers/misc/ibmasm/dot_command.c b/drivers/misc/ibmasm/dot_command.c
index 478a8d898fc1..13c52f866e2e 100644
--- a/drivers/misc/ibmasm/dot_command.c
+++ b/drivers/misc/ibmasm/dot_command.c
@@ -33,7 +33,13 @@ void ibmasm_receive_message(struct service_processor *sp, void *message, int mes
33 u32 size; 33 u32 size;
34 struct dot_command_header *header = (struct dot_command_header *)message; 34 struct dot_command_header *header = (struct dot_command_header *)message;
35 35
36 if (message_size == 0)
37 return;
38
36 size = get_dot_command_size(message); 39 size = get_dot_command_size(message);
40 if (size == 0)
41 return;
42
37 if (size > message_size) 43 if (size > message_size)
38 size = message_size; 44 size = message_size;
39 45
@@ -67,7 +73,7 @@ int ibmasm_send_driver_vpd(struct service_processor *sp)
67 u8 *vpd_data; 73 u8 *vpd_data;
68 int result = 0; 74 int result = 0;
69 75
70 command = ibmasm_new_command(INIT_BUFFER_SIZE); 76 command = ibmasm_new_command(sp, INIT_BUFFER_SIZE);
71 if (command == NULL) 77 if (command == NULL)
72 return -ENOMEM; 78 return -ENOMEM;
73 79
@@ -121,7 +127,7 @@ int ibmasm_send_os_state(struct service_processor *sp, int os_state)
121 struct os_state_command *os_state_cmd; 127 struct os_state_command *os_state_cmd;
122 int result = 0; 128 int result = 0;
123 129
124 cmd = ibmasm_new_command(sizeof(struct os_state_command)); 130 cmd = ibmasm_new_command(sp, sizeof(struct os_state_command));
125 if (cmd == NULL) 131 if (cmd == NULL)
126 return -ENOMEM; 132 return -ENOMEM;
127 133
diff --git a/drivers/misc/ibmasm/event.c b/drivers/misc/ibmasm/event.c
index e100f34f1587..fe1e819235a4 100644
--- a/drivers/misc/ibmasm/event.c
+++ b/drivers/misc/ibmasm/event.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include "ibmasm.h" 25#include "ibmasm.h"
26#include "lowlevel.h"
26 27
27/* 28/*
28 * ASM service processor event handling routines. 29 * ASM service processor event handling routines.
@@ -34,7 +35,6 @@
34 * circular buffer. 35 * circular buffer.
35 */ 36 */
36 37
37
38static void wake_up_event_readers(struct service_processor *sp) 38static void wake_up_event_readers(struct service_processor *sp)
39{ 39{
40 struct event_reader *reader; 40 struct event_reader *reader;
@@ -63,7 +63,7 @@ void ibmasm_receive_event(struct service_processor *sp, void *data, unsigned int
63 spin_lock_irqsave(&sp->lock, flags); 63 spin_lock_irqsave(&sp->lock, flags);
64 /* copy the event into the next slot in the circular buffer */ 64 /* copy the event into the next slot in the circular buffer */
65 event = &buffer->events[buffer->next_index]; 65 event = &buffer->events[buffer->next_index];
66 memcpy(event->data, data, data_size); 66 memcpy_fromio(event->data, data, data_size);
67 event->data_size = data_size; 67 event->data_size = data_size;
68 event->serial_number = buffer->next_serial_number; 68 event->serial_number = buffer->next_serial_number;
69 69
@@ -93,7 +93,10 @@ int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *rea
93 unsigned int index; 93 unsigned int index;
94 unsigned long flags; 94 unsigned long flags;
95 95
96 if (wait_event_interruptible(reader->wait, event_available(buffer, reader))) 96 reader->cancelled = 0;
97
98 if (wait_event_interruptible(reader->wait,
99 event_available(buffer, reader) || reader->cancelled))
97 return -ERESTARTSYS; 100 return -ERESTARTSYS;
98 101
99 if (!event_available(buffer, reader)) 102 if (!event_available(buffer, reader))
@@ -116,6 +119,12 @@ int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *rea
116 return event->data_size; 119 return event->data_size;
117} 120}
118 121
122void ibmasm_cancel_next_event(struct event_reader *reader)
123{
124 reader->cancelled = 1;
125 wake_up_interruptible(&reader->wait);
126}
127
119void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader) 128void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader)
120{ 129{
121 unsigned long flags; 130 unsigned long flags;
@@ -131,8 +140,6 @@ void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_r
131{ 140{
132 unsigned long flags; 141 unsigned long flags;
133 142
134 wake_up_interruptible(&reader->wait);
135
136 spin_lock_irqsave(&sp->lock, flags); 143 spin_lock_irqsave(&sp->lock, flags);
137 list_del(&reader->node); 144 list_del(&reader->node);
138 spin_unlock_irqrestore(&sp->lock, flags); 145 spin_unlock_irqrestore(&sp->lock, flags);
@@ -164,6 +171,5 @@ int ibmasm_event_buffer_init(struct service_processor *sp)
164 171
165void ibmasm_event_buffer_exit(struct service_processor *sp) 172void ibmasm_event_buffer_exit(struct service_processor *sp)
166{ 173{
167 wake_up_event_readers(sp);
168 kfree(sp->event_buffer); 174 kfree(sp->event_buffer);
169} 175}
diff --git a/drivers/misc/ibmasm/heartbeat.c b/drivers/misc/ibmasm/heartbeat.c
index ce09309174d6..f295401fac21 100644
--- a/drivers/misc/ibmasm/heartbeat.c
+++ b/drivers/misc/ibmasm/heartbeat.c
@@ -25,6 +25,7 @@
25#include <linux/notifier.h> 25#include <linux/notifier.h>
26#include "ibmasm.h" 26#include "ibmasm.h"
27#include "dot_command.h" 27#include "dot_command.h"
28#include "lowlevel.h"
28 29
29static int suspend_heartbeats = 0; 30static int suspend_heartbeats = 0;
30 31
@@ -62,7 +63,7 @@ void ibmasm_unregister_panic_notifier(void)
62 63
63int ibmasm_heartbeat_init(struct service_processor *sp) 64int ibmasm_heartbeat_init(struct service_processor *sp)
64{ 65{
65 sp->heartbeat = ibmasm_new_command(HEARTBEAT_BUFFER_SIZE); 66 sp->heartbeat = ibmasm_new_command(sp, HEARTBEAT_BUFFER_SIZE);
66 if (sp->heartbeat == NULL) 67 if (sp->heartbeat == NULL)
67 return -ENOMEM; 68 return -ENOMEM;
68 69
@@ -71,6 +72,12 @@ int ibmasm_heartbeat_init(struct service_processor *sp)
71 72
72void ibmasm_heartbeat_exit(struct service_processor *sp) 73void ibmasm_heartbeat_exit(struct service_processor *sp)
73{ 74{
75 char tsbuf[32];
76
77 dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
78 ibmasm_wait_for_response(sp->heartbeat, IBMASM_CMD_TIMEOUT_NORMAL);
79 dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
80 suspend_heartbeats = 1;
74 command_put(sp->heartbeat); 81 command_put(sp->heartbeat);
75} 82}
76 83
@@ -78,14 +85,16 @@ void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size
78{ 85{
79 struct command *cmd = sp->heartbeat; 86 struct command *cmd = sp->heartbeat;
80 struct dot_command_header *header = (struct dot_command_header *)cmd->buffer; 87 struct dot_command_header *header = (struct dot_command_header *)cmd->buffer;
88 char tsbuf[32];
81 89
90 dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
82 if (suspend_heartbeats) 91 if (suspend_heartbeats)
83 return; 92 return;
84 93
85 /* return the received dot command to sender */ 94 /* return the received dot command to sender */
86 cmd->status = IBMASM_CMD_PENDING; 95 cmd->status = IBMASM_CMD_PENDING;
87 size = min(size, cmd->buffer_size); 96 size = min(size, cmd->buffer_size);
88 memcpy(cmd->buffer, message, size); 97 memcpy_fromio(cmd->buffer, message, size);
89 header->type = sp_write; 98 header->type = sp_write;
90 ibmasm_exec_command(sp, cmd); 99 ibmasm_exec_command(sp, cmd);
91} 100}
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
index 6fec7fd8cd1a..ecce4ffd3e23 100644
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -34,16 +34,31 @@
34#include <linux/version.h> 34#include <linux/version.h>
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/device.h> 36#include <linux/device.h>
37#include <linux/input.h>
37 38
38/* Driver identification */ 39/* Driver identification */
39#define DRIVER_NAME "ibmasm" 40#define DRIVER_NAME "ibmasm"
40#define DRIVER_VERSION "0.4" 41#define DRIVER_VERSION "1.0"
41#define DRIVER_AUTHOR "Max Asbock" 42#define DRIVER_AUTHOR "Max Asbock <masbock@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"
42#define DRIVER_DESC "IBM ASM Service Processor Driver" 43#define DRIVER_DESC "IBM ASM Service Processor Driver"
43 44
44#define err(msg) printk(KERN_ERR "%s: " msg "\n", DRIVER_NAME) 45#define err(msg) printk(KERN_ERR "%s: " msg "\n", DRIVER_NAME)
45#define info(msg) printk(KERN_INFO "%s: " msg "\n", DRIVER_NAME) 46#define info(msg) printk(KERN_INFO "%s: " msg "\n", DRIVER_NAME)
46 47
48extern int ibmasm_debug;
49#define dbg(STR, ARGS...) \
50 do { \
51 if (ibmasm_debug) \
52 printk(KERN_DEBUG STR , ##ARGS); \
53 } while (0)
54
55static inline char *get_timestamp(char *buf)
56{
57 struct timeval now;
58 do_gettimeofday(&now);
59 sprintf(buf, "%lu.%lu", now.tv_sec, now.tv_usec);
60 return buf;
61}
47 62
48#define IBMASM_CMD_PENDING 0 63#define IBMASM_CMD_PENDING 0
49#define IBMASM_CMD_COMPLETE 1 64#define IBMASM_CMD_COMPLETE 1
@@ -52,7 +67,7 @@
52#define IBMASM_CMD_TIMEOUT_NORMAL 45 67#define IBMASM_CMD_TIMEOUT_NORMAL 45
53#define IBMASM_CMD_TIMEOUT_EXTRA 240 68#define IBMASM_CMD_TIMEOUT_EXTRA 240
54 69
55#define IBMASM_CMD_MAX_BUFFER_SIZE 0x4000 70#define IBMASM_CMD_MAX_BUFFER_SIZE 0x8000
56 71
57#define REVERSE_HEARTBEAT_TIMEOUT 120 72#define REVERSE_HEARTBEAT_TIMEOUT 120
58 73
@@ -80,12 +95,17 @@ struct command {
80 size_t buffer_size; 95 size_t buffer_size;
81 int status; 96 int status;
82 struct kobject kobj; 97 struct kobject kobj;
98 spinlock_t *lock;
83}; 99};
84#define to_command(c) container_of(c, struct command, kobj) 100#define to_command(c) container_of(c, struct command, kobj)
85 101
86static inline void command_put(struct command *cmd) 102static inline void command_put(struct command *cmd)
87{ 103{
104 unsigned long flags;
105
106 spin_lock_irqsave(cmd->lock, flags);
88 kobject_put(&cmd->kobj); 107 kobject_put(&cmd->kobj);
108 spin_unlock_irqrestore(cmd->lock, flags);
89} 109}
90 110
91static inline void command_get(struct command *cmd) 111static inline void command_get(struct command *cmd)
@@ -108,6 +128,7 @@ struct event_buffer {
108}; 128};
109 129
110struct event_reader { 130struct event_reader {
131 int cancelled;
111 unsigned int next_serial_number; 132 unsigned int next_serial_number;
112 wait_queue_head_t wait; 133 wait_queue_head_t wait;
113 struct list_head node; 134 struct list_head node;
@@ -120,41 +141,11 @@ struct reverse_heartbeat {
120 unsigned int stopped; 141 unsigned int stopped;
121}; 142};
122 143
123 144struct ibmasm_remote {
124/* remote console events */ 145 struct input_dev keybd_dev;
125struct mouse_event { 146 struct input_dev mouse_dev;
126 long x;
127 long y;
128 unsigned char buttons;
129 unsigned char transitions;
130};
131
132struct keyboard_event {
133 unsigned long key_code;
134 unsigned char key_down;
135}; 147};
136 148
137struct 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
147struct 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
158struct service_processor { 149struct service_processor {
159 struct list_head node; 150 struct list_head node;
160 spinlock_t lock; 151 spinlock_t lock;
@@ -167,13 +158,13 @@ struct service_processor {
167 char dirname[IBMASM_NAME_SIZE]; 158 char dirname[IBMASM_NAME_SIZE];
168 char devname[IBMASM_NAME_SIZE]; 159 char devname[IBMASM_NAME_SIZE];
169 unsigned int number; 160 unsigned int number;
170 struct remote_queue remote_queue; 161 struct ibmasm_remote *remote;
171 int serial_line; 162 int serial_line;
172 struct device *dev; 163 struct device *dev;
173}; 164};
174 165
175/* command processing */ 166/* command processing */
176extern struct command *ibmasm_new_command(size_t buffer_size); 167extern struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size);
177extern void ibmasm_exec_command(struct service_processor *sp, struct command *cmd); 168extern void ibmasm_exec_command(struct service_processor *sp, struct command *cmd);
178extern void ibmasm_wait_for_response(struct command *cmd, int timeout); 169extern void ibmasm_wait_for_response(struct command *cmd, int timeout);
179extern void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size); 170extern void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size);
@@ -185,6 +176,7 @@ extern void ibmasm_receive_event(struct service_processor *sp, void *data, unsi
185extern void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader); 176extern void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader);
186extern void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader); 177extern void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader);
187extern int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader); 178extern int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader);
179extern void ibmasm_cancel_next_event(struct event_reader *reader);
188 180
189/* heartbeat - from SP to OS */ 181/* heartbeat - from SP to OS */
190extern void ibmasm_register_panic_notifier(void); 182extern void ibmasm_register_panic_notifier(void);
@@ -208,11 +200,9 @@ extern int ibmasm_send_i2o_message(struct service_processor *sp);
208extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs); 200extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs);
209 201
210/* remote console */ 202/* remote console */
211extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp); 203extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp, struct pt_regs *regs);
212extern int ibmasm_init_remote_queue(struct service_processor *sp); 204extern int ibmasm_init_remote_input_dev(struct service_processor *sp);
213extern void ibmasm_free_remote_queue(struct service_processor *sp); 205extern void ibmasm_free_remote_input_dev(struct service_processor *sp);
214extern void ibmasm_advance_reader(struct remote_queue *q, unsigned int n);
215extern size_t ibmasm_events_available(struct remote_queue *q);
216 206
217/* file system */ 207/* file system */
218extern int ibmasmfs_register(void); 208extern int ibmasmfs_register(void);
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
index 866e867e68f2..5c550fcac2c4 100644
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -37,9 +37,7 @@
37 * | |-- event 37 * | |-- event
38 * | |-- reverse_heartbeat 38 * | |-- reverse_heartbeat
39 * | `-- remote_video 39 * | `-- remote_video
40 * | |-- connected
41 * | |-- depth 40 * | |-- depth
42 * | |-- events
43 * | |-- height 41 * | |-- height
44 * | `-- width 42 * | `-- width
45 * . 43 * .
@@ -50,9 +48,7 @@
50 * |-- event 48 * |-- event
51 * |-- reverse_heartbeat 49 * |-- reverse_heartbeat
52 * `-- remote_video 50 * `-- remote_video
53 * |-- connected
54 * |-- depth 51 * |-- depth
55 * |-- events
56 * |-- height 52 * |-- height
57 * `-- width 53 * `-- width
58 * 54 *
@@ -75,14 +71,6 @@
75 * remote_video/width: control remote display settings 71 * remote_video/width: control remote display settings
76 * write: set value 72 * write: set value
77 * read: read value 73 * read: read value
78 *
79 * remote_video/connected
80 * read: return "1" if web browser VNC java applet is connected,
81 * "0" otherwise
82 *
83 * remote_video/events
84 * read: sleep until a remote mouse or keyboard event occurs, then return
85 * then event.
86 */ 74 */
87 75
88#include <linux/fs.h> 76#include <linux/fs.h>
@@ -333,7 +321,7 @@ static ssize_t command_file_write(struct file *file, const char __user *ubuff, s
333 if (command_data->command) 321 if (command_data->command)
334 return -EAGAIN; 322 return -EAGAIN;
335 323
336 cmd = ibmasm_new_command(count); 324 cmd = ibmasm_new_command(command_data->sp, count);
337 if (!cmd) 325 if (!cmd)
338 return -ENOMEM; 326 return -ENOMEM;
339 327
@@ -374,6 +362,7 @@ static int event_file_open(struct inode *inode, struct file *file)
374 ibmasm_event_reader_register(sp, &event_data->reader); 362 ibmasm_event_reader_register(sp, &event_data->reader);
375 363
376 event_data->sp = sp; 364 event_data->sp = sp;
365 event_data->active = 0;
377 file->private_data = event_data; 366 file->private_data = event_data;
378 return 0; 367 return 0;
379} 368}
@@ -391,7 +380,9 @@ static ssize_t event_file_read(struct file *file, char __user *buf, size_t count
391{ 380{
392 struct ibmasmfs_event_data *event_data = file->private_data; 381 struct ibmasmfs_event_data *event_data = file->private_data;
393 struct event_reader *reader = &event_data->reader; 382 struct event_reader *reader = &event_data->reader;
383 struct service_processor *sp = event_data->sp;
394 int ret; 384 int ret;
385 unsigned long flags;
395 386
396 if (*offset < 0) 387 if (*offset < 0)
397 return -EINVAL; 388 return -EINVAL;
@@ -400,17 +391,32 @@ static ssize_t event_file_read(struct file *file, char __user *buf, size_t count
400 if (*offset != 0) 391 if (*offset != 0)
401 return 0; 392 return 0;
402 393
403 ret = ibmasm_get_next_event(event_data->sp, reader); 394 spin_lock_irqsave(&sp->lock, flags);
395 if (event_data->active) {
396 spin_unlock_irqrestore(&sp->lock, flags);
397 return -EBUSY;
398 }
399 event_data->active = 1;
400 spin_unlock_irqrestore(&sp->lock, flags);
401
402 ret = ibmasm_get_next_event(sp, reader);
404 if (ret <= 0) 403 if (ret <= 0)
405 return ret; 404 goto out;
406 405
407 if (count < reader->data_size) 406 if (count < reader->data_size) {
408 return -EINVAL; 407 ret = -EINVAL;
408 goto out;
409 }
409 410
410 if (copy_to_user(buf, reader->data, reader->data_size)) 411 if (copy_to_user(buf, reader->data, reader->data_size)) {
411 return -EFAULT; 412 ret = -EFAULT;
413 goto out;
414 }
415 ret = reader->data_size;
412 416
413 return reader->data_size; 417out:
418 event_data->active = 0;
419 return ret;
414} 420}
415 421
416static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) 422static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
@@ -424,7 +430,7 @@ static ssize_t event_file_write(struct file *file, const char __user *buf, size_
424 if (*offset != 0) 430 if (*offset != 0)
425 return 0; 431 return 0;
426 432
427 wake_up_interruptible(&event_data->reader.wait); 433 ibmasm_cancel_next_event(&event_data->reader);
428 return 0; 434 return 0;
429} 435}
430 436
@@ -575,75 +581,6 @@ static ssize_t remote_settings_file_write(struct file *file, const char __user *
575 return count; 581 return count;
576} 582}
577 583
578static int remote_event_file_open(struct inode *inode, struct file *file)
579{
580 struct service_processor *sp;
581 unsigned long flags;
582 struct remote_queue *q;
583
584 file->private_data = inode->u.generic_ip;
585 sp = file->private_data;
586 q = &sp->remote_queue;
587
588 /* allow only one event reader */
589 spin_lock_irqsave(&sp->lock, flags);
590 if (q->open) {
591 spin_unlock_irqrestore(&sp->lock, flags);
592 return -EBUSY;
593 }
594 q->open = 1;
595 spin_unlock_irqrestore(&sp->lock, flags);
596
597 enable_mouse_interrupts(sp);
598
599 return 0;
600}
601
602static int remote_event_file_close(struct inode *inode, struct file *file)
603{
604 struct service_processor *sp = file->private_data;
605
606 disable_mouse_interrupts(sp);
607 wake_up_interruptible(&sp->remote_queue.wait);
608 sp->remote_queue.open = 0;
609
610 return 0;
611}
612
613static ssize_t remote_event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
614{
615 struct service_processor *sp = file->private_data;
616 struct remote_queue *q = &sp->remote_queue;
617 size_t data_size;
618 struct remote_event *reader = q->reader;
619 size_t num_events;
620
621 if (*offset < 0)
622 return -EINVAL;
623 if (count == 0 || count > 1024)
624 return 0;
625 if (*offset != 0)
626 return 0;
627
628 if (wait_event_interruptible(q->wait, q->reader != q->writer))
629 return -ERESTARTSYS;
630
631 /* only get multiples of struct remote_event */
632 num_events = min((count/sizeof(struct remote_event)), ibmasm_events_available(q));
633 if (!num_events)
634 return 0;
635
636 data_size = num_events * sizeof(struct remote_event);
637
638 if (copy_to_user(buf, reader, data_size))
639 return -EFAULT;
640
641 ibmasm_advance_reader(q, num_events);
642
643 return data_size;
644}
645
646
647static struct file_operations command_fops = { 584static struct file_operations command_fops = {
648 .open = command_file_open, 585 .open = command_file_open,
649 .release = command_file_close, 586 .release = command_file_close,
@@ -672,12 +609,6 @@ static struct file_operations remote_settings_fops = {
672 .write = remote_settings_file_write, 609 .write = remote_settings_file_write,
673}; 610};
674 611
675static struct file_operations remote_event_fops = {
676 .open = remote_event_file_open,
677 .release = remote_event_file_close,
678 .read = remote_event_file_read,
679};
680
681 612
682static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root) 613static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
683{ 614{
@@ -703,7 +634,5 @@ static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
703 ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR); 634 ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR);
704 ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR); 635 ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR);
705 ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR); 636 ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR);
706 ibmasmfs_create_file(sb, remote_dir, "connected", &remote_settings_fops, (void *)vnc_status(sp), S_IRUSR);
707 ibmasmfs_create_file(sb, remote_dir, "events", &remote_event_fops, (void *)sp, S_IRUSR);
708 } 637 }
709} 638}
diff --git a/drivers/misc/ibmasm/lowlevel.c b/drivers/misc/ibmasm/lowlevel.c
index 5156de2759d8..47949a2c7e94 100644
--- a/drivers/misc/ibmasm/lowlevel.c
+++ b/drivers/misc/ibmasm/lowlevel.c
@@ -46,8 +46,8 @@ int ibmasm_send_i2o_message(struct service_processor *sp)
46 46
47 message = get_i2o_message(sp->base_address, mfa); 47 message = get_i2o_message(sp->base_address, mfa);
48 48
49 memcpy(&message->header, &header, sizeof(struct i2o_header)); 49 memcpy_toio(&message->header, &header, sizeof(struct i2o_header));
50 memcpy(&message->data, command->buffer, command_size); 50 memcpy_toio(&message->data, command->buffer, command_size);
51 51
52 set_mfa_inbound(sp->base_address, mfa); 52 set_mfa_inbound(sp->base_address, mfa);
53 53
@@ -59,23 +59,27 @@ irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *reg
59 u32 mfa; 59 u32 mfa;
60 struct service_processor *sp = (struct service_processor *)dev_id; 60 struct service_processor *sp = (struct service_processor *)dev_id;
61 void __iomem *base_address = sp->base_address; 61 void __iomem *base_address = sp->base_address;
62 char tsbuf[32];
62 63
63 if (!sp_interrupt_pending(base_address)) 64 if (!sp_interrupt_pending(base_address))
64 return IRQ_NONE; 65 return IRQ_NONE;
65 66
67 dbg("respond to interrupt at %s\n", get_timestamp(tsbuf));
68
66 if (mouse_interrupt_pending(sp)) { 69 if (mouse_interrupt_pending(sp)) {
67 ibmasm_handle_mouse_interrupt(sp); 70 ibmasm_handle_mouse_interrupt(sp, regs);
68 mfa = get_mfa_outbound(base_address);
69 clear_mouse_interrupt(sp); 71 clear_mouse_interrupt(sp);
70 set_mfa_outbound(base_address, mfa);
71 return IRQ_HANDLED;
72 } 72 }
73 73
74 mfa = get_mfa_outbound(base_address); 74 mfa = get_mfa_outbound(base_address);
75 if (valid_mfa(mfa)) { 75 if (valid_mfa(mfa)) {
76 struct i2o_message *msg = get_i2o_message(base_address, mfa); 76 struct i2o_message *msg = get_i2o_message(base_address, mfa);
77 ibmasm_receive_message(sp, &msg->data, incoming_data_size(msg)); 77 ibmasm_receive_message(sp, &msg->data, incoming_data_size(msg));
78 } 78 } else
79 dbg("didn't get a valid MFA\n");
80
79 set_mfa_outbound(base_address, mfa); 81 set_mfa_outbound(base_address, mfa);
82 dbg("finished interrupt at %s\n", get_timestamp(tsbuf));
83
80 return IRQ_HANDLED; 84 return IRQ_HANDLED;
81} 85}
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
index 777432ae764a..1fdf03fd2da7 100644
--- a/drivers/misc/ibmasm/module.c
+++ b/drivers/misc/ibmasm/module.c
@@ -56,17 +56,26 @@
56#include "lowlevel.h" 56#include "lowlevel.h"
57#include "remote.h" 57#include "remote.h"
58 58
59int ibmasm_debug = 0;
60module_param(ibmasm_debug, int , S_IRUGO | S_IWUSR);
61MODULE_PARM_DESC(ibmasm_debug, " Set debug mode on or off");
62
59 63
60static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) 64static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
61{ 65{
62 int err, result = -ENOMEM; 66 int result;
63 struct service_processor *sp; 67 struct service_processor *sp;
64 68
65 if ((err = pci_enable_device(pdev))) { 69 if ((result = pci_enable_device(pdev))) {
66 printk(KERN_ERR "%s: can't enable PCI device at %s\n", 70 dev_err(&pdev->dev, "Failed to enable PCI device\n");
67 DRIVER_NAME, pci_name(pdev)); 71 return result;
68 return err;
69 } 72 }
73 if ((result = pci_request_regions(pdev, DRIVER_NAME))) {
74 dev_err(&pdev->dev, "Failed to allocate PCI resources\n");
75 goto error_resources;
76 }
77 /* vnc client won't work without bus-mastering */
78 pci_set_master(pdev);
70 79
71 sp = kmalloc(sizeof(struct service_processor), GFP_KERNEL); 80 sp = kmalloc(sizeof(struct service_processor), GFP_KERNEL);
72 if (sp == NULL) { 81 if (sp == NULL) {
@@ -76,6 +85,9 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi
76 } 85 }
77 memset(sp, 0, sizeof(struct service_processor)); 86 memset(sp, 0, sizeof(struct service_processor));
78 87
88 sp->lock = SPIN_LOCK_UNLOCKED;
89 INIT_LIST_HEAD(&sp->command_queue);
90
79 pci_set_drvdata(pdev, (void *)sp); 91 pci_set_drvdata(pdev, (void *)sp);
80 sp->dev = &pdev->dev; 92 sp->dev = &pdev->dev;
81 sp->number = pdev->bus->number; 93 sp->number = pdev->bus->number;
@@ -101,15 +113,6 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi
101 goto error_ioremap; 113 goto error_ioremap;
102 } 114 }
103 115
104 result = ibmasm_init_remote_queue(sp);
105 if (result) {
106 dev_err(sp->dev, "Failed to initialize remote queue\n");
107 goto error_remote_queue;
108 }
109
110 spin_lock_init(&sp->lock);
111 INIT_LIST_HEAD(&sp->command_queue);
112
113 result = request_irq(sp->irq, ibmasm_interrupt_handler, SA_SHIRQ, sp->devname, (void*)sp); 116 result = request_irq(sp->irq, ibmasm_interrupt_handler, SA_SHIRQ, sp->devname, (void*)sp);
114 if (result) { 117 if (result) {
115 dev_err(sp->dev, "Failed to register interrupt handler\n"); 118 dev_err(sp->dev, "Failed to register interrupt handler\n");
@@ -117,7 +120,12 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi
117 } 120 }
118 121
119 enable_sp_interrupts(sp->base_address); 122 enable_sp_interrupts(sp->base_address);
120 disable_mouse_interrupts(sp); 123
124 result = ibmasm_init_remote_input_dev(sp);
125 if (result) {
126 dev_err(sp->dev, "Failed to initialize remote queue\n");
127 goto error_send_message;
128 }
121 129
122 result = ibmasm_send_driver_vpd(sp); 130 result = ibmasm_send_driver_vpd(sp);
123 if (result) { 131 if (result) {
@@ -133,30 +141,25 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi
133 141
134 ibmasm_register_uart(sp); 142 ibmasm_register_uart(sp);
135 143
136 dev_printk(KERN_DEBUG, &pdev->dev, "WARNING: This software may not be supported or function\n");
137 dev_printk(KERN_DEBUG, &pdev->dev, "correctly on your IBM server. Please consult the IBM\n");
138 dev_printk(KERN_DEBUG, &pdev->dev, "ServerProven website\n");
139 dev_printk(KERN_DEBUG, &pdev->dev, "http://www.pc.ibm.com/ww/eserver/xseries/serverproven\n");
140 dev_printk(KERN_DEBUG, &pdev->dev, "for information on the specific driver level and support\n");
141 dev_printk(KERN_DEBUG, &pdev->dev, "statement for your IBM server.\n");
142
143 return 0; 144 return 0;
144 145
145error_send_message: 146error_send_message:
146 disable_sp_interrupts(sp->base_address); 147 disable_sp_interrupts(sp->base_address);
148 ibmasm_free_remote_input_dev(sp);
147 free_irq(sp->irq, (void *)sp); 149 free_irq(sp->irq, (void *)sp);
148error_request_irq: 150error_request_irq:
149 ibmasm_free_remote_queue(sp);
150error_remote_queue:
151 iounmap(sp->base_address); 151 iounmap(sp->base_address);
152error_ioremap: 152error_ioremap:
153 ibmasm_heartbeat_exit(sp); 153 ibmasm_heartbeat_exit(sp);
154error_heartbeat: 154error_heartbeat:
155 ibmasm_event_buffer_exit(sp); 155 ibmasm_event_buffer_exit(sp);
156error_eventbuffer: 156error_eventbuffer:
157 pci_set_drvdata(pdev, NULL);
157 kfree(sp); 158 kfree(sp);
158error_kmalloc: 159error_kmalloc:
159 pci_disable_device(pdev); 160 pci_release_regions(pdev);
161error_resources:
162 pci_disable_device(pdev);
160 163
161 return result; 164 return result;
162} 165}
@@ -165,16 +168,24 @@ static void __devexit ibmasm_remove_one(struct pci_dev *pdev)
165{ 168{
166 struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev); 169 struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev);
167 170
171 dbg("Unregistering UART\n");
168 ibmasm_unregister_uart(sp); 172 ibmasm_unregister_uart(sp);
169 ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN); 173 dbg("Sending OS down message\n");
174 if (ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN))
175 err("failed to get repsonse to 'Send OS State' command\n");
176 dbg("Disabling heartbeats\n");
177 ibmasm_heartbeat_exit(sp);
178 dbg("Disabling interrupts\n");
170 disable_sp_interrupts(sp->base_address); 179 disable_sp_interrupts(sp->base_address);
171 disable_mouse_interrupts(sp); 180 dbg("Freeing SP irq\n");
172 free_irq(sp->irq, (void *)sp); 181 free_irq(sp->irq, (void *)sp);
173 ibmasm_heartbeat_exit(sp); 182 dbg("Cleaning up\n");
174 ibmasm_free_remote_queue(sp); 183 ibmasm_free_remote_input_dev(sp);
175 iounmap(sp->base_address); 184 iounmap(sp->base_address);
176 ibmasm_event_buffer_exit(sp); 185 ibmasm_event_buffer_exit(sp);
186 pci_set_drvdata(pdev, NULL);
177 kfree(sp); 187 kfree(sp);
188 pci_release_regions(pdev);
178 pci_disable_device(pdev); 189 pci_disable_device(pdev);
179} 190}
180 191
diff --git a/drivers/misc/ibmasm/r_heartbeat.c b/drivers/misc/ibmasm/r_heartbeat.c
index 93d9c1b2ad6f..f8fdb2d5417e 100644
--- a/drivers/misc/ibmasm/r_heartbeat.c
+++ b/drivers/misc/ibmasm/r_heartbeat.c
@@ -63,7 +63,7 @@ int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_
63 int times_failed = 0; 63 int times_failed = 0;
64 int result = 1; 64 int result = 1;
65 65
66 cmd = ibmasm_new_command(sizeof rhb_dot_cmd); 66 cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd);
67 if (!cmd) 67 if (!cmd)
68 return -ENOMEM; 68 return -ENOMEM;
69 69
diff --git a/drivers/misc/ibmasm/remote.c b/drivers/misc/ibmasm/remote.c
index 520c3f10c271..d3c48d23ee51 100644
--- a/drivers/misc/ibmasm/remote.c
+++ b/drivers/misc/ibmasm/remote.c
@@ -1,4 +1,3 @@
1
2/* 1/*
3 * IBM ASM Service Processor Device Driver 2 * IBM ASM Service Processor Device Driver
4 * 3 *
@@ -18,135 +17,256 @@
18 * 17 *
19 * Copyright (C) IBM Corporation, 2004 18 * Copyright (C) IBM Corporation, 2004
20 * 19 *
21 * Author: Max Asböck <amax@us.ibm.com> 20 * Authors: Max Asböck <amax@us.ibm.com>
21 * Vernon Mauery <vernux@us.ibm.com>
22 * 22 *
23 */ 23 */
24 24
25/* Remote mouse and keyboard event handling functions */ 25/* Remote mouse and keyboard event handling functions */
26 26
27#include <linux/pci.h>
27#include "ibmasm.h" 28#include "ibmasm.h"
28#include "remote.h" 29#include "remote.h"
29 30
30int ibmasm_init_remote_queue(struct service_processor *sp) 31static int xmax = 1600;
31{ 32static int ymax = 1200;
32 struct remote_queue *q = &sp->remote_queue;
33
34 disable_mouse_interrupts(sp);
35 33
36 q->open = 0;
37 q->size = 0;
38 34
39 q->start = kmalloc(DRIVER_REMOTE_QUEUE_SIZE * sizeof(struct remote_event), GFP_KERNEL); 35static unsigned short xlate_high[XLATE_SIZE] = {
40 if (q->start == 0) 36 [KEY_SYM_ENTER & 0xff] = KEY_ENTER,
41 return -ENOMEM; 37 [KEY_SYM_KPSLASH & 0xff] = KEY_KPSLASH,
38 [KEY_SYM_KPSTAR & 0xff] = KEY_KPASTERISK,
39 [KEY_SYM_KPMINUS & 0xff] = KEY_KPMINUS,
40 [KEY_SYM_KPDOT & 0xff] = KEY_KPDOT,
41 [KEY_SYM_KPPLUS & 0xff] = KEY_KPPLUS,
42 [KEY_SYM_KP0 & 0xff] = KEY_KP0,
43 [KEY_SYM_KP1 & 0xff] = KEY_KP1,
44 [KEY_SYM_KP2 & 0xff] = KEY_KP2, [KEY_SYM_KPDOWN & 0xff] = KEY_KP2,
45 [KEY_SYM_KP3 & 0xff] = KEY_KP3,
46 [KEY_SYM_KP4 & 0xff] = KEY_KP4, [KEY_SYM_KPLEFT & 0xff] = KEY_KP4,
47 [KEY_SYM_KP5 & 0xff] = KEY_KP5,
48 [KEY_SYM_KP6 & 0xff] = KEY_KP6, [KEY_SYM_KPRIGHT & 0xff] = KEY_KP6,
49 [KEY_SYM_KP7 & 0xff] = KEY_KP7,
50 [KEY_SYM_KP8 & 0xff] = KEY_KP8, [KEY_SYM_KPUP & 0xff] = KEY_KP8,
51 [KEY_SYM_KP9 & 0xff] = KEY_KP9,
52 [KEY_SYM_BK_SPC & 0xff] = KEY_BACKSPACE,
53 [KEY_SYM_TAB & 0xff] = KEY_TAB,
54 [KEY_SYM_CTRL & 0xff] = KEY_LEFTCTRL,
55 [KEY_SYM_ALT & 0xff] = KEY_LEFTALT,
56 [KEY_SYM_INSERT & 0xff] = KEY_INSERT,
57 [KEY_SYM_DELETE & 0xff] = KEY_DELETE,
58 [KEY_SYM_SHIFT & 0xff] = KEY_LEFTSHIFT,
59 [KEY_SYM_UARROW & 0xff] = KEY_UP,
60 [KEY_SYM_DARROW & 0xff] = KEY_DOWN,
61 [KEY_SYM_LARROW & 0xff] = KEY_LEFT,
62 [KEY_SYM_RARROW & 0xff] = KEY_RIGHT,
63 [KEY_SYM_ESCAPE & 0xff] = KEY_ESC,
64 [KEY_SYM_PAGEUP & 0xff] = KEY_PAGEUP,
65 [KEY_SYM_PAGEDOWN & 0xff] = KEY_PAGEDOWN,
66 [KEY_SYM_HOME & 0xff] = KEY_HOME,
67 [KEY_SYM_END & 0xff] = KEY_END,
68 [KEY_SYM_F1 & 0xff] = KEY_F1,
69 [KEY_SYM_F2 & 0xff] = KEY_F2,
70 [KEY_SYM_F3 & 0xff] = KEY_F3,
71 [KEY_SYM_F4 & 0xff] = KEY_F4,
72 [KEY_SYM_F5 & 0xff] = KEY_F5,
73 [KEY_SYM_F6 & 0xff] = KEY_F6,
74 [KEY_SYM_F7 & 0xff] = KEY_F7,
75 [KEY_SYM_F8 & 0xff] = KEY_F8,
76 [KEY_SYM_F9 & 0xff] = KEY_F9,
77 [KEY_SYM_F10 & 0xff] = KEY_F10,
78 [KEY_SYM_F11 & 0xff] = KEY_F11,
79 [KEY_SYM_F12 & 0xff] = KEY_F12,
80 [KEY_SYM_CAP_LOCK & 0xff] = KEY_CAPSLOCK,
81 [KEY_SYM_NUM_LOCK & 0xff] = KEY_NUMLOCK,
82 [KEY_SYM_SCR_LOCK & 0xff] = KEY_SCROLLLOCK,
83};
84static unsigned short xlate[XLATE_SIZE] = {
85 [NO_KEYCODE] = KEY_RESERVED,
86 [KEY_SYM_SPACE] = KEY_SPACE,
87 [KEY_SYM_TILDE] = KEY_GRAVE, [KEY_SYM_BKTIC] = KEY_GRAVE,
88 [KEY_SYM_ONE] = KEY_1, [KEY_SYM_BANG] = KEY_1,
89 [KEY_SYM_TWO] = KEY_2, [KEY_SYM_AT] = KEY_2,
90 [KEY_SYM_THREE] = KEY_3, [KEY_SYM_POUND] = KEY_3,
91 [KEY_SYM_FOUR] = KEY_4, [KEY_SYM_DOLLAR] = KEY_4,
92 [KEY_SYM_FIVE] = KEY_5, [KEY_SYM_PERCENT] = KEY_5,
93 [KEY_SYM_SIX] = KEY_6, [KEY_SYM_CARAT] = KEY_6,
94 [KEY_SYM_SEVEN] = KEY_7, [KEY_SYM_AMPER] = KEY_7,
95 [KEY_SYM_EIGHT] = KEY_8, [KEY_SYM_STAR] = KEY_8,
96 [KEY_SYM_NINE] = KEY_9, [KEY_SYM_LPAREN] = KEY_9,
97 [KEY_SYM_ZERO] = KEY_0, [KEY_SYM_RPAREN] = KEY_0,
98 [KEY_SYM_MINUS] = KEY_MINUS, [KEY_SYM_USCORE] = KEY_MINUS,
99 [KEY_SYM_EQUAL] = KEY_EQUAL, [KEY_SYM_PLUS] = KEY_EQUAL,
100 [KEY_SYM_LBRKT] = KEY_LEFTBRACE, [KEY_SYM_LCURLY] = KEY_LEFTBRACE,
101 [KEY_SYM_RBRKT] = KEY_RIGHTBRACE, [KEY_SYM_RCURLY] = KEY_RIGHTBRACE,
102 [KEY_SYM_SLASH] = KEY_BACKSLASH, [KEY_SYM_PIPE] = KEY_BACKSLASH,
103 [KEY_SYM_TIC] = KEY_APOSTROPHE, [KEY_SYM_QUOTE] = KEY_APOSTROPHE,
104 [KEY_SYM_SEMIC] = KEY_SEMICOLON, [KEY_SYM_COLON] = KEY_SEMICOLON,
105 [KEY_SYM_COMMA] = KEY_COMMA, [KEY_SYM_LT] = KEY_COMMA,
106 [KEY_SYM_PERIOD] = KEY_DOT, [KEY_SYM_GT] = KEY_DOT,
107 [KEY_SYM_BSLASH] = KEY_SLASH, [KEY_SYM_QMARK] = KEY_SLASH,
108 [KEY_SYM_A] = KEY_A, [KEY_SYM_a] = KEY_A,
109 [KEY_SYM_B] = KEY_B, [KEY_SYM_b] = KEY_B,
110 [KEY_SYM_C] = KEY_C, [KEY_SYM_c] = KEY_C,
111 [KEY_SYM_D] = KEY_D, [KEY_SYM_d] = KEY_D,
112 [KEY_SYM_E] = KEY_E, [KEY_SYM_e] = KEY_E,
113 [KEY_SYM_F] = KEY_F, [KEY_SYM_f] = KEY_F,
114 [KEY_SYM_G] = KEY_G, [KEY_SYM_g] = KEY_G,
115 [KEY_SYM_H] = KEY_H, [KEY_SYM_h] = KEY_H,
116 [KEY_SYM_I] = KEY_I, [KEY_SYM_i] = KEY_I,
117 [KEY_SYM_J] = KEY_J, [KEY_SYM_j] = KEY_J,
118 [KEY_SYM_K] = KEY_K, [KEY_SYM_k] = KEY_K,
119 [KEY_SYM_L] = KEY_L, [KEY_SYM_l] = KEY_L,
120 [KEY_SYM_M] = KEY_M, [KEY_SYM_m] = KEY_M,
121 [KEY_SYM_N] = KEY_N, [KEY_SYM_n] = KEY_N,
122 [KEY_SYM_O] = KEY_O, [KEY_SYM_o] = KEY_O,
123 [KEY_SYM_P] = KEY_P, [KEY_SYM_p] = KEY_P,
124 [KEY_SYM_Q] = KEY_Q, [KEY_SYM_q] = KEY_Q,
125 [KEY_SYM_R] = KEY_R, [KEY_SYM_r] = KEY_R,
126 [KEY_SYM_S] = KEY_S, [KEY_SYM_s] = KEY_S,
127 [KEY_SYM_T] = KEY_T, [KEY_SYM_t] = KEY_T,
128 [KEY_SYM_U] = KEY_U, [KEY_SYM_u] = KEY_U,
129 [KEY_SYM_V] = KEY_V, [KEY_SYM_v] = KEY_V,
130 [KEY_SYM_W] = KEY_W, [KEY_SYM_w] = KEY_W,
131 [KEY_SYM_X] = KEY_X, [KEY_SYM_x] = KEY_X,
132 [KEY_SYM_Y] = KEY_Y, [KEY_SYM_y] = KEY_Y,
133 [KEY_SYM_Z] = KEY_Z, [KEY_SYM_z] = KEY_Z,
134};
42 135
43 q->end = q->start + DRIVER_REMOTE_QUEUE_SIZE; 136static char remote_mouse_name[] = "ibmasm RSA I remote mouse";
44 q->reader = q->start; 137static char remote_keybd_name[] = "ibmasm RSA I remote keyboard";
45 q->writer = q->start;
46 q->size = DRIVER_REMOTE_QUEUE_SIZE;
47 init_waitqueue_head(&q->wait);
48 138
49 return 0; 139static void print_input(struct remote_input *input)
50}
51
52void ibmasm_free_remote_queue(struct service_processor *sp)
53{ 140{
54 kfree(sp->remote_queue.start); 141 if (input->type == INPUT_TYPE_MOUSE) {
142 unsigned char buttons = input->mouse_buttons;
143 dbg("remote mouse movement: (x,y)=(%d,%d)%s%s%s%s\n",
144 input->data.mouse.x, input->data.mouse.y,
145 (buttons)?" -- buttons:":"",
146 (buttons & REMOTE_BUTTON_LEFT)?"left ":"",
147 (buttons & REMOTE_BUTTON_MIDDLE)?"middle ":"",
148 (buttons & REMOTE_BUTTON_RIGHT)?"right":""
149 );
150 } else {
151 dbg("remote keypress (code, flag, down):"
152 "%d (0x%x) [0x%x] [0x%x]\n",
153 input->data.keyboard.key_code,
154 input->data.keyboard.key_code,
155 input->data.keyboard.key_flag,
156 input->data.keyboard.key_down
157 );
158 }
55} 159}
56 160
57void ibmasm_advance_reader(struct remote_queue *q, unsigned int n) 161static void send_mouse_event(struct input_dev *dev, struct pt_regs *regs,
162 struct remote_input *input)
58{ 163{
59 q->reader += n; 164 unsigned char buttons = input->mouse_buttons;
60 if (q->reader >= q->end)
61 q->reader -= q->size;
62}
63 165
64size_t ibmasm_events_available(struct remote_queue *q) 166 input_regs(dev, regs);
65{ 167 input_report_abs(dev, ABS_X, input->data.mouse.x);
66 ssize_t diff = q->writer - q->reader; 168 input_report_abs(dev, ABS_Y, input->data.mouse.y);
67 169 input_report_key(dev, BTN_LEFT, buttons & REMOTE_BUTTON_LEFT);
68 return (diff >= 0) ? diff : q->end - q->reader; 170 input_report_key(dev, BTN_MIDDLE, buttons & REMOTE_BUTTON_MIDDLE);
171 input_report_key(dev, BTN_RIGHT, buttons & REMOTE_BUTTON_RIGHT);
172 input_sync(dev);
69} 173}
70
71 174
72static int space_free(struct remote_queue *q) 175static void send_keyboard_event(struct input_dev *dev, struct pt_regs *regs,
176 struct remote_input *input)
73{ 177{
74 if (q->reader == q->writer) 178 unsigned int key;
75 return q->size - 1; 179 unsigned short code = input->data.keyboard.key_code;
76 180
77 return ( (q->reader + q->size - q->writer) % q->size ) - 1; 181 if (code & 0xff00)
182 key = xlate_high[code & 0xff];
183 else
184 key = xlate[code];
185 input_regs(dev, regs);
186 input_report_key(dev, key, (input->data.keyboard.key_down) ? 1 : 0);
187 input_sync(dev);
78} 188}
79 189
80static void set_mouse_event(struct remote_input *input, struct mouse_event *mouse) 190void ibmasm_handle_mouse_interrupt(struct service_processor *sp,
191 struct pt_regs *regs)
81{ 192{
82 static char last_buttons = 0; 193 unsigned long reader;
194 unsigned long writer;
195 struct remote_input input;
83 196
84 mouse->x = input->data.mouse.x; 197 reader = get_queue_reader(sp);
85 mouse->y = input->data.mouse.y; 198 writer = get_queue_writer(sp);
86 199
87 if (input->mouse_buttons == REMOTE_MOUSE_DOUBLE_CLICK) { 200 while (reader != writer) {
88 mouse->buttons = REMOTE_MOUSE_DOUBLE_CLICK; 201 memcpy_fromio(&input, get_queue_entry(sp, reader),
89 last_buttons = 0; 202 sizeof(struct remote_input));
90 return;
91 }
92 mouse->transitions = last_buttons ^ input->mouse_buttons;
93 mouse->buttons = input->mouse_buttons;
94 203
95 last_buttons = input->mouse_buttons; 204 print_input(&input);
96} 205 if (input.type == INPUT_TYPE_MOUSE) {
206 send_mouse_event(&sp->remote->mouse_dev, regs, &input);
207 } else if (input.type == INPUT_TYPE_KEYBOARD) {
208 send_keyboard_event(&sp->remote->keybd_dev, regs, &input);
209 } else
210 break;
97 211
98static void set_keyboard_event(struct remote_input *input, struct keyboard_event *keyboard) 212 reader = advance_queue_reader(sp, reader);
99{ 213 writer = get_queue_writer(sp);
100 keyboard->key_code = input->data.keyboard.key_code; 214 }
101 keyboard->key_down = input->data.keyboard.key_down;
102} 215}
103 216
104static int add_to_driver_queue(struct remote_queue *q, struct remote_input *input) 217int ibmasm_init_remote_input_dev(struct service_processor *sp)
105{ 218{
106 struct remote_event *event = q->writer; 219 /* set up the mouse input device */
220 struct ibmasm_remote *remote;
221 struct pci_dev *pdev = to_pci_dev(sp->dev);
222 int i;
107 223
108 if (space_free(q) < 1) { 224 sp->remote = remote = kmalloc(sizeof(*remote), GFP_KERNEL);
109 return 1; 225 if (!remote)
110 } 226 return -ENOMEM;
111 227
112 switch(input->type) { 228 memset(remote, 0, sizeof(*remote));
113 case (INPUT_TYPE_MOUSE):
114 event->type = INPUT_TYPE_MOUSE;
115 set_mouse_event(input, &event->data.mouse);
116 break;
117 case (INPUT_TYPE_KEYBOARD):
118 event->type = INPUT_TYPE_KEYBOARD;
119 set_keyboard_event(input, &event->data.keyboard);
120 break;
121 default:
122 return 0;
123 }
124 event->type = input->type;
125 229
126 q->writer++; 230 remote->mouse_dev.private = remote;
127 if (q->writer == q->end) 231 init_input_dev(&remote->mouse_dev);
128 q->writer = q->start; 232 remote->mouse_dev.id.vendor = pdev->vendor;
233 remote->mouse_dev.id.product = pdev->device;
234 remote->mouse_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
235 remote->mouse_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) |
236 BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
237 set_bit(BTN_TOUCH, remote->mouse_dev.keybit);
238 remote->mouse_dev.name = remote_mouse_name;
239 input_set_abs_params(&remote->mouse_dev, ABS_X, 0, xmax, 0, 0);
240 input_set_abs_params(&remote->mouse_dev, ABS_Y, 0, ymax, 0, 0);
129 241
130 return 0; 242 remote->keybd_dev.private = remote;
131} 243 init_input_dev(&remote->keybd_dev);
132 244 remote->keybd_dev.id.vendor = pdev->vendor;
245 remote->keybd_dev.id.product = pdev->device;
246 remote->keybd_dev.evbit[0] = BIT(EV_KEY);
247 remote->keybd_dev.name = remote_keybd_name;
133 248
134void ibmasm_handle_mouse_interrupt(struct service_processor *sp) 249 for (i=0; i<XLATE_SIZE; i++) {
135{ 250 if (xlate_high[i])
136 unsigned long reader; 251 set_bit(xlate_high[i], remote->keybd_dev.keybit);
137 unsigned long writer; 252 if (xlate[i])
138 struct remote_input input; 253 set_bit(xlate[i], remote->keybd_dev.keybit);
254 }
139 255
140 reader = get_queue_reader(sp); 256 input_register_device(&remote->mouse_dev);
141 writer = get_queue_writer(sp); 257 input_register_device(&remote->keybd_dev);
258 enable_mouse_interrupts(sp);
142 259
143 while (reader != writer) { 260 printk(KERN_INFO "ibmasm remote responding to events on RSA card %d\n", sp->number);
144 memcpy(&input, (void *)get_queue_entry(sp, reader), sizeof(struct remote_input));
145 261
146 if (add_to_driver_queue(&sp->remote_queue, &input)) 262 return 0;
147 break; 263}
148 264
149 reader = advance_queue_reader(sp, reader); 265void ibmasm_free_remote_input_dev(struct service_processor *sp)
150 } 266{
151 wake_up_interruptible(&sp->remote_queue.wait); 267 disable_mouse_interrupts(sp);
268 input_unregister_device(&sp->remote->keybd_dev);
269 input_unregister_device(&sp->remote->mouse_dev);
270 kfree(sp->remote);
152} 271}
272
diff --git a/drivers/misc/ibmasm/remote.h b/drivers/misc/ibmasm/remote.h
index a8eb19f02d3f..b7076a8442d2 100644
--- a/drivers/misc/ibmasm/remote.h
+++ b/drivers/misc/ibmasm/remote.h
@@ -51,11 +51,13 @@
51 51
52 52
53/* mouse button states received from SP */ 53/* mouse button states received from SP */
54#define REMOTE_MOUSE_DOUBLE_CLICK 0xF0 54#define REMOTE_DOUBLE_CLICK 0xF0
55#define REMOTE_MOUSE_BUTTON_LEFT 0x01 55#define REMOTE_BUTTON_LEFT 0x01
56#define REMOTE_MOUSE_BUTTON_MIDDLE 0x02 56#define REMOTE_BUTTON_MIDDLE 0x02
57#define REMOTE_MOUSE_BUTTON_RIGHT 0x04 57#define REMOTE_BUTTON_RIGHT 0x04
58 58
59/* size of keysym/keycode translation matricies */
60#define XLATE_SIZE 256
59 61
60struct mouse_input { 62struct mouse_input {
61 unsigned short y; 63 unsigned short y;
@@ -83,11 +85,13 @@ struct remote_input {
83 unsigned char pad3; 85 unsigned char pad3;
84}; 86};
85 87
86#define mouse_addr(sp) sp->base_address + CONDOR_MOUSE_DATA 88#define mouse_addr(sp) (sp->base_address + CONDOR_MOUSE_DATA)
87#define display_width(sp) mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESX 89#define display_width(sp) (mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESX)
88#define display_height(sp) mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESY 90#define display_height(sp) (mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESY)
89#define display_depth(sp) mouse_addr(sp) + CONDOR_INPUT_DISPLAY_BITS 91#define display_depth(sp) (mouse_addr(sp) + CONDOR_INPUT_DISPLAY_BITS)
90#define vnc_status(sp) mouse_addr(sp) + CONDOR_OUTPUT_VNC_STATUS 92#define desktop_info(sp) (mouse_addr(sp) + CONDOR_INPUT_DESKTOP_INFO)
93#define vnc_status(sp) (mouse_addr(sp) + CONDOR_OUTPUT_VNC_STATUS)
94#define isr_control(sp) (mouse_addr(sp) + CONDOR_MOUSE_ISR_CONTROL)
91 95
92#define mouse_interrupt_pending(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS) 96#define mouse_interrupt_pending(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS)
93#define clear_mouse_interrupt(sp) writel(0, mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS) 97#define clear_mouse_interrupt(sp) writel(0, mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS)
@@ -101,10 +105,10 @@ struct remote_input {
101#define get_queue_reader(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_Q_READER) 105#define get_queue_reader(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_Q_READER)
102#define set_queue_reader(sp, reader) writel(reader, mouse_addr(sp) + CONDOR_MOUSE_Q_READER) 106#define set_queue_reader(sp, reader) writel(reader, mouse_addr(sp) + CONDOR_MOUSE_Q_READER)
103 107
104#define queue_begin mouse_addr(sp) + CONDOR_MOUSE_Q_BEGIN 108#define queue_begin (mouse_addr(sp) + CONDOR_MOUSE_Q_BEGIN)
105 109
106#define get_queue_entry(sp, read_index) \ 110#define get_queue_entry(sp, read_index) \
107 queue_begin + read_index * sizeof(struct remote_input) 111 ((void*)(queue_begin + read_index * sizeof(struct remote_input)))
108 112
109static inline int advance_queue_reader(struct service_processor *sp, unsigned long reader) 113static inline int advance_queue_reader(struct service_processor *sp, unsigned long reader)
110{ 114{
@@ -116,4 +120,151 @@ static inline int advance_queue_reader(struct service_processor *sp, unsigned lo
116 return reader; 120 return reader;
117} 121}
118 122
123#define NO_KEYCODE 0
124#define KEY_SYM_BK_SPC 0xFF08
125#define KEY_SYM_TAB 0xFF09
126#define KEY_SYM_ENTER 0xFF0D
127#define KEY_SYM_SCR_LOCK 0xFF14
128#define KEY_SYM_ESCAPE 0xFF1B
129#define KEY_SYM_HOME 0xFF50
130#define KEY_SYM_LARROW 0xFF51
131#define KEY_SYM_UARROW 0xFF52
132#define KEY_SYM_RARROW 0xFF53
133#define KEY_SYM_DARROW 0xFF54
134#define KEY_SYM_PAGEUP 0xFF55
135#define KEY_SYM_PAGEDOWN 0xFF56
136#define KEY_SYM_END 0xFF57
137#define KEY_SYM_INSERT 0xFF63
138#define KEY_SYM_NUM_LOCK 0xFF7F
139#define KEY_SYM_KPSTAR 0xFFAA
140#define KEY_SYM_KPPLUS 0xFFAB
141#define KEY_SYM_KPMINUS 0xFFAD
142#define KEY_SYM_KPDOT 0xFFAE
143#define KEY_SYM_KPSLASH 0xFFAF
144#define KEY_SYM_KPRIGHT 0xFF96
145#define KEY_SYM_KPUP 0xFF97
146#define KEY_SYM_KPLEFT 0xFF98
147#define KEY_SYM_KPDOWN 0xFF99
148#define KEY_SYM_KP0 0xFFB0
149#define KEY_SYM_KP1 0xFFB1
150#define KEY_SYM_KP2 0xFFB2
151#define KEY_SYM_KP3 0xFFB3
152#define KEY_SYM_KP4 0xFFB4
153#define KEY_SYM_KP5 0xFFB5
154#define KEY_SYM_KP6 0xFFB6
155#define KEY_SYM_KP7 0xFFB7
156#define KEY_SYM_KP8 0xFFB8
157#define KEY_SYM_KP9 0xFFB9
158#define KEY_SYM_F1 0xFFBE // 1B 5B 5B 41
159#define KEY_SYM_F2 0xFFBF // 1B 5B 5B 42
160#define KEY_SYM_F3 0xFFC0 // 1B 5B 5B 43
161#define KEY_SYM_F4 0xFFC1 // 1B 5B 5B 44
162#define KEY_SYM_F5 0xFFC2 // 1B 5B 5B 45
163#define KEY_SYM_F6 0xFFC3 // 1B 5B 31 37 7E
164#define KEY_SYM_F7 0xFFC4 // 1B 5B 31 38 7E
165#define KEY_SYM_F8 0xFFC5 // 1B 5B 31 39 7E
166#define KEY_SYM_F9 0xFFC6 // 1B 5B 32 30 7E
167#define KEY_SYM_F10 0xFFC7 // 1B 5B 32 31 7E
168#define KEY_SYM_F11 0xFFC8 // 1B 5B 32 33 7E
169#define KEY_SYM_F12 0xFFC9 // 1B 5B 32 34 7E
170#define KEY_SYM_SHIFT 0xFFE1
171#define KEY_SYM_CTRL 0xFFE3
172#define KEY_SYM_ALT 0xFFE9
173#define KEY_SYM_CAP_LOCK 0xFFE5
174#define KEY_SYM_DELETE 0xFFFF
175#define KEY_SYM_TILDE 0x60
176#define KEY_SYM_BKTIC 0x7E
177#define KEY_SYM_ONE 0x31
178#define KEY_SYM_BANG 0x21
179#define KEY_SYM_TWO 0x32
180#define KEY_SYM_AT 0x40
181#define KEY_SYM_THREE 0x33
182#define KEY_SYM_POUND 0x23
183#define KEY_SYM_FOUR 0x34
184#define KEY_SYM_DOLLAR 0x24
185#define KEY_SYM_FIVE 0x35
186#define KEY_SYM_PERCENT 0x25
187#define KEY_SYM_SIX 0x36
188#define KEY_SYM_CARAT 0x5E
189#define KEY_SYM_SEVEN 0x37
190#define KEY_SYM_AMPER 0x26
191#define KEY_SYM_EIGHT 0x38
192#define KEY_SYM_STAR 0x2A
193#define KEY_SYM_NINE 0x39
194#define KEY_SYM_LPAREN 0x28
195#define KEY_SYM_ZERO 0x30
196#define KEY_SYM_RPAREN 0x29
197#define KEY_SYM_MINUS 0x2D
198#define KEY_SYM_USCORE 0x5F
199#define KEY_SYM_EQUAL 0x2B
200#define KEY_SYM_PLUS 0x3D
201#define KEY_SYM_LBRKT 0x5B
202#define KEY_SYM_LCURLY 0x7B
203#define KEY_SYM_RBRKT 0x5D
204#define KEY_SYM_RCURLY 0x7D
205#define KEY_SYM_SLASH 0x5C
206#define KEY_SYM_PIPE 0x7C
207#define KEY_SYM_TIC 0x27
208#define KEY_SYM_QUOTE 0x22
209#define KEY_SYM_SEMIC 0x3B
210#define KEY_SYM_COLON 0x3A
211#define KEY_SYM_COMMA 0x2C
212#define KEY_SYM_LT 0x3C
213#define KEY_SYM_PERIOD 0x2E
214#define KEY_SYM_GT 0x3E
215#define KEY_SYM_BSLASH 0x2F
216#define KEY_SYM_QMARK 0x3F
217#define KEY_SYM_A 0x41
218#define KEY_SYM_B 0x42
219#define KEY_SYM_C 0x43
220#define KEY_SYM_D 0x44
221#define KEY_SYM_E 0x45
222#define KEY_SYM_F 0x46
223#define KEY_SYM_G 0x47
224#define KEY_SYM_H 0x48
225#define KEY_SYM_I 0x49
226#define KEY_SYM_J 0x4A
227#define KEY_SYM_K 0x4B
228#define KEY_SYM_L 0x4C
229#define KEY_SYM_M 0x4D
230#define KEY_SYM_N 0x4E
231#define KEY_SYM_O 0x4F
232#define KEY_SYM_P 0x50
233#define KEY_SYM_Q 0x51
234#define KEY_SYM_R 0x52
235#define KEY_SYM_S 0x53
236#define KEY_SYM_T 0x54
237#define KEY_SYM_U 0x55
238#define KEY_SYM_V 0x56
239#define KEY_SYM_W 0x57
240#define KEY_SYM_X 0x58
241#define KEY_SYM_Y 0x59
242#define KEY_SYM_Z 0x5A
243#define KEY_SYM_a 0x61
244#define KEY_SYM_b 0x62
245#define KEY_SYM_c 0x63
246#define KEY_SYM_d 0x64
247#define KEY_SYM_e 0x65
248#define KEY_SYM_f 0x66
249#define KEY_SYM_g 0x67
250#define KEY_SYM_h 0x68
251#define KEY_SYM_i 0x69
252#define KEY_SYM_j 0x6A
253#define KEY_SYM_k 0x6B
254#define KEY_SYM_l 0x6C
255#define KEY_SYM_m 0x6D
256#define KEY_SYM_n 0x6E
257#define KEY_SYM_o 0x6F
258#define KEY_SYM_p 0x70
259#define KEY_SYM_q 0x71
260#define KEY_SYM_r 0x72
261#define KEY_SYM_s 0x73
262#define KEY_SYM_t 0x74
263#define KEY_SYM_u 0x75
264#define KEY_SYM_v 0x76
265#define KEY_SYM_w 0x77
266#define KEY_SYM_x 0x78
267#define KEY_SYM_y 0x79
268#define KEY_SYM_z 0x7A
269#define KEY_SYM_SPACE 0x20
119#endif /* _IBMASM_REMOTE_H_ */ 270#endif /* _IBMASM_REMOTE_H_ */