[PARISC] Convert HIL drivers to use input_allocate_device
Helge Deller [Sun, 26 Mar 2006 14:41:55 +0000 (07:41 -0700)]
Convert HIL drivers to use input_allocate_device() - avoids crashes.

Signed-off-by: Helge Deller <deller@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>

drivers/input/keyboard/hil_kbd.c
drivers/input/keyboard/hilkbd.c
drivers/input/mouse/hil_ptr.c

index 0a90962..99f8c5b 100644 (file)
@@ -66,7 +66,7 @@ static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] =
 static char hil_language[][16] = { HIL_LOCALE_MAP };
 
 struct hil_kbd {
-       struct input_dev dev;
+       struct input_dev *dev;
        struct serio *serio;
 
        /* Input buffer and index for packets from HIL bus. */
@@ -86,7 +86,7 @@ struct hil_kbd {
 /* Process a complete packet after transfer from the HIL */
 static void hil_kbd_process_record(struct hil_kbd *kbd)
 {
-       struct input_dev *dev = &kbd->dev;
+       struct input_dev *dev = kbd->dev;
        hil_packet *data = kbd->data;
        hil_packet p;
        int idx, i, cnt;
@@ -240,8 +240,9 @@ static void hil_kbd_disconnect(struct serio *serio)
                return;
        }
 
-       input_unregister_device(&kbd->dev);
+       input_unregister_device(kbd->dev);
        serio_close(serio);
+       input_free_device(kbd->dev);
        kfree(kbd);
 }
 
@@ -251,16 +252,18 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
        uint8_t         did, *idd;
        int             i;
        
-       kbd = kmalloc(sizeof(*kbd), GFP_KERNEL);
+       kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
        if (!kbd)
                return -ENOMEM;
-       memset(kbd, 0, sizeof(struct hil_kbd));
+
+       kbd->dev = input_allocate_device();
+       if (!kbd->dev) goto bail1;
+       kbd->dev->private = kbd;
 
        if (serio_open(serio, drv)) goto bail0;
 
        serio_set_drvdata(serio, kbd);
        kbd->serio = serio;
-       kbd->dev.private = kbd;
 
        init_MUTEX_LOCKED(&(kbd->sem));
 
@@ -302,38 +305,38 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
                        did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]);
                break;
        default:
-               goto bail1;
+               goto bail2;
        }
 
        if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) {
                printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n");
-               goto bail1;
+               goto bail2;
        }
 
 
-       kbd->dev.evbit[0]       = BIT(EV_KEY) | BIT(EV_REP);
-       kbd->dev.ledbit[0]      = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
-       kbd->dev.keycodemax     = HIL_KEYCODES_SET1_TBLSIZE;
-       kbd->dev.keycodesize    = sizeof(hil_kbd_set1[0]);
-       kbd->dev.keycode        = hil_kbd_set1;
-       kbd->dev.name           = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME;
-       kbd->dev.phys           = "hpkbd/input0";       /* XXX */
+       kbd->dev->evbit[0]      = BIT(EV_KEY) | BIT(EV_REP);
+       kbd->dev->ledbit[0]     = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+       kbd->dev->keycodemax    = HIL_KEYCODES_SET1_TBLSIZE;
+       kbd->dev->keycodesize   = sizeof(hil_kbd_set1[0]);
+       kbd->dev->keycode       = hil_kbd_set1;
+       kbd->dev->name          = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME;
+       kbd->dev->phys          = "hpkbd/input0";       /* XXX */
 
-       kbd->dev.id.bustype     = BUS_HIL;
-       kbd->dev.id.vendor      = PCI_VENDOR_ID_HP;
-       kbd->dev.id.product     = 0x0001; /* TODO: get from kbd->rsc */
-       kbd->dev.id.version     = 0x0100; /* TODO: get from kbd->rsc */
-       kbd->dev.dev            = &serio->dev;
+       kbd->dev->id.bustype    = BUS_HIL;
+       kbd->dev->id.vendor     = PCI_VENDOR_ID_HP;
+       kbd->dev->id.product    = 0x0001; /* TODO: get from kbd->rsc */
+       kbd->dev->id.version    = 0x0100; /* TODO: get from kbd->rsc */
+       kbd->dev->dev           = &serio->dev;
 
        for (i = 0; i < 128; i++) {
-               set_bit(hil_kbd_set1[i], kbd->dev.keybit);
-               set_bit(hil_kbd_set3[i], kbd->dev.keybit);
+               set_bit(hil_kbd_set1[i], kbd->dev->keybit);
+               set_bit(hil_kbd_set3[i], kbd->dev->keybit);
        }
