patch-2.2.8 linux/drivers/usb/usb.c

Next file: linux/drivers/usb/usb.h
Previous file: linux/drivers/usb/uhci.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.7/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
@@ -213,6 +213,15 @@
 		return -1;
 	}
 
+	interface->endpoint = (struct usb_endpoint_descriptor *)
+		kmalloc(interface->bNumEndpoints * sizeof(struct usb_endpoint_descriptor), GFP_KERNEL);
+	if(interface->endpoint==NULL)
+	{
+		printk(KERN_WARNING "usb: out of memory.\n");
+		return -1;	
+	}
+	memset(interface->endpoint, 0, interface->bNumEndpoints*sizeof(struct usb_endpoint_descriptor));
+	
 	for (i = 0; i < interface->bNumEndpoints; i++) {
 //		if(((USB_DT_HID << 8) | 9) == *(unsigned short*)(ptr + parsed)) {
 //			parsed += 9;	/* skip over the HID descriptor for now */
@@ -242,8 +251,18 @@
 	{
 		printk(KERN_WARNING "usb: too many interfaces.\n");
 		return -1;
+
 	}
 
+	config->interface = (struct usb_interface_descriptor *)
+		kmalloc(config->bNumInterfaces * sizeof(struct usb_interface_descriptor), GFP_KERNEL);
+	if(config->interface==NULL)
+	{
+		printk(KERN_WARNING "usb: out of memory.\n");
+		return -1;	
+	}
+	memset(config->interface, 0, config->bNumInterfaces*sizeof(struct usb_interface_descriptor));
+	
 	for (i = 0; i < config->bNumInterfaces; i++) {
 		int retval = usb_parse_interface(dev, config->interface + i, ptr + parsed, len);
 		if (retval < 0)
@@ -266,6 +285,14 @@
 		return -1;
 	}
 
+	dev->config = (struct usb_config_descriptor *)
+		kmalloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor), GFP_KERNEL);
+	if(dev->config==NULL)
+	{
+		printk(KERN_WARNING "usb: out of memory.\n");
+		return -1;	
+	}
+	memset(dev->config, 0, dev->descriptor.bNumConfigurations*sizeof(struct usb_config_descriptor));
 	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
 		int retval = usb_parse_config(dev, dev->config + i, ptr, bytes);
 		if (retval < 0)
@@ -276,6 +303,31 @@
 	return 0;
 }
 
+void usb_destroy_configuration(struct usb_device *dev)
+{
+	int c, i;
+	struct usb_config_descriptor *cf;
+	struct usb_interface_descriptor *ifp;
+	
+	if(dev->config==NULL)
+		return;
+	for(c=0;c<dev->descriptor.bNumConfigurations;c++)
+	{
+		cf=&dev->config[c];
+		if(cf->interface==NULL)
+			break;
+		for(i=0;i<cf->bNumInterfaces;i++)
+		{
+			ifp=&cf->interface[i];
+			if(ifp->endpoint==NULL)
+				break;
+			kfree(ifp->endpoint);
+		}
+		kfree(cf->interface);
+	}
+	kfree(dev->config);
+}
+			
 void usb_init_root_hub(struct usb_device *dev)
 {
 	dev->devnum = -1;
@@ -517,24 +569,29 @@
 
 int usb_get_configuration(struct usb_device *dev)
 {
-	unsigned int size;
+	unsigned int cfgno,size;
 	unsigned char buffer[400];
-
-	/* Get the first 8 bytes - guaranteed */
-	if (usb_get_descriptor(dev, USB_DT_CONFIG, 0, buffer, 8))
-		return -1;
-
-	/* Get the full buffer */
-	size = *(unsigned short *)(buffer+2);
-	if (size > sizeof(buffer))
-	{
-		printk(KERN_INFO "usb: truncated DT_CONFIG (want %d).\n", size);
-		size = sizeof(buffer);
+	unsigned char * bufptr;
+	
+	bufptr=buffer;
+        for (cfgno=0;cfgno<dev->descriptor.bNumConfigurations;cfgno++) {
+  		/* Get the first 8 bytes - guaranteed */
+	  	if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, 8))
+	    		return -1;
+
+  	  	/* Get the full buffer */
+	  	size = *(unsigned short *)(bufptr+2);
+	  	if (bufptr+size > buffer+sizeof(buffer))
+	  	{
+			printk(KERN_INFO "usb: truncated DT_CONFIG (want %d).\n", size);
+			size = buffer+sizeof(buffer)-bufptr;
+		}
+		if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, size))
+			return -1;
+			
+		/* Prepare for next configuration */
+		bufptr+=size;
 	}
-
-	if (usb_get_descriptor(dev, USB_DT_CONFIG, 0, buffer, size))
-		return -1;
-
 	return usb_parse_configuration(dev, buffer, size);
 }
 

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