svn commit: r250207 - in head/sys/dev/usb: . template
Hans Petter Selasky
hselasky at FreeBSD.org
Fri May 3 11:10:07 UTC 2013
Author: hselasky
Date: Fri May 3 11:10:04 2013
New Revision: 250207
URL: http://svnweb.freebsd.org/changeset/base/250207
Log:
- Add more defines to limit USB memory usage and number of allocations
in reduced memory systems.
- Split allocation and freeing of the configuration descriptor into a separate
function, so that the configuration descriptor can be made fixed size
to save memory allocations. This applies for both device and host mode.
Modified:
head/sys/dev/usb/template/usb_template.c
head/sys/dev/usb/usb_device.c
head/sys/dev/usb/usb_device.h
head/sys/dev/usb/usb_dynamic.c
head/sys/dev/usb/usb_freebsd.h
head/sys/dev/usb/usb_freebsd_loader.h
head/sys/dev/usb/usb_generic.c
head/sys/dev/usb/usb_hub.c
head/sys/dev/usb/usb_hub.h
head/sys/dev/usb/usb_request.c
head/sys/dev/usb/usb_request.h
Modified: head/sys/dev/usb/template/usb_template.c
==============================================================================
--- head/sys/dev/usb/template/usb_template.c Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/template/usb_template.c Fri May 3 11:10:04 2013 (r250207)
@@ -69,6 +69,7 @@
#include <dev/usb/usb_controller.h>
#include <dev/usb/usb_bus.h>
+#include <dev/usb/usb_request.h>
#include <dev/usb/template/usb_template.h>
#endif /* USB_GLOBAL_INCLUDE_FILE */
@@ -1267,7 +1268,7 @@ usb_temp_setup(struct usb_device *udev,
goto done;
}
/* allocate zeroed memory */
- uts->buf = malloc(uts->size, M_USB, M_WAITOK | M_ZERO);
+ uts->buf = usbd_alloc_config_desc(udev, uts->size);
/*
* Allow malloc() to return NULL regardless of M_WAITOK flag.
* This helps when porting the software to non-FreeBSD
@@ -1336,12 +1337,8 @@ done:
void
usb_temp_unsetup(struct usb_device *udev)
{
- if (udev->usb_template_ptr) {
-
- free(udev->usb_template_ptr, M_USB);
-
- udev->usb_template_ptr = NULL;
- }
+ usbd_free_config_desc(udev, udev->usb_template_ptr);
+ udev->usb_template_ptr = NULL;
}
static usb_error_t
Modified: head/sys/dev/usb/usb_device.c
==============================================================================
--- head/sys/dev/usb/usb_device.c Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_device.c Fri May 3 11:10:04 2013 (r250207)
@@ -493,7 +493,7 @@ usb_unconfigure(struct usb_device *udev,
/* free "cdesc" after "ifaces" and "endpoints", if any */
if (udev->cdesc != NULL) {
if (udev->flags.usb_mode != USB_MODE_DEVICE)
- free(udev->cdesc, M_USB);
+ usbd_free_config_desc(udev, udev->cdesc);
udev->cdesc = NULL;
}
/* set unconfigured state */
@@ -552,7 +552,7 @@ usbd_set_config_index(struct usb_device
} else {
/* normal request */
err = usbd_req_get_config_desc_full(udev,
- NULL, &cdp, M_USB, index);
+ NULL, &cdp, index);
}
if (err) {
goto done;
Modified: head/sys/dev/usb/usb_device.h
==============================================================================
--- head/sys/dev/usb/usb_device.h Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_device.h Fri May 3 11:10:04 2013 (r250207)
@@ -267,6 +267,10 @@ struct usb_device {
uint32_t clear_stall_errors; /* number of clear-stall failures */
union usb_device_scratch scratch;
+
+#if (USB_HAVE_FIXED_CONFIG != 0)
+ uint32_t config_data[(USB_CONFIG_MAX + 3) / 4];
+#endif
};
/* globals */
Modified: head/sys/dev/usb/usb_dynamic.c
==============================================================================
--- head/sys/dev/usb/usb_dynamic.c Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_dynamic.c Fri May 3 11:10:04 2013 (r250207)
@@ -53,6 +53,7 @@
#include <dev/usb/usb_process.h>
#include <dev/usb/usb_device.h>
#include <dev/usb/usb_dynamic.h>
+#include <dev/usb/usb_request.h>
#endif /* USB_GLOBAL_INCLUDE_FILE */
/* function prototypes */
@@ -98,12 +99,8 @@ usb_temp_get_desc_w(struct usb_device *u
static void
usb_temp_unsetup_w(struct usb_device *udev)
{
- if (udev->usb_template_ptr) {
-
- free(udev->usb_template_ptr, M_USB);
-
- udev->usb_template_ptr = NULL;
- }
+ usbd_free_config_desc(udev, udev->usb_template_ptr);
+ udev->usb_template_ptr = NULL;
}
void
Modified: head/sys/dev/usb/usb_freebsd.h
==============================================================================
--- head/sys/dev/usb/usb_freebsd.h Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_freebsd.h Fri May 3 11:10:04 2013 (r250207)
@@ -47,6 +47,8 @@
#define USB_HAVE_PER_BUS_PROCESS 1
#define USB_HAVE_FIXED_ENDPOINT 0
#define USB_HAVE_FIXED_IFACE 0
+#define USB_HAVE_FIXED_CONFIG 0
+#define USB_HAVE_FIXED_PORT 0
#define USB_TD_GET_PROC(td) (td)->td_proc
#define USB_PROC_GET_GID(td) (td)->p_pgid
@@ -68,6 +70,7 @@
#define USB_FIFO_MAX 128 /* units */
#define USB_MAX_EP_STREAMS 8 /* units */
#define USB_MAX_EP_UNITS 32 /* units */
+#define USB_MAX_PORTS 255 /* 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 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_freebsd_loader.h Fri May 3 11:10:04 2013 (r250207)
@@ -47,6 +47,8 @@
#define USB_HAVE_PER_BUS_PROCESS 0
#define USB_HAVE_FIXED_ENDPOINT 0
#define USB_HAVE_FIXED_IFACE 0
+#define USB_HAVE_FIXED_CONFIG 0
+#define USB_HAVE_FIXED_PORT 0
#define USB_TD_GET_PROC(td) (td)->td_proc
#define USB_PROC_GET_GID(td) (td)->p_pgid
@@ -68,6 +70,7 @@
#define USB_FIFO_MAX 128 /* units */
#define USB_MAX_EP_UNITS 32 /* units */
#define USB_MAX_EP_STREAMS 8 /* units */
+#define USB_MAX_PORTS 255 /* 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_generic.c
==============================================================================
--- head/sys/dev/usb/usb_generic.c Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_generic.c Fri May 3 11:10:04 2013 (r250207)
@@ -688,18 +688,21 @@ ugen_get_cdesc(struct usb_fifo *f, struc
if ((ugd->ugd_config_index == USB_UNCONFIG_INDEX) ||
(ugd->ugd_config_index == udev->curr_config_index)) {
cdesc = usbd_get_config_descriptor(udev);
- if (cdesc == NULL) {
+ if (cdesc == NULL)
return (ENXIO);
- }
free_data = 0;
} else {
+#if (USB_HAVE_FIXED_CONFIG == 0)
if (usbd_req_get_config_desc_full(udev,
- NULL, &cdesc, M_USBDEV,
- ugd->ugd_config_index)) {
+ NULL, &cdesc, ugd->ugd_config_index)) {
return (ENXIO);
}
free_data = 1;
+#else
+ /* configuration descriptor data is shared */
+ return (EINVAL);
+#endif
}
len = UGETW(cdesc->wTotalLength);
@@ -713,9 +716,9 @@ ugen_get_cdesc(struct usb_fifo *f, struc
error = copyout(cdesc, ugd->ugd_data, len);
- if (free_data) {
- free(cdesc, M_USBDEV);
- }
+ if (free_data)
+ usbd_free_config_desc(udev, cdesc);
+
return (error);
}
Modified: head/sys/dev/usb/usb_hub.c
==============================================================================
--- head/sys/dev/usb/usb_hub.c Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_hub.c Fri May 3 11:10:04 2013 (r250207)
@@ -100,6 +100,9 @@ struct uhub_current_state {
struct uhub_softc {
struct uhub_current_state sc_st;/* current state */
+#if (USB_HAVE_FIXED_PORT != 0)
+ struct usb_hub sc_hub;
+#endif
device_t sc_dev; /* base device */
struct mtx sc_mtx; /* our mutex */
struct usb_device *sc_udev; /* USB device */
@@ -922,8 +925,8 @@ uhub_attach(device_t dev)
struct usb_hub_descriptor hubdesc20;
struct usb_hub_ss_descriptor hubdesc30;
uint16_t pwrdly;
+ uint16_t nports;
uint8_t x;
- uint8_t nports;
uint8_t portno;
uint8_t removable;
uint8_t iface_index;
@@ -1067,12 +1070,19 @@ uhub_attach(device_t dev)
DPRINTFN(0, "portless HUB\n");
goto error;
}
+ if (nports > USB_MAX_PORTS) {
+ DPRINTF("Port limit exceeded\n");
+ goto error;
+ }
+#if (USB_HAVE_FIXED_PORT == 0)
hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports),
M_USBDEV, M_WAITOK | M_ZERO);
- if (hub == NULL) {
+ if (hub == NULL)
goto error;
- }
+#else
+ hub = &sc->sc_hub;
+#endif
udev->hub = hub;
/* initialize HUB structure */
@@ -1197,10 +1207,10 @@ uhub_attach(device_t dev)
error:
usbd_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
- if (udev->hub) {
- free(udev->hub, M_USBDEV);
- udev->hub = NULL;
- }
+#if (USB_HAVE_FIXED_PORT == 0)
+ free(udev->hub, M_USBDEV);
+#endif
+ udev->hub = NULL;
mtx_destroy(&sc->sc_mtx);
@@ -1240,7 +1250,9 @@ uhub_detach(device_t dev)
usb_free_device(child, 0);
}
+#if (USB_HAVE_FIXED_PORT == 0)
free(hub, M_USBDEV);
+#endif
sc->sc_udev->hub = NULL;
mtx_destroy(&sc->sc_mtx);
Modified: head/sys/dev/usb/usb_hub.h
==============================================================================
--- head/sys/dev/usb/usb_hub.h Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_hub.h Fri May 3 11:10:04 2013 (r250207)
@@ -48,7 +48,11 @@ struct usb_hub {
uint16_t portpower; /* mA per USB port */
uint8_t isoc_last_time;
uint8_t nports;
+#if (USB_HAVE_FIXED_PORT == 0)
struct usb_port ports[0];
+#else
+ struct usb_port ports[USB_MAX_PORTS];
+#endif
};
/* function prototypes */
Modified: head/sys/dev/usb/usb_request.c
==============================================================================
--- head/sys/dev/usb/usb_request.c Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_request.c Fri May 3 11:10:04 2013 (r250207)
@@ -1260,10 +1260,49 @@ done:
}
/*------------------------------------------------------------------------*
+ * usbd_alloc_config_desc
+ *
+ * This function is used to allocate a zeroed configuration
+ * descriptor.
+ *
+ * Returns:
+ * NULL: Failure
+ * Else: Success
+ *------------------------------------------------------------------------*/
+void *
+usbd_alloc_config_desc(struct usb_device *udev, uint32_t size)
+{
+ if (size > USB_CONFIG_MAX) {
+ DPRINTF("Configuration descriptor too big\n");
+ return (NULL);
+ }
+#if (USB_HAVE_FIXED_CONFIG == 0)
+ return (malloc(size, M_USBDEV, M_ZERO | M_WAITOK));
+#else
+ memset(udev->config_data, 0, sizeof(udev->config_data));
+ return (udev->config_data);
+#endif
+}
+
+/*------------------------------------------------------------------------*
+ * usbd_alloc_config_desc
+ *
+ * This function is used to free a configuration descriptor.
+ *------------------------------------------------------------------------*/
+void
+usbd_free_config_desc(struct usb_device *udev, void *ptr)
+{
+#if (USB_HAVE_FIXED_CONFIG == 0)
+ free(ptr, M_USBDEV);
+#endif
+}
+
+/*------------------------------------------------------------------------*
* usbd_req_get_config_desc_full
*
* This function gets the complete USB configuration descriptor and
- * ensures that "wTotalLength" is correct.
+ * ensures that "wTotalLength" is correct. The returned configuration
+ * descriptor is freed by calling "usbd_free_config_desc()".
*
* Returns:
* 0: Success
@@ -1271,8 +1310,7 @@ done:
*------------------------------------------------------------------------*/
usb_error_t
usbd_req_get_config_desc_full(struct usb_device *udev, struct mtx *mtx,
- struct usb_config_descriptor **ppcd, struct malloc_type *mtype,
- uint8_t index)
+ struct usb_config_descriptor **ppcd, uint8_t index)
{
struct usb_config_descriptor cd;
struct usb_config_descriptor *cdesc;
@@ -1296,13 +1334,13 @@ usbd_req_get_config_desc_full(struct usb
DPRINTF("Configuration descriptor was truncated\n");
len = USB_CONFIG_MAX;
}
- cdesc = malloc(len, mtype, M_WAITOK);
+ cdesc = usbd_alloc_config_desc(udev, len);
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) {
- free(cdesc, mtype);
+ usbd_free_config_desc(udev, cdesc);
return (err);
}
/* make sure that the device is not fooling us: */
Modified: head/sys/dev/usb/usb_request.h
==============================================================================
--- head/sys/dev/usb/usb_request.h Fri May 3 10:37:59 2013 (r250206)
+++ head/sys/dev/usb/usb_request.h Fri May 3 11:10:04 2013 (r250207)
@@ -44,7 +44,7 @@ usb_error_t usbd_req_get_config_desc(str
struct usb_config_descriptor *d, uint8_t conf_index);
usb_error_t usbd_req_get_config_desc_full(struct usb_device *udev,
struct mtx *mtx, struct usb_config_descriptor **ppcd,
- struct malloc_type *mtype, uint8_t conf_index);
+ uint8_t conf_index);
usb_error_t usbd_req_get_desc(struct usb_device *udev, struct mtx *mtx,
uint16_t *actlen, void *desc, uint16_t min_len,
uint16_t max_len, uint16_t id, uint8_t type,
@@ -94,4 +94,7 @@ usb_error_t usbd_req_set_port_link_state
usb_error_t usbd_req_set_lpm_info(struct usb_device *udev, struct mtx *mtx,
uint8_t port, uint8_t besl, uint8_t addr, uint8_t rwe);
+void * usbd_alloc_config_desc(struct usb_device *, uint32_t);
+void usbd_free_config_desc(struct usb_device *, void *);
+
#endif /* _USB_REQUEST_H_ */
More information about the svn-src-all
mailing list