Beispiel #1
0
void
ucom_cleanup(struct ucom_softc *sc)
{
	DPRINTF(("ucom_cleanup: closing pipes\n"));

	sc->sc_open = 0;

	ucom_shutdown(sc);
	if (sc->sc_bulkin_pipe != NULL) {
		usbd_abort_pipe(sc->sc_bulkin_pipe);
		usbd_close_pipe(sc->sc_bulkin_pipe);
		sc->sc_bulkin_pipe = NULL;
	}
	if (sc->sc_bulkout_pipe != NULL) {
		usbd_abort_pipe(sc->sc_bulkout_pipe);
		usbd_close_pipe(sc->sc_bulkout_pipe);
		sc->sc_bulkout_pipe = NULL;
	}
	if (sc->sc_ixfer != NULL) {
		if (sc->sc_uhidev == NULL)
			usbd_free_xfer(sc->sc_ixfer);
		sc->sc_ixfer = NULL;
	}
	if (sc->sc_oxfer != NULL) {
		usbd_free_buffer(sc->sc_oxfer);
		if (sc->sc_uhidev == NULL)
			usbd_free_xfer(sc->sc_oxfer);
		sc->sc_oxfer = NULL;
	}
}
static int
auvitek_stop_xfer(struct auvitek_softc *sc)
{
	struct auvitek_xfer *ax = &sc->sc_ax;
	usbd_status err;
	int i;

	if (ax->ax_pipe != NULL) {
		usbd_abort_pipe(ax->ax_pipe);
		usbd_close_pipe(ax->ax_pipe);
		ax->ax_pipe = NULL;
	}

	for (i = 0; i < AUVITEK_NISOC_XFERS; i++) {
		struct auvitek_isoc *isoc = &ax->ax_i[i];
		if (isoc->i_xfer != NULL) {
			usbd_free_buffer(isoc->i_xfer);
			usbd_free_xfer(isoc->i_xfer);
			isoc->i_xfer = NULL;
		}
		if (isoc->i_frlengths != NULL) {
			kmem_free(isoc->i_frlengths,
			    sizeof(isoc->i_frlengths[0]) * ax->ax_nframes);
			isoc->i_frlengths = NULL;
		}
	}

	usbd_delay_ms(sc->sc_udev, 1000);
	err = usbd_set_interface(sc->sc_isoc_iface, 0);
	if (err != USBD_NORMAL_COMPLETION) {
		aprint_error_dev(sc->sc_dev,
		    "couldn't set zero bw interface: %s\n",
		    usbd_errstr(err));
		return EIO;
	}

	return 0;
}
Beispiel #3
0
int
stuirda_fwload(struct uirda_softc *sc) {


	int rc;
	firmware_handle_t fh;
	off_t fwsize;
	usb_device_descriptor_t usbddsc;
	usbd_xfer_handle	fwxfer;
	usbd_pipe_handle	fwpipe;
	usbd_status status;
	usb_device_request_t req;
	char *buffer;
	char *p;
	char fwname[12];
	int n;
	u_int8_t *usbbuf;
	/* size_t bsize; */

	printf("%s: needing to download firmware\n",
		device_xname(sc->sc_dev));

	status = usbd_get_device_desc(sc->sc_udev, &usbddsc);
	if (status) {
		printf("%s: can't get device descriptor, status %d\n",
		    device_xname(sc->sc_dev), status);
		return status;
	}

	rc = usbd_get_class_desc(sc->sc_udev, UDESC_IRDA, 0,
		USB_IRDA_DESCRIPTOR_SIZE, &sc->sc_irdadesc);
	printf("error %d reading class desc\n", rc);

	snprintf(fwname, sizeof(fwname), "4210%02x%02x.sb",
		usbddsc.bcdDevice[1],
		usbddsc.bcdDevice[0]);

	printf("%s: Attempting to load firmware %s\n",
		device_xname(sc->sc_dev), fwname);
	
	rc = firmware_open("stuirda", fwname, &fh);

	if (rc) {
		printf("%s: Cannot load firmware\n",
			device_xname(sc->sc_dev));
		return rc;
	}
	fwsize = firmware_get_size(fh);

	printf("%s: Firmware size %lld\n",
		device_xname(sc->sc_dev), (long long)fwsize);

	buffer = firmware_malloc(fwsize);
	if (buffer == NULL) {
		printf("%s: Cannot load firmware: out of memory\n",
			device_xname(sc->sc_dev));
		goto giveup2;
	}

	rc = firmware_read(fh, 0, buffer, (size_t)fwsize);

	if (rc) {
		printf("%s: Cannot read firmware\n", device_xname(sc->sc_dev));
		goto giveup3;
	}

	for (p = buffer + sizeof("Product Version:");
	    p < buffer + fwsize - 5; p++) {

		if (0x1A == *p)
			break;
	}
	if (0x1a != *p || memcmp(p+1, "STMP", 4) != 0) {
		/* firmware bad */
		printf("%s: Bad firmware\n", device_xname(sc->sc_dev));
		goto giveup3;
	}

	p += 5;

	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
	req.bRequest = 2 /* XXX magic */;
	USETW(req.wValue, 0);
	USETW(req.wIndex, 0);
	USETW(req.wLength, 0);
	rc = usbd_do_request(sc->sc_udev, &req, 0);
	if (rc) {
		printf("%s: Cannot switch to f/w d/l mode, error %d\n",
			device_xname(sc->sc_dev), rc);
		goto giveup3;
	}

	delay(100000);

	rc = usbd_open_pipe(sc->sc_iface, sc->sc_wr_addr, 0, &fwpipe);
	if (rc) {
		printf("%s: Cannot open pipe, rc=%d\n",
		    device_xname(sc->sc_dev), rc);
		goto giveup3;
	}
	fwxfer = usbd_alloc_xfer(sc->sc_udev);
	if (fwxfer == NULL) {
		printf("%s: Cannot alloc xfer\n", device_xname(sc->sc_dev));
		goto giveup4;
	}
	usbbuf = usbd_alloc_buffer(fwxfer, 1024);
	if (usbbuf == NULL) {
		printf("%s: Cannot alloc usb buf\n", device_xname(sc->sc_dev));
		goto giveup5;
	}
	n = (buffer + fwsize - p);
	while (n > 0) {
		if (n > 1023)
			n = 1023;
		memcpy(usbbuf, p, n);
		rc = usbd_bulk_transfer(fwxfer, fwpipe,
		    USBD_SYNCHRONOUS|USBD_FORCE_SHORT_XFER,
		    5000, usbbuf, &n, "uirda-fw-wr");
		printf("%s: write: rc=%d, %d left\n",
		    device_xname(sc->sc_dev), rc, n);
		if (rc) {
			printf("%s: write: rc=%d, %d bytes written\n",
			    device_xname(sc->sc_dev), rc, n);
			goto giveup4;
		}
		printf("%s: written %d\n", device_xname(sc->sc_dev), n);
		p += n; 
		n = (buffer + fwsize - p);
	}
	delay(100000);
	/* TODO: more code here */
	rc = 0;
	usbd_free_buffer(fwxfer);

	giveup5: usbd_free_xfer(fwxfer);	
	giveup4: usbd_close_pipe(fwpipe);
	giveup3: firmware_free(buffer, fwsize);
	giveup2: firmware_close(fh);

	return rc;
		
}
Beispiel #4
0
static int
uticom_download_fw(struct uticom_softc *sc, int pipeno,
    struct usbd_device *dev)
{
	u_char *obuf, *firmware;
	size_t firmware_size;
	int buffer_size, pos;
	uint8_t cs = 0, *buffer;
	usbd_status err;
	struct uticom_fw_header *header;
	struct usbd_xfer *oxfer = 0;
	usbd_status error = 0;
	struct usbd_pipe *pipe;

