PERFORCE change 149748 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Sep 14 11:53:15 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=149748
Change 149748 by hselasky at 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)
More information about the p4-projects
mailing list