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

          Line data    Source code
       1             : /*      $OpenBSD: uslcom.c,v 1.40 2017/05/20 10:13:42 kettenis Exp $    */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2006 Jonathan Gray <jsg@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             : #include <sys/param.h>
      20             : #include <sys/systm.h>
      21             : #include <sys/kernel.h>
      22             : #include <sys/tty.h>
      23             : #include <sys/device.h>
      24             : 
      25             : #include <dev/usb/usb.h>
      26             : #include <dev/usb/usbdi.h>
      27             : #include <dev/usb/usbdi_util.h>
      28             : #include <dev/usb/usbdevs.h>
      29             : 
      30             : #include <dev/usb/ucomvar.h>
      31             : 
      32             : #ifdef USLCOM_DEBUG
      33             : #define DPRINTFN(n, x)  do { if (uslcomdebug > (n)) printf x; } while (0)
      34             : int     uslcomdebug = 0;
      35             : #else
      36             : #define DPRINTFN(n, x)
      37             : #endif
      38             : #define DPRINTF(x) DPRINTFN(0, x)
      39             : 
      40             : #define USLCOMBUFSZ             256
      41             : #define USLCOM_IFACE_NO         0
      42             : 
      43             : #define USLCOM_SET_DATA_BITS(x) (x << 8)
      44             : 
      45             : #define USLCOM_WRITE            0x41
      46             : #define USLCOM_READ             0xc1
      47             : 
      48             : #define USLCOM_UART             0x00
      49             : #define USLCOM_SET_BAUD_DIV     0x01
      50             : #define USLCOM_DATA             0x03
      51             : #define USLCOM_BREAK            0x05
      52             : #define USLCOM_CTRL             0x07
      53             : #define USLCOM_SET_FLOW         0x13
      54             : #define USLCOM_SET_BAUD_RATE    0x1e
      55             : 
      56             : #define USLCOM_UART_DISABLE     0x00
      57             : #define USLCOM_UART_ENABLE      0x01
      58             : 
      59             : #define USLCOM_CTRL_DTR_ON      0x0001  
      60             : #define USLCOM_CTRL_DTR_SET     0x0100
      61             : #define USLCOM_CTRL_RTS_ON      0x0002
      62             : #define USLCOM_CTRL_RTS_SET     0x0200
      63             : #define USLCOM_CTRL_CTS         0x0010
      64             : #define USLCOM_CTRL_DSR         0x0020
      65             : #define USLCOM_CTRL_DCD         0x0080
      66             : 
      67             : #define USLCOM_BAUD_REF         3686400 /* 3.6864 MHz */
      68             : 
      69             : #define USLCOM_STOP_BITS_1      0x00
      70             : #define USLCOM_STOP_BITS_2      0x02
      71             : 
      72             : #define USLCOM_PARITY_NONE      0x00
      73             : #define USLCOM_PARITY_ODD       0x10
      74             : #define USLCOM_PARITY_EVEN      0x20
      75             : 
      76             : #define USLCOM_BREAK_OFF        0x00
      77             : #define USLCOM_BREAK_ON         0x01
      78             : 
      79             : /* USLCOM_SET_FLOW values - 1st word */
      80             : #define USLCOM_FLOW_DTR_ON      0x00000001 /* DTR static active */
      81             : #define USLCOM_FLOW_CTS_HS      0x00000008 /* CTS handshake */
      82             : /* USLCOM_SET_FLOW values - 2nd word */
      83             : #define USLCOM_FLOW_RTS_ON      0x00000040 /* RTS static active */
      84             : #define USLCOM_FLOW_RTS_HS      0x00000080 /* RTS handshake */
      85             : 
      86             : struct uslcom_softc {
      87             :         struct device            sc_dev;
      88             :         struct usbd_device      *sc_udev;
      89             :         struct usbd_interface   *sc_iface;
      90             :         struct device           *sc_subdev;
      91             : 
      92             :         u_char                   sc_msr;
      93             :         u_char                   sc_lsr;
      94             : };
      95             : 
      96             : void    uslcom_get_status(void *, int portno, u_char *lsr, u_char *msr);
      97             : void    uslcom_set(void *, int, int, int);
      98             : int     uslcom_param(void *, int, struct termios *);
      99             : int     uslcom_open(void *sc, int portno);
     100             : void    uslcom_close(void *, int);
     101             : void    uslcom_break(void *sc, int portno, int onoff);
     102             : 
     103             : struct ucom_methods uslcom_methods = {
     104             :         uslcom_get_status,
     105             :         uslcom_set,
     106             :         uslcom_param,
     107             :         NULL,
     108             :         uslcom_open,
     109             :         uslcom_close,
     110             :         NULL,
     111             :         NULL,
     112             : };
     113             : 
     114             : static const struct usb_devno uslcom_devs[] = {
     115             :         { USB_VENDOR_ARUBA,             USB_PRODUCT_ARUBA_CP210X },
     116             :         { USB_VENDOR_BALTECH,           USB_PRODUCT_BALTECH_CARDREADER },
     117             :         { USB_VENDOR_CLIPSAL,           USB_PRODUCT_CLIPSAL_5000CT2 },
     118             :         { USB_VENDOR_CLIPSAL,           USB_PRODUCT_CLIPSAL_5500PACA },
     119             :         { USB_VENDOR_CLIPSAL,           USB_PRODUCT_CLIPSAL_5500PCU },
     120             :         { USB_VENDOR_CLIPSAL,           USB_PRODUCT_CLIPSAL_560884 },
     121             :         { USB_VENDOR_CLIPSAL,           USB_PRODUCT_CLIPSAL_5800PC },
     122             :         { USB_VENDOR_CLIPSAL,           USB_PRODUCT_CLIPSAL_C5000CT2 },
     123             :         { USB_VENDOR_CLIPSAL,           USB_PRODUCT_CLIPSAL_L51xx },
     124             :         { USB_VENDOR_CORSAIR,           USB_PRODUCT_CORSAIR_CP210X },
     125             :         { USB_VENDOR_DATAAPEX,          USB_PRODUCT_DATAAPEX_MULTICOM },
     126             :         { USB_VENDOR_DELL,              USB_PRODUCT_DELL_DW700 },
     127             :         { USB_VENDOR_DIGIANSWER,        USB_PRODUCT_DIGIANSWER_ZIGBEE802154 },
     128             :         { USB_VENDOR_DYNASTREAM,        USB_PRODUCT_DYNASTREAM_ANT2USB },
     129             :         { USB_VENDOR_DYNASTREAM,        USB_PRODUCT_DYNASTREAM_ANTDEVBOARD },
     130             :         { USB_VENDOR_DYNASTREAM,        USB_PRODUCT_DYNASTREAM_ANTDEVBOARD2 },
     131             :         { USB_VENDOR_ELV,               USB_PRODUCT_ELV_USBI2C },
     132             :         { USB_VENDOR_FESTO,             USB_PRODUCT_FESTO_CMSP },
     133             :         { USB_VENDOR_FESTO,             USB_PRODUCT_FESTO_CPX_USB },
     134             :         { USB_VENDOR_FOXCONN,           USB_PRODUCT_FOXCONN_PIRELLI_DP_L10 },
     135             :         { USB_VENDOR_FOXCONN,           USB_PRODUCT_FOXCONN_TCOM_TC_300 },
     136             :         { USB_VENDOR_GEMPLUS,           USB_PRODUCT_GEMPLUS_PROXPU },
     137             :         { USB_VENDOR_JABLOTRON,         USB_PRODUCT_JABLOTRON_PC60B },
     138             :         { USB_VENDOR_KAMSTRUP,          USB_PRODUCT_KAMSTRUP_MBUS_250D },
     139             :         { USB_VENDOR_KAMSTRUP,          USB_PRODUCT_KAMSTRUP_OPTICALEYE },
     140             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M121 },
     141             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M218A },
     142             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M219 },
     143             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M233 },
     144             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M235 },
     145             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M335 },
     146             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M336 },
     147             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M350 },
     148             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M371 },
     149             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M411 },
     150             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M425 },
     151             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M455A },
     152             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M465 },
     153             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M475A },
     154             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M625A },
     155             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M642A },
     156             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M648 },
     157             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M737 },
     158             :         { USB_VENDOR_LAKESHORE,         USB_PRODUCT_LAKESHORE_M776 },
     159             :         { USB_VENDOR_LINKINSTRUMENTS,   USB_PRODUCT_LINKINSTRUMENTS_MSO19 },
     160             :         { USB_VENDOR_LINKINSTRUMENTS,   USB_PRODUCT_LINKINSTRUMENTS_MSO28 },
     161             :         { USB_VENDOR_LINKINSTRUMENTS,   USB_PRODUCT_LINKINSTRUMENTS_MSO28_2 },
     162             :         { USB_VENDOR_MEI,               USB_PRODUCT_MEI_CASHFLOW_SC },
     163             :         { USB_VENDOR_MEI,               USB_PRODUCT_MEI_S2000 },
     164             :         { USB_VENDOR_NETGEAR,           USB_PRODUCT_NETGEAR_M7100 },
     165             :         { USB_VENDOR_OREGONSCI,         USB_PRODUCT_OREGONSCI_OWL_CM160 },
     166             :         { USB_VENDOR_OWEN,              USB_PRODUCT_OWEN_AC4 },
     167             :         { USB_VENDOR_PHILIPS,           USB_PRODUCT_PHILIPS_ACE1001 },
     168             :         { USB_VENDOR_RENESAS,           USB_PRODUCT_RENESAS_RX610 },
     169             :         { USB_VENDOR_SEL,               USB_PRODUCT_SEL_C662 },
     170             :         { USB_VENDOR_SELUXIT,           USB_PRODUCT_SELUXIT_RF },
     171             :         { USB_VENDOR_SIEMENS4,          USB_PRODUCT_SIEMENS4_RUGGEDCOM },
     172             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_AC_SERV_CAN },
     173             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_AC_SERV_CIS },
     174             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_AC_SERV_IBUS },
     175             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_AC_SERV_OBD },
     176             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_AEROCOMM },
     177             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_AMBER_AMB2560 },
     178             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_ARGUSISP },
     179             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_ARKHAM_DS101_A },
     180             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_ARKHAM_DS101_M },
     181             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_ARYGON_MIFARE },
     182             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_AVIT_USB_TTL },
     183             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_BALLUFF_RFID },
     184             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_BEI_VCP },
     185             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_BSM7DUSB },
     186             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_B_G_H3000 },
     187             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_C2_EDGE_MODEM },
     188             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_CELDEVKIT },
     189             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_CP210X_1 },
     190             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_CP210X_2 },
     191             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_CP210X_3 },
     192             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_CRUMB128 },
     193             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_CYGNAL },
     194             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_CYGNAL_DEBUG },
     195             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_CYGNAL_GPS },
     196             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_DEGREECONT },
     197             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_DEKTEK_DTAPLUS },
     198             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_DESKTOPMOBILE },
     199             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_EDG1228 },
     200             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_EM357 },
     201             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_EM357LR },
     202             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_EMS_C1007 },
     203             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_GSM2228 },
     204             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_HAMLINKUSB },
     205             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_HUBZ },
     206             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_IMS_USB_RS422 },
     207             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_INFINITY_MIC },
     208             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_INSYS_MODEM },
     209             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_IPLINK1220 },
     210             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_IRZ_SG10 },
     211             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_KCF_PRN },
     212             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_KETRA_N1 },
     213             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_KYOCERA_GPS },
     214             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_LIPOWSKY_HARP },
     215             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_LIPOWSKY_JTAG },
     216             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_LIPOWSKY_LIN },
     217             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_MC35PU },
     218             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_MJS_TOSLINK },
     219             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_MMB_ZIGBEE },
     220             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_MSD_DASHHAWK },
     221             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_MULTIPLEX_RC },
     222             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_OPTRIS_MSPRO },
     223             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_PII_ZIGBEE },
     224             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_PLUGDRIVE },
     225             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_POLOLU },
     226             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_PREON32 },
     227             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_PROCYON_AVS },
     228             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_RIGBLASTER },
     229             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_RIGTALK },
     230             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_SB_PARAMOUNT_ME },
     231             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_SB_PARAMOUNT_ME2 },
     232             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_SUUNTO },
     233             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_TAMSMASTER },
     234             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_TELEGESIS_ETRX2 },
     235             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_TRACIENT },
     236             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_TRAQMATE },
     237             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_USBCOUNT50 },
     238             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_USBPULSE100 },
     239             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_USBSCOPE50 },
     240             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_USBWAVE12 },
     241             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_VSTABI },
     242             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_WAVIT },
     243             :         { USB_VENDOR_SILABS,            USB_PRODUCT_SILABS_ZEPHYR_BIO },
     244             :         { USB_VENDOR_SILABS2,           USB_PRODUCT_SILABS2_DCU11CLONE },
     245             :         { USB_VENDOR_SILABS3,           USB_PRODUCT_SILABS3_GPRS_MODEM },
     246             :         { USB_VENDOR_SILABS4,           USB_PRODUCT_SILABS4_100EU_MODEM },
     247             :         { USB_VENDOR_SILABS5,           USB_PRODUCT_SILABS5_EM358X },
     248             :         { USB_VENDOR_SYNTECH,           USB_PRODUCT_SYNTECH_CIPHERLAB100 },
     249             :         { USB_VENDOR_USI,               USB_PRODUCT_USI_MC60 },
     250             :         { USB_VENDOR_VAISALA,           USB_PRODUCT_VAISALA_USBINSTCABLE },
     251             :         { USB_VENDOR_VOTI,              USB_PRODUCT_VOTI_SELETEK_1 },
     252             :         { USB_VENDOR_VOTI,              USB_PRODUCT_VOTI_SELETEK_2 },
     253             :         { USB_VENDOR_WAGO,              USB_PRODUCT_WAGO_SERVICECABLE },
     254             :         { USB_VENDOR_WAVESENSE,         USB_PRODUCT_WAVESENSE_JAZZ },
     255             :         { USB_VENDOR_WIENERPLEINBAUS,   USB_PRODUCT_WIENERPLEINBAUS_CML },
     256             :         { USB_VENDOR_WIENERPLEINBAUS,   USB_PRODUCT_WIENERPLEINBAUS_MPOD },
     257             :         { USB_VENDOR_WIENERPLEINBAUS,   USB_PRODUCT_WIENERPLEINBAUS_PL512 },
     258             :         { USB_VENDOR_WIENERPLEINBAUS,   USB_PRODUCT_WIENERPLEINBAUS_RCM },
     259             :         { USB_VENDOR_WMR,               USB_PRODUCT_WMR_RIGBLASTER },
     260             : };
     261             : 
     262             : int uslcom_match(struct device *, void *, void *);
     263             : void uslcom_attach(struct device *, struct device *, void *);
     264             : int uslcom_detach(struct device *, int);
     265             : 
     266             : struct cfdriver uslcom_cd = {
     267             :         NULL, "uslcom", DV_DULL
     268             : };
     269             : 
     270             : const struct cfattach uslcom_ca = {
     271             :         sizeof(struct uslcom_softc), uslcom_match, uslcom_attach, uslcom_detach
     272             : };
     273             : 
     274             : int
     275           0 : uslcom_match(struct device *parent, void *match, void *aux)
     276             : {
     277           0 :         struct usb_attach_arg *uaa = aux;
     278             : 
     279           0 :         if (uaa->iface == NULL)
     280           0 :                 return UMATCH_NONE;
     281             : 
     282           0 :         return (usb_lookup(uslcom_devs, uaa->vendor, uaa->product) != NULL) ?
     283             :             UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
     284           0 : }
     285             : 
     286             : void
     287           0 : uslcom_attach(struct device *parent, struct device *self, void *aux)
     288             : {
     289           0 :         struct uslcom_softc *sc = (struct uslcom_softc *)self;
     290           0 :         struct usb_attach_arg *uaa = aux;
     291           0 :         struct ucom_attach_args uca;
     292             :         usb_interface_descriptor_t *id;
     293             :         usb_endpoint_descriptor_t *ed;
     294             :         usbd_status error;
     295             :         int i;
     296             : 
     297           0 :         bzero(&uca, sizeof(uca));
     298           0 :         sc->sc_udev = uaa->device;
     299             : 
     300             :         /* get the first interface handle */
     301           0 :         error = usbd_device2interface_handle(sc->sc_udev, USLCOM_IFACE_NO,
     302           0 :             &sc->sc_iface);
     303           0 :         if (error != 0) {
     304           0 :                 printf("%s: could not get interface handle\n",
     305           0 :                     sc->sc_dev.dv_xname);
     306           0 :                 usbd_deactivate(sc->sc_udev);
     307           0 :                 return;
     308             :         }
     309             : 
     310           0 :         id = usbd_get_interface_descriptor(sc->sc_iface);
     311             : 
     312           0 :         uca.bulkin = uca.bulkout = -1;
     313           0 :         for (i = 0; i < id->bNumEndpoints; i++) {
     314           0 :                 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
     315           0 :                 if (ed == NULL) {
     316           0 :                         printf("%s: no endpoint descriptor found for %d\n",
     317           0 :                             sc->sc_dev.dv_xname, i);
     318           0 :                         usbd_deactivate(sc->sc_udev);
     319           0 :                         return;
     320             :                 }
     321             : 
     322           0 :                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
     323           0 :                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
     324           0 :                         uca.bulkin = ed->bEndpointAddress;
     325           0 :                 else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
     326           0 :                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
     327           0 :                         uca.bulkout = ed->bEndpointAddress;
     328             :         }
     329             : 
     330           0 :         if (uca.bulkin == -1 || uca.bulkout == -1) {
     331           0 :                 printf("%s: missing endpoint\n", sc->sc_dev.dv_xname);
     332           0 :                 usbd_deactivate(sc->sc_udev);
     333           0 :                 return;
     334             :         }
     335             : 
     336           0 :         uca.ibufsize = USLCOMBUFSZ;
     337           0 :         uca.obufsize = USLCOMBUFSZ;
     338           0 :         uca.ibufsizepad = USLCOMBUFSZ;
     339           0 :         uca.opkthdrlen = 0;
     340           0 :         uca.device = sc->sc_udev;
     341           0 :         uca.iface = sc->sc_iface;
     342           0 :         uca.methods = &uslcom_methods;
     343           0 :         uca.arg = sc;
     344           0 :         uca.info = NULL;
     345             : 
     346           0 :         sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);
     347           0 : }
     348             : 
     349             : int
     350           0 : uslcom_detach(struct device *self, int flags)
     351             : {
     352           0 :         struct uslcom_softc *sc = (struct uslcom_softc *)self;
     353             :         int rv = 0;
     354             : 
     355           0 :         if (sc->sc_subdev != NULL) {
     356           0 :                 rv = config_detach(sc->sc_subdev, flags);
     357           0 :                 sc->sc_subdev = NULL;
     358           0 :         }
     359             : 
     360           0 :         return (rv);
     361             : }
     362             : 
     363             : int
     364           0 : uslcom_open(void *vsc, int portno)
     365             : {
     366           0 :         struct uslcom_softc *sc = vsc;
     367           0 :         usb_device_request_t req;
     368             :         usbd_status err;
     369             : 
     370           0 :         if (usbd_is_dying(sc->sc_udev))
     371           0 :                 return (EIO);
     372             : 
     373           0 :         req.bmRequestType = USLCOM_WRITE;
     374           0 :         req.bRequest = USLCOM_UART;
     375           0 :         USETW(req.wValue, USLCOM_UART_ENABLE);
     376           0 :         USETW(req.wIndex, portno);
     377           0 :         USETW(req.wLength, 0);
     378           0 :         err = usbd_do_request(sc->sc_udev, &req, NULL);
     379           0 :         if (err)
     380           0 :                 return (EIO);
     381             : 
     382           0 :         return (0);
     383           0 : }
     384             : 
     385             : void
     386           0 : uslcom_close(void *vsc, int portno)
     387             : {
     388           0 :         struct uslcom_softc *sc = vsc;
     389           0 :         usb_device_request_t req;
     390             : 
     391           0 :         if (usbd_is_dying(sc->sc_udev))
     392           0 :                 return;
     393             : 
     394           0 :         req.bmRequestType = USLCOM_WRITE;
     395           0 :         req.bRequest = USLCOM_UART;
     396           0 :         USETW(req.wValue, USLCOM_UART_DISABLE);
     397           0 :         USETW(req.wIndex, portno);
     398           0 :         USETW(req.wLength, 0);
     399           0 :         usbd_do_request(sc->sc_udev, &req, NULL);
     400           0 : }
     401             : 
     402             : void
     403           0 : uslcom_set(void *vsc, int portno, int reg, int onoff)
     404             : {
     405           0 :         struct uslcom_softc *sc = vsc;
     406           0 :         usb_device_request_t req;
     407             :         int ctl;
     408             : 
     409           0 :         switch (reg) {
     410             :         case UCOM_SET_DTR:
     411           0 :                 ctl = onoff ? USLCOM_CTRL_DTR_ON : 0;
     412           0 :                 ctl |= USLCOM_CTRL_DTR_SET;
     413           0 :                 break;
     414             :         case UCOM_SET_RTS:
     415           0 :                 ctl = onoff ? USLCOM_CTRL_RTS_ON : 0;
     416           0 :                 ctl |= USLCOM_CTRL_RTS_SET;
     417           0 :                 break;
     418             :         case UCOM_SET_BREAK:
     419           0 :                 uslcom_break(sc, portno, onoff);
     420           0 :                 return;
     421             :         default:
     422           0 :                 return;
     423             :         }
     424           0 :         req.bmRequestType = USLCOM_WRITE;
     425           0 :         req.bRequest = USLCOM_CTRL;
     426           0 :         USETW(req.wValue, ctl);
     427           0 :         USETW(req.wIndex, portno);
     428           0 :         USETW(req.wLength, 0);
     429           0 :         usbd_do_request(sc->sc_udev, &req, NULL);
     430           0 : }
     431             : 
     432             : int
     433           0 : uslcom_param(void *vsc, int portno, struct termios *t)
     434             : {
     435           0 :         struct uslcom_softc *sc = (struct uslcom_softc *)vsc;
     436             :         usbd_status err;
     437           0 :         usb_device_request_t req;
     438           0 :         uint32_t baudrate, flowctrl[4];
     439             :         int data;
     440             : 
     441           0 :         if (t->c_ospeed <= 0 || t->c_ospeed > 2000000)
     442           0 :                 return (EINVAL);
     443             : 
     444           0 :         baudrate = t->c_ospeed;
     445           0 :         req.bmRequestType = USLCOM_WRITE;
     446           0 :         req.bRequest = USLCOM_SET_BAUD_RATE;
     447           0 :         USETW(req.wValue, 0);
     448           0 :         USETW(req.wIndex, portno);
     449           0 :         USETW(req.wLength, sizeof(baudrate));
     450           0 :         err = usbd_do_request(sc->sc_udev, &req, &baudrate);
     451           0 :         if (err)
     452           0 :                 return (EIO);
     453             : 
     454           0 :         if (ISSET(t->c_cflag, CSTOPB))
     455           0 :                 data = USLCOM_STOP_BITS_2;
     456             :         else
     457             :                 data = USLCOM_STOP_BITS_1;
     458           0 :         if (ISSET(t->c_cflag, PARENB)) {
     459           0 :                 if (ISSET(t->c_cflag, PARODD))
     460           0 :                         data |= USLCOM_PARITY_ODD;
     461             :                 else
     462           0 :                         data |= USLCOM_PARITY_EVEN;
     463             :         } else
     464             :                 data |= USLCOM_PARITY_NONE;
     465           0 :         switch (ISSET(t->c_cflag, CSIZE)) {
     466             :         case CS5:
     467           0 :                 data |= USLCOM_SET_DATA_BITS(5);
     468           0 :                 break;
     469             :         case CS6:
     470           0 :                 data |= USLCOM_SET_DATA_BITS(6);
     471           0 :                 break;
     472             :         case CS7:
     473           0 :                 data |= USLCOM_SET_DATA_BITS(7);
     474           0 :                 break;
     475             :         case CS8:
     476           0 :                 data |= USLCOM_SET_DATA_BITS(8);
     477           0 :                 break;
     478             :         }
     479             : 
     480           0 :         req.bmRequestType = USLCOM_WRITE;
     481           0 :         req.bRequest = USLCOM_DATA;
     482           0 :         USETW(req.wValue, data);
     483           0 :         USETW(req.wIndex, portno);
     484           0 :         USETW(req.wLength, 0);
     485           0 :         err = usbd_do_request(sc->sc_udev, &req, NULL);
     486           0 :         if (err)
     487           0 :                 return (EIO);
     488             : 
     489           0 :         if (ISSET(t->c_cflag, CRTSCTS)) {
     490             :                 /*  rts/cts flow ctl */
     491           0 :                 flowctrl[0] = htole32(USLCOM_FLOW_DTR_ON | USLCOM_FLOW_CTS_HS);
     492           0 :                 flowctrl[1] = htole32(USLCOM_FLOW_RTS_HS);
     493           0 :         } else {
     494             :                 /* disable flow ctl */
     495           0 :                 flowctrl[0] = htole32(USLCOM_FLOW_DTR_ON);
     496           0 :                 flowctrl[1] = htole32(USLCOM_FLOW_RTS_ON);
     497             :         }
     498           0 :         flowctrl[2] = 0;
     499           0 :         flowctrl[3] = 0;
     500             : 
     501           0 :         req.bmRequestType = USLCOM_WRITE;
     502           0 :         req.bRequest = USLCOM_SET_FLOW;
     503           0 :         USETW(req.wValue, 0);
     504           0 :         USETW(req.wIndex, portno);
     505           0 :         USETW(req.wLength, sizeof(flowctrl));
     506           0 :         err = usbd_do_request(sc->sc_udev, &req, flowctrl);
     507           0 :         if (err)
     508           0 :                 return (EIO);
     509             : 
     510           0 :         return (0);
     511           0 : }
     512             : 
     513             : void
     514           0 : uslcom_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
     515             : {
     516           0 :         struct uslcom_softc *sc = vsc;
     517             :         
     518           0 :         if (msr != NULL)
     519           0 :                 *msr = sc->sc_msr;
     520           0 :         if (lsr != NULL)
     521           0 :                 *lsr = sc->sc_lsr;
     522           0 : }
     523             : 
     524             : void
     525           0 : uslcom_break(void *vsc, int portno, int onoff)
     526             : {
     527           0 :         struct uslcom_softc *sc = vsc;
     528           0 :         usb_device_request_t req;
     529           0 :         int brk = onoff ? USLCOM_BREAK_ON : USLCOM_BREAK_OFF;   
     530             : 
     531           0 :         req.bmRequestType = USLCOM_WRITE;
     532           0 :         req.bRequest = USLCOM_BREAK;
     533           0 :         USETW(req.wValue, brk);
     534           0 :         USETW(req.wIndex, portno);
     535           0 :         USETW(req.wLength, 0);
     536           0 :         usbd_do_request(sc->sc_udev, &req, NULL);
     537           0 : }

Generated by: LCOV version 1.13