Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Jun 2007 06:53:47 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 120879 for review
Message-ID:  <200706040653.l546rlT5021821@repoman.freebsd.org>

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

Change 120879 by hselasky@hselasky_mini_itx on 2007/06/04 06:53:08

	Finished converting uipaq to new USB stack.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/uipaq.c#3 edit

Differences ...

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

@@ -54,317 +54,451 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/module.h>
+#include <sys/termios.h>
+#include <sys/serial.h>
 
+#include <dev/usb/usb_port.h>
 #include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
+#include <dev/usb/usb_subr.h>
+#include <dev/usb/usb_cdc.h>
 
-#include <dev/usb/usbcdc.h>	/*UCDC_* stuff */
+#include <dev/usb/ucomvar.h>
 
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
 #include "usbdevs.h"
 
-#include <dev/usb/ucomvar.h>
-
-#ifdef UIPAQ_DEBUG
-#define DPRINTF(x)	if (uipaqdebug) printf x
-#define DPRINTFN(n,x)	if (uipaqdebug>(n)) printf x
-int uipaqdebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
 #define UIPAQ_CONFIG_NO		1
 #define UIPAQ_IFACE_INDEX	0
 
-#define UIPAQIBUFSIZE 1024
-#define UIPAQOBUFSIZE 1024
+#define UIPAQ_BUF_SIZE		1024
+#define UIPAQ_N_DATA_TRANSFER	4
+
+#define DPRINTF(...) do { } while (0)
 
 struct uipaq_softc {
-	struct ucom_softc       sc_ucom;
-	u_int16_t		sc_lcr;		/* state for DTR/RTS */
-	u_int16_t		sc_flags;
+	struct ucom_super_softc	sc_super_ucom;
+	struct ucom_softc	sc_ucom;
+
+	struct usbd_xfer	*sc_xfer_data[UIPAQ_N_DATA_TRANSFER];
+	struct usbd_device	*sc_udev;
+
+	uint16_t	sc_line;
 
+	uint8_t		sc_lsr;	/* local status register */
+	uint8_t		sc_msr;	/* modem status register */
+	uint8_t		sc_flag;
+#define UIPAQ_FLAG_READ_STALL  0x01
+#define UIPAQ_FLAG_WRITE_STALL 0x02
+#define UIPAQ_FLAG_INTR_STALL  0x04
 };
 
-/* Callback routines */
-static void	uipaq_set(void *, int, int, int);
+static device_probe_t uipaq_probe;
+static device_attach_t uipaq_attach;
+static device_detach_t uipaq_detach;
+
+static usbd_callback_t uipaq_write_callback;
+static usbd_callback_t uipaq_read_callback;
+static usbd_callback_t uipaq_write_clear_stall_callback;
+static usbd_callback_t uipaq_read_clear_stall_callback;
+
+static void	uipaq_start_read(struct ucom_softc *ucom);
+static void	uipaq_stop_read(struct ucom_softc *ucom);
+static void	uipaq_start_write(struct ucom_softc *ucom);
+static void	uipaq_stop_write(struct ucom_softc *ucom);
+static void	uipaq_cfg_do_request(struct uipaq_softc *sc, usb_device_request_t *req, void *data);
+static void	uipaq_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff);
+static void	uipaq_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff);
+static void	uipaq_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff);
+
+static const struct usbd_config uipaq_config_data[UIPAQ_N_DATA_TRANSFER] = {
+
+    [0] = {
+      .type      = UE_BULK,
+      .endpoint  = -1, /* any */
+      .direction = UE_DIR_OUT,
+      .bufsize   = UIPAQ_BUF_SIZE,
+      .flags     = 0,
+      .callback  = &uipaq_write_callback,
+    },
+
+    [1] = {
+      .type      = UE_BULK,
+      .endpoint  = -1, /* any */
+      .direction = UE_DIR_IN,
+      .bufsize   = UIPAQ_BUF_SIZE,
+      .flags     = USBD_SHORT_XFER_OK,
+      .callback  = &uipaq_read_callback,
+    },
 
-/* Support routines. */
-/* based on uppc module by Sam Lawrance */
-static void	uipaq_dtr(struct uipaq_softc *sc, int onoff);
-static void	uipaq_rts(struct uipaq_softc *sc, int onoff);
-static void	uipaq_break(struct uipaq_softc* sc, int onoff);
+    [2] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0x00, /* Control pipe */
+      .direction = -1,
+      .bufsize   = sizeof(usb_device_request_t),
+      .callback  = &uipaq_write_clear_stall_callback,
+      .timeout   = 1000, /* 1 second */
+    },
 
