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