USB keyboard and mouse "embedded" drivers from cromwell and linux 2.5.0 usb stack...
authorAleksey Bragin <aleksey@reactos.org>
Fri, 12 Aug 2005 19:54:40 +0000 (19:54 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Fri, 12 Aug 2005 19:54:40 +0000 (19:54 +0000)
svn path=/trunk/; revision=17349

reactos/drivers/usb/cromwell/core/core_drivers/usbkey.c [new file with mode: 0644]
reactos/drivers/usb/cromwell/core/core_drivers/usbmouse.c [new file with mode: 0644]

diff --git a/reactos/drivers/usb/cromwell/core/core_drivers/usbkey.c b/reactos/drivers/usb/cromwell/core/core_drivers/usbkey.c
new file mode 100644 (file)
index 0000000..a37ffb6
--- /dev/null
@@ -0,0 +1,236 @@
+/*\r
+ This driver is based on Cromwell's usbkey driver\r
+ and also includes stuff from Linux 2.5 usbkey driver by Vojtech Pavlik\r
+*/\r
+\r
+#define NDEBUG\r
+#include "../../usb_wrapper.h"\r
+\r
+#define keyboarddebug  0\r
+\r
+#if keyboarddebug\r
+//extern int printk(const char *szFormat, ...);\r
+#endif\r
+\r
+unsigned int current_keyboard_key;\r
+\r
+extern USBPORT_INTERFACE UsbPortInterface;\r
+\r
+static unsigned char usb_kbd_keycode[256] = {\r
+         0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,\r
+        50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,\r
+         4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,\r
+        27, 43, 84, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,\r
+        65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,\r
+       105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,\r
+        72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95,\r
+       120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113,\r
+       115,114,  0,  0,  0,124,  0,181,182,183,184,185,186,187,188,189,\r
+       190,191,192,193,194,195,196,197,198,  0,  0,  0,  0,  0,  0,  0,\r
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\r
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\r
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\r
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\r
+        29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,\r
+       150,158,159,128,136,177,178,176,142,152,173,140\r
+};\r
+\r
+struct usb_kbd_info {\r
+       struct urb *urb;\r
+       unsigned char kbd_pkt[8];\r
+       unsigned char old[8];\r
+\r
+       /*\r
+       struct input_dev dev;\r
+       struct usb_device *usbdev;\r
+       struct urb irq, led;\r
+       struct usb_ctrlrequest dr;\r
+       unsigned char leds, newleds;\r
+       char name[128];\r
+       int open;\r
+       */\r
+};\r
+\r
+/**\r
+ * memscan - Find a character in an area of memory.\r
+ * @addr: The memory area\r
+ * @c: The byte to search for\r
+ * @size: The size of the area.\r
+ *\r
+ * returns the address of the first occurrence of @c, or 1 byte past\r
+ * the area if @c is not found\r
+ */\r
+void * memscan(void * addr, int c, size_t size)\r
+{\r
+       unsigned char * p = (unsigned char *) addr;\r
+\r
+       while (size) {\r
+               if (*p == c)\r
+                       return (void *) p;\r
+               p++;\r
+               size--;\r
+       }\r
+       return (void *) p;\r
+}\r
+\r
+void input_report_key(unsigned int code, int value)\r
+{\r
+       KEYBOARD_INPUT_DATA KeyboardInputData;\r
+       ULONG InputDataConsumed;\r
+\r
+       KeyboardInputData.MakeCode = code;\r
+       KeyboardInputData.Flags = (value == 1) ? KEY_MAKE : KEY_BREAK;\r
+\r
+       if (UsbPortInterface.KbdConnectData->ClassService)\r
+       {\r
+               KIRQL OldIrql;\r
+\r
+               KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);\r
+               (*(PSERVICE_CALLBACK_ROUTINE)UsbPortInterface.KbdConnectData->ClassService)(\r
+                       UsbPortInterface.KbdConnectData->ClassDeviceObject,\r
+                       &KeyboardInputData,\r
+                       (&KeyboardInputData)+1,\r
+                       &InputDataConsumed);\r
+               KeLowerIrql(OldIrql);\r
+       }\r
+}\r
+\r
+static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)\r
+{\r
+       struct usb_kbd_info *kbd = urb->context;\r
+       int i;\r
+\r
+       if (urb->status) return;\r
+\r
+       memcpy(kbd->kbd_pkt, urb->transfer_buffer, 8);\r
+\r
+       //for (i = 0; i < 8; i++)\r
+       //      input_report_key(usb_kbd_keycode[i + 224], (kbd->kbd_pkt[0] >> i) & 1);\r
+\r
+       for (i = 2; i < 8; i++) {\r
+\r
+               if (kbd->old[i] > 3 && memscan(kbd->kbd_pkt + 2, kbd->old[i], 6) == kbd->kbd_pkt + 8) {\r
+                       if (usb_kbd_keycode[kbd->old[i]])\r
+                               input_report_key(usb_kbd_keycode[kbd->old[i]], 0);\r
+                       else\r
+                               info("Unknown key (scancode %#x) released.", kbd->old[i]);\r
+               }\r
+\r
+               if (kbd->kbd_pkt[i] > 3 && memscan(kbd->old + 2, kbd->kbd_pkt[i], 6) == kbd->old + 8) {\r
+                       if (usb_kbd_keycode[kbd->kbd_pkt[i]])\r
+                               input_report_key(usb_kbd_keycode[kbd->kbd_pkt[i]], 1);\r
+                       else\r
+                               info("Unknown key (scancode %#x) pressed.", kbd->kbd_pkt[i]);\r
+               }\r
+       }\r
+\r
+       memcpy(kbd->old, kbd->kbd_pkt, 8);\r
+\r
+#if 0\r
+       //memcpy(kbd->kbd_pkt, urb->transfer_buffer, 8);\r
+       //current_keyboard_key = kbd->kbd_pkt[2];\r
+       {\r
+               KEYBOARD_INPUT_DATA KeyboardInputData;\r
+               ULONG InputDataConsumed;\r
+\r
+               KeyboardInputData.MakeCode = current_keyboard_key & ~0x80;\r
+               KeyboardInputData.Flags = (current_keyboard_key & 0x80) ? KEY_MAKE : KEY_BREAK;\r
+\r
+               if (UsbPortInterface.KbdConnectData->ClassService)\r
+               {\r
+                       KIRQL OldIrql;\r
+\r
+                       KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);\r
+                       (*(PSERVICE_CALLBACK_ROUTINE)UsbPortInterface.KbdConnectData->ClassService)(\r
+                               UsbPortInterface.KbdConnectData->ClassDeviceObject,\r
+                               &KeyboardInputData,\r
+                               (&KeyboardInputData)+1,\r
+                               &InputDataConsumed);\r
+                       KeLowerIrql(OldIrql);\r
+               }\r
+       }\r
+#endif\r
+       \r
+       \r
+       #if keyboarddebug\r
+       printk(" -%02x %02x %02x %02x %02x %02x\n",kbd->kbd_pkt[0],kbd->kbd_pkt[1],kbd->kbd_pkt[2],kbd->kbd_pkt[3],kbd->kbd_pkt[4],kbd->kbd_pkt[5]);\r
+       #endif\r
+       \r
+       usb_submit_urb(urb,GFP_ATOMIC);\r
+               \r
+}\r
+\r
+static int usb_kbd_probe(struct usb_interface *intf, const struct usb_device_id *id)\r
+{\r
+       struct urb *urb;\r
+       struct usb_device *udev = interface_to_usbdev (intf);\r
+       struct usb_endpoint_descriptor *ep_irq_in;\r
+       //struct usb_endpoint_descriptor *ep_irq_out;\r
+       struct usb_kbd_info *usbk;\r
+\r
+       //int i, pipe, maxp;\r
+       //char *buf;\r
+\r
+       usbk=(struct usb_kbd_info *)kmalloc(sizeof(struct usb_kbd_info),0);\r
+       if (!usbk) return -1;\r
+    memset(usbk, 0, sizeof(struct usb_kbd_info));\r
+\r
+       urb=usb_alloc_urb(0,0);\r
+       if (!urb) return -1;\r
+\r
+       usbk->urb=urb;\r
+\r
+       ep_irq_in = &intf->altsetting[0].endpoint[0].desc;\r
+       usb_fill_int_urb(urb, udev,\r
+                         usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),\r
+                         usbk->kbd_pkt, 8, usb_kbd_irq,\r
+                         usbk, 8);\r
+\r
+       usb_submit_urb(urb,GFP_ATOMIC);\r
+       usb_set_intfdata(intf,usbk);\r
+       #if keyboarddebug\r
+       printk("USB Keyboard Connected\n");     \r
+       #endif\r
+\r
+       return 0;\r
+}\r
+\r
+\r
+static void usb_kbd_disconnect(struct usb_interface *intf)\r
+{\r
+       struct usb_kbd_info *usbk = usb_get_intfdata (intf);\r
+       usbprintk("Keyboard disconnected\n ");\r
+       usb_unlink_urb(usbk->urb);\r
+       usb_free_urb(usbk->urb);\r
+       kfree(usbk);\r
+}\r
+\r
+static struct usb_device_id usb_kbd_id_table [] = {\r
+       { USB_INTERFACE_INFO(3, 1, 1) },\r
+       { }                                             /* Terminating entry */\r
+};\r
+\r
+\r
+static struct usb_driver usb_kbd_driver = {\r
+       .owner =                THIS_MODULE,\r
+       .name =                 "keyboard",\r
+       .probe =                usb_kbd_probe,\r
+       .disconnect =           usb_kbd_disconnect,\r
+       .id_table =             usb_kbd_id_table,\r
+};\r
+\r
+void UsbKeyBoardInit(void)\r
+{\r
+       //current_remote_key=0;\r
+       //sbprintk("Keyboard probe %p ",xremote_probe);\r
+       if (usb_register(&usb_kbd_driver) < 0) {\r
+               #if keyboarddebug\r
+               printk("Unable to register Keyboard driver");\r
+               #endif\r
+               return;\r
+       }       \r
+}\r
+\r
+void UsbKeyBoardRemove(void) {\r
+       usb_deregister(&usb_kbd_driver);\r
+}\r
diff --git a/reactos/drivers/usb/cromwell/core/core_drivers/usbmouse.c b/reactos/drivers/usb/cromwell/core/core_drivers/usbmouse.c
new file mode 100644 (file)
index 0000000..bef9a12
--- /dev/null
@@ -0,0 +1,279 @@
+/*\r
+ This driver is based on Linux 2.5.75 usbmouse driver by Vojtech Pavlik\r
+*/\r
+
+#define NDEBUG
+#include "../../usb_wrapper.h"\r
+
+extern USBPORT_INTERFACE UsbPortInterface;\r
+
+struct usb_mouse {
+       char name[128];
+       char phys[64];
+       struct usb_device *usbdev;
+       char btn_old;
+       //struct input_dev dev;
+       struct urb *irq;
+       int open;
+
+       signed char *data;
+       dma_addr_t data_dma;
+};
+
+static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)
+{
+       struct usb_mouse *mouse = urb->context;
+       signed char *data = mouse->data;
+       int status;
+
+       switch (urb->status) {
+       case 0:                 /* success */
+               break;
+       case -ECONNRESET:       /* unlink */
+       case -ENOENT:
+       case -ESHUTDOWN:
+               return;
+       /* -EPIPE:  should clear the halt */
+       default:                /* error */
+               goto resubmit;
+       }
+/*
+       input_regs(dev, regs);
+
+       input_report_key(dev, BTN_LEFT,   data[0] & 0x01);
+       input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);
+       input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);
+       input_report_key(dev, BTN_SIDE,   data[0] & 0x08);
+       input_report_key(dev, BTN_EXTRA,  data[0] & 0x10);
+
+       input_report_rel(dev, REL_X,     data[1]);
+       input_report_rel(dev, REL_Y,     data[2]);
+       input_report_rel(dev, REL_WHEEL, data[3]);
+
+       input_sync(dev);
+*/
+
+       {
+               MOUSE_INPUT_DATA MouseInputData;\r
+               ULONG InputDataConsumed;\r
+\r
+               MouseInputData.Flags = MOUSE_MOVE_RELATIVE;\r
+               MouseInputData.LastX = data[1];\r
+               MouseInputData.LastY = data[2];\r
+\r
+               MouseInputData.ButtonFlags = 0;\r
+               MouseInputData.ButtonData = 0;\r
+\r
+               if ((data[0] & 0x01) && ((mouse->btn_old & 0x01) != (data[0] & 0x01)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_LEFT_BUTTON_DOWN;\r
+               else if (!(data[0] & 0x01) && ((mouse->btn_old & 0x01) != (data[0] & 0x01)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_LEFT_BUTTON_UP;\r
+\r
+               if ((data[0] & 0x02) && ((mouse->btn_old & 0x02) != (data[0] & 0x02)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_RIGHT_BUTTON_DOWN;\r
+               else if (!(data[0] & 0x02) && ((mouse->btn_old & 0x02) != (data[0] & 0x02)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_RIGHT_BUTTON_UP;\r
+\r
+               if ((data[0] & 0x04) && ((mouse->btn_old & 0x04) != (data[0] & 0x04)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_MIDDLE_BUTTON_DOWN;\r
+               else if (!(data[0] & 0x04) && ((mouse->btn_old & 0x04) != (data[0] & 0x04)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_MIDDLE_BUTTON_UP;\r
+\r
+               if ((data[0] & 0x08) && ((mouse->btn_old & 0x08) != (data[0] & 0x08)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_BUTTON_4_DOWN;\r
+               else if (!(data[0] & 0x08) && ((mouse->btn_old & 0x08) != (data[0] & 0x08)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_BUTTON_4_UP;\r
+\r
+               if ((data[0] & 0x10) && ((mouse->btn_old & 0x10) != (data[0] & 0x10)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_BUTTON_5_DOWN;\r
+               else if (!(data[0] & 0x10) && ((mouse->btn_old & 0x10) != (data[0] & 0x10)))\r
+                       MouseInputData.ButtonFlags |= MOUSE_BUTTON_5_UP;\r
+\r
+               if (data[3])\r
+               {\r
+                       MouseInputData.ButtonFlags |= MOUSE_WHEEL;\r
+                       MouseInputData.ButtonData = data[3];\r
+               }\r
+        \r
+               if (UsbPortInterface.MouseConnectData->ClassService)\r
+               {\r
+                       KIRQL OldIrql;\r
+\r
+                       KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);\r
+                       (*(PSERVICE_CALLBACK_ROUTINE)UsbPortInterface.MouseConnectData->ClassService)(\r
+                               UsbPortInterface.MouseConnectData->ClassDeviceObject,\r
+                               &MouseInputData,\r
+                               (&MouseInputData)+1,\r
+                               &InputDataConsumed);\r
+                       KeLowerIrql(OldIrql);\r
+               }\r
+\r
+               mouse->btn_old = data[0];\r
+\r
+               // debug info\r
+               printk("MouseInputData.Buttons=0x%03x\n", MouseInputData.Buttons);\r
+       }\r
+
+       printk("Mouse input: x %d, y %d, w %d, btn: 0x%02x\n", data[1], data[2], data[3], data[0]);
+
+resubmit:
+       status = usb_submit_urb (urb, SLAB_ATOMIC);
+       if (status)
+               err ("can't resubmit intr, %s-%s/input0, status %d",
+                               mouse->usbdev->bus->bus_name,
+                               mouse->usbdev->devpath, status);
+}
+/*
+static int usb_mouse_open(struct input_dev *dev)
+{
+       struct usb_mouse *mouse = dev->private;
+
+       if (mouse->open++)
+               return 0;
+
+       mouse->irq->dev = mouse->usbdev;
+       if (usb_submit_urb(mouse->irq, GFP_KERNEL)) {
+               mouse->open--;
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static void usb_mouse_close(struct input_dev *dev)
+{
+       struct usb_mouse *mouse = dev->private;
+
+       if (!--mouse->open)
+               usb_unlink_urb(mouse->irq);
+}
+*/
+
+static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id)
+{
+       struct usb_device * dev = interface_to_usbdev(intf);
+       struct usb_host_interface *interface;
+       struct usb_endpoint_descriptor *endpoint;
+       struct usb_mouse *mouse;
+       int pipe, maxp;
+       char path[64];
+       char *buf;
+
+       interface = &intf->altsetting[intf->act_altsetting];
+
+       if (interface->desc.bNumEndpoints != 1) 
+               return -ENODEV;
+
+       endpoint = &interface->endpoint[0].desc;
+       if (!(endpoint->bEndpointAddress & 0x80)) 
+               return -ENODEV;
+       if ((endpoint->bmAttributes & 3) != 3) 
+               return -ENODEV;
+
+       pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
+       maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+
+       if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) 
+               return -ENOMEM;
+       memset(mouse, 0, sizeof(struct usb_mouse));
+
+       mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
+       if (!mouse->data) {
+               kfree(mouse);
+               return -ENOMEM;
+       }
+
+       mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
+       if (!mouse->irq) {
+               usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
+               kfree(mouse);
+               return -ENODEV;
+       }
+
+       mouse->usbdev = dev;
+
+       usb_make_path(dev, path, 64);
+       sprintf(mouse->phys, "%s/input0", path);
+
+       if (!(buf = kmalloc(63, GFP_KERNEL))) {
+               usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
+               kfree(mouse);
+               return -ENOMEM;
+       }
+
+       if (dev->descriptor.iManufacturer &&
+               usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0)
+                       strcat(mouse->name, buf);
+       if (dev->descriptor.iProduct &&
+               usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
+                       sprintf(mouse->name, "%s %s", mouse->name, buf);
+
+       if (!strlen(mouse->name))
+               sprintf(mouse->name, "USB HIDBP Mouse %04x:%04x",
+                       dev->descriptor.idVendor, dev->descriptor.idProduct);
+
+       kfree(buf);
+
+       usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
+                        (maxp > 8 ? 8 : maxp),
+                        usb_mouse_irq, mouse, endpoint->bInterval);
+       //mouse->irq->transfer_dma = mouse->data_dma;
+       //mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
+
+       usb_set_intfdata(intf, mouse);
+
+       // Open device
+       mouse->irq->dev = mouse->usbdev;
+       if (usb_submit_urb(mouse->irq, GFP_KERNEL)) {
+               return -EIO;
+       }
+
+       mouse->btn_old = 0;
+
+       return 0;
+}
+
+static void usb_mouse_disconnect(struct usb_interface *intf)
+{
+       struct usb_mouse *mouse = usb_get_intfdata (intf);
+       
+       usb_set_intfdata(intf, NULL);
+       usbprintk("Mouse disconnected\n ");\r
+       if (mouse) {
+               usb_unlink_urb(mouse->irq);
+               usb_free_urb(mouse->irq);
+               usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
+               kfree(mouse);
+       }
+}
+
+static struct usb_device_id usb_mouse_id_table [] = {
+       { USB_INTERFACE_INFO(3, 1, 2) },
+    { }                                                /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
+
+static struct usb_driver usb_mouse_driver = {
+       .owner          = THIS_MODULE,
+       .name           = "usbmouse",
+       .probe          = usb_mouse_probe,
+       .disconnect     = usb_mouse_disconnect,
+       .id_table       = usb_mouse_id_table,
+};
+
+void UsbMouseInit(void)\r
+{\r
+       if (usb_register(&usb_mouse_driver) < 0) {\r
+               #if mousedebug\r
+               printk("Unable to register Mouse driver");\r
+               #endif\r
+               return;\r
+       }       \r
+}\r
+\r
+void UsbMouseRemove(void) {\r
+       usb_deregister(&usb_mouse_driver);\r
+}\r