-int uipaq_detach(device_t self);
+    [3] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0x00, /* Control pipe */
+      .direction = -1,
+      .bufsize   = sizeof(usb_device_request_t),
+      .callback  = &uipaq_read_clear_stall_callback,
+      .timeout   = 1000, /* 1 second */
+    },
+};
 
-struct ucom_callback uipaq_callback = {
-	NULL,
-	uipaq_set,
-	NULL,
-	NULL,
-	NULL,	/*open*/
-	NULL,	/*close*/
-	NULL,
-	NULL
+static const struct ucom_callback uipaq_callback = {
+  .ucom_cfg_set_dtr     = &uipaq_cfg_set_dtr,
+  .ucom_cfg_set_rts     = &uipaq_cfg_set_rts,
+  .ucom_cfg_set_break   = &uipaq_cfg_set_break,
+  .ucom_start_read      = &uipaq_start_read,
+  .ucom_stop_read       = &uipaq_stop_read,
+  .ucom_start_write     = &uipaq_start_write,
+  .ucom_stop_write      = &uipaq_stop_write,
 };
 
-struct uipaq_type {
-	struct usb_devno	uv_dev;
-	u_int16_t		uv_flags;
+static const struct usb_devno uipaq_devs[] = {
+	{ USB_VENDOR_HP, USB_PRODUCT_HP_2215 },
+	{ USB_VENDOR_HP, USB_PRODUCT_HP_568J },
+	{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQPOCKETPC },
+	{ USB_VENDOR_CASIO, USB_PRODUCT_CASIO_BE300 },
+	{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WZERO3ES },
 };
 
-static const struct uipaq_type uipaq_devs[] = {
-	{{ USB_VENDOR_HP, USB_PRODUCT_HP_2215 }, 0 },
-	{{ USB_VENDOR_HP, USB_PRODUCT_HP_568J }, 0},
-	{{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQPOCKETPC } , 0},
-	{{ USB_VENDOR_CASIO, USB_PRODUCT_CASIO_BE300 } , 0},
-	{{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WZERO3ES }, 0},
+#define uipaq_lookup(v, p) ((const void *)usb_lookup(uipaq_devs, v, p))
+
+static device_method_t uipaq_methods[] = {
+    DEVMETHOD(device_probe, uipaq_probe),
+    DEVMETHOD(device_attach, uipaq_attach),
+    DEVMETHOD(device_detach, uipaq_detach),
+    { 0, 0 }
 };
 
-#define uipaq_lookup(v, p) ((const struct uipaq_type *)usb_lookup(uipaq_devs, v, p))
+static devclass_t uipaq_devclass;
 
-USB_MATCH(uipaq)
-{
-	USB_MATCH_START(uipaq, uaa);
+static driver_t uipaq_driver = {
+    .name    = "uipaq",
+    .methods = uipaq_methods,
+    .size    = sizeof(struct uipaq_softc),
+};
 
-	if (uaa->iface != NULL)
-		return (UMATCH_NONE);
+DRIVER_MODULE(uipaq, uhub, uipaq_driver, uipaq_devclass, usbd_driver_load, 0);
+MODULE_DEPEND(uipaq, usb, 1, 1, 1);
+MODULE_DEPEND(uipaq, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
 
-	DPRINTFN(20,("uipaq: vendor=0x%x, product=0x%x\n",
-	    uaa->vendor, uaa->product));
+static int
+uipaq_probe(device_t dev)
+{
+	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	const struct usb_devno *up;
 
-	return (uipaq_lookup(uaa->vendor, uaa->product) != NULL ?
-	    UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
+	if (uaa->iface == NULL) {
+	    up = uipaq_lookup(uaa->vendor, uaa->product);
+	    if (up) {
+	        return UMATCH_VENDOR_PRODUCT;
+	    }
+	}
+	return UMATCH_NONE;
 }
 
 static int
-uipaq_attach(device_t self)
+uipaq_attach(device_t dev)
 {
-	struct uipaq_softc *sc = device_get_softc(self);
-	struct usb_attach_arg *uaa = device_get_ivars(self);
-	usbd_device_handle dev = uaa->device;
-	usbd_interface_handle iface;
-	usb_interface_descriptor_t *id;
-	usb_endpoint_descriptor_t *ed;
-	char *devinfop;
-	int i;
-	usbd_status err;
-	struct ucom_softc *ucom = &sc->sc_ucom;
+	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	struct uipaq_softc *sc = device_get_softc(dev);
+	int error;
+
+	if (sc == NULL) {
+	    return ENOMEM;
+	}
+
+	sc->sc_udev = uaa->device;
 
-	ucom->sc_dev = self;
-	ucom->sc_udev = dev;
+	usbd_set_desc(dev, uaa->device);
 
-	DPRINTFN(10,("\nuipaq_attach: sc=%p\n", sc));
+	error = usbd_set_config_no(uaa->device, UIPAQ_CONFIG_NO, 1);
 
-	/* Move the device into the configured state. */
-	err = usbd_set_config_no(dev, UIPAQ_CONFIG_NO, 1);
-	if (err) {
-		device_printf(ucom->sc_dev,
-		    "failed to set configuration: %s\n", usbd_errstr(err));
-		goto bad;
+	if (error) {
+		device_printf(dev, "setting config "
+			      "number failed!\n");
+		goto detach;
 	}
 
-	err = usbd_device2interface_handle(dev, UIPAQ_IFACE_INDEX, &iface);
-	if (err) {
-		device_printf(ucom->sc_dev, "failed to get interface: %s\n",
-		    usbd_errstr(err));
-		goto bad;
+	error = usbd_transfer_setup(uaa->device, UIPAQ_IFACE_INDEX,
+				    sc->sc_xfer_data, uipaq_config_data, 
+				    UIPAQ_N_DATA_TRANSFER,
+				    sc, &Giant);
+	if (error) {
+	    goto detach;
 	}
 
-	devinfop = malloc (1024, M_USBDEV, M_WAITOK);
-	if (devinfop == NULL) {
-		err = ENOMEM;
-		goto bad;
+	/* clear stall at first run */
+	sc->sc_flag |= (UIPAQ_FLAG_READ_STALL|
+			UIPAQ_FLAG_WRITE_STALL);
+
+	error = ucom_attach(&(sc->sc_super_ucom), &(sc->sc_ucom), 1, sc,
+			    &uipaq_callback, &Giant);
+	if (error) {
+	    goto detach;
 	}
-	usbd_devinfo(dev, 0, devinfop);
-	ucom->sc_dev = self;
-	device_set_desc_copy(self, devinfop);
-	device_printf(ucom->sc_dev, "%s\n", devinfop);
-	free(devinfop, M_USBDEV);
+
+	return 0;
+
+ detach:
+	uipaq_detach(dev);
+	return ENXIO;
+}
+
+int
+uipaq_detach(device_t dev)
+{
+	struct uipaq_softc *sc = device_get_softc(dev);
+
+	ucom_detach(&(sc->sc_super_ucom), &(sc->sc_ucom), 1);
+
+	usbd_transfer_unsetup(sc->sc_xfer_data, UIPAQ_N_DATA_TRANSFER);
+
+	return 0;
+}
+
+static void
+uipaq_start_read(struct ucom_softc *ucom)
+{
+	struct uipaq_softc *sc = ucom->sc_parent;
+	/* start read endpoint */
+	usbd_transfer_start(sc->sc_xfer_data[1]);
+	return;
+}
+
+static void
+uipaq_stop_read(struct ucom_softc *ucom)
+{
+	struct uipaq_softc *sc = ucom->sc_parent;
+	/* stop read endpoint */
+	usbd_transfer_stop(sc->sc_xfer_data[3]);
+	usbd_transfer_stop(sc->sc_xfer_data[1]);
+	return;
+}
+
+static void
+uipaq_start_write(struct ucom_softc *ucom)
+{
+	struct uipaq_softc *sc = ucom->sc_parent;
+	usbd_transfer_start(sc->sc_xfer_data[0]);
+	return;
+}
+
+static void
+uipaq_stop_write(struct ucom_softc *ucom)
+{
+	struct uipaq_softc *sc = ucom->sc_parent;
+	usbd_transfer_stop(sc->sc_xfer_data[2]);
+	usbd_transfer_stop(sc->sc_xfer_data[0]);
+	return;
+}
+
+static void
+uipaq_cfg_do_request(struct uipaq_softc *sc, usb_device_request_t *req, 
+		      void *data)
+{
+	uint16_t length;
+	usbd_status err;
 
-	sc->sc_flags = uipaq_lookup(uaa->vendor, uaa->product)->uv_flags;
-	id = usbd_get_interface_descriptor(iface);
-	ucom->sc_iface = iface;
-	ucom->sc_ibufsize = UIPAQIBUFSIZE;
-	ucom->sc_obufsize = UIPAQOBUFSIZE;
-	ucom->sc_ibufsizepad = UIPAQIBUFSIZE;
-	ucom->sc_opkthdrlen = 0;
-	ucom->sc_callback = &uipaq_callback;
-	ucom->sc_parent = sc;
-	ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
-	for (i=0; i<id->bNumEndpoints; i++) {
-		ed = usbd_interface2endpoint_descriptor(iface, i);
-		if (ed == NULL) {
-			device_printf(ucom->sc_dev, 
-			    "no endpoint descriptor for %d\n", i);
-			goto bad;
-		}
-		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
-		    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
-		       ucom->sc_bulkin_no = ed->bEndpointAddress;
-		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
-		    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
-		       ucom->sc_bulkout_no = ed->bEndpointAddress;
-		}
+	if (ucom_cfg_is_gone(&(sc->sc_ucom))) {
+	    goto error;
 	}
-	if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) {
-		device_printf(ucom->sc_dev,
-		    "no proper endpoints found (%d,%d)\n",
-		    ucom->sc_bulkin_no, ucom->sc_bulkout_no);
-		return (ENXIO);
+
+	err = usbd_do_request_flags_mtx(sc->sc_udev, &Giant, req, 
+					data, 0, NULL, 1000);
+
+	if (err) {
+
+	    DPRINTF(-1, "device request failed, err=%s "
+		    "(ignored)\n", usbd_errstr(err));
+
+	error:
+	    length = UGETW(req->wLength);
+
+	    if ((req->bmRequestType & UT_READ) && length) {
+		bzero(data, length);
+	    }
 	}
-	
-	ucom_attach(&sc->sc_ucom);
-	return (0);
-bad:
-	DPRINTF(("uipaq_attach: ATTACH ERROR\n"));
-	ucom->sc_dying = 1;
-	return (ENXIO);
+	return;
 }
 
-void
-uipaq_dtr(struct uipaq_softc* sc, int onoff)
+static void
+uipaq_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
 {
+	struct uipaq_softc *sc = ucom->sc_parent;
 	usb_device_request_t req;
-	struct ucom_softc *ucom = &sc->sc_ucom;
-	usbd_status err;
-	int retries = 3;
 
-	DPRINTF(("%s: uipaq_dtr: onoff=%x\n", device_get_nameunit(ucom->sc_dev), onoff));
+	DPRINTF(0, "onoff=%d\n", onoff);
 
-	/* Avoid sending unnecessary requests */
-	if (onoff && (sc->sc_lcr & UCDC_LINE_DTR))
-		return;
-	if (!onoff && !(sc->sc_lcr & UCDC_LINE_DTR))
-		return;
+	if (onoff)
+	  sc->sc_line |= UCDC_LINE_DTR;
+	else
+	  sc->sc_line &= ~UCDC_LINE_DTR;
 
-	/* Other parameters depend on reg */
 	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
 	req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
-	sc->sc_lcr = onoff ? sc->sc_lcr | UCDC_LINE_DTR : sc->sc_lcr & ~UCDC_LINE_DTR;
-	USETW(req.wValue, sc->sc_lcr);
-	USETW(req.wIndex, 0x0);
+	USETW(req.wValue, sc->sc_line);
+	req.wIndex[0] = UIPAQ_IFACE_INDEX;
+	req.wIndex[1] = 0;
 	USETW(req.wLength, 0);
 
-	/* Fire off the request a few times if necessary */
-	while (retries) {
-		err = usbd_do_request(ucom->sc_udev, &req, NULL);
-		if (!err)
-			break;
-		retries--;
-	}
+	uipaq_cfg_do_request(sc, &req, NULL);
+	return;
 }
 
-void
-uipaq_rts(struct uipaq_softc* sc, int onoff)
+static void
+uipaq_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff)
 {
+	struct uipaq_softc *sc = ucom->sc_parent;
 	usb_device_request_t req;
-	struct ucom_softc *ucom = &sc->sc_ucom;
-	usbd_status err;
-	int retries = 3;
 
-	DPRINTF(("%s: uipaq_rts: onoff=%x\n", device_get_nameunit(ucom->sc_dev), onoff));
+	DPRINTF(0, "onoff=%d\n", onoff);
 
-	/* Avoid sending unnecessary requests */
-	if (onoff && (sc->sc_lcr & UCDC_LINE_RTS)) return;
-	if (!onoff && !(sc->sc_lcr & UCDC_LINE_RTS)) return;
+	if (onoff)
+	  sc->sc_line |= UCDC_LINE_RTS;
+	else
+	  sc->sc_line &= ~UCDC_LINE_RTS;
 
 	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
 	req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
-	sc->sc_lcr = onoff ? sc->sc_lcr | UCDC_LINE_RTS : sc->sc_lcr & ~UCDC_LINE_RTS;
-	USETW(req.wValue, sc->sc_lcr);
-	USETW(req.wIndex, 0x0);
+	USETW(req.wValue, sc->sc_line);
+	req.wIndex[0] = UIPAQ_IFACE_INDEX;
+	req.wIndex[1] = 0;
 	USETW(req.wLength, 0);
 
-	while (retries) {
-		err = usbd_do_request(ucom->sc_udev, &req, NULL);
-		if (!err)
-			break;
-		retries--;
-	}
+	uipaq_cfg_do_request(sc, &req, NULL);
+	return;
 }
 
-void
-uipaq_break(struct uipaq_softc* sc, int onoff)
+static void
+uipaq_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)
 {
+	struct uipaq_softc *sc = ucom->sc_parent;
 	usb_device_request_t req;
-	struct ucom_softc *ucom = &sc->sc_ucom;
-	usbd_status err;
-	int retries = 3;
+	uint16_t temp;
 
-	DPRINTF(("%s: uipaq_break: onoff=%x\n", device_get_nameunit(ucom->sc_dev), onoff));
+	temp = onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF;
 
 	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
 	req.bRequest = UCDC_SEND_BREAK;
+	USETW(req.wValue, temp);
+	req.wIndex[0] = UIPAQ_IFACE_INDEX;
+	req.wIndex[1] = 0;
+	USETW(req.wLength, 0);
 
-	USETW(req.wValue, onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
-	USETW(req.wIndex, 0x0);
-	USETW(req.wLength, 0);
+	uipaq_cfg_do_request(sc, &req, NULL);
+	return;
+}
+
+static void
+uipaq_write_callback(struct usbd_xfer *xfer)
+{
+	struct uipaq_softc *sc = xfer->priv_sc;
+	uint32_t actlen;
+
+	USBD_CHECK_STATUS(xfer);
+
+tr_error:
+	if (xfer->error != USBD_CANCELLED) {
+	    sc->sc_flag |= UIPAQ_FLAG_WRITE_STALL;
+	    usbd_transfer_start(sc->sc_xfer_data[2]);
+	}
+	return;
+
+tr_setup:
+tr_transferred:
+	if (sc->sc_flag & UIPAQ_FLAG_WRITE_STALL) {
+	    usbd_transfer_start(sc->sc_xfer_data[2]);
+	    return;
+	}
+
+	if(ucom_get_data(&(sc->sc_ucom), xfer->buffer,
+			 UIPAQ_BUF_SIZE, &actlen)) {
+
+	    xfer->length = actlen;
 
-	while (retries) {
-		err = usbd_do_request(ucom->sc_udev, &req, NULL);
-		if (!err)
-			break;
-		retries--;
+	    usbd_start_hardware(xfer);
 	}
+	return;
 }
 
-void
-uipaq_set(void *addr, int portno, int reg, int onoff)
+static void
+uipaq_write_clear_stall_callback(struct usbd_xfer *xfer)
 {
-	struct uipaq_softc* sc = addr;
-	struct ucom_softc *ucom = &sc->sc_ucom;
+	struct uipaq_softc *sc = xfer->priv_sc;
+
+	USBD_CHECK_STATUS(xfer);
+
+ tr_setup:
+	/* start clear stall */
+	usbd_clear_stall_tr_setup(xfer, sc->sc_xfer_data[0]);
+	return;
+
+ tr_transferred:
+	usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer_data[0]);
+	sc->sc_flag &= ~UIPAQ_FLAG_WRITE_STALL;
+	usbd_transfer_start(sc->sc_xfer_data[0]);
+	return;
 
-	switch (reg) {
-	case UCOM_SET_DTR:
-		uipaq_dtr(addr, onoff);
-		break;
-	case UCOM_SET_RTS:
-		uipaq_rts(addr, onoff);
-		break;
-	case UCOM_SET_BREAK:
-		uipaq_break(addr, onoff);
-		break;
-	default:
-		printf("%s: unhandled set request: reg=%x onoff=%x\n",
-		  device_get_nameunit(ucom->sc_dev), reg, onoff);
-		return;
-	}
+ tr_error:
+	sc->sc_flag &= ~UIPAQ_FLAG_WRITE_STALL;
+	DPRINTF(0, "clear stall failed, error=%s\n",
+		usbd_errstr(xfer->error));
+	return;
 }
 
-int
-uipaq_detach(device_t self)
+static void
+uipaq_read_callback(struct usbd_xfer *xfer)
 {
-	struct uipaq_softc *sc = device_get_softc(self);
-	struct ucom_softc *ucom = &sc->sc_ucom;
-	int rv = 0;
+	struct uipaq_softc *sc = xfer->priv_sc;
+
+	USBD_CHECK_STATUS(xfer);
+
+ tr_error:
+	if (xfer->error != USBD_CANCELLED) {
+	    sc->sc_flag |= UIPAQ_FLAG_READ_STALL;
+	    usbd_transfer_start(sc->sc_xfer_data[3]);
+	}
+	return;
 
-	DPRINTF(("uipaq_detach: sc=%p flags=%d\n", sc, flags));
-	ucom->sc_dying = 1;
+ tr_transferred:
+	ucom_put_data(&(sc->sc_ucom), xfer->buffer, xfer->actlen);
 
-	return (rv);
+ tr_setup:
+	if (sc->sc_flag & UIPAQ_FLAG_READ_STALL) {
+	    usbd_transfer_start(sc->sc_xfer_data[3]);
+	} else {
+	    usbd_start_hardware(xfer);
+	}
+	return;
 }
 
-static device_method_t uipaq_methods[] = {
-	/* Device interface */
-	DEVMETHOD(device_probe, uipaq_match),
-	DEVMETHOD(device_attach, uipaq_attach),
-	DEVMETHOD(device_detach, uipaq_detach),
+static void
+uipaq_read_clear_stall_callback(struct usbd_xfer *xfer)
+{
+	struct uipaq_softc *sc = xfer->priv_sc;
+
+	USBD_CHECK_STATUS(xfer);
+
+ tr_setup:
+	/* start clear stall */
+	usbd_clear_stall_tr_setup(xfer, sc->sc_xfer_data[1]);
+	return;
 
-	{ 0, 0 }
-};
-static driver_t uipaq_driver = {
-	"ucom",
-	uipaq_methods,
-	sizeof (struct uipaq_softc)
-};
+ tr_transferred:
+	usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer_data[1]);
+	sc->sc_flag &= ~UIPAQ_FLAG_READ_STALL;
+	usbd_transfer_start(sc->sc_xfer_data[1]);
+	return;
 
-DRIVER_MODULE(uipaq, uhub, uipaq_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uipaq, usb, 1, 1, 1);
-MODULE_DEPEND(uipaq, ucom,UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
+ tr_error:
+	sc->sc_flag &= ~UIPAQ_FLAG_READ_STALL;
+	DPRINTF(0, "clear stall failed, error=%s\n",
+		usbd_errstr(xfer->error));
+	return;
+}



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