Date: Sun, 23 Sep 2007 14:32:09 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 126733 for review Message-ID: <200709231432.l8NEW9d9086718@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=126733 Change 126733 by hselasky@hselasky_laptop001 on 2007/09/23 14:31:53 FYI; The comments follow the P4 diff from top to bottom. - remove redundant inclusion of "sys/vnode.h" - the pre-allocate USB control request belonging to the "uhid_ioctl_callback()" has been removed. "usbd_do_request()" is used instead. - all USB BULK/ISOC/INTR transfers must setup "xfer->frlengths[]" before calling "usbd_start_hardware()". Else the actual length of the previous transfer will be used for transfer length of the next USB transfer. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/uhid.c#17 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/uhid.c#17 (text+ko) ==== @@ -56,7 +56,6 @@ #include <sys/filio.h> #include <sys/tty.h> #include <sys/file.h> -#include <sys/vnode.h> #include <sys/poll.h> #include <dev/usb/usb_port.h> @@ -91,7 +90,7 @@ #define USB_PRODUCT_WACOM_GRAPHIRE3_4X5 0 #endif -#define UHID_N_TRANSFER 5 /* units */ +#define UHID_N_TRANSFER 4 /* units */ #define UHID_BSIZE 1024 /* bytes, buffer size */ #define UHID_FRAME_NUM 50 /* bytes, frame number */ @@ -99,14 +98,15 @@ struct usb_cdev sc_cdev; struct mtx sc_mtx; - struct usbd_xfer * sc_xfer[UHID_N_TRANSFER]; - void * sc_repdesc_ptr; + struct usbd_xfer *sc_xfer[UHID_N_TRANSFER]; + struct usbd_device *sc_udev; + void *sc_repdesc_ptr; u_int32_t sc_isize; u_int32_t sc_osize; u_int32_t sc_fsize; - u_int32_t sc_repdesc_size; - u_int32_t sc_transfer_len; + + uint16_t sc_repdesc_size; u_int8_t sc_transfer_buf[sizeof(usb_device_request_t) + UHID_BSIZE]; u_int8_t sc_iface_no; @@ -117,7 +117,6 @@ #define UHID_FLAG_IMMED 0x01 /* set if read should be immediate */ #define UHID_FLAG_INTR_STALL 0x02 /* set if interrupt transfer stalled */ #define UHID_FLAG_STATIC_DESC 0x04 /* set if report descriptors are static */ -#define UHID_FLAG_COMMAND_ERR 0x08 /* set if control transfer had an error */ }; static u_int8_t uhid_xb360gp_report_descr[] = { UHID_XB360GP_REPORT_DESCR() }; @@ -134,7 +133,6 @@ static usbd_callback_t uhid_intr_clear_stall_callback; static usbd_callback_t uhid_write_callback; static usbd_callback_t uhid_read_callback; -static usbd_callback_t uhid_ioctl_callback; static void uhid_intr_callback(struct usbd_xfer *xfer) @@ -148,8 +146,8 @@ DPRINTF(0, "transferred!\n"); if (xfer->actlen >= sc->sc_isize) { - usb_cdev_put_data(&(sc->sc_cdev), - xfer->buffer, sc->sc_isize, 1); + usb_cdev_put_data(&(sc->sc_cdev), &(xfer->buf_data), + 0, sc->sc_isize, 1); } else { /* ignore it */ DPRINTF(0, "ignored short transfer, " @@ -163,6 +161,7 @@ USBD_IF_POLL(&(sc->sc_cdev.sc_rdq_free), m); if (m) { + xfer->frlengths[0] = xfer->max_data_length; usbd_start_hardware(xfer); } } @@ -195,7 +194,7 @@ uhid_write_callback(struct usbd_xfer *xfer) { struct uhid_softc *sc = xfer->priv_sc; - usb_device_request_t *req = xfer->buffer; + usb_device_request_t req; u_int32_t size = sc->sc_osize; u_int32_t actlen; u_int8_t id; @@ -207,10 +206,14 @@ /* try to extract the ID byte */ if (sc->sc_oid) { - if (usb_cdev_get_data(&(sc->sc_cdev), &id, 1, &actlen, 0)) { + if (usb_cdev_get_data(&(sc->sc_cdev), &(xfer->buf_data), + 0, 1, &actlen, 0)) { if (actlen != 1) { goto tr_error; } + + usbd_copy_out(&(xfer->buf_data), 0, &id, 1); + } else { return; } @@ -221,16 +224,20 @@ id = 0; } - if (usb_cdev_get_data(&(sc->sc_cdev), req->bData, - UHID_BSIZE, &actlen, 1)) { + if (usb_cdev_get_data(&(sc->sc_cdev), xfer->frbuffers + 1, + 0, UHID_BSIZE, &actlen, 1)) { if (actlen != size) { goto tr_error; } + usbd_fill_set_report - (req, sc->sc_iface_no, + (&req, sc->sc_iface_no, UHID_OUTPUT_REPORT, id, size); - xfer->length = sizeof(*req) + size; + usbd_copy_in(xfer->frbuffers + 0, 0, &req, sizeof(req)); + + xfer->frlengths[0] = sizeof(req); + xfer->frlengths[1] = size; usbd_start_hardware(xfer); } @@ -246,24 +253,27 @@ uhid_read_callback(struct usbd_xfer *xfer) { struct uhid_softc *sc = xfer->priv_sc; - usb_device_request_t *req = xfer->buffer; - struct usbd_mbuf *m; + usb_device_request_t req; USBD_CHECK_STATUS(xfer); tr_transferred: - usb_cdev_put_data(&(sc->sc_cdev), req->bData, sc->sc_isize, 1); + usb_cdev_put_data(&(sc->sc_cdev), &(xfer->buf_data), + sizeof(req), sc->sc_isize, 1); return; tr_setup: - USBD_IF_POLL(&(sc->sc_cdev.sc_rdq_free), m); + + if (usb_cdev_put_bytes_max(&(sc->sc_cdev)) > 0) { - if (m) { usbd_fill_get_report - (req, sc->sc_iface_no, UHID_INPUT_REPORT, + (&req, sc->sc_iface_no, UHID_INPUT_REPORT, sc->sc_iid, sc->sc_isize); - xfer->length = sizeof(*req) + sc->sc_isize; + usbd_copy_in(xfer->frbuffers + 0, 0, &req, sizeof(req)); + + xfer->frlengths[0] = sizeof(req); + xfer->frlengths[1] = sc->sc_isize; usbd_start_hardware(xfer); } @@ -275,39 +285,13 @@ return; } -static void -uhid_ioctl_callback(struct usbd_xfer *xfer) -{ - struct uhid_softc *sc = xfer->priv_sc; - - USBD_CHECK_STATUS(xfer); - - tr_transferred: - bcopy(xfer->buffer, sc->sc_transfer_buf, sc->sc_transfer_len); - sc->sc_flags &= ~UHID_FLAG_COMMAND_ERR; - usb_cdev_wakeup(&(sc->sc_cdev)); - return; - - tr_error: - DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error)); - sc->sc_flags |= UHID_FLAG_COMMAND_ERR; - usb_cdev_wakeup(&(sc->sc_cdev)); - return; - - tr_setup: - bcopy(sc->sc_transfer_buf, xfer->buffer, sc->sc_transfer_len); - xfer->length = sc->sc_transfer_len; - usbd_start_hardware(xfer); - return; -} - static const struct usbd_config uhid_config[UHID_N_TRANSFER] = { [0] = { .type = UE_INTERRUPT, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, - .flags = (USBD_PIPE_BOF|USBD_SHORT_XFER_OK), + .flags = { .pipe_bof = 1, .short_xfer_ok = 1, }, .bufsize = 0, /* use wMaxPacketSize */ .callback = &uhid_intr_callback, }, @@ -339,15 +323,6 @@ .callback = &uhid_read_callback, .timeout = 1000, /* 1 second */ }, - - [4] = { - .type = UE_CONTROL, - .endpoint = 0x00, /* Control pipe */ - .direction = UE_DIR_ANY, - .bufsize = sizeof(usb_device_request_t) + UHID_BSIZE, - .callback = &uhid_ioctl_callback, - .timeout = 1000, /* 1 second */ - }, }; static void @@ -392,70 +367,63 @@ } static int32_t -uhid_do_control_transfer(struct uhid_softc *sc, int32_t fflags) +uhid_do_control_transfer(struct uhid_softc *sc, + usb_device_request_t *req, + void *data, int32_t fflags) { int32_t error; - sc->sc_flags |= UHID_FLAG_COMMAND_ERR; + usb_cdev_unlock(&(sc->sc_cdev), fflags); - usbd_transfer_start(sc->sc_xfer[4]); - - error = usb_cdev_sleep(&(sc->sc_cdev), fflags, 0); + error = usbd_do_request(sc->sc_udev, NULL, req, data); - usbd_transfer_stop(sc->sc_xfer[4]); - if (error) { - return error; + error = ENXIO; } - if (sc->sc_flags & UHID_FLAG_COMMAND_ERR) { - return ENXIO; - } - return 0; + return usb_cdev_lock(&(sc->sc_cdev), fflags, error); } static int32_t uhid_get_report(struct uhid_softc *sc, int32_t fflags, u_int8_t type, u_int8_t id, void *data, u_int16_t len) { - usb_device_request_t *req = (void *)(sc->sc_transfer_buf); - int error; + usb_device_request_t req; if (len > UHID_BSIZE) { len = UHID_BSIZE; } + if (data == NULL) { + /* dummy buffer */ + data = sc->sc_transfer_buf; + } + usbd_fill_get_report - (req, sc->sc_iface_no, type, id, len); + (&req, sc->sc_iface_no, type, id, len); - sc->sc_transfer_len = sizeof(*req) + len; - - error = uhid_do_control_transfer(sc, fflags); - - if (data) { - bcopy(req->bData, data, len); - } - return error; + return uhid_do_control_transfer(sc, &req, data, fflags); } static int32_t uhid_set_report(struct uhid_softc *sc, int32_t fflags, u_int8_t type, u_int8_t id, void *data, u_int16_t len) { - usb_device_request_t *req = (void *)(sc->sc_transfer_buf); + usb_device_request_t req; if (len > UHID_BSIZE) { len = UHID_BSIZE; } + if (data == NULL) { + /* dummy buffer */ + data = sc->sc_transfer_buf; + } + usbd_fill_set_report - (req, sc->sc_iface_no, type, id, len); + (&req, sc->sc_iface_no, type, id, len); - bcopy(data, req->bData, len); - - sc->sc_transfer_len = sizeof(*req) + len; - - return uhid_do_control_transfer(sc, fflags); + return uhid_do_control_transfer(sc, &req, data, fflags); } static int32_t @@ -645,6 +613,8 @@ mtx_init(&(sc->sc_mtx), "uhid lock", NULL, MTX_DEF|MTX_RECURSE); + sc->sc_udev = uaa->device; + sc->sc_iface_no = uaa->iface->idesc->bInterfaceNumber; error = usbd_transfer_setup(uaa->device, uaa->iface_index, @@ -675,9 +645,8 @@ * returning digitizer data. */ error = usbreq_set_report - (uaa->device, uaa->iface_index, - UHID_FEATURE_REPORT, 2, - reportbuf, sizeof(reportbuf)); + (uaa->device, &usb_global_lock, reportbuf, sizeof(reportbuf), + uaa->iface_index, UHID_FEATURE_REPORT, 2); if (error) { DPRINTF(0, "set report failed, error=%s (ignored)\n", @@ -700,9 +669,9 @@ if (sc->sc_repdesc_ptr == NULL) { - error = usbreq_read_report_desc - (uaa->device, uaa->iface_index, - &(sc->sc_repdesc_ptr), &(sc->sc_repdesc_size), M_USBDEV); + error = hid_read_report_desc_from_usb + (uaa->device, &usb_global_lock, &(sc->sc_repdesc_ptr), + &(sc->sc_repdesc_size), M_USBDEV, uaa->iface_index); if (error) { device_printf(dev, "no report descriptor\n"); @@ -710,7 +679,7 @@ } } - error = usbreq_set_idle(uaa->device, uaa->iface_index, 0, 0); + error = usbreq_set_idle(uaa->device, &usb_global_lock, uaa->iface_index, 0, 0); if (error) { DPRINTF(0, "set idle failed, error=%s (ignored)\n", @@ -756,8 +725,7 @@ sc->sc_cdev.sc_stop_write = &uhid_stop_write; sc->sc_cdev.sc_open = &uhid_open; sc->sc_cdev.sc_ioctl = &uhid_ioctl; - sc->sc_cdev.sc_flags |= (USB_CDEV_FLAG_FWD_SHORT| - USB_CDEV_FLAG_WAKEUP_RD_IMMED| + sc->sc_cdev.sc_flags |= (USB_CDEV_FLAG_WAKEUP_RD_IMMED| USB_CDEV_FLAG_WAKEUP_WR_IMMED); /* make the buffers one byte larger than maximum so
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709231432.l8NEW9d9086718>