summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2013-05-03 09:23:06 +0000
committerhselasky <hselasky@FreeBSD.org>2013-05-03 09:23:06 +0000
commit57751c101234923903b31c7a3c647344c8ce0b07 (patch)
treedd0a8296a2fbe99965630ec96718a239a7bd0c44
parentd165ee7e6a9a2954de10e6475980c19e1de8a8df (diff)
downloadFreeBSD-src-57751c101234923903b31c7a3c647344c8ce0b07.zip
FreeBSD-src-57751c101234923903b31c7a3c647344c8ce0b07.tar.gz
Add some defines to limit USB memory usage in reduced memory systems.
-rw-r--r--sys/dev/usb/usb_device.c27
-rw-r--r--sys/dev/usb/usb_device.h8
-rw-r--r--sys/dev/usb/usb_freebsd.h4
-rw-r--r--sys/dev/usb/usb_freebsd_loader.h4
-rw-r--r--sys/dev/usb/usb_parse.c15
-rw-r--r--sys/dev/usb/usb_request.c14
6 files changed, 53 insertions, 19 deletions
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 9fa0e5c..b1770ce 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -729,10 +729,6 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd)
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, uint8_t iface_index, uint8_t cmd)
/* 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, uint8_t iface_index, uint8_t cmd)
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, uint8_t iface_index, uint8_t cmd)
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, uint8_t iface_index, uint8_t cmd)
} 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;
}
}
diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h
index b194256..89dff36 100644
--- a/sys/dev/usb/usb_device.h
+++ b/sys/dev/usb/usb_device.h
@@ -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 */
diff --git a/sys/dev/usb/usb_freebsd.h b/sys/dev/usb/usb_freebsd.h
index 026baab..10f412e 100644
--- a/sys/dev/usb/usb_freebsd.h
+++ b/sys/dev/usb/usb_freebsd.h
@@ -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 */
diff --git a/sys/dev/usb/usb_freebsd_loader.h b/sys/dev/usb/usb_freebsd_loader.h
index b21c229..10ee063 100644
--- a/sys/dev/usb/usb_freebsd_loader.h
+++ b/sys/dev/usb/usb_freebsd_loader.h
@@ -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 */
diff --git a/sys/dev/usb/usb_parse.c b/sys/dev/usb/usb_parse.c
index d6e54ad..0744696 100644
--- a/sys/dev/usb/usb_parse.c
+++ b/sys/dev/usb/usb_parse.c
@@ -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_descriptor *cd,
}
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_descriptor *cd,
/* 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;
diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
index 673ec7c..cc77656 100644
--- a/sys/dev/usb/usb_request.c
+++ b/sys/dev/usb/usb_request.c
@@ -1276,7 +1276,7 @@ usbd_req_get_config_desc_full(struct usb_device *udev, struct mtx *mtx,
{
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_device *udev, struct mtx *mtx,
*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) {
OpenPOWER on IntegriCloud