void urio_attach(struct device *parent, struct device *self, void *aux) { struct urio_softc *sc = (struct urio_softc *)self; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->device; struct usbd_interface *iface; usbd_status err; usb_endpoint_descriptor_t *ed; u_int8_t epcount; int i; DPRINTFN(10,("urio_attach: sc=%p\n", sc)); err = usbd_set_config_no(dev, URIO_CONFIG_NO, 1); if (err) { printf("%s: setting config no failed\n", sc->sc_dev.dv_xname); return; } err = usbd_device2interface_handle(dev, URIO_IFACE_IDX, &iface); if (err) { printf("%s: getting interface handle failed\n", sc->sc_dev.dv_xname); return; } sc->sc_udev = dev; sc->sc_iface = iface; epcount = 0; (void)usbd_endpoint_count(iface, &epcount); sc->sc_in_addr = -1; sc->sc_out_addr = -1; for (i = 0; i < epcount; i++) { ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { printf("%s: couldn't get ep %d\n", sc->sc_dev.dv_xname, i); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->sc_in_addr = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->sc_out_addr = ed->bEndpointAddress; } } if (sc->sc_in_addr == -1 || sc->sc_out_addr == -1) { printf("%s: missing endpoint\n", sc->sc_dev.dv_xname); return; } DPRINTFN(10, ("urio_attach: %p\n", sc->sc_udev)); }
int ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) { struct usbd_interface *iface; usb_endpoint_descriptor_t *ed; int err; struct ugen_endpoint *sce; u_int8_t niface, nendpt, endptno, endpt; int dir; DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); err = usbd_interface_count(sc->sc_udev, &niface); if (err) return (err); if (ifaceidx < 0 || ifaceidx >= niface || usbd_iface_claimed(sc->sc_udev, ifaceidx)) return (USBD_INVAL); err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); if (err) return (err); err = usbd_endpoint_count(iface, &nendpt); if (err) return (err); for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; sce->sc = 0; sce->edesc = 0; sce->iface = 0; } /* change setting */ err = usbd_set_interface(iface, altno); if (err) goto out; err = usbd_endpoint_count(iface, &nendpt); if (err) goto out; out: for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; sce->sc = sc; sce->edesc = ed; sce->iface = iface; } return (err); }
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); }
int ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) { struct usbd_interface *iface; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; struct ugen_endpoint *sce; uint8_t endptno, endpt; int dir, err; DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); cdesc = usbd_get_config_descriptor(sc->sc_udev); if (ifaceidx < 0 || ifaceidx >= cdesc->bNumInterface || usbd_iface_claimed(sc->sc_udev, ifaceidx)) return (USBD_INVAL); err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); if (err) return (err); id = usbd_get_interface_descriptor(iface); for (endptno = 0; endptno < id->bNumEndpoints; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; sce->sc = 0; sce->edesc = 0; sce->iface = 0; } /* change setting */ err = usbd_set_interface(iface, altno); if (err) return (err); id = usbd_get_interface_descriptor(iface); for (endptno = 0; endptno < id->bNumEndpoints; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; sce->sc = sc; sce->edesc = ed; sce->iface = iface; } return (err); }
static int init_keyboard(ukbd_state_t *state, int *type, int flags) { usb_endpoint_descriptor_t *ed; usbd_status err; *type = KB_OTHER; state->ks_ifstate |= DISCONNECTED; ed = usbd_interface2endpoint_descriptor(state->ks_iface, 0); if (!ed) { kprintf("ukbd: could not read endpoint descriptor\n"); return EIO; } DPRINTFN(10,("ukbd:init_keyboard: \ bLength=%d bDescriptorType=%d bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d bInterval=%d\n", ed->bLength, ed->bDescriptorType, UE_GET_ADDR(ed->bEndpointAddress), UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? "in":"out", UE_GET_XFERTYPE(ed->bmAttributes), UGETW(ed->wMaxPacketSize), ed->bInterval)); if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN || UE_GET_XFERTYPE(ed->bmAttributes) != UE_INTERRUPT) { kprintf("ukbd: unexpected endpoint\n"); return EINVAL; } if ((usbd_get_quirks(state->ks_uaa->device)->uq_flags & UQ_NO_SET_PROTO) == 0) { err = usbd_set_protocol(state->ks_iface, 0); DPRINTFN(5, ("ukbd:init_keyboard: protocol set\n")); if (err) { kprintf("ukbd: set protocol failed\n"); return EIO; } } /* Ignore if SETIDLE fails since it is not crucial. */ usbd_set_idle(state->ks_iface, 0, 0); state->ks_ep_addr = ed->bEndpointAddress; state->ks_ifstate &= ~DISCONNECTED; return 0; }
static usbd_status open_in_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *, int)) { usbd_status err = USBD_NORMAL_COMPLETION; struct umidi_endpoint *ep = jack->endpoint; if (jack->opened) return USBD_IN_USE; jack->arg = arg; jack->u.in.intr = intr; jack->opened = 1; if (ep->num_open++==0 && UE_GET_DIR(ep->addr)==UE_DIR_IN) { err = start_input_transfer(ep); if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) { ep->num_open--; } } return err; }
void uftdi_attach(struct device *parent, struct device *self, void *aux) { struct uftdi_softc *sc = (struct uftdi_softc *)self; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->device; struct usbd_interface *iface; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devname = sc->sc_dev.dv_xname; int i; usbd_status err; struct ucom_attach_args uca; DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc)); sc->sc_udev = dev; if (uaa->iface == NULL) { /* Move the device into the configured state. */ err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1); if (err) { printf("%s: failed to set configuration, err=%s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); goto bad; } err = usbd_device2interface_handle(dev, UFTDI_IFACE_INDEX, &iface); if (err) { printf("%s: failed to get interface, err=%s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); goto bad; } } else iface = uaa->iface; id = usbd_get_interface_descriptor(iface); sc->sc_iface = iface; if (uaa->release < 0x0200) { sc->sc_type = UFTDI_TYPE_SIO; sc->sc_hdrlen = 1; } else if (uaa->release == 0x0700 || uaa->release == 0x0800) { sc->sc_type = UFTDI_TYPE_2232H; sc->sc_hdrlen = 0; } else { sc->sc_type = UFTDI_TYPE_8U232AM; sc->sc_hdrlen = 0; } uca.bulkin = uca.bulkout = -1; for (i = 0; i < id->bNumEndpoints; i++) { int addr, dir, attr; ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { printf("%s: could not read endpoint descriptor\n", devname); goto bad; } addr = ed->bEndpointAddress; dir = UE_GET_DIR(ed->bEndpointAddress); attr = ed->bmAttributes & UE_XFERTYPE; if (dir == UE_DIR_IN && attr == UE_BULK) { uca.bulkin = addr; uca.ibufsize = (UGETW(ed->wMaxPacketSize) > 0) ? UGETW(ed->wMaxPacketSize) : UFTDIIBUFSIZE; } else if (dir == UE_DIR_OUT && attr == UE_BULK) { uca.bulkout = addr; uca.obufsize = (UGETW(ed->wMaxPacketSize) > 0) ? UGETW(ed->wMaxPacketSize) : UFTDIOBUFSIZE; uca.obufsize-= sc->sc_hdrlen; } else { printf("%s: unexpected endpoint\n", devname); goto bad; } } if (uca.bulkin == -1) { printf("%s: Could not find data bulk in\n", sc->sc_dev.dv_xname); goto bad; } if (uca.bulkout == -1) { printf("%s: Could not find data bulk out\n", sc->sc_dev.dv_xname); goto bad; } if (uaa->iface == NULL) uca.portno = FTDI_PIT_SIOA; else uca.portno = FTDI_PIT_SIOA + id->bInterfaceNumber; /* bulkin, bulkout set above */ uca.ibufsizepad = uca.ibufsize; uca.opkthdrlen = sc->sc_hdrlen; uca.device = dev; uca.iface = iface; uca.methods = &uftdi_methods; uca.arg = sc; uca.info = NULL; DPRINTF(("uftdi: in=0x%x out=0x%x\n", uca.bulkin, uca.bulkout)); sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); return; bad: DPRINTF(("uftdi_attach: ATTACH ERROR\n")); usbd_deactivate(sc->sc_udev); }
void umct_attach(struct device *parent, struct device *self, void *aux) { struct umct_softc *sc = (struct umct_softc *)self; struct usb_attach_arg *uaa = aux; usbd_device_handle dev = uaa->device; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devname = sc->sc_dev.dv_xname; usbd_status err; int i; struct ucom_attach_args uca; sc->sc_udev = dev; sc->sc_product = uaa->product; DPRINTF(("\n\numct attach: sc=%p\n", sc)); /* initialize endpoints */ uca.bulkin = uca.bulkout = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; /* Move the device into the configured state. */ err = usbd_set_config_index(dev, UMCT_CONFIG_INDEX, 1); if (err) { printf("\n%s: failed to set configuration, err=%s\n", devname, usbd_errstr(err)); sc->sc_dying = 1; return; } /* get the config descriptor */ cdesc = usbd_get_config_descriptor(sc->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } /* get the interface */ err = usbd_device2interface_handle(dev, UMCT_IFACE_INDEX, &sc->sc_iface); if (err) { printf("\n%s: failed to get interface, err=%s\n", devname, usbd_errstr(err)); sc->sc_dying = 1; return; } /* Find the bulk{in,out} and interrupt endpoints */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); sc->sc_dying = 1; return; } /* * The Bulkin endpoint is marked as an interrupt. Since * we can't rely on the endpoint descriptor order, we'll * check the wMaxPacketSize field to differentiate. */ if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT && UGETW(ed->wMaxPacketSize) != 0x2) { uca.bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkout = ed->bEndpointAddress; } else 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 (uca.bulkin == -1) { printf("%s: Could not find data bulk in\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } if (uca.bulkout == -1) { printf("%s: Could not find data bulk out\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } if (sc->sc_intr_number== -1) { printf("%s: Could not find interrupt in\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } sc->sc_dtr = sc->sc_rts = 0; uca.portno = UCOM_UNK_PORTNO; /* bulkin, bulkout set above */ uca.ibufsize = UMCTIBUFSIZE; if (sc->sc_product == USB_PRODUCT_MCT_SITECOM_USB232) uca.obufsize = 16; /* device is broken */ else uca.obufsize = UMCTOBUFSIZE; uca.ibufsizepad = UMCTIBUFSIZE; uca.opkthdrlen = 0; uca.device = dev; uca.iface = sc->sc_iface; uca.methods = &umct_methods; uca.arg = sc; uca.info = NULL; umct_init(sc); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, &sc->sc_dev); DPRINTF(("umct: in=0x%x out=0x%x intr=0x%x\n", uca.bulkin, uca.bulkout, sc->sc_intr_number )); sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); }
static int atausb_attach(device_t dev) { struct atausb_softc *sc = device_get_softc(dev); struct usb_attach_arg *uaa = device_get_ivars(dev); usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usbd_device_handle udev; usb_device_request_t request; char devinfo[1024], *proto, *subclass; u_int8_t maxlun; int err, i; sc->dev = dev; usbd_devinfo(uaa->device, 0, devinfo); device_set_desc_copy(dev, devinfo); sc->bulkin = sc->bulkout = sc->bulkirq = -1; sc->bulkin_pipe = sc->bulkout_pipe= sc->bulkirq_pipe = NULL; sc->iface = uaa->iface; sc->ifaceno = uaa->ifaceno; sc->maxlun = 0; sc->timeout = 5000; sc->locked_ch = NULL; sc->restart_ch = NULL; spin_init(&sc->locked_mtx); id = usbd_get_interface_descriptor(sc->iface); switch (id->bInterfaceProtocol) { case UIPROTO_MASS_BBB: case UIPROTO_MASS_BBB_OLD: proto = "Bulk-Only"; break; case UIPROTO_MASS_CBI: proto = "CBI"; break; case UIPROTO_MASS_CBI_I: proto = "CBI with CCI"; break; default: proto = "Unknown"; } switch (id->bInterfaceSubClass) { case UISUBCLASS_RBC: subclass = "RBC"; break; case UISUBCLASS_QIC157: case UISUBCLASS_SFF8020I: case UISUBCLASS_SFF8070I: subclass = "ATAPI"; break; case UISUBCLASS_SCSI: subclass = "SCSI"; break; case UISUBCLASS_UFI: subclass = "UFI"; break; default: subclass = "Unknown"; } device_printf(dev, "using %s over %s\n", subclass, proto); if (strcmp(proto, "Bulk-Only") || (strcmp(subclass, "ATAPI") && strcmp(subclass, "SCSI"))) return ENXIO; for (i = 0 ; i < id->bNumEndpoints ; i++) { if (!(ed = usbd_interface2endpoint_descriptor(sc->iface, i))) { device_printf(sc->dev, "could not read endpoint descriptor\n"); return ENXIO; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { sc->bulkin = ed->bEndpointAddress; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { sc->bulkout = ed->bEndpointAddress; } if (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I && UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) { sc->bulkirq = ed->bEndpointAddress; } } /* check whether we found at least the endpoints we need */ if (!sc->bulkin || !sc->bulkout) { device_printf(sc->dev, "needed endpoints not found (%d,%d)\n", sc->bulkin, sc->bulkout); atausb_detach(dev); return ENXIO; } /* open the pipes */ if (usbd_open_pipe(sc->iface, sc->bulkout, USBD_EXCLUSIVE_USE, &sc->bulkout_pipe)) { device_printf(sc->dev, "cannot open bulkout pipe (%d)\n", sc->bulkout); atausb_detach(dev); return ENXIO; } if (usbd_open_pipe(sc->iface, sc->bulkin, USBD_EXCLUSIVE_USE, &sc->bulkin_pipe)) { device_printf(sc->dev, "cannot open bulkin pipe (%d)\n", sc->bulkin); atausb_detach(dev); return ENXIO; } if (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I) { if (usbd_open_pipe(sc->iface, sc->bulkirq, USBD_EXCLUSIVE_USE, &sc->bulkirq_pipe)) { device_printf(sc->dev, "cannot open bulkirq pipe (%d)\n", sc->bulkirq); atausb_detach(dev); return ENXIO; } } sc->state = ATAUSB_S_ATTACH; /* alloc needed number of transfer handles */ for (i = 0; i < ATAUSB_T_MAX; i++) { sc->transfer[i] = usbd_alloc_xfer(uaa->device); if (!sc->transfer[i]) { device_printf(sc->dev, "out of memory\n"); atausb_detach(dev); return ENXIO; } } /* driver is ready to process requests here */ sc->state = ATAUSB_S_IDLE; /* get number of devices so we can add matching channels */ usbd_interface2device_handle(sc->iface, &udev); request.bmRequestType = UT_READ_CLASS_INTERFACE; request.bRequest = 0xfe; /* GET_MAX_LUN; */ USETW(request.wValue, 0); USETW(request.wIndex, sc->ifaceno); USETW(request.wLength, sizeof(maxlun)); switch ((err = usbd_do_request(udev, &request, &maxlun))) { case USBD_NORMAL_COMPLETION: if (bootverbose) device_printf(sc->dev, "maxlun=%d\n", maxlun); sc->maxlun = maxlun; break; default: if (bootverbose) device_printf(sc->dev, "get maxlun not supported %s\n", usbd_errstr(err)); } /* ata channels are children to this USB control device */ for (i = 0; i <= sc->maxlun; i++) { /* XXX TGEN devclass_find_free_unit() implementation */ int freeunit = 2; while (freeunit < devclass_get_maxunit(ata_devclass) && devclass_get_device(ata_devclass, freeunit) != NULL) freeunit++; if (!device_add_child(sc->dev, "ata", freeunit)) { device_printf(sc->dev, "failed to attach ata child device\n"); atausb_detach(dev); return ENXIO; } } bus_generic_attach(sc->dev); return 0; }
/* * Attach the interface. Allocate softc structures, do ifmedia * setup and ethernet/BPF attach. */ void wi_usb_attach(struct device *parent, struct device *self, void *aux) { struct wi_usb_softc *sc = (struct wi_usb_softc *)self; struct usb_attach_arg *uaa = aux; /* int s; */ struct usbd_device *dev = uaa->device; struct usbd_interface *iface; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; DPRINTFN(5,(" : wi_usb_attach: sc=%p", sc)); err = usbd_set_config_no(dev, WI_USB_CONFIG_NO, 1); if (err) { printf("%s: setting config no failed\n", sc->wi_usb_dev.dv_xname); return; } /* XXX - any tasks? */ err = usbd_device2interface_handle(dev, WI_USB_IFACE_IDX, &iface); if (err) { printf("%s: getting interface handle failed\n", sc->wi_usb_dev.dv_xname); return; } /* XXX - flags? */ sc->wi_usb_udev = dev; sc->wi_usb_iface = iface; sc->wi_usb_product = uaa->product; sc->wi_usb_vendor = uaa->vendor; sc->sc_wi.wi_usb_cdata = sc; sc->sc_wi.wi_flags |= WI_FLAGS_BUS_USB; sc->wi_lock = 0; sc->wi_lockwait = 0; sc->wi_resetonce = 0; id = usbd_get_interface_descriptor(iface); /* Find endpoints. */ for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { printf("%s: couldn't get endpoint descriptor %d\n", sc->wi_usb_dev.dv_xname, i); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->wi_usb_ed[WI_USB_ENDPT_RX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->wi_usb_ed[WI_USB_ENDPT_TX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->wi_usb_ed[WI_USB_ENDPT_INTR] = ed->bEndpointAddress; } } sc->wi_usb_nummem = 0; /* attach wi device */ if (wi_usb_rx_list_init(sc)) { printf("%s: rx list init failed\n", sc->wi_usb_dev.dv_xname); return; } if (wi_usb_tx_list_init(sc)) { printf("%s: tx list init failed\n", sc->wi_usb_dev.dv_xname); return; } if (wi_usb_open_pipes(sc)){ printf("%s: open pipes failed\n", sc->wi_usb_dev.dv_xname); return; } sc->wi_usb_attached = 1; kthread_create_deferred(wi_usb_start_thread, sc); }
void smsc_attach(device_t parent, device_t self, void *aux) { struct smsc_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; usbd_device_handle dev = uaa->device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; struct mii_data *mii; struct ifnet *ifp; int err, s, i; uint32_t mac_h, mac_l; sc->sc_dev = self; sc->sc_udev = dev; aprint_naive("\n"); aprint_normal("\n"); devinfop = usbd_devinfo_alloc(sc->sc_udev, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); err = usbd_set_config_no(dev, SMSC_CONFIG_INDEX, 1); if (err) { aprint_error_dev(self, "failed to set configuration" ", err=%s\n", usbd_errstr(err)); return; } /* Setup the endpoints for the SMSC LAN95xx device(s) */ usb_init_task(&sc->sc_tick_task, smsc_tick_task, sc, 0); usb_init_task(&sc->sc_stop_task, (void (*)(void *))smsc_stop, sc, 0); mutex_init(&sc->sc_mii_lock, MUTEX_DEFAULT, IPL_NONE); err = usbd_device2interface_handle(dev, SMSC_IFACE_IDX, &sc->sc_iface); if (err) { aprint_error_dev(self, "getting interface handle failed\n"); return; } id = usbd_get_interface_descriptor(sc->sc_iface); if (sc->sc_udev->speed >= USB_SPEED_HIGH) sc->sc_bufsz = SMSC_MAX_BUFSZ; else sc->sc_bufsz = SMSC_MIN_BUFSZ; /* Find endpoints. */ for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (!ed) { aprint_error_dev(self, "couldn't get ep %d\n", i); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->sc_ed[SMSC_ENDPT_RX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->sc_ed[SMSC_ENDPT_TX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_ed[SMSC_ENDPT_INTR] = ed->bEndpointAddress; } } s = splnet(); ifp = &sc->sc_ec.ec_if; ifp->if_softc = sc; strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_init = smsc_init; ifp->if_ioctl = smsc_ioctl; ifp->if_start = smsc_start; ifp->if_stop = smsc_stop; #ifdef notyet /* * We can do TCPv4, and UDPv4 checksums in hardware. */ ifp->if_capabilities |= /*IFCAP_CSUM_TCPv4_Tx |*/ IFCAP_CSUM_TCPv4_Rx | /*IFCAP_CSUM_UDPv4_Tx |*/ IFCAP_CSUM_UDPv4_Rx; #endif sc->sc_ec.ec_capabilities = ETHERCAP_VLAN_MTU; /* Setup some of the basics */ sc->sc_phyno = 1; /* * Attempt to get the mac address, if an EEPROM is not attached this * will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC * address based on urandom. */ memset(sc->sc_enaddr, 0xff, ETHER_ADDR_LEN); prop_dictionary_t dict = device_properties(self); prop_data_t eaprop = prop_dictionary_get(dict, "mac-address"); if (eaprop != NULL) { KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA); KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN); memcpy(sc->sc_enaddr, prop_data_data_nocopy(eaprop), ETHER_ADDR_LEN); } else /* Check if there is already a MAC address in the register */ if ((smsc_read_reg(sc, SMSC_MAC_ADDRL, &mac_l) == 0) && (smsc_read_reg(sc, SMSC_MAC_ADDRH, &mac_h) == 0)) { sc->sc_enaddr[5] = (uint8_t)((mac_h >> 8) & 0xff); sc->sc_enaddr[4] = (uint8_t)((mac_h) & 0xff); sc->sc_enaddr[3] = (uint8_t)((mac_l >> 24) & 0xff); sc->sc_enaddr[2] = (uint8_t)((mac_l >> 16) & 0xff); sc->sc_enaddr[1] = (uint8_t)((mac_l >> 8) & 0xff); sc->sc_enaddr[0] = (uint8_t)((mac_l) & 0xff); }
void uslcom_attach(struct device *parent, struct device *self, void *aux) { struct uslcom_softc *sc = (struct uslcom_softc *)self; struct usb_attach_arg *uaa = aux; struct ucom_attach_args uca; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usbd_status error; int i; bzero(&uca, sizeof(uca)); sc->sc_udev = uaa->device; if (usbd_set_config_index(sc->sc_udev, USLCOM_CONFIG_NO, 1) != 0) { printf("%s: could not set configuration no\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } /* get the first interface handle */ error = usbd_device2interface_handle(sc->sc_udev, USLCOM_IFACE_NO, &sc->sc_iface); if (error != 0) { printf("%s: could not get interface handle\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } id = usbd_get_interface_descriptor(sc->sc_iface); uca.bulkin = uca.bulkout = -1; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor found for %d\n", sc->sc_dev.dv_xname, i); sc->sc_dying = 1; return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) uca.bulkin = ed->bEndpointAddress; else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) uca.bulkout = ed->bEndpointAddress; } if (uca.bulkin == -1 || uca.bulkout == -1) { printf("%s: missing endpoint\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } uca.ibufsize = USLCOMBUFSZ; uca.obufsize = USLCOMBUFSZ; uca.ibufsizepad = USLCOMBUFSZ; uca.opkthdrlen = 0; uca.device = sc->sc_udev; uca.iface = sc->sc_iface; uca.methods = &uslcom_methods; uca.arg = sc; uca.info = NULL; sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); }
static void udsir_attach(device_t parent, device_t self, void *aux) { struct udsir_softc *sc = device_private(self); struct usbif_attach_arg *uiaa = aux; struct usbd_device *dev = uiaa->uiaa_device; struct usbd_interface *iface = uiaa->uiaa_iface; char *devinfop; usb_endpoint_descriptor_t *ed; uint8_t epcount; int i; struct ir_attach_args ia; DPRINTFN(10, ("udsir_attach: sc=%p\n", sc)); sc->sc_dev = self; aprint_naive("\n"); aprint_normal("\n"); devinfop = usbd_devinfo_alloc(dev, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); sc->sc_udev = dev; sc->sc_iface = iface; epcount = 0; (void)usbd_endpoint_count(iface, &epcount); sc->sc_rd_addr = -1; sc->sc_wr_addr = -1; for (i = 0; i < epcount; i++) { ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { aprint_error_dev(self, "couldn't get ep %d\n", i); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_rd_addr = ed->bEndpointAddress; sc->sc_rd_maxpsz = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_wr_addr = ed->bEndpointAddress; sc->sc_wr_maxpsz = UGETW(ed->wMaxPacketSize); } } if (sc->sc_rd_addr == -1 || sc->sc_wr_addr == -1) { aprint_error_dev(self, "missing endpoint\n"); return; } DPRINTFN(10, ("udsir_attach: %p\n", sc->sc_udev)); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); ia.ia_type = IR_TYPE_IRFRAME; ia.ia_methods = &udsir_methods; ia.ia_handle = sc; sc->sc_child = config_found(self, &ia, ir_print); selinit(&sc->sc_rd_sel); selinit(&sc->sc_wr_sel); return; }
usbd_status umsm_umass_changemode(struct umsm_softc *sc) { #define UMASS_CMD_REZERO_UNIT 0x01 #define UMASS_CMD_START_STOP 0x1b #define UMASS_CMDPARAM_EJECT 0x02 #define UMASS_SERVICE_ACTION_OUT 0x9f usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; struct usbd_xfer *xfer; struct usbd_pipe *cmdpipe; usbd_status err; u_int32_t n; void *bufp; int target_ep, i; struct umass_bbb_cbw cbw; static int dCBWTag = 0x12345678; USETDW(cbw.dCBWSignature, CBWSIGNATURE); USETDW(cbw.dCBWTag, dCBWTag); cbw.bCBWLUN = 0; cbw.bCDBLength= 6; bzero(cbw.CBWCDB, sizeof(cbw.CBWCDB)); switch (sc->sc_flag) { case DEV_UMASS1: USETDW(cbw.dCBWDataTransferLength, 0x0); cbw.bCBWFlags = CBWFLAGS_OUT; cbw.CBWCDB[0] = UMASS_CMD_REZERO_UNIT; cbw.CBWCDB[1] = 0x0; /* target LUN: 0 */ break; case DEV_UMASS2: USETDW(cbw.dCBWDataTransferLength, 0x1); cbw.bCBWFlags = CBWFLAGS_IN; cbw.CBWCDB[0] = UMASS_CMD_REZERO_UNIT; cbw.CBWCDB[1] = 0x0; /* target LUN: 0 */ break; case DEV_UMASS3: /* longcheer */ USETDW(cbw.dCBWDataTransferLength, 0x80); cbw.bCBWFlags = CBWFLAGS_IN; cbw.CBWCDB[0] = 0x06; cbw.CBWCDB[1] = 0xf5; cbw.CBWCDB[2] = 0x04; cbw.CBWCDB[3] = 0x02; cbw.CBWCDB[4] = 0x52; cbw.CBWCDB[5] = 0x70; break; case DEV_UMASS4: USETDW(cbw.dCBWDataTransferLength, 0x0); cbw.bCBWFlags = CBWFLAGS_OUT; cbw.CBWCDB[0] = UMASS_CMD_START_STOP; cbw.CBWCDB[1] = 0x00; /* target LUN: 0 */ cbw.CBWCDB[4] = UMASS_CMDPARAM_EJECT; break; case DEV_UMASS5: cbw.bCBWFlags = CBWFLAGS_OUT; cbw.CBWCDB[0] = 0x11; cbw.CBWCDB[1] = 0x06; break; case DEV_UMASS6: /* ZTE */ USETDW(cbw.dCBWDataTransferLength, 0x20); cbw.bCBWFlags = CBWFLAGS_IN; cbw.bCDBLength= 12; cbw.CBWCDB[0] = 0x85; cbw.CBWCDB[1] = 0x01; cbw.CBWCDB[2] = 0x01; cbw.CBWCDB[3] = 0x01; cbw.CBWCDB[4] = 0x18; cbw.CBWCDB[5] = 0x01; cbw.CBWCDB[6] = 0x01; cbw.CBWCDB[7] = 0x01; cbw.CBWCDB[8] = 0x01; cbw.CBWCDB[9] = 0x01; break; case DEV_UMASS7: /* ZTE */ USETDW(cbw.dCBWDataTransferLength, 0xc0); cbw.bCBWFlags = CBWFLAGS_IN; cbw.CBWCDB[0] = UMASS_SERVICE_ACTION_OUT; cbw.CBWCDB[1] = 0x03; break; case DEV_UMASS8: USETDW(cbw.dCBWDataTransferLength, 0x0); cbw.bCBWFlags = CBWFLAGS_OUT; cbw.CBWCDB[0] = 0xf0; cbw.CBWCDB[1] = 0x01; cbw.CBWCDB[2] = 0x03; break; default: DPRINTF(("%s: unknown device type.\n", sc->sc_dev.dv_xname)); break; } /* get command endpoint address */ id = usbd_get_interface_descriptor(sc->sc_iface); for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { return (USBD_IOERROR); } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) target_ep = ed->bEndpointAddress; } /* open command endppoint */ err = usbd_open_pipe(sc->sc_iface, target_ep, USBD_EXCLUSIVE_USE, &cmdpipe); if (err) { DPRINTF(("%s: open pipe for modem change cmd failed: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err))); return (err); } xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == NULL) { usbd_close_pipe(cmdpipe); return (USBD_NOMEM); } else { bufp = usbd_alloc_buffer(xfer, UMASS_BBB_CBW_SIZE); if (bufp == NULL) err = USBD_NOMEM; else { n = UMASS_BBB_CBW_SIZE; memcpy(bufp, &cbw, UMASS_BBB_CBW_SIZE); usbd_setup_xfer(xfer, cmdpipe, 0, bufp, n, USBD_NO_COPY | USBD_SYNCHRONOUS, 0, NULL); err = usbd_transfer(xfer); if (err) { usbd_clear_endpoint_stall(cmdpipe); DPRINTF(("%s: send error:%s", __func__, usbd_errstr(err))); } } usbd_close_pipe(cmdpipe); usbd_free_buffer(xfer); usbd_free_xfer(xfer); } return (err); }
void umsm_attach(struct device *parent, struct device *self, void *aux) { struct umsm_softc *sc = (struct umsm_softc *)self; struct usb_attach_arg *uaa = aux; struct ucom_attach_args uca; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; bzero(&uca, sizeof(uca)); sc->sc_udev = uaa->device; sc->sc_iface = uaa->iface; sc->sc_flag = umsm_lookup(uaa->vendor, uaa->product)->umsm_flag; id = usbd_get_interface_descriptor(sc->sc_iface); /* * Some 3G modems have multiple interfaces and some of them * are umass class. Don't claim ownership in such case. */ if (id == NULL || id->bInterfaceClass == UICLASS_MASS) { /* * Some 3G modems require a special request to * enable their modem function. */ if ((sc->sc_flag & DEV_HUAWEI) && uaa->ifaceno == 0) { umsm_huawei_changemode(uaa->device); printf("%s: umass only mode. need to reattach\n", sc->sc_dev.dv_xname); } else if ((sc->sc_flag & DEV_TRUINSTALL) && uaa->ifaceno == 0) { umsm_truinstall_changemode(uaa->device); printf("%s: truinstall mode. need to reattach\n", sc->sc_dev.dv_xname); } else if ((sc->sc_flag & DEV_UMASS) && uaa->ifaceno == 0) { umsm_umass_changemode(sc); } /* * The device will reset its own bus from the device side * when its mode was changed, so just return. */ return; } sc->sc_iface_no = id->bInterfaceNumber; uca.bulkin = uca.bulkout = -1; sc->sc_intr_number = sc->sc_isize = -1; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor found for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); return; } 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); DPRINTF(("%s: find interrupt endpoint for %s\n", __func__, sc->sc_dev.dv_xname)); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) uca.bulkin = ed->bEndpointAddress; else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) uca.bulkout = ed->bEndpointAddress; } if (uca.bulkin == -1 || uca.bulkout == -1) { printf("%s: missing endpoint\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } sc->sc_dtr = sc->sc_rts = -1; /* We need to force size as some devices lie */ uca.ibufsize = UMSMBUFSZ; uca.obufsize = UMSMBUFSZ; uca.ibufsizepad = UMSMBUFSZ; uca.opkthdrlen = 0; uca.device = sc->sc_udev; uca.iface = sc->sc_iface; uca.methods = &umsm_methods; uca.arg = sc; uca.info = NULL; uca.portno = UCOM_UNK_PORTNO; sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); }
void ubsa_attach(struct device *parent, struct device *self, void *aux) { struct ubsa_softc *sc = (struct ubsa_softc *)self; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->device; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; const char *devname = sc->sc_dev.dv_xname; usbd_status err; struct ucom_attach_args uca; int i; sc->sc_udev = dev; /* * initialize rts, dtr variables to something * different from boolean 0, 1 */ sc->sc_dtr = -1; sc->sc_rts = -1; DPRINTF(("ubsa attach: sc = %p\n", sc)); /* initialize endpoints */ uca.bulkin = uca.bulkout = -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) { printf("%s: failed to set configuration: %s\n", devname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); goto error; } /* get the config descriptor */ cdesc = usbd_get_config_descriptor(sc->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", devname); usbd_deactivate(sc->sc_udev); goto error; } /* get the first interface */ err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX, &sc->sc_iface); if (err) { printf("%s: failed to get interface: %s\n", devname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); goto error; } /* Find the endpoints */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); 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) { uca.bulkin = ed->bEndpointAddress; uca.ibufsize = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkout = ed->bEndpointAddress; uca.obufsize = UGETW(ed->wMaxPacketSize); } } if (sc->sc_intr_number == -1) { printf("%s: Could not find interrupt in\n", devname); usbd_deactivate(sc->sc_udev); goto error; } if (uca.bulkin == -1) { printf("%s: Could not find data bulk in\n", devname); usbd_deactivate(sc->sc_udev); goto error; } if (uca.bulkout == -1) { printf("%s: Could not find data bulk out\n", devname); usbd_deactivate(sc->sc_udev); goto error; } uca.portno = UCOM_UNK_PORTNO; /* bulkin, bulkout set above */ uca.ibufsizepad = uca.ibufsize; uca.opkthdrlen = 0; uca.device = dev; uca.iface = sc->sc_iface; uca.methods = &ubsa_methods; uca.arg = sc; uca.info = NULL; DPRINTF(("ubsa: in = 0x%x, out = 0x%x, intr = 0x%x\n", uca.bulkin, uca.bulkout, sc->sc_intr_number)); sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); error: return; }
static usbd_status alloc_all_endpoints_genuine(struct umidi_softc *sc) { usb_interface_descriptor_t *interface_desc; usb_config_descriptor_t *config_desc; usb_descriptor_t *desc; int num_ep; size_t remain, descsize; struct umidi_endpoint *p, *q, *lowest, *endep, tmpep; int epaddr; interface_desc = usbd_get_interface_descriptor(sc->sc_iface); num_ep = interface_desc->bNumEndpoints; sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint) * num_ep, M_USBDEV, M_WAITOK); if (!p) return USBD_NOMEM; sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0; epaddr = -1; /* get the list of endpoints for midi stream */ config_desc = usbd_get_config_descriptor(sc->sc_udev); desc = (usb_descriptor_t *) config_desc; remain = (size_t)UGETW(config_desc->wTotalLength); while (remain>=sizeof(usb_descriptor_t)) { descsize = desc->bLength; if (descsize>remain || descsize==0) break; if (desc->bDescriptorType==UDESC_ENDPOINT && remain>=USB_ENDPOINT_DESCRIPTOR_SIZE && UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) { epaddr = TO_EPD(desc)->bEndpointAddress; } else if (desc->bDescriptorType==UDESC_CS_ENDPOINT && remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE && epaddr!=-1) { if (num_ep>0) { num_ep--; p->sc = sc; p->addr = epaddr; p->num_jacks = TO_CSEPD(desc)->bNumEmbMIDIJack; if (UE_GET_DIR(epaddr)==UE_DIR_OUT) { sc->sc_out_num_endpoints++; sc->sc_out_num_jacks += p->num_jacks; } else { sc->sc_in_num_endpoints++; sc->sc_in_num_jacks += p->num_jacks; } p++; } } else epaddr = -1; desc = NEXT_D(desc); remain-=descsize; } /* sort endpoints */ num_ep = sc->sc_out_num_endpoints + sc->sc_in_num_endpoints; p = sc->sc_endpoints; endep = p + num_ep; while (p<endep) { lowest = p; for (q=p+1; q<endep; q++) { if ((UE_GET_DIR(lowest->addr)==UE_DIR_IN && UE_GET_DIR(q->addr)==UE_DIR_OUT) || ((UE_GET_DIR(lowest->addr)== UE_GET_DIR(q->addr)) && (UE_GET_ADDR(lowest->addr)> UE_GET_ADDR(q->addr)))) lowest = q; } if (lowest != p) { memcpy((void *)&tmpep, (void *)p, sizeof(tmpep)); memcpy((void *)p, (void *)lowest, sizeof(tmpep)); memcpy((void *)lowest, (void *)&tmpep, sizeof(tmpep)); } p->num_open = 0; p++; } sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL; sc->sc_in_ep = sc->sc_in_num_endpoints ? sc->sc_endpoints+sc->sc_out_num_endpoints : NULL; return USBD_NORMAL_COMPLETION; }
static usbd_status alloc_all_endpoints_yamaha(struct umidi_softc *sc) { /* This driver currently supports max 1in/1out bulk endpoints */ usb_descriptor_t *desc; umidi_cs_descriptor_t *udesc; usb_endpoint_descriptor_t *epd; int out_addr, in_addr, i; int dir; size_t remain, descsize; sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; out_addr = in_addr = 0; /* detect endpoints */ desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface)); for (i=(int)TO_IFD(desc)->bNumEndpoints-1; i>=0; i--) { epd = usbd_interface2endpoint_descriptor(sc->sc_iface, i); KASSERT(epd != NULL); if (UE_GET_XFERTYPE(epd->bmAttributes) == UE_BULK) { dir = UE_GET_DIR(epd->bEndpointAddress); if (dir==UE_DIR_OUT && !out_addr) out_addr = epd->bEndpointAddress; else if (dir==UE_DIR_IN && !in_addr) in_addr = epd->bEndpointAddress; } } udesc = (umidi_cs_descriptor_t *)NEXT_D(desc); /* count jacks */ if (!(udesc->bDescriptorType==UDESC_CS_INTERFACE && udesc->bDescriptorSubtype==UMIDI_MS_HEADER)) return USBD_INVAL; remain = (size_t)UGETW(TO_CSIFD(udesc)->wTotalLength) - (size_t)udesc->bLength; udesc = (umidi_cs_descriptor_t *)NEXT_D(udesc); while (remain>=sizeof(usb_descriptor_t)) { descsize = udesc->bLength; if (descsize>remain || descsize==0) break; if (udesc->bDescriptorType==UDESC_CS_INTERFACE && remain>=UMIDI_JACK_DESCRIPTOR_SIZE) { if (udesc->bDescriptorSubtype==UMIDI_OUT_JACK) sc->sc_out_num_jacks++; else if (udesc->bDescriptorSubtype==UMIDI_IN_JACK) sc->sc_in_num_jacks++; } udesc = (umidi_cs_descriptor_t *)NEXT_D(udesc); remain-=descsize; } /* validate some parameters */ if (sc->sc_out_num_jacks>UMIDI_MAX_EPJACKS) sc->sc_out_num_jacks = UMIDI_MAX_EPJACKS; if (sc->sc_in_num_jacks>UMIDI_MAX_EPJACKS) sc->sc_in_num_jacks = UMIDI_MAX_EPJACKS; if (sc->sc_out_num_jacks && out_addr) { sc->sc_out_num_endpoints = 1; } else { sc->sc_out_num_endpoints = 0; sc->sc_out_num_jacks = 0; } if (sc->sc_in_num_jacks && in_addr) { sc->sc_in_num_endpoints = 1; } else { sc->sc_in_num_endpoints = 0; sc->sc_in_num_jacks = 0; } sc->sc_endpoints = malloc(sizeof(struct umidi_endpoint)* (sc->sc_out_num_endpoints+ sc->sc_in_num_endpoints), M_USBDEV, M_WAITOK); if (!sc->sc_endpoints) return USBD_NOMEM; if (sc->sc_out_num_endpoints) { sc->sc_out_ep = sc->sc_endpoints; sc->sc_out_ep->sc = sc; sc->sc_out_ep->addr = out_addr; sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks; sc->sc_out_ep->num_open = 0; memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks)); } else sc->sc_out_ep = NULL; if (sc->sc_in_num_endpoints) { sc->sc_in_ep = sc->sc_endpoints+sc->sc_out_num_endpoints; sc->sc_in_ep->sc = sc; sc->sc_in_ep->addr = in_addr; sc->sc_in_ep->num_jacks = sc->sc_in_num_jacks; sc->sc_in_ep->num_open = 0; memset(sc->sc_in_ep->jacks, 0, sizeof(sc->sc_in_ep->jacks)); } else sc->sc_in_ep = NULL; return USBD_NORMAL_COMPLETION; }
static usbd_status alloc_all_endpoints_fixed_ep(struct umidi_softc *sc) { usbd_status err; const struct umq_fixed_ep_desc *fp; struct umidi_endpoint *ep; usb_endpoint_descriptor_t *epd; int i; fp = umidi_get_quirk_data_from_type(sc->sc_quirk, UMQ_TYPE_FIXED_EP); sc->sc_out_num_jacks = 0; sc->sc_in_num_jacks = 0; sc->sc_out_num_endpoints = fp->num_out_ep; sc->sc_in_num_endpoints = fp->num_in_ep; sc->sc_endpoints = malloc(sizeof(*sc->sc_out_ep)* (sc->sc_out_num_endpoints+ sc->sc_in_num_endpoints), M_USBDEV, M_WAITOK); if (!sc->sc_endpoints) { return USBD_NOMEM; } sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL; sc->sc_in_ep = sc->sc_in_num_endpoints ? sc->sc_endpoints+sc->sc_out_num_endpoints : NULL; ep = &sc->sc_out_ep[0]; for (i=0; i<sc->sc_out_num_endpoints; i++) { epd = usbd_interface2endpoint_descriptor( sc->sc_iface, fp->out_ep[i].ep); if (!epd) { aprint_error_dev(sc->sc_dev, "cannot get endpoint descriptor(out:%d)\n", fp->out_ep[i].ep); err = USBD_INVAL; goto error; } if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK || UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_OUT) { aprint_error_dev(sc->sc_dev, "illegal endpoint(out:%d)\n", fp->out_ep[i].ep); err = USBD_INVAL; goto error; } ep->sc = sc; ep->addr = epd->bEndpointAddress; ep->num_jacks = fp->out_ep[i].num_jacks; sc->sc_out_num_jacks += fp->out_ep[i].num_jacks; ep->num_open = 0; memset(ep->jacks, 0, sizeof(ep->jacks)); ep++; } ep = &sc->sc_in_ep[0]; for (i=0; i<sc->sc_in_num_endpoints; i++) { epd = usbd_interface2endpoint_descriptor( sc->sc_iface, fp->in_ep[i].ep); if (!epd) { aprint_error_dev(sc->sc_dev, "cannot get endpoint descriptor(in:%d)\n", fp->in_ep[i].ep); err = USBD_INVAL; goto error; } /* * MIDISPORT_2X4 inputs on an interrupt rather than a bulk * endpoint. The existing input logic in this driver seems * to work successfully if we just stop treating an interrupt * endpoint as illegal (or the in_progress status we get on * the initial transfer). It does not seem necessary to * actually use the interrupt flavor of alloc_pipe or make * other serious rearrangements of logic. I like that. */ switch ( UE_GET_XFERTYPE(epd->bmAttributes) ) { case UE_BULK: case UE_INTERRUPT: if ( UE_DIR_IN == UE_GET_DIR(epd->bEndpointAddress) ) break; /*FALLTHROUGH*/ default: aprint_error_dev(sc->sc_dev, "illegal endpoint(in:%d)\n", fp->in_ep[i].ep); err = USBD_INVAL; goto error; } ep->sc = sc; ep->addr = epd->bEndpointAddress; ep->num_jacks = fp->in_ep[i].num_jacks; sc->sc_in_num_jacks += fp->in_ep[i].num_jacks; ep->num_open = 0; memset(ep->jacks, 0, sizeof(ep->jacks)); ep++; } return USBD_NORMAL_COMPLETION; error: free(sc->sc_endpoints, M_USBDEV); sc->sc_endpoints = NULL; return err; }
static int moscom_attach(device_t self) { struct moscom_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; usbd_status error; int i; bzero(sc, sizeof (struct moscom_softc)); ucom = &sc->sc_ucom; ucom->sc_dev = self; ucom->sc_udev = uaa->device; ucom->sc_iface = uaa->iface; if (usbd_set_config_index(ucom->sc_udev, MOSCOM_CONFIG_NO, 1) != 0) { device_printf(ucom->sc_dev, "could not set configuration no\n"); ucom->sc_dying = 1; return ENXIO; } /* get the first interface handle */ error = usbd_device2interface_handle(ucom->sc_udev, MOSCOM_IFACE_NO, &ucom->sc_iface); if (error != 0) { device_printf(ucom->sc_dev, "could not get interface handle\n"); ucom->sc_dying = 1; return ENXIO; } id = usbd_get_interface_descriptor(ucom->sc_iface); 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); ucom->sc_dying = 1; return ENXIO; } 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"); ucom->sc_dying = 1; return ENXIO; } ucom->sc_parent = sc; ucom->sc_portno = UCOM_UNK_PORTNO; ucom->sc_ibufsize = MOSCOMBUFSZ; ucom->sc_obufsize = MOSCOMBUFSZ; ucom->sc_ibufsizepad = MOSCOMBUFSZ; ucom->sc_opkthdrlen = 0; ucom->sc_callback = &moscom_callback; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, ucom->sc_udev, ucom->sc_dev); return 0; }
void smsc_attach(struct device *parent, struct device *self, void *aux) { struct smsc_softc *sc = (struct smsc_softc *)self; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; struct mii_data *mii; struct ifnet *ifp; int err, s, i; uint32_t mac_h, mac_l; sc->sc_udev = dev; err = usbd_set_config_no(dev, SMSC_CONFIG_INDEX, 1); /* Setup the endpoints for the SMSC LAN95xx device(s) */ usb_init_task(&sc->sc_tick_task, smsc_tick_task, sc, USB_TASK_TYPE_GENERIC); rw_init(&sc->sc_mii_lock, "smscmii"); usb_init_task(&sc->sc_stop_task, (void (*)(void *))smsc_stop, sc, USB_TASK_TYPE_GENERIC); err = usbd_device2interface_handle(dev, SMSC_IFACE_IDX, &sc->sc_iface); if (err) { printf("%s: getting interface handle failed\n", sc->sc_dev.dv_xname); return; } id = usbd_get_interface_descriptor(sc->sc_iface); if (sc->sc_udev->speed >= USB_SPEED_HIGH) sc->sc_bufsz = SMSC_MAX_BUFSZ; else sc->sc_bufsz = SMSC_MIN_BUFSZ; /* Find endpoints. */ for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (!ed) { printf("%s: couldn't get ep %d\n", sc->sc_dev.dv_xname, i); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->sc_ed[SMSC_ENDPT_RX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->sc_ed[SMSC_ENDPT_TX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_ed[SMSC_ENDPT_INTR] = ed->bEndpointAddress; } } s = splnet(); ifp = &sc->sc_ac.ac_if; ifp->if_softc = sc; strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = smsc_ioctl; ifp->if_start = smsc_start; ifp->if_capabilities = IFCAP_VLAN_MTU; /* Setup some of the basics */ sc->sc_phyno = 1; /* * Attempt to get the mac address, if an EEPROM is not attached this * will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC * address based on urandom. */ memset(sc->sc_ac.ac_enaddr, 0xff, ETHER_ADDR_LEN); /* Check if there is already a MAC address in the register */ if ((smsc_read_reg(sc, SMSC_MAC_ADDRL, &mac_l) == 0) && (smsc_read_reg(sc, SMSC_MAC_ADDRH, &mac_h) == 0)) { sc->sc_ac.ac_enaddr[5] = (uint8_t)((mac_h >> 8) & 0xff); sc->sc_ac.ac_enaddr[4] = (uint8_t)((mac_h) & 0xff); sc->sc_ac.ac_enaddr[3] = (uint8_t)((mac_l >> 24) & 0xff); sc->sc_ac.ac_enaddr[2] = (uint8_t)((mac_l >> 16) & 0xff); sc->sc_ac.ac_enaddr[1] = (uint8_t)((mac_l >> 8) & 0xff); sc->sc_ac.ac_enaddr[0] = (uint8_t)((mac_l) & 0xff); }
/* * Attach the interface. */ static int lgue_attach(device_t dev) { struct lgue_softc *sc; struct usb_attach_arg *uaa; struct ifnet *ifp; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; u_char eaddr[ETHER_ADDR_LEN]; usbd_status err; sc = device_get_softc(dev); uaa = device_get_ivars(dev); sc->lgue_ctl_iface = uaa->iface; sc->lgue_udev = uaa->device; /* It has only config but in case... */ if (usbd_set_config_no(sc->lgue_udev, LGUE_CONFIG_NO, 0)) { device_printf(dev, "setting config no %d failed\n", LGUE_CONFIG_NO); return(ENXIO); } /* Get control and data intefaces */ id = usbd_get_interface_descriptor(uaa->iface); sc->lgue_ctl_iface_no = id->bInterfaceNumber; sc->lgue_data_iface_no = lgue_get_data_iface_no(sc->lgue_udev, id); if (sc->lgue_data_iface_no == -1) { device_printf(dev, "no data interface number\n"); goto bad; } /* Claim data interface */ 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 == sc->lgue_data_iface_no) { err = usbd_set_interface(uaa->ifaces[i], LGUE_ALTERNATE_SETTING); if ( err != USBD_NORMAL_COMPLETION) { device_printf(dev, "no alternate data interface. err:%s\n", usbd_errstr(err)); goto bad; } sc->lgue_data_iface = uaa->ifaces[i]; uaa->ifaces[i] = NULL; } } } if (sc->lgue_data_iface == NULL) { device_printf(dev, "no data interface\n"); goto bad; } /* Find data interface endpoints */ id = usbd_get_interface_descriptor(sc->lgue_data_iface); sc->lgue_ed[LGUE_ENDPT_RX] = sc->lgue_ed[LGUE_ENDPT_TX] = -1; for (i = 0; i < id->bNumEndpoints; ++i) { ed = usbd_interface2endpoint_descriptor(sc->lgue_data_iface, i); if (!ed) { device_printf(dev, "couldn't get endpoint descriptor %d\n", i); goto bad; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->lgue_ed[LGUE_ENDPT_RX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->lgue_ed[LGUE_ENDPT_TX] = ed->bEndpointAddress; } } if (sc->lgue_ed[LGUE_ENDPT_RX] == -1) { device_printf(dev, "couldn't find data bilk in\n"); goto bad; } if (sc->lgue_ed[LGUE_ENDPT_TX] == -1) { device_printf(dev, "couldn't find data bilk out\n"); goto bad; } /* Find control interface endpoint */ id = usbd_get_interface_descriptor(sc->lgue_ctl_iface); sc->lgue_ed[LGUE_ENDPT_INTR] = -1; for (i = 0; i < id->bNumEndpoints; ++i) { ed = usbd_interface2endpoint_descriptor(sc->lgue_ctl_iface, i); if (!ed) { device_printf(dev, "couldn't get endpoint descriptor %d\n", i); goto bad; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->lgue_ed[LGUE_ENDPT_INTR] = ed->bEndpointAddress; } } if (sc->lgue_ed[LGUE_ENDPT_INTR] == -1) { device_printf(dev, "couldn't find interrupt bilk in\n"); goto bad; } /* Create interface */ ifp = &sc->lgue_arpcom.ac_if; ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); lgue_getmac(sc, eaddr); ifp->if_mtu = lgue_getmtu(sc); ifp->if_data.ifi_mtu = ifp->if_mtu; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_baudrate = 10000000; ifp->if_ioctl = lgue_ioctl; ifp->if_start = lgue_start; ifp->if_watchdog = lgue_watchdog; ifp->if_init = lgue_init; ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); ifq_set_ready(&ifp->if_snd); /* Call attach routine */ ether_ifattach(ifp, eaddr, NULL); usb_register_netisr(); sc->lgue_dying = 0; return(0); bad: return(ENXIO); }
void kue_attachhook(void *xsc) { struct kue_softc *sc = xsc; int s; struct ifnet *ifp; usbd_device_handle dev = sc->kue_udev; usbd_interface_handle iface; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; /* Load the firmware into the NIC. */ if (kue_load_fw(sc)) { printf("%s: loading firmware failed\n", sc->kue_dev.dv_xname); return; } err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &iface); if (err) { printf("%s: getting interface handle failed\n", sc->kue_dev.dv_xname); return; } sc->kue_iface = iface; id = usbd_get_interface_descriptor(iface); /* Find endpoints. */ for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { printf("%s: couldn't get ep %d\n", sc->kue_dev.dv_xname, i); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress; } } if (sc->kue_ed[KUE_ENDPT_RX] == 0 || sc->kue_ed[KUE_ENDPT_TX] == 0) { printf("%s: missing endpoint\n", sc->kue_dev.dv_xname); return; } /* Read ethernet descriptor */ err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR, 0, &sc->kue_desc, sizeof(sc->kue_desc)); if (err) { printf("%s: could not read Ethernet descriptor\n", sc->kue_dev.dv_xname); return; } sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, M_USBDEV, M_NOWAIT); if (sc->kue_mcfilters == NULL) { printf("%s: no memory for multicast filter buffer\n", sc->kue_dev.dv_xname); return; } s = splnet(); /* * A KLSI chip was detected. Inform the world. */ printf("%s: address %s\n", sc->kue_dev.dv_xname, ether_sprintf(sc->kue_desc.kue_macaddr)); bcopy(sc->kue_desc.kue_macaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); /* Initialize interface info.*/ ifp = GET_IFP(sc); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = kue_ioctl; ifp->if_start = kue_start; ifp->if_watchdog = kue_watchdog; strlcpy(ifp->if_xname, sc->kue_dev.dv_xname, IFNAMSIZ); IFQ_SET_READY(&ifp->if_snd); /* Attach the interface. */ if_attach(ifp); ether_ifattach(ifp); sc->kue_attached = 1; splx(s); }
void uftdi_attach(device_t parent, device_t self, void *aux) { struct uftdi_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; usbd_device_handle dev = uaa->device; usbd_interface_handle iface; usb_device_descriptor_t *ddesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; const char *devname = device_xname(self); int i,idx; usbd_status err; struct ucom_attach_args uca; DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc)); aprint_naive("\n"); aprint_normal("\n"); devinfop = usbd_devinfo_alloc(dev, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); /* Move the device into the configured state. */ err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1); if (err) { aprint_error("\n%s: failed to set configuration, err=%s\n", devname, usbd_errstr(err)); goto bad; } sc->sc_dev = self; sc->sc_udev = dev; sc->sc_numports = 1; sc->sc_type = UFTDI_TYPE_8U232AM; /* most devices are post-8U232AM */ sc->sc_hdrlen = 0; if (uaa->vendor == USB_VENDOR_FTDI && uaa->product == USB_PRODUCT_FTDI_SERIAL_8U100AX) { sc->sc_type = UFTDI_TYPE_SIO; sc->sc_hdrlen = 1; } ddesc = usbd_get_device_descriptor(dev); sc->sc_chiptype = UGETW(ddesc->bcdDevice); switch (sc->sc_chiptype) { case 0x500: /* 2232D */ case 0x700: /* 2232H */ sc->sc_numports = 2; break; case 0x800: /* 4232H */ sc->sc_numports = 4; break; case 0x200: /* 232/245AM */ case 0x400: /* 232/245BL */ case 0x600: /* 232/245R */ default: break; } for (idx = UFTDI_IFACE_INDEX; idx < sc->sc_numports; idx++) { err = usbd_device2interface_handle(dev, idx, &iface); if (err) { aprint_error( "\n%s: failed to get interface idx=%d, err=%s\n", devname, idx, usbd_errstr(err)); goto bad; } id = usbd_get_interface_descriptor(iface); sc->sc_iface[idx] = iface; uca.bulkin = uca.bulkout = -1; uca.ibufsize = uca.obufsize = 0; for (i = 0; i < id->bNumEndpoints; i++) { int addr, dir, attr; ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { aprint_error_dev(self, "could not read endpoint descriptor: %s\n", usbd_errstr(err)); goto bad; } addr = ed->bEndpointAddress; dir = UE_GET_DIR(ed->bEndpointAddress); attr = ed->bmAttributes & UE_XFERTYPE; if (dir == UE_DIR_IN && attr == UE_BULK) { uca.bulkin = addr; uca.ibufsize = UGETW(ed->wMaxPacketSize); if (uca.ibufsize >= UFTDI_MAX_IBUFSIZE) uca.ibufsize = UFTDI_MAX_IBUFSIZE; } else if (dir == UE_DIR_OUT && attr == UE_BULK) { uca.bulkout = addr; uca.obufsize = UGETW(ed->wMaxPacketSize) - sc->sc_hdrlen; if (uca.obufsize >= UFTDI_MAX_OBUFSIZE) uca.obufsize = UFTDI_MAX_OBUFSIZE; /* Limit length if we have a 6-bit header. */ if ((sc->sc_hdrlen > 0) && (uca.obufsize > UFTDIOBUFSIZE)) uca.obufsize = UFTDIOBUFSIZE; } else { aprint_error_dev(self, "unexpected endpoint\n"); goto bad; } } if (uca.bulkin == -1) { aprint_error_dev(self, "Could not find data bulk in\n"); goto bad; } if (uca.bulkout == -1) { aprint_error_dev(self, "Could not find data bulk out\n"); goto bad; } uca.portno = FTDI_PIT_SIOA + idx; /* bulkin, bulkout set above */ if (uca.ibufsize == 0) uca.ibufsize = UFTDIIBUFSIZE; uca.ibufsizepad = uca.ibufsize; if (uca.obufsize == 0) uca.obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen; uca.opkthdrlen = sc->sc_hdrlen; uca.device = dev; uca.iface = iface; uca.methods = &uftdi_methods; uca.arg = sc; uca.info = NULL; DPRINTF(("uftdi: in=0x%x out=0x%x isize=0x%x osize=0x%x\n", uca.bulkin, uca.bulkout, uca.ibufsize, uca.obufsize)); sc->sc_subdev[idx] = config_found_sm_loc(self, "ucombus", NULL, &uca, ucomprint, ucomsubmatch); } usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); return; bad: DPRINTF(("uftdi_attach: ATTACH ERROR\n")); sc->sc_dying = 1; return; }
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; }
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; }
void uts_attach(struct device *parent, struct device *self, void *aux) { struct uts_softc *sc = (struct uts_softc *)self; struct usb_attach_arg *uaa = aux; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; struct wsmousedev_attach_args a; int i; sc->sc_udev = uaa->device; sc->sc_product = uaa->product; sc->sc_vendor = uaa->vendor; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; sc->sc_enabled = sc->sc_isize = 0; /* Copy the default scalue values to each softc */ bcopy(&def_scale, &sc->sc_tsscale, sizeof(sc->sc_tsscale)); /* Move the device into the configured state. */ if (usbd_set_config_index(uaa->device, UTS_CONFIG_INDEX, 1) != 0) { printf("%s: could not set configuartion no\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } /* get the config descriptor */ cdesc = usbd_get_config_descriptor(sc->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } /* get the interface */ if (usbd_device2interface_handle(uaa->device, 0, &sc->sc_iface) != 0) { printf("%s: failed to get interface\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } /* Find the interrupt endpoint */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); sc->sc_dying = 1; return; } 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", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } a.accessops = &uts_accessops; a.accesscookie = sc; sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint); }
static void usbd_non_isoc_callback(struct usb_xfer *xfer, usb_error_t error) { irp *ip; struct ndis_softc *sc = usbd_xfer_softc(xfer); struct ndisusb_ep *ne = usbd_xfer_get_priv(xfer); struct ndisusb_xfer *nx; struct usbd_urb_bulk_or_intr_transfer *ubi; struct usb_page_cache *pc; uint8_t irql; uint32_t len; union usbd_urb *urb; usb_endpoint_descriptor_t *ep; int actlen, sumlen; usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: nx = usbd_aq_getfirst(sc, ne); pc = usbd_xfer_get_frame(xfer, 0); if (nx == NULL) return; /* copy in data with regard to the URB */ if (ne->ne_dirin != 0) usbd_copy_out(pc, 0, nx->nx_urbbuf, actlen); nx->nx_urbbuf += actlen; nx->nx_urbactlen += actlen; nx->nx_urblen -= actlen; /* check for short transfer */ if (actlen < sumlen) nx->nx_urblen = 0; else { /* check remainder */ if (nx->nx_urblen > 0) { KeAcquireSpinLock(&ne->ne_lock, &irql); InsertHeadList((&ne->ne_active), (&nx->nx_next)); KeReleaseSpinLock(&ne->ne_lock, irql); ip = nx->nx_priv; urb = usbd_geturb(ip); ubi = &urb->uu_bulkintr; ep = ubi->ubi_epdesc; goto extra; } } usbd_xfer_complete(sc, ne, nx, ((actlen < sumlen) && (nx->nx_shortxfer == 0)) ? USB_ERR_SHORT_XFER : USB_ERR_NORMAL_COMPLETION); /* fall through */ case USB_ST_SETUP: next: /* get next transfer */ KeAcquireSpinLock(&ne->ne_lock, &irql); if (IsListEmpty(&ne->ne_pending)) { KeReleaseSpinLock(&ne->ne_lock, irql); return; } nx = CONTAINING_RECORD(ne->ne_pending.nle_flink, struct ndisusb_xfer, nx_next); RemoveEntryList(&nx->nx_next); /* add a entry to the active queue's tail. */ InsertTailList((&ne->ne_active), (&nx->nx_next)); KeReleaseSpinLock(&ne->ne_lock, irql); ip = nx->nx_priv; urb = usbd_geturb(ip); ubi = &urb->uu_bulkintr; ep = ubi->ubi_epdesc; nx->nx_urbbuf = ubi->ubi_trans_buf; nx->nx_urbactlen = 0; nx->nx_urblen = ubi->ubi_trans_buflen; nx->nx_shortxfer = (ubi->ubi_trans_flags & USBD_SHORT_TRANSFER_OK) ? 1 : 0; extra: len = MIN(usbd_xfer_max_len(xfer), nx->nx_urblen); pc = usbd_xfer_get_frame(xfer, 0); if (UE_GET_DIR(ep->bEndpointAddress) == UE_DIR_OUT) usbd_copy_in(pc, 0, nx->nx_urbbuf, len); usbd_xfer_set_frame_len(xfer, 0, len); usbd_xfer_set_frames(xfer, 1); usbd_transfer_submit(xfer); break; default: nx = usbd_aq_getfirst(sc, ne); if (nx == NULL) return; if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); device_printf(sc->ndis_dev, "usb xfer warning (%s)\n", usbd_errstr(error)); } usbd_xfer_complete(sc, ne, nx, error); if (error != USB_ERR_CANCELLED) goto next; break; } }
void uscanner_attach(device_t parent, device_t self, void *aux) { struct uscanner_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; usb_interface_descriptor_t *id = 0; usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL; char *devinfop; int i; usbd_status err; sc->sc_dev = self; aprint_naive("\n"); aprint_normal("\n"); devinfop = usbd_devinfo_alloc(uaa->device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags; sc->sc_udev = uaa->device; err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */ if (err) { aprint_error_dev(self, "failed to set configuration" ", err=%s\n", usbd_errstr(err)); sc->sc_dying = 1; return; } /* XXX We only check the first interface */ err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface); if (!err && sc->sc_iface) id = usbd_get_interface_descriptor(sc->sc_iface); if (err || id == 0) { aprint_error_dev(self, "could not get interface descriptor, err=%d,id=%p\n", err, id); sc->sc_dying = 1; return; } /* Find the two first bulk endpoints */ for (i = 0 ; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == 0) { aprint_error_dev(self, "could not read endpoint descriptor\n"); sc->sc_dying = 1; return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { ed_bulkin = ed; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { ed_bulkout = ed; } if (ed_bulkin && ed_bulkout) /* found all we need */ break; } /* Verify that we got something sensible */ if (ed_bulkin == NULL || ed_bulkout == NULL) { aprint_error_dev(self, "bulk-in and/or bulk-out endpoint not found\n"); sc->sc_dying = 1; return; } sc->sc_bulkin = ed_bulkin->bEndpointAddress; sc->sc_bulkout = ed_bulkout->bEndpointAddress; selinit(&sc->sc_selq); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); return; }
void uticom_attach_hook(void *arg) { struct uticom_softc *sc = arg; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usbd_status err; int status, i; usb_device_descriptor_t *dd; struct ucom_attach_args uca; /* Initialize endpoints. */ uca.bulkin = uca.bulkout = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; dd = usbd_get_device_descriptor(sc->sc_udev); DPRINTF(("%s: uticom_attach: num of configurations %d\n", sc->sc_dev.dv_xname, dd->bNumConfigurations)); /* The device without firmware has single configuration with single * bulk out interface. */ if (dd->bNumConfigurations > 1) goto fwload_done; /* Loading firmware. */ DPRINTF(("%s: uticom_attach: starting loading firmware\n", sc->sc_dev.dv_xname)); err = usbd_set_config_index(sc->sc_udev, UTICOM_CONFIG_INDEX, 1); if (err) { printf("%s: failed to set configuration: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } /* Get the config descriptor. */ cdesc = usbd_get_config_descriptor(sc->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } err = usbd_device2interface_handle(sc->sc_udev, UTICOM_IFACE_INDEX, &sc->sc_iface); if (err) { printf("%s: failed to get interface: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } /* Find the bulk out interface used to upload firmware. */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkout = ed->bEndpointAddress; DPRINTF(("%s: uticom_attach: data bulk out num: %d\n", sc->sc_dev.dv_xname, ed->bEndpointAddress)); } if (uca.bulkout == -1) { printf("%s: could not find data bulk out\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } } status = uticom_download_fw(sc, uca.bulkout, sc->sc_udev); if (status) { printf("%s: firmware download failed\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } else { DPRINTF(("%s: firmware download succeeded\n", sc->sc_dev.dv_xname)); } status = usbd_reload_device_desc(sc->sc_udev); if (status) { printf("%s: error reloading device descriptor\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } fwload_done: dd = usbd_get_device_descriptor(sc->sc_udev); DPRINTF(("%s: uticom_attach: num of configurations %d\n", sc->sc_dev.dv_xname, dd->bNumConfigurations)); err = usbd_set_config_index(sc->sc_udev, UTICOM_ACTIVE_INDEX, 1); if (err) { printf("%s: failed to set configuration: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } /* Get the config descriptor. */ cdesc = usbd_get_config_descriptor(sc->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } /* Get the interface (XXX: multiport chips are not supported yet). */ err = usbd_device2interface_handle(sc->sc_udev, UTICOM_IFACE_INDEX, &sc->sc_iface); if (err) { printf("%s: failed to get interface: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } /* Find the interrupt endpoints. */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); return; } 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", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } /* Keep interface for interrupt. */ sc->sc_intr_iface = sc->sc_iface; /* Find the bulk{in,out} endpoints. */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkout = ed->bEndpointAddress; } } if (uca.bulkin == -1) { printf("%s: could not find data bulk in\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } if (uca.bulkout == -1) { printf("%s: could not find data bulk out\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } sc->sc_dtr = sc->sc_rts = -1; uca.portno = UCOM_UNK_PORTNO; uca.ibufsize = UTICOM_IBUFSZ; uca.obufsize = UTICOM_OBUFSZ; uca.ibufsizepad = UTICOM_IBUFSZ; uca.device = sc->sc_udev; uca.iface = sc->sc_iface; uca.opkthdrlen = 0; uca.methods = &uticom_methods; uca.arg = sc; uca.info = NULL; err = uticom_reset(sc); if (err) { printf("%s: reset failed: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } DPRINTF(("%s: uticom_attach: in = 0x%x, out = 0x%x, intr = 0x%x\n", sc->sc_dev.dv_xname, uca.bulkin, uca.bulkout, sc->sc_intr_number)); sc->sc_subdev = config_found_sm((struct device *)sc, &uca, ucomprint, ucomsubmatch); }