LCOV - code coverage report
Current view: top level - dev/usb - uow.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 266 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: uow.c,v 1.35 2016/11/06 12:58:01 mpi Exp $    */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
       5             :  *
       6             :  * Permission to use, copy, modify, and distribute this software for any
       7             :  * purpose with or without fee is hereby granted, provided that the above
       8             :  * copyright notice and this permission notice appear in all copies.
       9             :  *
      10             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17             :  */
      18             : 
      19             : /*
      20             :  * Maxim/Dallas DS2490 USB 1-Wire adapter driver.
      21             :  */
      22             : 
      23             : #include <sys/param.h>
      24             : #include <sys/systm.h>
      25             : #include <sys/device.h>
      26             : #include <sys/kernel.h>
      27             : 
      28             : #include <dev/onewire/onewirereg.h>
      29             : #include <dev/onewire/onewirevar.h>
      30             : 
      31             : #include <dev/usb/usb.h>
      32             : #include <dev/usb/usbdevs.h>
      33             : #include <dev/usb/usbdi.h>
      34             : #include <dev/usb/usbdi_util.h>
      35             : 
      36             : #include <dev/usb/uowreg.h>
      37             : 
      38             : #define UOW_TIMEOUT     1000    /* ms */
      39             : 
      40             : struct uow_softc {
      41             :         struct device            sc_dev;
      42             : 
      43             :         struct onewire_bus       sc_ow_bus;
      44             :         struct device           *sc_ow_dev;
      45             : 
      46             :         struct usbd_device      *sc_udev;
      47             :         struct usbd_interface   *sc_iface;
      48             :         struct usbd_pipe        *sc_ph_ibulk;
      49             :         struct usbd_pipe        *sc_ph_obulk;
      50             :         struct usbd_pipe        *sc_ph_intr;
      51             :         u_int8_t                 sc_regs[DS2490_NREGS];
      52             :         struct usbd_xfer        *sc_xfer_in;
      53             :         struct usbd_xfer        *sc_xfer_out;
      54             :         u_int8_t                 sc_fifo[DS2490_DATAFIFOSIZE];
      55             : };
      56             : 
      57             : int uow_match(struct device *, void *, void *); 
      58             : void uow_attach(struct device *, struct device *, void *); 
      59             : int uow_detach(struct device *, int); 
      60             : int uow_activate(struct device *, int); 
      61             : 
      62             : struct cfdriver uow_cd = { 
      63             :         NULL, "uow", DV_DULL 
      64             : }; 
      65             : 
      66             : const struct cfattach uow_ca = { 
      67             :         sizeof(struct uow_softc), 
      68             :         uow_match, 
      69             :         uow_attach, 
      70             :         uow_detach, 
      71             :         uow_activate, 
      72             : };
      73             : 
      74             : /* List of supported devices */
      75             : static const struct usb_devno uow_devs[] = {
      76             :         { USB_VENDOR_DALLAS,            USB_PRODUCT_DALLAS_USB_FOB_IBUTTON }
      77             : };
      78             : 
      79             : int     uow_ow_reset(void *);
      80             : int     uow_ow_bit(void *, int);
      81             : int     uow_ow_read_byte(void *);
      82             : void    uow_ow_write_byte(void *, int);
      83             : void    uow_ow_read_block(void *, void *, int);
      84             : void    uow_ow_write_block(void *, const void *, int);
      85             : void    uow_ow_matchrom(void *, u_int64_t);
      86             : int     uow_ow_search(void *, u_int64_t *, int, u_int64_t);
      87             : 
      88             : int     uow_cmd(struct uow_softc *, int, int, int);
      89             : #define uow_ctlcmd(s, c, p)     uow_cmd((s), DS2490_CONTROL_CMD, (c), (p))
      90             : #define uow_commcmd(s, c, p)    uow_cmd((s), DS2490_COMM_CMD, (c), (p))
      91             : #define uow_modecmd(s, c, p)    uow_cmd((s), DS2490_MODE_CMD, (c), (p))
      92             : 
      93             : void    uow_intr(struct usbd_xfer *, void *, usbd_status);
      94             : int     uow_read(struct uow_softc *, void *, int);
      95             : int     uow_write(struct uow_softc *, const void *, int);
      96             : int     uow_reset(struct uow_softc *);
      97             : 
      98             : int
      99           0 : uow_match(struct device *parent, void *match, void *aux)
     100             : {
     101           0 :         struct usb_attach_arg *uaa = aux;
     102             : 
     103           0 :         if (uaa->iface == NULL || uaa->configno != DS2490_USB_CONFIG)
     104           0 :                 return (UMATCH_NONE);
     105             : 
     106           0 :         return ((usb_lookup(uow_devs, uaa->vendor, uaa->product) != NULL) ?
     107             :             UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
     108           0 : }
     109             : 
     110             : void
     111           0 : uow_attach(struct device *parent, struct device *self, void *aux)
     112             : {
     113           0 :         struct uow_softc *sc = (struct uow_softc *)self;
     114           0 :         struct usb_attach_arg *uaa = aux;
     115             :         usb_interface_descriptor_t *id;
     116             :         usb_endpoint_descriptor_t *ed;
     117             :         int ep_ibulk = -1, ep_obulk = -1, ep_intr = -1;
     118           0 :         struct onewirebus_attach_args oba;
     119             :         usbd_status error;
     120             :         int i;
     121             : 
     122           0 :         sc->sc_udev = uaa->device;
     123             : 
     124             :         /* Get interface handle */
     125           0 :         if ((error = usbd_device2interface_handle(sc->sc_udev,
     126           0 :             DS2490_USB_IFACE, &sc->sc_iface)) != 0) {
     127           0 :                 printf("%s: failed to get iface %d: %s\n",
     128           0 :                     sc->sc_dev.dv_xname, DS2490_USB_IFACE,
     129           0 :                     usbd_errstr(error));
     130           0 :                 return;
     131             :         }
     132             : 
     133             :         /* Find endpoints */
     134           0 :         id = usbd_get_interface_descriptor(sc->sc_iface);
     135           0 :         for (i = 0; i < id->bNumEndpoints; i++) {
     136           0 :                 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
     137           0 :                 if (ed == NULL) {
     138           0 :                         printf("%s: failed to get endpoint %d descriptor\n",
     139           0 :                             sc->sc_dev.dv_xname, i);
     140           0 :                         return;
     141             :                 }
     142             : 
     143           0 :                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
     144           0 :                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
     145           0 :                         ep_ibulk = ed->bEndpointAddress;
     146           0 :                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
     147           0 :                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
     148           0 :                         ep_obulk = ed->bEndpointAddress;
     149           0 :                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
     150           0 :                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT)
     151           0 :                         ep_intr = ed->bEndpointAddress;
     152             :         }
     153           0 :         if (ep_ibulk == -1 || ep_obulk == -1 || ep_intr == -1) {
     154           0 :                 printf("%s: missing endpoint: ibulk %d, obulk %d, intr %d\n",
     155           0 :                    sc->sc_dev.dv_xname, ep_ibulk, ep_obulk, ep_intr);
     156           0 :                 return;
     157             :         }
     158             : 
     159             :         /* Open pipes */
     160           0 :         if ((error = usbd_open_pipe(sc->sc_iface, ep_ibulk, USBD_EXCLUSIVE_USE,
     161           0 :             &sc->sc_ph_ibulk)) != 0) {
     162           0 :                 printf("%s: failed to open bulk-in pipe: %s\n",
     163           0 :                     sc->sc_dev.dv_xname, usbd_errstr(error));
     164           0 :                 return;
     165             :         }
     166           0 :         if ((error = usbd_open_pipe(sc->sc_iface, ep_obulk, USBD_EXCLUSIVE_USE,
     167           0 :             &sc->sc_ph_obulk)) != 0) {
     168           0 :                 printf("%s: failed to open bulk-out pipe: %s\n",
     169           0 :                     sc->sc_dev.dv_xname, usbd_errstr(error));
     170           0 :                 goto fail;
     171             :         }
     172           0 :         if ((error = usbd_open_pipe_intr(sc->sc_iface, ep_intr,
     173           0 :             USBD_SHORT_XFER_OK, &sc->sc_ph_intr, sc,
     174           0 :             sc->sc_regs, sizeof(sc->sc_regs), uow_intr,
     175           0 :             USBD_DEFAULT_INTERVAL)) != 0) {
     176           0 :                 printf("%s: failed to open intr pipe: %s\n",
     177           0 :                     sc->sc_dev.dv_xname, usbd_errstr(error));
     178           0 :                 goto fail;
     179             :         }
     180             : 
     181             :         /* Allocate xfers for bulk transfers */
     182           0 :         if ((sc->sc_xfer_in = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
     183           0 :                 printf("%s: failed to alloc bulk-in xfer\n",
     184           0 :                     sc->sc_dev.dv_xname);
     185           0 :                 goto fail;
     186             :         }
     187           0 :         if ((sc->sc_xfer_out = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
     188           0 :                 printf("%s: failed to alloc bulk-out xfer\n",
     189           0 :                     sc->sc_dev.dv_xname);
     190           0 :                 goto fail;
     191             :         }
     192             : 
     193           0 :         memset(sc->sc_fifo, 0xff, sizeof(sc->sc_fifo));
     194             : 
     195             :         /* Reset device */
     196           0 :         uow_reset(sc);
     197             : 
     198             :         /* Attach 1-Wire bus */
     199           0 :         sc->sc_ow_bus.bus_cookie = sc;
     200           0 :         sc->sc_ow_bus.bus_reset = uow_ow_reset;
     201           0 :         sc->sc_ow_bus.bus_bit = uow_ow_bit;
     202           0 :         sc->sc_ow_bus.bus_read_byte = uow_ow_read_byte;
     203           0 :         sc->sc_ow_bus.bus_write_byte = uow_ow_write_byte;
     204           0 :         sc->sc_ow_bus.bus_read_block = uow_ow_read_block;
     205           0 :         sc->sc_ow_bus.bus_write_block = uow_ow_write_block;
     206           0 :         sc->sc_ow_bus.bus_matchrom = uow_ow_matchrom;
     207             : #if 0
     208             :         sc->sc_ow_bus.bus_search = uow_ow_search;
     209             : #endif
     210             : 
     211           0 :         bzero(&oba, sizeof(oba));
     212           0 :         oba.oba_bus = &sc->sc_ow_bus;
     213           0 :         sc->sc_ow_dev = config_found(self, &oba, onewirebus_print);
     214             : 
     215           0 :         return;
     216             : 
     217             : fail:
     218           0 :         if (sc->sc_ph_ibulk != NULL) {
     219           0 :                 usbd_close_pipe(sc->sc_ph_ibulk);
     220           0 :                 sc->sc_ph_ibulk = NULL;
     221           0 :         }
     222           0 :         if (sc->sc_ph_obulk != NULL) {
     223           0 :                 usbd_close_pipe(sc->sc_ph_obulk);
     224           0 :                 sc->sc_ph_obulk = NULL;
     225           0 :         }
     226           0 :         if (sc->sc_ph_intr != NULL) {
     227           0 :                 usbd_close_pipe(sc->sc_ph_intr);
     228           0 :                 sc->sc_ph_intr = NULL;
     229           0 :         }
     230           0 :         if (sc->sc_xfer_in != NULL) {
     231           0 :                 usbd_free_xfer(sc->sc_xfer_in);
     232           0 :                 sc->sc_xfer_in = NULL;
     233           0 :         }
     234           0 :         if (sc->sc_xfer_out != NULL) {
     235           0 :                 usbd_free_xfer(sc->sc_xfer_out);
     236           0 :                 sc->sc_xfer_out = NULL;
     237           0 :         }
     238           0 : }
     239             : 
     240             : int
     241           0 : uow_detach(struct device *self, int flags)
     242             : {
     243           0 :         struct uow_softc *sc = (struct uow_softc *)self;
     244             :         int rv = 0, s;
     245             : 
     246           0 :         s = splusb();
     247             : 
     248           0 :         if (sc->sc_ph_ibulk != NULL) {
     249           0 :                 usbd_abort_pipe(sc->sc_ph_ibulk);
     250           0 :                 usbd_close_pipe(sc->sc_ph_ibulk);
     251           0 :         }
     252           0 :         if (sc->sc_ph_obulk != NULL) {
     253           0 :                 usbd_abort_pipe(sc->sc_ph_obulk);
     254           0 :                 usbd_close_pipe(sc->sc_ph_obulk);
     255           0 :         }
     256           0 :         if (sc->sc_ph_intr != NULL) {
     257           0 :                 usbd_abort_pipe(sc->sc_ph_intr);
     258           0 :                 usbd_close_pipe(sc->sc_ph_intr);
     259           0 :         }
     260             : 
     261           0 :         if (sc->sc_xfer_in != NULL)
     262           0 :                 usbd_free_xfer(sc->sc_xfer_in);
     263           0 :         if (sc->sc_xfer_out != NULL)
     264           0 :                 usbd_free_xfer(sc->sc_xfer_out);
     265             : 
     266           0 :         if (sc->sc_ow_dev != NULL)
     267           0 :                 rv = config_detach(sc->sc_ow_dev, flags);
     268             : 
     269           0 :         splx(s);
     270             : 
     271           0 :         return (rv);
     272             : }
     273             : 
     274             : int
     275           0 : uow_activate(struct device *self, int act)
     276             : {
     277           0 :         struct uow_softc *sc = (struct uow_softc *)self;
     278             :         int rv = 0;
     279             : 
     280           0 :         switch (act) {
     281             :         case DVACT_DEACTIVATE:
     282           0 :                 if (sc->sc_ow_dev != NULL)
     283           0 :                         rv = config_deactivate(sc->sc_ow_dev);
     284           0 :                 usbd_deactivate(sc->sc_udev);
     285           0 :                 break;
     286             :         }
     287             : 
     288           0 :         return (rv);
     289             : }
     290             : 
     291             : int
     292           0 : uow_ow_reset(void *arg)
     293             : {
     294           0 :         struct uow_softc *sc = arg;
     295             : 
     296           0 :         if (uow_commcmd(sc, DS2490_COMM_1WIRE_RESET | DS2490_BIT_IM, 0) != 0)
     297           0 :                 return (1);
     298             : 
     299             :         /* XXX: check presence pulse */
     300           0 :         return (0);
     301           0 : }
     302             : 
     303             : int
     304           0 : uow_ow_bit(void *arg, int value)
     305             : {
     306           0 :         struct uow_softc *sc = arg;
     307           0 :         u_int8_t data;
     308             : 
     309           0 :         if (uow_commcmd(sc, DS2490_COMM_BIT_IO | DS2490_BIT_IM |
     310           0 :             (value ? DS2490_BIT_D : 0), 0) != 0)
     311           0 :                 return (1);
     312           0 :         if (uow_read(sc, &data, 1) != 1)
     313           0 :                 return (1);
     314             : 
     315           0 :         return (data);
     316           0 : }
     317             : 
     318             : int
     319           0 : uow_ow_read_byte(void *arg)
     320             : {
     321           0 :         struct uow_softc *sc = arg;
     322           0 :         u_int8_t data;
     323             : 
     324           0 :         if (uow_commcmd(sc, DS2490_COMM_BYTE_IO | DS2490_BIT_IM, 0xff) != 0)
     325           0 :                 return (-1);
     326           0 :         if (uow_read(sc, &data, 1) != 1)
     327           0 :                 return (-1);
     328             : 
     329           0 :         return (data);
     330           0 : }
     331             : 
     332             : void
     333           0 : uow_ow_write_byte(void *arg, int value)
     334             : {
     335           0 :         struct uow_softc *sc = arg;
     336           0 :         u_int8_t data;
     337             : 
     338           0 :         if (uow_commcmd(sc, DS2490_COMM_BYTE_IO | DS2490_BIT_IM, value) != 0)
     339           0 :                 return;
     340           0 :         uow_read(sc, &data, sizeof(data));
     341           0 : }
     342             : 
     343             : void
     344           0 : uow_ow_read_block(void *arg, void *buf, int len)
     345             : {
     346           0 :         struct uow_softc *sc = arg;
     347             : 
     348           0 :         if (uow_write(sc, sc->sc_fifo, len) != 0)
     349           0 :                 return;
     350           0 :         if (uow_commcmd(sc, DS2490_COMM_BLOCK_IO | DS2490_BIT_IM, len) != 0)
     351           0 :                 return;
     352           0 :         uow_read(sc, buf, len);
     353           0 : }
     354             : 
     355             : void
     356           0 : uow_ow_write_block(void *arg, const void *buf, int len)
     357             : {
     358           0 :         struct uow_softc *sc = arg;
     359             : 
     360           0 :         if (uow_write(sc, buf, len) != 0)
     361           0 :                 return;
     362           0 :         if (uow_commcmd(sc, DS2490_COMM_BLOCK_IO | DS2490_BIT_IM, len) != 0)
     363           0 :                 return;
     364           0 : }
     365             : 
     366             : void
     367           0 : uow_ow_matchrom(void *arg, u_int64_t rom)
     368             : {
     369           0 :         struct uow_softc *sc = arg;
     370           0 :         u_int8_t data[8];
     371             :         int i;
     372             : 
     373           0 :         for (i = 0; i < 8; i++)
     374           0 :                 data[i] = (rom >> (i * 8)) & 0xff;
     375             : 
     376           0 :         if (uow_write(sc, data, 8) != 0)
     377           0 :                 return;
     378           0 :         if (uow_commcmd(sc, DS2490_COMM_MATCH_ACCESS | DS2490_BIT_IM,
     379           0 :             ONEWIRE_CMD_MATCH_ROM) != 0)
     380           0 :                 return;
     381           0 : }
     382             : 
     383             : int
     384           0 : uow_ow_search(void *arg, u_int64_t *buf, int size, u_int64_t startrom)
     385             : {
     386           0 :         struct uow_softc *sc = arg;
     387           0 :         u_int8_t data[8];
     388             :         int i, rv;
     389             : 
     390           0 :         for (i = 0; i < 8; i++)
     391           0 :                 data[i] = (startrom >> (i * 8)) & 0xff;
     392             : 
     393           0 :         if (uow_write(sc, data, 8) != 0)
     394           0 :                 return (-1);
     395           0 :         if (uow_commcmd(sc, DS2490_COMM_SEARCH_ACCESS | DS2490_BIT_IM |
     396             :             DS2490_BIT_SM | DS2490_BIT_RST | DS2490_BIT_F, size << 8 |
     397           0 :             ONEWIRE_CMD_SEARCH_ROM) != 0)
     398           0 :                 return (-1);
     399             : 
     400           0 :         if ((rv = uow_read(sc, buf, size * 8)) == -1)
     401           0 :                 return (-1);
     402             : 
     403           0 :         return (rv / 8);
     404           0 : }
     405             : 
     406             : int
     407           0 : uow_cmd(struct uow_softc *sc, int type, int cmd, int param)
     408             : {
     409           0 :         usb_device_request_t req;
     410             :         usbd_status error;
     411             : 
     412           0 :         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
     413           0 :         req.bRequest = type;
     414           0 :         USETW(req.wValue, cmd);
     415           0 :         USETW(req.wIndex, param);
     416           0 :         USETW(req.wLength, 0);
     417           0 :         if ((error = usbd_do_request(sc->sc_udev, &req, NULL)) != 0) {
     418           0 :                 printf("%s: cmd failed, type 0x%02x, cmd 0x%04x, "
     419           0 :                     "param 0x%04x: %s\n", sc->sc_dev.dv_xname, type, cmd,
     420           0 :                     param, usbd_errstr(error));
     421           0 :                 if (cmd != DS2490_CTL_RESET_DEVICE)
     422           0 :                         uow_reset(sc);
     423           0 :                 return (1);
     424             :         }
     425             : 
     426             : again:
     427           0 :         if (tsleep(sc->sc_regs, PRIBIO, "uowcmd",
     428           0 :             (UOW_TIMEOUT * hz) / 1000) != 0) {
     429           0 :                 printf("%s: cmd timeout, type 0x%02x, cmd 0x%04x, "
     430           0 :                     "param 0x%04x\n", sc->sc_dev.dv_xname, type, cmd,
     431             :                     param);
     432           0 :                 return (1);
     433             :         }
     434           0 :         if ((sc->sc_regs[DS2490_ST_STFL] & DS2490_ST_STFL_IDLE) == 0)
     435           0 :                 goto again;
     436             : 
     437           0 :         return (0);
     438           0 : }
     439             : 
     440             : void
     441           0 : uow_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
     442             : {
     443           0 :         struct uow_softc *sc = priv;
     444             : 
     445           0 :         if (status != USBD_NORMAL_COMPLETION) {
     446           0 :                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
     447           0 :                         return;
     448           0 :                 if (status == USBD_STALLED)
     449           0 :                         usbd_clear_endpoint_stall_async(sc->sc_ph_intr);
     450           0 :                 return;
     451             :         }
     452             : 
     453           0 :         wakeup(sc->sc_regs);
     454           0 : }
     455             : 
     456             : int
     457           0 : uow_read(struct uow_softc *sc, void *buf, int len)
     458             : {
     459           0 :         usbd_status error;
     460           0 :         int count;
     461             : 
     462             :         /* XXX: implement FIFO status monitoring */
     463           0 :         if (len > DS2490_DATAFIFOSIZE) {
     464           0 :                 printf("%s: read %d bytes, xfer too big\n",
     465           0 :                     sc->sc_dev.dv_xname, len);
     466           0 :                 return (-1);
     467             :         }
     468             : 
     469           0 :         usbd_setup_xfer(sc->sc_xfer_in, sc->sc_ph_ibulk, sc, buf, len,
     470             :             USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS, UOW_TIMEOUT, NULL);
     471           0 :         error = usbd_transfer(sc->sc_xfer_in);
     472           0 :         if (error != 0) {
     473           0 :                 printf("%s: read failed, len %d: %s\n",
     474           0 :                     sc->sc_dev.dv_xname, len, usbd_errstr(error));
     475           0 :                 uow_reset(sc);
     476           0 :                 return (-1);
     477             :         }
     478             : 
     479           0 :         usbd_get_xfer_status(sc->sc_xfer_in, NULL, NULL, &count, &error);
     480           0 :         return (count);
     481           0 : }
     482             : 
     483             : int
     484           0 : uow_write(struct uow_softc *sc, const void *buf, int len)
     485             : {
     486             :         usbd_status error;
     487             : 
     488             :         /* XXX: implement FIFO status monitoring */
     489           0 :         if (len > DS2490_DATAFIFOSIZE) {
     490           0 :                 printf("%s: write %d bytes, xfer too big\n",
     491           0 :                     sc->sc_dev.dv_xname, len);
     492           0 :                 return (1);
     493             :         }
     494             : 
     495           0 :         usbd_setup_xfer(sc->sc_xfer_out, sc->sc_ph_obulk, sc, (void *)buf,
     496             :             len, USBD_SYNCHRONOUS, UOW_TIMEOUT, NULL);
     497           0 :         error = usbd_transfer(sc->sc_xfer_out);
     498           0 :         if (error != 0) {
     499           0 :                 printf("%s: write failed, len %d: %s\n",
     500           0 :                     sc->sc_dev.dv_xname, len, usbd_errstr(error));
     501           0 :                 uow_reset(sc);
     502           0 :                 return (1);
     503             :         }
     504             : 
     505           0 :         return (0);
     506           0 : }
     507             : 
     508             : int
     509           0 : uow_reset(struct uow_softc *sc)
     510             : {
     511           0 :         return (uow_ctlcmd(sc, DS2490_CTL_RESET_DEVICE, 0));
     512             : }

Generated by: LCOV version 1.13