root/dev/usb/ucycom.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ucycom_match
  2. ucycom_attach
  3. ucycom_get_status
  4. ucycom_open
  5. ucycom_close
  6. ucycom_read
  7. ucycom_write
  8. ucycom_param
  9. ucycom_intr
  10. ucycom_set
  11. ucycom_get_cfg
  12. ucycom_detach
  13. ucycom_activate

    1 /*      $OpenBSD: ucycom.c,v 1.11 2007/06/14 10:11:15 mbalmer Exp $     */
    2 /*      $NetBSD: ucycom.c,v 1.3 2005/08/05 07:27:47 skrll Exp $ */
    3 
    4 /*
    5  * Copyright (c) 2005 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Nick Hudson
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 /*
   40  * This code is based on the ucom driver.
   41  */
   42 
   43 /*
   44  * Device driver for Cypress CY7C637xx and CY7C640/1xx series USB to
   45  * RS232 bridges.
   46  */
   47 
   48 #include <sys/param.h>
   49 #include <sys/systm.h>
   50 #include <sys/conf.h>
   51 #include <sys/kernel.h>
   52 #include <sys/malloc.h>
   53 #include <sys/device.h>
   54 #include <sys/sysctl.h>
   55 #include <sys/tty.h>
   56 #include <sys/file.h>
   57 #include <sys/vnode.h>
   58 
   59 #include <dev/usb/usb.h>
   60 #include <dev/usb/usbhid.h>
   61 
   62 #include <dev/usb/usbdi.h>
   63 #include <dev/usb/usbdi_util.h>
   64 #include <dev/usb/usbdevs.h>
   65 #include <dev/usb/uhidev.h>
   66 #include <dev/usb/hid.h>
   67 
   68 #include <dev/usb/ucomvar.h>
   69 
   70 #ifdef UCYCOM_DEBUG
   71 #define DPRINTF(x)      if (ucycomdebug) printf x
   72 #define DPRINTFN(n, x)  if (ucycomdebug > (n)) printf x
   73 int     ucycomdebug = 200;
   74 #else
   75 #define DPRINTF(x)
   76 #define DPRINTFN(n,x)
   77 #endif
   78 
   79 /* Configuration Byte */
   80 #define UCYCOM_RESET            0x80
   81 #define UCYCOM_PARITY_TYPE_MASK 0x20
   82 #define  UCYCOM_PARITY_ODD       0x20
   83 #define  UCYCOM_PARITY_EVEN      0x00
   84 #define UCYCOM_PARITY_MASK      0x10
   85 #define  UCYCOM_PARITY_ON        0x10
   86 #define  UCYCOM_PARITY_OFF       0x00
   87 #define UCYCOM_STOP_MASK        0x08
   88 #define  UCYCOM_STOP_BITS_2      0x08
   89 #define  UCYCOM_STOP_BITS_1      0x00
   90 #define UCYCOM_DATA_MASK        0x03
   91 #define  UCYCOM_DATA_BITS_8      0x03
   92 #define  UCYCOM_DATA_BITS_7      0x02
   93 #define  UCYCOM_DATA_BITS_6      0x01
   94 #define  UCYCOM_DATA_BITS_5      0x00
   95 
   96 /* Modem (Input) status byte */
   97 #define UCYCOM_RI       0x80
   98 #define UCYCOM_DCD      0x40
   99 #define UCYCOM_DSR      0x20
  100 #define UCYCOM_CTS      0x10
  101 #define UCYCOM_ERROR    0x08
  102 #define UCYCOM_LMASK    0x07
  103 
  104 /* Modem (Output) control byte */
  105 #define UCYCOM_DTR      0x20
  106 #define UCYCOM_RTS      0x10
  107 #define UCYCOM_ORESET   0x08
  108 
  109 struct ucycom_softc {
  110         struct uhidev            sc_hdev;
  111         usbd_device_handle       sc_udev;
  112 
  113         /* uhidev parameters */
  114         size_t                   sc_flen;       /* feature report length */
  115         size_t                   sc_ilen;       /* input report length */
  116         size_t                   sc_olen;       /* output report length */
  117 
  118         uint8_t                 *sc_obuf;
  119 
  120         uint8_t                 *sc_ibuf;
  121         uint32_t                 sc_icnt;
  122 
  123         /* settings */
  124         uint32_t                 sc_baud;
  125         uint8_t                  sc_cfg;        /* Data format */
  126         uint8_t                  sc_mcr;        /* Modem control */
  127         uint8_t                  sc_msr;        /* Modem status */
  128         uint8_t                  sc_newmsr;     /* from HID intr */
  129         int                      sc_swflags;
  130 
  131         struct device           *sc_subdev;
  132 
  133         /* flags */
  134         u_char                   sc_dying;
  135 };
  136 
  137 /* Callback routines */
  138 void    ucycom_set(void *, int, int, int);
  139 int     ucycom_param(void *, int, struct termios *);
  140 void    ucycom_get_status(void *, int, u_char *, u_char *);
  141 int     ucycom_open(void *, int);
  142 void    ucycom_close(void *, int);
  143 void    ucycom_write(void *, int, u_char *, u_char *, u_int32_t *);
  144 void    ucycom_read(void *, int, u_char **, u_int32_t *);
  145 
  146 struct ucom_methods ucycom_methods = {
  147         NULL, /* ucycom_get_status, */
  148         ucycom_set,
  149         ucycom_param,
  150         NULL,
  151         ucycom_open,
  152         ucycom_close,
  153         ucycom_read,
  154         ucycom_write,
  155 };
  156 
  157 void ucycom_intr(struct uhidev *, void *, u_int);
  158 
  159 void ucycom_get_cfg(struct ucycom_softc *);
  160 
  161 const struct usb_devno ucycom_devs[] = {
  162         { USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_USBRS232 },
  163         { USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EMUSB },
  164         { USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EMLT20 },
  165 };
  166 #define ucycom_lookup(v, p) usb_lookup(ucycom_devs, v, p)
  167 
  168 int ucycom_match(struct device *, void *, void *); 
  169 void ucycom_attach(struct device *, struct device *, void *); 
  170 int ucycom_detach(struct device *, int); 
  171 int ucycom_activate(struct device *, enum devact); 
  172 
  173 struct cfdriver ucycom_cd = { 
  174         NULL, "ucycom", DV_DULL 
  175 }; 
  176 
  177 const struct cfattach ucycom_ca = { 
  178         sizeof(struct ucycom_softc), 
  179         ucycom_match, 
  180         ucycom_attach, 
  181         ucycom_detach, 
  182         ucycom_activate, 
  183 };
  184 
  185 int
  186 ucycom_match(struct device *parent, void *match, void *aux)
  187 {
  188         struct uhidev_attach_arg *uha = aux;
  189 
  190         DPRINTF(("ucycom match\n"));
  191         return (ucycom_lookup(uha->uaa->vendor, uha->uaa->product) != NULL ?
  192             UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
  193 }
  194 
  195 void
  196 ucycom_attach(struct device *parent, struct device *self, void *aux)
  197 {
  198         struct ucycom_softc *sc = (struct ucycom_softc *)self;
  199         struct usb_attach_arg *uaa = aux;
  200         struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
  201         usbd_device_handle dev = uha->parent->sc_udev;
  202         struct ucom_attach_args uca;
  203         int size, repid, err;
  204         void *desc;
  205 
  206         sc->sc_hdev.sc_intr = ucycom_intr;
  207         sc->sc_hdev.sc_parent = uha->parent;
  208         sc->sc_hdev.sc_report_id = uha->reportid;
  209 
  210         uhidev_get_report_desc(uha->parent, &desc, &size);
  211         repid = uha->reportid;
  212         sc->sc_ilen = hid_report_size(desc, size, hid_input, repid);
  213         sc->sc_olen = hid_report_size(desc, size, hid_output, repid);
  214         sc->sc_flen = hid_report_size(desc, size, hid_feature, repid);
  215 
  216         DPRINTF(("ucycom_open: olen %d ilen %d flen %d\n", sc->sc_ilen,
  217             sc->sc_olen, sc->sc_flen));
  218 
  219         printf("\n");
  220 
  221         sc->sc_udev = dev;
  222 
  223         sc->sc_msr = sc->sc_mcr = 0;
  224 
  225         err = uhidev_open(&sc->sc_hdev);
  226         if (err) {
  227                 DPRINTF(("ucycom_open: uhidev_open %d\n", err));
  228                 return;
  229         }
  230 
  231         DPRINTF(("ucycom attach: sc %p opipe %p ipipe %p report_id %d\n",
  232             sc, sc->sc_hdev.sc_parent->sc_opipe, sc->sc_hdev.sc_parent->sc_ipipe,
  233             uha->reportid));
  234 
  235         /* bulkin, bulkout set above */
  236         bzero(&uca, sizeof uca);
  237         uca.bulkin = uca.bulkout = -1;
  238         uca.uhidev = sc->sc_hdev.sc_parent;
  239         uca.ibufsize = sc->sc_ilen - 1;
  240         uca.obufsize = sc->sc_olen - 1;
  241         uca.ibufsizepad = 1;
  242         uca.opkthdrlen = 0;
  243         uca.device = uaa->device;
  244         uca.iface = uaa->iface;
  245         uca.methods = &ucycom_methods;
  246         uca.arg = sc;
  247         uca.info = NULL;
  248 
  249         usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
  250                            &sc->sc_hdev.sc_dev);
  251 
  252         sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);
  253         DPRINTF(("ucycom_attach: complete %p\n", sc->sc_subdev));
  254 }
  255 
  256 void
  257 ucycom_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
  258 {
  259         struct ucycom_softc *sc = addr;
  260 
  261         DPRINTF(("ucycom_get_status:\n"));
  262 
  263 #if 0
  264         if (lsr != NULL)
  265                 *lsr = sc->sc_lsr;
  266 #endif
  267         if (msr != NULL)
  268                 *msr = sc->sc_msr;
  269 }
  270 
  271 int
  272 ucycom_open(void *addr, int portno)
  273 {
  274         struct ucycom_softc *sc = addr;
  275         struct termios t;
  276         int err;
  277 
  278         DPRINTF(("ucycom_open: complete\n"));
  279 
  280         if (sc->sc_dying)
  281                 return (EIO);
  282 
  283         /* Allocate an output report buffer */
  284         sc->sc_obuf = malloc(sc->sc_olen, M_USBDEV, M_WAITOK);
  285 
  286         /* Allocate an input report buffer */
  287         sc->sc_ibuf = malloc(sc->sc_ilen, M_USBDEV, M_WAITOK);
  288 
  289         DPRINTF(("ucycom_open: sc->sc_ibuf=%p sc->sc_obuf=%p \n",
  290             sc->sc_ibuf, sc->sc_obuf));
  291 
  292         t.c_ospeed = 9600;
  293         t.c_cflag = CSTOPB | CS8;
  294         (void)ucycom_param(sc, portno, &t);
  295 
  296         sc->sc_mcr = UCYCOM_DTR | UCYCOM_RTS;
  297         memset(sc->sc_obuf, 0, sc->sc_olen);
  298         sc->sc_obuf[0] = sc->sc_mcr;
  299         err = uhidev_write(sc->sc_hdev.sc_parent, sc->sc_obuf, sc->sc_olen);
  300         if (err) {
  301                 DPRINTF(("ucycom_open: set RTS err=%d\n", err));
  302                 return (EIO);
  303         }
  304 
  305         return (0);
  306 }
  307 
  308 void
  309 ucycom_close(void *addr, int portno)
  310 {
  311         struct ucycom_softc *sc = addr;
  312         int s;
  313 
  314         if (sc->sc_dying)
  315                 return;
  316 
  317         s = splusb();
  318         if (sc->sc_obuf != NULL) {
  319                 free(sc->sc_obuf, M_USBDEV);
  320                 sc->sc_obuf = NULL;
  321         }
  322         if (sc->sc_ibuf != NULL) {
  323                 free(sc->sc_ibuf, M_USBDEV);
  324                 sc->sc_ibuf = NULL;
  325         }
  326         splx(s);
  327 }
  328 
  329 void
  330 ucycom_read(void *addr, int portno, u_char **ptr, u_int32_t *count)
  331 {
  332         struct ucycom_softc *sc = addr;
  333 
  334         if (sc->sc_newmsr ^ sc->sc_msr) {
  335                 DPRINTF(("ucycom_read: msr %d new %d\n",
  336                     sc->sc_msr, sc->sc_newmsr));
  337                 sc->sc_msr = sc->sc_newmsr;
  338                 ucom_status_change((struct ucom_softc *)sc->sc_subdev);
  339         }
  340 
  341         DPRINTF(("ucycom_read: buf %p chars %d\n", sc->sc_ibuf, sc->sc_icnt));
  342         *ptr = sc->sc_ibuf;
  343         *count = sc->sc_icnt;
  344 }
  345 
  346 void
  347 ucycom_write(void *addr, int portno, u_char *to, u_char *data, u_int32_t *cnt)
  348 {
  349         struct ucycom_softc *sc = addr;
  350         u_int32_t len;
  351 #ifdef UCYCOM_DEBUG
  352         u_int32_t want = *cnt;
  353 #endif
  354 
  355         /*
  356          * The 8 byte output report uses byte 0 for control and byte
  357          * count.
  358          *
  359          * The 32 byte output report uses byte 0 for control. Byte 1
  360          * is used for byte count.
  361          */
  362         len = sc->sc_olen;
  363         memset(to, 0, len);
  364         switch (sc->sc_olen) {
  365         case 8:
  366                 to[0] = *cnt | sc->sc_mcr;
  367                 memcpy(&to[1], data, *cnt);
  368                 DPRINTF(("ucycomstart(8): to[0] = %d | %d = %d\n",
  369                     *cnt, sc->sc_mcr, to[0]));
  370                 break;
  371 
  372         case 32:
  373                 to[0] = sc->sc_mcr;
  374                 to[1] = *cnt;
  375                 memcpy(&to[2], data, *cnt);
  376                 DPRINTF(("ucycomstart(32): to[0] = %d\nto[1] = %d\n",
  377                     to[0], to[1]));
  378                 break;
  379         }
  380 
  381 #ifdef UCYCOM_DEBUG
  382         if (ucycomdebug > 5) {
  383                 int i;
  384 
  385                 if (len != 0) {
  386                         DPRINTF(("ucycomstart: to[0..%d) =", len-1));
  387                         for (i = 0; i < len; i++)
  388                                 DPRINTF((" %02x", to[i]));
  389                         DPRINTF(("\n"));
  390                 }
  391         }
  392 #endif
  393         *cnt = len;
  394 
  395 #if 0
  396         ucycom_get_cfg(sc);
  397 #endif
  398         DPRINTFN(4,("ucycomstart: req %d chars did %d chars\n", want, len));
  399 }
  400 
  401 int
  402 ucycom_param(void *addr, int portno, struct termios *t)
  403 {
  404         struct ucycom_softc *sc = addr;
  405         uint8_t report[5];
  406         uint32_t baud = 0;
  407         uint8_t cfg;
  408         int err;
  409 
  410         if (sc->sc_dying)
  411                 return (EIO);
  412 
  413         switch (t->c_ospeed) {
  414         case 600:
  415         case 1200:
  416         case 2400:
  417         case 4800:
  418         case 9600:
  419         case 19200:
  420         case 38400:
  421         case 57600:
  422 #if 0
  423         /*
  424          * Stock chips only support standard baud rates in the 600 - 57600
  425          * range, but higher rates can be achieved using custom firmware.
  426          */
  427         case 115200:
  428         case 153600:
  429         case 192000:
  430 #endif
  431                 baud = t->c_ospeed;
  432                 break;
  433         default:
  434                 return (EINVAL);
  435         }
  436 
  437         if (t->c_cflag & CIGNORE) {
  438                 cfg = sc->sc_cfg;
  439         } else {
  440                 cfg = 0;
  441                 switch (t->c_cflag & CSIZE) {
  442                 case CS8:
  443                         cfg |= UCYCOM_DATA_BITS_8;
  444                         break;
  445                 case CS7:
  446                         cfg |= UCYCOM_DATA_BITS_7;
  447                         break;
  448                 case CS6:
  449                         cfg |= UCYCOM_DATA_BITS_6;
  450                         break;
  451                 case CS5:
  452                         cfg |= UCYCOM_DATA_BITS_5;
  453                         break;
  454                 default:
  455                         return (EINVAL);
  456                 }
  457                 cfg |= ISSET(t->c_cflag, CSTOPB) ?
  458                     UCYCOM_STOP_BITS_2 : UCYCOM_STOP_BITS_1;
  459                 cfg |= ISSET(t->c_cflag, PARENB) ?
  460                     UCYCOM_PARITY_ON : UCYCOM_PARITY_OFF;
  461                 cfg |= ISSET(t->c_cflag, PARODD) ?
  462                     UCYCOM_PARITY_ODD : UCYCOM_PARITY_EVEN;
  463         }
  464 
  465         DPRINTF(("ucycom_param: setting %d baud, %d-%c-%d (%d)\n", baud,
  466             5 + (cfg & UCYCOM_DATA_MASK),
  467             (cfg & UCYCOM_PARITY_MASK) ?
  468                 ((cfg & UCYCOM_PARITY_TYPE_MASK) ? 'O' : 'E') : 'N',
  469             (cfg & UCYCOM_STOP_MASK) ? 2 : 1, cfg));
  470 
  471         report[0] = baud & 0xff;
  472         report[1] = (baud >> 8) & 0xff;
  473         report[2] = (baud >> 16) & 0xff;
  474         report[3] = (baud >> 24) & 0xff;
  475         report[4] = cfg;
  476         err = uhidev_set_report(&sc->sc_hdev, UHID_FEATURE_REPORT,
  477             report, sc->sc_flen);
  478         if (err != 0) {
  479                 DPRINTF(("ucycom_param: uhidev_set_report %d %s\n",
  480                     err, usbd_errstr(err)));
  481                 return EIO;
  482         }
  483         sc->sc_baud = baud;
  484         return (err);
  485 }
  486 
  487 void
  488 ucycom_intr(struct uhidev *addr, void *ibuf, u_int len)
  489 {
  490         extern void ucomreadcb(usbd_xfer_handle, usbd_private_handle, usbd_status);
  491         struct ucycom_softc *sc = (struct ucycom_softc *)addr;
  492         uint8_t *cp = ibuf;
  493         int n, st, s;
  494 
  495         /* not accepting data anymore.. */
  496         if (sc->sc_ibuf == NULL)
  497                 return;
  498 
  499         /* We understand 8 byte and 32 byte input records */
  500         switch (len) {
  501         case 8:
  502                 n = cp[0] & UCYCOM_LMASK;
  503                 st = cp[0] & ~UCYCOM_LMASK;
  504                 cp++;
  505                 break;
  506 
  507         case 32:
  508                 st = cp[0];
  509                 n = cp[1];
  510                 cp += 2;
  511                 break;
  512 
  513         default:
  514                 DPRINTFN(3,("ucycom_intr: Unknown input report length\n"));
  515                 return;
  516         }
  517 
  518 #ifdef UCYCOM_DEBUG
  519         if (ucycomdebug > 5) {
  520                 u_int32_t i;
  521 
  522                 if (n != 0) {
  523                         DPRINTF(("ucycom_intr: ibuf[0..%d) =", n));
  524                         for (i = 0; i < n; i++)
  525                                 DPRINTF((" %02x", cp[i]));
  526                         DPRINTF(("\n"));
  527                 }
  528         }
  529 #endif
  530 
  531         if (n > 0 || st != sc->sc_msr) {
  532                 s = spltty();
  533                 sc->sc_newmsr = st;
  534                 bcopy(cp, sc->sc_ibuf, n);
  535                 sc->sc_icnt = n;
  536                 ucomreadcb(addr->sc_parent->sc_ixfer, sc->sc_subdev,
  537                     USBD_NORMAL_COMPLETION);
  538                 splx(s);
  539         }
  540 }
  541 
  542 void
  543 ucycom_set(void *addr, int portno, int reg, int onoff)
  544 {
  545         struct ucycom_softc *sc = addr;
  546         int err;
  547 
  548         switch (reg) {
  549         case UCOM_SET_DTR:
  550                 if (onoff)
  551                         SET(sc->sc_mcr, UCYCOM_DTR);
  552                 else
  553                         CLR(sc->sc_mcr, UCYCOM_DTR);
  554                 break;
  555         case UCOM_SET_RTS:
  556                 if (onoff)
  557                         SET(sc->sc_mcr, UCYCOM_RTS);
  558                 else
  559                         CLR(sc->sc_mcr, UCYCOM_RTS);
  560                 break;
  561         case UCOM_SET_BREAK:
  562                 break;
  563         }
  564 
  565         memset(sc->sc_obuf, 0, sc->sc_olen);
  566         sc->sc_obuf[0] = sc->sc_mcr;
  567 
  568         err = uhidev_write(sc->sc_hdev.sc_parent, sc->sc_obuf, sc->sc_olen);
  569         if (err)
  570                 DPRINTF(("ucycom_set_status: err=%d\n", err));
  571 }
  572 
  573 void
  574 ucycom_get_cfg(struct ucycom_softc *sc)
  575 {
  576         int err, cfg, baud;
  577         uint8_t report[5];
  578 
  579         err = uhidev_get_report(&sc->sc_hdev, UHID_FEATURE_REPORT,
  580             report, sc->sc_flen);
  581         cfg = report[4];
  582         baud = (report[3] << 24) + (report[2] << 16) + (report[1] << 8) + report[0];
  583         DPRINTF(("ucycom_configure: device reports %d baud, %d-%c-%d (%d)\n", baud,
  584             5 + (cfg & UCYCOM_DATA_MASK),
  585             (cfg & UCYCOM_PARITY_MASK) ?
  586                 ((cfg & UCYCOM_PARITY_TYPE_MASK) ? 'O' : 'E') : 'N',
  587             (cfg & UCYCOM_STOP_MASK) ? 2 : 1, cfg));
  588 }
  589 
  590 int
  591 ucycom_detach(struct device *self, int flags)
  592 {
  593         struct ucycom_softc *sc = (struct ucycom_softc *)self;
  594 
  595         DPRINTF(("ucycom_detach: sc=%p flags=%d\n", sc, flags));
  596         sc->sc_dying = 1;
  597         if (sc->sc_subdev != NULL) {
  598                 config_detach(sc->sc_subdev, flags);
  599                 sc->sc_subdev = NULL;
  600         }
  601         return (0);
  602 }
  603 
  604 int
  605 ucycom_activate(struct device *self, enum devact act)
  606 {
  607         struct ucycom_softc *sc = (struct ucycom_softc *)self;
  608         int rv = 0;
  609 
  610         DPRINTFN(5,("ucycom_activate: %d\n", act));
  611 
  612         switch (act) {
  613         case DVACT_ACTIVATE:
  614                 break;
  615 
  616         case DVACT_DEACTIVATE:
  617                 if (sc->sc_subdev != NULL)
  618                         rv = config_deactivate(sc->sc_subdev);
  619                 sc->sc_dying = 1;
  620                 break;
  621         }
  622         return (rv);
  623 }

/* [<][>][^][v][top][bottom][index][help] */