[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] [PATCH] Make memory allocation for device and configuration descriptors dynamic



Hi,

I have seen some device with configuration descriptor bigger than 512
bytes (size of static buffer in our USB stack), so I've made buffers
memory allocation for device and configuration descriptors dynamic.

----------------------------------

Commit message:

Make buffers memory allocation for device and configuration descriptors dynamic.
Index: sys/usb/src.km/usb.c
===================================================================
RCS file: /mint/freemint/sys/usb/src.km/usb.c,v
retrieving revision 1.15
diff -u -8 -r1.15 usb.c
--- sys/usb/src.km/usb.c	16 Jul 2014 16:31:41 -0000	1.15
+++ sys/usb/src.km/usb.c	5 Oct 2014 18:22:46 -0000
@@ -466,43 +466,50 @@
 			buf, size, USB_CNTL_TIMEOUT);
 }
 
 /**********************************************************************
  * gets configuration cfgno and store it in the buffer
  */
 long usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer, long cfgno)
 {
-	long result;
+	long result, err;
 	unsigned long tmp;
 	struct usb_config_descriptor *config;
 
-
+	buffer = kmalloc(9);
 	config = (struct usb_config_descriptor *)&buffer[0];
 	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9);
 	if (result < 9) {
 		if (result < 0)
 			DEBUG(("unable to get descriptor, error %lx",
 				dev->status));
 		else
 			DEBUG(("config descriptor too short " \
 				"(expected %i, got %i)", 9, result));
+		kfree(buffer);
 		return -1;
 	}
 	tmp = le2cpu16(config->wTotalLength);
+	kfree(buffer);
 
-	if (tmp > USB_BUFSIZ) {
-		DEBUG(("usb_get_configuration_no: failed to get " \
-			   "descriptor - too long: %ld", tmp));
-		return -1;
-	}
-
+	buffer = kmalloc(tmp);
 	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp);
 	DEBUG(("get_conf_no %ld Result %ld, wLength %ld",
 		   cfgno, result, tmp));
+
+	err = usb_parse_config(dev, buffer, 0);
+	if (err < 0) {
+		DEBUG(("usb_new_device: Cannot parse configuration, " \
+		       "skipping device %04x:%04x\n",
+		       dev->descriptor.idVendor, dev->descriptor.idProduct));
+		kfree(buffer);
+		return -1;
+	}
+	kfree(buffer);
 	return result;
 }
 
 /********************************************************************
  * set address of a device to the value in dev->devnum.
  * This can only be done by addressing the device via the default address (0)
  */
 long usb_set_address(struct usb_device *dev)
@@ -852,56 +859,58 @@
  * and is in the default state. We need to identify the thing and
  * get the ball rolling..
  *
  * Returns 0 for success, != 0 for error.
  */
 long usb_new_device(struct usb_device *dev)
 {
 	long addr, err;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	unsigned char *tmpbuf;
 	long tmp;
 	struct usb_device_descriptor *desc;
 	long port = -1;
 	struct usb_device *parent = dev->parent;
 
 	DEBUG(("usb_new_device: "));
  
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
 	dev->devnum = 0;
 
 	/* send 64-byte GET-DEVICE-DESCRIPTOR request.  Since the descriptor is
 	 * only 18 bytes long, this will terminate with a short packet.  But if
 	 * the maxpacket size is 8 or 16 the device may be waiting to transmit
 	 * some more, or keeps on retransmitting the 8 byte header. */
-
+	tmpbuf = kmalloc(64);
 	desc = (struct usb_device_descriptor *)tmpbuf;
 
 	dev->descriptor.bMaxPacketSize0 = 64;	    /* Start off at 64 bytes  */
 
 	/* Default to 64 byte max packet size */
 	dev->maxpacketsize = PACKET_SIZE_64;
 	dev->epmaxpacketin[0] = 64;
 	dev->epmaxpacketout[0] = 64;
 
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
 	if (err < 0) {
 		DEBUG(("usb_new_device: usb_get_descriptor() failed"));
 		dev->devnum = addr;
+		kfree(tmpbuf);
 		return 1;
 	}
 	
 	dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
 
 	/*
 	 * Fetch the device class, driver can use this info
 	 * to differentiate between HUB and DEVICE.
 	 */
 	dev->descriptor.bDeviceClass = desc->bDeviceClass;
+	kfree(tmpbuf);
 
 	/* find the port number we're at */
 	if (parent) {
 		long j;
 
 		for (j = 0; j < parent->maxchild; j++) {
 			if (parent->children[j] == dev) {
 				port = j;
@@ -951,48 +960,46 @@
 		DEBUG(("USB device not accepting new address " \
 			"(error=%lx)", dev->status));
 		return 1;
 	}
 
 	mdelay(200);	/* Let the SET_ADDRESS settle */
 
 	tmp = sizeof(dev->descriptor);
+	tmpbuf = kmalloc(tmp);
 
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, tmpbuf, tmp);
 	if (err < tmp) {
 		if (err < 0)
 			DEBUG(("unable to get device descriptor (error=%ld)",
 			       err));
 		else
 			DEBUG(("USB device descriptor short read " \
 				"(expected %li, got %li)", tmp, err));
+		kfree(tmpbuf);
 		return 1;
 	}
 	memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
 	/* correct le values */
 	dev->descriptor.bcdUSB = le2cpu16(dev->descriptor.bcdUSB);
 	dev->descriptor.idVendor = le2cpu16(dev->descriptor.idVendor);
 	dev->descriptor.idProduct = le2cpu16(dev->descriptor.idProduct);
 	dev->descriptor.bcdDevice = le2cpu16(dev->descriptor.bcdDevice);
+	kfree(tmpbuf);
+
 	/* only support for one config for now */
 	err = usb_get_configuration_no(dev, tmpbuf, 0);
 	if (err < 0) {
 		DEBUG(("usb_new_device: Cannot read configuration, " \
 		       "skipping device %04x:%04x\n",
 		       dev->descriptor.idVendor, dev->descriptor.idProduct));
 		return -1;
 	}
-	err = usb_parse_config(dev, tmpbuf, 0);
-	if (err < 0) {
-		DEBUG(("usb_new_device: Cannot parse configuration, " \
-		       "skipping device %04x:%04x\n",
-		       dev->descriptor.idVendor, dev->descriptor.idProduct));
-		return -1;
-	}
+
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
 		DEBUG(("failed to set default configuration " \
 			"len %ld, status %lx", dev->act_len, dev->status));
 		return -1;
 	}
 	DEBUG(("new device strings: Mfr=%d, Product=%d, SerialNumber=%d",