static usb_error_t usbd_setup_endpoint_one(irp *ip, uint8_t ifidx, struct ndisusb_ep *ne, struct usb_config *epconf) { device_t dev = IRP_NDIS_DEV(ip); struct ndis_softc *sc = device_get_softc(dev); struct usb_xfer *xfer; usb_error_t status; InitializeListHead(&ne->ne_active); InitializeListHead(&ne->ne_pending); KeInitializeSpinLock(&ne->ne_lock); status = usbd_transfer_setup(sc->ndisusb_dev, &ifidx, ne->ne_xfer, epconf, 1, sc, &sc->ndisusb_mtx); if (status != USB_ERR_NORMAL_COMPLETION) { device_printf(dev, "couldn't setup xfer: %s\n", usbd_errstr(status)); return (status); } xfer = ne->ne_xfer[0]; usbd_xfer_set_priv(xfer, ne); return (status); }
static usb_error_t usbd_setup_endpoint(irp *ip, uint8_t ifidx, struct usb_endpoint_descriptor *ep) { device_t dev = IRP_NDIS_DEV(ip); struct ndis_softc *sc = device_get_softc(dev); struct ndisusb_ep *ne; struct usb_config cfg; struct usb_xfer *xfer; usb_error_t status; /* check for non-supported transfer types */ if (UE_GET_XFERTYPE(ep->bmAttributes) == UE_CONTROL || UE_GET_XFERTYPE(ep->bmAttributes) == UE_ISOCHRONOUS) { device_printf(dev, "%s: unsuppotted transfer types %#x\n", __func__, UE_GET_XFERTYPE(ep->bmAttributes)); return (USB_ERR_INVAL); } ne = &sc->ndisusb_ep[NDISUSB_GET_ENDPT(ep->bEndpointAddress)]; InitializeListHead(&ne->ne_active); InitializeListHead(&ne->ne_pending); KeInitializeSpinLock(&ne->ne_lock); ne->ne_dirin = UE_GET_DIR(ep->bEndpointAddress) >> 7; memset(&cfg, 0, sizeof(struct usb_config)); cfg.type = UE_GET_XFERTYPE(ep->bmAttributes); cfg.endpoint = UE_GET_ADDR(ep->bEndpointAddress); cfg.direction = UE_GET_DIR(ep->bEndpointAddress); cfg.callback = &usbd_non_isoc_callback; cfg.bufsize = UGETW(ep->wMaxPacketSize); cfg.flags.proxy_buffer = 1; if (UE_GET_DIR(ep->bEndpointAddress) == UE_DIR_IN) cfg.flags.short_xfer_ok = 1; status = usbd_transfer_setup(sc->ndisusb_dev, &ifidx, ne->ne_xfer, &cfg, 1, sc, &sc->ndisusb_mtx); if (status != USB_ERR_NORMAL_COMPLETION) { device_printf(dev, "couldn't setup xfer: %s\n", usbd_errstr(status)); return (status); } xfer = ne->ne_xfer[0]; usbd_xfer_set_priv(xfer, ne); if (UE_GET_DIR(ep->bEndpointAddress) == UE_DIR_IN) usbd_xfer_set_timeout(xfer, NDISUSB_NO_TIMEOUT); else { if (UE_GET_XFERTYPE(ep->bmAttributes) == UE_BULK) usbd_xfer_set_timeout(xfer, NDISUSB_TX_TIMEOUT); else usbd_xfer_set_timeout(xfer, NDISUSB_INTR_TIMEOUT); } return (status); }
/* * Interrupt callback for the multiplexed serial port. Indicates * which serial port has data waiting. */ static void uhso_mux_intr_callback(struct usb_xfer *xfer, usb_error_t error) { struct usb_page_cache *pc; struct usb_page_search res; struct uhso_softc *sc = usbd_xfer_softc(xfer); unsigned int i, mux; UHSO_DPRINTF(3, "status %d\n", USB_GET_STATE(xfer)); switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: /* * The multiplexed port number can be found at the first byte. * It contains a bit mask, we transform this in to an integer. */ pc = usbd_xfer_get_frame(xfer, 0); usbd_get_page(pc, 0, &res); i = *((unsigned char *)res.buffer); mux = 0; while (i >>= 1) { mux++; } UHSO_DPRINTF(3, "mux port %d (%d)\n", mux, i); if (mux > UHSO_MPORT_TYPE_NOMAX) break; /* Issue a read for this serial port */ usbd_xfer_set_priv( sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ], &sc->sc_tty[mux]); usbd_transfer_start(sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ]); break; case USB_ST_SETUP: tr_setup: usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); usbd_transfer_submit(xfer); break; default: UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); if (error == USB_ERR_CANCELLED) break; usbd_xfer_set_stall(xfer); goto tr_setup; } }
static void uhso_ucom_start_write(struct ucom_softc *ucom) { struct uhso_softc *sc = ucom->sc_parent; if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_subunit); usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); usbd_xfer_set_priv( sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE], &sc->sc_tty[ucom->sc_subunit]); usbd_transfer_start( sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]); } else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]); } }
static void usie_uc_tx_callback(struct usb_xfer *xfer, usb_error_t error) { struct ucom_softc *ucom = usbd_xfer_softc(xfer); struct usb_page_cache *pc; uint32_t actlen; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: case USB_ST_SETUP: tr_setup: pc = usbd_xfer_get_frame(xfer, 0); /* handle CnS request */ struct mbuf *m = usbd_xfer_get_priv(xfer); if (m != NULL) { usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len); usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len); usbd_xfer_set_priv(xfer, NULL); usbd_transfer_submit(xfer); m_freem(m); break; } /* standard ucom transfer */ if (ucom_get_data(ucom, pc, 0, USIE_BUFSIZE, &actlen)) { usbd_xfer_set_frame_len(xfer, 0, actlen); usbd_transfer_submit(xfer); } break; default: /* Error */ if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); goto tr_setup; } break; } }
static void usie_cns_req(struct usie_softc *sc, uint32_t id, uint16_t obj) { struct ifnet *ifp = sc->sc_ifp; struct mbuf *m; struct usb_xfer *xfer; struct usie_hip *hip; struct usie_cns *cns; uint8_t *param; uint8_t *tmp; uint8_t cns_len; m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m == NULL)) { DPRINTF("could not allocate mbuf\n"); ifp->if_ierrors++; return; } /* to align usie_hip{} on 32 bit */ m->m_data += 3; param = mtod(m, uint8_t *); *param++ = USIE_HIP_FRM_CHR; hip = (struct usie_hip *)param; cns = (struct usie_cns *)(hip + 1); tmp = param + USIE_HIPCNS_MIN - 2; switch (obj) { case USIE_CNS_OB_LINK_UPDATE: cns_len = 2; cns->op = USIE_CNS_OP_SET; *tmp++ = 1; /* profile ID, always use 1 for now */ *tmp++ = id == USIE_CNS_ID_INIT ? 1 : 0; break; case USIE_CNS_OB_PROF_WRITE: cns_len = 245; cns->op = USIE_CNS_OP_SET; *tmp++ = 1; /* profile ID, always use 1 for now */ *tmp++ = 2; memcpy(tmp, &sc->sc_net, 34); memset(tmp + 35, 0, 245 - 36); tmp += 243; break; case USIE_CNS_OB_RSSI: cns_len = 0; cns->op = USIE_CNS_OP_REQ; break; default: DPRINTF("unsupported CnS object type\n"); return; } *tmp = USIE_HIP_FRM_CHR; hip->len = htobe16(sizeof(struct usie_cns) + cns_len); hip->id = USIE_HIP_CNS2M; hip->param = 0; /* none for CnS */ cns->obj = htobe16(obj); cns->id = htobe32(id); cns->len = cns_len; cns->rsv0 = cns->rsv1 = 0; /* always '0' */ param = (uint8_t *)(cns + 1); DPRINTF("param: %16D\n", param, ":"); m->m_pkthdr.len = m->m_len = USIE_HIPCNS_MIN + cns_len + 2; xfer = sc->sc_uc_xfer[USIE_HIP_IF][USIE_UC_TX]; if (usbd_xfer_get_priv(xfer) == NULL) { usbd_xfer_set_priv(xfer, m); usbd_transfer_start(xfer); } else { DPRINTF("Dropped CNS event\n"); m_freem(m); } }