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