linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* problem of writing a virtual ps2 mouse driver
@ 2009-04-27  7:18 chang yao chung
  2009-04-28 13:18 ` Dmitry Torokhov
  0 siblings, 1 reply; 2+ messages in thread
From: chang yao chung @ 2009-04-27  7:18 UTC (permalink / raw)
  To: linux-input

Hi all

I want to write a virtual PS/2 mouse driver to hook to the input core,  
after I load the driver
The psmouse input device driver probes my virtual device as a “Generic  
PS/2 mouse” in /dev/input/mouse1
And sent a F4 (mouse enable command) to my pseudo device.

I use a user space program to send the following mouse movement packet  
and launch
gpm –m /dev/input/mouse1 –t ps2

but when I run the user space program , there is no mouse movement  
event occurred,
is there anything wrong with my code using serio_interrupt () ?


#include <fcntl.h>

int main()
{
     int fd;
     int x, y;
     char buffer[10];

     fd = open ("/sys/devices/platform/dummy/coordinates", O_RDWR);
     if (fd < 0) {
         perror ("open file");
         exit (0);
     }

     while (1) {
         x = random () % 20;
         y = random () % 20;

         sprintf (buffer, "%d", x, y);
         write (fd, buffer, strlen(buffer));
         fsync (fd);
         sleep (1);
     }

}



/*
  * dummy mouse serio driver for linux
  */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/err.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <linux/platform_device.h>

MODULE_AUTHOR("Wisecamera Corp.");
MODULE_DESCRIPTION("dummy ps2 mouse driver");
MODULE_LICENSE("GPL");

static struct serio *dummy_port;
static struct platform_device *dummy_device;
int port_num;

static ssize_t
write_vms (struct device *dev, struct device_attribute *attr, const  
char *buffer, size_t count)
{
         int x, y;
         sscanf (buffer, "%x", &x);
         serio_interrupt (dev, 0x8, 0 , NULL);
         serio_interrupt (dev, x, NULL);
         serio_interrupt (dev, y, 0, NULL);
         serio_interrupt (dev, 0, 0, NULL);
         return count;
}

/* Attach the sysgs write method */
DEVICE_ATTR (coordinates, 0644, NULL, write_vms);

static struct attribute *vms_attrs [] = {
         &dev_attr_coordinates.attr,
         NULL
};

static struct attribute_group vms_attr_group = {
         .attrs = vms_attrs,
};

static int dummy_open (struct serio *dev)
{
         printk ("dummy open\n");
         serio_interrupt (dev, 0xaa, 0, NULL);
         serio_interrupt (dev, 0x00, 0, NULL);

         return 0;
}

static int dummy_write (struct serio *dev, unsigned char val)
{
         printk ("dummy write %x\n", val);

         switch (val) {
                 case 0xf2:
                         serio_interrupt (dev, 0xfa, 0, NULL);
                         serio_interrupt (dev, 0x00, 0, NULL);
                         break;
                 default:
                         serio_interrupt (dev, 0xfa, 0, NULL);

         }
         return 0;
}


static void dummy_close (struct serio *dev)
{
         printk ("dummy close\n");
         return;
}

static struct serio * __init dummy_allocate_port (void *port_data,  
char *name, char *phys)
{
         struct serio *serio;

         serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
         if (serio)
         {
                 memset(serio, 0, sizeof(struct serio));
                 serio->id.type          = SERIO_8042;
                 serio->write             = dummy_write;
                 serio->open             = dummy_open;
                 serio->close            = dummy_close;
                 snprintf(serio->name, sizeof(serio->name), name);
                 snprintf(serio->phys, sizeof(serio->phys), phys);
                 serio->port_data      = NULL;
                 serio->dev.parent    = &dummy_device->dev;
         }

         return serio;
}

static void __exit dummy_exit (void)
{
         sysfs_remove_group (&dummy_device->dev.kobj, &vms_attr_group);
         serio_unregister_port(dummy_port);
         platform_device_unregister(dummy_device);
}

static int __init dummy_init (void)
{
         char phys[20];
         char name[20];

         dummy_device = platform_device_register_simple("dummy", -1,  
NULL, 0);

         if (IS_ERR(dummy_device))
                 return PTR_ERR(dummy_device);

         sysfs_create_group (&dummy_device->dev.kobj, &vms_attr_group);

         sprintf(name, "dummy PS2 mouse port");
         sprintf(phys, "dummy/serio%d", 0);

         if ((dummy_port = dummy_allocate_port(NULL, name, phys)) ==  
NULL)
         {
                 dummy_exit();
                 return -1;
         }

         /* register port */
         serio_register_port(dummy_port);

         return 0;
}

module_init(dummy_init);
module_exit(dummy_exit);

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: problem of writing a virtual ps2 mouse driver
  2009-04-27  7:18 problem of writing a virtual ps2 mouse driver chang yao chung
@ 2009-04-28 13:18 ` Dmitry Torokhov
  0 siblings, 0 replies; 2+ messages in thread
From: Dmitry Torokhov @ 2009-04-28 13:18 UTC (permalink / raw)
  To: chang yao chung; +Cc: linux-input

Hi,

On Mon, Apr 27, 2009 at 03:18:07PM +0800, chang yao chung wrote:
> Hi all
>
> I want to write a virtual PS/2 mouse driver to hook to the input core,  
> after I load the driver
> The psmouse input device driver probes my virtual device as a “Generic  
> PS/2 mouse” in /dev/input/mouse1
> And sent a F4 (mouse enable command) to my pseudo device.
>
> I use a user space program to send the following mouse movement packet  
> and launch
> gpm –m /dev/input/mouse1 –t ps2
>
> but when I run the user space program , there is no mouse movement event 
> occurred,

Do you see any data coming out if you just do a 'cat /dev/input/mouse1'?
Are you positive that mouse1 is bound to your virtual device?

> is there anything wrong with my code using serio_interrupt () ?
>

...

>
> static ssize_t
> write_vms (struct device *dev, struct device_attribute *attr, const char 
> *buffer, size_t count)
> {
>         int x, y;
>         sscanf (buffer, "%x", &x);

You don't read 'y' coordinate and below pass garbage to serio, users
is likely to reject packets that are suspicious.

>         serio_interrupt (dev, 0x8, 0 , NULL);
>         serio_interrupt (dev, x, NULL);

First question - does it even compile? I don't think so given that you
trying to pass either 3 or 4 arguments to it.

>         serio_interrupt (dev, y, 0, NULL);
>         serio_interrupt (dev, 0, 0, NULL);

You also need to decide the flavor of PS/2 protocol you are trying to
support. You seem to be aiming for ImPS/2 with 0 4th byte but don't
respond to ImPS/2 probes which will confuse users.

-- 
Dmitry

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-04-28 13:18 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-27  7:18 problem of writing a virtual ps2 mouse driver chang yao chung
2009-04-28 13:18 ` Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).