-       clear_bit(0, kbd->dev.keybit);
+       clear_bit(0, kbd->dev->keybit);
 
-       input_register_device(&kbd->dev);
+       input_register_device(kbd->dev);
        printk(KERN_INFO "input: %s, ID: %d\n",
-               kbd->dev.name, did);
+               kbd->dev->name, did);
 
        serio->write(serio, 0);
        serio->write(serio, 0);
@@ -343,8 +346,10 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
        up(&(kbd->sem));
 
        return 0;
- bail1:
+ bail2:
        serio_close(serio);
+ bail1:
+       input_free_device(kbd->dev);
  bail0:
        kfree(kbd);
        serio_set_drvdata(serio, NULL);
index e95bc05..452c5f3 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1998 Philip Blundell <philb@gnu.org>
  *  Copyright (C) 1999 Matthew Wilcox <willy@bofh.ai>
- *  Copyright (C) 1999-2003 Helge Deller <deller@gmx.de>
+ *  Copyright (C) 1999-2006 Helge Deller <deller@gmx.de>
  *
  *  Very basic HP Human Interface Loop (HIL) driver.
  *  This driver handles the keyboard on HP300 (m68k) and on some 
@@ -90,7 +90,7 @@ static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] =
 
 /* HIL structure */
 static struct {
-       struct input_dev dev;
+       struct input_dev *dev;
 
        unsigned int curdev;
        
@@ -117,7 +117,7 @@ static void poll_finished(void)
                down = (hil_dev.data[1] & 1) == 0;
                scode = hil_dev.data[1] >> 1;
                key = hphilkeyb_keycode[scode];
-               input_report_key(&hil_dev.dev, key, down);
+               input_report_key(hil_dev.dev, key, down);
                break;
        }
        hil_dev.curdev = 0;
@@ -207,9 +207,14 @@ hil_keyb_init(void)
        unsigned int i, kbid;
        wait_queue_head_t hil_wait;
 
-       if (hil_dev.dev.id.bustype) {
+       if (hil_dev.dev) {
                return -ENODEV; /* already initialized */
        }
+
+       hil_dev.dev = input_allocate_device();
+       if (!hil_dev.dev)
+               return -ENOMEM;
+       hil_dev.dev->private = &hil_dev;
        
 #if defined(CONFIG_HP300)
        if (!hwreg_present((void *)(HILBASE + HIL_DATA)))
@@ -247,28 +252,26 @@ hil_keyb_init(void)
        c = 0;
        hil_do(HIL_WRITEKBDSADR, &c, 1);
        
-       init_input_dev(&hil_dev.dev);
-
        for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
                if (hphilkeyb_keycode[i] != KEY_RESERVED)
-                       set_bit(hphilkeyb_keycode[i], hil_dev.dev.keybit);
-
-       hil_dev.dev.evbit[0]    = BIT(EV_KEY) | BIT(EV_REP);
-       hil_dev.dev.ledbit[0]   = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
-       hil_dev.dev.keycodemax  = HIL_KEYCODES_SET1_TBLSIZE;
-        hil_dev.dev.keycodesize = sizeof(hphilkeyb_keycode[0]);
-       hil_dev.dev.keycode     = hphilkeyb_keycode;
-       hil_dev.dev.name        = "HIL keyboard";
-       hil_dev.dev.phys        = "hpkbd/input0";
-
-       hil_dev.dev.id.bustype  = BUS_HIL;
-       hil_dev.dev.id.vendor   = PCI_VENDOR_ID_HP;
-       hil_dev.dev.id.product  = 0x0001;
-       hil_dev.dev.id.version  = 0x0010;
-
-       input_register_device(&hil_dev.dev);
+                       set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
+
+       hil_dev.dev->evbit[0]    = BIT(EV_KEY) | BIT(EV_REP);
+       hil_dev.dev->ledbit[0]   = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+       hil_dev.dev->keycodemax  = HIL_KEYCODES_SET1_TBLSIZE;
+       hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]);
+       hil_dev.dev->keycode     = hphilkeyb_keycode;
+       hil_dev.dev->name       = "HIL keyboard";
+       hil_dev.dev->phys       = "hpkbd/input0";
+
+       hil_dev.dev->id.bustype = BUS_HIL;
+       hil_dev.dev->id.vendor  = PCI_VENDOR_ID_HP;
+       hil_dev.dev->id.product = 0x0001;
+       hil_dev.dev->id.version = 0x0010;
+
+       input_register_device(hil_dev.dev);
        printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
