+++ /dev/null
-.\" $OpenBSD: udfu.4,v 1.3 2009/11/11 19:11:13 fgsch Exp $
-.\"
-.\" Copyright (c) 2008 Ian Darwin <ian@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.
-.\"
-.Dd $Mdocdate: November 11 2009 $
-.Dt UDFU 4
-.Os
-.Sh NAME
-.Nm udfu
-.Nd Device Firmware Upgrade (DFU) Attach
-.Sh SYNOPSIS
-.Cd "udfu* at uhub?"
-.Sh DESCRIPTION
-The
-.Nm
-driver configures a DFU-compatible device such as the Openmoko telephone
-into DFU mode, then detaches it,
-permitting it to be attached for read/write access as a
-.Xr ugen 4
-device to re-flash the memory.
-.Pp
-Note that this interferes with using the
-.Xr umodem 4
-interface to this device, which is sometimes needed for manual re-configuration.
-To enable the use of
-.Xr umodem 4 ,
-it is necessary to disable
-.Nm ,
-either permanently in the kernel configuration file or using
-.Xr boot_config 8 .
-.Sh SEE ALSO
-.Xr ugen 4 ,
-.Xr uhub 4 ,
-.Xr usb 4 ,
-.Xr boot_config 8 ,
-.Xr config 8
-.\" .Pp
-.\" The
-.\" .Xr dfu-util
-.\" program is available in the OpenBSD ports tree.
-.Sh HISTORY
-The
-.Nm
-driver
-first appeared in
-.Ox 4.5 .
+++ /dev/null
-/* $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));
-}