3 * IBM ASM Service Processor Device Driver
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.
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.
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.
19 * Copyright (C) IBM Corporation, 2004
21 * Author: Max Asböck <amax@us.ibm.com>
25 /* Remote mouse and keyboard event handling functions */
30 int ibmasm_init_remote_queue(struct service_processor
*sp
)
32 struct remote_queue
*q
= &sp
->remote_queue
;
34 disable_mouse_interrupts(sp
);
39 q
->start
= kmalloc(DRIVER_REMOTE_QUEUE_SIZE
* sizeof(struct remote_event
), GFP_KERNEL
);
43 q
->end
= q
->start
+ DRIVER_REMOTE_QUEUE_SIZE
;
46 q
->size
= DRIVER_REMOTE_QUEUE_SIZE
;
47 init_waitqueue_head(&q
->wait
);
52 void ibmasm_free_remote_queue(struct service_processor
*sp
)
54 kfree(sp
->remote_queue
.start
);
57 void ibmasm_advance_reader(struct remote_queue
*q
, unsigned int n
)
60 if (q
->reader
>= q
->end
)
64 size_t ibmasm_events_available(struct remote_queue
*q
)
66 ssize_t diff
= q
->writer
- q
->reader
;
68 return (diff
>= 0) ? diff
: q
->end
- q
->reader
;
72 static int space_free(struct remote_queue
*q
)
74 if (q
->reader
== q
->writer
)
77 return ( (q
->reader
+ q
->size
- q
->writer
) % q
->size
) - 1;
80 static void set_mouse_event(struct remote_input
*input
, struct mouse_event
*mouse
)
82 static char last_buttons
= 0;
84 mouse
->x
= input
->data
.mouse
.x
;
85 mouse
->y
= input
->data
.mouse
.y
;
87 if (input
->mouse_buttons
== REMOTE_MOUSE_DOUBLE_CLICK
) {
88 mouse
->buttons
= REMOTE_MOUSE_DOUBLE_CLICK
;
92 mouse
->transitions
= last_buttons
^ input
->mouse_buttons
;
93 mouse
->buttons
= input
->mouse_buttons
;
95 last_buttons
= input
->mouse_buttons
;
98 static void set_keyboard_event(struct remote_input
*input
, struct keyboard_event
*keyboard
)
100 keyboard
->key_code
= input
->data
.keyboard
.key_code
;
101 keyboard
->key_down
= input
->data
.keyboard
.key_down
;
104 static int add_to_driver_queue(struct remote_queue
*q
, struct remote_input
*input
)
106 struct remote_event
*event
= q
->writer
;
108 if (space_free(q
) < 1) {
112 switch(input
->type
) {
113 case (INPUT_TYPE_MOUSE
):
114 event
->type
= INPUT_TYPE_MOUSE
;
115 set_mouse_event(input
, &event
->data
.mouse
);
117 case (INPUT_TYPE_KEYBOARD
):
118 event
->type
= INPUT_TYPE_KEYBOARD
;
119 set_keyboard_event(input
, &event
->data
.keyboard
);
124 event
->type
= input
->type
;
127 if (q
->writer
== q
->end
)
128 q
->writer
= q
->start
;
134 void ibmasm_handle_mouse_interrupt(struct service_processor
*sp
)
136 unsigned long reader
;
137 unsigned long writer
;
138 struct remote_input input
;
140 reader
= get_queue_reader(sp
);
141 writer
= get_queue_writer(sp
);
143 while (reader
!= writer
) {
144 memcpy(&input
, (void *)get_queue_entry(sp
, reader
), sizeof(struct remote_input
));
146 if (add_to_driver_queue(&sp
->remote_queue
, &input
))
149 reader
= advance_queue_reader(sp
, reader
);
151 wake_up_interruptible(&sp
->remote_queue
.wait
);