From owner-p4-projects@FreeBSD.ORG Mon Jun 4 06:53:48 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0EBA716A468; Mon, 4 Jun 2007 06:53:48 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id D284716A41F for ; Mon, 4 Jun 2007 06:53:47 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id C385E13C4BB for ; Mon, 4 Jun 2007 06:53:47 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l546rlqq021827 for ; Mon, 4 Jun 2007 06:53:47 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l546rlT5021821 for perforce@freebsd.org; Mon, 4 Jun 2007 06:53:47 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 4 Jun 2007 06:53:47 GMT Message-Id: <200706040653.l546rlT5021821@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 120879 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Jun 2007 06:53:48 -0000 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 #include #include -#include -#include -#include -#include +#include +#include +#include #include -#include +#include +#include -#include /*UCDC_* stuff */ +#include -#include -#include #include "usbdevs.h" -#include - -#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; ibNumEndpoints; 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; +}