patch-2.4.0-test2 linux/drivers/usb/hid.c

Next file: linux/drivers/usb/hid.h
Previous file: linux/drivers/usb/hid-debug.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/drivers/usb/hid.c linux/drivers/usb/hid.c
@@ -1,5 +1,5 @@
 /*
- *  hid.c  Version 0.8
+ * $Id: hid.c,v 1.6 2000/05/29 09:01:52 vojtech Exp $
  *
  *  Copyright (c) 1999 Andreas Gal
  *  Copyright (c) 2000 Vojtech Pavlik
@@ -80,6 +80,9 @@
 	__s32 y;
 }  hid_hat_to_axis[] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}, { 0, 0}};
 
+static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
+				"Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
+
 /*
  * Register a new report for a device.
  */
@@ -1259,6 +1262,27 @@
 	return 0;
 }
 
+static int hid_open(struct input_dev *dev)
+{
+	struct hid_device *hid = dev->private;
+
+	if (hid->open++)
+		return 0;
+
+	 if (usb_submit_urb(&hid->urb))
+		return -EIO;
+
+	return 0;
+}
+
+static void hid_close(struct input_dev *dev)
+{
+	struct hid_device *hid = dev->private;
+
+	if (!--hid->open)
+		usb_unlink_urb(&hid->urb);
+}
+
 /*
  * Configure the input layer interface
  * Read all reports and initalize the absoulte field values.
@@ -1272,6 +1296,8 @@
 
 	hid->input.private = hid;
 	hid->input.event = hid_event;
+	hid->input.open = hid_open;
+	hid->input.close = hid_close;
 
 	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
 
@@ -1313,7 +1339,7 @@
 	{ 0, 0 }
 };
 
-static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
+static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum, char *name)
 {
 	struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
 	struct hid_descriptor *hdesc;
@@ -1380,11 +1406,6 @@
 
 		FILL_INT_URB(&hid->urb, dev, pipe, hid->buffer, maxp > 32 ? 32 : maxp, hid_irq, hid, endpoint->bInterval);
 	
-		if (usb_submit_urb(&hid->urb)) {
-			dbg("submitting interrupt URB failed");
-			continue;
-		}
-
 		break;
 	}
 
@@ -1405,6 +1426,20 @@
 	hid->dr.index = hid->ifnum;
 	hid->dr.length = 1;
 
+	hid->input.name = hid->name;
+	hid->input.idbus = BUS_USB;
+	hid->input.idvendor = dev->descriptor.idVendor;
+	hid->input.idproduct = dev->descriptor.idProduct;
+	hid->input.idversion = dev->descriptor.bcdDevice;
+
+	if (strlen(name)) 
+		strcpy(hid->name, name);
+	else
+		sprintf(hid->name, "USB HID %s %04x:%04x",
+			((hid->application >= 0x00010000) && (hid->application <= 0x00010008)) ?
+			hid_types[hid->application & 0xffff] : "Device",
+			hid->input.idvendor, hid->input.idproduct);
+
 	FILL_CONTROL_URB(&hid->urbout, dev, usb_sndctrlpipe(dev, 0),
 		(void*) &hid->dr, hid->bufout, 1, hid_ctrl, hid);
 
@@ -1416,13 +1451,27 @@
 
 static void* hid_probe(struct usb_device *dev, unsigned int ifnum)
 {
-	char *hid_name[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
-				"Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
 	struct hid_device *hid;
+	char name[128];
+	char *buf;
 
 	dbg("HID probe called for ifnum %d", ifnum);
 
-	if (!(hid = usb_hid_configure(dev, ifnum)))
+	name[0] = 0;
+
+	if (!(buf = kmalloc(63, GFP_KERNEL)))
+		return NULL;
+
+	if (dev->descriptor.iManufacturer &&
+		usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0)
+			strcat(name, buf);
+	if (dev->descriptor.iProduct &&
+		usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
+			sprintf(name, "%s %s", name, buf);
+
+	kfree(buf);
+
+	if (!(hid = usb_hid_configure(dev, ifnum, name)))
 		return NULL;
 
 	hid_dump_device(hid);
@@ -1430,10 +1479,18 @@
 	hid_init_input(hid);
 	input_register_device(&hid->input);
 
-	printk(KERN_INFO "input%d: USB HID v%x.%02x %s\n",
-		hid->input.number, hid->version >> 8, hid->version & 0xff,
+	printk(KERN_INFO "input%d: USB HID v%x.%02x %s",
+		hid->input.number,
+		hid->version >> 8, hid->version & 0xff,
 		((hid->application >= 0x00010000) && (hid->application <= 0x00010008)) ?
-			hid_name[hid->application & 0xffff] : "device");
+		hid_types[hid->application & 0xffff] : "Device");
+
+	if (strlen(name))
+		printk(" [%s]", name);
+	else
+		printk(" [%04x:%04x]", hid->input.idvendor, hid->input.idproduct);
+	
+	printk(" on usb%d:%d.%d\n", dev->bus->busnum, dev->devnum, ifnum);
 
 	return hid;
 }

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