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); }
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); }
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)); }
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; }
/*ARGSUSED*/ static int u3g_open(void *arg, int portno) { struct u3g_softc *sc = arg; usb_device_request_t req; usb_endpoint_descriptor_t *ed; usb_interface_descriptor_t *id; usbd_interface_handle ih; usbd_status err; int i; if (sc->sc_dying) return (0); err = usbd_device2interface_handle(sc->sc_udev, portno, &ih); if (err) return (EIO); id = usbd_get_interface_descriptor(ih); for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(ih, i); if (ed == NULL) return (EIO); if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { /* Issue ENDPOINT_HALT request */ req.bmRequestType = UT_WRITE_ENDPOINT; req.bRequest = UR_CLEAR_FEATURE; USETW(req.wValue, UF_ENDPOINT_HALT); USETW(req.wIndex, ed->bEndpointAddress); USETW(req.wLength, 0); err = usbd_do_request(sc->sc_udev, &req, 0); if (err) return (EIO); } } sc->sc_open = true; sc->sc_purging = true; getmicrotime(&sc->sc_purge_start); return (0); }
void emdtv_dtv_attach(struct emdtv_softc *sc) { usb_endpoint_descriptor_t *ed; usbd_status status; int i; for (i = 0; i < EMDTV_NXFERS; i++) { sc->sc_ix[i].ix_altix = (i & 1) ? &sc->sc_ix[i - 1] : &sc->sc_ix[i + 1]; sc->sc_ix[i].ix_sc = sc; } ed = usbd_interface2endpoint_descriptor(sc->sc_iface, 3); if (ed == NULL) { aprint_error_dev(sc->sc_dev, "couldn't find endpoint 3\n"); return; } sc->sc_isoc_maxpacketsize = UGETW(ed->wMaxPacketSize); sc->sc_isoc_buflen = sc->sc_isoc_maxpacketsize * EMDTV_NFRAMES; aprint_debug_dev(sc->sc_dev, "calling usbd_open_pipe, ep 0x%02x\n", ed->bEndpointAddress); status = usbd_open_pipe(sc->sc_iface, ed->bEndpointAddress, USBD_EXCLUSIVE_USE|USBD_MPSAFE, &sc->sc_isoc_pipe); if (status != USBD_NORMAL_COMPLETION) { aprint_error_dev(sc->sc_dev, "couldn't open isoc pipe\n"); usbd_set_interface(sc->sc_iface, 0); return; } emdtv_write_1(sc, UR_GET_STATUS, 0x48, 0x00); emdtv_write_1(sc, UR_GET_STATUS, 0x12, 0x77); usbd_delay_ms(sc->sc_udev, 6); emdtv_gpio_ctl(sc, EMDTV_GPIO_ANALOG_ON, false); emdtv_gpio_ctl(sc, EMDTV_GPIO_TS1_ON, true); emdtv_gpio_ctl(sc, EMDTV_GPIO_TUNER1_ON, true); emdtv_gpio_ctl(sc, EMDTV_GPIO_DEMOD1_RESET, true); usbd_delay_ms(sc->sc_udev, 100); emdtv_dtv_rescan(sc, NULL, NULL); }
void emdtv_ir_attach(struct emdtv_softc *sc) { struct ir_attach_args ia; usb_endpoint_descriptor_t *ed; usbd_status status; int err; ed = usbd_interface2endpoint_descriptor(sc->sc_iface, 0); if (ed == NULL) return; status = usbd_open_pipe_intr(sc->sc_iface, ed->bEndpointAddress, USBD_EXCLUSIVE_USE, &sc->sc_intr_pipe, sc, &sc->sc_intr_buf, 1, emdtv_ir_intr, USBD_DEFAULT_INTERVAL); if (status != USBD_NORMAL_COMPLETION) { aprint_error_dev(sc->sc_dev, "couldn't open intr pipe: %s\n", usbd_errstr(status)); return; } mutex_init(&sc->sc_ir_mutex, MUTEX_DEFAULT, IPL_VM); err = workqueue_create(&sc->sc_ir_wq, "emdtvir", emdtv_ir_worker, sc, PRI_NONE, IPL_VM, 0); if (err) aprint_error_dev(sc->sc_dev, "couldn't create workqueue: %d\n", err); ia.ia_type = IR_TYPE_CIR; ia.ia_methods = &emdtv_ir_methods; ia.ia_handle = sc; sc->sc_cirdev = config_found_ia(sc->sc_dev, "irbus", &ia, ir_print); }
/* * 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); }
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; }
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 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 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; }
void uhub_attach(struct device *parent, struct device *self, void *aux) { struct uhub_softc *sc = (struct uhub_softc *)self; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->device; struct usbd_hub *hub = NULL; union { usb_hub_descriptor_t hs; usb_hub_ss_descriptor_t ss; } hd; int p, port, nports, powerdelay; struct usbd_interface *iface; usb_endpoint_descriptor_t *ed; struct usbd_tt *tts = NULL; uint8_t ttthink = 0; usbd_status err; #ifdef UHUB_DEBUG int nremov; #endif sc->sc_hub = dev; err = usbd_set_config_index(dev, 0, 1); if (err) { DPRINTF("%s: configuration failed, error=%s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); return; } if (dev->depth > USB_HUB_MAX_DEPTH) { printf("%s: hub depth (%d) exceeded, hub ignored\n", sc->sc_dev.dv_xname, USB_HUB_MAX_DEPTH); return; } /* * Super-Speed hubs need to know their depth to be able to * parse the bits of the route-string that correspond to * their downstream port number. * * This does no apply to root hubs. */ if (dev->depth != 0 && dev->speed == USB_SPEED_SUPER) { if (usbd_set_hub_depth(dev, dev->depth - 1)) { printf("%s: unable to set HUB depth\n", sc->sc_dev.dv_xname); return; } } /* Get hub descriptor. */ if (dev->speed == USB_SPEED_SUPER) { err = usbd_get_hub_ss_descriptor(dev, &hd.ss, 1); nports = hd.ss.bNbrPorts; powerdelay = (hd.ss.bPwrOn2PwrGood * UHD_PWRON_FACTOR); if (!err && nports > 7) usbd_get_hub_ss_descriptor(dev, &hd.ss, nports); } else { err = usbd_get_hub_descriptor(dev, &hd.hs, 1); nports = hd.hs.bNbrPorts; powerdelay = (hd.hs.bPwrOn2PwrGood * UHD_PWRON_FACTOR); ttthink = UGETW(hd.hs.wHubCharacteristics) & UHD_TT_THINK; if (!err && nports > 7) usbd_get_hub_descriptor(dev, &hd.hs, nports); } if (err) { DPRINTF("%s: getting hub descriptor failed, error=%s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); return; } #ifdef UHUB_DEBUG for (nremov = 0, port = 1; port <= nports; port++) { if (dev->speed == USB_SPEED_SUPER) { if (!UHD_NOT_REMOV(&hd.ss, port)) nremov++; } else { if (!UHD_NOT_REMOV(&hd.hs, port)) nremov++; } } printf("%s: %d port%s with %d removable, %s powered", sc->sc_dev.dv_xname, nports, nports != 1 ? "s" : "", nremov, dev->self_powered ? "self" : "bus"); if (dev->depth > 0 && UHUB_IS_HIGH_SPEED(sc)) { printf(", %s transaction translator%s", UHUB_IS_SINGLE_TT(sc) ? "single" : "multiple", UHUB_IS_SINGLE_TT(sc) ? "" : "s"); } printf("\n"); #endif if (nports == 0) { printf("%s: no ports, hub ignored\n", sc->sc_dev.dv_xname); goto bad; } hub = malloc(sizeof(*hub), M_USBDEV, M_NOWAIT); if (hub == NULL) return; hub->ports = mallocarray(nports, sizeof(struct usbd_port), M_USBDEV, M_NOWAIT); if (hub->ports == NULL) { free(hub, M_USBDEV, 0); return; } dev->hub = hub; dev->hub->hubsoftc = sc; hub->explore = uhub_explore; hub->nports = nports; hub->powerdelay = powerdelay; hub->ttthink = ttthink >> 5; if (!dev->self_powered && dev->powersrc->parent != NULL && !dev->powersrc->parent->self_powered) { printf("%s: bus powered hub connected to bus powered hub, " "ignored\n", sc->sc_dev.dv_xname); goto bad; } /* Set up interrupt pipe. */ err = usbd_device2interface_handle(dev, 0, &iface); if (err) { printf("%s: no interface handle\n", sc->sc_dev.dv_xname); goto bad; } ed = usbd_interface2endpoint_descriptor(iface, 0); if (ed == NULL) { printf("%s: no endpoint descriptor\n", sc->sc_dev.dv_xname); goto bad; } if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) { printf("%s: bad interrupt endpoint\n", sc->sc_dev.dv_xname); goto bad; } sc->sc_statuslen = (nports + 1 + 7) / 8; sc->sc_statusbuf = malloc(sc->sc_statuslen, M_USBDEV, M_NOWAIT); if (!sc->sc_statusbuf) goto bad; err = usbd_open_pipe_intr(iface, ed->bEndpointAddress, USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_statusbuf, sc->sc_statuslen, uhub_intr, UHUB_INTR_INTERVAL); if (err) { printf("%s: cannot open interrupt pipe\n", sc->sc_dev.dv_xname); goto bad; } /* Wait with power off for a while. */ usbd_delay_ms(dev, USB_POWER_DOWN_TIME); /* * To have the best chance of success we do things in the exact same * order as Windoze98. This should not be necessary, but some * devices do not follow the USB specs to the letter. * * These are the events on the bus when a hub is attached: * Get device and config descriptors (see attach code) * Get hub descriptor (see above) * For all ports * turn on power * wait for power to become stable * (all below happens in explore code) * For all ports * clear C_PORT_CONNECTION * For all ports * get port status * if device connected * wait 100 ms * turn on reset * wait * clear C_PORT_RESET * get port status * proceed with device attachment */ if (UHUB_IS_HIGH_SPEED(sc)) { tts = mallocarray((UHUB_IS_SINGLE_TT(sc) ? 1 : nports), sizeof (struct usbd_tt), M_USBDEV, M_NOWAIT); if (!tts) goto bad; } /* Set up data structures */ for (p = 0; p < nports; p++) { struct usbd_port *up = &hub->ports[p]; up->device = NULL; up->parent = dev; up->portno = p + 1; if (dev->self_powered) /* Self powered hub, give ports maximum current. */ up->power = USB_MAX_POWER; else up->power = USB_MIN_POWER; up->restartcnt = 0; up->reattach = 0; if (UHUB_IS_HIGH_SPEED(sc)) { up->tt = &tts[UHUB_IS_SINGLE_TT(sc) ? 0 : p]; up->tt->hub = hub; } else { up->tt = NULL; } } for (port = 1; port <= nports; port++) { /* Turn the power on. */ err = usbd_set_port_feature(dev, port, UHF_PORT_POWER); if (err) printf("%s: port %d power on failed, %s\n", sc->sc_dev.dv_xname, port, usbd_errstr(err)); /* Make sure we check the port status at least once. */ sc->sc_status |= (1 << port); } /* Wait for stable power. */ if (dev->powersrc->parent != NULL) usbd_delay_ms(dev, powerdelay + USB_EXTRA_POWER_UP_TIME); /* The usual exploration will finish the setup. */ sc->sc_running = 1; return; bad: if (sc->sc_statusbuf) free(sc->sc_statusbuf, M_USBDEV, 0); if (hub) { if (hub->ports) free(hub->ports, M_USBDEV, 0); free(hub, M_USBDEV, 0); } dev->hub = NULL; }
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); }
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; }
/* * 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); }
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; }
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; }
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 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; }
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); }
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 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); }
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); }
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 urio_attach(device_t self) { struct urio_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); usbd_interface_handle iface; u_int8_t epcount; usbd_status r; char * ermsg = "<none>"; int i; DPRINTFN(10,("urio_attach: sc=%p\n", sc)); sc->sc_dev = self; sc->sc_udev = uaa->device; if ((!uaa->device) || (!uaa->iface)) { ermsg = "device or iface"; goto nobulk; } sc->sc_iface = iface = uaa->iface; sc->sc_opened = 0; sc->sc_pipeh_in = 0; sc->sc_pipeh_out = 0; sc->sc_refcnt = 0; r = usbd_endpoint_count(iface, &epcount); if (r != USBD_NORMAL_COMPLETION) { ermsg = "endpoints"; goto nobulk; } sc->sc_epaddr[RIO_OUT] = 0xff; sc->sc_epaddr[RIO_IN] = 0x00; for (i = 0; i < epcount; i++) { usb_endpoint_descriptor_t *edesc = usbd_interface2endpoint_descriptor(iface, i); int d; if (!edesc) { ermsg = "interface endpoint"; goto nobulk; } d = RIO_UE_GET_DIR(edesc->bEndpointAddress); if (d != RIO_NODIR) sc->sc_epaddr[d] = edesc->bEndpointAddress; } if ( sc->sc_epaddr[RIO_OUT] == 0xff || sc->sc_epaddr[RIO_IN] == 0x00) { ermsg = "Rio I&O"; goto nobulk; } make_dev(&urio_ops, device_get_unit(self), UID_ROOT, GID_OPERATOR, 0644, "urio%d", device_get_unit(self)); DPRINTFN(10, ("urio_attach: %p\n", sc->sc_udev)); return 0; nobulk: kprintf("%s: could not find %s\n", device_get_nameunit(sc->sc_dev),ermsg); 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 int uhub_attach(device_t self) { struct uhub_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); usbd_device_handle dev = uaa->device; usbd_status err; struct usbd_hub *hub = NULL; usb_device_request_t req; usb_hub_descriptor_t hubdesc; int p, port, nports, nremov, pwrdly; usbd_interface_handle iface; usb_endpoint_descriptor_t *ed; struct usbd_tt *tts = NULL; DPRINTFN(1,("uhub_attach\n")); sc->sc_hub = dev; if (dev->depth > 0 && UHUB_IS_HIGH_SPEED(sc)) { device_printf(self, "%s transaction translator%s\n", UHUB_IS_SINGLE_TT(sc) ? "single" : "multiple", UHUB_IS_SINGLE_TT(sc) ? "" : "s"); } err = usbd_set_config_index(dev, 0, 1); if (err) { DPRINTF(("%s: configuration failed, error=%s\n", device_get_nameunit(self), usbd_errstr(err))); return ENXIO; } if (dev->depth > USB_HUB_MAX_DEPTH) { device_printf(self, "hub depth (%d) exceeded, hub ignored\n", USB_HUB_MAX_DEPTH); return ENXIO; } /* Get hub descriptor. */ req.bmRequestType = UT_READ_CLASS_DEVICE; req.bRequest = UR_GET_DESCRIPTOR; USETW2(req.wValue, (dev->address > 1 ? UDESC_HUB : 0), 0); USETW(req.wIndex, 0); USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE); DPRINTFN(1,("usb_init_hub: getting hub descriptor\n")); err = usbd_do_request(dev, &req, &hubdesc); nports = hubdesc.bNbrPorts; if (!err && nports > 7) { USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8); err = usbd_do_request(dev, &req, &hubdesc); } if (err) { DPRINTF(("%s: getting hub descriptor failed, error=%s\n", device_get_nameunit(self), usbd_errstr(err))); return ENXIO; } for (nremov = 0, port = 1; port <= nports; port++) if (!UHD_NOT_REMOV(&hubdesc, port)) nremov++; device_printf(self, "%d port%s with %d removable, %s powered\n", nports, nports != 1 ? "s" : "", nremov, dev->self_powered ? "self" : "bus"); if (nports == 0) { device_printf(self, "no ports, hub ignored\n"); goto bad; } hub = kmalloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port), M_USBDEV, M_WAITOK); dev->hub = hub; dev->hub->hubdev = self; hub->explore = uhub_explore; hub->hubdesc = hubdesc; DPRINTFN(1,("usbhub_init_hub: selfpowered=%d, parent=%p, " "parent->selfpowered=%d\n", dev->self_powered, dev->powersrc->parent, dev->powersrc->parent ? dev->powersrc->parent->self_powered : 0)); if (!dev->self_powered && dev->powersrc->parent != NULL && !dev->powersrc->parent->self_powered) { device_printf(self, "bus powered hub connected to bus powered hub, " "ignored\n"); goto bad; } /* Set up interrupt pipe. */ err = usbd_device2interface_handle(dev, 0, &iface); if (err) { device_printf(self, "no interface handle\n"); goto bad; } ed = usbd_interface2endpoint_descriptor(iface, 0); if (ed == NULL) { device_printf(self, "no endpoint descriptor\n"); goto bad; } if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) { device_printf(self, "bad interrupt endpoint\n"); goto bad; } err = usbd_open_pipe_intr(iface, ed->bEndpointAddress, USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status, sizeof(sc->sc_status), uhub_intr, UHUB_INTR_INTERVAL); if (err) { device_printf(self, "cannot open interrupt pipe\n"); goto bad; } /* Wait with power off for a while. */ usbd_delay_ms(dev, USB_POWER_DOWN_TIME); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, self); /* * To have the best chance of success we do things in the exact same * order as Windoze98. This should not be necessary, but some * devices do not follow the USB specs to the letter. * * These are the events on the bus when a hub is attached: * Get device and config descriptors (see attach code) * Get hub descriptor (see above) * For all ports * turn on power * wait for power to become stable * (all below happens in explore code) * For all ports * clear C_PORT_CONNECTION * For all ports * get port status * if device connected * wait 100 ms * turn on reset * wait * clear C_PORT_RESET * get port status * proceed with device attachment */ if (UHUB_IS_HIGH_SPEED(sc)) { tts = kmalloc((UHUB_IS_SINGLE_TT(sc) ? 1 : nports) * sizeof(struct usbd_tt), M_USBDEV, M_WAITOK); } /* Set up data structures */ for (p = 0; p < nports; p++) { struct usbd_port *up = &hub->ports[p]; up->device = NULL; up->parent = dev; up->portno = p+1; if (dev->self_powered) /* Self powered hub, give ports maximum current. */ up->power = USB_MAX_POWER; else up->power = USB_MIN_POWER; up->restartcnt = 0; if (UHUB_IS_HIGH_SPEED(sc)) { up->tt = &tts[UHUB_IS_SINGLE_TT(sc) ? 0 : p]; up->tt->hub = hub; } else { up->tt = NULL; } } /* XXX should check for none, individual, or ganged power? */ pwrdly = dev->hub->hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR + USB_EXTRA_POWER_UP_TIME; for (port = 1; port <= nports; port++) { /* Turn the power on. */ err = usbd_set_port_feature(dev, port, UHF_PORT_POWER); if (err) device_printf(self, "port %d power on failed, %s\n", port, usbd_errstr(err)); DPRINTF(("usb_init_port: turn on port %d power\n", port)); } /* Wait for stable power if we are not a root hub */ if (dev->powersrc->parent != NULL) usbd_delay_ms(dev, pwrdly); /* The usual exploration will finish the setup. */ sc->sc_running = 1; return 0; bad: if (hub) kfree(hub, M_USBDEV); dev->hub = NULL; return ENXIO; }
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); }