-               hil_dev.dev.name, kbid, HILBASE, HIL_IRQ);
+               hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
 
        return 0;
 }
@@ -329,7 +332,10 @@ static void __exit hil_exit(void)
        /* Turn off interrupts */
        hil_do(HIL_INTOFF, NULL, 0);
 
-       input_unregister_device(&hil_dev.dev);
+       input_unregister_device(hil_dev.dev);
+
+       input_free_device(hil_dev.dev);
+       hil_dev.dev = NULL;
 
 #if defined(CONFIG_PARISC)
        unregister_parisc_driver(&hil_driver);
index c2bf2ed..a648f9f 100644 (file)
@@ -55,7 +55,7 @@ MODULE_LICENSE("Dual BSD/GPL");
 #define HIL_PTR_MAX_LENGTH 16
 
 struct hil_ptr {
-       struct input_dev dev;
+       struct input_dev *dev;
        struct serio *serio;
 
        /* Input buffer and index for packets from HIL bus. */
@@ -79,7 +79,7 @@ struct hil_ptr {
 /* Process a complete packet after transfer from the HIL */
 static void hil_ptr_process_record(struct hil_ptr *ptr)
 {
-       struct input_dev *dev = &ptr->dev;
+       struct input_dev *dev = ptr->dev;
        hil_packet *data = ptr->data;
        hil_packet p;
        int idx, i, cnt, laxis;
@@ -148,12 +148,12 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
                if (absdev) {
                        val = lo + (hi<<8);
 #ifdef TABLET_AUTOADJUST
-                       if (val < ptr->dev.absmin[ABS_X + i])
-                               ptr->dev.absmin[ABS_X + i] = val;
-                       if (val > ptr->dev.absmax[ABS_X + i])
-                               ptr->dev.absmax[ABS_X + i] = val;
+                       if (val < dev->absmin[ABS_X + i])
+                               dev->absmin[ABS_X + i] = val;
+                       if (val > dev->absmax[ABS_X + i])
+                               dev->absmax[ABS_X + i] = val;
 #endif
-                       if (i%3) val = ptr->dev.absmax[ABS_X + i] - val;
+                       if (i%3) val = dev->absmax[ABS_X + i] - val;
                        input_report_abs(dev, ABS_X + i, val);
                } else {
                        val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
@@ -233,26 +233,30 @@ static void hil_ptr_disconnect(struct serio *serio)
                return;
        }
 
-       input_unregister_device(&ptr->dev);
+       input_unregister_device(ptr->dev);
        serio_close(serio);
+       input_free_device(ptr->dev);
        kfree(ptr);
 }
 
 static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 {
-       struct hil_ptr  *ptr;
-       char            *txt;
-       unsigned int    i, naxsets, btntype;
-       uint8_t         did, *idd;
+       struct hil_ptr   *ptr;
+       char             *txt;
+       unsigned int     i, naxsets, btntype;
+       uint8_t          did, *idd;
 
-       if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM;
-       memset(ptr, 0, sizeof(struct hil_ptr));
+       if (!(ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL)))
+               return -ENOMEM;
 
-       if (serio_open(serio, driver)) goto bail0;
+       ptr->dev = input_allocate_device();
+       if (!ptr->dev) goto bail0;
+       ptr->dev->private = ptr;
+
+       if (serio_open(serio, driver)) goto bail1;
 
        serio_set_drvdata(serio, ptr);
        ptr->serio = serio;
-       ptr->dev.private = ptr;
 
        init_MUTEX_LOCKED(&(ptr->sem));
 
@@ -283,25 +287,24 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 
        up(&(ptr->sem));
 
-       init_input_dev(&ptr->dev);
        did = ptr->idd[0];
        idd = ptr->idd + 1;
        txt = "unknown";
        if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
-               ptr->dev.evbit[0] = BIT(EV_REL);
+               ptr->dev->evbit[0] = BIT(EV_REL);
                txt = "relative";
        }
 
        if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
-               ptr->dev.evbit[0] = BIT(EV_ABS);
+               ptr->dev->evbit[0] = BIT(EV_ABS);
                txt = "absolute";
        }
