2 * Copyright 2005-2007 Haiku, Inc.
3 * Distributed under the terms of the MIT License.
7 * Authors (in chronological order):
8 * Marcus Overhagen (marcus@overhagen.de)
12 #include "ps2_service.h"
14 #include "packet_buffer.h"
17 #define DEBUG_PUBLISHING
18 #ifdef DEBUG_PUBLISHING
30 PS2_SERVICE_NOTIFY_DEVICE_ADDED
= 1,
31 PS2_SERVICE_NOTIFY_DEVICE_REPUBLISH
,
32 PS2_SERVICE_NOTIFY_DEVICE_REMOVED
,
36 static sem_id sServiceSem
;
37 static thread_id sServiceThread
;
38 static volatile bool sServiceTerminate
;
39 static packet_buffer
* sServiceCmdBuffer
;
43 ps2_service_notify_device_added(ps2_dev
*dev
)
47 TRACE("ps2: ps2_service_notify_device_added %s\n", dev
->name
);
49 cmd
.id
= PS2_SERVICE_NOTIFY_DEVICE_ADDED
;
52 packet_buffer_write(sServiceCmdBuffer
, (const uint8
*)&cmd
, sizeof(cmd
));
53 release_sem_etc(sServiceSem
, 1, B_DO_NOT_RESCHEDULE
);
55 TRACE("ps2: ps2_service_notify_device_added done\n");
60 ps2_service_notify_device_republish(ps2_dev
*dev
)
64 TRACE("ps2: ps2_service_notify_device_republish %s\n", dev
->name
);
66 cmd
.id
= PS2_SERVICE_NOTIFY_DEVICE_REPUBLISH
;
69 packet_buffer_write(sServiceCmdBuffer
, (const uint8
*)&cmd
, sizeof(cmd
));
70 release_sem_etc(sServiceSem
, 1, B_DO_NOT_RESCHEDULE
);
72 TRACE("ps2: ps2_service_notify_device_republish done\n");
77 ps2_service_notify_device_removed(ps2_dev
*dev
)
81 TRACE("ps2: ps2_service_notify_device_removed %s\n", dev
->name
);
83 cmd
.id
= PS2_SERVICE_NOTIFY_DEVICE_REMOVED
;
86 packet_buffer_write(sServiceCmdBuffer
, (const uint8
*)&cmd
, sizeof(cmd
));
87 release_sem_etc(sServiceSem
, 1, B_DO_NOT_RESCHEDULE
);
89 TRACE("ps2: ps2_service_notify_device_removed done\n");
94 ps2_service_thread(void *arg
)
96 TRACE("ps2: ps2_service_thread started\n");
100 status
= acquire_sem_etc(sServiceSem
, 1, B_CAN_INTERRUPT
, 0);
101 if (sServiceTerminate
)
103 if (status
== B_OK
) {
105 // process service commands
107 packet_buffer_read(sServiceCmdBuffer
, (uint8
*)&cmd
, sizeof(cmd
));
109 case PS2_SERVICE_NOTIFY_DEVICE_ADDED
:
110 TRACE("ps2: PS2_SERVICE_NOTIFY_DEVICE_ADDED %s\n", cmd
.dev
->name
);
111 ps2_dev_publish(cmd
.dev
);
114 case PS2_SERVICE_NOTIFY_DEVICE_REPUBLISH
:
115 TRACE("ps2: PS2_SERVICE_NOTIFY_DEVICE_REPUBLISH %s\n", cmd
.dev
->name
);
116 ps2_dev_unpublish(cmd
.dev
);
118 ps2_dev_publish(cmd
.dev
);
121 case PS2_SERVICE_NOTIFY_DEVICE_REMOVED
:
122 TRACE("ps2: PS2_SERVICE_NOTIFY_DEVICE_REMOVED %s\n", cmd
.dev
->name
);
123 ps2_dev_unpublish(cmd
.dev
);
127 TRACE("ps2: PS2_SERVICE: unknown id %lu\n", cmd
.id
);
131 INFO("ps2: ps2_service_thread: Error, status 0x%08" B_PRIx32
", "
132 "terminating\n", status
);
140 #ifdef DEBUG_PUBLISHING
142 ps2_republish(int argc
, char **argv
)
146 dev
= strtoul(argv
[1], NULL
, 0);
147 if (dev
< 0 || dev
> 4)
149 ps2_service_notify_device_republish(&ps2_device
[dev
]);
156 ps2_service_init(void)
158 TRACE("ps2: ps2_service_init\n");
159 sServiceCmdBuffer
= create_packet_buffer(sizeof(ps2_service_cmd
) * 50);
160 if (sServiceCmdBuffer
== NULL
)
162 sServiceSem
= create_sem(0, "ps2 service");
163 if (sServiceSem
< B_OK
)
165 sServiceThread
= spawn_kernel_thread(ps2_service_thread
, "ps2 service", 20, NULL
);
166 if (sServiceThread
< B_OK
)
168 sServiceTerminate
= false;
169 resume_thread(sServiceThread
);
171 #ifdef DEBUG_PUBLISHING
172 add_debugger_command("ps2republish", &ps2_republish
, "republish a ps2 device (0-3 mouse, 4 keyb (default))");
175 TRACE("ps2: ps2_service_init done\n");
179 delete_sem(sServiceSem
);
181 delete_packet_buffer(sServiceCmdBuffer
);
183 TRACE("ps2: ps2_service_init failed\n");
189 ps2_service_exit(void)
191 TRACE("ps2: ps2_service_exit enter\n");
192 sServiceTerminate
= true;
193 release_sem(sServiceSem
);
194 wait_for_thread(sServiceThread
, NULL
);
195 delete_sem(sServiceSem
);
196 delete_packet_buffer(sServiceCmdBuffer
);
198 #ifdef DEBUG_PUBLISHING
199 remove_debugger_command("ps2republish", &ps2_republish
);
201 TRACE("ps2: ps2_service_exit done\n");