From owner-p4-projects@FreeBSD.ORG Sun Sep 14 11:53:15 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 321121065674; Sun, 14 Sep 2008 11:53:15 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EA18B1065673 for ; Sun, 14 Sep 2008 11:53:14 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id E8E7B8FC1B for ; Sun, 14 Sep 2008 11:53:14 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id m8EBrEaR006606 for ; Sun, 14 Sep 2008 11:53:14 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id m8EBrEbu006604 for perforce@freebsd.org; Sun, 14 Sep 2008 11:53:14 GMT (envelope-from hselasky@FreeBSD.org) Date: Sun, 14 Sep 2008 11:53:14 GMT Message-Id: <200809141153.m8EBrEbu006604@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 149748 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: Sun, 14 Sep 2008 11:53:15 -0000 http://perforce.freebsd.org/chv.cgi?CH=149748 Change 149748 by hselasky@hselasky_laptop001 on 2008/09/14 11:52:35 Add more IOCTL for Libusb. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#24 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.h#8 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#24 edit .. //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#18 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#24 (text+ko) ==== @@ -1333,6 +1333,7 @@ udev->bus = bus; udev->address = USB_START_ADDR; /* default value */ udev->plugtime = (uint32_t)ticks; + udev->power_mode = USB_POWER_MODE_ON; /* we are not ready yet */ udev->refcount = 1; ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.h#8 (text+ko) ==== @@ -128,6 +128,7 @@ uint8_t hs_hub_addr; /* high-speed HUB address */ uint8_t hs_port_no; /* high-speed HUB port number */ uint8_t driver_added_refcount; /* our driver added generation count */ + uint8_t power_mode; /* see USB_POWER_XXX */ /* the "flags" field is write-protected by "bus->mtx" */ ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#24 (text+ko) ==== @@ -934,9 +934,6 @@ /*------------------------------------------------------------------------ * ugen_re_enumerate - * - * NOTE: This function will currently not restore the device - * configuration. *------------------------------------------------------------------------*/ static int ugen_re_enumerate(struct usb2_fifo *f) @@ -1239,6 +1236,7 @@ } fs_ep.status = xfer->error; fs_ep.aFrames = xfer->aframes; + fs_ep.isoc_time_complete = xfer->isoc_time_complete; if (xfer->error) { goto complete; } @@ -1337,12 +1335,19 @@ /* update "aFrames" */ error = copyout(&fs_ep.aFrames, &fs_ep_uptr->aFrames, sizeof(fs_ep.aFrames)); - if (error) { - return (error); - } + if (error) + goto done; + + /* update "isoc_time_complete" */ + error = copyout(&fs_ep.isoc_time_complete, + &fs_ep_uptr->isoc_time_complete, + sizeof(fs_ep.isoc_time_complete)); + if (error) + goto done; /* update "status" */ error = copyout(&fs_ep.status, &fs_ep_uptr->status, sizeof(fs_ep.status)); +done: return (error); } @@ -1723,6 +1728,105 @@ } static int +ugen_set_power_mode(struct usb2_fifo *f, int mode) +{ + struct usb2_device *udev = f->udev; + int err; + + if ((udev == NULL) || + (udev->parent_hub == NULL)) { + return (EINVAL); + } + if (suser(curthread)) { + return (EPERM); + } + switch (mode) { + case USB_POWER_MODE_OFF: + /* clear suspend */ + err = usb2_req_clear_port_feature(udev->parent_hub, + NULL, udev->port_no, UHF_PORT_SUSPEND); + if (err) + break; + + /* clear port enable */ + err = usb2_req_clear_port_feature(udev->parent_hub, + NULL, udev->port_no, UHF_PORT_ENABLE); + break; + + case USB_POWER_MODE_ON: + case USB_POWER_MODE_SAVE: + case USB_POWER_MODE_RESUME: + /* TODO: implement USB power save */ + err = usb2_req_clear_port_feature(udev->parent_hub, + NULL, udev->port_no, UHF_PORT_SUSPEND); + break; + + case USB_POWER_MODE_SUSPEND: + /* TODO: implement USB power save */ + err = usb2_req_set_port_feature(udev->parent_hub, + NULL, udev->port_no, UHF_PORT_SUSPEND); + break; + default: + return (EINVAL); + } + + if (err) + return (ENXIO); /* I/O failure */ + + udev->power_mode = mode; /* update copy of power mode */ + + return (0); /* success */ +} + +static int +ugen_get_power_mode(struct usb2_fifo *f) +{ + struct usb2_device *udev = f->udev; + + if ((udev == NULL) || + (udev->parent_hub == NULL)) { + return (USB_POWER_MODE_ON); + } + return (udev->power_mode); +} + +static int +ugen_do_port_feature(struct usb2_fifo *f, uint8_t port_no, + uint8_t set, uint16_t feature) +{ + struct usb2_device *udev = f->udev; + struct usb2_hub *hub; + int err; + + if (suser(curthread)) { + return (EPERM); + } + if (port_no == 0) { + return (EINVAL); + } + if ((udev == NULL) || + (udev->hub == NULL)) { + return (EINVAL); + } + hub = udev->hub; + + if (port_no > hub->nports) { + return (EINVAL); + } + if (set) + err = usb2_req_set_port_feature(udev, + NULL, port_no, feature); + else + err = usb2_req_clear_port_feature(udev, + NULL, port_no, feature); + + if (err) + return (ENXIO); /* failure */ + + return (0); /* success */ +} + +static int ugen_iface_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags) { struct usb2_fifo *f_rx; @@ -1875,6 +1979,7 @@ struct usb2_device_stats *stat; uint32_t *ptime; void *addr; + int *pint; } u; struct usb2_device_descriptor *dtemp; struct usb2_config_descriptor *ctemp; @@ -1991,7 +2096,41 @@ *u.ptime = f->udev->plugtime; break; - /* ... more IOCTL's to come ! ... --hps */ + case USB_CLAIM_INTERFACE: + case USB_RELEASE_INTERFACE: + /* TODO */ + break; + + case USB_IFACE_DRIVER_ACTIVE: + /* TODO */ + *u.pint = 0; + break; + + case USB_IFACE_DRIVER_DETACH: + /* TODO */ + if (suser(curthread)) + error = EPERM; + else + error = EINVAL; + break; + + case USB_SET_POWER_MODE: + error = ugen_set_power_mode(f, *u.pint); + break; + + case USB_GET_POWER_MODE: + *u.pint = ugen_get_power_mode(f); + break; + + case USB_SET_PORT_ENABLE: + error = ugen_do_port_feature(f, + *u.pint, 1, UHF_PORT_ENABLE); + break; + + case USB_SET_PORT_DISABLE: + error = ugen_do_port_feature(f, + *u.pint, 0, UHF_PORT_ENABLE); + break; default: error = EINVAL; ==== //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#18 (text+ko) ==== @@ -34,6 +34,13 @@ #define USB_DEVICE_NAME "usb" #define USB_GENERIC_NAME "ugen" +/* definition of USB power mode */ +#define USB_POWER_MODE_OFF 0 /* turn off device */ +#define USB_POWER_MODE_ON 1 /* always on */ +#define USB_POWER_MODE_SAVE 2 /* automatic suspend and resume */ +#define USB_POWER_MODE_SUSPEND 3 /* force suspend */ +#define USB_POWER_MODE_RESUME 4 /* force resume */ + struct usb2_read_dir { void *urd_data; uint32_t urd_startentry; @@ -148,6 +155,8 @@ /* will do a clear-stall before xfer */ #define USB_FS_FLAG_CLEAR_STALL 0x0008 uint16_t timeout; /* in milliseconds */ + /* isocronous completion time in milliseconds - used for echo cancel */ + uint16_t isoc_time_complete; /* timeout value for no timeout */ #define USB_FS_TIMEOUT_NONE 0 uint8_t status; /* see USB_ERR_XXX */ @@ -252,10 +261,14 @@ #define USB_SET_TX_BUFFER_SIZE _IOW ('U', 140, int) #define USB_GET_TX_INTERFACE_DESC _IOR ('U', 141, struct usb2_interface_descriptor) #define USB_GET_TX_ENDPOINT_DESC _IOR ('U', 142, struct usb2_endpoint_descriptor) +#define USB_SET_PORT_ENABLE _IOW ('U', 143, int) +#define USB_SET_PORT_DISABLE _IOW ('U', 144, int) +#define USB_SET_POWER_MODE _IOW ('U', 145, int) +#define USB_GET_POWER_MODE _IOW ('U', 146, int) /* Modem device */ -#define USB_GET_CM_OVER_DATA _IOR ('U', 160, int) -#define USB_SET_CM_OVER_DATA _IOW ('U', 161, int) +#define USB_GET_CM_OVER_DATA _IOR ('U', 180, int) +#define USB_SET_CM_OVER_DATA _IOW ('U', 181, int) /* USB file system interface */ #define USB_FS_START _IOW ('U', 192, struct usb2_fs_start)