PERFORCE change 126733 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Sep 23 07:32:10 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=126733
Change 126733 by hselasky at 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
More information about the p4-projects
mailing list