	error = loadfirmware("tusb3410", &firmware, &firmware_size);
	if (error)
		return (error);

	buffer_size = UTICOM_FW_BUFSZ + sizeof(struct uticom_fw_header);
	buffer = malloc(buffer_size, M_USBDEV, M_WAITOK | M_CANFAIL);

	if (!buffer) {
		printf("%s: uticom_download_fw: out of memory\n",
		    sc->sc_dev.dv_xname);
		free(firmware, M_DEVBUF);
		return ENOMEM;
	}

	memcpy(buffer, firmware, firmware_size);
	memset(buffer + firmware_size, 0xff, buffer_size - firmware_size);

	for (pos = sizeof(struct uticom_fw_header); pos < buffer_size; pos++)
		cs = (uint8_t)(cs + buffer[pos]);

	header = (struct uticom_fw_header*)buffer;
	header->length = (uint16_t)(buffer_size -
	    sizeof(struct uticom_fw_header));
	header->checkSum = cs;

	DPRINTF(("%s: downloading firmware ...\n",
	    sc->sc_dev.dv_xname));

	err = usbd_open_pipe(sc->sc_iface, pipeno, USBD_EXCLUSIVE_USE,
	    &pipe);
	if (err) {
		printf("%s: open bulk out error (addr %d): %s\n",
		    sc->sc_dev.dv_xname, pipeno, usbd_errstr(err));
		error = EIO;
		goto finish;
	}

