Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Oct 2008 14:54:31 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 151664 for review
Message-ID:  <200810211454.m9LEsVFs016685@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=151664

Change 151664 by hselasky@hselasky_laptop001 on 2008/10/21 14:53:33

	
	Improve UGEN ioctl interface by not returning EBUSY if
	parameters that should be set do not change value.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#28 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#28 (text+ko) ====

@@ -867,8 +867,9 @@
  * Else: No access
  *------------------------------------------------------------------------*/
 static int
-ugen_check_request(struct usb2_device_request *req)
+ugen_check_request(struct usb2_device *udev, struct usb2_device_request *req)
 {
+	struct usb2_pipe *pipe;
 	int error;
 
 	/*
@@ -889,13 +890,21 @@
 		}
 	}
 	/*
-	 * Clearing the stall this way is not allowed, hence it does
-	 * not update the data toggle value in "struct usb2_pipe" !
+	 * Special case - handle clearing of stall
 	 */
 	if (req->bmRequestType == UT_WRITE_ENDPOINT) {
-		error = priv_check(curthread, PRIV_DRIVER);
-		if (error) {
-			return (error);
+
+		pipe = usb2_get_pipe_by_addr(udev, req->wIndex[0]);
+		if (pipe == NULL) {
+			return (EINVAL);
+		}
+		if (usb2_check_thread_perm(udev, curthread, FREAD | FWRITE,
+		    pipe->iface_index, req->wIndex[0] & UE_ADDR)) {
+			return (EPERM);
+		}
+		if ((req->bRequest == UR_CLEAR_FEATURE) &&
+		    (UGETW(req->wValue) == UF_ENDPOINT_HALT)) {
+			usb2_clear_data_toggle(udev, pipe);
 		}
 	}
 	/* TODO: add more checks to verify the interface index */
@@ -914,7 +923,7 @@
 		/* control endpoint only */
 		return (EINVAL);
 	}
-	if (ugen_check_request(&ur->ucr_request)) {
+	if (ugen_check_request(f->udev, &ur->ucr_request)) {
 		return (EPERM);
 	}
 	len = UGETW(ur->ucr_request.wLength);
@@ -1105,7 +1114,7 @@
 				return (error);
 			}
 		}
-		if (ugen_check_request(req)) {
+		if (ugen_check_request(f->udev, req)) {
 			xfer->error = USB_ERR_INVAL;
 			goto complete;
 		}
@@ -1652,14 +1661,22 @@
 static int
 ugen_set_short_xfer(struct usb2_fifo *f, void *addr)
 {
+	uint8_t t;
+
+	if (*(int *)addr)
+		t = 1;
+	else
+		t = 0;
+
+	if (f->flag_short == t) {
+		/* same value like before - accept */
+		return (0);
+	}
 	if (f->xfer[0] || f->xfer[1]) {
 		/* cannot change this during transfer */
 		return (EBUSY);
 	}
-	if (*(int *)addr)
-		f->flag_short = 1;
-	else
-		f->flag_short = 0;
+	f->flag_short = t;
 	return (0);
 }
 
@@ -1688,16 +1705,24 @@
 static int
 ugen_set_buffer_size(struct usb2_fifo *f, void *addr)
 {
+	uint32_t t;
+
+	if (*(int *)addr < 1024)
+		t = 1024;
+	else if (*(int *)addr < (256 * 1024))
+		t = *(int *)addr;
+	else
+		t = 256 * 1024;
+
+	if (f->bufsize == t) {
+		/* same value like before - accept */
+		return (0);
+	}
 	if (f->xfer[0] || f->xfer[1]) {
 		/* cannot change this during transfer */
 		return (EBUSY);
 	}
-	if (*(int *)addr < 1024)
-		f->bufsize = 1024;
-	else if (*(int *)addr < (256 * 1024))
-		f->bufsize = *(int *)addr;
-	else
-		f->bufsize = 256 * 1024;
+	f->bufsize = t;
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810211454.m9LEsVFs016685>