USB -> PS/2

Walter C. Pelissero walter at pelissero.de
Sat Aug 30 04:52:25 PDT 2003


I just bought a USB -> PS/2 keyboard and mouse converter for my
laptop.  It's a Sitecom brand and it gets recognised as MCT Corp.

addr 1: UHCI root hub, Intel
 addr 2: Generic USB Hub, ALCOR
  addr 4: HID-compliant Mouse (USB), Mitsumi
  addr 3: PS/2 - USB Interface Adaptor, MCT Corp.

Although the keyboard works, the mouse doesn't.  I tried to plug two
types of mice (a Micro$oft 2 buttons and a Trust 3 buttons) but both,
while generating traffic on the USB bus (the converter LED blinks),
don't move the pointer.

This is the usbd log:

  uhub1: ALCOR Generic USB Hub, class 9/0, rev 1.10/3.12, addr 2
  uhub1: 4 ports with 4 removable, bus powered
  ums0: Mitsumi HID-compliant Mouse (USB), rev 1.00/1.10, addr 3, iclass 3/1
  ums0: 2 buttons
  ukbd0: MCT Corp. PS/2 - USB Interface Adaptor, rev 1.10/1.00, addr 4, iclass 3/1
  kbd1 at ukbd0
  ums1: MCT Corp. PS/2 - USB Interface Adaptor, rev 1.10/1.00, addr 4, iclass 3/1
  ums1: 3 buttons and Z dir.

Moused is there:

  179  ??  Ss     0:05.83 /usr/sbin/moused -3 -p /dev/ums0 -I /var/run/moused.ums0.pid
  209  ??  Ss     0:05.57 moused -3 -p /dev/psm0 -t auto
  237  ??  Is     0:00.01 /usr/sbin/moused -p /dev/jogdial -t jogdial
  370  ??  Ss     0:10.21 /usr/sbin/moused -3 -p /dev/ums1 -I /var/run/moused.ums1.pid

(The PS/2 mouse is either the first or the last one.)

This is on a FreeBSD 4.9-PRERELASE.  On Windoze the converter works
out of the box, with keyboard and mouse, without additional drivers.

Does anybody know how to make the PS/2 mouse work?

BTW, usbd, as it is, is not suitable to handle devices like this PS/2
adapter because it matches and executes only one entry in the
usbd.conf.  USB devices implementing multiple features are in my
humble opinion better handled matching multiple entries in usbd.conf.
Below I attached a patch to usbd.c to change this behaviour (hence the
crossposting to the hackers list).

Cheers,

-- 
walter pelissero
http://www.pelissero.de




--- /usr/src/usr.sbin/usbd/usbd.c	Tue Dec 31 10:05:27 2002
+++ usbd.c	Sat Aug 30 13:43:23 2003
@@ -102,6 +102,7 @@
 
 int lineno;
 int verbose = 0;		/* print message on what it is doing */
+int single_action = 0;
 
 typedef struct event_name_s {
 	int	type;		/* event number (from usb.h) */
@@ -204,8 +205,7 @@
 void print_event	__P((struct usb_event *event));
 void print_action	__P((action_t *action, int i));
 void print_actions	__P((void));
-int  find_action	__P((struct usb_device_info *devinfo,
-			action_match_t *action_match));
+void execute_command	__P((char *cmd));
 
 
 void
@@ -697,9 +697,8 @@
 	return(-1);
 }
 
-
-int
-find_action(struct usb_device_info *devinfo, action_match_t *action_match)
+void
+execute_actions (struct usb_device_info *devinfo, int event_type)
 {
 	action_t *action;
 	char *devname = NULL;
@@ -722,6 +721,8 @@
 		     (match = match_devname(action, devinfo)) != -1)) {
 			/* found match !*/
 
+			if (verbose >= 2)
+				print_action(action, 0);
 			/* Find a devname for pretty printing. Either
 			 * the matched one or otherwise, if there is only
 			 * one devname for that device, use that.
@@ -735,21 +736,37 @@
 
 			if (verbose) {
 				printf("%s: Found action '%s' for %s, %s",
-					__progname, action->name,
-					devinfo->udi_product, devinfo->udi_vendor);
+				       __progname, action->name,
+				       devinfo->udi_product, devinfo->udi_vendor);
 				if (devname)
 					printf(" at %s", devname);
 				printf("\n");
 			}
 
-			action_match->action = action;
-			action_match->devname = devname;
+			if (devname) {
+				int error;
+				if (verbose >= 2)
+					printf("%s: Setting DEVNAME='%s'\n",
+					       __progname, devname);
+				error = setenv("DEVNAME", devname, 1);
+				if (error)
+					fprintf(stderr, "%s: setenv(\"DEVNAME\",
+		\"%s\",1) failed, %s\n",
+						__progname, devname, strerror(errno));
+			}
 
-			return(1);
+			if (USB_EVENT_IS_ATTACH(event_type) && action->attach) 
+				execute_command(action->attach);
+			if (USB_EVENT_IS_DETACH(event_type) && action->detach)
+				execute_command(action->detach);
+			if (single_action) {
+				printf("single action mode: done\n");
+				return;
+			} else {
+				printf("looking for more actions\n");
+			}
 		}
 	}
-
-	return(0);
 }
 
 void
@@ -881,30 +898,7 @@
 			break;
 		case USB_EVENT_DEVICE_ATTACH:
 		case USB_EVENT_DEVICE_DETACH:
-			if (find_action(&event.u.ue_device, &action_match) == 0)
-				/* nothing found */
-				break;
-
-			if (verbose >= 2)
-				print_action(action_match.action, 0);
-
-			if (action_match.devname) {
-				if (verbose >= 2)
-					printf("%s: Setting DEVNAME='%s'\n",
-						__progname, action_match.devname);
-
-				error = setenv("DEVNAME", action_match.devname, 1);
-				if (error)
-					fprintf(stderr, "%s: setenv(\"DEVNAME\", \"%s\",1) failed, %s\n",
-						__progname, action_match.devname, strerror(errno));
-			}
-
-			if (USB_EVENT_IS_ATTACH(event.ue_type) &&
-			    action_match.action->attach) 
-				execute_command(action_match.action->attach);
-			if (USB_EVENT_IS_DETACH(event.ue_type) &&
-			    action_match.action->detach)
-				execute_command(action_match.action->detach);
+			execute_actions(&event.u.ue_device, event.ue_type);
 			break;
 		case USB_EVENT_DRIVER_ATTACH:
 			if (verbose)
@@ -944,7 +938,7 @@
 		}
 	}
 
-	while ((ch = getopt(argc, argv, "c:def:nt:v")) != -1) {
+	while ((ch = getopt(argc, argv, "c:def:nst:v")) != -1) {
 		switch(ch) {
 		case 'c':
 			configfile = strdup(optarg);
@@ -965,6 +959,9 @@
 			break;
 		case 'n':
 			handle_events = 0;
+			break;
+		case 's':
+			single_action = 1;
 			break;
 		case 't':
 			itimeout = atoi(optarg);


More information about the freebsd-hackers mailing list