btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / add-ons / kernel / bus_managers / ps2 / ps2_service.cpp
blob1bf5ed32990d6e072c53c6fd00b53441295bf0b7
1 /*
2 * Copyright 2005-2007 Haiku, Inc.
3 * Distributed under the terms of the MIT License.
5 * PS/2 bus manager
7 * Authors (in chronological order):
8 * Marcus Overhagen (marcus@overhagen.de)
9 */
12 #include "ps2_service.h"
14 #include "packet_buffer.h"
17 #define DEBUG_PUBLISHING
18 #ifdef DEBUG_PUBLISHING
19 # include <stdlib.h>
20 # include <debug.h>
21 #endif
24 typedef struct {
25 uint32 id;
26 ps2_dev * dev;
27 } ps2_service_cmd;
29 enum {
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;
42 void
43 ps2_service_notify_device_added(ps2_dev *dev)
45 ps2_service_cmd cmd;
47 TRACE("ps2: ps2_service_notify_device_added %s\n", dev->name);
49 cmd.id = PS2_SERVICE_NOTIFY_DEVICE_ADDED;
50 cmd.dev = dev;
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");
59 void
60 ps2_service_notify_device_republish(ps2_dev *dev)
62 ps2_service_cmd cmd;
64 TRACE("ps2: ps2_service_notify_device_republish %s\n", dev->name);
66 cmd.id = PS2_SERVICE_NOTIFY_DEVICE_REPUBLISH;
67 cmd.dev = dev;
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");
76 void
77 ps2_service_notify_device_removed(ps2_dev *dev)
79 ps2_service_cmd cmd;
81 TRACE("ps2: ps2_service_notify_device_removed %s\n", dev->name);
83 cmd.id = PS2_SERVICE_NOTIFY_DEVICE_REMOVED;
84 cmd.dev = dev;
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");
93 static int32
94 ps2_service_thread(void *arg)
96 TRACE("ps2: ps2_service_thread started\n");
98 for (;;) {
99 status_t status;
100 status = acquire_sem_etc(sServiceSem, 1, B_CAN_INTERRUPT, 0);
101 if (sServiceTerminate)
102 break;
103 if (status == B_OK) {
105 // process service commands
106 ps2_service_cmd cmd;
107 packet_buffer_read(sServiceCmdBuffer, (uint8 *)&cmd, sizeof(cmd));
108 switch (cmd.id) {
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);
112 break;
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);
117 snooze(1500000);
118 ps2_dev_publish(cmd.dev);
119 break;
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);
124 break;
126 default:
127 TRACE("ps2: PS2_SERVICE: unknown id %lu\n", cmd.id);
128 break;
130 } else {
131 INFO("ps2: ps2_service_thread: Error, status 0x%08" B_PRIx32 ", "
132 "terminating\n", status);
133 break;
136 return 0;
140 #ifdef DEBUG_PUBLISHING
141 static int
142 ps2_republish(int argc, char **argv)
144 int dev = 4;
145 if (argc == 2)
146 dev = strtoul(argv[1], NULL, 0);
147 if (dev < 0 || dev > 4)
148 dev = 4;
149 ps2_service_notify_device_republish(&ps2_device[dev]);
150 return 0;
152 #endif
155 status_t
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)
161 goto err1;
162 sServiceSem = create_sem(0, "ps2 service");
163 if (sServiceSem < B_OK)
164 goto err2;
165 sServiceThread = spawn_kernel_thread(ps2_service_thread, "ps2 service", 20, NULL);
166 if (sServiceThread < B_OK)
167 goto err3;
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))");
173 #endif
175 TRACE("ps2: ps2_service_init done\n");
176 return B_OK;
178 err3:
179 delete_sem(sServiceSem);
180 err2:
181 delete_packet_buffer(sServiceCmdBuffer);
182 err1:
183 TRACE("ps2: ps2_service_init failed\n");
184 return B_ERROR;
188 void
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);
200 #endif
201 TRACE("ps2: ps2_service_exit done\n");