-       if (!ptr->dev.evbit[0]) {
-               goto bail1;
+       if (!ptr->dev->evbit[0]) {
+               goto bail2;
        }
 
        ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
-       if (ptr->nbtn) ptr->dev.evbit[0] |= BIT(EV_KEY);
+       if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY);
 
        naxsets = HIL_IDD_NUM_AXSETS(*idd);
        ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
@@ -325,7 +328,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
                btntype = BTN_MOUSE;
 
        for (i = 0; i < ptr->nbtn; i++) {
-               set_bit(btntype | i, ptr->dev.keybit);
+               set_bit(btntype | i, ptr->dev->keybit);
                ptr->btnmap[i] = btntype | i;
        }
 
@@ -337,50 +340,52 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 
        if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
                for (i = 0; i < ptr->naxes; i++) {
-                       set_bit(REL_X + i, ptr->dev.relbit);
+                       set_bit(REL_X + i, ptr->dev->relbit);
                }
                for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
-                       set_bit(REL_X + i, ptr->dev.relbit);
+                       set_bit(REL_X + i, ptr->dev->relbit);
                }
        } else {
                for (i = 0; i < ptr->naxes; i++) {
-                       set_bit(ABS_X + i, ptr->dev.absbit);
-                       ptr->dev.absmin[ABS_X + i] = 0;
-                       ptr->dev.absmax[ABS_X + i] = 
+                       set_bit(ABS_X + i, ptr->dev->absbit);
+                       ptr->dev->absmin[ABS_X + i] = 0;
+                       ptr->dev->absmax[ABS_X + i] =
                                HIL_IDD_AXIS_MAX((ptr->idd + 1), i);
                }
                for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
-                       set_bit(ABS_X + i, ptr->dev.absbit);
-                       ptr->dev.absmin[ABS_X + i] = 0;
-                       ptr->dev.absmax[ABS_X + i] = 
+                       set_bit(ABS_X + i, ptr->dev->absbit);
+                       ptr->dev->absmin[ABS_X + i] = 0;
+                       ptr->dev->absmax[ABS_X + i] =
                                HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3));
                }
 #ifdef TABLET_AUTOADJUST
                for (i = 0; i < ABS_MAX; i++) {
-                       int diff = ptr->dev.absmax[ABS_X + i] / 10;
-                       ptr->dev.absmin[ABS_X + i] += diff;
-                       ptr->dev.absmax[ABS_X + i] -= diff;
+                       int diff = ptr->dev->absmax[ABS_X + i] / 10;
+                       ptr->dev->absmin[ABS_X + i] += diff;
+                       ptr->dev->absmax[ABS_X + i] -= diff;
                }
 #endif
        }
 
-       ptr->dev.name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;
+       ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;
 
-       ptr->dev.id.bustype     = BUS_HIL;
-       ptr->dev.id.vendor      = PCI_VENDOR_ID_HP;
-       ptr->dev.id.product     = 0x0001; /* TODO: get from ptr->rsc */
-       ptr->dev.id.version     = 0x0100; /* TODO: get from ptr->rsc */
-       ptr->dev.dev            = &serio->dev;
+       ptr->dev->id.bustype    = BUS_HIL;
+       ptr->dev->id.vendor     = PCI_VENDOR_ID_HP;
+       ptr->dev->id.product    = 0x0001; /* TODO: get from ptr->rsc */
+       ptr->dev->id.version    = 0x0100; /* TODO: get from ptr->rsc */
+       ptr->dev->dev           = &serio->dev;
 
-       input_register_device(&ptr->dev);
+       input_register_device(ptr->dev);
        printk(KERN_INFO "input: %s (%s), ID: %d\n",
-                ptr->dev.name, 
+               ptr->dev->name,
                (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
                did);
 
        return 0;
- bail1:
+ bail2:
        serio_close(serio);
+ bail1:
+       input_free_device(ptr->dev);
  bail0:
        kfree(ptr);
        serio_set_drvdata(serio, NULL);