Date: Mon, 30 Jun 2008 18:56:34 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 144376 for review Message-ID: <200806301856.m5UIuY5S018045@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=144376 Change 144376 by hselasky@hselasky_laptop001 on 2008/06/30 18:55:29 The USB Input module for USB mouse and keyboard is complete. - Mostly symbol renaming. "s/usbd_|usb_/usb2/g" (scripted) - UHID has been reworked a little bit. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#5 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#4 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.h#3 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#2 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#5 edit .. //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#3 edit .. //depot/projects/usb/src/sys/dev/usb2/input/uhid2.c#2 edit .. //depot/projects/usb/src/sys/dev/usb2/input/ukbd2.c#2 edit .. //depot/projects/usb/src/sys/dev/usb2/input/ums2.c#2 edit .. //depot/projects/usb/src/sys/dev/usb2/input/usb2_hid.c#2 edit .. //depot/projects/usb/src/sys/dev/usb2/input/usb2_hid.h#2 delete .. //depot/projects/usb/src/sys/dev/usb2/input/usb2_input.c#1 add .. //depot/projects/usb/src/sys/dev/usb2/input/usb2_input.h#1 add .. //depot/projects/usb/src/sys/modules/usb2/input/Makefile#2 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#5 (text+ko) ==== @@ -405,5 +405,6 @@ usb2_error_t usb2_ref_device(struct file *fp, struct usb2_location *ploc, uint32_t devloc); void usb2_unref_device(struct usb2_location *ploc); void usb2_set_parent_iface(struct usb2_device *udev, uint8_t iface_index, uint8_t parent_index); +void usb2_set_iface_perm(struct usb2_device *udev, uint8_t iface_index, uint32_t uid, uint32_t gid, uint16_t mode); #endif /* _USB2_CORE_H_ */ ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#4 (text+ko) ==== @@ -208,6 +208,30 @@ } /*------------------------------------------------------------------------* + * usb2_set_iface_perm + * + * This function will set the interface permissions. + *------------------------------------------------------------------------*/ +void +usb2_set_iface_perm(struct usb2_device *udev, uint8_t iface_index, + uint32_t uid, uint32_t gid, uint16_t mode) +{ + struct usb2_interface *iface; + + iface = usb2_get_iface(udev, iface_index); + if (iface && iface->idesc) { + mtx_lock(&usb2_ref_lock); + iface->perm.uid = uid; + iface->perm.gid = gid; + iface->perm.mode = mode; + iface->perm.active = 1; + mtx_unlock(&usb2_ref_lock); + + } + return; +} + +/*------------------------------------------------------------------------* * usb2_match_perm * * This function will compare two permission structures and see if @@ -278,8 +302,10 @@ ploc->devloc = devloc; ploc->bus_index = devloc % USB_BUS_MAX; ploc->dev_index = (devloc / USB_BUS_MAX) % USB_DEV_MAX; - ploc->iface_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX)) % USB_IFACE_MAX; - ploc->ep_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX * USB_IFACE_MAX)) % USB_EP_MAX; + ploc->iface_index = (devloc / (USB_BUS_MAX * + USB_DEV_MAX)) % USB_IFACE_MAX; + ploc->ep_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX * + USB_IFACE_MAX)) % USB_EP_MAX; mtx_lock(&usb2_ref_lock); ploc->bus = devclass_get_softc(usb2_devclass_ptr, ploc->bus_index); @@ -571,7 +597,6 @@ usb2_fifo_open(struct usb2_fifo *f, struct file *fp, struct thread *td, int fflags) { - struct usb2_mbuf *m; int err; if (f == NULL) { @@ -620,6 +645,24 @@ f->curr_file = fp; /* reset queue */ + usb2_fifo_reset(f); + + mtx_unlock(f->priv_mtx); +done: + return (err); +} + +/*------------------------------------------------------------------------* + * usb2_fifo_reset + *------------------------------------------------------------------------*/ +void +usb2_fifo_reset(struct usb2_fifo *f) +{ + struct usb2_mbuf *m; + + if (f == NULL) { + return; + } while (1) { USB_IF_DEQUEUE(&(f->used_q), m); if (m) { @@ -628,9 +671,7 @@ break; } } - mtx_unlock(f->priv_mtx); -done: - return (err); + return; } /*------------------------------------------------------------------------* ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.h#3 (text+ko) ==== @@ -117,5 +117,6 @@ void usb2_fifo_get_data_error(struct usb2_fifo *fifo); uint8_t usb2_fifo_opened(struct usb2_fifo *fifo); void usb2_fifo_free(struct usb2_fifo *f); +void usb2_fifo_reset(struct usb2_fifo *f); #endif /* _USB2_DEV_H_ */ ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#2 (text+ko) ==== @@ -469,6 +469,7 @@ iface->idesc = NULL; iface->alt_index = 0; iface->parent_iface_index = USB_IFACE_INDEX_ANY; + iface->perm.active = 0; /* disable permissions */ iface++; } ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#5 (text+ko) ==== @@ -2134,7 +2134,7 @@ usb2_transfer_timeout_ms(xfer, &usb2_dma_delay_done_cb, temp); - return (1); /* wait for new callback */ + return (1); /* wait for new callback */ } /* check actual number of frames */ if (xfer->aframes > xfer->nframes) { ==== //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#3 (text+ko) ==== @@ -59,6 +59,7 @@ uint8_t ugd_iface_index; uint8_t ugd_altif_index; uint8_t ugd_endpt_index; + uint8_t ugd_report_type; uint8_t reserved[8]; }; @@ -110,7 +111,7 @@ #define USB_DEVICEENUMERATE _IOW ('U', 6, struct usb2_device_enumerate) /* Generic HID device */ -#define USB_GET_REPORT_DESC _IOR ('U', 21, struct usb2_ctl_report_desc) +#define USB_GET_REPORT_DESC _IOR ('U', 21, struct usb2_gen_descriptor) #define USB_SET_IMMED _IOW ('U', 22, int) #define USB_GET_REPORT _IOWR('U', 23, struct usb2_gen_descriptor) #define USB_SET_REPORT _IOW ('U', 24, struct usb2_gen_descriptor) ==== //depot/projects/usb/src/sys/dev/usb2/input/uhid2.c#2 (text+ko) ==== @@ -48,59 +48,49 @@ * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/ioccom.h> -#include <sys/filio.h> -#include <sys/tty.h> -#include <sys/file.h> -#include <sys/poll.h> +#include <dev/usb2/include/usb2_devid.h> +#include <dev/usb2/include/usb2_standard.h> +#include <dev/usb2/include/usb2_mfunc.h> +#include <dev/usb2/include/usb2_error.h> +#include <dev/usb2/include/usb2_hid.h> +#include <dev/usb2/include/usb2_ioctl.h> + +#define USB_DEBUG_VAR uhid_debug + +#include <dev/usb2/core/usb2_core.h> +#include <dev/usb2/core/usb2_util.h> +#include <dev/usb2/core/usb2_debug.h> +#include <dev/usb2/core/usb2_busdma.h> +#include <dev/usb2/core/usb2_process.h> +#include <dev/usb2/core/usb2_transfer.h> +#include <dev/usb2/core/usb2_request.h> +#include <dev/usb2/core/usb2_dynamic.h> +#include <dev/usb2/core/usb2_mbuf.h> +#include <dev/usb2/core/usb2_dev.h> -#include <dev/usb/usb_port.h> -#include <dev/usb/usb.h> -#include <dev/usb/usb_subr.h> -#include <dev/usb/usb_hid.h> -#include <dev/usb/usb_rdesc.h> -#include <dev/usb/usb_quirks.h> +#include <dev/usb2/input/usb2_input.h> +#include <dev/usb2/input/usb2_rdesc.h> -#include "usbdevs.h" +#include <dev/usb2/quirk/usb2_quirk.h> #ifdef USB_DEBUG -#define DPRINTF(n,fmt,...) \ - do { if (uhid_debug > (n)) { \ - printf("%s: " fmt, __FUNCTION__,## __VA_ARGS__); } } while (0) - static int uhid_debug = 0; -SYSCTL_NODE(_hw_usb, OID_AUTO, uhid, CTLFLAG_RW, 0, "USB uhid"); -SYSCTL_INT(_hw_usb_uhid, OID_AUTO, debug, CTLFLAG_RW, - &uhid_debug, 0, "uhid debug level"); -#else -#define DPRINTF(...) do { } while (0) +SYSCTL_NODE(_hw_usb2, OID_AUTO, uhid, CTLFLAG_RW, 0, "USB uhid"); +SYSCTL_INT(_hw_usb2_uhid, OID_AUTO, debug, CTLFLAG_RW, + &uhid_debug, 0, "Debug level"); #endif -/* temporary compile hacks for old USB systems: */ - -#ifndef UQ_HID_IGNORE -#define UQ_HID_IGNORE 0 -#endif - -#ifndef USB_PRODUCT_WACOM_GRAPHIRE3_4X5 -#define USB_PRODUCT_WACOM_GRAPHIRE3_4X5 0 -#endif - #define UHID_N_TRANSFER 4 /* units */ #define UHID_BSIZE 1024 /* bytes, buffer size */ #define UHID_FRAME_NUM 50 /* bytes, frame number */ struct uhid_softc { - struct usb_cdev sc_cdev; + struct usb2_fifo_sc sc_fifo; struct mtx sc_mtx; - struct usbd_xfer *sc_xfer[UHID_N_TRANSFER]; - struct usbd_device *sc_udev; + struct usb2_xfer *sc_xfer[UHID_N_TRANSFER]; + struct usb2_device *sc_udev; void *sc_repdesc_ptr; uint32_t sc_isize; @@ -109,8 +99,8 @@ uint16_t sc_repdesc_size; - uint8_t sc_transfer_buf[sizeof(usb_device_request_t) + UHID_BSIZE]; uint8_t sc_iface_no; + uint8_t sc_iface_index; uint8_t sc_iid; uint8_t sc_oid; uint8_t sc_fid; @@ -121,9 +111,9 @@ * static */ }; -static uint8_t uhid_xb360gp_report_descr[] = {UHID_XB360GP_REPORT_DESCR()}; -static uint8_t uhid_graphire_report_descr[] = {UHID_GRAPHIRE_REPORT_DESCR()}; -static uint8_t uhid_graphire3_4x5_report_descr[] = {UHID_GRAPHIRE3_4X5_REPORT_DESCR()}; +static const uint8_t uhid_xb360gp_report_descr[] = {UHID_XB360GP_REPORT_DESCR()}; +static const uint8_t uhid_graphire_report_descr[] = {UHID_GRAPHIRE_REPORT_DESCR()}; +static const uint8_t uhid_graphire3_4x5_report_descr[] = {UHID_GRAPHIRE3_4X5_REPORT_DESCR()}; /* prototypes */ @@ -131,23 +121,43 @@ static device_attach_t uhid_attach; static device_detach_t uhid_detach; -static usbd_callback_t uhid_intr_callback; -static usbd_callback_t uhid_intr_clear_stall_callback; -static usbd_callback_t uhid_write_callback; -static usbd_callback_t uhid_read_callback; +static usb2_callback_t uhid_intr_callback; +static usb2_callback_t uhid_intr_clear_stall_callback; +static usb2_callback_t uhid_write_callback; +static usb2_callback_t uhid_read_callback; + +static usb2_fifo_cmd_t uhid_start_read; +static usb2_fifo_cmd_t uhid_stop_read; +static usb2_fifo_cmd_t uhid_start_write; +static usb2_fifo_cmd_t uhid_stop_write; +static usb2_fifo_open_t uhid_open; +static usb2_fifo_close_t uhid_close; +static usb2_fifo_ioctl_t uhid_ioctl; + +static struct usb2_fifo_methods uhid_fifo_methods = { + .f_open = &uhid_open, + .f_close = &uhid_close, + .f_ioctl = &uhid_ioctl, + .f_start_read = &uhid_start_read, + .f_stop_read = &uhid_stop_read, + .f_start_write = &uhid_start_write, + .f_stop_write = &uhid_stop_write, + .basename[0] = "uhid", +}; static void -uhid_intr_callback(struct usbd_xfer *xfer) +uhid_intr_callback(struct usb2_xfer *xfer) { struct uhid_softc *sc = xfer->priv_sc; - struct usbd_mbuf *m; - switch (USBD_GET_STATE(xfer)) { - case USBD_ST_TRANSFERRED: + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: DPRINTF(0, "transferred!\n"); if (xfer->actlen >= sc->sc_isize) { - usb_cdev_put_data(&(sc->sc_cdev), xfer->frbuffers, + usb2_fifo_put_data( + sc->sc_fifo.fp[USB_FIFO_RX], + xfer->frbuffers, 0, sc->sc_isize, 1); } else { /* ignore it */ @@ -155,64 +165,91 @@ "%d bytes\n", xfer->actlen); } - case USBD_ST_SETUP: + case USB_ST_SETUP: if (sc->sc_flags & UHID_FLAG_INTR_STALL) { - usbd_transfer_start(sc->sc_xfer[1]); + usb2_transfer_start(sc->sc_xfer[1]); } else { - USBD_IF_POLL(&(sc->sc_cdev.sc_rdq_free), m); - - if (m) { + if (usb2_fifo_put_bytes_max( + sc->sc_fifo.fp[USB_FIFO_RX]) != 0) { xfer->frlengths[0] = xfer->max_data_length; - usbd_start_hardware(xfer); + usb2_start_hardware(xfer); } } return; default: /* Error */ - if (xfer->error != USBD_ERR_CANCELLED) { + if (xfer->error != USB_ERR_CANCELLED) { /* try to clear stall first */ sc->sc_flags |= UHID_FLAG_INTR_STALL; - usbd_transfer_start(sc->sc_xfer[1]); + usb2_transfer_start(sc->sc_xfer[1]); } return; } } static void -uhid_intr_clear_stall_callback(struct usbd_xfer *xfer) +uhid_intr_clear_stall_callback(struct usb2_xfer *xfer) { struct uhid_softc *sc = xfer->priv_sc; - struct usbd_xfer *xfer_other = sc->sc_xfer[0]; + struct usb2_xfer *xfer_other = sc->sc_xfer[0]; - if (usbd_clear_stall_callback(xfer, xfer_other)) { + if (usb2_clear_stall_callback(xfer, xfer_other)) { DPRINTF(0, "stall cleared\n"); sc->sc_flags &= ~UHID_FLAG_INTR_STALL; - usbd_transfer_start(xfer_other); + usb2_transfer_start(xfer_other); } return; } static void -uhid_write_callback(struct usbd_xfer *xfer) +uhid_fill_set_report(struct usb2_device_request *req, uint8_t iface_no, + uint8_t type, uint8_t id, uint16_t size) +{ + req->bmRequestType = UT_WRITE_CLASS_INTERFACE; + req->bRequest = UR_SET_REPORT; + USETW2(req->wValue, type, id); + req->wIndex[0] = iface_no; + req->wIndex[1] = 0; + USETW(req->wLength, size); + return; +} + +static void +uhid_fill_get_report(struct usb2_device_request *req, uint8_t iface_no, + uint8_t type, uint8_t id, uint16_t size) +{ + req->bmRequestType = UT_READ_CLASS_INTERFACE; + req->bRequest = UR_GET_REPORT; + USETW2(req->wValue, type, id); + req->wIndex[0] = iface_no; + req->wIndex[1] = 0; + USETW(req->wLength, size); + return; +} + +static void +uhid_write_callback(struct usb2_xfer *xfer) { struct uhid_softc *sc = xfer->priv_sc; - usb_device_request_t req; + struct usb2_device_request req; uint32_t size = sc->sc_osize; uint32_t actlen; uint8_t id; - switch (USBD_GET_STATE(xfer)) { - case USBD_ST_TRANSFERRED: - case USBD_ST_SETUP: + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + case USB_ST_SETUP: /* try to extract the ID byte */ if (sc->sc_oid) { - if (usb_cdev_get_data(&(sc->sc_cdev), xfer->frbuffers, + if (usb2_fifo_get_data( + sc->sc_fifo.fp[USB_FIFO_TX], + xfer->frbuffers, 0, 1, &actlen, 0)) { if (actlen != 1) { goto tr_error; } - usbd_copy_out(xfer->frbuffers, 0, &id, 1); + usb2_copy_out(xfer->frbuffers, 0, &id, 1); } else { return; @@ -224,69 +261,71 @@ id = 0; } - if (usb_cdev_get_data(&(sc->sc_cdev), xfer->frbuffers + 1, + if (usb2_fifo_get_data( + sc->sc_fifo.fp[USB_FIFO_TX], + xfer->frbuffers + 1, 0, UHID_BSIZE, &actlen, 1)) { if (actlen != size) { goto tr_error; } - usbd_fill_set_report + uhid_fill_set_report (&req, sc->sc_iface_no, UHID_OUTPUT_REPORT, id, size); - usbd_copy_in(xfer->frbuffers, 0, &req, sizeof(req)); + usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req)); xfer->frlengths[0] = sizeof(req); xfer->frlengths[1] = size; xfer->nframes = xfer->frlengths[1] ? 2 : 1; - usbd_start_hardware(xfer); + usb2_start_hardware(xfer); } return; default: tr_error: /* bomb out */ - usb_cdev_get_data_error(&(sc->sc_cdev)); + usb2_fifo_get_data_error(sc->sc_fifo.fp[USB_FIFO_TX]); return; } } static void -uhid_read_callback(struct usbd_xfer *xfer) +uhid_read_callback(struct usb2_xfer *xfer) { struct uhid_softc *sc = xfer->priv_sc; - usb_device_request_t req; + struct usb2_device_request req; - switch (USBD_GET_STATE(xfer)) { - case USBD_ST_TRANSFERRED: - usb_cdev_put_data(&(sc->sc_cdev), xfer->frbuffers, + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + usb2_fifo_put_data(sc->sc_fifo.fp[USB_FIFO_RX], xfer->frbuffers, sizeof(req), sc->sc_isize, 1); return; - case USBD_ST_SETUP: + case USB_ST_SETUP: - if (usb_cdev_put_bytes_max(&(sc->sc_cdev)) > 0) { + if (usb2_fifo_put_bytes_max(sc->sc_fifo.fp[USB_FIFO_RX]) > 0) { - usbd_fill_get_report + uhid_fill_get_report (&req, sc->sc_iface_no, UHID_INPUT_REPORT, sc->sc_iid, sc->sc_isize); - usbd_copy_in(xfer->frbuffers, 0, &req, sizeof(req)); + usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req)); xfer->frlengths[0] = sizeof(req); xfer->frlengths[1] = sc->sc_isize; xfer->nframes = xfer->frlengths[1] ? 2 : 1; - usbd_start_hardware(xfer); + usb2_start_hardware(xfer); } return; default: /* Error */ /* bomb out */ - usb_cdev_put_data_error(&(sc->sc_cdev)); + usb2_fifo_put_data_error(sc->sc_fifo.fp[USB_FIFO_RX]); return; } } -static const struct usbd_config uhid_config[UHID_N_TRANSFER] = { +static const struct usb2_config uhid_config[UHID_N_TRANSFER] = { [0] = { .type = UE_INTERRUPT, @@ -301,7 +340,7 @@ .type = UE_CONTROL, .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, - .mh.bufsize = sizeof(usb_device_request_t), + .mh.bufsize = sizeof(struct usb2_device_request), .mh.callback = &uhid_intr_clear_stall_callback, .mh.timeout = 1000, /* 1 second */ .mh.interval = 50, /* 50ms */ @@ -311,7 +350,7 @@ .type = UE_CONTROL, .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, - .mh.bufsize = sizeof(usb_device_request_t) + UHID_BSIZE, + .mh.bufsize = sizeof(struct usb2_device_request) + UHID_BSIZE, .mh.callback = &uhid_write_callback, .mh.timeout = 1000, /* 1 second */ }, @@ -320,169 +359,211 @@ .type = UE_CONTROL, .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, - .mh.bufsize = sizeof(usb_device_request_t) + UHID_BSIZE, + .mh.bufsize = sizeof(struct usb2_device_request) + UHID_BSIZE, .mh.callback = &uhid_read_callback, .mh.timeout = 1000, /* 1 second */ }, }; static void -uhid_start_read(struct usb_cdev *cdev) +uhid_start_read(struct usb2_fifo *fifo) { - struct uhid_softc *sc = cdev->sc_priv_ptr; + struct uhid_softc *sc = fifo->priv_sc0; if (sc->sc_flags & UHID_FLAG_IMMED) { - usbd_transfer_start(sc->sc_xfer[3]); + usb2_transfer_start(sc->sc_xfer[3]); } else { - usbd_transfer_start(sc->sc_xfer[0]); + usb2_transfer_start(sc->sc_xfer[0]); } return; } static void -uhid_stop_read(struct usb_cdev *cdev) +uhid_stop_read(struct usb2_fifo *fifo) { - struct uhid_softc *sc = cdev->sc_priv_ptr; + struct uhid_softc *sc = fifo->priv_sc0; - usbd_transfer_stop(sc->sc_xfer[3]); - usbd_transfer_stop(sc->sc_xfer[0]); + usb2_transfer_stop(sc->sc_xfer[3]); + usb2_transfer_stop(sc->sc_xfer[0]); return; } static void -uhid_start_write(struct usb_cdev *cdev) +uhid_start_write(struct usb2_fifo *fifo) { - struct uhid_softc *sc = cdev->sc_priv_ptr; + struct uhid_softc *sc = fifo->priv_sc0; - usbd_transfer_start(sc->sc_xfer[2]); + usb2_transfer_start(sc->sc_xfer[2]); return; } static void -uhid_stop_write(struct usb_cdev *cdev) +uhid_stop_write(struct usb2_fifo *fifo) { - struct uhid_softc *sc = cdev->sc_priv_ptr; + struct uhid_softc *sc = fifo->priv_sc0; - usbd_transfer_stop(sc->sc_xfer[2]); + usb2_transfer_stop(sc->sc_xfer[2]); return; } -static int32_t -uhid_do_control_transfer(struct uhid_softc *sc, - usb_device_request_t *req, - void *data, int32_t fflags) +static int +uhid_get_report(struct uhid_softc *sc, uint8_t type, + uint8_t id, void *kern_data, void *user_data, + uint16_t len) { - int32_t error; + int err; + uint8_t free_data = 0; - usb_cdev_unlock(&(sc->sc_cdev), fflags); - - error = usbd_do_request(sc->sc_udev, NULL, req, data); - - if (error) { - error = ENXIO; + if (kern_data == NULL) { + kern_data = malloc(len, M_USBDEV, M_WAITOK); + if (kern_data == NULL) { + err = ENOMEM; + goto done; + } + free_data = 1; } - return (usb_cdev_lock(&(sc->sc_cdev), fflags, error)); -} - -static int32_t -uhid_get_report(struct uhid_softc *sc, int32_t fflags, - uint8_t type, uint8_t id, void *data, uint16_t len) -{ - usb_device_request_t req; - - if (len > UHID_BSIZE) { - len = UHID_BSIZE; + err = usb2_req_get_report(sc->sc_udev, NULL, kern_data, + len, sc->sc_iface_index, type, id); + if (err) { + err = ENXIO; + goto done; } - if (data == NULL) { + if (user_data) { /* dummy buffer */ - data = sc->sc_transfer_buf; + err = copyout(kern_data, user_data, len); + if (err) { + goto done; + } + } +done: + if (free_data) { + free(kern_data, M_USBDEV); } - usbd_fill_get_report - (&req, sc->sc_iface_no, type, id, len); - - return (uhid_do_control_transfer(sc, &req, data, fflags)); + return (err); } -static int32_t -uhid_set_report(struct uhid_softc *sc, int32_t fflags, - uint8_t type, uint8_t id, void *data, uint16_t len) +static int +uhid_set_report(struct uhid_softc *sc, uint8_t type, + uint8_t id, void *kern_data, void *user_data, + uint16_t len) { - usb_device_request_t req; + int err; + uint8_t free_data = 0; - if (len > UHID_BSIZE) { - len = UHID_BSIZE; + if (kern_data == NULL) { + kern_data = malloc(len, M_USBDEV, M_WAITOK); + if (kern_data == NULL) { + err = ENOMEM; + goto done; + } + free_data = 1; + err = copyin(user_data, kern_data, len); + if (err) { + goto done; + } + } + err = usb2_req_set_report(sc->sc_udev, NULL, kern_data, + len, sc->sc_iface_index, type, id); + if (err) { + err = ENXIO; + goto done; } - if (data == NULL) { - /* dummy buffer */ - data = sc->sc_transfer_buf; +done: + if (free_data) { + free(kern_data, M_USBDEV); } - usbd_fill_set_report - (&req, sc->sc_iface_no, type, id, len); - - return (uhid_do_control_transfer(sc, &req, data, fflags)); + return (err); } -static int32_t -uhid_open(struct usb_cdev *cdev, int32_t fflags, - int32_t devtype, struct thread *td) +static int +uhid_open(struct usb2_fifo *fifo, int fflags, struct thread *td) { - struct uhid_softc *sc = cdev->sc_priv_ptr; + struct uhid_softc *sc = fifo->priv_sc0; + /* + * The buffers are one byte larger than maximum so that one + * can detect too large read/writes and short transfers: + */ if (fflags & FREAD) { /* reset flags */ sc->sc_flags &= ~UHID_FLAG_IMMED; + + if (usb2_fifo_alloc_buffer(fifo, + sc->sc_isize + 1, UHID_FRAME_NUM)) { + return (ENOMEM); + } + } + if (fflags & FWRITE) { + if (usb2_fifo_alloc_buffer(fifo, + sc->sc_osize + 1, UHID_FRAME_NUM)) { + return (ENOMEM); + } } return (0); } -static int32_t -uhid_ioctl(struct usb_cdev *cdev, u_long cmd, caddr_t addr, - int32_t fflags, struct thread *td) +static void +uhid_close(struct usb2_fifo *fifo, int fflags, struct thread *td) +{ + if (fflags & (FREAD | FWRITE)) { + usb2_fifo_free_buffer(fifo); + } + return; +} + +static int +uhid_ioctl(struct usb2_fifo *fifo, u_long cmd, void *addr, + int fflags, struct thread *td) { - struct uhid_softc *sc = cdev->sc_priv_ptr; - struct usb_ctl_report_desc *rd; - struct usb_ctl_report *re; + struct uhid_softc *sc = fifo->priv_sc0; + struct usb2_gen_descriptor *ugd; uint32_t size; - int32_t error = 0; + int error = 0; uint8_t id; switch (cmd) { case USB_GET_REPORT_DESC: - rd = (void *)addr; - size = min(sc->sc_repdesc_size, sizeof(rd->ucrd_data)); - rd->ucrd_size = size; - bcopy(sc->sc_repdesc_ptr, rd->ucrd_data, size); + ugd = addr; + if (sc->sc_repdesc_size > ugd->ugd_maxlen) { + size = ugd->ugd_maxlen; + } else { + size = sc->sc_repdesc_size; + } + ugd->ugd_actlen = size; + error = copyout(sc->sc_repdesc_ptr, ugd->ugd_data, size); break; case USB_SET_IMMED: - if (!(fflags & FREAD)) { error = EPERM; - goto done; + break; } if (*(int *)addr) { /* do a test read */ - error = uhid_get_report(sc, fflags, UHID_INPUT_REPORT, - sc->sc_iid, NULL, sc->sc_isize); + error = uhid_get_report(sc, UHID_INPUT_REPORT, + sc->sc_iid, NULL, NULL, sc->sc_isize); if (error) { - goto done; + break; } + mtx_lock(&(sc->sc_mtx)); sc->sc_flags |= UHID_FLAG_IMMED; + mtx_unlock(&(sc->sc_mtx)); } else { + mtx_lock(&(sc->sc_mtx)); sc->sc_flags &= ~UHID_FLAG_IMMED; + mtx_unlock(&(sc->sc_mtx)); } break; case USB_GET_REPORT: - if (!(fflags & FREAD)) { error = EPERM; - goto done; + break; } - re = (void *)addr; - switch (re->ucr_report) { + ugd = addr; + switch (ugd->ugd_report_type) { case UHID_INPUT_REPORT: size = sc->sc_isize; id = sc->sc_iid; @@ -496,24 +577,19 @@ id = sc->sc_fid; break; default: - error = EINVAL; - goto done; + return (EINVAL); } - error = uhid_get_report(sc, fflags, re->ucr_report, id, - re->ucr_data, size); - if (error) { - goto done; - } + error = uhid_get_report(sc, ugd->ugd_report_type, id, + NULL, ugd->ugd_data, size); break; case USB_SET_REPORT: - if (!(fflags & FWRITE)) { error = EPERM; - goto done; + break; } - re = (void *)addr; - switch (re->ucr_report) { + ugd = addr; + switch (ugd->ugd_report_type) { case UHID_INPUT_REPORT: size = sc->sc_isize; id = sc->sc_iid; @@ -529,11 +605,8 @@ default: return (EINVAL); } - error = uhid_set_report(sc, fflags, re->ucr_report, id, - re->ucr_data, size); - if (error) { - goto done; - } + error = uhid_set_report(sc, ugd->ugd_report_type, id, + NULL, ugd->ugd_data, size); break; case USB_GET_REPORT_ID: @@ -544,89 +617,76 @@ error = EINVAL; break; } - -done: return (error); } static int uhid_probe(device_t dev) { - struct usb_attach_arg *uaa = device_get_ivars(dev); - usb_interface_descriptor_t *id; + struct usb2_attach_arg *uaa = device_get_ivars(dev); DPRINTF(10, "\n"); - if (uaa->usb_mode != USB_MODE_HOST) { - return (UMATCH_NONE); + if (uaa->usb2_mode != USB_MODE_HOST) { + return (ENXIO); } - if (uaa->iface == NULL) { - return (UMATCH_NONE); - } - id = usbd_get_interface_descriptor(uaa->iface); - if (id == NULL) { - return (UMATCH_NONE); - } - if (id->bInterfaceClass != UICLASS_HID) { + if (uaa->info.bInterfaceClass != UICLASS_HID) { /* the Xbox 360 gamepad doesn't use the HID class */ - if ((id->bInterfaceClass != UICLASS_VENDOR) || - (id->bInterfaceSubClass != UISUBCLASS_XBOX360_CONTROLLER) || - (id->bInterfaceProtocol != UIPROTO_XBOX360_GAMEPAD)) { - return (UMATCH_NONE); + if ((uaa->info.bInterfaceClass != UICLASS_VENDOR) || + (uaa->info.bInterfaceSubClass != UISUBCLASS_XBOX360_CONTROLLER) || + (uaa->info.bInterfaceProtocol != UIPROTO_XBOX360_GAMEPAD)) { + return (ENXIO); } } - if (usbd_get_quirks(uaa->device)->uq_flags & UQ_HID_IGNORE) { - return (UMATCH_NONE); + if (usb2_test_quirk(uaa, UQ_HID_IGNORE)) { + return (ENXIO); } - return (UMATCH_IFACECLASS_GENERIC); + return (0); } static int uhid_attach(device_t dev) { - struct usb_attach_arg *uaa = device_get_ivars(dev); + struct usb2_attach_arg *uaa = device_get_ivars(dev); struct uhid_softc *sc = device_get_softc(dev); - usb_interface_descriptor_t *id = - usbd_get_interface_descriptor(uaa->iface); - const char *p_buf[2]; - int32_t unit = device_get_unit(dev); - int32_t error = 0; - char buf[16]; + int unit = device_get_unit(dev); + int error = 0; DPRINTF(10, "sc=%p\n", sc); if (sc == NULL) { return (ENOMEM); } - usbd_set_device_desc(dev); + device_set_usb2_desc(dev); 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; + sc->sc_iface_no = uaa->info.bIfaceNum; + sc->sc_iface_index = uaa->info.bIfaceIndex; - error = usbd_transfer_setup(uaa->device, - &(uaa->iface_index), sc->sc_xfer, uhid_config, + error = usb2_transfer_setup(uaa->device, + &(uaa->info.bIfaceIndex), sc->sc_xfer, uhid_config, UHID_N_TRANSFER, sc, &(sc->sc_mtx)); if (error) { - DPRINTF(0, "error=%s\n", usbd_errstr(error)); + DPRINTF(0, "error=%s\n", usb2_errstr(error)); goto detach; } - if (uaa->vendor == USB_VENDOR_WACOM) { + if (uaa->info.idVendor == USB_VENDOR_WACOM) { >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200806301856.m5UIuY5S018045>