Lines Matching +full:mux +full:- +full:int +full:- +full:port
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
74 int ht_muxport; /* Mux. port no */
75 int ht_open;
84 int sc_radio;
104 int sc_ttys;
107 int sc_msr;
108 int sc_lsr;
109 int sc_line;
116 * The first one has 2,3 or 4 interfaces with a multiplexed serial port
120 * can be detected during run-time.
122 #define UHSO_IFACE_SPEC(usb_type, port, port_type) \ argument
123 (((usb_type) << 24) | ((port) << 16) | (port_type))
133 #define UHSO_IF_MUX 0x02 /* Multiplexed serial port */
137 * Port types
140 #define UHSO_PORT_SERIAL 0x01 /* Serial port */
144 * Multiplexed serial port destination sub-port names
146 #define UHSO_MPORT_TYPE_CTL 0x00 /* Control port */
152 #define UHSO_MPORT_TYPE_NOMAX 8 /* Max number of mux ports */
155 * Port definitions
176 /* Overall port type */
185 * Map between interface port type read from device and description type.
214 "Unknown", /* Not a valid port */
291 static int uhso_autoswitch = 1;
297 static int uhso_debug = UHSO_DEBUG;
299 static int uhso_debug = -1;
395 /* Config for the raw IP-packet interface */
446 static int uhso_probe_iface(struct uhso_softc *, int,
447 int (*probe)(struct usb_device *, int));
448 static int uhso_probe_iface_auto(struct usb_device *, int);
449 static int uhso_probe_iface_static(struct usb_device *, int);
450 static int uhso_attach_muxserial(struct uhso_softc *, struct usb_interface *,
451 int type);
452 static int uhso_attach_bulkserial(struct uhso_softc *, struct usb_interface *,
453 int type);
454 static int uhso_attach_ifnet(struct uhso_softc *, struct usb_interface *,
455 int type);
458 static int uhso_driver_loaded(struct module *, int, void *);
459 static int uhso_radio_sysctl(SYSCTL_HANDLER_ARGS);
460 static int uhso_radio_ctrl(struct uhso_softc *, int);
473 static int uhso_if_ioctl(if_t, u_long, caddr_t);
474 static int uhso_if_output(if_t, struct mbuf *,
513 static int
517 int error; in uhso_probe()
519 if (uaa->usb_mode != USB_MODE_HOST) in uhso_probe()
521 if (uaa->info.bConfigIndex != 0) in uhso_probe()
523 if (uaa->info.bDeviceClass != 0xff) in uhso_probe()
535 if (uhso_probe_iface_auto(uaa->device, in uhso_probe()
536 uaa->info.bIfaceNum) == 0) in uhso_probe()
542 static int
553 int i, error, port; in uhso_attach() local
558 sc->sc_dev = self; in uhso_attach()
559 sc->sc_udev = uaa->device; in uhso_attach()
560 mtx_init(&sc->sc_mtx, "uhso", NULL, MTX_DEF); in uhso_attach()
561 mbufq_init(&sc->sc_rxq, INT_MAX); /* XXXGL: sane maximum */ in uhso_attach()
562 ucom_ref(&sc->sc_super_ucom); in uhso_attach()
564 sc->sc_radio = 1; in uhso_attach()
566 id = usbd_get_interface_descriptor(uaa->iface); in uhso_attach()
567 sc->sc_ctrl_iface_no = id->bInterfaceNumber; in uhso_attach()
569 sc->sc_iface_no = uaa->info.bIfaceNum; in uhso_attach()
570 sc->sc_iface_index = uaa->info.bIfaceIndex; in uhso_attach()
573 uerr = usbd_transfer_setup(uaa->device, in uhso_attach()
574 &sc->sc_iface_index, sc->sc_ctrl_xfer, in uhso_attach()
575 uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx); in uhso_attach()
589 error = uhso_probe_iface(sc, uaa->info.bIfaceNum, probe_f); in uhso_attach()
593 sctx = device_get_sysctl_ctx(sc->sc_dev); in uhso_attach()
594 soid = device_get_sysctl_tree(sc->sc_dev); in uhso_attach()
597 CTLFLAG_RD, uhso_port[UHSO_IFACE_PORT(sc->sc_type)], 0, in uhso_attach()
598 "Port available at this interface"); in uhso_attach()
608 device_set_desc_copy(self, uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)]); in uhso_attach()
610 device_printf(self, "<%s port> at <%s %s> on %s\n", in uhso_attach()
611 uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)], in uhso_attach()
612 usb_get_manufacturer(uaa->device), in uhso_attach()
613 usb_get_product(uaa->device), in uhso_attach()
616 if (sc->sc_ttys > 0) { in uhso_attach()
618 CTLFLAG_RD, &sc->sc_ttys, 0, "Number of attached serial ports"); in uhso_attach()
621 "port", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Serial ports"); in uhso_attach()
628 for (i = 0; i < sc->sc_ttys; i++) { in uhso_attach()
629 ht = &sc->sc_tty[i]; in uhso_attach()
630 ucom = &sc->sc_ucom[i]; in uhso_attach()
632 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) in uhso_attach()
633 port = uhso_mux_port_map[ht->ht_muxport]; in uhso_attach()
635 port = UHSO_IFACE_PORT_TYPE(sc->sc_type); in uhso_attach()
637 desc = uhso_port_type_sysctl[port]; in uhso_attach()
642 ht->ht_name[0] = 0; in uhso_attach()
643 if (sc->sc_ttys == 1) in uhso_attach()
644 snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_super->sc_unit); in uhso_attach()
646 snprintf(ht->ht_name, 32, "cuaU%d.%d", in uhso_attach()
647 ucom->sc_super->sc_unit, ucom->sc_subunit); in uhso_attach()
650 desc = uhso_port_type[port]; in uhso_attach()
652 "tty", CTLFLAG_RD, ht->ht_name, 0, ""); in uhso_attach()
657 device_printf(sc->sc_dev, in uhso_attach()
658 "\"%s\" port at %s\n", desc, ht->ht_name); in uhso_attach()
663 uhso_detach(sc->sc_dev); in uhso_attach()
667 static int
671 int i; in uhso_detach()
673 usbd_transfer_unsetup(sc->sc_xfer, 3); in uhso_detach()
674 usbd_transfer_unsetup(sc->sc_ctrl_xfer, UHSO_CTRL_MAX); in uhso_detach()
675 if (sc->sc_ttys > 0) { in uhso_detach()
676 ucom_detach(&sc->sc_super_ucom, sc->sc_ucom); in uhso_detach()
678 for (i = 0; i < sc->sc_ttys; i++) { in uhso_detach()
679 if (sc->sc_tty[i].ht_muxport != -1) { in uhso_detach()
680 usbd_transfer_unsetup(sc->sc_tty[i].ht_xfer, in uhso_detach()
686 if (sc->sc_ifp != NULL) { in uhso_detach()
687 callout_drain(&sc->sc_c); in uhso_detach()
688 free_unr(uhso_ifnet_unit, if_getdunit(sc->sc_ifp)); in uhso_detach()
689 mtx_lock(&sc->sc_mtx); in uhso_detach()
691 mtx_unlock(&sc->sc_mtx); in uhso_detach()
692 bpfdetach(sc->sc_ifp); in uhso_detach()
693 if_detach(sc->sc_ifp); in uhso_detach()
694 if_free(sc->sc_ifp); in uhso_detach()
695 usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX); in uhso_detach()
710 if (ucom_unref(&sc->sc_super_ucom)) { in uhso_free_softc()
711 free(sc->sc_tty, M_USBDEV); in uhso_free_softc()
712 free(sc->sc_ucom, M_USBDEV); in uhso_free_softc()
713 mtx_destroy(&sc->sc_mtx); in uhso_free_softc()
721 uhso_free_softc(ucom->sc_parent); in uhso_free()
731 if (uaa->dev_state != UAA_DEV_READY || !uhso_autoswitch) in uhso_test_autoinst()
737 id = iface->idesc; in uhso_test_autoinst()
738 if (id == NULL || id->bInterfaceClass != UICLASS_MASS) in uhso_test_autoinst()
745 uaa->dev_state = UAA_DEV_EJECTING; in uhso_test_autoinst()
749 static int
750 uhso_driver_loaded(struct module *mod, int what, void *arg) in uhso_driver_loaded()
775 static int
776 uhso_probe_iface_auto(struct usb_device *udev, int index) in uhso_probe_iface_auto()
781 char port; in uhso_probe_iface_auto() local
807 uhso_port_type[(int)uhso_port_map[(int)buf[index]]]); in uhso_probe_iface_auto()
810 port = 0; in uhso_probe_iface_auto()
812 port = uhso_port_map[(int)buf[index]]; in uhso_probe_iface_auto()
814 switch (port) { in uhso_probe_iface_auto()
817 UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, port)); in uhso_probe_iface_auto()
827 UHSO_PORT_SERIAL, port)); in uhso_probe_iface_auto()
843 static int
844 uhso_probe_iface_static(struct usb_device *udev, int index) in uhso_probe_iface_static()
849 if (cd->bNumInterface <= 3) { in uhso_probe_iface_static()
888 static int
889 uhso_probe_iface(struct uhso_softc *sc, int index, in uhso_probe_iface() argument
890 int (*probe)(struct usb_device *, int)) in uhso_probe_iface()
893 int type, error; in uhso_probe_iface()
897 type = probe(sc->sc_udev, index); in uhso_probe_iface()
902 sc->sc_type = type; in uhso_probe_iface()
903 iface = usbd_get_iface(sc->sc_udev, index); in uhso_probe_iface()
914 * interface then we most likely have a multiplexed serial port in uhso_probe_iface()
917 if (iface->idesc->bNumEndpoints < 3) { in uhso_probe_iface()
918 sc->sc_type = UHSO_IFACE_SPEC( in uhso_probe_iface()
925 UHSO_DPRINTF(1, "Trying to attach mux. serial\n"); in uhso_probe_iface()
927 if (error == 0 && sc->sc_ttys > 0) { in uhso_probe_iface()
928 error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom, in uhso_probe_iface()
929 sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx); in uhso_probe_iface()
931 device_printf(sc->sc_dev, "ucom_attach failed\n"); in uhso_probe_iface()
934 ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev); in uhso_probe_iface()
936 mtx_lock(&sc->sc_mtx); in uhso_probe_iface()
937 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); in uhso_probe_iface()
938 mtx_unlock(&sc->sc_mtx); in uhso_probe_iface()
946 error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom, in uhso_probe_iface()
947 sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx); in uhso_probe_iface()
949 device_printf(sc->sc_dev, "ucom_attach failed\n"); in uhso_probe_iface()
952 ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev); in uhso_probe_iface()
962 static int
963 uhso_radio_ctrl(struct uhso_softc *sc, int onoff) in uhso_radio_ctrl()
974 uerr = usbd_do_request(sc->sc_udev, NULL, &req, NULL); in uhso_radio_ctrl()
976 device_printf(sc->sc_dev, "usbd_do_request_flags failed: %s\n", in uhso_radio_ctrl()
978 return (-1); in uhso_radio_ctrl()
983 static int
987 int error, radio; in uhso_radio_sysctl()
989 radio = sc->sc_radio; in uhso_radio_sysctl()
993 if (radio != sc->sc_radio) { in uhso_radio_sysctl()
996 if (error != -1) in uhso_radio_sysctl()
997 sc->sc_radio = radio; in uhso_radio_sysctl()
1008 static int
1012 sc->sc_ttys++; in uhso_alloc_tty()
1013 sc->sc_tty = reallocf(sc->sc_tty, sizeof(struct uhso_tty) * sc->sc_ttys, in uhso_alloc_tty()
1015 if (sc->sc_tty == NULL) in uhso_alloc_tty()
1016 return (-1); in uhso_alloc_tty()
1018 sc->sc_ucom = reallocf(sc->sc_ucom, in uhso_alloc_tty()
1019 sizeof(struct ucom_softc) * sc->sc_ttys, M_USBDEV, M_WAITOK | M_ZERO); in uhso_alloc_tty()
1020 if (sc->sc_ucom == NULL) in uhso_alloc_tty()
1021 return (-1); in uhso_alloc_tty()
1023 sc->sc_tty[sc->sc_ttys - 1].ht_sc = sc; in uhso_alloc_tty()
1025 UHSO_DPRINTF(1, "Allocated TTY %d\n", sc->sc_ttys - 1); in uhso_alloc_tty()
1026 return (sc->sc_ttys - 1); in uhso_alloc_tty()
1030 * Attach a multiplexed serial port
1034 static int
1036 int type) in uhso_attach_muxserial()
1039 int i, port, tty; in uhso_attach_muxserial() local
1045 * are available through this multiplexed serial port. in uhso_attach_muxserial()
1047 desc = usbd_find_descriptor(sc->sc_udev, NULL, in uhso_attach_muxserial()
1048 iface->idesc->bInterfaceNumber, UDESC_CS_INTERFACE, 0xff, 0, 0); in uhso_attach_muxserial()
1054 UHSO_DPRINTF(1, "Mux port mask %x\n", desc->bDescriptorSubtype); in uhso_attach_muxserial()
1055 if (desc->bDescriptorSubtype == 0) in uhso_attach_muxserial()
1063 port = (1 << i); in uhso_attach_muxserial()
1064 if ((port & desc->bDescriptorSubtype) == port) { in uhso_attach_muxserial()
1065 UHSO_DPRINTF(2, "Found mux port %x (%d)\n", port, i); in uhso_attach_muxserial()
1069 sc->sc_tty[tty].ht_muxport = i; in uhso_attach_muxserial()
1070 uerr = usbd_transfer_setup(sc->sc_udev, in uhso_attach_muxserial()
1071 &sc->sc_iface_index, sc->sc_tty[tty].ht_xfer, in uhso_attach_muxserial()
1072 uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx); in uhso_attach_muxserial()
1074 device_printf(sc->sc_dev, in uhso_attach_muxserial()
1083 uerr = usbd_transfer_setup(sc->sc_udev, in uhso_attach_muxserial()
1084 &iface->idesc->bInterfaceNumber, sc->sc_xfer, in uhso_attach_muxserial()
1085 uhso_mux_config, 1, sc, &sc->sc_mtx); in uhso_attach_muxserial()
1093 * Interrupt callback for the multiplexed serial port. Indicates
1094 * which serial port has data waiting.
1102 unsigned i, mux; in uhso_mux_intr_callback() local
1109 * The multiplexed port number can be found at the first byte. in uhso_mux_intr_callback()
1116 mux = 0; in uhso_mux_intr_callback()
1118 mux++; in uhso_mux_intr_callback()
1121 UHSO_DPRINTF(3, "mux port %d (%d)\n", mux, i); in uhso_mux_intr_callback()
1122 if (mux > UHSO_MPORT_TYPE_NOMAX) in uhso_mux_intr_callback()
1125 /* Issue a read for this serial port */ in uhso_mux_intr_callback()
1127 sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ], in uhso_mux_intr_callback()
1128 &sc->sc_tty[mux]); in uhso_mux_intr_callback()
1129 usbd_transfer_start(sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ]); in uhso_mux_intr_callback()
1154 int actlen, len; in uhso_mux_read_callback()
1161 UHSO_DPRINTF(3, "ht=%p open=%d\n", ht, ht->ht_open); in uhso_mux_read_callback()
1169 UHSO_DPRINTF(3, "got %d bytes on mux port %d\n", len, in uhso_mux_read_callback()
1170 ht->ht_muxport); in uhso_mux_read_callback()
1172 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); in uhso_mux_read_callback()
1177 if (ht->ht_open) in uhso_mux_read_callback()
1178 ucom_put_data(&sc->sc_ucom[ht->ht_muxport], pc, 0, len); in uhso_mux_read_callback()
1186 USETW(req.wIndex, ht->ht_muxport); in uhso_mux_read_callback()
1213 int actlen; in uhso_mux_write_callback()
1219 UHSO_DPRINTF(3, "status=%d, using mux port %d\n", in uhso_mux_write_callback()
1220 USB_GET_STATE(xfer), ht->ht_muxport); in uhso_mux_write_callback()
1225 actlen - sizeof(struct usb_device_request) , in uhso_mux_write_callback()
1226 ht->ht_muxport); in uhso_mux_write_callback()
1231 if (ucom_get_data(&sc->sc_ucom[ht->ht_muxport], pc, in uhso_mux_write_callback()
1239 USETW(req.wIndex, ht->ht_muxport); in uhso_mux_write_callback()
1250 "on muxport %d\n", actlen, ht->ht_muxport); in uhso_mux_write_callback()
1264 static int
1266 int type) in uhso_attach_bulkserial()
1269 int tty; in uhso_attach_bulkserial()
1272 uerr = usbd_transfer_setup(sc->sc_udev, in uhso_attach_bulkserial()
1273 &iface->idesc->bInterfaceNumber, sc->sc_xfer, in uhso_attach_bulkserial()
1274 uhso_bs_config, UHSO_BULK_ENDPT_MAX, sc, &sc->sc_mtx); in uhso_attach_bulkserial()
1277 uerr = usbd_transfer_setup(sc->sc_udev, in uhso_attach_bulkserial()
1278 &iface->idesc->bInterfaceNumber, sc->sc_xfer, in uhso_attach_bulkserial()
1279 uhso_bs_config, UHSO_BULK_ENDPT_MAX - 1, sc, &sc->sc_mtx); in uhso_attach_bulkserial()
1283 return (-1); in uhso_attach_bulkserial()
1288 usbd_transfer_unsetup(sc->sc_xfer, UHSO_BULK_ENDPT_MAX); in uhso_attach_bulkserial()
1292 sc->sc_tty[tty].ht_muxport = -1; in uhso_attach_bulkserial()
1301 int actlen; in uhso_bs_read_callback()
1310 ucom_put_data(&sc->sc_ucom[0], pc, 0, actlen); in uhso_bs_read_callback()
1331 int actlen; in uhso_bs_write_callback()
1342 if (ucom_get_data(&sc->sc_ucom[0], pc, 0, 8192, &actlen)) { in uhso_bs_write_callback()
1363 if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK)) in uhso_bs_cfg()
1368 USETW(req.wValue, sc->sc_line); in uhso_bs_cfg()
1369 USETW(req.wIndex, sc->sc_iface_no); in uhso_bs_cfg()
1372 uerr = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom[0], &req, NULL, 0, 1000); in uhso_bs_cfg()
1374 device_printf(sc->sc_dev, "failed to set ctrl line state to " in uhso_bs_cfg()
1375 "0x%02x: %s\n", sc->sc_line, usbd_errstr(uerr)); in uhso_bs_cfg()
1384 int actlen; in uhso_bs_intr_callback()
1396 else if (actlen > (int)sizeof(struct usb_cdc_notification)) { in uhso_bs_intr_callback()
1404 if (UGETW(cdc.wIndex) != sc->sc_iface_no) { in uhso_bs_intr_callback()
1406 UGETW(cdc.wIndex), sc->sc_iface_no); in uhso_bs_intr_callback()
1414 sc->sc_msr = 0; in uhso_bs_intr_callback()
1415 sc->sc_lsr = 0; in uhso_bs_intr_callback()
1417 sc->sc_msr |= SER_RI; in uhso_bs_intr_callback()
1419 sc->sc_msr |= SER_DSR; in uhso_bs_intr_callback()
1421 sc->sc_msr |= SER_DCD; in uhso_bs_intr_callback()
1423 ucom_status_change(&sc->sc_ucom[0]); in uhso_bs_intr_callback()
1438 struct uhso_softc *sc = ucom->sc_parent; in uhso_ucom_cfg_get_status()
1440 *lsr = sc->sc_lsr; in uhso_ucom_cfg_get_status()
1441 *msr = sc->sc_msr; in uhso_ucom_cfg_get_status()
1447 struct uhso_softc *sc = ucom->sc_parent; in uhso_ucom_cfg_set_dtr()
1449 if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK)) in uhso_ucom_cfg_set_dtr()
1453 sc->sc_line |= UCDC_LINE_DTR; in uhso_ucom_cfg_set_dtr()
1455 sc->sc_line &= ~UCDC_LINE_DTR; in uhso_ucom_cfg_set_dtr()
1463 struct uhso_softc *sc = ucom->sc_parent; in uhso_ucom_cfg_set_rts()
1465 if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK)) in uhso_ucom_cfg_set_rts()
1469 sc->sc_line |= UCDC_LINE_RTS; in uhso_ucom_cfg_set_rts()
1471 sc->sc_line &= ~UCDC_LINE_RTS; in uhso_ucom_cfg_set_rts()
1479 struct uhso_softc *sc = ucom->sc_parent; in uhso_ucom_start_read()
1482 ucom->sc_super->sc_unit, ucom->sc_subunit); in uhso_ucom_start_read()
1484 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { in uhso_ucom_start_read()
1485 sc->sc_tty[ucom->sc_subunit].ht_open = 1; in uhso_ucom_start_read()
1486 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); in uhso_ucom_start_read()
1488 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { in uhso_ucom_start_read()
1489 sc->sc_tty[0].ht_open = 1; in uhso_ucom_start_read()
1490 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]); in uhso_ucom_start_read()
1491 if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL) in uhso_ucom_start_read()
1492 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]); in uhso_ucom_start_read()
1500 struct uhso_softc *sc = ucom->sc_parent; in uhso_ucom_stop_read()
1502 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { in uhso_ucom_stop_read()
1503 sc->sc_tty[ucom->sc_subunit].ht_open = 0; in uhso_ucom_stop_read()
1505 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_READ]); in uhso_ucom_stop_read()
1507 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { in uhso_ucom_stop_read()
1508 sc->sc_tty[0].ht_open = 0; in uhso_ucom_stop_read()
1509 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]); in uhso_ucom_stop_read()
1510 if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL) in uhso_ucom_stop_read()
1511 usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]); in uhso_ucom_stop_read()
1518 struct uhso_softc *sc = ucom->sc_parent; in uhso_ucom_start_write()
1520 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { in uhso_ucom_start_write()
1521 UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_subunit); in uhso_ucom_start_write()
1523 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); in uhso_ucom_start_write()
1526 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE], in uhso_ucom_start_write()
1527 &sc->sc_tty[ucom->sc_subunit]); in uhso_ucom_start_write()
1529 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]); in uhso_ucom_start_write()
1531 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { in uhso_ucom_start_write()
1532 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]); in uhso_ucom_start_write()
1539 struct uhso_softc *sc = ucom->sc_parent; in uhso_ucom_stop_write()
1541 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { in uhso_ucom_stop_write()
1543 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]); in uhso_ucom_stop_write()
1545 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { in uhso_ucom_stop_write()
1546 usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]); in uhso_ucom_stop_write()
1550 static int
1551 uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface *iface, int type) in uhso_attach_ifnet()
1559 uerr = usbd_transfer_setup(sc->sc_udev, in uhso_attach_ifnet()
1560 &iface->idesc->bInterfaceNumber, sc->sc_if_xfer, in uhso_attach_ifnet()
1561 uhso_ifnet_config, UHSO_IFNET_MAX, sc, &sc->sc_mtx); in uhso_attach_ifnet()
1565 return (-1); in uhso_attach_ifnet()
1568 sc->sc_ifp = ifp = if_alloc(IFT_OTHER); in uhso_attach_ifnet()
1570 callout_init_mtx(&sc->sc_c, &sc->sc_mtx, 0); in uhso_attach_ifnet()
1571 mtx_lock(&sc->sc_mtx); in uhso_attach_ifnet()
1572 callout_reset(&sc->sc_c, 1, uhso_if_rxflush, sc); in uhso_attach_ifnet()
1573 mtx_unlock(&sc->sc_mtx); in uhso_attach_ifnet()
1582 if_initname(ifp, device_get_name(sc->sc_dev), devunit); in uhso_attach_ifnet()
1596 sctx = device_get_sysctl_ctx(sc->sc_dev); in uhso_attach_ifnet()
1597 soid = device_get_sysctl_tree(sc->sc_dev); in uhso_attach_ifnet()
1611 int actlen; in uhso_ifnet_read_callback()
1619 if (actlen > 0 && (if_getdrvflags(sc->sc_ifp) & IFF_DRV_RUNNING)) { in uhso_ifnet_read_callback()
1621 if (mbufq_full(&sc->sc_rxq)) in uhso_ifnet_read_callback()
1625 m->m_pkthdr.len = m->m_len = actlen; in uhso_ifnet_read_callback()
1627 mbufq_enqueue(&sc->sc_rxq, m); in uhso_ifnet_read_callback()
1628 if (!callout_pending(&sc->sc_c) || in uhso_ifnet_read_callback()
1629 !callout_active(&sc->sc_c)) { in uhso_ifnet_read_callback()
1630 callout_schedule(&sc->sc_c, 1); in uhso_ifnet_read_callback()
1651 * Each frame we receive might contain several small ip-packets as well
1652 * as partial ip-packets. We need to separate/assemble them into individual
1653 * packets before sending them to the ip-layer.
1660 if_t ifp = sc->sc_ifp; in uhso_if_rxflush()
1668 int isr; in uhso_if_rxflush()
1671 mwait = sc->sc_mwait; in uhso_if_rxflush()
1675 if ((m = mbufq_dequeue(&sc->sc_rxq)) == NULL) in uhso_if_rxflush()
1677 UHSO_DPRINTF(3, "dequeue m=%p, len=%d\n", m, m->m_len); in uhso_if_rxflush()
1679 mtx_unlock(&sc->sc_mtx); in uhso_if_rxflush()
1687 m0, m0->m_len, m, m->m_len); in uhso_if_rxflush()
1694 mtx_lock(&sc->sc_mtx); in uhso_if_rxflush()
1698 m, m->m_pkthdr.len); in uhso_if_rxflush()
1708 if (ip->ip_v == IPVERSION) { in uhso_if_rxflush()
1709 iplen = htons(ip->ip_len); in uhso_if_rxflush()
1714 else if ((ip6->ip6_vfc & IPV6_VERSION_MASK) == IPV6_VERSION) { in uhso_if_rxflush()
1715 iplen = htons(ip6->ip6_plen); in uhso_if_rxflush()
1721 "m=%p, len=%d\n", (*cp & 0xf0) >> 4, m, m->m_len); in uhso_if_rxflush()
1726 mtx_lock(&sc->sc_mtx); in uhso_if_rxflush()
1735 mtx_lock(&sc->sc_mtx); in uhso_if_rxflush()
1740 m, m->m_pkthdr.len, cp, iplen); in uhso_if_rxflush()
1745 if (iplen < m->m_pkthdr.len) { in uhso_if_rxflush()
1750 * copy the IP-packet into it. in uhso_if_rxflush()
1754 m->m_pkthdr.len = m->m_len = iplen; in uhso_if_rxflush()
1761 "m0_len=%d/%d\n", m, m->m_pkthdr.len, m->m_len, in uhso_if_rxflush()
1762 m0, m0->m_pkthdr.len, m0->m_len); in uhso_if_rxflush()
1764 else if (iplen > m->m_pkthdr.len) { in uhso_if_rxflush()
1766 m, m->m_pkthdr.len); in uhso_if_rxflush()
1769 mtx_lock(&sc->sc_mtx); in uhso_if_rxflush()
1774 m->m_pkthdr.rcvif = ifp; in uhso_if_rxflush()
1777 BPF_MTAP(sc->sc_ifp, m); in uhso_if_rxflush()
1781 mtx_lock(&sc->sc_mtx); in uhso_if_rxflush()
1784 sc->sc_mwait = mwait; in uhso_if_rxflush()
1791 if_t ifp = sc->sc_ifp; in uhso_ifnet_write_callback()
1794 int actlen; in uhso_ifnet_write_callback()
1812 if (m->m_pkthdr.len > MCLBYTES) in uhso_ifnet_write_callback()
1813 m->m_pkthdr.len = MCLBYTES; in uhso_ifnet_write_callback()
1815 usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len); in uhso_ifnet_write_callback()
1817 usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len); in uhso_ifnet_write_callback()
1832 static int
1848 mtx_lock(&sc->sc_mtx); in uhso_if_ioctl()
1850 mtx_unlock(&sc->sc_mtx); in uhso_if_ioctl()
1868 if_t ifp = sc->sc_ifp; in uhso_if_init()
1870 mtx_lock(&sc->sc_mtx); in uhso_if_init()
1872 ifp = sc->sc_ifp; in uhso_if_init()
1875 mtx_unlock(&sc->sc_mtx); in uhso_if_init()
1880 static int
1884 int error; in uhso_if_output()
1887 if (dst->sa_family != AF_INET in uhso_if_output()
1889 && dst->sa_family != AF_INET6 in uhso_if_output()
1914 mtx_lock(&sc->sc_mtx); in uhso_if_start()
1915 usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_READ]); in uhso_if_start()
1916 usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_WRITE]); in uhso_if_start()
1917 mtx_unlock(&sc->sc_mtx); in uhso_if_start()
1925 usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_READ]); in uhso_if_stop()
1926 usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_WRITE]); in uhso_if_stop()
1927 if_setdrvflagbits(sc->sc_ifp, 0, (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)); in uhso_if_stop()