Exemple #1
0
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));
}
Exemple #2
0
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);
}
Exemple #3
0
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);
}
Exemple #4
0
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);
}
Exemple #5
0
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;
}
Exemple #7
0
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);
}
Exemple #8
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);
}
Exemple #9
0
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;
}
Exemple #10
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);
}
Exemple #11
0
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);
        }
Exemple #12
0
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);
}
Exemple #13
0
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;
}
Exemple #14
0
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);
}
Exemple #15
0
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);
}
Exemple #16
0
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;
}
Exemple #20
0
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;
}
Exemple #21
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);
	}
Exemple #22
0
/*
 * 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);
}
Exemple #23
0
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);

}
Exemple #24
0
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;
}
Exemple #25
0
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;
}
Exemple #26
0
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;
}
Exemple #27
0
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);
}
Exemple #28
0
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;
}
Exemple #30
0
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);
}