	oxfer = usbd_alloc_xfer(dev);
	if (oxfer == NULL) {
		error = ENOMEM;
		goto finish;
	}

	obuf = usbd_alloc_buffer(oxfer, buffer_size);
	if (obuf == NULL) {
		error = ENOMEM;
		goto finish;
	}

	memcpy(obuf, buffer, buffer_size);

	usbd_setup_xfer(oxfer, pipe, (void *)sc, obuf, buffer_size,
	    USBD_NO_COPY | USBD_SYNCHRONOUS, USBD_NO_TIMEOUT, 0);
	err = usbd_transfer(oxfer);

	if (err != USBD_NORMAL_COMPLETION)
		printf("%s: uticom_download_fw: error: %s\n",
		    sc->sc_dev.dv_xname, usbd_errstr(err));

finish:
	free(firmware, M_DEVBUF);
	usbd_free_buffer(oxfer);
	usbd_free_xfer(oxfer);
	oxfer = NULL;
	usbd_abort_pipe(pipe);
	usbd_close_pipe(pipe);
	free(buffer, M_USBDEV);
	return err;
}
Beispiel #5
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);
}
Beispiel #6
0
int
ucom_detach(struct device *self, int flags)
{
	struct ucom_softc *sc = (struct ucom_softc *)self;
	struct tty *tp = sc->sc_tty;
	int maj, mn;
	int s;

	DPRINTF(("ucom_detach: sc=%p flags=%d tp=%p, pipe=%d,%d\n",
		 sc, flags, tp, sc->sc_bulkin_no, sc->sc_bulkout_no));

	if (sc->sc_bulkin_pipe != NULL) {
		usbd_abort_pipe(sc->sc_bulkin_pipe);
		usbd_close_pipe(sc->sc_bulkin_pipe);
		sc->sc_bulkin_pipe = NULL;
	}
	if (sc->sc_bulkout_pipe != NULL) {
		usbd_abort_pipe(sc->sc_bulkout_pipe);
		usbd_close_pipe(sc->sc_bulkout_pipe);
		sc->sc_bulkout_pipe = NULL;
	}
	if (sc->sc_ixfer != NULL) {
		if (sc->sc_uhidev == NULL)
			usbd_free_xfer(sc->sc_ixfer);
		sc->sc_ixfer = NULL;
	}
	if (sc->sc_oxfer != NULL) {
		usbd_free_buffer(sc->sc_oxfer);
		if (sc->sc_uhidev == NULL)
			usbd_free_xfer(sc->sc_oxfer);
		sc->sc_oxfer = NULL;
	}

	s = splusb();
	if (--sc->sc_refcnt >= 0) {
		/* Wake up anyone waiting */
		if (tp != NULL) {
			CLR(tp->t_state, TS_CARR_ON);
			CLR(tp->t_cflag, CLOCAL | MDMBUF);
			ttyflush(tp, FREAD|FWRITE);
		}
		usb_detach_wait(&sc->sc_dev);
	}
	splx(s);

	/* locate the major number */
	for (maj = 0; maj < nchrdev; maj++)
		if (cdevsw[maj].d_open == ucomopen)
			break;

	/* Nuke the vnodes for any open instances. */
	mn = self->dv_unit;
	DPRINTF(("ucom_detach: maj=%d mn=%d\n", maj, mn));
	vdevgone(maj, mn, mn, VCHR);
	vdevgone(maj, mn | UCOMCUA_MASK, mn | UCOMCUA_MASK, VCHR);

	/* Detach and free the tty. */
	if (tp != NULL) {
		(*LINESW(tp, l_close))(tp, FNONBLOCK, curproc);
		s = spltty();
		CLR(tp->t_state, TS_BUSY | TS_FLUSH);
		ttyclose(tp);
		splx(s);
		ttyfree(tp);
		sc->sc_tty = NULL;
	}

	return (0);
}
int
uirda_set_params(void *h, struct irda_params *p)
{
	struct uirda_softc *sc = h;
	usbd_status err;
	int i;
	u_int8_t hdr;
	u_int32_t n;
	u_int mask;

	DPRINTF(("%s: sc=%p, speed=%d ebofs=%d maxsize=%d\n", __func__,
		 sc, p->speed, p->ebofs, p->maxsize));

	if (sc->sc_dying)
		return (EIO);

	hdr = 0;
	if (p->ebofs != sc->sc_params.ebofs) {
		/* round up ebofs */
		mask = 1 /* sc->sc_irdadesc.bmAdditionalBOFs*/;
		DPRINTF(("u.s.p.: mask=0x%x, sc->ebofs=%d, p->ebofs=%d\n",
			mask, sc->sc_params.ebofs, p->ebofs));
		for (i = 0; i < UIRDA_NEBOFS; i++) {
			DPRINTF(("u.s.p.: u_e[%d].mask=0x%x, count=%d\n",
				i, uirda_ebofs[i].mask, uirda_ebofs[i].count));
			if ((mask & uirda_ebofs[i].mask) &&
			    uirda_ebofs[i].count >= p->ebofs) {
				hdr = uirda_ebofs[i].header;
				goto found1;
			}
		}
		for (i = 0; i < UIRDA_NEBOFS; i++) {
			DPRINTF(("u.s.p.: u_e[%d].mask=0x%x, count=%d\n",
				i, uirda_ebofs[i].mask, uirda_ebofs[i].count));
			if ((mask & uirda_ebofs[i].mask)) {
				hdr = uirda_ebofs[i].header;
				goto found1;
			}
		}
		/* no good value found */
		return (EINVAL);
	found1:
		DPRINTF(("uirda_set_params: ebofs hdr=0x%02x\n", hdr));
		;

	}
	if (hdr != 0 || p->speed != sc->sc_params.speed) {
		/* find speed */
		mask = UGETW(sc->sc_irdadesc.wBaudRate);
		for (i = 0; i < UIRDA_NSPEEDS; i++) {
			if ((mask & uirda_speeds[i].mask) &&
			    uirda_speeds[i].speed == p->speed) {
				hdr |= uirda_speeds[i].header;
				goto found2;
			}
		}
		/* no good value found */
		return (EINVAL);
	found2:
		DPRINTF(("uirda_set_params: speed hdr=0x%02x\n", hdr));
		;
	}
	if (p->maxsize != sc->sc_params.maxsize) {
		if (p->maxsize > IRDA_MAX_FRAME_SIZE)
			return (EINVAL);
		sc->sc_params.maxsize = p->maxsize;
#if 0
		DPRINTF(("%s: new buffers, old size=%d\n", __func__,
			 sc->sc_params.maxsize));
		if (p->maxsize > 10000 || p < 0) /* XXX */
			return (EINVAL);

		/* Change the write buffer */
		mutex_enter(&sc->sc_wr_buf_lk);
		if (sc->sc_wr_buf != NULL)
			usbd_free_buffer(sc->sc_wr_xfer);
		sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, p->maxsize+1);
		mutex_exit(&sc->sc_wr_buf_lk);
		if (sc->sc_wr_buf == NULL)
			return (ENOMEM);

		/* Change the read buffer */
		mutex_enter(&sc->sc_rd_buf_lk);
		usbd_abort_pipe(sc->sc_rd_pipe);
		if (sc->sc_rd_buf != NULL)
			usbd_free_buffer(sc->sc_rd_xfer);
		sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, p->maxsize+1);
		sc->sc_rd_count = 0;
		if (sc->sc_rd_buf == NULL) {
			mutex_exit(&sc->sc_rd_buf_lk);
			return (ENOMEM);
		}
		sc->sc_params.maxsize = p->maxsize;
		err = uirda_start_read(sc); /* XXX check */
		mutex_exit(&sc->sc_rd_buf_lk);
#endif
	}
	if (hdr != 0 && hdr != sc->sc_wr_hdr) {
		/*
		 * A change has occurred, transmit a 0 length frame with
		 * the new settings.  The 0 length frame is not sent to the
		 * device.
		 */
		DPRINTF(("%s: sc=%p setting header 0x%02x\n",
			 __func__, sc, hdr));
		sc->sc_wr_hdr = hdr;
		mutex_enter(&sc->sc_wr_buf_lk);
		sc->sc_wr_buf[0] = hdr;
		n = UIRDA_OUTPUT_HEADER_SIZE;
		err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe,
			  USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
			  UIRDA_WR_TIMEOUT, sc->sc_wr_buf, &n, "uirdast");
		if (err) {
			aprint_error_dev(sc->sc_dev, "set failed, err=%d\n",
			    err);
			usbd_clear_endpoint_stall(sc->sc_wr_pipe);
		}
		mutex_exit(&sc->sc_wr_buf_lk);
	}

	sc->sc_params = *p;

	return (0);
}