diff options
| author | Hans Petter Selasky <hselasky@FreeBSD.org> | 2013-05-03 11:10:04 +0000 |
|---|---|---|
| committer | Hans Petter Selasky <hselasky@FreeBSD.org> | 2013-05-03 11:10:04 +0000 |
| commit | 2c79a775ed2daeee80f5a665e947648f501bf40e (patch) | |
| tree | da34869305f7442f6ba4ce940376c157aa9705e3 | |
| parent | 5d0b98f2c3b1859dd31c4481cc2db94c7f2431ef (diff) | |
Notes
| -rw-r--r-- | sys/dev/usb/template/usb_template.c | 11 | ||||
| -rw-r--r-- | sys/dev/usb/usb_device.c | 4 | ||||
| -rw-r--r-- | sys/dev/usb/usb_device.h | 4 | ||||
| -rw-r--r-- | sys/dev/usb/usb_dynamic.c | 9 | ||||
| -rw-r--r-- | sys/dev/usb/usb_freebsd.h | 3 | ||||
| -rw-r--r-- | sys/dev/usb/usb_freebsd_loader.h | 3 | ||||
| -rw-r--r-- | sys/dev/usb/usb_generic.c | 17 | ||||
| -rw-r--r-- | sys/dev/usb/usb_hub.c | 26 | ||||
| -rw-r--r-- | sys/dev/usb/usb_hub.h | 4 | ||||
| -rw-r--r-- | sys/dev/usb/usb_request.c | 48 | ||||
| -rw-r--r-- | sys/dev/usb/usb_request.h | 5 |
11 files changed, 99 insertions, 35 deletions
diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c index b815161e898e..73ca73b079e3 100644 --- a/sys/dev/usb/template/usb_template.c +++ b/sys/dev/usb/template/usb_template.c @@ -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 diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index b1770cee11e5..b88a0e1cea5d 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -493,7 +493,7 @@ usb_unconfigure(struct usb_device *udev, uint8_t flag) /* 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 *udev, uint8_t index) } else { /* normal request */ err = usbd_req_get_config_desc_full(udev, - NULL, &cdp, M_USB, index); + NULL, &cdp, index); } if (err) { goto done; diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h index 89dff364c8fe..06b931fb0b26 100644 --- a/sys/dev/usb/usb_device.h +++ b/sys/dev/usb/usb_device.h @@ -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 */ diff --git a/sys/dev/usb/usb_dynamic.c b/sys/dev/usb/usb_dynamic.c index 58deb4e2cf32..d08e7f84afd8 100644 --- a/sys/dev/usb/usb_dynamic.c +++ b/sys/dev/usb/usb_dynamic.c @@ -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 *udev, struct usb_device_request *req, con 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 diff --git a/sys/dev/usb/usb_freebsd.h b/sys/dev/usb/usb_freebsd.h index 10f412e91ec5..870e869e714d 100644 --- a/sys/dev/usb/usb_freebsd.h +++ b/sys/dev/usb/usb_freebsd.h @@ -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 */ diff --git a/sys/dev/usb/usb_freebsd_loader.h b/sys/dev/usb/usb_freebsd_loader.h index 10ee06374d67..2a1e1044bcfb 100644 --- a/sys/dev/usb/usb_freebsd_loader.h +++ b/sys/dev/usb/usb_freebsd_loader.h @@ -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 */ diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c index 013210aa7e05..8e1033e4a9ca 100644 --- a/sys/dev/usb/usb_generic.c +++ b/sys/dev/usb/usb_generic.c @@ -688,18 +688,21 @@ ugen_get_cdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd) 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, struct usb_gen_descriptor *ugd) 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); } diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index a359ee252937..227f31730f6c 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -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); diff --git a/sys/dev/usb/usb_hub.h b/sys/dev/usb/usb_hub.h index 23a1fa4f1c5c..4a48f747c782 100644 --- a/sys/dev/usb/usb_hub.h +++ b/sys/dev/usb/usb_hub.h @@ -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 */ diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c index cc7765624e46..0a82462148d9 100644 --- a/sys/dev/usb/usb_request.c +++ b/sys/dev/usb/usb_request.c @@ -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_device *udev, struct mtx *mtx, 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: */ diff --git a/sys/dev/usb/usb_request.h b/sys/dev/usb/usb_request.h index 5fcedd5e5247..9f0a4e644d55 100644 --- a/sys/dev/usb/usb_request.h +++ b/sys/dev/usb/usb_request.h @@ -44,7 +44,7 @@ usb_error_t usbd_req_get_config_desc(struct usb_device *udev, struct mtx *mtx, 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(struct usb_device *udev, 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_ */ |
