PERFORCE change 98570 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Jun 5 15:38:57 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=98570
Change 98570 by hselasky at hselasky_mini_itx on 2006/06/05 15:36:05
Converted "ulpt" into using the new "USB cdev".
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/ulpt.c#6 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_cdev.c#2 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#8 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/ulpt.c#6 (text+ko) ====
@@ -60,7 +60,7 @@
#include <dev/usb/usb_subr.h>
#include <dev/usb/usb_quirks.h>
-__FBSDID("$FreeBSD: src/sys/dev/usb/ulpt.c,v 1.68 2005/11/12 17:39:31 iedowse Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/usb/ulpt.c $");
#ifdef USB_DEBUG
#define DPRINTF(n,fmt,...) \
@@ -75,12 +75,10 @@
#define DPRINTF(...)
#endif
-#define DEV2SC(dev) (dev)->si_drv1
-
#define ULPT_BSIZE (1<<17) /* bytes */
#define ULPT_IFQ_MAXLEN 2 /* units */
#define ULPT_WATCHDOG_INTERVAL 5 /* times per second */
-#define ULPT_N_TRANSFER 4 /* units */
+#define ULPT_N_TRANSFER 6 /* units */
#define UR_GET_DEVICE_ID 0x00
#define UR_GET_PORT_STATUS 0x01
@@ -93,54 +91,27 @@
#define LPS_MASK (LPS_SELECT|LPS_NERR|LPS_NOPAPER)
struct ulpt_softc {
- device_t sc_dev;
- struct usbd_device * sc_udev;
- struct cdev * sc_cdev_1;
- struct cdev * sc_cdev_2;
- struct usbd_xfer * sc_xfer[ULPT_N_TRANSFER];
+ struct usb_cdev sc_cdev;
struct __callout sc_watchdog;
struct mtx sc_mtx;
- struct usbd_ifqueue sc_rdq_free;
- struct usbd_ifqueue sc_rdq_used;
- struct usbd_ifqueue sc_wrq_free;
- struct usbd_ifqueue sc_wrq_used;
- void * sc_mem_ptr_1; /* should be freed at detach */
- void * sc_mem_ptr_2; /* should be freed at detach */
+ device_t sc_dev;
+ struct usbd_xfer * sc_xfer[ULPT_N_TRANSFER];
- u_int32_t sc_flags;
-#define ULPT_FLAG_DEV_OPEN 0x00000001 /* device is open */
-#define ULPT_FLAG_NO_READ 0x00000002 /* device has no read endpoint */
-#define ULPT_FLAG_RST_SLP 0x00000004 /* device is sleeping */
-#define ULPT_FLAG_RST_WUP 0x00000008 /* device is waiting for wakeup */
-#define ULPT_FLAG_WR_UIO 0x00000010 /* device is doing I/O */
-#define ULPT_FLAG_RD_UIO 0x00000020 /* device is doing I/O */
-#define ULPT_FLAG_WR_SLP 0x00000040 /* device is sleeping */
-#define ULPT_FLAG_RD_SLP 0x00000080 /* device is sleeping */
-#define ULPT_FLAG_WR_WUP 0x00000100 /* device is waiting for wakeup */
-#define ULPT_FLAG_RD_WUP 0x00000200 /* device is waiting for wakeup */
-#define ULPT_FLAG_CLOSING 0x00000400 /* device is closing */
-#define ULPT_FLAG_GONE 0x00000800 /* device is gone */
-#define ULPT_FLAG_WAIT_USB 0x00001000 /* device is waiting for USB callbacks */
-#define ULPT_FLAG_WAIT_CO 0x00002000 /* device is waiting for callouts */
-#define ULPT_FLAG_DUMP_READ 0x00004000 /* device is not opened for read */
-#define ULPT_FLAG_WR_FLUSH 0x00008000 /* device is flushing write data */
-#define ULPT_FLAG_NO_FLUSH 0x00010000 /* device should not flush write data */
-#define ULPT_FLAG_PIPE_ERR 0x00020000 /* device has signalled an error */
+ u_int8_t sc_flags;
+#define ULPT_FLAG_NO_READ 0x01 /* device has no read endpoint */
+#define ULPT_FLAG_DUMP_READ 0x02 /* device is not opened for read */
+#define ULPT_FLAG_WAIT_USB 0x04 /* device is waiting for USB callbacks */
+#define ULPT_FLAG_WAIT_CO 0x08 /* device is waiting for callouts */
+#define ULPT_FLAG_READ_STALL 0x10 /* read transfer stalled */
+#define ULPT_FLAG_WRITE_STALL 0x20 /* write transfer stalled */
+#define ULPT_FLAG_RESETTING 0x40 /* device is resetting */
u_int8_t sc_iface_no;
u_int8_t sc_last_status;
-
u_int8_t sc_wakeup_detach; /* dummy */
- u_int8_t sc_wakeup_reset; /* dummy */
- u_int8_t sc_wakeup_read; /* dummy */
- u_int8_t sc_wakeup_write; /* dummy */
- u_int8_t sc_wakeup_flush; /* dummy */
- u_int8_t sc_wakeup_sync_1; /* dummy */
};
-extern cdevsw_t ulpt_cdevsw;
-
static void
ulpt_watchdog(void *__sc)
{
@@ -154,9 +125,12 @@
usbd_transfer_start(sc->sc_xfer[2]);
- if ((sc->sc_flags & (ULPT_FLAG_NO_READ|ULPT_FLAG_DUMP_READ)) &&
- (sc->sc_flags & (ULPT_FLAG_DEV_OPEN)) &&
- (!(sc->sc_flags & (ULPT_FLAG_CLOSING)))) {
+ if ((sc->sc_flags & (ULPT_FLAG_NO_READ|
+ ULPT_FLAG_DUMP_READ)) &&
+ (!(sc->sc_flags & ULPT_FLAG_RESETTING)) &&
+ (sc->sc_cdev.sc_flags & (USB_CDEV_FLAG_OPEN_READ|
+ USB_CDEV_FLAG_OPEN_WRITE)) &&
+ (!(sc->sc_cdev.sc_flags & USB_CDEV_FLAG_CLOSING_READ))) {
/* start reading of data, if not already started */
@@ -176,56 +150,55 @@
ulpt_write_callback(struct usbd_xfer *xfer)
{
struct ulpt_softc *sc = xfer->priv_sc;
- struct usbd_mbuf *m;
+ u_int32_t actlen;
USBD_CHECK_STATUS(xfer);
tr_transferred:
tr_setup:
- USBD_IF_DEQUEUE(&sc->sc_wrq_used, m);
+ if (sc->sc_flags & ULPT_FLAG_WRITE_STALL) {
+ return;
+ }
+ if (usb_cdev_get_data(&(sc->sc_cdev), xfer->buffer,
+ ULPT_BSIZE, &actlen, 0)) {
- if (m) {
+ xfer->length = actlen;
+ usbd_start_hardware(xfer);
+ }
+ return;
- if (m->cur_data_len > ULPT_BSIZE) {
- /* extra length check */
- m->cur_data_len = ULPT_BSIZE;
- }
+ tr_error:
+ if (xfer->error != USBD_CANCELLED) {
+ /* try to clear stall first */
+ sc->sc_flags |= ULPT_FLAG_WRITE_STALL;
+ usbd_transfer_start(sc->sc_xfer[4]);
+ }
+ return;
+}
- bcopy(m->cur_data_ptr, xfer->buffer, m->cur_data_len);
- xfer->length = m->cur_data_len;
+static void
+ulpt_write_clear_stall_callback(struct usbd_xfer *xfer)
+{
+ struct ulpt_softc *sc = xfer->priv_sc;
- USBD_IF_ENQUEUE(&sc->sc_wrq_free, m);
+ USBD_CHECK_STATUS(xfer);
- usbd_start_hardware(xfer);
+ tr_setup:
+ /* start clear stall */
+ usbd_clear_stall_tr_setup(xfer, sc->sc_xfer[0]);
+ return;
- if (sc->sc_flags & ULPT_FLAG_WR_WUP) {
- sc->sc_flags &= ~ULPT_FLAG_WR_WUP;
- wakeup(&(sc->sc_wakeup_write));
- }
+ tr_transferred:
+ usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer[0]);
- } else {
- if (sc->sc_flags & ULPT_FLAG_WR_FLUSH) {
- sc->sc_flags &= ~ULPT_FLAG_WR_FLUSH;
- wakeup(&(sc->sc_wakeup_flush));
- }
- }
+ sc->sc_flags &= ~ULPT_FLAG_WRITE_STALL;
+ usbd_transfer_start(sc->sc_xfer[0]);
return;
tr_error:
- DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
-
- sc->sc_flags |= ULPT_FLAG_PIPE_ERR;
-
- if (sc->sc_flags & ULPT_FLAG_WR_WUP) {
- sc->sc_flags &= ~ULPT_FLAG_WR_WUP;
- wakeup(&(sc->sc_wakeup_write));
- }
-
- if (sc->sc_flags & ULPT_FLAG_WR_FLUSH) {
- sc->sc_flags &= ~ULPT_FLAG_WR_FLUSH;
- wakeup(&(sc->sc_wakeup_flush));
- }
-
+ /* bomb out */
+ sc->sc_flags &= ~ULPT_FLAG_WRITE_STALL;
+ usb_cdev_get_data_error(&(sc->sc_cdev));
return;
}
@@ -242,45 +215,52 @@
return;
}
- USBD_IF_DEQUEUE(&sc->sc_rdq_free, m);
+ usb_cdev_put_data(&(sc->sc_cdev), xfer->buffer, xfer->actlen, 1);
+
+ tr_setup:
+ if (sc->sc_flags & ULPT_FLAG_READ_STALL) {
+ return;
+ }
+
+ USBD_IF_POLL(&sc->sc_cdev.sc_rdq_free, m);
if (m) {
- USBD_MBUF_RESET(m);
+ usbd_start_hardware(xfer);
+ }
+ return;
- if (xfer->actlen > ULPT_BSIZE) {
- /* extra length check */
- xfer->actlen = ULPT_BSIZE;
- }
+ tr_error:
+ if (xfer->error != USBD_CANCELLED) {
+ /* try to clear stall first */
+ sc->sc_flags |= ULPT_FLAG_READ_STALL;
+ usbd_transfer_start(sc->sc_xfer[5]);
+ }
+ return;
+}
- bcopy(xfer->buffer, m->cur_data_ptr, xfer->actlen);
- m->cur_data_len = xfer->actlen;
+static void
+ulpt_read_clear_stall_callback(struct usbd_xfer *xfer)
+{
+ struct ulpt_softc *sc = xfer->priv_sc;
- USBD_IF_ENQUEUE(&sc->sc_rdq_used, m);
-
- if (sc->sc_flags & ULPT_FLAG_RD_WUP) {
- sc->sc_flags &= ~ULPT_FLAG_RD_WUP;
- wakeup(&(sc->sc_wakeup_read));
- }
- }
+ USBD_CHECK_STATUS(xfer);
tr_setup:
- USBD_IF_POLL(&sc->sc_rdq_free, m);
+ /* start clear stall */
+ usbd_clear_stall_tr_setup(xfer, sc->sc_xfer[1]);
+ return;
- if (m) {
- usbd_start_hardware(xfer);
- }
+ tr_transferred:
+ usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer[1]);
+ sc->sc_flags &= ~ULPT_FLAG_READ_STALL;
+ usbd_transfer_start(sc->sc_xfer[1]);
return;
tr_error:
- DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
-
- sc->sc_flags |= ULPT_FLAG_PIPE_ERR;
-
- if (sc->sc_flags & ULPT_FLAG_RD_WUP) {
- sc->sc_flags &= ~ULPT_FLAG_RD_WUP;
- wakeup(&(sc->sc_wakeup_read));
- }
+ /* bomb out */
+ sc->sc_flags &= ~ULPT_FLAG_READ_STALL;
+ usb_cdev_put_data_error(&(sc->sc_cdev));
return;
}
@@ -335,6 +315,10 @@
USBD_CHECK_STATUS(xfer);
tr_error:
+ if (xfer->error == USBD_CANCELLED) {
+ return;
+ }
+
if (req->bmRequestType == UT_WRITE_CLASS_OTHER) {
/*
* There was a mistake in the USB printer 1.0 spec that
@@ -354,11 +338,7 @@
}
tr_transferred:
- if (sc->sc_flags & ULPT_FLAG_RST_WUP) {
- sc->sc_flags &= ~ULPT_FLAG_RST_WUP;
-
- wakeup(&(sc->sc_wakeup_reset));
- }
+ usb_cdev_wakeup(&(sc->sc_cdev));
return;
tr_setup:
@@ -409,14 +389,109 @@
.callback = &ulpt_reset_callback,
.timeout = 1000, /* 1 second */
},
+
+ [4] = {
+ .type = UE_CONTROL,
+ .endpoint = 0x00, /* Control pipe */
+ .direction = -1,
+ .bufsize = sizeof(usb_device_request_t),
+ .callback = &ulpt_write_clear_stall_callback,
+ .timeout = 1000, /* 1 second */
+ },
+
+ [5] = {
+ .type = UE_CONTROL,
+ .endpoint = 0x00, /* Control pipe */
+ .direction = -1,
+ .bufsize = sizeof(usb_device_request_t),
+ .callback = &ulpt_read_clear_stall_callback,
+ .timeout = 1000, /* 1 second */
+ },
};
+static void
+ulpt_start_read(struct usb_cdev *cdev)
+{
+ struct ulpt_softc *sc = cdev->sc_priv_ptr;
+ usbd_transfer_start(sc->sc_xfer[1]);
+ return;
+}
+
+static void
+ulpt_stop_read(struct usb_cdev *cdev)
+{
+ struct ulpt_softc *sc = cdev->sc_priv_ptr;
+ usbd_transfer_stop(sc->sc_xfer[5]);
+ usbd_transfer_stop(sc->sc_xfer[1]);
+ return;
+}
+
+static void
+ulpt_start_write(struct usb_cdev *cdev)
+{
+ struct ulpt_softc *sc = cdev->sc_priv_ptr;
+ usbd_transfer_start(sc->sc_xfer[0]);
+ return;
+}
+
+static void
+ulpt_stop_write(struct usb_cdev *cdev)
+{
+ struct ulpt_softc *sc = cdev->sc_priv_ptr;
+ usbd_transfer_stop(sc->sc_xfer[4]);
+ usbd_transfer_stop(sc->sc_xfer[0]);
+ return;
+}
+
+static int32_t
+ulpt_open(struct usb_cdev *cdev, int32_t fflags,
+ int32_t devtype, struct thread *td)
+{
+ u_int8_t prime = ((cdev->sc_last_cdev == cdev->sc_cdev[0]) &&
+ (cdev->sc_first_open));
+ struct ulpt_softc *sc = cdev->sc_priv_ptr;
+ int32_t error = 0;
+
+ if (prime) {
+ DPRINTF(0, "opening prime device (reset)\n");
+
+ sc->sc_flags |= ULPT_FLAG_RESETTING;
+
+ usbd_transfer_start(sc->sc_xfer[3]);
+
+ error = usb_cdev_sleep(&(sc->sc_cdev), fflags);
+
+ usbd_transfer_stop(sc->sc_xfer[3]);
+
+ sc->sc_flags &= ~ULPT_FLAG_RESETTING;
+
+ if (error) {
+ goto done;
+ }
+ }
+
+ if (cdev->sc_flags & USB_CDEV_FLAG_OPEN_READ) {
+ sc->sc_flags &= ~ULPT_FLAG_DUMP_READ;
+ } else {
+ sc->sc_flags |= ULPT_FLAG_DUMP_READ;
+ }
+ done:
+ return error;
+}
+
+static int32_t
+ulpt_ioctl(struct usb_cdev *cdev, u_long cmd, caddr_t data,
+ int32_t fflags, struct thread *td)
+{
+ return ENODEV;
+}
+
+
/* prototypes */
static device_probe_t ulpt_probe;
static device_attach_t ulpt_attach;
static device_detach_t ulpt_detach;
-static d_close_t ulpt_close;
static int
ulpt_probe(device_t dev)
@@ -450,7 +525,7 @@
mtx_lock(&(sc->sc_mtx));
- if (sc->sc_flags & ULPT_FLAG_WAIT_USB) {
+ if (sc->sc_flags & ULPT_FLAG_WAIT_USB) {
sc->sc_flags &= ~ULPT_FLAG_WAIT_USB;
wakeup(&(sc->sc_wakeup_detach));
}
@@ -467,22 +542,19 @@
struct ulpt_softc *sc = device_get_softc(dev);
struct usbd_interface *iface_ptr = uaa->iface;
usb_interface_descriptor_t *id;
+ const char * p_buf[3];
int32_t iface_index = uaa->iface_index;
int32_t iface_alt_index = 0;
int32_t unit = device_get_unit(dev);
- usbd_status err;
+ int32_t error;
+ char buf_1[16];
+ char buf_2[16];
DPRINTF(10, "sc=%p\n", sc);
sc->sc_dev = dev;
- sc->sc_udev = uaa->device;
- sc->sc_rdq_free.ifq_maxlen = ULPT_IFQ_MAXLEN;
- sc->sc_rdq_used.ifq_maxlen = ULPT_IFQ_MAXLEN;
- sc->sc_wrq_free.ifq_maxlen = ULPT_IFQ_MAXLEN;
- sc->sc_wrq_used.ifq_maxlen = ULPT_IFQ_MAXLEN;
-
- usbd_set_desc(dev, sc->sc_udev);
+ usbd_set_desc(dev, uaa->device);
mtx_init(&(sc->sc_mtx), "ulpt lock", NULL, MTX_DEF|MTX_RECURSE);
@@ -494,30 +566,16 @@
sc->sc_flags |= ULPT_FLAG_WAIT_CO;
#endif
- sc->sc_mem_ptr_1 =
- usbd_alloc_mbufs(M_DEVBUF, &(sc->sc_rdq_free), ULPT_BSIZE, ULPT_IFQ_MAXLEN);
-
- if (sc->sc_mem_ptr_1 == NULL) {
- goto detach;
- }
-
- sc->sc_mem_ptr_2 =
- usbd_alloc_mbufs(M_DEVBUF, &(sc->sc_wrq_free), ULPT_BSIZE, ULPT_IFQ_MAXLEN);
-
- if (sc->sc_mem_ptr_2 == NULL) {
- goto detach;
- }
-
/* search through all the descriptors looking for bidir mode */
while(iface_alt_index < 32) {
- err = usbd_fill_iface_data
- (sc->sc_udev, iface_index, iface_alt_index);
+ error = usbd_fill_iface_data
+ (uaa->device, iface_index, iface_alt_index);
- if (err) {
+ if (error) {
DPRINTF(0, "end of alternate settings, "
- "error=%s\n", usbd_errstr(err));
+ "error=%s\n", usbd_errstr(error));
goto detach;
}
@@ -540,29 +598,29 @@
if (iface_alt_index) {
- err = usbreq_set_interface
- (sc->sc_udev, iface_index, iface_alt_index);
+ error = usbreq_set_interface
+ (uaa->device, iface_index, iface_alt_index);
- if (err) {
+ if (error) {
DPRINTF(0, "could not set alternate "
- "config, error=%s\n", usbd_errstr(err));
+ "config, error=%s\n", usbd_errstr(error));
goto detach;
}
}
sc->sc_iface_no = id->bInterfaceNumber;
- err = usbd_transfer_setup(sc->sc_udev, iface_index, sc->sc_xfer,
- ulpt_config, ULPT_N_TRANSFER, sc, &(sc->sc_mtx),
- &ulpt_detach_complete);
- if (err) {
- DPRINTF(0, "error=%s\n", usbd_errstr(err)) ;
+ error = usbd_transfer_setup(uaa->device, iface_index,
+ sc->sc_xfer, ulpt_config, ULPT_N_TRANSFER,
+ sc, &(sc->sc_mtx), &(ulpt_detach_complete));
+ if (error) {
+ DPRINTF(0, "error=%s\n", usbd_errstr(error)) ;
goto detach;
}
sc->sc_flags |= ULPT_FLAG_WAIT_USB;
- if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BROKEN_BIDIR) {
+ if (usbd_get_quirks(uaa->device)->uq_flags & UQ_BROKEN_BIDIR) {
/* this device doesn't handle reading properly. */
sc->sc_flags |= ULPT_FLAG_NO_READ;
}
@@ -587,9 +645,9 @@
USETW(req.wValue, cd->bConfigurationValue);
USETW2(req.wIndex, id->bInterfaceNumber, id->bAlternateSetting);
USETW(req.wLength, sizeof devinfo - 1);
- err = usbd_do_request_flags(dev, &req, devinfo, USBD_SHORT_XFER_OK,
+ error = usbd_do_request_flags(dev, &req, devinfo, USBD_SHORT_XFER_OK,
&alen, USBD_DEFAULT_TIMEOUT);
- if (err) {
+ if (error) {
device_printf(sc->sc_dev, "cannot get device id\n");
} else if (alen <= 2) {
device_printf(sc->sc_dev, "empty device id, no "
@@ -607,20 +665,33 @@
}
#endif
- sc->sc_cdev_1 = make_dev
- (&ulpt_cdevsw, (2*unit)|0, UID_ROOT, GID_OPERATOR,
- 0644, "ulpt%d", unit);
+ snprintf(buf_1, sizeof(buf_1), "ulpt%d", unit);
+ snprintf(buf_2, sizeof(buf_2), "unlpt%d", unit);
- sc->sc_cdev_2 = make_dev
- (&ulpt_cdevsw, (2*unit)|1, UID_ROOT, GID_OPERATOR,
- 0644, "unlpt%d", unit);
+ p_buf[0] = buf_1;
+ p_buf[1] = buf_2;
+ p_buf[2] = NULL;
- if (sc->sc_cdev_1) {
- DEV2SC(sc->sc_cdev_1) = sc;
- }
+ sc->sc_cdev.sc_start_read = &ulpt_start_read;
+ sc->sc_cdev.sc_start_write = &ulpt_start_write;
+ sc->sc_cdev.sc_stop_read = &ulpt_stop_read;
+ sc->sc_cdev.sc_stop_write = &ulpt_stop_write;
+ sc->sc_cdev.sc_open = &ulpt_open;
+ sc->sc_cdev.sc_ioctl = &ulpt_ioctl;
+ sc->sc_cdev.sc_flags |= (USB_CDEV_FLAG_FWD_SHORT|
+ USB_CDEV_FLAG_WAKEUP_RD_IMMED|
+ USB_CDEV_FLAG_WAKEUP_WR_IMMED);
- if (sc->sc_cdev_2) {
- DEV2SC(sc->sc_cdev_2) = sc;
+ /* make the buffers one byte larger than maximum so
+ * that one can detect too large read/writes and
+ * short transfers:
+ */
+ error = usb_cdev_attach(&(sc->sc_cdev), sc, &(sc->sc_mtx), p_buf,
+ UID_ROOT, GID_OPERATOR, 0644,
+ ULPT_BSIZE, ULPT_IFQ_MAXLEN,
+ ULPT_BSIZE, ULPT_IFQ_MAXLEN);
+ if (error) {
+ goto detach;
}
/* start watchdog (returns unlocked) */
@@ -644,51 +715,21 @@
DPRINTF(0, "sc=%p\n", sc);
- mtx_lock(&(sc->sc_mtx));
- sc->sc_flags |= ULPT_FLAG_GONE;
- mtx_unlock(&(sc->sc_mtx));
-
- if (sc->sc_cdev_1) {
-
- ulpt_close(sc->sc_cdev_1, 0, 0, 0);
-
- DEV2SC(sc->sc_cdev_1) = NULL;
-
- destroy_dev(sc->sc_cdev_1);
- }
-
- if (sc->sc_cdev_2) {
+ usb_cdev_detach(&(sc->sc_cdev));
- ulpt_close(sc->sc_cdev_2, 0, 0, 0);
-
- DEV2SC(sc->sc_cdev_2) = NULL;
-
- destroy_dev(sc->sc_cdev_2);
- }
-
mtx_lock(&(sc->sc_mtx));
-
__callout_stop(&(sc->sc_watchdog));
-
mtx_unlock(&(sc->sc_mtx));
usbd_transfer_unsetup(sc->sc_xfer, ULPT_N_TRANSFER);
- if (sc->sc_mem_ptr_1) {
- free(sc->sc_mem_ptr_1, M_DEVBUF);
- }
-
- if (sc->sc_mem_ptr_2) {
- free(sc->sc_mem_ptr_2, M_DEVBUF);
- }
-
/* wait for callbacks to be aborted */
mtx_lock(&(sc->sc_mtx));
while (sc->sc_flags & (ULPT_FLAG_WAIT_USB|ULPT_FLAG_WAIT_CO)) {
error = msleep(&(sc->sc_wakeup_detach), &(sc->sc_mtx),
- PRIBIO, "ulpt_sync_2", 0);
+ PRIBIO, "ulpt_sync", 0);
}
mtx_unlock(&(sc->sc_mtx));
@@ -697,389 +738,6 @@
return 0;
}
-static int
-ulpt_uiomove(struct ulpt_softc *sc, u_int32_t context_bit, void *cp, int n,
- struct uio *uio)
-{
- int error;
-
- sc->sc_flags |= context_bit;
-
- mtx_unlock(&(sc->sc_mtx));
-
- /* "uiomove()" can sleep so one
- * needs to make a wrapper, exiting
- * the mutex and checking things
- */
- error = uiomove(cp, n, uio);
-
- mtx_lock(&(sc->sc_mtx));
-
- sc->sc_flags &= ~context_bit;
-
- if (sc->sc_flags & ULPT_FLAG_CLOSING) {
- wakeup(&(sc->sc_wakeup_sync_1));
- error = EINTR;
- }
-
- if (sc->sc_flags & ULPT_FLAG_PIPE_ERR) {
- error = EINTR;
- }
-
- if (error) {
- sc->sc_flags |= ULPT_FLAG_NO_FLUSH;
- }
-
- return error;
-}
-
-static int
-ulpt_msleep(struct ulpt_softc *sc, u_int32_t context_bit, void *ident)
-{
- int error;
-
- sc->sc_flags |= context_bit;
-
- error = msleep(ident, &(sc->sc_mtx), PRIBIO|PCATCH, "ulpt_sleep", 0);
-
- sc->sc_flags &= ~context_bit;
-
- if (sc->sc_flags & ULPT_FLAG_CLOSING) {
- wakeup(&(sc->sc_wakeup_sync_1));
- error = EINTR;
- }
-
- if (sc->sc_flags & ULPT_FLAG_PIPE_ERR) {
- error = EINTR;
- }
-
- if (error) {
- sc->sc_flags |= ULPT_FLAG_NO_FLUSH;
- }
- return error;
-}
-
-static int
-ulpt_reset(struct ulpt_softc *sc)
-{
- DPRINTF(1, "\n");
-
- /* start reset, if not already started */
-
- usbd_transfer_start(sc->sc_xfer[3]);
-
- return ulpt_msleep(sc, ULPT_FLAG_RST_SLP|ULPT_FLAG_RST_WUP,
- &(sc->sc_wakeup_reset));
-}
-
-static int
-ulpt_open(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- u_int8_t no_prime = (minor(dev) & 1);
- struct ulpt_softc *sc = DEV2SC(dev);
- struct usbd_mbuf *m;
- int error = 0;
-
- DPRINTF(1, "\n");
-
- if (sc == NULL) {
- return EIO;
- }
-
- mtx_lock(&(sc->sc_mtx));
-
- if (sc->sc_flags &
- (ULPT_FLAG_DEV_OPEN|ULPT_FLAG_GONE|
- ULPT_FLAG_RST_SLP|ULPT_FLAG_RST_WUP)) {
- error = EBUSY;
- goto done;
- }
-
- if (no_prime == 0) {
- error = ulpt_reset(sc);
- if (error) {
- goto done;
- }
- }
-
- /* reset read queue */
-
- while(1) {
- USBD_IF_DEQUEUE(&(sc->sc_rdq_used), m);
-
- if (m) {
- USBD_IF_ENQUEUE(&(sc->sc_rdq_free), m);
- } else {
- break;
- }
- }
-
- /* reset write queue */
-
- while(1) {
- USBD_IF_DEQUEUE(&(sc->sc_wrq_used), m);
-
- if (m) {
- USBD_IF_ENQUEUE(&(sc->sc_wrq_free), m);
- } else {
- break;
- }
- }
-
- if (flag & FREAD) {
- sc->sc_flags &= ~ULPT_FLAG_DUMP_READ;
- } else {
- sc->sc_flags |= ULPT_FLAG_DUMP_READ;
- }
-
- sc->sc_flags |= ULPT_FLAG_DEV_OPEN;
-
- done:
- mtx_unlock(&(sc->sc_mtx));
-
- DPRINTF(0, "done, error=%d\n", error);
- return error;
-}
-
-static int
-ulpt_close(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct ulpt_softc *sc = DEV2SC(dev);
- int error;
-
- DPRINTF(1, "\n");
-
- if (sc == NULL) {
- return EIO;
- }
-
- mtx_lock(&(sc->sc_mtx));
-
- if (sc->sc_flags & (ULPT_FLAG_WR_FLUSH|ULPT_FLAG_CLOSING)) {
- goto done;
- }
-
- if (sc->sc_flags & ULPT_FLAG_DEV_OPEN) {
-
- /*
- * wait for data to
- * be written to pipe:
- */
-
- if (!(sc->sc_flags & (ULPT_FLAG_GONE|ULPT_FLAG_NO_FLUSH|
- ULPT_FLAG_PIPE_ERR))) {
-
- sc->sc_flags |= ULPT_FLAG_WR_FLUSH;
-
- /* start write transfer, if not already started */
-
- usbd_transfer_start(sc->sc_xfer[0]);
-
- while (sc->sc_flags & ULPT_FLAG_WR_FLUSH) {
-
- error = msleep(&(sc->sc_wakeup_flush), &(sc->sc_mtx),
- PRIBIO|PCATCH, "ulpt_sync_0", 0);
- if (error) {
- break;
- }
- }
- }
-
- sc->sc_flags |= ULPT_FLAG_CLOSING;
-
- if (sc->sc_xfer[0]) {
- usbd_transfer_stop(sc->sc_xfer[0]);
- }
-
- if (sc->sc_xfer[1]) {
- usbd_transfer_stop(sc->sc_xfer[1]);
- }
-
- while (sc->sc_flags &
- (ULPT_FLAG_RD_SLP|ULPT_FLAG_RD_WUP|ULPT_FLAG_RD_UIO|
- ULPT_FLAG_WR_SLP|ULPT_FLAG_WR_WUP|ULPT_FLAG_WR_UIO|
- ULPT_FLAG_RST_SLP|ULPT_FLAG_RST_WUP)) {
-
- if (sc->sc_flags & ULPT_FLAG_RD_WUP) {
- sc->sc_flags &= ~ULPT_FLAG_RD_WUP;
- wakeup(&(sc->sc_wakeup_read));
- }
-
- if (sc->sc_flags & ULPT_FLAG_WR_WUP) {
- sc->sc_flags &= ~ULPT_FLAG_WR_WUP;
- wakeup(&(sc->sc_wakeup_write));
- }
-
- if (sc->sc_flags & ULPT_FLAG_RST_WUP) {
- sc->sc_flags &= ~ULPT_FLAG_RST_WUP;
- wakeup(&(sc->sc_wakeup_reset));
- }
-
- error = msleep(&(sc->sc_wakeup_sync_1), &(sc->sc_mtx),
- PRIBIO, "ulpt_sync_1", 0);
- }
-
- sc->sc_flags &= ~(ULPT_FLAG_DEV_OPEN|
- ULPT_FLAG_CLOSING|
- ULPT_FLAG_WR_FLUSH|
- ULPT_FLAG_NO_FLUSH|
- ULPT_FLAG_PIPE_ERR);
- }
-
- done:
- mtx_unlock(&(sc->sc_mtx));
-
- DPRINTF(0, "closed\n");
-
- return 0;
-}
-
-static int
-ulpt_write(struct cdev *dev, struct uio *uio, int flags)
-{
- struct ulpt_softc *sc = DEV2SC(dev);
- struct usbd_mbuf *m;
- int error = 0;
- int io_len;
-
- DPRINTF(1, "\n");
-
- if (sc == NULL) {
- return EIO;
- }
-
- mtx_lock(&(sc->sc_mtx));
-
- if(sc->sc_flags & (ULPT_FLAG_CLOSING|ULPT_FLAG_GONE|
- ULPT_FLAG_WR_SLP|ULPT_FLAG_WR_UIO|
- ULPT_FLAG_PIPE_ERR)) {
- error = EIO;
- goto done;
- }
-
- while (uio->uio_resid) {
-
- USBD_IF_DEQUEUE(&sc->sc_wrq_free, m);
-
- if (m == NULL) {
- error = ulpt_msleep(sc, (ULPT_FLAG_WR_SLP|ULPT_FLAG_WR_WUP),
- &(sc->sc_wakeup_write));
- if (error) {
- break;
- } else {
- continue;
- }
- }
-
- USBD_MBUF_RESET(m);
-
- io_len = min(m->cur_data_len, uio->uio_resid);
-
- m->cur_data_len = io_len;
-
- DPRINTF(1, "transfer %d bytes to %p\n",
- io_len, m->cur_data_ptr);
-
- error = ulpt_uiomove(sc, ULPT_FLAG_WR_UIO,
- m->cur_data_ptr, io_len, uio);
-
- if (error) {
- USBD_IF_ENQUEUE(&sc->sc_wrq_free, m);
- break;
- } else {
- USBD_IF_ENQUEUE(&sc->sc_wrq_used, m);
- usbd_transfer_start(sc->sc_xfer[0]);
- }
- }
- done:
- mtx_unlock(&(sc->sc_mtx));
-
- return error;
-}
-
-static int
-ulpt_read(struct cdev *dev, struct uio *uio, int flags)
-{
- struct ulpt_softc *sc = DEV2SC(dev);
- struct usbd_mbuf *m;
- int error = 0;
- int io_len;
-
- if (sc == NULL) {
- return EIO;
- }
-
- DPRINTF(1, "\n");
-
- mtx_lock(&(sc->sc_mtx));
-
- if(sc->sc_flags & (ULPT_FLAG_CLOSING|ULPT_FLAG_GONE|
- ULPT_FLAG_RD_UIO|ULPT_FLAG_RD_SLP|
- ULPT_FLAG_PIPE_ERR)) {
- error = EIO;
- goto done;
- }
-
- while (uio->uio_resid) {
-
- USBD_IF_DEQUEUE(&sc->sc_rdq_used, m);
-
- if (m == NULL) {
-
- /* start reader thread */
-
- usbd_transfer_start(sc->sc_xfer[1]);
-
- error = ulpt_msleep(sc, (ULPT_FLAG_RD_SLP|ULPT_FLAG_RD_WUP),
- &(sc->sc_wakeup_read));
- if (error) {
- break;
- } else {
- continue;
- }
- }
-
- io_len = min(m->cur_data_len, uio->uio_resid);
-
- DPRINTF(1, "transfer %d bytes from %p\n",
- io_len, m->cur_data_ptr);
-
- error = ulpt_uiomove(sc, ULPT_FLAG_RD_UIO,
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list