patch-2.3.36 linux/drivers/usb/keyboard.c

Next file: linux/drivers/usb/keymap-mac.c
Previous file: linux/drivers/usb/keybdev.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.35/linux/drivers/usb/keyboard.c linux/drivers/usb/keyboard.c
@@ -1,295 +0,0 @@
-/*
-	Fixes:
-	1999/09/04 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-		Handle states in usb_kbd_irq
-	1999/09/06 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-		rmmod usb-keyboard doesn't crash the system anymore: the irq
-		handlers are correctly released with usb_release_irq
-*/
-#include <linux/kernel.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/kbd_ll.h>
-#include "usb.h"
-
-#define PCKBD_PRESSED  0x00
-#define PCKBD_RELEASED 0x80
-#define PCKBD_NEEDS_E0 0x80
-
-#define USBKBD_MODIFIER_BASE  224
-#define USBKBD_KEYCODE_OFFSET 2
-#define USBKBD_KEYCODE_COUNT  6
-
-#define USBKBD_VALID_KEYCODE(key) ((unsigned char)(key) > 3)
-#define USBKBD_FIND_KEYCODE(down, key, count) \
-    ((unsigned char*) memscan((down), (key), (count)) < ((down) + (count)))
-
-#define USBKBD_REPEAT_DELAY (HZ / 4)
-#define USBKBD_REPEAT_RATE (HZ / 20)
-
-struct usb_keyboard {
-	struct usb_device *dev;
-	unsigned long down[2];
-	unsigned char repeat_key;
-	struct timer_list repeat_timer;
-	struct list_head list;
-	unsigned int irqpipe;
-	void *irq_handler;	/* host controller's IRQ transfer handle */
-};
-
-extern unsigned char usb_kbd_map[];
-
-static void *usb_kbd_probe(struct usb_device *dev, unsigned int i);
-static void usb_kbd_disconnect(struct usb_device *dev, void *ptr);
-static void usb_kbd_repeat(unsigned long dummy);
-
-static LIST_HEAD(usb_kbd_list);
-
-static struct usb_driver usb_kbd_driver = {
-	"keyboard",
-	usb_kbd_probe,
-	usb_kbd_disconnect,
-	{NULL, NULL}
-};
-
-
-static void usb_kbd_handle_key(unsigned char key, int down)
-{
-	int scancode = (int) usb_kbd_map[key];
-	if (scancode) {
-#ifndef CONFIG_MAC_KEYBOARD
-		if (scancode & PCKBD_NEEDS_E0) {
-			handle_scancode(0xe0, 1);
-		}
-#endif				/* CONFIG_MAC_KEYBOARD */
-		handle_scancode((scancode & ~PCKBD_NEEDS_E0), down);
-	}
-}
-
-static void usb_kbd_repeat(unsigned long dev_id)
-{
-	struct usb_keyboard *kbd = (struct usb_keyboard *) dev_id;
-
-	unsigned long flags;
-	save_flags(flags);
-	cli();
-
-	if (kbd->repeat_key) {
-		usb_kbd_handle_key(kbd->repeat_key, 1);
-
-		/* reset repeat timer */
-		kbd->repeat_timer.function = usb_kbd_repeat;
-		kbd->repeat_timer.expires = jiffies + USBKBD_REPEAT_RATE;
-		kbd->repeat_timer.data = (unsigned long) kbd;
-		kbd->repeat_timer.prev = NULL;
-		kbd->repeat_timer.next = NULL;
-		add_timer(&kbd->repeat_timer);
-	}
-
-	restore_flags(flags);
-}
-
-static int usb_kbd_irq(int state, void *buffer, int len, void *dev_id)
-{
-	struct usb_keyboard *kbd = (struct usb_keyboard *) dev_id;
-	unsigned long *down = (unsigned long *) buffer;
-
-	/*
-	 * USB_ST_NOERROR is the normal case.
-	 * USB_ST_REMOVED occurs if keyboard disconnected
-	 * On other states, ignore
-	 */
-
-	switch (state) {
-	case USB_ST_REMOVED:
-	case USB_ST_INTERNALERROR:
-		printk(KERN_DEBUG "%s(%d): Suspending\n", __FILE__,
-		       __LINE__);
-		return 0;	/* disable */
-	case USB_ST_NOERROR:
-		break;
-	default:
-		return 1;	/* ignore */
-	}
-
-	if (kbd->down[0] != down[0] || kbd->down[1] != down[1]) {
-		unsigned char *olddown, *newdown;
-		unsigned char modsdelta, key;
-		int i;
-
-		/* handle modifier change */
-		modsdelta =
-		    (*(unsigned char *) down ^ *(unsigned char *) kbd->
-		     down);
-		if (modsdelta) {
-			for (i = 0; i < 8; i++) {
-				if (modsdelta & 0x01) {
-					int pressed =
-					    (*(unsigned char *) down >> i)
-					    & 0x01;
-					usb_kbd_handle_key(i +
-							   USBKBD_MODIFIER_BASE,
-							   pressed);
-				}
-				modsdelta >>= 1;
-			}
-		}
-
-		olddown =
-		    (unsigned char *) kbd->down + USBKBD_KEYCODE_OFFSET;
-		newdown = (unsigned char *) down + USBKBD_KEYCODE_OFFSET;
-
-		/* handle released keys */
-		for (i = 0; i < USBKBD_KEYCODE_COUNT; i++) {
-			key = olddown[i];
-			if (USBKBD_VALID_KEYCODE(key)
-			    && !USBKBD_FIND_KEYCODE(newdown, key,
-						    USBKBD_KEYCODE_COUNT))
-			{
-				usb_kbd_handle_key(key, 0);
-			}
-		}
-
-		/* handle pressed keys */
-		kbd->repeat_key = 0;
-		for (i = 0; i < USBKBD_KEYCODE_COUNT; i++) {
-			key = newdown[i];
-			if (USBKBD_VALID_KEYCODE(key)
-			    && !USBKBD_FIND_KEYCODE(olddown, key,
-						    USBKBD_KEYCODE_COUNT))
-			{
-				usb_kbd_handle_key(key, 1);
-				kbd->repeat_key = key;
-			}
-		}
-
-		/* set repeat timer if any keys were pressed */
-		if (kbd->repeat_key) {
-			del_timer(&kbd->repeat_timer);
-			kbd->repeat_timer.function = usb_kbd_repeat;
-			kbd->repeat_timer.expires =
-			    jiffies + USBKBD_REPEAT_DELAY;
-			kbd->repeat_timer.data = (unsigned long) kbd;
-			kbd->repeat_timer.prev = NULL;
-			kbd->repeat_timer.next = NULL;
-			add_timer(&kbd->repeat_timer);
-		}
-
-		kbd->down[0] = down[0];
-		kbd->down[1] = down[1];
-	}
-
-	return 1;
-}
-
-static void *usb_kbd_probe(struct usb_device *dev, unsigned int i)
-{
-	struct usb_interface_descriptor *interface;
-	struct usb_endpoint_descriptor *endpoint;
-	struct usb_keyboard *kbd;
-	int ret;
-
-	interface = &dev->actconfig->interface[i].altsetting[0];
-	endpoint = &interface->endpoint[0];
-
-	if (interface->bInterfaceClass != 3
-	    || interface->bInterfaceSubClass != 1
-	    || interface->bInterfaceProtocol != 1) {
-		return NULL;
-	}
-
-	printk(KERN_INFO "USB HID boot protocol keyboard detected.\n");
-
-	kbd = kmalloc(sizeof(struct usb_keyboard), GFP_KERNEL);
-	if (kbd) {
-		memset(kbd, 0, sizeof(*kbd));
-		kbd->dev = dev;
-
-		usb_set_protocol(dev, 0);
-		usb_set_idle(dev, 0, 0);
-
-		kbd->irqpipe =
-		    usb_rcvintpipe(dev, endpoint->bEndpointAddress);
-		ret =
-		    usb_request_irq(dev, kbd->irqpipe, usb_kbd_irq,
-				    endpoint->bInterval, kbd,
-				    &kbd->irq_handler);
-		if (ret) {
-			printk(KERN_INFO
-			       "usb-keyboard failed usb_request_irq (0x%x)\n",
-			       ret);
-			goto probe_err;
-		}
-
-		list_add(&kbd->list, &usb_kbd_list);
-
-		return kbd;
-	}
-
-probe_err:
-	if (kbd)
-		kfree(kbd);
-	return NULL;
-}
-
-static void usb_kbd_disconnect(struct usb_device *dev, void *ptr)
-{
-	struct usb_keyboard *kbd = (struct usb_keyboard *) ptr;
-	if (kbd) {
-		usb_release_irq(dev, kbd->irq_handler, kbd->irqpipe);
-		list_del(&kbd->list);
-		del_timer(&kbd->repeat_timer);
-		kfree(kbd);
-	}
-
-	printk(KERN_INFO "USB HID boot protocol keyboard removed.\n");
-}
-
-int usb_kbd_init(void)
-{
-	return usb_register(&usb_kbd_driver);
-}
-
-void usb_kbd_cleanup(void)
-{
-	struct list_head *cur, *head = &usb_kbd_list;
-
-	cur = head->next;
-
-	while (cur != head) {
-		struct usb_keyboard *kbd =
-		    list_entry(cur, struct usb_keyboard, list);
-
-		cur = cur->next;
-
-		list_del(&kbd->list);
-		INIT_LIST_HEAD(&kbd->list);
-
-		if (kbd->irq_handler) {
-			usb_release_irq(kbd->dev, kbd->irq_handler,
-					kbd->irqpipe);
-			/* never keep a reference to a released IRQ! */
-			kbd->irq_handler = NULL;
-		}
-	}
-
-	usb_deregister(&usb_kbd_driver);
-}
-
-#ifdef MODULE
-int init_module(void)
-{
-	return usb_kbd_init();
-}
-
-void cleanup_module(void)
-{
-	usb_kbd_cleanup();
-}
-
-#endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)