From owner-svn-src-all@FreeBSD.ORG Fri May 3 11:10:06 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id EC39B862; Fri, 3 May 2013 11:10:06 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id CEC77179D; Fri, 3 May 2013 11:10:06 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r43BA6Sv023519; Fri, 3 May 2013 11:10:06 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r43BA4Rx023357; Fri, 3 May 2013 11:10:04 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201305031110.r43BA4Rx023357@svn.freebsd.org> From: Hans Petter Selasky Date: Fri, 3 May 2013 11:10:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r250207 - in head/sys/dev/usb: . template X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 May 2013 11:10:07 -0000 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 #include +#include #include #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 #include #include +#include #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_ */