svn commit: r250204 - head/sys/dev/usb

Hans Petter Selasky hselasky at FreeBSD.org
Fri May 3 09:23:08 UTC 2013


Author: hselasky
Date: Fri May  3 09:23:06 2013
New Revision: 250204
URL: http://svnweb.freebsd.org/changeset/base/250204

Log:
  Add some defines to limit USB memory usage in reduced memory systems.

Modified:
  head/sys/dev/usb/usb_device.c
  head/sys/dev/usb/usb_device.h
  head/sys/dev/usb/usb_freebsd.h
  head/sys/dev/usb/usb_freebsd_loader.h
  head/sys/dev/usb/usb_parse.c
  head/sys/dev/usb/usb_request.c

Modified: head/sys/dev/usb/usb_device.c
==============================================================================
--- head/sys/dev/usb/usb_device.c	Fri May  3 08:20:10 2013	(r250203)
+++ head/sys/dev/usb/usb_device.c	Fri May  3 09:23:06 2013	(r250204)
@@ -729,10 +729,6 @@ usb_config_parse(struct usb_device *udev
 
 	while ((id = usb_idesc_foreach(udev->cdesc, &ips))) {
 
-		/* check for interface overflow */
-		if (ips.iface_index == USB_IFACE_MAX)
-			break;			/* crazy */
-
 		iface = udev->ifaces + ips.iface_index;
 
 		/* check for specific interface match */
@@ -779,8 +775,11 @@ usb_config_parse(struct usb_device *udev
 		/* iterate all the endpoint descriptors */
 		while ((ed = usb_edesc_foreach(udev->cdesc, ed))) {
 
-			if (temp == USB_EP_MAX)
-				break;			/* crazy */
+			/* check if endpoint limit has been reached */
+			if (temp >= USB_MAX_EP_UNITS) {
+				DPRINTF("Endpoint limit reached\n");
+				break;
+			}
 
 			ep = udev->endpoints + temp;
 
@@ -810,6 +809,7 @@ usb_config_parse(struct usb_device *udev
 
 	if (cmd == USB_CFG_ALLOC) {
 		udev->ifaces_max = ips.iface_index;
+#if (USB_HAVE_FIXED_IFACE == 0)
 		udev->ifaces = NULL;
 		if (udev->ifaces_max != 0) {
 			udev->ifaces = malloc(sizeof(*iface) * udev->ifaces_max,
@@ -819,6 +819,8 @@ usb_config_parse(struct usb_device *udev
 				goto done;
 			}
 		}
+#endif
+#if (USB_HAVE_FIXED_ENDPOINT == 0)
 		if (ep_max != 0) {
 			udev->endpoints = malloc(sizeof(*ep) * ep_max,
 			        M_USB, M_WAITOK | M_ZERO);
@@ -829,6 +831,7 @@ usb_config_parse(struct usb_device *udev
 		} else {
 			udev->endpoints = NULL;
 		}
+#endif
 		USB_BUS_LOCK(udev->bus);
 		udev->endpoints_max = ep_max;
 		/* reset any ongoing clear-stall */
@@ -846,14 +849,14 @@ cleanup:
 			udev->ep_curr = NULL;
 			USB_BUS_UNLOCK(udev->bus);
 
-			/* cleanup */
-			if (udev->ifaces != NULL)
-				free(udev->ifaces, M_USB);
-			if (udev->endpoints != NULL)
-				free(udev->endpoints, M_USB);
-
+#if (USB_HAVE_FIXED_IFACE == 0)
+			free(udev->ifaces, M_USB);
 			udev->ifaces = NULL;
+#endif
+#if (USB_HAVE_FIXED_ENDPOINT == 0)
+			free(udev->endpoints, M_USB);
 			udev->endpoints = NULL;
+#endif
 			udev->ifaces_max = 0;
 		}
 	}

Modified: head/sys/dev/usb/usb_device.h
==============================================================================
--- head/sys/dev/usb/usb_device.h	Fri May  3 08:20:10 2013	(r250203)
+++ head/sys/dev/usb/usb_device.h	Fri May  3 09:23:06 2013	(r250204)
@@ -186,9 +186,17 @@ struct usb_device {
 	struct mtx device_mtx;
 	struct cv ctrlreq_cv;
 	struct cv ref_cv;
+#if (USB_HAVE_FIXED_IFACE == 0)
 	struct usb_interface *ifaces;
+#else
+	struct usb_interface ifaces[USB_IFACE_MAX];
+#endif
 	struct usb_endpoint ctrl_ep;	/* Control Endpoint 0 */
+#if (USB_HAVE_FIXED_ENDPOINT == 0)
 	struct usb_endpoint *endpoints;
+#else
+	struct usb_endpoint endpoints[USB_MAX_EP_UNITS];
+#endif
 	struct usb_power_save pwr_save;/* power save data */
 	struct usb_bus *bus;		/* our USB BUS */
 	device_t parent_dev;		/* parent device */

Modified: head/sys/dev/usb/usb_freebsd.h
==============================================================================
--- head/sys/dev/usb/usb_freebsd.h	Fri May  3 08:20:10 2013	(r250203)
+++ head/sys/dev/usb/usb_freebsd.h	Fri May  3 09:23:06 2013	(r250204)
@@ -45,6 +45,8 @@
 #define	USB_HAVE_ROOT_MOUNT_HOLD 1
 #define	USB_HAVE_ID_SECTION 1
 #define	USB_HAVE_PER_BUS_PROCESS 1
+#define	USB_HAVE_FIXED_ENDPOINT 0
+#define	USB_HAVE_FIXED_IFACE 0
 
 #define	USB_TD_GET_PROC(td) (td)->td_proc
 #define	USB_PROC_GET_GID(td) (td)->p_pgid
@@ -61,9 +63,11 @@
 #define	USB_FS_ISOC_UFRAME_MAX 4	/* exclusive unit */
 #define	USB_BUS_MAX 256			/* units */
 #define	USB_MAX_DEVICES 128		/* units */
+#define	USB_CONFIG_MAX 65535		/* bytes */
 #define	USB_IFACE_MAX 32		/* units */
 #define	USB_FIFO_MAX 128		/* units */
 #define	USB_MAX_EP_STREAMS 8		/* units */
+#define	USB_MAX_EP_UNITS 32		/* units */
 
 #define	USB_MAX_FS_ISOC_FRAMES_PER_XFER (120)	/* units */
 #define	USB_MAX_HS_ISOC_FRAMES_PER_XFER (8*120)	/* units */

Modified: head/sys/dev/usb/usb_freebsd_loader.h
==============================================================================
--- head/sys/dev/usb/usb_freebsd_loader.h	Fri May  3 08:20:10 2013	(r250203)
+++ head/sys/dev/usb/usb_freebsd_loader.h	Fri May  3 09:23:06 2013	(r250204)
@@ -45,6 +45,8 @@
 #define	USB_HAVE_ROOT_MOUNT_HOLD 0
 #define	USB_HAVE_ID_SECTION 0
 #define	USB_HAVE_PER_BUS_PROCESS 0
+#define	USB_HAVE_FIXED_ENDPOINT 0
+#define	USB_HAVE_FIXED_IFACE 0
 
 #define	USB_TD_GET_PROC(td) (td)->td_proc
 #define	USB_PROC_GET_GID(td) (td)->p_pgid
@@ -61,8 +63,10 @@
 #define	USB_FS_ISOC_UFRAME_MAX 4	/* exclusive unit */
 #define	USB_BUS_MAX 256			/* units */
 #define	USB_MAX_DEVICES 128		/* units */
+#define	USB_CONFIG_MAX 65535		/* bytes */
 #define	USB_IFACE_MAX 32		/* units */
 #define	USB_FIFO_MAX 128		/* units */
+#define	USB_MAX_EP_UNITS 32		/* units */
 #define	USB_MAX_EP_STREAMS 8		/* units */
 
 #define	USB_MAX_FS_ISOC_FRAMES_PER_XFER (120)	/* units */

Modified: head/sys/dev/usb/usb_parse.c
==============================================================================
--- head/sys/dev/usb/usb_parse.c	Fri May  3 08:20:10 2013	(r250203)
+++ head/sys/dev/usb/usb_parse.c	Fri May  3 09:23:06 2013	(r250204)
@@ -49,6 +49,11 @@
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
+
+#define	USB_DEBUG_VAR usb_debug
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_debug.h>
 #endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /*------------------------------------------------------------------------*
@@ -142,7 +147,7 @@ usb_idesc_foreach(struct usb_config_desc
 	}
 
 	if (ps->desc == NULL) {
-		/* first time */
+		/* first time or zero descriptors */
 	} else if (new_iface) {
 		/* new interface */
 		ps->iface_index ++;
@@ -151,6 +156,14 @@ usb_idesc_foreach(struct usb_config_desc
 		/* new alternate interface */
 		ps->iface_index_alt ++;
 	}
+#if (USB_IFACE_MAX <= 0)
+#error "USB_IFACE_MAX must be defined greater than zero"
+#endif
+	/* check for too many interfaces */
+	if (ps->iface_index >= USB_IFACE_MAX) {
+		DPRINTF("Interface limit reached\n");
+		id = NULL;
+	}
 
 	/* store and return current descriptor */
 	ps->desc = (struct usb_descriptor *)id;

Modified: head/sys/dev/usb/usb_request.c
==============================================================================
--- head/sys/dev/usb/usb_request.c	Fri May  3 08:20:10 2013	(r250203)
+++ head/sys/dev/usb/usb_request.c	Fri May  3 09:23:06 2013	(r250204)
@@ -1276,7 +1276,7 @@ usbd_req_get_config_desc_full(struct usb
 {
 	struct usb_config_descriptor cd;
 	struct usb_config_descriptor *cdesc;
-	uint16_t len;
+	uint32_t len;
 	usb_error_t err;
 
 	DPRINTFN(4, "index=%d\n", index);
@@ -1284,19 +1284,21 @@ usbd_req_get_config_desc_full(struct usb
 	*ppcd = NULL;
 
 	err = usbd_req_get_config_desc(udev, mtx, &cd, index);
-	if (err) {
+	if (err)
 		return (err);
-	}
+
 	/* get full descriptor */
 	len = UGETW(cd.wTotalLength);
-	if (len < sizeof(*cdesc)) {
+	if (len < (uint32_t)sizeof(*cdesc)) {
 		/* corrupt descriptor */
 		return (USB_ERR_INVAL);
+	} else if (len > USB_CONFIG_MAX) {
+		DPRINTF("Configuration descriptor was truncated\n");
+		len = USB_CONFIG_MAX;
 	}
 	cdesc = malloc(len, mtype, M_WAITOK);
-	if (cdesc == NULL) {
+	if (cdesc == NULL)
 		return (USB_ERR_NOMEM);
-	}
 	err = usbd_req_get_desc(udev, mtx, NULL, cdesc, len, len, 0,
 	    UDESC_CONFIG, index, 3);
 	if (err) {


More information about the svn-src-all mailing list