static int ubsa_attach(device_t self) { struct ubsa_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); usbd_device_handle dev; struct ucom_softc *ucom; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usbd_status err; int i; dev = uaa->device; ucom = &sc->sc_ucom; bzero(sc, sizeof (struct ubsa_softc)); /* * initialize rts, dtr variables to something * different from boolean 0, 1 */ sc->sc_dtr = -1; sc->sc_rts = -1; ucom->sc_dev = self; ucom->sc_udev = dev; ucom->sc_iface = uaa->iface; DPRINTF(("ubsa attach: sc = %p\n", sc)); /* initialize endpoints */ ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; /* Move the device into the configured state. */ err = usbd_set_config_index(dev, UBSA_CONFIG_INDEX, 1); if (err) { device_printf(ucom->sc_dev, "failed to set configuration: %s\n", usbd_errstr(err)); ucom->sc_dying = 1; goto error; } /* get the config descriptor */ cdesc = usbd_get_config_descriptor(ucom->sc_udev); if (cdesc == NULL) { device_printf(ucom->sc_dev, "failed to get configuration " "descriptor\n"); ucom->sc_dying = 1; goto error; } /* get the first interface */ err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX, &ucom->sc_iface); if (err) { device_printf(ucom->sc_dev, "failed to get interface: %s\n", usbd_errstr(err)); ucom->sc_dying = 1; goto error; } /* Find the endpoints */ id = usbd_get_interface_descriptor(ucom->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i); if (ed == NULL) { device_printf(ucom->sc_dev, "no endpoint descriptor " "for %d\n", i); ucom->sc_dying = 1; goto error; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_intr_number = ed->bEndpointAddress; sc->sc_isize = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { ucom->sc_bulkin_no = ed->bEndpointAddress; ucom->sc_ibufsize = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { ucom->sc_bulkout_no = ed->bEndpointAddress; ucom->sc_obufsize = UGETW(ed->wMaxPacketSize); } } if (sc->sc_intr_number == -1) { device_printf(ucom->sc_dev, "could not find interrupt in\n"); ucom->sc_dying = 1; goto error; } /* keep interface for interrupt */ sc->sc_intr_iface = ucom->sc_iface; if (ucom->sc_bulkin_no == -1) { device_printf(ucom->sc_dev, "could not find data bulk in\n"); ucom->sc_dying = 1; goto error; } if (ucom->sc_bulkout_no == -1) { device_printf(ucom->sc_dev, "could not find data bulk out\n"); ucom->sc_dying = 1; goto error; } ucom->sc_parent = sc; ucom->sc_portno = UCOM_UNK_PORTNO; /* bulkin, bulkout set above */ ucom->sc_ibufsizepad = ucom->sc_ibufsize; ucom->sc_opkthdrlen = 0; ucom->sc_callback = &ubsa_callback; DPRINTF(("ubsa: in = 0x%x, out = 0x%x, intr = 0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number)); ucom_attach(ucom); return 0; error: return ENXIO; }
/* * Probes an interface for its particular capabilities and attaches if * it's a supported interface. */ static int uhso_probe_iface(struct uhso_softc *sc, int index, int (*probe)(struct usb_device *, int)) { struct usb_interface *iface; int type, error; UHSO_DPRINTF(1, "Probing for interface %d, probe_func=%p\n", index, probe); type = probe(sc->sc_udev, index); UHSO_DPRINTF(1, "Probe result %x\n", type); if (type <= 0) return (ENXIO); sc->sc_type = type; iface = usbd_get_iface(sc->sc_udev, index); if (UHSO_IFACE_PORT_TYPE(type) == UHSO_PORT_TYPE_NETWORK) { error = uhso_attach_ifnet(sc, iface, type); if (error) { UHSO_DPRINTF(1, "uhso_attach_ifnet failed"); return (ENXIO); } /* * If there is an additional interrupt endpoint on this * interface then we most likely have a multiplexed serial port * available. */ if (iface->idesc->bNumEndpoints < 3) { sc->sc_type = UHSO_IFACE_SPEC( UHSO_IFACE_USB_TYPE(type) & ~UHSO_IF_MUX, UHSO_IFACE_PORT(type) & ~UHSO_PORT_SERIAL, UHSO_IFACE_PORT_TYPE(type)); return (0); } UHSO_DPRINTF(1, "Trying to attach mux. serial\n"); error = uhso_attach_muxserial(sc, iface, type); if (error == 0 && sc->sc_ttys > 0) { error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx); if (error) { device_printf(sc->sc_dev, "ucom_attach failed\n"); return (ENXIO); } ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev); mtx_lock(&sc->sc_mtx); usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); mtx_unlock(&sc->sc_mtx); } } else if ((UHSO_IFACE_USB_TYPE(type) & UHSO_IF_BULK) && UHSO_IFACE_PORT(type) & UHSO_PORT_SERIAL) { error = uhso_attach_bulkserial(sc, iface, type); if (error) return (ENXIO); error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx); if (error) { device_printf(sc->sc_dev, "ucom_attach failed\n"); return (ENXIO); } ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev); } else { UHSO_DPRINTF(0, "Unknown type %x\n", type); return (ENXIO); } return (0); }
static int usie_attach(device_t self) { struct usie_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); struct ifnet *ifp; struct usb_interface *iface; struct usb_interface_descriptor *id; struct usb_device_request req; int err; uint16_t fwattr; uint8_t iface_index; uint8_t ifidx; uint8_t start; device_set_usb_desc(self); sc->sc_udev = uaa->device; sc->sc_dev = self; mtx_init(&sc->sc_mtx, "usie", MTX_NETWORK_LOCK, MTX_DEF); TASK_INIT(&sc->sc_if_status_task, 0, usie_if_status_cb, sc); TASK_INIT(&sc->sc_if_sync_task, 0, usie_if_sync_cb, sc); usb_callout_init_mtx(&sc->sc_if_sync_ch, &sc->sc_mtx, 0); mtx_lock(&sc->sc_mtx); /* set power mode to D0 */ req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = USIE_POWER; USETW(req.wValue, 0); USETW(req.wIndex, 0); USETW(req.wLength, 0); if (usie_do_request(sc, &req, NULL)) { mtx_unlock(&sc->sc_mtx); goto detach; } /* read fw attr */ fwattr = 0; req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = USIE_FW_ATTR; USETW(req.wValue, 0); USETW(req.wIndex, 0); USETW(req.wLength, sizeof(fwattr)); if (usie_do_request(sc, &req, &fwattr)) { mtx_unlock(&sc->sc_mtx); goto detach; } mtx_unlock(&sc->sc_mtx); /* check DHCP supports */ DPRINTF("fwattr=%x\n", fwattr); if (!(fwattr & USIE_FW_DHCP)) { device_printf(self, "DHCP is not supported. A firmware upgrade might be needed.\n"); } /* find available interfaces */ sc->sc_nucom = 0; for (ifidx = 0; ifidx < USIE_IFACE_MAX; ifidx++) { iface = usbd_get_iface(uaa->device, ifidx); if (iface == NULL) break; id = usbd_get_interface_descriptor(iface); if ((id == NULL) || (id->bInterfaceClass != UICLASS_VENDOR)) continue; /* setup Direct IP transfer */ if (id->bInterfaceNumber >= 7 && id->bNumEndpoints == 3) { sc->sc_if_ifnum = id->bInterfaceNumber; iface_index = ifidx; DPRINTF("ifnum=%d, ifidx=%d\n", sc->sc_if_ifnum, ifidx); err = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_if_xfer, usie_if_config, USIE_IF_N_XFER, sc, &sc->sc_mtx); if (err == 0) continue; device_printf(self, "could not allocate USB transfers on " "iface_index=%d, err=%s\n", iface_index, usbd_errstr(err)); goto detach; } /* setup ucom */ if (sc->sc_nucom >= USIE_UCOM_MAX) continue; usbd_set_parent_iface(uaa->device, ifidx, uaa->info.bIfaceIndex); DPRINTF("NumEndpoints=%d bInterfaceNumber=%d\n", id->bNumEndpoints, id->bInterfaceNumber); if (id->bNumEndpoints == 2) { sc->sc_uc_xfer[sc->sc_nucom][0] = NULL; start = 1; } else start = 0; err = usbd_transfer_setup(uaa->device, &ifidx, sc->sc_uc_xfer[sc->sc_nucom] + start, usie_uc_config + start, USIE_UC_N_XFER - start, &sc->sc_ucom[sc->sc_nucom], &sc->sc_mtx); if (err != 0) { DPRINTF("usbd_transfer_setup error=%s\n", usbd_errstr(err)); continue; } mtx_lock(&sc->sc_mtx); for (; start < USIE_UC_N_XFER; start++) usbd_xfer_set_stall(sc->sc_uc_xfer[sc->sc_nucom][start]); mtx_unlock(&sc->sc_mtx); sc->sc_uc_ifnum[sc->sc_nucom] = id->bInterfaceNumber; sc->sc_nucom++; /* found a port */ } if (sc->sc_nucom == 0) { device_printf(self, "no comports found\n"); goto detach; } err = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_nucom, sc, &usie_uc_callback, &sc->sc_mtx); if (err != 0) { DPRINTF("ucom_attach failed\n"); goto detach; } DPRINTF("Found %d interfaces.\n", sc->sc_nucom); /* setup ifnet (Direct IP) */ sc->sc_ifp = ifp = if_alloc(IFT_OTHER); if (ifp == NULL) { device_printf(self, "Could not allocate a network interface\n"); goto detach; } if_initname(ifp, "usie", device_get_unit(self)); ifp->if_softc = sc; ifp->if_mtu = USIE_MTU_MAX; ifp->if_flags |= IFF_NOARP; ifp->if_init = usie_if_init; ifp->if_ioctl = usie_if_ioctl; ifp->if_start = usie_if_start; ifp->if_output = usie_if_output; IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); bpfattach(ifp, DLT_RAW, 0); if (fwattr & USIE_PM_AUTO) { usbd_set_power_mode(uaa->device, USB_POWER_MODE_SAVE); DPRINTF("enabling automatic suspend and resume\n"); } else { usbd_set_power_mode(uaa->device, USB_POWER_MODE_ON); DPRINTF("USB power is always ON\n"); } DPRINTF("device attached\n"); return (0); detach: usie_detach(self); return (ENOMEM); }
static int ugensa_attach(device_t self) { struct ugensa_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); struct ucom_softc *ucom; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; ucom = &sc->sc_ucom; bzero(sc, sizeof (struct ugensa_softc)); ucom->sc_dev = self; ucom->sc_udev = uaa->device; ucom->sc_iface = uaa->iface; id = usbd_get_interface_descriptor(ucom->sc_iface); sc->sc_iface_no = id->bInterfaceNumber; ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i); if (ed == NULL) { device_printf(ucom->sc_dev, "no endpoint descriptor " "found for %d\n", i); goto error; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_intr_number = ed->bEndpointAddress; sc->sc_isize = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) ucom->sc_bulkin_no = ed->bEndpointAddress; else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) ucom->sc_bulkout_no = ed->bEndpointAddress; } if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) { device_printf(ucom->sc_dev, "missing endpoint\n"); goto error; } sc->sc_dtr = sc->sc_rts = -1; ucom->sc_parent = sc; ucom->sc_portno = UCOM_UNK_PORTNO; ucom->sc_ibufsize = UGENSABUFSZ; ucom->sc_obufsize = UGENSABUFSZ; ucom->sc_ibufsizepad = UGENSABUFSZ; ucom->sc_opkthdrlen = 0; ucom->sc_callback = &ugensa_callback; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, ucom->sc_udev, ucom->sc_dev); DPRINTF(("%s: in = 0x%x, out = 0x%x\n", device_get_nameunit(ucom->sc_dev), ucom->sc_bulkin_no, ucom->sc_bulkout_no)); ucom_attach(&sc->sc_ucom); return 0; error: ucom->sc_dying = 1; return ENXIO; }
static int umodem_attach(device_t self) { struct umodem_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); usbd_device_handle dev = uaa->device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; const char *devname; usbd_status err; int data_ifcno; int i; struct ucom_softc *ucom; ucom = &sc->sc_ucom; ucom->sc_dev = self; sc->sc_dev = self; ucom->sc_udev = dev; ucom->sc_iface = uaa->iface; sc->sc_udev = dev; sc->sc_ctl_iface = uaa->iface; devname = device_get_nameunit(sc->sc_dev); /* XXX ? use something else ? XXX */ id = usbd_get_interface_descriptor(sc->sc_ctl_iface); sc->sc_ctl_iface_no = id->bInterfaceNumber; sc->sc_data_iface_no = data_ifcno = umodem_get_caps(dev, &sc->sc_cm_cap, &sc->sc_acm_cap, id); if (data_ifcno == -1) { kprintf("%s: no pointer to data interface\n", devname); goto bad; } kprintf("%s: data interface %d, has %sCM over data, has %sbreak\n", devname, data_ifcno, sc->sc_cm_cap & USB_CDC_CM_OVER_DATA ? "" : "no ", sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK ? "" : "no "); /* Get the data interface too. */ for (i = 0; i < uaa->nifaces; i++) { if (uaa->ifaces[i] != NULL) { id = usbd_get_interface_descriptor(uaa->ifaces[i]); if (id != NULL && id->bInterfaceNumber == data_ifcno) { sc->sc_data_iface = uaa->ifaces[i]; uaa->ifaces[i] = NULL; } } } if (sc->sc_data_iface == NULL) { kprintf("%s: no data interface\n", devname); goto bad; } ucom->sc_iface = sc->sc_data_iface; /* * Find the bulk endpoints. * Iterate over all endpoints in the data interface and take note. */ ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1; id = usbd_get_interface_descriptor(sc->sc_data_iface); for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_data_iface, i); if (ed == NULL) { kprintf("%s: no endpoint descriptor for %d\n", devname, i); goto bad; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { ucom->sc_bulkin_no = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { ucom->sc_bulkout_no = ed->bEndpointAddress; } } if (ucom->sc_bulkin_no == -1) { kprintf("%s: Could not find data bulk in\n", devname); goto bad; } if (ucom->sc_bulkout_no == -1) { kprintf("%s: Could not find data bulk out\n", devname); goto bad; } if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_ASSUME_CM_OVER_DATA) { DPRINTF(("Quirk says to assume CM over data\n")); sc->sc_cm_over_data = 1; } else { if (sc->sc_cm_cap & USB_CDC_CM_OVER_DATA) { if (sc->sc_acm_cap & USB_CDC_ACM_HAS_FEATURE) err = umodem_set_comm_feature(sc, UCDC_ABSTRACT_STATE, UCDC_DATA_MULTIPLEXED); else err = 0; if (err) { kprintf("%s: could not set data multiplex mode\n", devname); goto bad; } sc->sc_cm_over_data = 1; } } /* * The standard allows for notification messages (to indicate things * like a modem hangup) to come in via an interrupt endpoint * off of the control interface. Iterate over the endpoints on * the control interface and see if there are any interrupt * endpoints; if there are, then register it. */ sc->sc_ctl_notify = -1; sc->sc_notify_pipe = NULL; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i); if (ed == NULL) continue; if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) { kprintf("%s: status change notification available\n", devname); sc->sc_ctl_notify = ed->bEndpointAddress; } } sc->sc_dtr = -1; ucom->sc_parent = sc; ucom->sc_portno = UCOM_UNK_PORTNO; /* bulkin, bulkout set above */ ucom->sc_ibufsize = UMODEMIBUFSIZE; ucom->sc_obufsize = UMODEMOBUFSIZE; ucom->sc_ibufsizepad = UMODEMIBUFSIZE; ucom->sc_opkthdrlen = 0; ucom->sc_callback = &umodem_callback; ucom_attach(&sc->sc_ucom); return 0; bad: ucom->sc_dying = 1; return ENXIO; }
static int uplcom_attach(device_t self) { struct uplcom_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); usbd_device_handle dev = uaa->device; struct ucom_softc *ucom; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; const char *devname; usbd_status err; int i; ucom = &sc->sc_ucom; ucom->sc_dev = self; ucom->sc_udev = dev; ucom->sc_iface = uaa->iface; devname = device_get_nameunit(ucom->sc_dev); DPRINTF(("uplcom attach: sc = %p\n", sc)); /* determine chip type */ for (i = 0; uplcom_products[i].vendor != 0; i++) { if (uplcom_products[i].vendor == uaa->vendor && uplcom_products[i].product == uaa->product && (uplcom_products[i].release == uaa->release || uplcom_products[i].release == -1)) { sc->sc_chiptype = uplcom_products[i].chiptype; break; } } /* * check we found the device - attach should have ensured we * don't get here without matching device */ if (uplcom_products[i].vendor == 0) { printf("%s: didn't match\n", devname); ucom->sc_dying = 1; goto error; } #ifdef USB_DEBUG /* print the chip type */ if (sc->sc_chiptype == TYPE_PL2303X) { DPRINTF(("uplcom_attach: chiptype 2303X\n")); } else { DPRINTF(("uplcom_attach: chiptype 2303\n")); } #endif /* initialize endpoints */ ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; /* Move the device into the configured state. */ err = usbd_set_config_index(dev, UPLCOM_CONFIG_INDEX, 1); if (err) { printf("%s: failed to set configuration: %s\n", devname, usbd_errstr(err)); ucom->sc_dying = 1; goto error; } /* get the config descriptor */ cdesc = usbd_get_config_descriptor(ucom->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", device_get_nameunit(ucom->sc_dev)); ucom->sc_dying = 1; goto error; } /* get the (first/common) interface */ err = usbd_device2interface_handle(dev, UPLCOM_IFACE_INDEX, &ucom->sc_iface); if (err) { printf("%s: failed to get interface: %s\n", devname, usbd_errstr(err)); ucom->sc_dying = 1; goto error; } /* Find the interrupt endpoints */ id = usbd_get_interface_descriptor(ucom->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", device_get_nameunit(ucom->sc_dev), i); ucom->sc_dying = 1; goto error; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_intr_number = ed->bEndpointAddress; sc->sc_isize = UGETW(ed->wMaxPacketSize); } } if (sc->sc_intr_number == -1) { printf("%s: Could not find interrupt in\n", device_get_nameunit(ucom->sc_dev)); ucom->sc_dying = 1; goto error; } /* keep interface for interrupt */ sc->sc_intr_iface = ucom->sc_iface; /* * USB-RSAQ1 has two interface * * USB-RSAQ1 | USB-RSAQ2 * -----------------+----------------- * Interface 0 |Interface 0 * Interrupt(0x81) | Interrupt(0x81) * -----------------+ BulkIN(0x02) * Interface 1 | BulkOUT(0x83) * BulkIN(0x02) | * BulkOUT(0x83) | */ if (cdesc->bNumInterface == 2) { err = usbd_device2interface_handle(dev, UPLCOM_SECOND_IFACE_INDEX, &ucom->sc_iface); if (err) { printf("%s: failed to get second interface: %s\n", devname, usbd_errstr(err)); ucom->sc_dying = 1; goto error; } } /* Find the bulk{in,out} endpoints */ id = usbd_get_interface_descriptor(ucom->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", device_get_nameunit(ucom->sc_dev), i); ucom->sc_dying = 1; goto error; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { ucom->sc_bulkin_no = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { ucom->sc_bulkout_no = ed->bEndpointAddress; } } if (ucom->sc_bulkin_no == -1) { printf("%s: Could not find data bulk in\n", device_get_nameunit(ucom->sc_dev)); ucom->sc_dying = 1; goto error; } if (ucom->sc_bulkout_no == -1) { printf("%s: Could not find data bulk out\n", device_get_nameunit(ucom->sc_dev)); ucom->sc_dying = 1; goto error; } sc->sc_dtr = sc->sc_rts = -1; ucom->sc_parent = sc; ucom->sc_portno = UCOM_UNK_PORTNO; /* bulkin, bulkout set above */ ucom->sc_ibufsize = UPLCOMIBUFSIZE; ucom->sc_obufsize = UPLCOMOBUFSIZE; ucom->sc_ibufsizepad = UPLCOMIBUFSIZE; ucom->sc_opkthdrlen = 0; ucom->sc_callback = &uplcom_callback; err = uplcom_reset(sc); if (err) { printf("%s: reset failed: %s\n", device_get_nameunit(ucom->sc_dev), usbd_errstr(err)); ucom->sc_dying = 1; goto error; } DPRINTF(("uplcom: in = 0x%x, out = 0x%x, intr = 0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number)); TASK_INIT(&sc->sc_task, 0, uplcom_notify, sc); ucom_attach(&sc->sc_ucom); return 0; error: return ENXIO; }