diff options
Diffstat (limited to 'sys/dev/usb/udfu.c')
-rw-r--r-- | sys/dev/usb/udfu.c | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/sys/dev/usb/udfu.c b/sys/dev/usb/udfu.c deleted file mode 100644 index 10c4da4c903..00000000000 --- a/sys/dev/usb/udfu.c +++ /dev/null @@ -1,223 +0,0 @@ -/* $OpenBSD: udfu.c,v 1.6 2013/04/26 13:46:40 mglocker Exp $ */ - -/* - * Copyright (c) 2009 Federico G. Schwindt <fgsch@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for - * any purpose with or without fee is hereby granted, provided that - * the above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA - * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * DFU spec: http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf - */ - -#include <sys/param.h> -#include <sys/device.h> -#include <sys/systm.h> -#include <sys/timeout.h> - -#include <machine/bus.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdivar.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdevs.h> - -#ifdef UDFU_DEBUG -#define DPRINTF(x) printf x -#else -#define DPRINTF(x) -#endif - -#define RUNTIME_MODE 1 - -#define DFU_DETACH UT_WRITE_CLASS_INTERFACE, 0 -#define DFU_GETSTATE UT_READ_CLASS_INTERFACE, 5 -#define DFU_STATE_appIDLE 0 - -struct dfu_functional_descriptor { - uByte bLength; - uByte bDescriptorType; - uByte bmAttributes; -#define BWILLDETACH 8 - uWord wDetachTimeOut; - uWord wTransferSize; - uWord bcdDFUVersion; -} __packed; - -#define UDFU_DETACH_TIMEOUT 1000 /* in milliseconds */ - -struct udfu_softc { - struct device sc_dev; - struct usbd_device *sc_udev; - - int sc_iface_index; - - int sc_will_detach; - int sc_detach_timeout; -}; - -int udfu_match(struct device *, void *, void *); -void udfu_attach(struct device *, struct device *, void *); -int udfu_detach(struct device *, int); -int udfu_activate(struct device *, int); - -void udfu_parse_desc(struct udfu_softc *); -int udfu_request(struct udfu_softc *, int, int, int, void *, size_t); - -struct cfdriver udfu_cd = { - NULL, "udfu", DV_DULL -}; - -const struct cfattach udfu_ca = { - sizeof(struct udfu_softc), - udfu_match, - udfu_attach, - udfu_detach, - udfu_activate -}; - -int -udfu_match(struct device *parent, void *match, void *aux) -{ - struct usb_attach_arg *uaa = aux; - usb_interface_descriptor_t *id; - - if (uaa->iface == NULL) - return (UMATCH_NONE); - - id = usbd_get_interface_descriptor(uaa->iface); - if (id == NULL) - return (UMATCH_NONE); - - if (id->bInterfaceClass == UICLASS_APPL_SPEC && - id->bInterfaceSubClass == UISUBCLASS_FIRMWARE_DOWNLOAD && - id->bInterfaceProtocol == RUNTIME_MODE) - return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); - - return (UMATCH_NONE); -} - -void -udfu_attach(struct device *parent, struct device *self, void *aux) -{ - struct udfu_softc *sc = (struct udfu_softc *)self; - struct usb_attach_arg *uaa = aux; - usbd_status err; - u_int8_t state; - - sc->sc_udev = uaa->device; - sc->sc_iface_index = uaa->iface->index; - sc->sc_detach_timeout = UDFU_DETACH_TIMEOUT; - - /* Parse the DFU functional descriptor. */ - udfu_parse_desc(sc); - - /* - * GETSTATE is optional in Runtime mode. If it fails, assume - * appIDLE and hope for the best. - */ - if ((err = udfu_request(sc, DFU_GETSTATE, 0, &state, 1))) { - printf("%s: could not get current state, " - "assuming appIDLE\n", sc->sc_dev.dv_xname); - state = DFU_STATE_appIDLE; - } - - switch (state) { - case DFU_STATE_appIDLE: - err = udfu_request(sc, DFU_DETACH, - min(UDFU_DETACH_TIMEOUT, sc->sc_detach_timeout), - NULL, 0); - if (err) - printf("%s: DFU_DETACH failed\n", - sc->sc_dev.dv_xname); - break; - - default: - printf("%s: unexpected state %d\n", - sc->sc_dev.dv_xname, state); - err = 1; - break; - } - - if (!sc->sc_will_detach && err == 0) - usb_needs_reattach(sc->sc_udev); -} - -int -udfu_detach(struct device *self, int flags) -{ - /* struct udfu_softc *sc = (struct udfu_softc *)self; */ - - return (0); -} - -int -udfu_activate(struct device *self, int act) -{ - struct udfu_softc *sc = (struct udfu_softc *)self; - - switch (act) { - case DVACT_DEACTIVATE: - usbd_deactivate(sc->sc_udev); - break; - } - - return 0; -} - -void -udfu_parse_desc(struct udfu_softc *sc) -{ - struct dfu_functional_descriptor *dd; - const usb_descriptor_t *desc; - struct usbd_desc_iter iter; - - usbd_desc_iter_init(sc->sc_udev, &iter); - while ((desc = usbd_desc_iter_next(&iter))) { - if (desc->bDescriptorType == UDESC_CS_DEVICE) - break; - } - - if (!desc) - return; - - dd = (struct dfu_functional_descriptor *)desc; - - DPRINTF(("%s: %s: bLength=%d bDescriptorType=%d bmAttributes=%d " - "wDetachTimeOut=%d wTransferSize=%d bcdDFUVersion=%d\n", - sc->sc_dev.dv_xname, __func__, dd->bLength, - dd->bDescriptorType, dd->bmAttributes, - UGETW(dd->wDetachTimeOut), UGETW(dd->wTransferSize), - UGETW(dd->bcdDFUVersion))); - - sc->sc_will_detach = dd->bmAttributes & BWILLDETACH; - sc->sc_detach_timeout = UGETW(dd->wDetachTimeOut); -} - -int -udfu_request(struct udfu_softc *sc, int type, int cmd, int value, - void *data, size_t datalen) -{ - usb_device_request_t req; - - req.bmRequestType = type; - req.bRequest = cmd; - USETW(req.wValue, value); - USETW(req.wIndex, sc->sc_iface_index); - USETW(req.wLength, datalen); - - return (usbd_do_request(sc->sc_udev, &req, data)); -} |