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) {
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to