Import 2.3.18pre1
[davej-history.git] / drivers / char / joystick / joystick.c
blobc567a8c20f0a6eca5e9f25d44b9ba159edd04464
1 /*
2 * joystick.c Version 1.2
4 * Copyright (c) 1996-1998 Vojtech Pavlik
5 */
7 /*
8 * This is the main joystick driver for Linux. It doesn't support any
9 * devices directly, rather is lets you use sub-modules to do that job. See
10 * Documentation/joystick.txt for more info.
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Should you need to contact me, the author, you can do so either by
29 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
30 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
33 #include <asm/io.h>
34 #include <asm/system.h>
35 #include <asm/segment.h>
36 #include <linux/config.h>
37 #include <linux/delay.h>
38 #include <linux/errno.h>
39 #include <linux/joystick.h>
40 #include <linux/kernel.h>
41 #include <linux/major.h>
42 #include <linux/malloc.h>
43 #include <linux/mm.h>
44 #include <linux/module.h>
45 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
46 #include <linux/spinlock.h>
47 #include <linux/poll.h>
48 #endif
51 * Configurable parameters.
54 #define JS_REFRESH_TIME HZ/50 /* Time between two reads of joysticks (20ms) */
57 * Buffer macros.
60 #define ROT(A,B,C) ((((A)<(C))&&(((B)>(A))&&((B)<(C))))||(((A)>(C))&&(((B)>(A))||((B)<(C)))))
61 #define GOF(X) (((X)==JS_BUFF_SIZE-1)?0:(X)+1)
62 #define GOB(X) ((X)?(X)-1:JS_BUFF_SIZE-1)
63 #define DIFF(X,Y) ((X)>(Y)?(X)-(Y):(Y)-(X))
66 * Global variables.
69 static struct JS_DATA_SAVE_TYPE js_comp_glue;
70 static struct js_port *js_port = NULL;
71 static struct js_dev *js_dev = NULL;
72 static struct timer_list js_timer;
73 spinlock_t js_lock = SPIN_LOCK_UNLOCKED;
74 static int js_use_count = 0;
77 * Exported variables.
80 unsigned int js_time_speed = 0;
81 js_time_func js_get_time;
82 js_delta_func js_delta;
84 unsigned int js_time_speed_a = 0;
85 js_time_func js_get_time_a;
86 js_delta_func js_delta_a;
89 * Module info.
92 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
93 MODULE_SUPPORTED_DEVICE("js");
96 * js_get_time_*() are different functions to get current time.
97 * js_delta_*() are functions to compute time difference.
100 #ifdef __i386__
102 static unsigned int js_get_time_rdtsc(void)
104 unsigned int x;
105 __asm__ __volatile__ ( "rdtsc" : "=A" (x) );
106 return x;
109 static unsigned int js_get_time_pit(void)
111 unsigned long flags;
112 unsigned int x;
114 __save_flags(flags);
115 __cli();
116 outb(0, 0x43);
117 x = inb(0x40);
118 x |= inb(0x40) << 8;
119 __restore_flags(flags);
121 return x;
124 static int js_delta_pit(unsigned int x, unsigned int y)
126 return y - x + ( y < x ? 1193180L / HZ : 0 );
129 static unsigned int js_get_time_counter(void)
131 static int time_counter = 0;
132 return time_counter++;
135 #else
136 #ifdef __alpha__
138 static unsigned int js_get_time_rpcc(void)
140 unsigned int x;
141 __asm__ __volatile__ ( "rpcc %0" : "=r" (x) );
142 return x;
145 #else
147 #ifndef MODULE
148 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
149 static unsigned int js_get_time_system(void)
151 static struct timeval js_tv;
152 get_fast_time(&js_tv);
153 return js_tv.tv_sec * 1000000L + js_tv.tv_usec;
155 #endif
156 #endif
158 #endif
159 #endif
161 static int js_delta_normal(unsigned int x, unsigned int y)
163 return x - y;
167 * js_calibrate_time() calibrates a given timer.
170 static int __init js_calibrate_time(js_time_func get_time, js_delta_func delta)
172 unsigned int t1, t2, t3;
173 unsigned long flags;
175 __save_flags(flags);
176 __cli();
177 t1 = get_time();
178 udelay(1000);
179 t2 = get_time();
180 t3 = get_time();
181 __restore_flags(flags);
183 return delta(t2, t1) - delta(t3, t2);
187 * js_calibrate_time_counter() calibrates the counter timer, which can't
188 * be calibrated using the above function.
191 #ifdef __i386__
193 static int __init js_calibrate_time_counter(void)
195 unsigned int i, j, t1, t2, t3;
197 j = jiffies; do { inb(0x201); t1 = js_get_time_counter(); } while (j == jiffies);
198 j = jiffies; do { inb(0x201); t2 = js_get_time_counter(); } while (j == jiffies);
200 j = (t2 - t1) * HZ / 1000;
202 t1 = js_get_time_pit();
203 for (i = 0; i < 1000; i++) {
204 inb(0x201);
205 js_get_time_counter();
207 t2 = js_get_time_pit();
208 t3 = js_get_time_pit();
210 i = 1193180L / (js_delta_pit(t2, t1) - js_delta_pit(t3, t2));
212 if (DIFF(i,j) > 5)
213 printk(KERN_WARNING "js: Counter timer calibration unsure,"
214 " pass1 (0.%d MHz) and pass2 (0.%d MHz) differ.\n", j, i);
216 return (i + j) >> 1;
219 #endif
222 * js_setup_time chooses the best available timers
223 * on the system and calibrates them.
226 static int __init js_setup_time(void)
228 int t;
229 char *name, *name_a;
231 name = "";
232 name_a = "";
233 js_time_speed = 0;
234 js_time_speed_a = 0;
236 #ifdef __i386__
238 t = js_calibrate_time(js_get_time_pit, js_delta_pit);
240 if (DIFF(t, 1193) > 5)
241 printk(KERN_WARNING "js: Measured PIT speed is %d.%03d MHz, but should be 1.193 MHz.\n"
242 KERN_WARNING "js: This is probably caused by wrong BogoMIPS value. It is: %ld, should be: %ld.\n",
243 t / 1000, t % 1000, loops_per_sec / 500000, loops_per_sec / (t * 500000 / 1193));
245 if (JS_HAS_RDTSC && (t = js_calibrate_time(js_get_time_rdtsc, js_delta_normal)) > 0) {
247 js_time_speed_a = t;
248 js_get_time_a = js_get_time_rdtsc;
249 js_delta_a = js_delta_normal;
250 js_time_speed = t;
251 js_get_time = js_get_time_rdtsc;
252 js_delta = js_delta_normal;
253 name = "RDTSC";
255 } else {
257 js_time_speed_a = t;
258 js_get_time_a = js_get_time_pit;
259 js_delta_a = js_delta_pit;
260 name_a = "PIT";
262 t = js_calibrate_time_counter();
264 js_time_speed = t;
265 js_get_time = js_get_time_counter;
266 js_delta = js_delta_normal;
267 name = "counter";
271 #else
272 #ifdef __alpha__
274 t = js_calibrate_time(js_get_time_rpcc, js_delta_normal);
276 js_time_speed_a = t;
277 js_get_time_a = js_get_time_rpcc;
278 js_delta_a = js_delta_normal;
279 js_time_speed = t;
280 js_get_time = js_get_time_rpcc;
281 js_delta = js_delta_normal;
282 name = "RPCC";
284 #else
286 #ifndef MODULE
287 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
288 t = js_calibrate_time(js_get_time_system, js_delta_normal);
290 js_time_speed_a = t;
291 js_get_time_a = js_get_time_system;
292 js_delta_a = js_delta_normal;
293 js_time_speed = t;
294 js_get_time = js_get_time_system;
295 js_delta = js_delta_normal;
296 name = "system";
297 #endif
298 #endif
300 #endif
301 #endif
303 printk(KERN_INFO "js: Version %d.%d.%d ",
304 JS_VERSION >> 16 & 0xff, JS_VERSION >> 8 & 0xff, JS_VERSION & 0xff);
306 if (js_time_speed_a <= 0 || js_time_speed <= 0) {
307 printk("\n");
308 return -1;
311 printk("using ");
313 if (js_time_speed > 10000) {
314 t = js_time_speed / 1000 + (js_time_speed % 1000 >= 500);
315 printk("%d MHz ", t);
316 } else {
317 t = js_time_speed / 10 + (js_time_speed % 10 >= 5);
318 printk("%d.%02d MHz ", t / 100, t % 100);
321 if (js_get_time_a != js_get_time) {
322 t = js_time_speed_a / 10 + (js_time_speed_a % 10 >= 5);
323 printk("%s timer and %d.%02d MHz %s timer.\n",
324 name, t / 100, t % 100, name_a);
325 } else {
326 printk("%s timer.\n", name);
329 return 0;
334 * js_correct() performs correction of raw joystick data.
337 static int js_correct(int value, struct js_corr *corr)
339 switch (corr->type) {
340 case JS_CORR_NONE:
341 break;
342 case JS_CORR_BROKEN:
343 value = value > corr->coef[0] ? (value < corr->coef[1] ? 0 :
344 ((corr->coef[3] * (value - corr->coef[1])) >> 14)) :
345 ((corr->coef[2] * (value - corr->coef[0])) >> 14);
346 break;
348 default:
349 return 0;
352 if (value < -32767) return -32767;
353 if (value > 32767) return 32767;
355 return value;
359 * js_button() returns value of button number i.
362 static inline int js_button(int *buttons, int i)
364 return (buttons[i >> 5] >> (i & 0x1f)) & 1;
369 * js_add_event() adds an event to the buffer. This requires additional
370 * queue post-processing done by js_sync_buff.
373 static void js_add_event(struct js_dev *jd, __u32 time, __u8 type, __u8 number, __s16 value)
375 jd->buff[jd->ahead].time = time;
376 jd->buff[jd->ahead].type = type;
377 jd->buff[jd->ahead].number = number;
378 jd->buff[jd->ahead].value = value;
379 if (++jd->ahead == JS_BUFF_SIZE) jd->ahead = 0;
383 * js_flush_data() does the same as js_process_data, except for that it doesn't
384 * generate any events - it just copies the data from new to cur.
387 static void js_flush_data(struct js_dev *jd)
389 int i;
391 for (i = 0; i < ((jd->num_buttons - 1) >> 5) + 1; i++)
392 jd->cur.buttons[i] = jd->new.buttons[i];
393 for (i = 0; i < jd->num_axes; i++)
394 jd->cur.axes[i] = jd->new.axes[i];
398 * js_process_data() finds changes in button states and axis positions and adds
399 * them as events to the buffer.
402 static void js_process_data(struct js_dev *jd)
404 int i, t;
406 for (i = 0; i < jd->num_buttons; i++)
407 if ((t = js_button(jd->new.buttons, i)) != js_button(jd->cur.buttons, i)) {
408 js_add_event(jd, jiffies, JS_EVENT_BUTTON, i, t);
409 jd->cur.buttons[i >> 5] ^= (1 << (i & 0x1f));
412 for (i = 0; i < jd->num_axes; i++) {
413 t = js_correct(jd->new.axes[i], &jd->corr[i]);
414 if (((jd->corr[i].prec == -1) && t) ||
415 ((DIFF(jd->new.axes[i], jd->cur.axes[i]) > jd->corr[i].prec) &&
416 (t != js_correct(jd->cur.axes[i], &jd->corr[i])))) {
417 js_add_event(jd, jiffies, JS_EVENT_AXIS, i, t);
418 jd->cur.axes[i] = jd->new.axes[i];
424 * js_sync_buff() checks for all overflows caused by recent additions to the buffer.
425 * These happen only if some process is reading the data too slowly. It
426 * wakes up any process waiting for data.
429 static void js_sync_buff(struct js_dev *jd)
431 struct js_list *curl = jd->list;
433 if (jd->bhead != jd->ahead) {
434 if(ROT(jd->bhead, jd->tail, jd->ahead) || (jd->tail == jd->bhead)) {
435 while (curl) {
436 if (ROT(jd->bhead, curl->tail, jd->ahead) || (curl->tail == jd->bhead)) {
437 curl->tail = jd->ahead;
438 curl->startup = 0;
440 curl = curl->next;
442 jd->tail = jd->ahead;
444 jd->bhead = jd->ahead;
445 wake_up_interruptible(&jd->wait);
450 * js_do_timer() acts as an interrupt replacement. It reads the data
451 * from all ports and then generates events for all devices.
454 static void js_do_timer(unsigned long data)
456 struct js_port *curp = js_port;
457 struct js_dev *curd = js_dev;
458 unsigned long flags;
460 while (curp != NULL) {
461 curp->read(curp->info, curp->axes, curp->buttons);
462 curp = curp->next;
465 spin_lock_irqsave(&js_lock, flags);
467 while (curd != NULL) {
468 if (data) {
469 js_process_data(curd);
470 js_sync_buff(curd);
471 } else {
472 js_flush_data(curd);
474 curd = curd->next;
477 spin_unlock_irqrestore(&js_lock, flags);
479 js_timer.expires = jiffies + JS_REFRESH_TIME;
480 add_timer(&js_timer);
484 * js_read() copies one or more entries from jsd[].buff to user
485 * space.
488 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
489 static ssize_t js_read(struct file *file, char *buf, size_t count, loff_t *ppos)
490 #else
491 static int js_read(struct inode *inode, struct file *file, char *buf, int count)
492 #endif
494 DECLARE_WAITQUEUE(wait, current);
495 struct js_event *buff = (void *) buf;
496 struct js_list *curl;
497 struct js_dev *jd;
498 unsigned long blocks = count / sizeof(struct js_event);
499 int written = 0;
500 int new_tail, orig_tail;
501 int retval = 0;
502 unsigned long flags;
504 curl = file->private_data;
505 jd = curl->dev;
506 orig_tail = curl->tail;
509 * Check user data.
512 if (!blocks)
513 return -EINVAL;
516 * Lock it.
519 spin_lock_irqsave(&js_lock, flags);
522 * Handle (non)blocking i/o.
524 if (count != sizeof(struct JS_DATA_TYPE)) {
526 if (GOF(curl->tail) == jd->bhead && curl->startup == jd->num_axes + jd->num_buttons) {
528 __set_current_state(TASK_INTERRUPTIBLE);
529 add_wait_queue(&jd->wait, &wait);
531 while (GOF(curl->tail) == jd->bhead) {
533 if (file->f_flags & O_NONBLOCK) {
534 retval = -EAGAIN;
535 break;
537 if (signal_pending(current)) {
538 retval = -ERESTARTSYS;
539 break;
542 spin_unlock_irqrestore(&js_lock, flags);
543 schedule();
544 spin_lock_irqsave(&js_lock, flags);
548 current->state = TASK_RUNNING;
549 remove_wait_queue(&jd->wait, &wait);
552 if (retval) {
553 spin_unlock_irqrestore(&js_lock, flags);
554 return retval;
558 * Initial state.
561 while (curl->startup < jd->num_axes + jd->num_buttons && written < blocks && !retval) {
563 struct js_event tmpevent;
565 if (curl->startup < jd->num_buttons) {
566 tmpevent.type = JS_EVENT_BUTTON | JS_EVENT_INIT;
567 tmpevent.value = js_button(jd->cur.buttons, curl->startup);
568 tmpevent.number = curl->startup;
569 } else {
570 tmpevent.type = JS_EVENT_AXIS | JS_EVENT_INIT;
571 tmpevent.value = js_correct(jd->cur.axes[curl->startup - jd->num_buttons],
572 &jd->corr[curl->startup - jd->num_buttons]);
573 tmpevent.number = curl->startup - jd->num_buttons;
576 tmpevent.time = jiffies * (1000/HZ);
578 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
579 if (copy_to_user(&buff[written], &tmpevent, sizeof(struct js_event)))
580 retval = -EFAULT;
581 #else
582 if (!(retval = verify_area(VERIFY_WRITE, &buff[written], sizeof(struct js_event))))
583 memcpy_tofs(&buff[written], &tmpevent, sizeof(struct js_event));
584 #endif
586 curl->startup++;
587 written++;
591 * Buffer data.
594 while ((jd->bhead != (new_tail = GOF(curl->tail))) && (written < blocks) && !retval) {
596 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
597 if (copy_to_user(&buff[written], &jd->buff[new_tail], sizeof(struct js_event)))
598 retval = -EFAULT;
599 if (put_user((__u32)(jd->buff[new_tail].time * (1000/HZ)), &buff[written].time))
600 retval = -EFAULT;
601 #else
602 if (!(retval = verify_area(VERIFY_WRITE, &buff[written], sizeof(struct js_event)))) {
603 memcpy_tofs(&buff[written], &jd->buff[new_tail], sizeof(struct js_event));
604 put_user((__u32)(jd->buff[new_tail].time * (1000/HZ)), &buff[written].time);
606 #endif
607 curl->tail = new_tail;
608 written++;
612 else
615 * Handle version 0.x compatibility.
619 struct JS_DATA_TYPE data;
621 data.buttons = jd->new.buttons[0];
622 data.x = jd->num_axes < 1 ? 0 :
623 ((js_correct(jd->new.axes[0], &jd->corr[0]) / 256) + 128) >> js_comp_glue.JS_CORR.x;
624 data.y = jd->num_axes < 2 ? 0 :
625 ((js_correct(jd->new.axes[1], &jd->corr[1]) / 256) + 128) >> js_comp_glue.JS_CORR.y;
627 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
628 retval = copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
629 #else
630 if (!(retval = verify_area(VERIFY_WRITE, buf, sizeof(struct JS_DATA_TYPE)))) {
631 memcpy_tofs(buf, &data, sizeof(struct JS_DATA_TYPE));
633 #endif
635 curl->startup = 0;
636 curl->tail = GOB(jd->bhead);
637 if (!retval) retval = sizeof(struct JS_DATA_TYPE);
641 * Check main tail and move it.
644 if (orig_tail == jd->tail) {
645 new_tail = curl->tail;
646 curl = jd->list;
647 while (curl != NULL && curl->tail != jd->tail) {
648 if (ROT(jd->bhead, new_tail, curl->tail) ||
649 (jd->bhead == curl->tail)) new_tail = curl->tail;
650 curl = curl->next;
652 if (curl == NULL) jd->tail = new_tail;
655 spin_unlock_irqrestore(&js_lock, flags);
657 return retval ? retval : written * sizeof(struct js_event);
661 * js_poll() does select() support.
664 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
666 static unsigned int js_poll(struct file *file, poll_table *wait)
668 struct js_list *curl = file->private_data;
669 unsigned long flags;
670 int retval = 0;
671 poll_wait(file, &curl->dev->wait, wait);
672 spin_lock_irqsave(&js_lock, flags);
673 if (GOF(curl->tail) != curl->dev->bhead ||
674 curl->startup < curl->dev->num_axes + curl->dev->num_buttons) retval = POLLIN | POLLRDNORM;
675 spin_unlock_irqrestore(&js_lock, flags);
676 return retval;
679 #else
681 static int js_select(struct inode *inode, struct file *file, int sel_type, select_table *wait)
683 struct js_list *curl = file->private_data;
684 if (sel_type == SEL_IN) {
685 if (GOF(curl->tail) != curl->dev->bhead) return 1;
686 select_wait(&curl->dev->wait, wait);
688 return 0;
691 #endif
694 * js_ioctl handles misc ioctl calls.
697 static int js_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
699 struct js_list *curl;
700 struct js_dev *jd;
701 int len;
703 curl = file->private_data;
704 jd = curl->dev;
706 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
708 switch (cmd) {
711 * 0.x compatibility
714 case JS_SET_CAL:
715 return copy_from_user(&js_comp_glue.JS_CORR, (struct JS_DATA_TYPE *) arg,
716 sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
717 case JS_GET_CAL:
718 return copy_to_user((struct JS_DATA_TYPE *) arg, &js_comp_glue.JS_CORR,
719 sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
720 case JS_SET_TIMEOUT:
721 return get_user(js_comp_glue.JS_TIMEOUT, (int *) arg);
722 case JS_GET_TIMEOUT:
723 return put_user(js_comp_glue.JS_TIMEOUT, (int *) arg);
724 case JS_SET_TIMELIMIT:
725 return get_user(js_comp_glue.JS_TIMELIMIT, (long *) arg);
726 case JS_GET_TIMELIMIT:
727 return put_user(js_comp_glue.JS_TIMELIMIT, (long *) arg);
728 case JS_SET_ALL:
729 return copy_from_user(&js_comp_glue, (struct JS_DATA_SAVE_TYPE *) arg,
730 sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
731 case JS_GET_ALL:
732 return copy_to_user((struct JS_DATA_SAVE_TYPE *) arg, &js_comp_glue,
733 sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
736 * 1.x ioctl calls
739 case JSIOCGVERSION:
740 return put_user(JS_VERSION, (__u32 *) arg);
741 case JSIOCGAXES:
742 return put_user(jd->num_axes, (__u8 *) arg);
743 case JSIOCGBUTTONS:
744 return put_user(jd->num_buttons, (__u8 *) arg);
745 case JSIOCSCORR:
746 return copy_from_user(jd->corr, (struct js_corr *) arg,
747 sizeof(struct js_corr) * jd->num_axes) ? -EFAULT : 0;
748 case JSIOCGCORR:
749 return copy_to_user((struct js_corr *) arg, jd->corr,
750 sizeof(struct js_corr) * jd->num_axes) ? -EFAULT : 0;
751 default:
752 if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
753 len = strlen(jd->name) + 1;
754 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
755 if (copy_to_user((char *) arg, jd->name, len)) return -EFAULT;
756 return len;
760 #else
762 switch (cmd) {
765 * 0.x compatibility
768 case JS_SET_CAL:
769 if (verify_area(VERIFY_READ, (struct JS_DATA_TYPE *) arg,
770 sizeof(struct JS_DATA_TYPE))) return -EFAULT;
771 memcpy_fromfs(&js_comp_glue.JS_CORR, (struct JS_DATA_SAVE_TYPE *) arg,
772 sizeof(struct JS_DATA_TYPE));
773 return 0;
774 case JS_GET_CAL:
775 if (verify_area(VERIFY_WRITE, (struct JS_DATA_TYPE *) arg,
776 sizeof(struct JS_DATA_TYPE))) return -EFAULT;
777 memcpy_tofs((struct JS_DATA_SAVE_TYPE *) arg, &js_comp_glue.JS_CORR,
778 sizeof(struct JS_DATA_TYPE));
779 return 0;
780 case JS_SET_TIMEOUT:
781 if (verify_area(VERIFY_READ, (int *) arg, sizeof(int))) return -EFAULT;
782 js_comp_glue.JS_TIMEOUT = get_user((int *) arg);
783 return 0;
784 case JS_GET_TIMEOUT:
785 if (verify_area(VERIFY_WRITE, (int *) arg, sizeof(int))) return -EFAULT;
786 put_user(js_comp_glue.JS_TIMEOUT, (int *) arg);
787 return 0;
788 case JS_SET_TIMELIMIT:
789 if (verify_area(VERIFY_READ, (long *) arg, sizeof(long))) return -EFAULT;
790 js_comp_glue.JS_TIMELIMIT = get_user((long *) arg);
791 return 0;
792 case JS_GET_TIMELIMIT:
793 if (verify_area(VERIFY_WRITE, (long *) arg, sizeof(long))) return -EFAULT;
794 put_user(js_comp_glue.JS_TIMELIMIT, (long *) arg);
795 return 0;
796 case JS_SET_ALL:
797 if (verify_area(VERIFY_READ, (struct JS_DATA_SAVE_TYPE *) arg,
798 sizeof(struct JS_DATA_SAVE_TYPE))) return -EFAULT;
799 memcpy_fromfs(&js_comp_glue, (struct JS_DATA_SAVE_TYPE *) arg,
800 sizeof(struct JS_DATA_SAVE_TYPE));
801 return 0;
802 case JS_GET_ALL:
803 if (verify_area(VERIFY_WRITE, (struct JS_DATA_SAVE_TYPE *) arg,
804 sizeof(struct JS_DATA_SAVE_TYPE))) return -EFAULT;
805 memcpy_tofs((struct JS_DATA_SAVE_TYPE *) arg, &js_comp_glue,
806 sizeof(struct JS_DATA_SAVE_TYPE));
807 return 0;
810 * 1.x ioctl calls
813 case JSIOCGVERSION:
814 if (verify_area(VERIFY_WRITE, (__u32 *) arg, sizeof(__u32))) return -EFAULT;
815 put_user(JS_VERSION, (__u32 *) arg);
816 return 0;
817 case JSIOCGAXES:
818 if (verify_area(VERIFY_WRITE, (__u8 *) arg, sizeof(__u8))) return -EFAULT;
819 put_user(jd->num_axes, (__u8 *) arg);
820 return 0;
821 case JSIOCGBUTTONS:
822 if (verify_area(VERIFY_WRITE, (__u8 *) arg, sizeof(__u8))) return -EFAULT;
823 put_user(jd->num_buttons, (__u8 *) arg);
824 return 0;
825 case JSIOCSCORR:
826 if (verify_area(VERIFY_READ, (struct js_corr *) arg,
827 sizeof(struct js_corr) * jd->num_axes)) return -EFAULT;
828 memcpy_fromfs(jd->corr, (struct js_corr *) arg,
829 sizeof(struct js_corr) * jd->num_axes);
830 return 0;
831 case JSIOCGCORR:
832 if (verify_area(VERIFY_WRITE, (struct js_corr *) arg,
833 sizeof(struct js_corr) * jd->num_axes)) return -EFAULT;
834 memcpy_tofs((struct js_corr *) arg,
835 jd->corr, sizeof(struct js_corr) * jd->num_axes);
836 return 0;
837 default:
838 if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
839 len = strlen(jd->name) + 1;
840 if (verify_area(VERIFY_WRITE, (char *) arg, len)) return -EFAULT;
841 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
842 memcpy_tofs((char *) arg, jd->name, len);
843 return len;
847 #endif
849 return -EINVAL;
853 * js_open() performs necessary initialization and adds
854 * an entry to the linked list.
857 static int js_open(struct inode *inode, struct file *file)
859 struct js_list *curl, *new;
860 struct js_dev *jd = js_dev;
861 int i = MINOR(inode->i_rdev);
862 unsigned long flags;
863 int result;
865 if (MAJOR(inode->i_rdev) != JOYSTICK_MAJOR)
866 return -EINVAL;
868 spin_lock_irqsave(&js_lock, flags);
870 while (i > 0 && jd != NULL) {
871 jd = jd->next;
872 i--;
875 spin_unlock_irqrestore(&js_lock, flags);
877 if (jd == NULL) return -ENODEV;
879 if ((result = jd->open(jd))) return result;
881 MOD_INC_USE_COUNT;
882 if (!js_use_count++) js_do_timer(0);
884 if ((new = kmalloc(sizeof(struct js_list), GFP_KERNEL)) != NULL) {
886 spin_lock_irqsave(&js_lock, flags);
888 curl = jd->list;
890 jd->list = new;
891 jd->list->next = curl;
892 jd->list->dev = jd;
893 jd->list->startup = 0;
894 jd->list->tail = GOB(jd->bhead);
895 file->private_data = jd->list;
897 spin_unlock_irqrestore(&js_lock, flags);
899 } else {
900 result = -ENOMEM;
903 return result;
907 * js_release() removes an entry from list and deallocates memory
908 * used by it.
911 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
912 static int js_release(struct inode *inode, struct file *file)
913 #else
914 static void js_release(struct inode *inode, struct file *file)
915 #endif
917 struct js_list *curl = file->private_data;
918 struct js_dev *jd = curl->dev;
919 struct js_list **curp = &jd->list;
920 int new_tail;
921 unsigned long flags;
923 spin_lock_irqsave(&js_lock, flags);
925 while (*curp && (*curp != curl)) curp = &((*curp)->next);
926 *curp = (*curp)->next;
928 if (jd->list != NULL)
929 if (curl->tail == jd->tail) {
930 curl = jd->list;
931 new_tail = curl->tail;
932 while (curl != NULL && curl->tail != jd->tail) {
933 if (ROT(jd->bhead, new_tail, curl->tail) ||
934 (jd->bhead == curl->tail)) new_tail = curl->tail;
935 curl = curl->next;
937 if (!curl) jd->tail = new_tail;
940 spin_unlock_irqrestore(&js_lock, flags);
942 kfree(file->private_data);
944 if (!--js_use_count) del_timer(&js_timer);
945 MOD_DEC_USE_COUNT;
947 jd->close(jd);
949 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
950 return 0;
951 #endif
955 * js_dump_mem() dumps all data structures in memory.
956 * It's used for debugging only.
959 #if 0
960 static void js_dump_mem(void)
963 struct js_port *curp = js_port;
964 struct js_dev *curd = js_dev;
965 int i;
967 printk(",--- Dumping Devices:\n");
968 printk("| js_dev = %x\n", (int) js_dev);
970 while (curd != NULL) {
971 printk("| %s-device %x, next %x axes %d, buttons %d, port %x - %#x\n",
972 curd->next ? "|":"`",
973 (int) curd, (int) curd->next, curd->num_axes, curd->num_buttons, (int) curd->port, curd->port->io);
974 curd = curd->next;
977 printk(">--- Dumping ports:\n");
978 printk("| js_port = %x\n", (int) js_port);
980 while (curp != NULL) {
981 printk("| %s-port %x, next %x, io %#x, devices %d\n",
982 curp->next ? "|":"`",
983 (int) curp, (int) curp->next, curp->io, curp->ndevs);
984 for (i = 0; i < curp->ndevs; i++) {
985 curd = curp->devs[i];
986 if (curd)
987 printk("| %s %s-device %x, next %x axes %d, buttons %d, port %x\n",
988 curp->next ? "|":" ", (i < curp->ndevs-1) ? "|":"`",
989 (int) curd, (int) curd->next, curd->num_axes, curd->num_buttons, (int) curd->port);
990 else
991 printk("| %s %s-device %x, not there\n",
992 curp->next ? "|":" ", (i < curp->ndevs-1) ? "|":"`", (int) curd);
995 curp = curp->next;
998 printk("`--- Done\n");
1000 #endif
1003 struct js_port *js_register_port(struct js_port *port,
1004 void *info, int devs, int infos, js_read_func read)
1006 struct js_port **ptrp = &js_port;
1007 struct js_port *curp;
1008 void *all;
1009 int i;
1010 unsigned long flags;
1012 if ((all = kmalloc(sizeof(struct js_port) + 4 * devs * sizeof(void*) + infos, GFP_KERNEL)) == NULL)
1013 return NULL;
1015 curp = all;
1017 curp->next = NULL;
1018 curp->prev = port;
1019 curp->read = read;
1020 curp->ndevs = devs;
1022 curp->devs = all += sizeof(struct js_port);
1023 for (i = 0; i < devs; i++) curp->devs[i] = NULL;
1025 curp->axes = all += devs * sizeof(void*);
1026 curp->buttons = (void*) all += devs * sizeof(void*);
1027 curp->corr = all += devs * sizeof(void*);
1029 if (infos) {
1030 curp->info = all += devs * sizeof(void*);
1031 memcpy(curp->info, info, infos);
1032 } else {
1033 curp->info = NULL;
1036 spin_lock_irqsave(&js_lock, flags);
1038 while (*ptrp != NULL) ptrp=&((*ptrp)->next);
1039 *ptrp = curp;
1041 spin_unlock_irqrestore(&js_lock, flags);
1043 return curp;
1046 struct js_port *js_unregister_port(struct js_port *port)
1048 struct js_port **curp = &js_port;
1049 struct js_port *prev;
1050 unsigned long flags;
1052 spin_lock_irqsave(&js_lock, flags);
1054 while (*curp != NULL && (*curp != port)) curp = &((*curp)->next);
1055 *curp = (*curp)->next;
1057 spin_unlock_irqrestore(&js_lock, flags);
1059 prev = port->prev;
1060 kfree(port);
1062 return prev;
1065 int js_register_device(struct js_port *port, int number, int axes, int buttons, char *name,
1066 js_ops_func open, js_ops_func close)
1068 struct js_dev **ptrd = &js_dev;
1069 struct js_dev *curd;
1070 void *all;
1071 int i = 0;
1072 unsigned long flags;
1074 if ((all = kmalloc(sizeof(struct js_dev) + 2 * axes * sizeof(int) +
1075 2 * (((buttons - 1) >> 5) + 1) * sizeof(int) +
1076 axes * sizeof(struct js_corr) + strlen(name) + 1, GFP_KERNEL)) == NULL)
1077 return -1;
1079 curd = all;
1081 curd->next = NULL;
1082 curd->list = NULL;
1083 curd->port = port;
1084 init_waitqueue_head(&curd->wait);
1085 curd->open = open;
1086 curd->close = close;
1088 curd->ahead = 0;
1089 curd->bhead = 0;
1090 curd->tail = JS_BUFF_SIZE - 1;
1091 curd->num_axes = axes;
1092 curd->num_buttons = buttons;
1094 curd->cur.axes = all += sizeof(struct js_dev);
1095 curd->cur.buttons = all += axes * sizeof(int);
1096 curd->new.axes = all += (((buttons - 1) >> 5) + 1) * sizeof(int);
1097 curd->new.buttons = all += axes * sizeof(int);
1098 curd->corr = all += (((buttons -1 ) >> 5) + 1) * sizeof(int);
1100 curd->name = all += axes * sizeof(struct js_corr);
1101 strcpy(curd->name, name);
1103 port->devs[number] = curd;
1104 port->axes[number] = curd->new.axes;
1105 port->buttons[number] = curd->new.buttons;
1106 port->corr[number] = curd->corr;
1108 spin_lock_irqsave(&js_lock, flags);
1110 while (*ptrd != NULL) { ptrd=&(*ptrd)->next; i++; }
1111 *ptrd = curd;
1113 spin_unlock_irqrestore(&js_lock, flags);
1115 return i;
1118 void js_unregister_device(struct js_dev *dev)
1120 struct js_dev **curd = &js_dev;
1121 unsigned long flags;
1123 spin_lock_irqsave(&js_lock, flags);
1125 while (*curd != NULL && (*curd != dev)) curd = &((*curd)->next);
1126 *curd = (*curd)->next;
1128 spin_unlock_irqrestore(&js_lock, flags);
1130 kfree(dev);
1134 * The operations structure.
1137 static struct file_operations js_fops =
1139 read: js_read,
1140 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
1141 poll: js_poll,
1142 #else
1143 select: js_select,
1144 #endif
1145 ioctl: js_ioctl,
1146 open: js_open,
1147 release: js_release,
1151 * js_init() registers the driver and calls the probe function.
1152 * also initializes some crucial variables.
1155 #ifdef MODULE
1156 int init_module(void)
1157 #else
1158 int __init js_init(void)
1159 #endif
1161 int result;
1163 js_setup_time();
1165 if (register_chrdev(JOYSTICK_MAJOR, "js", &js_fops)) {
1166 printk(KERN_ERR "js: unable to get major %d for joystick\n", JOYSTICK_MAJOR);
1167 return -EBUSY;
1170 spin_lock_init(&js_lock);
1172 init_timer(&js_timer);
1173 js_timer.function = js_do_timer;
1174 js_timer.data = 1;
1176 memset(&js_comp_glue, 0, sizeof(struct JS_DATA_SAVE_TYPE));
1177 js_comp_glue.JS_TIMEOUT = JS_DEF_TIMEOUT;
1178 js_comp_glue.JS_TIMELIMIT = JS_DEF_TIMELIMIT;
1180 #ifdef MODULE
1181 result = 0;
1182 #else
1183 result = -ENODEV;
1184 #ifdef CONFIG_JOY_LIGHTNING
1185 if (!js_l4_init()) result = 0;
1186 #endif
1187 #ifdef CONFIG_JOY_SIDEWINDER
1188 if (!js_sw_init()) result = 0;
1189 #endif
1190 #ifdef CONFIG_JOY_ASSASIN
1191 if (!js_as_init()) result = 0;
1192 #endif
1193 #ifdef CONFIG_JOY_LOGITECH
1194 if (!js_lt_init()) result = 0;
1195 #endif
1196 #ifdef CONFIG_JOY_THRUSTMASTER
1197 if (!js_tm_init()) result = 0;
1198 #endif
1199 #ifdef CONFIG_JOY_GRAVIS
1200 if (!js_gr_init()) result = 0;
1201 #endif
1202 #ifdef CONFIG_JOY_ANALOG
1203 if (!js_an_init()) result = 0;
1204 #endif
1205 #ifdef CONFIG_JOY_CONSOLE
1206 if (!js_console_init()) result = 0;
1207 #endif
1208 #ifdef CONFIG_JOY_DB9
1209 if (!js_db9_init()) result = 0;
1210 #endif
1211 #ifdef CONFIG_JOY_AMIGA
1212 if (!js_am_init()) result = 0;
1213 #endif
1214 if (result) printk(KERN_ERR "js: no joysticks found\n");
1215 #endif
1217 return result;
1221 * cleanup_module() handles module removal.
1224 #ifdef MODULE
1225 void cleanup_module(void)
1227 del_timer(&js_timer);
1228 if (unregister_chrdev(JOYSTICK_MAJOR, "js"))
1229 printk(KERN_ERR "js: can't unregister device\n");
1231 #endif