PERFORCE change 99038 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Jun 12 06:56:07 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=99038
Change 99038 by hselasky at hselasky_mini_itx on 2006/06/12 06:53:02
Finished reworking "uvscom.c". Please test!
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/uvscom.c#5 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/uvscom.c#5 (text+ko) ====
@@ -134,13 +134,38 @@
#define UVSCOM_CTS 0x01
#define UVSCOM_USTAT_MASK (UVSCOM_NOCARD | UVSCOM_DSR | UVSCOM_CTS)
+/*
+ * 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 /* bytes */
+#define UVSCOM_OBUFSIZE 64 /* bytes */
+#define UVSCOM_INTR_SIZE 64 /* bytes */
+
+#ifndef UVSCOM_DEFAULT_OPKTSIZE
+#define UVSCOM_DEFAULT_OPKTSIZE 8
+#endif
+
+#define UVSCOM_N_TRANSFER 10
+
struct uvscom_softc {
struct ucom_softc sc_ucom;
struct __callout sc_watchdog;
+ struct usbd_xfer * sc_xfer[UVSCOM_N_TRANSFER];
+
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_int16_t sc_flag;
+#define UVSCOM_FLAG_WAIT_USB 0x0001
+#define UVSCOM_FLAG_WRITE_STALL 0x0002
+#define UVSCOM_FLAG_READ_STALL 0x0004
+#define UVSCOM_FLAG_INTR_STALL 0x0008
+#define UVSCOM_FLAG_OPEN 0x0010
+#define UVSCOM_FLAG_SET_LINE 0x0020
+#define UVSCOM_FLAG_SET_LINE_SPEED 0x0040
+#define UVSCOM_FLAG_SET_LINE_PARM 0x0080
u_int8_t sc_iface_no; /* interface number */
u_int8_t sc_iface_index; /* interface index */
@@ -148,37 +173,89 @@
u_int8_t sc_rts; /* current RTS state */
u_int8_t sc_lsr; /* local status register */
u_int8_t sc_msr; /* uvscom status register */
+ u_int8_t sc_unit_status; /* unit status */
+ u_int8_t sc_wakeup_detach; /* dummy */
+};
- XXX:
- int sc_iface_number;/* interface number */
+static device_probe_t uvscom_probe;
+static device_attach_t uvscom_attach;
+static device_detach_t uvscom_detach;
+
+static void
+uvscom_detach_complete(struct usbd_memory_info *info);
+
+static void
+uvscom_watchdog(void *arg);
+
+static void
+uvscom_write_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_write_clear_stall_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_read_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_read_clear_stall_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_intr_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_intr_clear_stall_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_read_status_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_shutdown_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_set_line_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_set_line_coding_callback(struct usbd_xfer *xfer);
+
+static void
+uvscom_set_dtr(struct ucom_softc *ucom, u_int8_t onoff);
+
+static void
+uvscom_set_rts(struct ucom_softc *ucom, u_int8_t onoff);
+
+static void
+uvscom_set_break(struct ucom_softc *ucom, u_int8_t onoff);
+
+static int
+uvscom_param(struct ucom_softc *ucom, struct termios *t);
+
+static int
+uvscom_open(struct ucom_softc *ucom);
- 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;
+static void
+uvscom_close(struct ucom_softc *ucom);
+static void
+uvscom_start_read(struct ucom_softc *ucom);
- u_int8_t sc_unit_status; /* unit status */
+static void
+uvscom_stop_read(struct ucom_softc *ucom);
- struct task sc_task;
-};
+static void
+uvscom_start_write(struct ucom_softc *ucom);
-/*
- * 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
+static void
+uvscom_stop_write(struct ucom_softc *ucom);
-#ifndef UVSCOM_DEFAULT_OPKTSIZE
-#define UVSCOM_DEFAULT_OPKTSIZE 8
-#endif
+static void
+uvscom_get_status(struct ucom_softc *ucom, u_int8_t *lsr, u_int8_t *msr);
-#define UVSCOM_N_TRANSFER X
+static int
+uvscom_ioctl(struct ucom_softc *ucom, u_long cmd, caddr_t data, int fflag,
+ struct thread *td);
-static const struct usbd_config umodem_config_data[UVSCOM_N_TRANSFER] = {
+static const struct usbd_config uvscom_config[UVSCOM_N_TRANSFER] = {
[0] = {
.type = UE_BULK,
@@ -186,7 +263,7 @@
.direction = UE_DIR_OUT,
.bufsize = UVSCOM_OBUFSIZE,
.flags = 0,
- .callback = &umodem_write_callback,
+ .callback = &uvscom_write_callback,
},
[1] = {
@@ -195,7 +272,7 @@
.direction = UE_DIR_IN,
.bufsize = UVSCOM_IBUFSIZE,
.flags = USBD_SHORT_XFER_OK,
- .callback = &umodem_read_callback,
+ .callback = &uvscom_read_callback,
},
[2] = {
@@ -203,7 +280,7 @@
.endpoint = 0x00, /* Control pipe */
.direction = -1,
.bufsize = sizeof(usb_device_request_t),
- .callback = &umodem_write_clear_stall_callback,
+ .callback = &uvscom_write_clear_stall_callback,
.timeout = 1000, /* 1 second */
},
@@ -212,7 +289,7 @@
.endpoint = 0x00, /* Control pipe */
.direction = -1,
.bufsize = sizeof(usb_device_request_t),
- .callback = &umodem_read_clear_stall_callback,
+ .callback = &uvscom_read_clear_stall_callback,
.timeout = 1000, /* 1 second */
},
@@ -221,8 +298,8 @@
.endpoint = -1, /* any */
.direction = UE_DIR_IN,
.flags = USBD_SHORT_XFER_OK,
- .bufsize = XXX,
- .callback = &umodem_intr_callback,
+ .bufsize = UVSCOM_INTR_SIZE,
+ .callback = &uvscom_intr_callback,
},
[5] = {
@@ -230,7 +307,7 @@
.endpoint = 0x00, /* Control pipe */
.direction = -1,
.bufsize = sizeof(usb_device_request_t),
- .callback = &umodem_intr_clear_stall_callback,
+ .callback = &uvscom_intr_clear_stall_callback,
.timeout = 1000, /* 1 second */
},
@@ -269,26 +346,21 @@
.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,
+ .ucom_get_status = &uvscom_get_status,
+ .ucom_set_dtr = &uvscom_set_dtr,
+ .ucom_set_rts = &uvscom_set_rts,
+ .ucom_set_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 [] = {
@@ -304,22 +376,17 @@
{ 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 }
+ DEVMETHOD(device_probe, uvscom_probe),
+ DEVMETHOD(device_attach, uvscom_attach),
+ DEVMETHOD(device_detach, uvscom_detach),
+ { 0, 0 }
};
static driver_t uvscom_driver = {
- "ucom",
- uvscom_methods,
- sizeof (struct uvscom_softc)
+ .name = "ucom",
+ .methods = uvscom_methods,
+ .size = sizeof (struct uvscom_softc),
};
DRIVER_MODULE(uvscom, uhub, uvscom_driver, ucom_devclass, usbd_driver_load, 0);
@@ -327,53 +394,7 @@
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);
@@ -444,25 +465,25 @@
sc->sc_flag |= UVSCOM_FLAG_WAIT_USB;
-isize = UGETW(sc->sc_xfer[->wMaxPacketSize)
+
+ isize = UGETW(sc->sc_xfer[4]->pipe->edesc->wMaxPacketSize);
- if (isize > UPLCOM_INTR_SIZE) {
+ if (isize > UVSCOM_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;
+ /* set interrupt transfer length */
+ sc->sc_xfer[4]->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;
+ sc->sc_ucom.sc_parent = sc;
+ sc->sc_ucom.sc_portno = 0;
+ sc->sc_ucom.sc_callback = &uvscom_callback;
error = ucom_attach(&(sc->sc_ucom), dev);
@@ -487,21 +508,27 @@
return ENXIO;
}
-#if 0
+static void
+uvscom_detach_complete(struct usbd_memory_info *info)
{
- 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
+ struct uvscom_softc *sc = info->priv_sc;
+
+ mtx_lock(&Giant);
+
+ if (sc->sc_flag & UVSCOM_FLAG_WAIT_USB) {
+ sc->sc_flag &= ~UVSCOM_FLAG_WAIT_USB;
+ wakeup(&(sc->sc_wakeup_detach));
+ }
+
+ mtx_unlock(&Giant);
+
+ return;
+}
static int
uvscom_detach(device_t dev)
{
- struct umodem_softc *sc = device_get_softc(dev);
+ struct uvscom_softc *sc = device_get_softc(dev);
int error;
DPRINTF(0, "sc=%p\n", sc);
@@ -520,7 +547,7 @@
/* wait for callbacks to finish */
- while (sc->sc_flag & UMODEM_FLAG_WAIT_USB) {
+ while (sc->sc_flag & UVSCOM_FLAG_WAIT_USB) {
error = msleep(&(sc->sc_wakeup_detach), &Giant,
PRIBIO, "uvscom_sync", 0);
@@ -547,10 +574,191 @@
}
static void
+uvscom_write_callback(struct usbd_xfer *xfer)
+{
+ struct uvscom_softc *sc = xfer->priv_sc;
+ u_int32_t actlen;
+
+ USBD_CHECK_STATUS(xfer);
+
+tr_error:
+ if (xfer->error != USBD_CANCELLED) {
+ sc->sc_flag |= UVSCOM_FLAG_WRITE_STALL;
+ usbd_transfer_start(sc->sc_xfer[2]);
+ }
+ return;
+
+tr_setup:
+tr_transferred:
+ if (sc->sc_flag & UVSCOM_FLAG_WRITE_STALL) {
+ usbd_transfer_start(sc->sc_xfer[2]);
+ return;
+ }
+
+ if(ucom_get_data(&(sc->sc_ucom), xfer->buffer, UVSCOM_OBUFSIZE, &actlen)) {
+
+ xfer->length = actlen;
+
+ usbd_start_hardware(xfer);
+ }
+ return;
+}
+
+static void
+uvscom_write_clear_stall_callback(struct usbd_xfer *xfer)
+{
+ struct uvscom_softc *sc = xfer->priv_sc;
+
+ USBD_CHECK_STATUS(xfer);
+
+ tr_setup:
+ /* start clear stall */
+ usbd_clear_stall_tr_setup(xfer, sc->sc_xfer[0]);
+ return;
+
+ tr_transferred:
+ usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer[0]);
+ sc->sc_flag &= ~UVSCOM_FLAG_WRITE_STALL;
+ usbd_transfer_start(sc->sc_xfer[0]);
+ return;
+
+ tr_error:
+ sc->sc_flag &= ~UVSCOM_FLAG_WRITE_STALL;
+ DPRINTF(0, "clear stall failed, error=%s\n",
+ usbd_errstr(xfer->error));
+ return;
+}
+
+static void
+uvscom_read_callback(struct usbd_xfer *xfer)
+{
+ struct uvscom_softc *sc = xfer->priv_sc;
+
+ USBD_CHECK_STATUS(xfer);
+
+ tr_error:
+ if (xfer->error != USBD_CANCELLED) {
+ sc->sc_flag |= UVSCOM_FLAG_READ_STALL;
+ usbd_transfer_start(sc->sc_xfer[3]);
+ }
+ return;
+
+ tr_transferred:
+ ucom_put_data(&(sc->sc_ucom), xfer->buffer, xfer->actlen);
+
+ tr_setup:
+ if (sc->sc_flag & UVSCOM_FLAG_READ_STALL) {
+ usbd_transfer_start(sc->sc_xfer[3]);
+ } else {
+ usbd_start_hardware(xfer);
+ }
+ return;
+}
+
+static void
+uvscom_read_clear_stall_callback(struct usbd_xfer *xfer)
+{
+ struct uvscom_softc *sc = xfer->priv_sc;
+
+ USBD_CHECK_STATUS(xfer);
+
+ tr_setup:
+ /* start clear stall */
+ usbd_clear_stall_tr_setup(xfer, sc->sc_xfer[1]);
+ return;
+
+ tr_transferred:
+ usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer[1]);
+ sc->sc_flag &= ~UVSCOM_FLAG_READ_STALL;
+ usbd_transfer_start(sc->sc_xfer[1]);
+ return;
+
+ tr_error:
+ sc->sc_flag &= ~UVSCOM_FLAG_READ_STALL;
+ DPRINTF(0, "clear stall failed, error=%s\n",
+ usbd_errstr(xfer->error));
+ return;
+}
+
+static void
+uvscom_intr_callback(struct usbd_xfer *xfer)
+{
+ struct uvscom_softc *sc = xfer->priv_sc;
+ u_int8_t *buf = xfer->buffer;
+
+ USBD_CHECK_STATUS(xfer);
+
+ tr_error:
+ if (xfer->error != USBD_CANCELLED) {
+ sc->sc_flag |= UVSCOM_FLAG_INTR_STALL;
+ usbd_transfer_start(sc->sc_xfer[5]);
+ }
+ return;
+
+ tr_transferred:
+ if (xfer->actlen >= 2) {
+ sc->sc_lsr = 0;
+ sc->sc_msr = 0;
+ sc->sc_unit_status = buf[1];
+
+ if (buf[0] & UVSCOM_TXRDY) {
+ sc->sc_lsr |= ULSR_TXRDY;
+ }
+ if (buf[0] & UVSCOM_RXRDY) {
+ sc->sc_lsr |= ULSR_RXRDY;
+ }
+ if (buf[1] & UVSCOM_CTS) {
+ sc->sc_msr |= SER_CTS;
+ }
+ if (buf[1] & UVSCOM_DSR) {
+ sc->sc_msr |= SER_DSR;
+ }
+ if (buf[1] & UVSCOM_DCD) {
+ sc->sc_msr |= SER_DCD;
+ }
+
+ if (sc->sc_flag & UVSCOM_FLAG_OPEN) {
+ ucom_status_change(&(sc->sc_ucom));
+ }
+ }
+ tr_setup:
+ if (sc->sc_flag & UVSCOM_FLAG_INTR_STALL) {
+ usbd_transfer_start(sc->sc_xfer[5]);
+ } else {
+ usbd_start_hardware(xfer);
+ }
+ return;
+}
+
+static void
+uvscom_intr_clear_stall_callback(struct usbd_xfer *xfer)
+{
+ struct uvscom_softc *sc = xfer->priv_sc;
+
+ USBD_CHECK_STATUS(xfer);
+
+ tr_setup:
+ /* start clear stall */
+ usbd_clear_stall_tr_setup(xfer, sc->sc_xfer[4]);
+ return;
+
+ tr_transferred:
+ usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer[4]);
+ sc->sc_flag &= ~UVSCOM_FLAG_INTR_STALL;
+ usbd_transfer_start(sc->sc_xfer[4]);
+ return;
+
+ tr_error:
+ sc->sc_flag &= ~UVSCOM_FLAG_INTR_STALL;
+ DPRINTF(0, "clear stall failed, error=%s\n",
+ usbd_errstr(xfer->error));
+ 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);
@@ -570,18 +778,10 @@
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);
@@ -602,13 +802,6 @@
}
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;
@@ -664,7 +857,7 @@
req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
req->bRequest = UVSCOM_SET_PARAM;
- USETW(req->wValue, sc->sc_line_parm);
+ USETW(req->wValue, sc->sc_line_param);
USETW(req->wIndex, 0);
USETW(req->wLength, 0);
usbd_start_hardware(xfer);
@@ -674,8 +867,10 @@
}
static void
-uvscom_set_dtr(struct uvscom_softc *sc, u_int8_t onoff)
+uvscom_set_dtr(struct ucom_softc *ucom, u_int8_t onoff)
{
+ struct uvscom_softc *sc = ucom->sc_parent;
+
DPRINTF(0, "onoff = %d\n", onoff);
if (sc->sc_dtr != onoff) {
@@ -693,8 +888,10 @@
}
static void
-uvscom_set_rts(struct uvscom_softc *sc, u_int8_t onoff)
+uvscom_set_rts(struct ucom_softc *ucom, u_int8_t onoff)
{
+ struct uvscom_softc *sc = ucom->sc_parent;
+
DPRINTF(0, "onoff = %d\n", onoff);
if (sc->sc_rts != onoff) {
@@ -712,8 +909,10 @@
}
static void
-uvscom_set_break(struct uvscom_softc *sc, u_int8_t onoff)
+uvscom_set_break(struct ucom_softc *ucom, u_int8_t onoff)
{
+ struct uvscom_softc *sc = ucom->sc_parent;
+
DPRINTF(0, "onoff = %d\n", onoff);
if (onoff)
@@ -771,12 +970,12 @@
return (EIO);
}
- sc->sc_line_parm = 0; /* reset */
+ sc->sc_line_param = 0; /* reset */
- sc->sc_line_parm |= ((t->c_cflag & CSTOPB) ?
+ sc->sc_line_param |= ((t->c_cflag & CSTOPB) ?
UVSCOM_STOP_BIT_2 : UVSCOM_STOP_BIT_1);
- sc->sc_line_parm |= ((t->c_cflag & PARENB) ?
+ sc->sc_line_param |= ((t->c_cflag & PARENB) ?
((t->c_cflag & PARODD) ?
UVSCOM_PARITY_ODD :
UVSCOM_PARITY_EVEN) :
@@ -784,16 +983,16 @@
switch (t->c_cflag & CSIZE) {
case CS5:
- sc->sc_line_parm |= UVSCOM_DATA_BIT_5;
+ sc->sc_line_param |= UVSCOM_DATA_BIT_5;
break;
case CS6:
- sc->sc_line_parm |= UVSCOM_DATA_BIT_6;
+ sc->sc_line_param |= UVSCOM_DATA_BIT_6;
break;
case CS7:
- sc->sc_line_parm |= UVSCOM_DATA_BIT_7;
+ sc->sc_line_param |= UVSCOM_DATA_BIT_7;
break;
case CS8:
- sc->sc_line_parm |= UVSCOM_DATA_BIT_8;
+ sc->sc_line_param |= UVSCOM_DATA_BIT_8;
break;
default:
return EIO;
@@ -804,143 +1003,73 @@
usbd_transfer_start(sc->sc_xfer[9]);
- return;
+ return 0;
}
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(0, "sc = %p\n", sc);
- DPRINTF(("uvscom_open: sc = %p\n", sc));
+ sc->sc_flag |= UVSCOM_FLAG_OPEN;
- /* change output packet size */
- sc->sc_ucom.sc_obufsize = uvscomobufsiz;
+ /* check if PC card was inserted */
-
- 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_NOCARD) {
+ DPRINTF(0, "no PC card!\n");
+ return ENXIO;
}
- 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);
+ 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(0, "sc=%p\n", sc);
- DPRINTF(("uvscom_close: close\n"));
+ usbd_transfer_start(sc->sc_xfer[7]);
- uvscom_shutdown(sc);
+ sc->sc_flag &= ~UVSCOM_FLAG_OPEN;
- 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;
- }
+ return;
}
static void
-uvscom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
+uvscom_start_read(struct ucom_softc *ucom)
{
- struct uvscom_softc *sc = priv;
- u_int8_t *buf = sc->sc_intr_buf;
- u_int8_t pstatus;
+ struct uvscom_softc *sc = ucom->sc_parent;
+ usbd_transfer_start(sc->sc_xfer[1]);
+ return;
+}
- if (sc->sc_ucom.sc_dying)
- return;
+static void
+uvscom_stop_read(struct ucom_softc *ucom)
+{
+ struct uvscom_softc *sc = ucom->sc_parent;
+ usbd_transfer_stop(sc->sc_xfer[3]);
+ usbd_transfer_stop(sc->sc_xfer[1]);
+ return;
+}
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
+static void
+uvscom_start_write(struct ucom_softc *ucom)
+{
+ struct uvscom_softc *sc = ucom->sc_parent;
+ usbd_transfer_start(sc->sc_xfer[0]);
+ 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));
- }
+static void
+uvscom_stop_write(struct ucom_softc *ucom)
+{
+ struct uvscom_softc *sc = ucom->sc_parent;
+ usbd_transfer_stop(sc->sc_xfer[2]);
+ usbd_transfer_stop(sc->sc_xfer[0]);
return;
}
@@ -949,37 +1078,33 @@
{
struct uvscom_softc *sc = ucom->sc_parent;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
+ if (lsr) {
+ *lsr = sc->sc_lsr;
+ }
+ if (msr) {
+ *msr = sc->sc_msr;
+ }
+ return;
}
-#if 0 /* TODO */
static int
-uvscom_ioctl(struct ucom_softc *ucom, u_long cmd, caddr_t data, int flag,
- usb_proc_ptr p)
+uvscom_ioctl(struct ucom_softc *ucom, u_long cmd, caddr_t data, int fflag,
+ struct thread *td)
{
- struct uvscom_softc *sc = ucom->sc_parent;
- int error = 0;
+ int error = ENOTTY;
- if (sc->sc_ucom.sc_dying)
- return (EIO);
-
- DPRINTF(("uvscom_ioctl: cmd = 0x%08lx\n", cmd));
+ DPRINTF(0, "cmd = 0x%08lx\n", cmd);
switch (cmd) {
case TIOCNOTTY:
case TIOCMGET:
case TIOCMSET:
- break;
+ break;
default:
- DPRINTF(("uvscom_ioctl: unknown\n"));
- error = ENOTTY;
- break;
+ DPRINTF(0, "unknown\n");
+ error = ENOTTY;
+ break;
}
-
- return (error);
+ return error;
}
-#endif
More information about the p4-projects
mailing list