Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Jun 2006 05:22:50 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 99035 for review
Message-ID:  <200606120522.k5C5MoPh021416@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=99035

Change 99035 by hselasky@hselasky_mini_itx on 2006/06/12 05:22:47

	Compilation fix for FreeBSD-6.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb_cdev.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb/uvscom.c#4 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/usb_cdev.c#4 (text+ko) ====

@@ -39,6 +39,7 @@
 #include <sys/vnode.h>
 #include <sys/proc.h>
 #include <sys/poll.h>
+#include <sys/signalvar.h>
 
 #include <dev/usb/usb_port.h>
 #include <dev/usb/usb.h>

==== //depot/projects/usb/src/sys/dev/usb/uvscom.c#4 (text+ko) ====

@@ -1,0 +1,985 @@
+/*	$NetBSD: usb/uvscom.c,v 1.1 2002/03/19 15:08:42 augustss Exp $	*/
+/*-
+ * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*
+ * uvscom: SUNTAC Slipper U VS-10U driver.
+ * Slipper U is a PC Card to USB converter for data communication card
+ * adapter.  It supports DDI Pocket's Air H" C@rd, C@rd H" 64, NTT's P-in,
+ * P-in m@ater and various data communication card adapters.
+ */
+
+#include "opt_uvscom.h" /* XXX remove this */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/termios.h>
+#include <sys/serial.h>
+#include <sys/taskqueue.h>
+
+#include <dev/usb/usb_port.h>
+#include <dev/usb/usb.h>
+#include <dev/usb/usb_subr.h>
+#include <dev/usb/usb_quirks.h>
+#include <dev/usb/usb_cdc.h>
+
+#include <dev/usb/ucomvar.h>
+
+#include "usbdevs.h"
+
+__FBSDID("$FreeBSD: src/sys/dev/usb/uvscom.c $");
+
+#ifdef USB_DEBUG
+#define DPRINTF(n,fmt,...)						\
+  do { if (uvscom_debug > (n)) {					\
+      printf("%s: " fmt, __FUNCTION__,## __VA_ARGS__); } } while (0)
+
+static int uvscom_debug = 0;
+SYSCTL_NODE(_hw_usb, OID_AUTO, uvscom, CTLFLAG_RW, 0, "USB uvscom");
+SYSCTL_INT(_hw_usb_uvscom, OID_AUTO, debug, CTLFLAG_RW,
+	   &uvscom_debug, 0, "uvscom debug level");
+#else
+#define DPRINTF(...)
+#endif
+
+#define UVSCOM_MODVER		1	/* module version */
+
+#define	UVSCOM_CONFIG_INDEX	0
+#define	UVSCOM_IFACE_INDEX	0
+
+#ifndef UVSCOM_INTR_INTERVAL
+#define UVSCOM_INTR_INTERVAL	0 /* default */
+#endif
+
+#define UVSCOM_UNIT_WAIT	5
+
+/* Request */
+#define UVSCOM_SET_SPEED	0x10
+#define UVSCOM_LINE_CTL		0x11
+#define UVSCOM_SET_PARAM	0x12
+#define UVSCOM_READ_STATUS	0xd0
+#define UVSCOM_SHUTDOWN		0xe0
+
+/* UVSCOM_SET_SPEED parameters */
+#define UVSCOM_SPEED_150BPS	0x00
+#define UVSCOM_SPEED_300BPS	0x01
+#define UVSCOM_SPEED_600BPS	0x02
+#define UVSCOM_SPEED_1200BPS	0x03
+#define UVSCOM_SPEED_2400BPS	0x04
+#define UVSCOM_SPEED_4800BPS	0x05
+#define UVSCOM_SPEED_9600BPS	0x06
+#define UVSCOM_SPEED_19200BPS	0x07
+#define UVSCOM_SPEED_38400BPS	0x08
+#define UVSCOM_SPEED_57600BPS	0x09
+#define UVSCOM_SPEED_115200BPS	0x0a
+
+/* UVSCOM_LINE_CTL parameters */
+#define UVSCOM_BREAK		0x40
+#define UVSCOM_RTS		0x02
+#define UVSCOM_DTR		0x01
+#define UVSCOM_LINE_INIT	0x08
+
+/* UVSCOM_SET_PARAM parameters */
+#define UVSCOM_DATA_MASK	0x03
+#define UVSCOM_DATA_BIT_8	0x03
+#define UVSCOM_DATA_BIT_7	0x02
+#define UVSCOM_DATA_BIT_6	0x01
+#define UVSCOM_DATA_BIT_5	0x00
+
+#define UVSCOM_STOP_MASK	0x04
+#define UVSCOM_STOP_BIT_2	0x04
+#define UVSCOM_STOP_BIT_1	0x00
+
+#define UVSCOM_PARITY_MASK	0x18
+#define UVSCOM_PARITY_EVEN	0x18
+#if 0
+#define UVSCOM_PARITY_UNK	0x10
+#endif
+#define UVSCOM_PARITY_ODD	0x08
+#define UVSCOM_PARITY_NONE	0x00
+
+/* Status bits */
+#define UVSCOM_TXRDY		0x04
+#define UVSCOM_RXRDY		0x01
+
+#define UVSCOM_DCD		0x08
+#define UVSCOM_NOCARD		0x04
+#define UVSCOM_DSR		0x02
+#define UVSCOM_CTS		0x01
+#define UVSCOM_USTAT_MASK	(UVSCOM_NOCARD | UVSCOM_DSR | UVSCOM_CTS)
+
+struct	uvscom_softc {
+	struct ucom_softc	sc_ucom;
+	struct __callout	sc_watchdog;
+
+	u_int16_t		sc_line_ctrl; /* line control register */
+	u_int16_t		sc_line_speed; /* line speed */
+	u_int16_t		sc_line_param; /* line parameters */
+
+	u_int8_t		sc_iface_no; /* interface number */
+	u_int8_t		sc_iface_index; /* interface index */
+	u_int8_t		sc_dtr; /* current DTR state */
+	u_int8_t		sc_rts; /* current RTS state */
+	u_int8_t		sc_lsr;	/* local status register */
+	u_int8_t		sc_msr; /* uvscom status register */
+
+
+  XXX:
+	int			sc_iface_number;/* interface number */
+
+	usbd_interface_handle	sc_intr_iface;	/* interrupt interface */
+	int			sc_intr_number;	/* interrupt number */
+	usbd_pipe_handle	sc_intr_pipe;	/* interrupt pipe */
+	u_int8_t			*sc_intr_buf;	/* interrupt buffer */
+	int			sc_isize;
+
+
+	u_int8_t		sc_unit_status; /* unit status */
+
+	struct task		sc_task;
+};
+
+/*
+ * These are the maximum number of bytes transferred per frame.
+ * The output buffer size cannot be increased due to the size encoding.
+ */
+#define UVSCOM_IBUFSIZE		512
+#define UVSCOM_OBUFSIZE		64
+
+#ifndef UVSCOM_DEFAULT_OPKTSIZE
+#define UVSCOM_DEFAULT_OPKTSIZE	8
+#endif
+
+#define UVSCOM_N_TRANSFER X
+
+static const struct usbd_config umodem_config_data[UVSCOM_N_TRANSFER] = {
+
+    [0] = {
+      .type      = UE_BULK,
+      .endpoint  = -1, /* any */
+      .direction = UE_DIR_OUT,
+      .bufsize   = UVSCOM_OBUFSIZE,
+      .flags     = 0,
+      .callback  = &umodem_write_callback,
+    },
+
+    [1] = {
+      .type      = UE_BULK,
+      .endpoint  = -1, /* any */
+      .direction = UE_DIR_IN,
+      .bufsize   = UVSCOM_IBUFSIZE,
+      .flags     = USBD_SHORT_XFER_OK,
+      .callback  = &umodem_read_callback,
+    },
+
+    [2] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0x00, /* Control pipe */
+      .direction = -1,
+      .bufsize   = sizeof(usb_device_request_t),
+      .callback  = &umodem_write_clear_stall_callback,
+      .timeout   = 1000, /* 1 second */
+    },
+
+    [3] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0x00, /* Control pipe */
+      .direction = -1,
+      .bufsize   = sizeof(usb_device_request_t),
+      .callback  = &umodem_read_clear_stall_callback,
+      .timeout   = 1000, /* 1 second */
+    },
+
+    [4] = {
+      .type      = UE_INTERRUPT,
+      .endpoint  = -1, /* any */
+      .direction = UE_DIR_IN,
+      .flags     = USBD_SHORT_XFER_OK,
+      .bufsize   = XXX,
+      .callback  = &umodem_intr_callback,
+    },
+
+    [5] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0x00, /* Control pipe */
+      .direction = -1,
+      .bufsize   = sizeof(usb_device_request_t),
+      .callback  = &umodem_intr_clear_stall_callback,
+      .timeout   = 1000, /* 1 second */
+    },
+
+    [6] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0x00, /* Control pipe */
+      .direction = -1,
+      .bufsize   = sizeof(usb_device_request_t) + 2,
+      .callback  = &uvscom_read_status_callback,
+      .timeout   = 1000, /* 1 second */
+    },
+
+    [7] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0x00, /* Control pipe */
+      .direction = -1,
+      .bufsize   = sizeof(usb_device_request_t),
+      .callback  = &uvscom_shutdown_callback,
+      .timeout   = 1000, /* 1 second */
+    },
+
+    [8] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0x00, /* Control pipe */
+      .direction = -1,
+      .bufsize   = sizeof(usb_device_request_t),
+      .callback  = &uvscom_set_line_callback,
+      .timeout   = 1000, /* 1 second */
+    },
+
+    [9] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0x00, /* Control pipe */
+      .direction = -1,
+      .bufsize   = sizeof(usb_device_request_t),
+      .callback  = &uvscom_set_line_coding_callback,
+      .timeout   = 1000, /* 1 second */
+    },
+
+
+
+
+XXX
+};
+
+static const struct ucom_callback uvscom_callback = {
+  .ucom_get_status  = &uvscom_get_status,
+  .ucom_set_dtr     = &uvscom_set_dtr,
+  .ucom_set_rts     = &uvscom_set_rts,
+  .ucom_break       = &uvscom_set_break,
+  .ucom_param       = &uvscom_param,
+  .ucom_ioctl       = &uvscom_ioctl,
+  .ucom_open        = &uvscom_open,
+  .ucom_close       = &uvscom_close,
+  .ucom_start_read  = &uvscom_start_read,
+  .ucom_stop_read   = &uvscom_stop_read,
+  .ucom_start_write = &uvscom_start_write,
+  .ucom_stop_write  = &uvscom_stop_write,
+};
+
+static const struct usb_devno uvscom_devs [] = {
+    /* SUNTAC U-Cable type A4 */
+    { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS144L4 },
+    /* SUNTAC U-Cable type D2 */
+    { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_DS96L },
+    /* SUNTAC Ir-Trinity */
+    { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_IS96U },
+    /* SUNTAC U-Cable type P1 */
+    { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_PS64P1 },
+    /* SUNTAC Slipper U */
+    { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_VS10U },
+};
+
+static device_probe_t uvscom_match;
+static device_attach_t uvscom_attach;
+static device_detach_t uvscom_detach;
+
+static device_method_t uvscom_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, uvscom_match),
+	DEVMETHOD(device_attach, uvscom_attach),
+	DEVMETHOD(device_detach, uvscom_detach),
+	{ 0, 0 }
+};
+
+static driver_t uvscom_driver = {
+	"ucom",
+	uvscom_methods,
+	sizeof (struct uvscom_softc)
+};
+
+DRIVER_MODULE(uvscom, uhub, uvscom_driver, ucom_devclass, usbd_driver_load, 0);
+MODULE_DEPEND(uvscom, usb, 1, 1, 1);
+MODULE_DEPEND(uvscom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
+MODULE_VERSION(uvscom, UVSCOM_MODVER);
+
+static int	uvscomobufsiz = UVSCOM_DEFAULT_OPKTSIZE;
+static int	uvscominterval = UVSCOM_INTR_INTERVAL;
+
+remove:
+
+static int
+sysctl_hw_usb_uvscom_opktsize(SYSCTL_HANDLER_ARGS)
+{
+	int err, val;
+
+	val = uvscomobufsiz;
+	err = sysctl_handle_int(oidp, &val, sizeof(val), req);
+	if (err != 0 || req->newptr == NULL)
+		return (err);
+	if (0 < val && val <= UVSCOM_OBUFSIZE)
+		uvscomobufsiz = val;
+	else
+		err = EINVAL;
+
+	return (err);
+}
+
+static int
+sysctl_hw_usb_uvscom_interval(SYSCTL_HANDLER_ARGS)
+{
+	int err, val;
+
+	val = uvscominterval;
+	err = sysctl_handle_int(oidp, &val, sizeof(val), req);
+	if (err != 0 || req->newptr == NULL)
+		return (err);
+	if (0 < val && val <= 1000)
+		uvscominterval = val;
+	else
+		err = EINVAL;
+
+	return (err);
+}
+
+SYSCTL_PROC(_hw_usb_uvscom, OID_AUTO, opktsize, CTLTYPE_INT | CTLFLAG_RW,
+	    0, sizeof(int), sysctl_hw_usb_uvscom_opktsize,
+	    "I", "uvscom output packet size");
+SYSCTL_PROC(_hw_usb_uvscom, OID_AUTO, interval, CTLTYPE_INT | CTLFLAG_RW,
+	    0, sizeof(int), sysctl_hw_usb_uvscom_interval,
+	    "I", "uvscom interrpt pipe interval");
+
+static int
+uvscom_probe(device_t dev)
+{
+	struct usb_attach_arg *uaa = device_get_ivars(dev);
+
+	if (uaa->iface) {
+	    return UMATCH_NONE;
+	}
+
+	return (usb_lookup(uvscom_devs, uaa->vendor, uaa->product) ?
+		UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
+}
+
+static int
+uvscom_attach(device_t dev)
+{
+	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	struct uvscom_softc *sc = device_get_softc(dev);
+	usb_interface_descriptor_t *id;
+	struct usbd_interface *iface;
+	u_int16_t isize;
+	int error;
+
+	if (sc == NULL) {
+	    return ENOMEM;
+	}
+
+	usbd_set_desc(dev, uaa->device);
+
+	DPRINTF(0, "sc=%p\n", sc);
+
+	__callout_init_mtx(&(sc->sc_watchdog), &Giant,
+                           CALLOUT_RETURNUNLOCKED);
+
+	/* configure the device */
+
+	error = usbd_set_config_index(uaa->device, UVSCOM_CONFIG_INDEX, 1);
+	if (error) {
+	    device_printf(dev, "failed to set configuration, "
+			  "error=%s\n", usbd_errstr(error));
+	    goto detach;
+	}
+
+	iface = usbd_get_iface(uaa->device, UVSCOM_IFACE_INDEX);
+
+	if (iface == NULL) {
+	    DPRINTF(0, "no interface\n");
+	    goto detach;
+	}
+
+	id = usbd_get_interface_descriptor(iface);
+
+	if (id == NULL) {
+	    DPRINTF(0, "no interface descriptor\n");
+	    goto detach;
+	}
+
+	sc->sc_iface_no = id->bInterfaceNumber;
+	sc->sc_iface_index = UVSCOM_IFACE_INDEX;
+
+	error = usbd_transfer_setup(uaa->device, sc->sc_iface_index,
+				    sc->sc_xfer, uvscom_config,
+				    UVSCOM_N_TRANSFER,
+				    sc, &Giant, &(uvscom_detach_complete));
+	if (error) {
+	    DPRINTF(0, "could not allocate all USB transfers!\n");
+	    goto detach;
+	}
+
+	sc->sc_flag |= UVSCOM_FLAG_WAIT_USB;
+
+isize = UGETW(sc->sc_xfer[->wMaxPacketSize)
+
+	if (isize > UPLCOM_INTR_SIZE) {
+	    DPRINTF(0, "cannot handle an interrupt "
+		    "packet of %d bytes\n", isize);
+	    goto detach;
+	}
+
+	/* set transfer length */
+	sc->sc_xfer_intr[0]->length = isize;
+
+	sc->sc_dtr = -1;
+	sc->sc_rts = -1;
+	sc->sc_break = -1;
+	sc->sc_line_ctrl = UVSCOM_LINE_INIT;
+
+	ucom->sc_parent = sc;
+	ucom->sc_portno = 0;
+	ucom->sc_callback = &uvscom_callback;
+
+	error = ucom_attach(&(sc->sc_ucom), dev);
+
+	if (error) {
+	    goto detach;
+	}
+
+	/* start interrupt pipe */
+
+	usbd_transfer_start(sc->sc_xfer[4]);
+
+	/* start watchdog (returns unlocked) */
+
+	mtx_lock(&Giant);
+
+	uvscom_watchdog(sc);
+
+	return 0;
+
+ detach:
+	uvscom_detach(dev);
+	return ENXIO;
+}
+
+#if 0
+{
+	UCOM_UNK_PORTNO;
+	/* bulkin, bulkout set above */
+	ucom->sc_ibufsize = UVSCOM_IBUFSIZE;
+	ucom->sc_obufsize = uvscomobufsiz;
+	ucom->sc_ibufsizepad = UVSCOM_IBUFSIZE;
+	ucom->sc_opkthdrlen = 0;
+ }
+#endif
+
+static int
+uvscom_detach(device_t dev)
+{
+	struct umodem_softc *sc = device_get_softc(dev);
+	int error;
+
+	DPRINTF(0, "sc=%p\n", sc);
+
+	__callout_stop(&(sc->sc_watchdog));
+
+	/* stop interrupt pipe */
+
+	if (sc->sc_xfer[4]) {
+	    usbd_transfer_stop(sc->sc_xfer[4]);
+	}
+
+	ucom_detach(&(sc->sc_ucom));
+
+	usbd_transfer_unsetup(sc->sc_xfer, UVSCOM_N_TRANSFER);
+
+	/* wait for callbacks to finish */
+
+	while (sc->sc_flag & UMODEM_FLAG_WAIT_USB) {
+
+	    error = msleep(&(sc->sc_wakeup_detach), &Giant, 
+			   PRIBIO, "uvscom_sync", 0);
+	}
+
+	return 0;
+}
+
+static void
+uvscom_watchdog(void *arg)
+{
+	struct uvscom_softc *sc = arg;
+
+	mtx_assert(&Giant, MA_OWNED);
+
+	usbd_transfer_start(sc->sc_xfer[6]);
+
+	__callout_reset(&(sc->sc_watchdog), hz, 
+			&(uvscom_watchdog), sc);
+
+	mtx_unlock(&Giant);
+
+	return;
+}
+
+static void
+uvscom_read_status_callback(struct usbd_xfer *xfer)
+{
+	usb_device_request_t *req = xfer->buffer;
+	struct uvscom_softc *sc = xfer->priv_sc;
+
+	USBD_CHECK_STATUS(xfer);
+
+ tr_error:
+	DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
+
+ tr_transferred:
+	return;
+
+ tr_setup:
+	req->bmRequestType = UT_READ_VENDOR_DEVICE;
+	req->bRequest = UVSCOM_READ_STATUS;
+	USETW(req->wValue, 0);
+	USETW(req->wIndex, 0);
+	USETW(req->wLength, 2);
+	usbd_start_hardware(xfer);
+	return;
+}
+
+static usbd_status
+uvscom_readstat(struct uvscom_softc *sc)
+{
+	usbd_transfer_start(sc->sc_xfer[6]);
+	return USBD_NORMAL_COMPLETION;
+}
+
+static void
+uvscom_shutdown_callback(struct usbd_xfer *xfer)
+{
+	usb_device_request_t *req = xfer->buffer;
+	struct uvscom_softc *sc = xfer->priv_sc;
+
+	USBD_CHECK_STATUS(xfer);
+
+ tr_error:
+	DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
+
+ tr_transferred:
+	return;
+
+ tr_setup:
+	req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
+	req->bRequest = UVSCOM_SHUTDOWN;
+	USETW(req->wValue, 0);
+	USETW(req->wIndex, 0);
+	USETW(req->wLength, 0);
+	usbd_start_hardware(xfer);
+	return;
+}
+
+static void
+uvscom_shutdown(struct uvscom_softc *sc)
+{
+	usbd_transfer_start(sc->sc_xfer[7]);
+	return;
+}
+
+static void
+uvscom_set_line_callback(struct usbd_xfer *xfer)
+{
+	usb_device_request_t *req = xfer->buffer;
+	struct uvscom_softc *sc = xfer->priv_sc;
+
+	USBD_CHECK_STATUS(xfer);
+
+ tr_error:
+	DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
+
+ tr_transferred:
+ tr_setup:
+	if (sc->sc_flag &   UVSCOM_FLAG_SET_LINE) {
+	    sc->sc_flag &= ~UVSCOM_FLAG_SET_LINE;
+
+	    req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
+	    req->bRequest = UVSCOM_LINE_CTL;
+	    USETW(req->wValue, sc->sc_line_ctrl);
+	    USETW(req->wIndex, 0);
+	    USETW(req->wLength, 0);
+
+	    usbd_start_hardware(xfer);
+	}
+	return;
+}
+
+static void
+uvscom_set_line_coding_callback(struct usbd_xfer *xfer)
+{
+	usb_device_request_t *req = xfer->buffer;
+	struct uvscom_softc *sc = xfer->priv_sc;
+
+	USBD_CHECK_STATUS(xfer);
+
+ tr_error:
+	DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
+
+ tr_transferred:
+ tr_setup:
+	if (sc->sc_flag &   UVSCOM_FLAG_SET_LINE_SPEED) {
+	    sc->sc_flag &= ~UVSCOM_FLAG_SET_LINE_SPEED;
+
+	    req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
+	    req->bRequest = UVSCOM_SET_SPEED;
+	    USETW(req->wValue, sc->sc_line_speed);
+	    USETW(req->wIndex, 0);
+	    USETW(req->wLength, 0);
+	    usbd_start_hardware(xfer);
+	    return;
+	}
+	if (sc->sc_flag &   UVSCOM_FLAG_SET_LINE_PARM) {
+	    sc->sc_flag &= ~UVSCOM_FLAG_SET_LINE_PARM;
+
+	    req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
+	    req->bRequest = UVSCOM_SET_PARAM;
+	    USETW(req->wValue, sc->sc_line_parm);
+	    USETW(req->wIndex, 0);
+	    USETW(req->wLength, 0);
+	    usbd_start_hardware(xfer);
+	    return;
+	}
+	return;
+}
+
+static void
+uvscom_set_dtr(struct uvscom_softc *sc, u_int8_t onoff)
+{
+	DPRINTF(0, "onoff = %d\n", onoff);
+
+	if (sc->sc_dtr != onoff) {
+	    sc->sc_dtr = onoff;
+
+	    if (onoff)
+	      sc->sc_line_ctrl |= UVSCOM_DTR;
+	    else
+	      sc->sc_line_ctrl &= ~UVSCOM_DTR;
+
+	    sc->sc_flag |= UVSCOM_FLAG_SET_LINE;
+	    usbd_transfer_start(sc->sc_xfer[8]);
+	}
+	return;
+}
+
+static void
+uvscom_set_rts(struct uvscom_softc *sc, u_int8_t onoff)
+{
+	DPRINTF(0, "onoff = %d\n", onoff);
+
+	if (sc->sc_rts != onoff) {
+	    sc->sc_rts = onoff;
+
+	    if (onoff)
+	      sc->sc_line_ctrl |= UVSCOM_RTS;
+	    else
+	      sc->sc_line_ctrl &= ~UVSCOM_RTS;
+
+	    sc->sc_flag |= UVSCOM_FLAG_SET_LINE;
+	    usbd_transfer_start(sc->sc_xfer[8]);
+	}
+	return;
+}
+
+static void
+uvscom_set_break(struct uvscom_softc *sc, u_int8_t onoff)
+{
+	DPRINTF(0, "onoff = %d\n", onoff);
+
+	if (onoff)
+	    sc->sc_line_ctrl |= UVSCOM_BREAK;
+	else
+	    sc->sc_line_ctrl &= ~UVSCOM_BREAK;
+
+	sc->sc_flag |= UVSCOM_FLAG_SET_LINE;
+	usbd_transfer_start(sc->sc_xfer[8]);
+	return;
+}
+
+static int
+uvscom_param(struct ucom_softc *ucom, struct termios *t)
+{
+	struct uvscom_softc *sc = ucom->sc_parent;
+
+	DPRINTF(0, "\n");
+
+	switch (t->c_ospeed) {
+	case B150:
+		sc->sc_line_speed = UVSCOM_SPEED_150BPS;
+		break;
+	case B300:
+		sc->sc_line_speed = UVSCOM_SPEED_300BPS;
+		break;
+	case B600:
+		sc->sc_line_speed = UVSCOM_SPEED_600BPS;
+		break;
+	case B1200:
+		sc->sc_line_speed = UVSCOM_SPEED_1200BPS;
+		break;
+	case B2400:
+		sc->sc_line_speed = UVSCOM_SPEED_2400BPS;
+		break;
+	case B4800:
+		sc->sc_line_speed = UVSCOM_SPEED_4800BPS;
+		break;
+	case B9600:
+		sc->sc_line_speed = UVSCOM_SPEED_9600BPS;
+		break;
+	case B19200:
+		sc->sc_line_speed = UVSCOM_SPEED_19200BPS;
+		break;
+	case B38400:
+		sc->sc_line_speed = UVSCOM_SPEED_38400BPS;
+		break;
+	case B57600:
+		sc->sc_line_speed = UVSCOM_SPEED_57600BPS;
+		break;
+	case B115200:
+		sc->sc_line_speed = UVSCOM_SPEED_115200BPS;
+		break;
+	default:
+		return (EIO);
+	}
+
+	sc->sc_line_parm = 0; /* reset */
+
+	sc->sc_line_parm |= ((t->c_cflag & CSTOPB) ?
+			     UVSCOM_STOP_BIT_2 : UVSCOM_STOP_BIT_1);
+
+	sc->sc_line_parm |= ((t->c_cflag & PARENB) ?
+			     ((t->c_cflag & PARODD) ? 
+			      UVSCOM_PARITY_ODD : 
+			      UVSCOM_PARITY_EVEN) :
+			     UVSCOM_PARITY_NONE);
+
+	switch (t->c_cflag & CSIZE) {
+	case CS5:
+	    sc->sc_line_parm |= UVSCOM_DATA_BIT_5;
+	    break;
+	case CS6:
+	    sc->sc_line_parm |= UVSCOM_DATA_BIT_6;
+	    break;
+	case CS7:
+	    sc->sc_line_parm |= UVSCOM_DATA_BIT_7;
+	    break;
+	case CS8:
+	    sc->sc_line_parm |= UVSCOM_DATA_BIT_8;
+	    break;
+	default:
+	    return EIO;
+	}
+
+	sc->sc_flag |= (UVSCOM_FLAG_SET_LINE_SPEED|
+			UVSCOM_FLAG_SET_LINE_PARM);
+
+	usbd_transfer_start(sc->sc_xfer[9]);
+
+	return;
+}
+
+static int
+uvscom_open(struct ucom_softc *ucom)
+{
+	struct uvscom_softc *sc = ucom->sc_parent;
+	int err;
+	int i;
+
+	if (sc->sc_ucom.sc_dying)
+		return (ENXIO);
+
+	DPRINTF(("uvscom_open: sc = %p\n", sc));
+
+	/* change output packet size */
+	sc->sc_ucom.sc_obufsize = uvscomobufsiz;
+
+
+		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
+		err = usbd_open_pipe_intr(sc->sc_ucom.sc_iface,
+					  sc->sc_intr_number,
+					  USBD_SHORT_XFER_OK,
+					  &sc->sc_intr_pipe,
+					  sc,
+					  sc->sc_intr_buf,
+					  sc->sc_isize,
+					  uvscom_intr,
+					  uvscominterval);
+		if (err) {
+			printf("%s: cannot open interrupt pipe (addr %d)\n",
+				 USBDEVNAME(sc->sc_ucom.sc_dev),
+				 sc->sc_intr_number);
+			return (ENXIO);
+		}
+	} else {
+		DPRINTF(("uvscom_open: did not open interrupt pipe.\n"));
+	}
+
+	if ((sc->sc_unit_status & UVSCOM_USTAT_MASK) == 0) {
+		/* unit is not ready */
+
+		for (i = UVSCOM_UNIT_WAIT; i > 0; --i) {
+			tsleep(&err, TTIPRI, "uvsop", hz);	/* XXX */
+			if (ISSET(sc->sc_unit_status, UVSCOM_USTAT_MASK))
+				break;
+		}
+		if (i == 0) {
+			DPRINTF(("%s: unit is not ready\n",
+				 USBDEVNAME(sc->sc_ucom.sc_dev)));
+			return (ENXIO);
+		}
+
+		/* check PC Card was inserted */
+		if (ISSET(sc->sc_unit_status, UVSCOM_NOCARD)) {
+			DPRINTF(("%s: no card\n",
+				 USBDEVNAME(sc->sc_ucom.sc_dev)));
+			return (ENXIO);
+		}
+	}
+
+	return (0);
+}
+
+static void
+uvscom_close(struct ucom_softc *ucom)
+{
+	struct uvscom_softc *sc = ucom->sc_parent;
+	int err;
+
+	if (sc->sc_ucom.sc_dying)
+		return;
+
+	DPRINTF(("uvscom_close: close\n"));
+
+	uvscom_shutdown(sc);
+
+	if (sc->sc_intr_pipe != NULL) {
+		err = usbd_abort_pipe(sc->sc_intr_pipe);
+		if (err)
+			printf("%s: abort interrupt pipe failed: %s\n",
+				USBDEVNAME(sc->sc_ucom.sc_dev),
+					   usbd_errstr(err));
+		err = usbd_close_pipe(sc->sc_intr_pipe);
+		if (err)
+			printf("%s: close interrupt pipe failed: %s\n",
+				USBDEVNAME(sc->sc_ucom.sc_dev),
+					   usbd_errstr(err));
+		free(sc->sc_intr_buf, M_USBDEV);
+		sc->sc_intr_pipe = NULL;
+	}
+}
+
+static void
+uvscom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
+{
+	struct uvscom_softc *sc = priv;
+	u_int8_t *buf = sc->sc_intr_buf;
+	u_int8_t pstatus;
+
+	if (sc->sc_ucom.sc_dying)
+		return;
+
+	if (status != USBD_NORMAL_COMPLETION) {
+		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
+			return;
+
+		printf("%s: uvscom_intr: abnormal status: %s\n",
+			USBDEVNAME(sc->sc_ucom.sc_dev),
+			usbd_errstr(status));
+		usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
+		return;
+	}
+
+	DPRINTFN(2, ("%s: uvscom status = %02x %02x\n",
+		 USBDEVNAME(sc->sc_ucom.sc_dev), buf[0], buf[1]));
+
+	sc->sc_lsr = sc->sc_msr = 0;
+	sc->sc_unit_status = buf[1];
+
+	pstatus = buf[0];
+	if (ISSET(pstatus, UVSCOM_TXRDY))
+		SET(sc->sc_lsr, ULSR_TXRDY);
+	if (ISSET(pstatus, UVSCOM_RXRDY))
+		SET(sc->sc_lsr, ULSR_RXRDY);
+
+	pstatus = buf[1];
+	if (ISSET(pstatus, UVSCOM_CTS))
+		SET(sc->sc_msr, SER_CTS);
+	if (ISSET(pstatus, UVSCOM_DSR))
+		SET(sc->sc_msr, SER_DSR);
+	if (ISSET(pstatus, UVSCOM_DCD))
+		SET(sc->sc_msr, SER_DCD);
+
+	if (sc->sc_flag & UVSCOM_FLAG_OPEN) {
+	    ucom_status_change(&(sc->sc_ucom));
+	}
+	return;
+}
+
+static void
+uvscom_get_status(struct ucom_softc *ucom, u_int8_t *lsr, u_int8_t *msr)
+{
+	struct uvscom_softc *sc = ucom->sc_parent;
+
+	if (lsr != NULL)
+		*lsr = sc->sc_lsr;
+	if (msr != NULL)
+		*msr = sc->sc_msr;
+}
+
+#if 0 /* TODO */
+static int
+uvscom_ioctl(struct ucom_softc *ucom, u_long cmd, caddr_t data, int flag,
+	     usb_proc_ptr p)
+{
+	struct uvscom_softc *sc = ucom->sc_parent;
+	int error = 0;
+
+	if (sc->sc_ucom.sc_dying)
+		return (EIO);
+
+	DPRINTF(("uvscom_ioctl: cmd = 0x%08lx\n", cmd));
+
+	switch (cmd) {
+	case TIOCNOTTY:
+	case TIOCMGET:
+	case TIOCMSET:
+		break;

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606120522.k5C5MoPh021416>