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